00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <tqdatastream.h>
00027 #include <tqdatetime.h>
00028 #include <tqfile.h>
00029 #include <tqstring.h>
00030 #include <tqptrlist.h>
00031
00032 #include <kdebug.h>
00033 #include <tdelocale.h>
00034 #include <kurl.h>
00035 #include <kstandarddirs.h>
00036
00037 #include "event.h"
00038 #include "exceptions.h"
00039 #include "incidence.h"
00040 #include "journal.h"
00041 #include "todo.h"
00042 #include <unistd.h>
00043
00044
00045 #include "resourcecached.h"
00046
00047 using namespace KCal;
00048
00049 static bool m_editoropen = false;
00050
00051 ResourceCached::ResourceCached( const TDEConfig* config )
00052 : ResourceCalendar( config ), mCalendar( TQString::fromLatin1( "UTC" ) ),
00053 mReloadPolicy( ReloadNever ), mReloadInterval( 10 ),
00054 mReloadTimer( 0, "mReloadTimer" ), mReloaded( false ),
00055 mSavePolicy( SaveNever ), mSaveInterval( 10 ),
00056 mSaveTimer( 0, "mSaveTimer" ), mIdMapper( "kcal/uidmaps/" )
00057 {
00058 connect( &mReloadTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotReload() ) );
00059 connect( &mSaveTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotSave() ) );
00060 }
00061
00062 ResourceCached::~ResourceCached()
00063 {
00064 }
00065
00066 void ResourceCached::setReloadPolicy( int i )
00067 {
00068 mReloadPolicy = i;
00069
00070 setupReloadTimer();
00071 }
00072
00073 int ResourceCached::reloadPolicy() const
00074 {
00075 return mReloadPolicy;
00076 }
00077
00078 void ResourceCached::setReloadInterval( int minutes )
00079 {
00080 mReloadInterval = minutes;
00081 }
00082
00083 int ResourceCached::reloadInterval() const
00084 {
00085 return mReloadInterval;
00086 }
00087
00088 void ResourceCached::setSavePolicy( int i )
00089 {
00090 mSavePolicy = i;
00091
00092 setupSaveTimer();
00093 }
00094
00095 int ResourceCached::savePolicy() const
00096 {
00097 return mSavePolicy;
00098 }
00099
00100 void ResourceCached::setSaveInterval( int minutes )
00101 {
00102 mSaveInterval = minutes;
00103 }
00104
00105 int ResourceCached::saveInterval() const
00106 {
00107 return mSaveInterval;
00108 }
00109
00110 void ResourceCached::readConfig( const TDEConfig *config )
00111 {
00112 mReloadPolicy = config->readNumEntry( "ReloadPolicy", ReloadNever );
00113 mReloadInterval = config->readNumEntry( "ReloadInterval", 10 );
00114
00115 mSaveInterval = config->readNumEntry( "SaveInterval", 10 );
00116 mSavePolicy = config->readNumEntry( "SavePolicy", SaveNever );
00117
00118 mLastLoad = config->readDateTimeEntry( "LastLoad" );
00119 mLastSave = config->readDateTimeEntry( "LastSave" );
00120
00121 setupSaveTimer();
00122 setupReloadTimer();
00123 }
00124
00125 void ResourceCached::setupSaveTimer()
00126 {
00127 if ( mSavePolicy == SaveInterval ) {
00128 kdDebug(5800) << "ResourceCached::setSavePolicy(): start save timer (interval "
00129 << mSaveInterval << " minutes)." << endl;
00130 mSaveTimer.start( mSaveInterval * 60 * 1000 );
00131 } else {
00132 mSaveTimer.stop();
00133 }
00134 }
00135
00136 void ResourceCached::setupReloadTimer()
00137 {
00138 if ( mReloadPolicy == ReloadInterval ) {
00139 kdDebug(5800) << "ResourceCached::setSavePolicy(): start reload timer "
00140 "(interval " << mReloadInterval << " minutes)" << endl;
00141 mReloadTimer.start( mReloadInterval * 60 * 1000 );
00142 } else {
00143 mReloadTimer.stop();
00144 }
00145 }
00146
00147 void ResourceCached::writeConfig( TDEConfig *config )
00148 {
00149 config->writeEntry( "ReloadPolicy", mReloadPolicy );
00150 config->writeEntry( "ReloadInterval", mReloadInterval );
00151
00152 config->writeEntry( "SavePolicy", mSavePolicy );
00153 config->writeEntry( "SaveInterval", mSaveInterval );
00154
00155 config->writeEntry( "LastLoad", mLastLoad );
00156 config->writeEntry( "LastSave", mLastSave );
00157 }
00158
00159 bool ResourceCached::addEvent(Event *event)
00160 {
00161 return mCalendar.addEvent( event );
00162 }
00163
00164 bool ResourceCached::addEvent(Event *event, const TQString &subresource )
00165 {
00166 Q_UNUSED( subresource );
00167 return mCalendar.addEvent( event );
00168 }
00169
00170
00171 bool ResourceCached::deleteEvent( Event *event )
00172 {
00173 kdDebug(5800) << "ResourceCached::deleteEvent" << endl;
00174
00175 return mCalendar.deleteEvent( event );
00176 }
00177
00178
00179 Event *ResourceCached::event( const TQString &uid )
00180 {
00181 return mCalendar.event( uid );
00182 }
00183
00184 Event::List ResourceCached::rawEventsForDate( const TQDate &qd,
00185 EventSortField sortField,
00186 SortDirection sortDirection )
00187 {
00188 Event::List list = mCalendar.rawEventsForDate( qd, sortField, sortDirection );
00189
00190 return list;
00191 }
00192
00193 Event::List ResourceCached::rawEvents( const TQDate &start, const TQDate &end,
00194 bool inclusive )
00195 {
00196 return mCalendar.rawEvents( start, end, inclusive );
00197 }
00198
00199 Event::List ResourceCached::rawEventsForDate( const TQDateTime &qdt )
00200 {
00201 return mCalendar.rawEventsForDate( qdt.date() );
00202 }
00203
00204 Event::List ResourceCached::rawEvents( EventSortField sortField, SortDirection sortDirection )
00205 {
00206 return mCalendar.rawEvents( sortField, sortDirection );
00207 }
00208
00209 bool ResourceCached::addTodo( Todo *todo )
00210 {
00211 return mCalendar.addTodo( todo );
00212 }
00213
00214 bool ResourceCached::addTodo( Todo *todo, const TQString &subresource )
00215 {
00216 Q_UNUSED( subresource );
00217 return mCalendar.addTodo( todo );
00218 }
00219
00220 bool ResourceCached::deleteTodo( Todo *todo )
00221 {
00222 return mCalendar.deleteTodo( todo );
00223 }
00224
00225 bool ResourceCached::deleteJournal( Journal *journal )
00226 {
00227 return mCalendar.deleteJournal( journal );
00228 }
00229
00230
00231 Todo::List ResourceCached::rawTodos( TodoSortField sortField, SortDirection sortDirection )
00232 {
00233 return mCalendar.rawTodos( sortField, sortDirection );
00234 }
00235
00236 Todo *ResourceCached::todo( const TQString &uid )
00237 {
00238 return mCalendar.todo( uid );
00239 }
00240
00241 Todo::List ResourceCached::rawTodosForDate( const TQDate &date )
00242 {
00243 return mCalendar.rawTodosForDate( date );
00244 }
00245
00246 bool ResourceCached::addJournal( Journal *journal )
00247 {
00248 return mCalendar.addJournal( journal );
00249 }
00250
00251 bool ResourceCached::addJournal( Journal *journal, const TQString &subresource )
00252 {
00253 Q_UNUSED( subresource );
00254 return mCalendar.addJournal( journal );
00255 }
00256
00257 Journal *ResourceCached::journal( const TQString &uid )
00258 {
00259 return mCalendar.journal( uid );
00260 }
00261
00262 Journal::List ResourceCached::rawJournals( JournalSortField sortField, SortDirection sortDirection )
00263 {
00264 return mCalendar.rawJournals( sortField, sortDirection );
00265 }
00266
00267 Journal::List ResourceCached::rawJournalsForDate( const TQDate &date )
00268 {
00269 return mCalendar.rawJournalsForDate( date );
00270 }
00271
00272
00273 Alarm::List ResourceCached::alarmsTo( const TQDateTime &to )
00274 {
00275 return mCalendar.alarmsTo( to );
00276 }
00277
00278 Alarm::List ResourceCached::alarms( const TQDateTime &from, const TQDateTime &to )
00279 {
00280
00281 return mCalendar.alarms( from, to );
00282 }
00283
00284
00285 void ResourceCached::setTimeZoneId( const TQString& tzid )
00286 {
00287 mCalendar.setTimeZoneId( tzid );
00288 }
00289
00290 TQString ResourceCached::timeZoneId() const
00291 {
00292 return mCalendar.timeZoneId();
00293 }
00294
00295 void ResourceCached::clearChanges()
00296 {
00297 mAddedIncidences.clear();
00298 mChangedIncidences.clear();
00299 mDeletedIncidences.clear();
00300 }
00301
00302 void ResourceCached::loadCache()
00303 {
00304 setIdMapperIdentifier();
00305 mIdMapper.load();
00306
00307 if ( TDEStandardDirs::exists( cacheFile() ) ) {
00308 mCalendar.load( cacheFile() );
00309 if ( readOnly() ) {
00310 Incidence::List incidences( rawIncidences() );
00311 Incidence::List::Iterator it;
00312 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
00313 (*it)->setReadOnly( true );
00314 }
00315 }
00316 }
00317 }
00318
00319 void ResourceCached::saveCache()
00320 {
00321 kdDebug(5800) << "ResourceCached::saveCache(): " << cacheFile() << endl;
00322
00323 setIdMapperIdentifier();
00324 mIdMapper.save();
00325
00326 mCalendar.save( cacheFile() );
00327 }
00328
00329 void ResourceCached::setIdMapperIdentifier()
00330 {
00331 mIdMapper.setIdentifier( type() + "_" + identifier() );
00332 }
00333
00334 void ResourceCached::clearCache()
00335 {
00336 mCalendar.close();
00337 }
00338
00339 void ResourceCached::clearEventsCache()
00340 {
00341 mCalendar.closeEvents();
00342 }
00343
00344 void ResourceCached::clearTodosCache()
00345 {
00346 mCalendar.closeTodos();
00347 }
00348
00349 void ResourceCached::clearJournalsCache()
00350 {
00351 mCalendar.closeJournals();
00352 }
00353
00354 void ResourceCached::cleanUpEventCache( const Event::List &eventList )
00355 {
00356 CalendarLocal calendar ( TQString::fromLatin1( "UTC" ) );
00357
00358 if ( TDEStandardDirs::exists( cacheFile() ) )
00359 calendar.load( cacheFile() );
00360 else
00361 return;
00362
00363 Event::List list = calendar.events();
00364 Event::List::ConstIterator cacheIt, it;
00365 for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) {
00366 bool found = false;
00367 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
00368 if ( (*it)->uid() == (*cacheIt)->uid() )
00369 found = true;
00370 }
00371
00372 if ( !found ) {
00373 mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt)->uid() ) );
00374 Event *event = mCalendar.event( (*cacheIt)->uid() );
00375 if ( event )
00376 mCalendar.deleteEvent( event );
00377 }
00378 }
00379
00380 calendar.close();
00381 }
00382
00383 void ResourceCached::cleanUpTodoCache( const Todo::List &todoList )
00384 {
00385 CalendarLocal calendar ( TQString::fromLatin1( "UTC" ) );
00386
00387 if ( TDEStandardDirs::exists( cacheFile() ) )
00388 calendar.load( cacheFile() );
00389 else
00390 return;
00391
00392 Todo::List list = calendar.todos();
00393 Todo::List::ConstIterator cacheIt, it;
00394 for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) {
00395
00396 bool found = false;
00397 for ( it = todoList.begin(); it != todoList.end(); ++it ) {
00398 if ( (*it)->uid() == (*cacheIt)->uid() )
00399 found = true;
00400 }
00401
00402 if ( !found ) {
00403 mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt)->uid() ) );
00404 Todo *todo = mCalendar.todo( (*cacheIt)->uid() );
00405 if ( todo )
00406 mCalendar.deleteTodo( todo );
00407 }
00408 }
00409
00410 calendar.close();
00411 }
00412
00413 KPIM::IdMapper& ResourceCached::idMapper()
00414 {
00415 return mIdMapper;
00416 }
00417
00418 TQString ResourceCached::cacheFile() const
00419 {
00420 return locateLocal( "cache", "kcal/tderesources/" + identifier() );
00421 }
00422
00423 TQString ResourceCached::changesCacheFile( const TQString &type ) const
00424 {
00425 return locateLocal( "cache", "kcal/changescache/" + identifier() + "_" + type );
00426 }
00427
00428 void ResourceCached::saveChangesCache( const TQMap<Incidence*, bool> &map, const TQString &type )
00429 {
00430 CalendarLocal calendar ( TQString::fromLatin1( "UTC" ) );
00431
00432 bool isEmpty = true;
00433 TQMap<Incidence *,bool>::ConstIterator it;
00434 for ( it = map.begin(); it != map.end(); ++it ) {
00435 isEmpty = false;
00436 calendar.addIncidence( it.key()->clone() );
00437 }
00438
00439 if ( !isEmpty ) {
00440 calendar.save( changesCacheFile( type ) );
00441 } else {
00442 TQFile file( changesCacheFile( type ) );
00443 file.remove();
00444 }
00445
00446 calendar.close();
00447 }
00448
00449 void ResourceCached::saveChangesCache()
00450 {
00451 saveChangesCache( mAddedIncidences, "added" );
00452 saveChangesCache( mDeletedIncidences, "deleted" );
00453 saveChangesCache( mChangedIncidences, "changed" );
00454 }
00455
00456 void ResourceCached::loadChangesCache( TQMap<Incidence*, bool> &map, const TQString &type )
00457 {
00458 CalendarLocal calendar ( TQString::fromLatin1( "UTC" ) );
00459
00460 if ( TDEStandardDirs::exists( changesCacheFile( type ) ) )
00461 calendar.load( changesCacheFile( type ) );
00462 else
00463 return;
00464
00465 const Incidence::List list = calendar.incidences();
00466 Incidence::List::ConstIterator it;
00467 for ( it = list.begin(); it != list.end(); ++it )
00468 map.insert( (*it)->clone(), true );
00469
00470 calendar.close();
00471 }
00472
00473 void ResourceCached::loadChangesCache()
00474 {
00475 loadChangesCache( mAddedIncidences, "added" );
00476 loadChangesCache( mDeletedIncidences, "deleted" );
00477 loadChangesCache( mChangedIncidences, "changed" );
00478 }
00479
00480 void ResourceCached::calendarIncidenceAdded( Incidence *i )
00481 {
00482 #if 1
00483 kdDebug(5800) << "ResourceCached::calendarIncidenceAdded(): "
00484 << i->uid() << endl;
00485 #endif
00486
00487 TQMap<Incidence *,bool>::ConstIterator it;
00488 it = mAddedIncidences.find( i );
00489 if ( it == mAddedIncidences.end() ) {
00490 mAddedIncidences.insert( i, true );
00491 }
00492
00493 checkForAutomaticSave();
00494 }
00495
00496 void ResourceCached::calendarIncidenceChanged( Incidence *i )
00497 {
00498 #if 1
00499 kdDebug(5800) << "ResourceCached::calendarIncidenceChanged(): "
00500 << i->uid() << endl;
00501 #endif
00502
00503 TQMap<Incidence *,bool>::ConstIterator it;
00504 it = mChangedIncidences.find( i );
00505
00506 if ( it == mChangedIncidences.end() ) {
00507 mChangedIncidences.insert( i, true );
00508 }
00509
00510 checkForAutomaticSave();
00511 }
00512
00513 void ResourceCached::calendarIncidenceDeleted( Incidence *i )
00514 {
00515 #if 1
00516 kdDebug(5800) << "ResourceCached::calendarIncidenceDeleted(): "
00517 << i->uid() << endl;
00518 #endif
00519
00520 if (i->hasRecurrenceID()) {
00521
00522
00523 IncidenceList il = i->childIncidences();
00524 IncidenceListIterator it;
00525 it = il.begin();
00526 Incidence *parentIncidence;
00527 parentIncidence = this->incidence(*it);
00528
00529 calendarIncidenceChanged(parentIncidence);
00530 }
00531 else {
00532 TQMap<Incidence *,bool>::ConstIterator it;
00533 it = mDeletedIncidences.find( i );
00534 if ( it == mDeletedIncidences.end() ) {
00535 mDeletedIncidences.insert( i, true );
00536 }
00537 }
00538 checkForAutomaticSave();
00539 }
00540
00541 Incidence::List ResourceCached::addedIncidences() const
00542 {
00543 Incidence::List added;
00544 TQMap<Incidence *,bool>::ConstIterator it;
00545 for( it = mAddedIncidences.begin(); it != mAddedIncidences.end(); ++it ) {
00546 added.append( it.key() );
00547 }
00548 return added;
00549 }
00550
00551 Incidence::List ResourceCached::changedIncidences() const
00552 {
00553 Incidence::List changed;
00554 TQMap<Incidence *,bool>::ConstIterator it;
00555 for( it = mChangedIncidences.begin(); it != mChangedIncidences.end(); ++it ) {
00556 changed.append( it.key() );
00557 }
00558 return changed;
00559 }
00560
00561 Incidence::List ResourceCached::deletedIncidences() const
00562 {
00563 Incidence::List deleted;
00564 TQMap<Incidence *,bool>::ConstIterator it;
00565 for( it = mDeletedIncidences.begin(); it != mDeletedIncidences.end(); ++it ) {
00566 deleted.append( it.key() );
00567 }
00568 return deleted;
00569 }
00570
00571 Incidence::List ResourceCached::allChanges() const
00572 {
00573 Incidence::List changes;
00574 TQMap<Incidence *,bool>::ConstIterator it;
00575 for( it = mAddedIncidences.begin(); it != mAddedIncidences.end(); ++it ) {
00576 changes.append( it.key() );
00577 }
00578 for( it = mChangedIncidences.begin(); it != mChangedIncidences.end(); ++it ) {
00579 changes.append( it.key() );
00580 }
00581 for( it = mDeletedIncidences.begin(); it != mDeletedIncidences.end(); ++it ) {
00582 changes.append( it.key() );
00583 }
00584 return changes;
00585 }
00586
00587 bool ResourceCached::hasChanges() const
00588 {
00589 return !( mAddedIncidences.isEmpty() && mChangedIncidences.isEmpty() &&
00590 mDeletedIncidences.isEmpty() );
00591 }
00592
00593 void ResourceCached::clearChange( Incidence *incidence )
00594 {
00595 clearChange( incidence->uid() );
00596 }
00597
00598 void ResourceCached::clearChange( const TQString &uid )
00599 {
00600 TQMap<Incidence*, bool>::Iterator it;
00601
00602 for ( it = mAddedIncidences.begin(); it != mAddedIncidences.end(); ++it )
00603 if ( it.key()->uid() == uid ) {
00604 mAddedIncidences.remove( it );
00605 break;
00606 }
00607
00608 for ( it = mChangedIncidences.begin(); it != mChangedIncidences.end(); ++it )
00609 if ( it.key()->uid() == uid ) {
00610 mChangedIncidences.remove( it );
00611 break;
00612 }
00613
00614 for ( it = mDeletedIncidences.begin(); it != mDeletedIncidences.end(); ++it )
00615 if ( it.key()->uid() == uid ) {
00616 mDeletedIncidences.remove( it );
00617 break;
00618 }
00619 }
00620
00621 void ResourceCached::enableChangeNotification()
00622 {
00623 mCalendar.registerObserver( this );
00624 }
00625
00626 void ResourceCached::disableChangeNotification()
00627 {
00628 mCalendar.unregisterObserver( this );
00629 }
00630
00631 bool ResourceCached::editorWindowOpen()
00632 {
00633 return m_editoropen;
00634 }
00635
00636 void ResourceCached::setEditorWindowOpen(bool open)
00637 {
00638 m_editoropen = open;
00639 }
00640
00641 void ResourceCached::slotReload()
00642 {
00643 if ( !isActive() ) return;
00644
00645
00646 if (editorWindowOpen() == true) return;
00647
00648 kdDebug(5800) << "ResourceCached::slotReload()" << endl;
00649
00650 load();
00651 }
00652
00653 void ResourceCached::slotSave()
00654 {
00655 if ( !isActive() ) return;
00656
00657 kdDebug(5800) << "ResourceCached::slotSave()" << endl;
00658
00659 save();
00660 }
00661
00662 void ResourceCached::checkForAutomaticSave()
00663 {
00664 if ( mSavePolicy == SaveAlways ) {
00665 kdDebug(5800) << "ResourceCached::checkForAutomaticSave(): save now" << endl;
00666 mSaveTimer.start( 1 * 1000, true );
00667 } else if ( mSavePolicy == SaveDelayed ) {
00668 kdDebug(5800) << "ResourceCached::checkForAutomaticSave(): save delayed"
00669 << endl;
00670 mSaveTimer.start( 15 * 1000, true );
00671 }
00672 }
00673
00674 bool ResourceCached::checkForReload()
00675 {
00676 if ( mReloadPolicy == ReloadNever ) return false;
00677 if ( mReloadPolicy == ReloadOnStartup ) return !mReloaded;
00678 return true;
00679 }
00680
00681 bool ResourceCached::checkForSave()
00682 {
00683 if ( mSavePolicy == SaveNever ) return false;
00684 return true;
00685 }
00686
00687 void ResourceCached::addInfoText( TQString &txt ) const
00688 {
00689 if ( mLastLoad.isValid() ) {
00690 txt += "<br>";
00691 txt += i18n("Last loaded: %1")
00692 .arg( TDEGlobal::locale()->formatDateTime( mLastLoad ) );
00693 }
00694 if ( mLastSave.isValid() ) {
00695 txt += "<br>";
00696 txt += i18n("Last saved: %1")
00697 .arg( TDEGlobal::locale()->formatDateTime( mLastSave ) );
00698 }
00699 }
00700
00701 void ResourceCached::doClose()
00702 {
00703 mCalendar.close();
00704 }
00705
00706 bool ResourceCached::doOpen()
00707 {
00708 kdDebug(5800) << "Opening resource " << resourceName() << endl;
00709 return true;
00710 }
00711
00712 void KCal::ResourceCached::setOwner( const Person &owner )
00713 {
00714 mCalendar.setOwner( owner );
00715 }
00716
00717 const Person & KCal::ResourceCached::getOwner() const
00718 {
00719 return mCalendar.getOwner();
00720 }
00721
00722 #include "resourcecached.moc"