calendarlocal.cpp
00001 /* 00002 This file is part of libkcal. 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 */ 00023 00024 #include <tqdatetime.h> 00025 #include <tqstring.h> 00026 #include <tqptrlist.h> 00027 00028 #include <kdebug.h> 00029 #include <tdelocale.h> 00030 #include <tdemessagebox.h> 00031 00032 #include "vcaldrag.h" 00033 #include "vcalformat.h" 00034 #include "icalformat.h" 00035 #include "exceptions.h" 00036 #include "incidence.h" 00037 #include "journal.h" 00038 #include "filestorage.h" 00039 00040 #include "calendarlocal.h" 00041 00042 using namespace KCal; 00043 00044 CalendarLocal::CalendarLocal( const TQString &timeZoneId ) 00045 : Calendar( timeZoneId ), mEvents( 47 ) 00046 { 00047 init(); 00048 } 00049 00050 void CalendarLocal::init() 00051 { 00052 mDeletedIncidences.setAutoDelete( true ); 00053 mFileName = TQString(); 00054 } 00055 00056 00057 CalendarLocal::~CalendarLocal() 00058 { 00059 close(); 00060 } 00061 00062 bool CalendarLocal::load( const TQString &fileName, CalFormat *format ) 00063 { 00064 mFileName = fileName; 00065 FileStorage storage( this, fileName, format ); 00066 return storage.load(); 00067 } 00068 00069 bool CalendarLocal::reload( const TQString &tz ) 00070 { 00071 const TQString filename = mFileName; 00072 save(); 00073 close(); 00074 mFileName = filename; 00075 setTimeZoneId( tz ); 00076 FileStorage storage( this, mFileName ); 00077 return storage.load(); 00078 } 00079 00080 bool CalendarLocal::save( const TQString &fileName, CalFormat *format ) 00081 { 00082 // Save only if the calendar is either modified, or saved to a 00083 // different file than it was loaded from 00084 if ( mFileName != fileName || isModified() ) { 00085 FileStorage storage( this, fileName, format ); 00086 return storage.save(); 00087 } else { 00088 return true; 00089 } 00090 } 00091 00092 void CalendarLocal::close() 00093 { 00094 setObserversEnabled( false ); 00095 mFileName = TQString(); 00096 00097 deleteAllEvents(); 00098 deleteAllTodos(); 00099 deleteAllJournals(); 00100 00101 mDeletedIncidences.clear(); 00102 setModified( false ); 00103 00104 setObserversEnabled( true ); 00105 } 00106 00107 void CalendarLocal::closeEvents() 00108 { 00109 setObserversEnabled( false ); 00110 mFileName = TQString(); 00111 00112 deleteAllEvents(); 00113 00114 mDeletedIncidences.clear(); 00115 setModified( false ); 00116 00117 setObserversEnabled( true ); 00118 } 00119 00120 void CalendarLocal::closeTodos() 00121 { 00122 setObserversEnabled( false ); 00123 mFileName = TQString(); 00124 00125 deleteAllTodos(); 00126 00127 mDeletedIncidences.clear(); 00128 setModified( false ); 00129 00130 setObserversEnabled( true ); 00131 } 00132 00133 void CalendarLocal::closeJournals() 00134 { 00135 setObserversEnabled( false ); 00136 mFileName = TQString(); 00137 00138 deleteAllJournals(); 00139 00140 mDeletedIncidences.clear(); 00141 setModified( false ); 00142 00143 setObserversEnabled( true ); 00144 } 00145 00146 00147 bool CalendarLocal::addEvent( Event *event ) 00148 { 00149 insertEvent( event ); 00150 00151 event->registerObserver( this ); 00152 00153 setModified( true ); 00154 00155 notifyIncidenceAdded( event ); 00156 00157 return true; 00158 } 00159 00160 bool CalendarLocal::deleteEvent( Event *event ) 00161 { 00162 // kdDebug(5800) << "CalendarLocal::deleteEvent" << endl; 00163 00164 if ( mEvents.remove( event->uid() ) ) { 00165 setModified( true ); 00166 notifyIncidenceDeleted( event ); 00167 mDeletedIncidences.append( event ); 00168 // Delete child events 00169 if (!event->hasRecurrenceID()) { 00170 deleteChildEvents(event); 00171 } 00172 return true; 00173 } else { 00174 kdWarning() << "CalendarLocal::deleteEvent(): Event not found." << endl; 00175 return false; 00176 } 00177 } 00178 00179 bool CalendarLocal::deleteChildEvents( Event *event ) 00180 { 00181 EventDictIterator it( mEvents ); 00182 for( ; it.current(); ++it ) { 00183 Event *e = *it; 00184 if (e->uid() == event->uid()) { 00185 if ( e->hasRecurrenceID() ) { 00186 deleteEvent(( e )); 00187 } 00188 } 00189 } 00190 00191 return true; 00192 } 00193 00194 void CalendarLocal::deleteAllEvents() 00195 { 00196 // kdDebug(5800) << "CalendarLocal::deleteAllEvents" << endl; 00197 TQDictIterator<Event> it( mEvents ); 00198 while( it.current() ) { 00199 notifyIncidenceDeleted( it.current() ); 00200 ++it; 00201 } 00202 00203 mEvents.setAutoDelete( true ); 00204 mEvents.clear(); 00205 mEvents.setAutoDelete( false ); 00206 } 00207 00208 Event *CalendarLocal::event( const TQString &uid ) 00209 { 00210 // kdDebug(5800) << "CalendarLocal::event(): " << uid << endl; 00211 return mEvents[ uid ]; 00212 } 00213 00214 bool CalendarLocal::addTodo( Todo *todo ) 00215 { 00216 mTodoList.append( todo ); 00217 00218 todo->registerObserver( this ); 00219 00220 // Set up subtask relations 00221 setupRelations( todo ); 00222 00223 setModified( true ); 00224 00225 notifyIncidenceAdded( todo ); 00226 00227 return true; 00228 } 00229 00230 bool CalendarLocal::deleteTodo( Todo *todo ) 00231 { 00232 // Handle orphaned children 00233 removeRelations( todo ); 00234 00235 if ( mTodoList.removeRef( todo ) ) { 00236 setModified( true ); 00237 notifyIncidenceDeleted( todo ); 00238 mDeletedIncidences.append( todo ); 00239 // Delete child todos 00240 if (!todo->hasRecurrenceID()) { 00241 deleteChildTodos(todo); 00242 } 00243 return true; 00244 } else { 00245 kdWarning() << "CalendarLocal::deleteTodo(): Todo not found." << endl; 00246 return false; 00247 } 00248 } 00249 00250 bool CalendarLocal::deleteChildTodos( Todo *todo ) 00251 { 00252 Todo::List::ConstIterator it; 00253 for( it = mTodoList.begin(); it != mTodoList.end(); ++it ) { 00254 Todo *t = *it; 00255 if (t->uid() == todo->uid()) { 00256 if ( t->hasRecurrenceID() ) { 00257 deleteTodo(( t )); 00258 } 00259 } 00260 } 00261 00262 return true; 00263 } 00264 00265 void CalendarLocal::deleteAllTodos() 00266 { 00267 // kdDebug(5800) << "CalendarLocal::deleteAllTodos()\n"; 00268 Todo::List::ConstIterator it; 00269 for( it = mTodoList.begin(); it != mTodoList.end(); ++it ) { 00270 notifyIncidenceDeleted( *it ); 00271 } 00272 00273 mTodoList.setAutoDelete( true ); 00274 mTodoList.clearAll(); 00275 mTodoList.setAutoDelete( false ); 00276 } 00277 00278 Todo::List CalendarLocal::rawTodos( TodoSortField sortField, 00279 SortDirection sortDirection ) 00280 { 00281 return sortTodos( &mTodoList, sortField, sortDirection ); 00282 } 00283 00284 Todo *CalendarLocal::todo( const TQString &uid ) 00285 { 00286 Todo::List::ConstIterator it; 00287 for ( it = mTodoList.begin(); it != mTodoList.end(); ++it ) { 00288 if ( (*it)->uid() == uid ) return *it; 00289 } 00290 00291 return 0; 00292 } 00293 00294 Todo::List CalendarLocal::rawTodosForDate( const TQDate &date ) 00295 { 00296 Todo::List todos; 00297 00298 Todo::List::ConstIterator it; 00299 for ( it = mTodoList.begin(); it != mTodoList.end(); ++it ) { 00300 Todo *todo = *it; 00301 if ( todo->hasDueDate() && todo->dtDue().date() == date ) { 00302 todos.append( todo ); 00303 } 00304 } 00305 00306 return todos; 00307 } 00308 00309 Alarm::List CalendarLocal::alarmsTo( const TQDateTime &to ) 00310 { 00311 return alarms( TQDateTime( TQDate( 1900, 1, 1 ) ), to ); 00312 } 00313 00314 Alarm::List CalendarLocal::alarms( const TQDateTime &from, const TQDateTime &to ) 00315 { 00316 // kdDebug(5800) << "CalendarLocal::alarms(" << from.toString() << " - " 00317 // << to.toString() << ")" << endl; 00318 00319 Alarm::List alarms; 00320 00321 EventDictIterator it( mEvents ); 00322 for( ; it.current(); ++it ) { 00323 Event *e = *it; 00324 if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to ); 00325 else appendAlarms( alarms, e, from, to ); 00326 } 00327 00328 Todo::List::ConstIterator it2; 00329 for( it2 = mTodoList.begin(); it2 != mTodoList.end(); ++it2 ) { 00330 Todo *t = *it2; 00331 if ( t->isCompleted() ) { 00332 continue; 00333 } 00334 if ( t->doesRecur() ) appendRecurringAlarms( alarms, t, from, to ); 00335 else appendAlarms( alarms, t, from, to ); 00336 } 00337 00338 return alarms; 00339 } 00340 00341 void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence, 00342 const TQDateTime &from, const TQDateTime &to ) 00343 { 00344 TQDateTime preTime = from.addSecs(-1); 00345 Alarm::List::ConstIterator it; 00346 for( it = incidence->alarms().begin(); it != incidence->alarms().end(); 00347 ++it ) { 00348 Alarm *alarm = *it; 00349 if ( alarm->enabled() ) { 00350 TQDateTime dt = alarm->nextRepetition( preTime ); 00351 if ( dt.isValid() && dt <= to ) { 00352 kdDebug(5800) << "CalendarLocal::appendAlarms() '" 00353 << incidence->summary() << "': " 00354 << dt.toString() << endl; 00355 alarms.append( alarm ); 00356 } 00357 } 00358 } 00359 } 00360 00361 void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms, 00362 Incidence *incidence, 00363 const TQDateTime &from, 00364 const TQDateTime &to ) 00365 { 00366 TQDateTime dt; 00367 Duration endOffset( 0 ); 00368 bool endOffsetValid = false; 00369 Duration period( from, to ); 00370 00371 Event *e = static_cast<Event *>( incidence ); 00372 Todo *t = static_cast<Todo *>( incidence ); 00373 00374 Alarm::List::ConstIterator it; 00375 for( it = incidence->alarms().begin(); it != incidence->alarms().end(); 00376 ++it ) { 00377 Alarm *alarm = *it; 00378 if ( alarm->enabled() ) { 00379 if ( alarm->hasTime() ) { 00380 // The alarm time is defined as an absolute date/time 00381 dt = alarm->nextRepetition( from.addSecs(-1) ); 00382 if ( !dt.isValid() || dt > to ) { 00383 continue; 00384 } 00385 } else { 00386 // Alarm time is defined by an offset from the event start or end time. 00387 // Find the offset from the event start time, which is also used as the 00388 // offset from the recurrence time. 00389 Duration offset( 0 ); 00390 if ( alarm->hasStartOffset() ) { 00391 offset = alarm->startOffset().asSeconds(); 00392 } else if ( alarm->hasEndOffset() ) { 00393 offset = alarm->endOffset().asSeconds(); 00394 if ( !endOffsetValid ) { 00395 if ( incidence->type() == "Event" ) { 00396 endOffset = Duration( e->dtStart(), e->dtEnd() ); 00397 endOffsetValid = true; 00398 } else if ( incidence->type() == "Todo" && 00399 t->hasStartDate() && t->hasDueDate() ) { 00400 endOffset = Duration( t->dtStart(), t->dtDue() ); 00401 endOffsetValid = true; 00402 } 00403 } 00404 } 00405 00406 // Find the incidence's earliest alarm 00407 TQDateTime alarmStart; 00408 if ( incidence->type() == "Event" ) { 00409 alarmStart = 00410 offset.end( alarm->hasEndOffset() ? e->dtEnd() : e->dtStart() ); 00411 } else if ( incidence->type() == "Todo" ) { 00412 alarmStart = 00413 offset.end( alarm->hasEndOffset() ? t->dtDue() : t->dtStart() ); 00414 } 00415 00416 if ( alarmStart.isValid() && alarmStart > to ) { 00417 continue; 00418 } 00419 00420 TQDateTime baseStart; 00421 if ( incidence->type() == "Event" ) { 00422 baseStart = e->dtStart(); 00423 } else if ( incidence->type() == "Todo" ) { 00424 baseStart = t->dtDue(); 00425 } 00426 if ( alarmStart.isValid() && from > alarmStart ) { 00427 alarmStart = from; // don't look earlier than the earliest alarm 00428 baseStart = (-offset).end( (-endOffset).end( alarmStart ) ); 00429 } 00430 00431 // Adjust the 'alarmStart' date/time and find the next recurrence 00432 // at or after it. Treat the two offsets separately in case one 00433 // is daily and the other not. 00434 dt = incidence->recurrence()->getNextDateTime( baseStart.addSecs(-1) ); 00435 if ( !dt.isValid() || 00436 ( dt = endOffset.end( offset.end( dt ) ) ) > to ) // adjust 'dt' to get the alarm time 00437 { 00438 // The next recurrence is too late. 00439 if ( !alarm->repeatCount() ) { 00440 continue; 00441 } 00442 00443 // The alarm has repetitions, so check whether repetitions of 00444 // previous recurrences fall within the time period. 00445 bool found = false; 00446 Duration alarmDuration = alarm->duration(); 00447 for ( TQDateTime base = baseStart; 00448 ( dt = incidence->recurrence()->getPreviousDateTime( base ) ).isValid(); 00449 base = dt ) { 00450 if ( alarm->duration().end( dt ) < base ) { 00451 break; // recurrence's last repetition is too early, so give up 00452 } 00453 00454 // The last repetition of this recurrence is on or after 00455 // 'alarmStart' time. Check if a repetition occurs between 00456 // 'alarmStart' and 'to'. 00457 int snooze = alarm->snoozeTime().value(); // in seconds or days 00458 if ( alarm->snoozeTime().isDaily() ) { 00459 Duration toFromDuration( dt, base ); 00460 int toFrom = toFromDuration.asDays(); 00461 if ( alarm->snoozeTime().end( from ) <= to || 00462 ( toFromDuration.isDaily() && toFrom % snooze == 0 ) || 00463 ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asDays() ) { 00464 found = true; 00465 #ifndef NDEBUG 00466 // for debug output 00467 dt = offset.end( dt ).addDays( ( ( toFrom - 1 ) / snooze + 1 ) * snooze ); 00468 #endif 00469 break; 00470 } 00471 } else { 00472 int toFrom = dt.secsTo( base ); 00473 if ( period.asSeconds() >= snooze || 00474 toFrom % snooze == 0 || 00475 ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asSeconds() ) 00476 { 00477 found = true; 00478 #ifndef NDEBUG 00479 // for debug output 00480 dt = offset.end( dt ).addSecs( ( ( toFrom - 1 ) / snooze + 1 ) * snooze ); 00481 #endif 00482 break; 00483 } 00484 } 00485 } 00486 if ( !found ) { 00487 continue; 00488 } 00489 } 00490 } 00491 kdDebug(5800) << "CalendarLocal::appendAlarms() '" << incidence->summary() 00492 << "': " << dt.toString() << endl; 00493 alarms.append( alarm ); 00494 } 00495 } 00496 } 00497 00498 00499 void CalendarLocal::incidenceUpdated( IncidenceBase *incidence ) 00500 { 00501 incidence->setSyncStatusSilent( Event::SYNCMOD ); 00502 incidence->setLastModified( TQDateTime::currentDateTime() ); 00503 // we should probably update the revision number here, 00504 // or internally in the Event itself when certain things change. 00505 // need to verify with ical documentation. 00506 00507 // The static_cast is ok as the CalendarLocal only observes Incidence objects 00508 notifyIncidenceChanged( static_cast<Incidence *>( incidence ) ); 00509 00510 setModified( true ); 00511 } 00512 00513 void CalendarLocal::insertEvent( Event *event ) 00514 { 00515 TQString uid = event->uid(); 00516 if ( mEvents[ uid ] == 0 ) { 00517 mEvents.insert( uid, event ); 00518 } 00519 #ifndef NDEBUG 00520 else // if we already have an event with this UID, it has to be the same event, 00521 // otherwise something's really broken 00522 Q_ASSERT( mEvents[uid] == event ); 00523 #endif 00524 } 00525 00526 Event::List CalendarLocal::rawEventsForDate( const TQDate &qd, 00527 EventSortField sortField, 00528 SortDirection sortDirection ) 00529 { 00530 Event::List eventList; 00531 00532 EventDictIterator it( mEvents ); 00533 for( ; it.current(); ++it ) { 00534 Event *event = *it; 00535 00536 if ( event->doesRecur() ) { 00537 if ( event->isMultiDay() ) { 00538 int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() ); 00539 int i; 00540 for ( i = 0; i <= extraDays; i++ ) { 00541 if ( event->recursOn( qd.addDays( -i ), this ) ) { 00542 eventList.append( event ); 00543 break; 00544 } 00545 } 00546 } else { 00547 if ( event->recursOn( qd, this ) ) 00548 eventList.append( event ); 00549 } 00550 } else { 00551 if ( event->dtStart().date() <= qd && event->dateEnd() >= qd ) { 00552 eventList.append( event ); 00553 } 00554 } 00555 } 00556 00557 return sortEventsForDate( &eventList, qd, sortField, sortDirection ); 00558 } 00559 00560 Event::List CalendarLocal::rawEvents( const TQDate &start, const TQDate &end, 00561 bool inclusive ) 00562 { 00563 Event::List eventList; 00564 TQDate yesterStart = start.addDays(-1); 00565 00566 // Get non-recurring events 00567 EventDictIterator it( mEvents ); 00568 for( ; it.current(); ++it ) { 00569 Event *event = *it; 00570 00571 TQDate rStart = event->dtStart().date(); 00572 if (end < rStart) { 00573 // kdDebug(5800) << "Skipping event starting after TOI" << endl; 00574 continue; 00575 } 00576 if ( inclusive && rStart < start) { 00577 // kdDebug(5800) << "Skipping event starting before TOI while inclusive" << endl; 00578 continue; 00579 } 00580 00581 if ( ! event->doesRecur() ) { // non-recurring events 00582 TQDate rEnd = event->dtEnd().date(); 00583 if (rEnd < start) { 00584 // kdDebug(5800) << "Skipping event ending before TOI" << endl; 00585 continue; 00586 } 00587 if ( inclusive && end < rEnd ) { 00588 // kdDebug(5800) << "Skipping event ending after TOI while inclusive" << endl; 00589 continue; 00590 } 00591 } else { // recurring events 00592 switch ( event->recurrence()->duration() ) { 00593 case -1: // infinite 00594 if ( inclusive ) { 00595 // kdDebug(5800) << "Skipping infinite event because inclusive" << endl; 00596 continue; 00597 } 00598 break; 00599 case 0: // end date given 00600 default: // count given 00601 TQDate rEnd = event->recurrence()->endDate(); 00602 if ( ! rEnd.isValid() ) { 00603 // kdDebug(5800) << "Skipping recurring event without occurences" << endl; 00604 continue; 00605 } 00606 if ( rEnd < start ) { 00607 // kdDebug(5800) << "Skipping recurring event ending before TOI" << endl; 00608 continue; 00609 } 00610 if ( inclusive && end < rEnd ) { 00611 // kdDebug(5800) << "Skipping recurring event ending after TOI while inclusive" << endl; 00612 continue; 00613 } 00614 /* FIXME: too much conversion between TQDate and TQDateTime makes this useless: 00615 * freebusy(end=TQDateTime(day, "00:00:00")) -> 00616 * rawEvents(end=TQDate(day)) -> 00617 * durationTo(TQDateTime(day, "23:59:59")) 00618 * so events repeating at the end day match and are included. 00619 */ 00620 #if 0 00621 int durationBeforeStart = event->recurrence()->durationTo(yesterStart); 00622 int durationUntilEnd = event->recurrence()->durationTo(end); 00623 if (durationBeforeStart == durationUntilEnd) { 00624 kdDebug(5800) << "Skipping recurring event without occurences in TOI" << endl; 00625 continue; 00626 } 00627 #endif 00628 break; 00629 } // switch(duration) 00630 } // if(doesRecur) 00631 00632 eventList.append( event ); 00633 } 00634 00635 return eventList; 00636 } 00637 00638 Event::List CalendarLocal::rawEventsForDate( const TQDateTime &qdt ) 00639 { 00640 return rawEventsForDate( qdt.date() ); 00641 } 00642 00643 Event::List CalendarLocal::rawEvents( EventSortField sortField, SortDirection sortDirection ) 00644 { 00645 Event::List eventList; 00646 EventDictIterator it( mEvents ); 00647 for( ; it.current(); ++it ) 00648 eventList.append( *it ); 00649 return sortEvents( &eventList, sortField, sortDirection ); 00650 } 00651 00652 bool CalendarLocal::addJournal(Journal *journal) 00653 { 00654 // if (journal->dtStart().isValid()) 00655 // kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl; 00656 // else 00657 // kdDebug(5800) << "Adding Journal without a DTSTART" << endl; 00658 00659 mJournalList.append(journal); 00660 00661 journal->registerObserver( this ); 00662 00663 setModified( true ); 00664 00665 notifyIncidenceAdded( journal ); 00666 00667 return true; 00668 } 00669 00670 bool CalendarLocal::deleteJournal( Journal *journal ) 00671 { 00672 if ( mJournalList.removeRef( journal ) ) { 00673 setModified( true ); 00674 notifyIncidenceDeleted( journal ); 00675 mDeletedIncidences.append( journal ); 00676 // Delete child journals 00677 if (!journal->hasRecurrenceID()) { 00678 deleteChildJournals(journal); 00679 } 00680 return true; 00681 } else { 00682 kdWarning() << "CalendarLocal::deleteJournal(): Journal not found." << endl; 00683 return false; 00684 } 00685 } 00686 00687 bool CalendarLocal::deleteChildJournals( Journal *journal ) 00688 { 00689 Journal::List::ConstIterator it; 00690 for( it = mJournalList.begin(); it != mJournalList.end(); ++it ) { 00691 Journal *j = *it; 00692 if (j->uid() == journal->uid()) { 00693 if ( j->hasRecurrenceID() ) { 00694 deleteJournal(( j )); 00695 } 00696 } 00697 } 00698 00699 return true; 00700 } 00701 00702 void CalendarLocal::deleteAllJournals() 00703 { 00704 Journal::List::ConstIterator it; 00705 for( it = mJournalList.begin(); it != mJournalList.end(); ++it ) { 00706 notifyIncidenceDeleted( *it ); 00707 } 00708 00709 mJournalList.setAutoDelete( true ); 00710 mJournalList.clearAll(); 00711 mJournalList.setAutoDelete( false ); 00712 } 00713 00714 Journal *CalendarLocal::journal( const TQString &uid ) 00715 { 00716 Journal::List::ConstIterator it; 00717 for ( it = mJournalList.begin(); it != mJournalList.end(); ++it ) 00718 if ( (*it)->uid() == uid ) 00719 return *it; 00720 00721 return 0; 00722 } 00723 00724 Journal::List CalendarLocal::rawJournals( JournalSortField sortField, SortDirection sortDirection ) 00725 { 00726 return sortJournals( &mJournalList, sortField, sortDirection ); 00727 } 00728 00729 Journal::List CalendarLocal::rawJournalsForDate( const TQDate &date ) 00730 { 00731 Journal::List journals; 00732 00733 Journal::List::ConstIterator it; 00734 for ( it = mJournalList.begin(); it != mJournalList.end(); ++it ) { 00735 Journal *journal = *it; 00736 if ( journal->dtStart().date() == date ) { 00737 journals.append( journal ); 00738 } 00739 } 00740 00741 return journals; 00742 } 00743 00744 void CalendarLocal::setTimeZoneIdViewOnly( const TQString& tz ) 00745 { 00746 const TQString question( i18n("The timezone setting was changed. In order to display the calendar " 00747 "you are looking at in the new timezone, it needs to be saved. Do you want to save the pending " 00748 "changes or rather wait and apply the new timezone on the next reload?" ) ); 00749 int rc = KMessageBox::Yes; 00750 if ( isModified() ) { 00751 rc = KMessageBox::questionYesNo( 0, question, 00752 i18n("Save before applying timezones?"), 00753 KStdGuiItem::save(), 00754 KGuiItem(i18n("Apply Timezone Change on Next Reload")), 00755 "calendarLocalSaveBeforeTimezoneShift"); 00756 } 00757 if ( rc == KMessageBox::Yes ) { 00758 reload( tz ); 00759 } 00760 }