KCalCore Library
memorycalendar.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the kcalcore library. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2001,2003,2004 Cornelius Schumacher <schumacher@kde.org> 00006 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 Boston, MA 02110-1301, USA. 00022 */ 00035 #include "memorycalendar.h" 00036 00037 #include <KDebug> 00038 00039 using namespace KCalCore; 00040 00045 //@cond PRIVATE 00046 class KCalCore::MemoryCalendar::Private 00047 { 00048 public: 00049 Private( MemoryCalendar *qq ) : q( qq ) 00050 { 00051 } 00052 ~Private() 00053 { 00054 } 00055 00056 MemoryCalendar *q; 00057 QString mFileName; // filename where calendar is stored 00058 CalFormat *mFormat; // calendar format 00059 00064 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mIncidences; 00065 00070 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mDeletedIncidences; 00071 00083 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, IncidenceBase::Ptr> > mIncidencesForDate; 00084 00085 void insertIncidence( Incidence::Ptr incidence ); 00086 00087 Incidence::Ptr incidence( const QString &uid, 00088 const IncidenceBase::IncidenceType type, 00089 const KDateTime &recurrenceId = KDateTime() ) const; 00090 00091 Incidence::Ptr deletedIncidence( const QString &uid, 00092 const KDateTime &recurrenceId, 00093 const IncidenceBase::IncidenceType type ) const; 00094 00095 void deleteAllIncidences( const IncidenceBase::IncidenceType type ); 00096 00097 }; 00098 00099 MemoryCalendar::MemoryCalendar( const KDateTime::Spec &timeSpec ) 00100 : Calendar( timeSpec ), 00101 d( new KCalCore::MemoryCalendar::Private( this ) ) 00102 { 00103 } 00104 00105 MemoryCalendar::MemoryCalendar( const QString &timeZoneId ) 00106 : Calendar( timeZoneId ), 00107 d( new KCalCore::MemoryCalendar::Private( this ) ) 00108 { 00109 } 00110 00111 MemoryCalendar::~MemoryCalendar() 00112 { 00113 close(); 00114 delete d; 00115 } 00116 00117 void MemoryCalendar::close() 00118 { 00119 setObserversEnabled( false ); 00120 d->mFileName.clear(); 00121 00122 deleteAllEvents(); 00123 deleteAllTodos(); 00124 deleteAllJournals(); 00125 00126 d->mDeletedIncidences.clear(); 00127 00128 setModified( false ); 00129 00130 setObserversEnabled( true ); 00131 } 00132 00133 bool MemoryCalendar::deleteIncidence( const Incidence::Ptr &incidence ) 00134 { 00135 // Handle orphaned children 00136 // relations is an Incidence's property, not a Todo's, so 00137 // we remove relations in deleteIncidence, not in deleteTodo. 00138 removeRelations( incidence ); 00139 const Incidence::IncidenceType type = incidence->type(); 00140 const QString uid = incidence->uid(); 00141 if ( d->mIncidences[type].remove( uid, incidence ) ) { 00142 setModified( true ); 00143 notifyIncidenceDeleted( incidence ); 00144 d->mDeletedIncidences[type].insert( uid, incidence ); 00145 00146 const KDateTime dt = incidence->dateTime( Incidence::RoleCalendarHashing ); 00147 if ( dt.isValid() ) { 00148 d->mIncidencesForDate[type].remove( dt.date().toString(), incidence ); 00149 } 00150 // Delete child-incidences. 00151 if ( !incidence->hasRecurrenceId() ) { 00152 deleteIncidenceInstances( incidence ); 00153 } 00154 return true; 00155 } else { 00156 kWarning() << incidence->typeStr() << " not found."; 00157 return false; 00158 } 00159 } 00160 00161 bool MemoryCalendar::deleteIncidenceInstances( const Incidence::Ptr &incidence ) 00162 { 00163 const Incidence::IncidenceType type = incidence->type(); 00164 QList<Incidence::Ptr> values = d->mIncidences[type].values( incidence->uid() ); 00165 QList<Incidence::Ptr>::const_iterator it; 00166 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00167 Incidence::Ptr i = *it; 00168 if ( i->hasRecurrenceId() ) { 00169 kDebug() << "deleting child" 00170 << ", type=" << int( type ) 00171 << ", uid=" << i->uid() 00172 << ", start=" << i->dtStart() 00173 << " from calendar"; 00174 deleteIncidence( i ); 00175 } 00176 } 00177 00178 return true; 00179 } 00180 00181 void MemoryCalendar::Private::deleteAllIncidences( const Incidence::IncidenceType incidenceType ) 00182 { 00183 QHashIterator<QString, Incidence::Ptr>i( mIncidences[incidenceType] ); 00184 while ( i.hasNext() ) { 00185 i.next(); 00186 q->notifyIncidenceDeleted( i.value() ); 00187 // suppress update notifications for the relation removal triggered 00188 // by the following deletions 00189 i.value()->startUpdates(); 00190 } 00191 mIncidences[incidenceType].clear(); 00192 mIncidencesForDate[incidenceType].clear(); 00193 } 00194 00195 Incidence::Ptr MemoryCalendar::Private::incidence( const QString &uid, 00196 const Incidence::IncidenceType type, 00197 const KDateTime &recurrenceId ) const 00198 { 00199 QList<Incidence::Ptr> values = mIncidences[type].values( uid ); 00200 QList<Incidence::Ptr>::const_iterator it; 00201 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00202 Incidence::Ptr i = *it; 00203 if ( recurrenceId.isNull() ) { 00204 if ( !i->hasRecurrenceId() ) { 00205 return i; 00206 } 00207 } else { 00208 if ( i->hasRecurrenceId() && i->recurrenceId() == recurrenceId ) { 00209 return i; 00210 } 00211 } 00212 } 00213 return Incidence::Ptr(); 00214 } 00215 00216 Incidence::Ptr 00217 MemoryCalendar::Private::deletedIncidence( const QString &uid, 00218 const KDateTime &recurrenceId, 00219 const IncidenceBase::IncidenceType type ) const 00220 { 00221 QList<Incidence::Ptr> values = mDeletedIncidences[type].values( uid ); 00222 QList<Incidence::Ptr>::const_iterator it; 00223 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00224 Incidence::Ptr i = *it; 00225 if ( recurrenceId.isNull() ) { 00226 if ( !i->hasRecurrenceId() ) { 00227 return i; 00228 } 00229 } else { 00230 if ( i->hasRecurrenceId() && i->recurrenceId() == recurrenceId ) { 00231 return i; 00232 } 00233 } 00234 } 00235 return Incidence::Ptr(); 00236 } 00237 00238 //@cond PRIVATE 00239 void MemoryCalendar::Private::insertIncidence( Incidence::Ptr incidence ) 00240 { 00241 const QString uid = incidence->uid(); 00242 const Incidence::IncidenceType type = incidence->type(); 00243 if ( !mIncidences[type].contains( uid, incidence ) ) { 00244 mIncidences[type].insert( uid, incidence ); 00245 const KDateTime dt = incidence->dateTime( Incidence::RoleCalendarHashing ); 00246 if ( dt.isValid() ) { 00247 mIncidencesForDate[type].insert( dt.date().toString(), incidence ); 00248 } 00249 00250 } else { 00251 #ifndef NDEBUG 00252 // if we already have an to-do with this UID, it must be the same incidence, 00253 // otherwise something's really broken 00254 Q_ASSERT( mIncidences[type].value( uid ) == incidence ); 00255 #endif 00256 } 00257 } 00258 //@endcond 00259 00260 bool MemoryCalendar::addIncidence( const Incidence::Ptr &incidence ) 00261 { 00262 notifyIncidenceAdded( incidence ); 00263 00264 d->insertIncidence( incidence ); 00265 00266 incidence->registerObserver( this ); 00267 00268 setupRelations( incidence ); 00269 00270 setModified( true ); 00271 00272 return true; 00273 } 00274 00275 bool MemoryCalendar::addEvent( const Event::Ptr &event ) 00276 { 00277 return addIncidence( event ); 00278 } 00279 00280 bool MemoryCalendar::deleteEvent( const Event::Ptr &event ) 00281 { 00282 return deleteIncidence( event ); 00283 } 00284 00285 bool MemoryCalendar::deleteEventInstances( const Event::Ptr &event ) 00286 { 00287 return deleteIncidenceInstances( event ); 00288 } 00289 00290 void MemoryCalendar::deleteAllEvents() 00291 { 00292 d->deleteAllIncidences( Incidence::TypeEvent ); 00293 } 00294 00295 Event::Ptr MemoryCalendar::event( const QString &uid, 00296 const KDateTime &recurrenceId ) const 00297 { 00298 return d->incidence( uid, Incidence::TypeEvent, recurrenceId ).staticCast<Event>(); 00299 } 00300 00301 Event::Ptr MemoryCalendar::deletedEvent( const QString &uid, const KDateTime &recurrenceId ) const 00302 { 00303 return d->deletedIncidence( uid, recurrenceId, Incidence::TypeEvent ).staticCast<Event>(); 00304 } 00305 00306 bool MemoryCalendar::addTodo( const Todo::Ptr &todo ) 00307 { 00308 return addIncidence( todo ); 00309 } 00310 00311 bool MemoryCalendar::deleteTodo( const Todo::Ptr &todo ) 00312 { 00313 return deleteIncidence( todo ); 00314 } 00315 00316 bool MemoryCalendar::deleteTodoInstances( const Todo::Ptr &todo ) 00317 { 00318 return deleteIncidenceInstances( todo ); 00319 } 00320 00321 void MemoryCalendar::deleteAllTodos() 00322 { 00323 d->deleteAllIncidences( Incidence::TypeTodo ); 00324 } 00325 00326 Todo::Ptr MemoryCalendar::todo( const QString &uid, 00327 const KDateTime &recurrenceId ) const 00328 { 00329 return d->incidence( uid, Incidence::TypeTodo, recurrenceId ).staticCast<Todo>(); 00330 } 00331 00332 Todo::Ptr MemoryCalendar::deletedTodo( const QString &uid, 00333 const KDateTime &recurrenceId ) const 00334 { 00335 return d->deletedIncidence( uid, recurrenceId, Incidence::TypeTodo ).staticCast<Todo>(); 00336 } 00337 00338 Todo::List MemoryCalendar::rawTodos( TodoSortField sortField, 00339 SortDirection sortDirection ) const 00340 { 00341 Todo::List todoList; 00342 QHashIterator<QString, Incidence::Ptr>i( d->mIncidences[Incidence::TypeTodo] ); 00343 while ( i.hasNext() ) { 00344 i.next(); 00345 todoList.append( i.value().staticCast<Todo>() ); 00346 } 00347 return Calendar::sortTodos( todoList, sortField, sortDirection ); 00348 } 00349 00350 Todo::List MemoryCalendar::deletedTodos( TodoSortField sortField, 00351 SortDirection sortDirection ) const 00352 { 00353 Todo::List todoList; 00354 QHashIterator<QString, Incidence::Ptr >i( d->mDeletedIncidences[Incidence::TypeTodo] ); 00355 while ( i.hasNext() ) { 00356 i.next(); 00357 todoList.append( i.value().staticCast<Todo>() ); 00358 } 00359 return Calendar::sortTodos( todoList, sortField, sortDirection ); 00360 } 00361 00362 Todo::List MemoryCalendar::todoInstances( const Incidence::Ptr &todo, 00363 TodoSortField sortField, 00364 SortDirection sortDirection ) const 00365 { 00366 Todo::List list; 00367 00368 QList<Incidence::Ptr > values = d->mIncidences[Incidence::TypeTodo].values( todo->uid() ); 00369 QList<Incidence::Ptr>::const_iterator it; 00370 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00371 Todo::Ptr t = ( *it ).staticCast<Todo>(); 00372 if ( t->hasRecurrenceId() ) { 00373 list.append( t ); 00374 } 00375 } 00376 return Calendar::sortTodos( list, sortField, sortDirection ); 00377 } 00378 00379 Todo::List MemoryCalendar::rawTodosForDate( const QDate &date ) const 00380 { 00381 Todo::List todoList; 00382 Todo::Ptr t; 00383 00384 KDateTime::Spec ts = timeSpec(); 00385 const QString dateStr = date.toString(); 00386 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = 00387 d->mIncidencesForDate[Incidence::TypeTodo].constFind( dateStr ); 00388 while ( it != d->mIncidencesForDate[Incidence::TypeTodo].constEnd() && it.key() == dateStr ) { 00389 t = it.value().staticCast<Todo>(); 00390 todoList.append( t ); 00391 ++it; 00392 } 00393 00394 // Iterate over all todos. Look for recurring todoss that occur on this date 00395 QHashIterator<QString, Incidence::Ptr >i( d->mIncidences[Incidence::TypeTodo] ); 00396 while ( i.hasNext() ) { 00397 i.next(); 00398 t = i.value().staticCast<Todo>(); 00399 if ( t->recurs() ) { 00400 if ( t->recursOn( date, ts ) ) { 00401 todoList.append( t ); 00402 } 00403 } 00404 } 00405 00406 return todoList; 00407 } 00408 00409 Todo::List MemoryCalendar::rawTodos( const QDate &start, 00410 const QDate &end, 00411 const KDateTime::Spec ×pec, 00412 bool inclusive ) const 00413 { 00414 Q_UNUSED( inclusive ); // use only exact dtDue/dtStart, not dtStart and dtEnd 00415 00416 Todo::List todoList; 00417 KDateTime::Spec ts = timespec.isValid() ? timespec : timeSpec(); 00418 KDateTime st( start, ts ); 00419 KDateTime nd( end, ts ); 00420 00421 // Get todos 00422 QHashIterator<QString, Incidence::Ptr >i( d->mIncidences[Incidence::TypeTodo] ); 00423 Todo::Ptr todo; 00424 while ( i.hasNext() ) { 00425 i.next(); 00426 todo = i.value().staticCast<Todo>(); 00427 if ( !isVisible( todo ) ) { 00428 continue; 00429 } 00430 00431 KDateTime rStart = todo->hasDueDate() ? todo->dtDue() : 00432 todo->hasStartDate() ? todo->dtStart() : KDateTime(); 00433 if ( !rStart.isValid() ) { 00434 continue; 00435 } 00436 00437 if ( !todo->recurs() ) { // non-recurring todos 00438 if ( nd.isValid() && nd < rStart ) { 00439 continue; 00440 } 00441 if ( st.isValid() && rStart < st ) { 00442 continue; 00443 } 00444 } else { // recurring events 00445 switch( todo->recurrence()->duration() ) { 00446 case -1: // infinite 00447 break; 00448 case 0: // end date given 00449 default: // count given 00450 KDateTime rEnd( todo->recurrence()->endDate(), ts ); 00451 if ( !rEnd.isValid() ) { 00452 continue; 00453 } 00454 if ( st.isValid() && rEnd < st ) { 00455 continue; 00456 } 00457 break; 00458 } // switch(duration) 00459 } //if(recurs) 00460 00461 todoList.append( todo ); 00462 } 00463 00464 return todoList; 00465 } 00466 00467 Alarm::List MemoryCalendar::alarmsTo( const KDateTime &to ) const 00468 { 00469 return alarms( KDateTime( QDate( 1900, 1, 1 ) ), to ); 00470 } 00471 00472 Alarm::List MemoryCalendar::alarms( const KDateTime &from, const KDateTime &to ) const 00473 { 00474 Alarm::List alarmList; 00475 QHashIterator<QString, Incidence::Ptr>ie( d->mIncidences[Incidence::TypeEvent] ); 00476 Event::Ptr e; 00477 while ( ie.hasNext() ) { 00478 ie.next(); 00479 e = ie.value().staticCast<Event>(); 00480 if ( e->recurs() ) { 00481 appendRecurringAlarms( alarmList, e, from, to ); 00482 } else { 00483 appendAlarms( alarmList, e, from, to ); 00484 } 00485 } 00486 00487 QHashIterator<QString, Incidence::Ptr>it( d->mIncidences[Incidence::TypeTodo] ); 00488 Todo::Ptr t; 00489 while ( it.hasNext() ) { 00490 it.next(); 00491 t = it.value().staticCast<Todo>(); 00492 00493 if ( !t->isCompleted() ) { 00494 appendAlarms( alarmList, t, from, to ); 00495 if ( t->recurs() ) { 00496 appendRecurringAlarms( alarmList, t, from, to ); 00497 } else { 00498 appendAlarms( alarmList, t, from, to ); 00499 } 00500 } 00501 } 00502 00503 return alarmList; 00504 } 00505 00506 void MemoryCalendar::incidenceUpdate( const QString &uid, const KDateTime &recurrenceId ) 00507 { 00508 Incidence::Ptr inc = incidence( uid, recurrenceId ); 00509 00510 if ( inc ) { 00511 const Incidence::IncidenceType type = inc->type(); 00512 const KDateTime dt = inc->dateTime( Incidence::RoleCalendarHashing ); 00513 00514 if ( dt.isValid() ) { 00515 d->mIncidencesForDate[type].remove( dt.date().toString(), inc ); 00516 } 00517 } 00518 } 00519 00520 void MemoryCalendar::incidenceUpdated( const QString &uid, const KDateTime &recurrenceId ) 00521 { 00522 Incidence::Ptr inc = incidence( uid, recurrenceId ); 00523 00524 if ( inc ) { 00525 KDateTime nowUTC = KDateTime::currentUtcDateTime(); 00526 inc->setLastModified( nowUTC ); 00527 // we should probably update the revision number here, 00528 // or internally in the Event itself when certain things change. 00529 // need to verify with ical documentation. 00530 00531 const Incidence::IncidenceType type = inc->type(); 00532 const KDateTime dt = inc->dateTime( Incidence::RoleCalendarHashing ); 00533 00534 if ( dt.isValid() ) { 00535 d->mIncidencesForDate[type].insert( dt.date().toString(), inc ); 00536 } 00537 00538 notifyIncidenceChanged( inc ); 00539 00540 setModified( true ); 00541 } 00542 } 00543 00544 Event::List MemoryCalendar::rawEventsForDate( const QDate &date, 00545 const KDateTime::Spec ×pec, 00546 EventSortField sortField, 00547 SortDirection sortDirection ) const 00548 { 00549 Event::List eventList; 00550 Event::Ptr ev; 00551 00552 // Find the hash for the specified date 00553 const QString dateStr = date.toString(); 00554 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = 00555 d->mIncidencesForDate[Incidence::TypeEvent].constFind( dateStr ); 00556 // Iterate over all non-recurring, single-day events that start on this date 00557 KDateTime::Spec ts = timespec.isValid() ? timespec : timeSpec(); 00558 KDateTime kdt( date, ts ); 00559 while ( it != d->mIncidencesForDate[Incidence::TypeEvent].constEnd() && it.key() == dateStr ) { 00560 ev = it.value().staticCast<Event>(); 00561 KDateTime end( ev->dtEnd().toTimeSpec( ev->dtStart() ) ); 00562 if ( ev->allDay() ) { 00563 end.setDateOnly( true ); 00564 } else { 00565 end = end.addSecs( -1 ); 00566 } 00567 if ( end >= kdt ) { 00568 eventList.append( ev ); 00569 } 00570 ++it; 00571 } 00572 00573 // Iterate over all events. Look for recurring events that occur on this date 00574 QHashIterator<QString, Incidence::Ptr>i( d->mIncidences[Incidence::TypeEvent] ); 00575 while ( i.hasNext() ) { 00576 i.next(); 00577 ev = i.value().staticCast<Event>(); 00578 if ( ev->recurs() ) { 00579 if ( ev->isMultiDay() ) { 00580 int extraDays = ev->dtStart().date().daysTo( ev->dtEnd().date() ); 00581 for ( int i = 0; i <= extraDays; ++i ) { 00582 if ( ev->recursOn( date.addDays( -i ), ts ) ) { 00583 eventList.append( ev ); 00584 break; 00585 } 00586 } 00587 } else { 00588 if ( ev->recursOn( date, ts ) ) { 00589 eventList.append( ev ); 00590 } 00591 } 00592 } else { 00593 if ( ev->isMultiDay() ) { 00594 if ( ev->dtStart().date() <= date && ev->dtEnd().date() >= date ) { 00595 eventList.append( ev ); 00596 } 00597 } 00598 } 00599 } 00600 00601 return Calendar::sortEvents( eventList, sortField, sortDirection ); 00602 } 00603 00604 Event::List MemoryCalendar::rawEvents( const QDate &start, 00605 const QDate &end, 00606 const KDateTime::Spec ×pec, 00607 bool inclusive ) const 00608 { 00609 Event::List eventList; 00610 KDateTime::Spec ts = timespec.isValid() ? timespec : timeSpec(); 00611 KDateTime st( start, ts ); 00612 KDateTime nd( end, ts ); 00613 KDateTime yesterStart = st.addDays( -1 ); 00614 00615 // Get non-recurring events 00616 QHashIterator<QString, Incidence::Ptr>i( d->mIncidences[Incidence::TypeEvent] ); 00617 Event::Ptr event; 00618 while ( i.hasNext() ) { 00619 i.next(); 00620 event = i.value().staticCast<Event>(); 00621 KDateTime rStart = event->dtStart(); 00622 if ( nd < rStart ) { 00623 continue; 00624 } 00625 if ( inclusive && rStart < st ) { 00626 continue; 00627 } 00628 00629 if ( !event->recurs() ) { // non-recurring events 00630 KDateTime rEnd = event->dtEnd(); 00631 if ( rEnd < st ) { 00632 continue; 00633 } 00634 if ( inclusive && nd < rEnd ) { 00635 continue; 00636 } 00637 } else { // recurring events 00638 switch( event->recurrence()->duration() ) { 00639 case -1: // infinite 00640 if ( inclusive ) { 00641 continue; 00642 } 00643 break; 00644 case 0: // end date given 00645 default: // count given 00646 KDateTime rEnd( event->recurrence()->endDate(), ts ); 00647 if ( !rEnd.isValid() ) { 00648 continue; 00649 } 00650 if ( rEnd < st ) { 00651 continue; 00652 } 00653 if ( inclusive && nd < rEnd ) { 00654 continue; 00655 } 00656 break; 00657 } // switch(duration) 00658 } //if(recurs) 00659 00660 eventList.append( event ); 00661 } 00662 00663 return eventList; 00664 } 00665 00666 Event::List MemoryCalendar::rawEventsForDate( const KDateTime &kdt ) const 00667 { 00668 return rawEventsForDate( kdt.date(), kdt.timeSpec() ); 00669 } 00670 00671 Event::List MemoryCalendar::rawEvents( EventSortField sortField, 00672 SortDirection sortDirection ) const 00673 { 00674 Event::List eventList; 00675 QHashIterator<QString, Incidence::Ptr> i( d->mIncidences[Incidence::TypeEvent] ); 00676 while ( i.hasNext() ) { 00677 i.next(); 00678 eventList.append( i.value().staticCast<Event>() ); 00679 } 00680 return Calendar::sortEvents( eventList, sortField, sortDirection ); 00681 } 00682 00683 Event::List MemoryCalendar::deletedEvents( EventSortField sortField, 00684 SortDirection sortDirection ) const 00685 { 00686 Event::List eventList; 00687 QHashIterator<QString, Incidence::Ptr>i( d->mDeletedIncidences[Incidence::TypeEvent] ); 00688 while ( i.hasNext() ) { 00689 i.next(); 00690 eventList.append( i.value().staticCast<Event>() ); 00691 } 00692 return Calendar::sortEvents( eventList, sortField, sortDirection ); 00693 } 00694 00695 Event::List MemoryCalendar::eventInstances( const Incidence::Ptr &event, 00696 EventSortField sortField, 00697 SortDirection sortDirection ) const 00698 { 00699 Event::List list; 00700 00701 QList<Incidence::Ptr> values = d->mIncidences[Incidence::TypeEvent].values( event->uid() ); 00702 QList<Incidence::Ptr>::const_iterator it; 00703 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00704 Event::Ptr ev = ( *it ).staticCast<Event>(); 00705 if ( ev->hasRecurrenceId() ) { 00706 list.append( ev ); 00707 } 00708 } 00709 return Calendar::sortEvents( list, sortField, sortDirection ); 00710 } 00711 00712 bool MemoryCalendar::addJournal( const Journal::Ptr &journal ) 00713 { 00714 return addIncidence( journal ); 00715 } 00716 00717 bool MemoryCalendar::deleteJournal( const Journal::Ptr &journal ) 00718 { 00719 return deleteIncidence( journal ); 00720 } 00721 00722 bool MemoryCalendar::deleteJournalInstances( const Journal::Ptr &journal ) 00723 { 00724 return deleteIncidenceInstances( journal ); 00725 } 00726 00727 void MemoryCalendar::deleteAllJournals() 00728 { 00729 d->deleteAllIncidences( Incidence::TypeJournal ); 00730 } 00731 00732 Journal::Ptr MemoryCalendar::journal( const QString &uid, 00733 const KDateTime &recurrenceId ) const 00734 { 00735 return d->incidence( uid, Incidence::TypeJournal, recurrenceId ).staticCast<Journal>(); 00736 } 00737 00738 Journal::Ptr MemoryCalendar::deletedJournal( const QString &uid, 00739 const KDateTime &recurrenceId ) const 00740 { 00741 return d->deletedIncidence( uid, recurrenceId, Incidence::TypeJournal ).staticCast<Journal>(); 00742 } 00743 00744 Journal::List MemoryCalendar::rawJournals( JournalSortField sortField, 00745 SortDirection sortDirection ) const 00746 { 00747 Journal::List journalList; 00748 QHashIterator<QString, Incidence::Ptr>i( d->mIncidences[Incidence::TypeJournal] ); 00749 while ( i.hasNext() ) { 00750 i.next(); 00751 journalList.append( i.value().staticCast<Journal>() ); 00752 } 00753 return Calendar::sortJournals( journalList, sortField, sortDirection ); 00754 } 00755 00756 Journal::List MemoryCalendar::deletedJournals( JournalSortField sortField, 00757 SortDirection sortDirection ) const 00758 { 00759 Journal::List journalList; 00760 QHashIterator<QString, Incidence::Ptr>i( d->mDeletedIncidences[Incidence::TypeJournal] ); 00761 while ( i.hasNext() ) { 00762 i.next(); 00763 journalList.append( i.value().staticCast<Journal>() ); 00764 } 00765 return Calendar::sortJournals( journalList, sortField, sortDirection ); 00766 } 00767 00768 Journal::List MemoryCalendar::journalInstances( const Incidence::Ptr &journal, 00769 JournalSortField sortField, 00770 SortDirection sortDirection ) const 00771 { 00772 Journal::List list; 00773 00774 QList<Incidence::Ptr> values = d->mIncidences[Incidence::TypeJournal].values( journal->uid() ); 00775 QList<Incidence::Ptr>::const_iterator it; 00776 for ( it = values.constBegin(); it != values.constEnd(); ++it ) { 00777 Journal::Ptr j = ( *it ).staticCast<Journal>(); 00778 if ( j->hasRecurrenceId() ) { 00779 list.append( j ); 00780 } 00781 } 00782 return Calendar::sortJournals( list, sortField, sortDirection ); 00783 } 00784 00785 Journal::List MemoryCalendar::rawJournalsForDate( const QDate &date ) const 00786 { 00787 Journal::List journalList; 00788 Journal::Ptr j; 00789 00790 QString dateStr = date.toString(); 00791 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = 00792 d->mIncidencesForDate[Incidence::TypeJournal].constFind( dateStr ); 00793 00794 while ( it != d->mIncidencesForDate[Incidence::TypeJournal].constEnd() && it.key() == dateStr ) { 00795 j = it.value().staticCast<Journal>(); 00796 journalList.append( j ); 00797 ++it; 00798 } 00799 return journalList; 00800 } 00801 00802 void MemoryCalendar::virtual_hook( int id, void *data ) 00803 { 00804 Q_UNUSED( id ); 00805 Q_UNUSED( data ); 00806 Q_ASSERT( false ); 00807 }