libkcal

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 <klocale.h>
00030 #include <kmessagebox.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 }