23 #include "resourcecached.h"
33 #include <kconfiggroup.h>
35 #include <klocalizedstring.h>
36 #include <kstandarddirs.h>
39 #include <QtCore/QDateTime>
40 #include <QtCore/QDataStream>
41 #include <QtCore/QFile>
42 #include <QtCore/QString>
43 #include <QtCore/QTimer>
49 class ResourceCached::Private
53 : mCalendar( QLatin1String(
"UTC" ) ),
55 mReloadInterval( 10 ),
56 mInhibitReload( false ),
58 mSavePending( false ),
61 mIdMapper(
"kcal/uidmaps/" )
80 QMap<KCal::Incidence *,bool> mAddedIncidences;
81 QMap<KCal::Incidence *,bool> mChangedIncidences;
82 QMap<KCal::Incidence *,bool> mDeletedIncidences;
88 ResourceCached::ResourceCached()
92 connect( &d->mReloadTimer, SIGNAL(timeout()), SLOT(slotReload()) );
93 connect( &d->mSaveTimer, SIGNAL(timeout()), SLOT(slotSave()) );
96 ResourceCached::ResourceCached(
const KConfigGroup &group )
100 connect( &d->mReloadTimer, SIGNAL(timeout()), SLOT(slotReload()) );
101 connect( &d->mSaveTimer, SIGNAL(timeout()), SLOT(slotSave()) );
104 ResourceCached::~ResourceCached()
111 return &d->mCalendar;
114 bool ResourceCached::defaultReloadInhibited()
const
116 return d->mInhibitReload;
131 d->mReloadPolicy = i;
138 return d->mReloadPolicy;
143 d->mReloadInterval = minutes;
148 return d->mReloadInterval;
153 if ( inhibit == d->mInhibitReload ) {
156 d->mInhibitReload = inhibit;
169 return d->mSavePolicy;
174 d->mSaveInterval = minutes;
179 return d->mSaveInterval;
182 void ResourceCached::readConfig(
const KConfigGroup &group )
184 d->mReloadPolicy = group.readEntry(
"ReloadPolicy",
int(ReloadNever) );
185 d->mReloadInterval = group.readEntry(
"ReloadInterval", 10 );
187 d->mSaveInterval = group.readEntry(
"SaveInterval", 10 );
188 d->mSavePolicy = group.readEntry(
"SavePolicy",
int(SaveNever) );
190 QDateTime curDt = QDateTime::currentDateTime();
191 QDateTime dt = group.readEntry(
"LastLoad", curDt );
192 d->mLastLoad = KDateTime( dt, KDateTime::UTC );
193 dt = group.readEntry(
"LastSave", curDt );
194 d->mLastSave = KDateTime( dt, KDateTime::UTC );
200 void ResourceCached::setupSaveTimer()
202 if ( d->mSavePolicy == SaveInterval ) {
203 kDebug() <<
"start save timer (interval " << d->mSaveInterval <<
"mins)";
204 d->mSaveTimer.start( d->mSaveInterval * 60 * 1000 );
206 d->mSaveTimer.stop();
210 void ResourceCached::setupReloadTimer()
212 if ( d->mReloadPolicy == ReloadInterval ) {
213 kDebug() <<
"start reload timer (interval " << d->mReloadInterval <<
"mins)";
214 d->mReloadTimer.start( d->mReloadInterval * 60 * 1000 );
216 d->mReloadTimer.stop();
220 void ResourceCached::writeConfig( KConfigGroup &group )
222 group.writeEntry(
"ReloadPolicy", d->mReloadPolicy );
223 group.writeEntry(
"ReloadInterval", d->mReloadInterval );
225 group.writeEntry(
"SavePolicy", d->mSavePolicy );
226 group.writeEntry(
"SaveInterval", d->mSaveInterval );
228 group.writeEntry(
"LastLoad", d->mLastLoad.toUtc().dateTime() );
229 group.writeEntry(
"LastSave", d->mLastSave.toUtc().dateTime() );
234 return d->mCalendar.addEvent( event );
242 return d->mCalendar.deleteEvent( event );
247 d->mCalendar.deleteAllEvents();
252 return d->mCalendar.event( uid );
256 EventSortField sortField,
257 SortDirection sortDirection )
259 Event::List list = d->mCalendar.rawEventsForDate( qd, timeSpec, sortField, sortDirection );
265 const KDateTime::Spec &timeSpec,
bool inclusive )
267 return d->mCalendar.rawEvents( start, end, timeSpec, inclusive );
272 return d->mCalendar.rawEventsForDate( kdt );
277 return d->mCalendar.rawEvents( sortField, sortDirection );
282 return d->mCalendar.addTodo( todo );
287 return d->mCalendar.deleteTodo( todo );
292 d->mCalendar.deleteAllTodos();
297 return d->mCalendar.deleteJournal( journal );
302 d->mCalendar.deleteAllJournals();
307 return d->mCalendar.rawTodos( sortField, sortDirection );
312 return d->mCalendar.todo( uid );
317 return d->mCalendar.rawTodosForDate( date );
322 return d->mCalendar.addJournal( journal );
327 return d->mCalendar.journal( uid );
332 return d->mCalendar.rawJournals( sortField, sortDirection );
337 return d->mCalendar.rawJournalsForDate( date );
342 return d->mCalendar.alarmsTo( to );
347 return d->mCalendar.alarms( from, to );
352 d->mCalendar.setTimeSpec( timeSpec );
357 return d->mCalendar.timeSpec();
362 d->mCalendar.setTimeZoneId( tzid );
367 return d->mCalendar.timeZoneId();
372 d->mCalendar.shiftTimes( oldSpec, newSpec );
375 void ResourceCached::clearChanges()
377 d->mAddedIncidences.clear();
378 d->mChangedIncidences.clear();
379 d->mDeletedIncidences.clear();
384 kDebug() << resourceName();
386 setReceivedLoadError(
false );
396 if ( !d->mReloaded && !d->mInhibitReload ) {
397 update = checkForReload();
406 success = doLoad( update );
408 if ( !success && !receivedLoadError() ) {
415 if ( !noReadOnlyOnLoad() && readOnly() ) {
417 Incidence::List::Iterator it;
418 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
419 (*it)->setReadOnly(
true );
423 kDebug() <<
"Done loading resource" << resourceName();
426 emit resourceLoaded(
this );
434 return load( SyncCache );
439 setIdMapperIdentifier();
442 if ( !KStandardDirs::exists( cacheFile() ) ) {
445 d->mCalendar.load( cacheFile() );
446 if ( !noReadOnlyOnLoad() && readOnly() ) {
448 Incidence::List::Iterator it;
449 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
450 (*it)->setReadOnly(
true );
458 if ( !incidence && ( d->mSavePolicy == SaveAlways || d->mSavePolicy == SaveDelayed ) ) {
459 d->mSaveTimer.stop();
461 d->mSavePending =
false;
462 if ( saveInhibited() ) {
466 kDebug() <<
"Save resource" << resourceName();
468 setReceivedSaveError(
false );
476 upload = checkForSave();
484 bool success = incidence ? doSave( upload, incidence ) : doSave( upload );
485 if ( !success && !receivedSaveError() ) {
488 emit resourceSaved(
this );
493 kDebug() <<
"Don't save read-only resource" << resourceName();
500 return save( SyncCache, incidence );
505 Q_UNUSED( incidence );
506 return doSave( syncCache );
511 kDebug() << cacheFile();
513 setIdMapperIdentifier();
516 d->mCalendar.save( cacheFile() );
519 void ResourceCached::setIdMapperIdentifier()
521 d->mIdMapper.setIdentifier( type() +
'_' + identifier() );
526 d->mCalendar.close();
529 void ResourceCached::cleanUpEventCache(
const Event::List &eventList )
533 if ( KStandardDirs::exists( cacheFile() ) ) {
534 calendar.load( cacheFile() );
540 Event::List::ConstIterator cacheIt, it;
541 for ( cacheIt = list.constBegin(); cacheIt != list.constEnd(); ++cacheIt ) {
543 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
544 if ( (*it)->uid() == (*cacheIt)->uid() ) {
551 d->mIdMapper.removeRemoteId( d->mIdMapper.remoteId( (*cacheIt)->uid() ) );
552 Event *
event = d->mCalendar.event( (*cacheIt)->uid() );
554 d->mCalendar.deleteEvent( event );
562 void ResourceCached::cleanUpTodoCache(
const Todo::List &todoList )
566 if ( KStandardDirs::exists( cacheFile() ) ) {
567 calendar.load( cacheFile() );
573 Todo::List::ConstIterator cacheIt, it;
574 for ( cacheIt = list.constBegin(); cacheIt != list.constEnd(); ++cacheIt ) {
577 for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
578 if ( (*it)->uid() == (*cacheIt)->uid() ) {
584 d->mIdMapper.removeRemoteId( d->mIdMapper.remoteId( (*cacheIt)->uid() ) );
585 Todo *todo = d->mCalendar.todo( (*cacheIt)->uid() );
587 d->mCalendar.deleteTodo( todo );
602 return KStandardDirs::locateLocal(
"cache",
"kcal/kresources/" + identifier() );
607 return KStandardDirs::locateLocal(
"cache",
"kcal/changescache/" + identifier() +
'_' + type );
610 void ResourceCached::saveChangesCache(
const QMap<Incidence *, bool> &map,
const QString &type )
615 QMap<Incidence *,bool>::ConstIterator it;
616 for ( it = map.begin(); it != map.end(); ++it ) {
618 calendar.addIncidence( it.key()->clone() );
622 calendar.save( changesCacheFile( type ) );
624 QFile file( changesCacheFile( type ) );
631 void ResourceCached::saveChangesCache()
633 saveChangesCache( d->mAddedIncidences,
"added" );
634 saveChangesCache( d->mDeletedIncidences,
"deleted" );
635 saveChangesCache( d->mChangedIncidences,
"changed" );
638 void ResourceCached::loadChangesCache( QMap<Incidence *, bool> &map,
const QString &type )
642 if ( KStandardDirs::exists( changesCacheFile( type ) ) ) {
643 calendar.load( changesCacheFile( type ) );
649 Incidence::List::ConstIterator it;
650 for ( it = list.begin(); it != list.end(); ++it ) {
651 map.insert( (*it)->clone(), true );
657 void ResourceCached::loadChangesCache()
659 loadChangesCache( d->mAddedIncidences,
"added" );
660 loadChangesCache( d->mDeletedIncidences,
"deleted" );
661 loadChangesCache( d->mChangedIncidences,
"changed" );
666 kDebug() << i->
uid();
668 QMap<Incidence *,bool>::ConstIterator it;
669 it = d->mAddedIncidences.constFind( i );
670 if ( it == d->mAddedIncidences.constEnd() ) {
671 d->mAddedIncidences.insert( i,
true );
674 checkForAutomaticSave();
679 kDebug() << i->
uid();
681 QMap<Incidence *,bool>::ConstIterator it;
682 it = d->mChangedIncidences.constFind( i );
684 if ( it == d->mChangedIncidences.constEnd() ) {
685 d->mChangedIncidences.insert( i,
true );
688 checkForAutomaticSave();
693 kDebug() << i->
uid();
695 QMap<Incidence *,bool>::ConstIterator it;
696 it = d->mDeletedIncidences.constFind( i );
697 if ( it == d->mDeletedIncidences.constEnd() ) {
698 d->mDeletedIncidences.insert( i,
true );
701 checkForAutomaticSave();
707 QMap<Incidence *,bool>::ConstIterator it;
708 for ( it = d->mAddedIncidences.constBegin(); it != d->mAddedIncidences.constEnd(); ++it ) {
709 added.append( it.key() );
717 QMap<Incidence *,bool>::ConstIterator it;
718 for ( it = d->mChangedIncidences.constBegin(); it != d->mChangedIncidences.constEnd(); ++it ) {
719 changed.append( it.key() );
727 QMap<Incidence *,bool>::ConstIterator it;
728 for ( it = d->mDeletedIncidences.constBegin(); it != d->mDeletedIncidences.constEnd(); ++it ) {
729 deleted.append( it.key() );
737 QMap<Incidence *,bool>::ConstIterator it;
738 for ( it = d->mAddedIncidences.constBegin(); it != d->mAddedIncidences.constEnd(); ++it ) {
739 changes.append( it.key() );
741 for ( it = d->mChangedIncidences.constBegin(); it != d->mChangedIncidences.constEnd(); ++it ) {
742 changes.append( it.key() );
744 for ( it = d->mDeletedIncidences.constBegin(); it != d->mDeletedIncidences.constEnd(); ++it ) {
745 changes.append( it.key() );
750 bool ResourceCached::hasChanges()
const
752 return !( d->mAddedIncidences.isEmpty() && d->mChangedIncidences.isEmpty() &&
753 d->mDeletedIncidences.isEmpty() );
756 void ResourceCached::clearChange(
Incidence *incidence )
758 clearChange( incidence->
uid() );
761 void ResourceCached::clearChange(
const QString &uid )
763 QMap<Incidence *, bool>::Iterator it;
765 for ( it = d->mAddedIncidences.begin(); it != d->mAddedIncidences.end(); ++it ) {
766 if ( it.key()->uid() == uid ) {
767 d->mAddedIncidences.erase( it );
772 for ( it = d->mChangedIncidences.begin(); it != d->mChangedIncidences.end(); ++it ) {
773 if ( it.key()->uid() == uid ) {
774 d->mChangedIncidences.erase( it );
779 for ( it = d->mDeletedIncidences.begin(); it != d->mDeletedIncidences.end(); ++it ) {
780 if ( it.key()->uid() == uid ) {
781 d->mDeletedIncidences.erase( it );
787 void ResourceCached::enableChangeNotification()
789 d->mCalendar.registerObserver(
this );
792 void ResourceCached::disableChangeNotification()
794 d->mCalendar.unregisterObserver(
this );
797 void ResourceCached::slotReload()
808 void ResourceCached::slotSave()
819 void ResourceCached::checkForAutomaticSave()
821 if ( d->mSavePolicy == SaveAlways ) {
822 kDebug() <<
"save now";
823 d->mSavePending =
true;
824 d->mSaveTimer.setSingleShot(
true );
825 d->mSaveTimer.start( 1 * 1000 );
826 }
else if ( d->mSavePolicy == SaveDelayed ) {
827 kDebug() <<
"save delayed";
828 d->mSavePending =
true;
829 d->mSaveTimer.setSingleShot(
true );
830 d->mSaveTimer.start( 15 * 1000 );
836 if ( d->mReloadPolicy == ReloadNever ) {
839 if ( d->mReloadPolicy == ReloadOnStartup ) {
840 return !d->mReloaded;
847 if ( d->mSavePolicy == SaveNever ) {
855 if ( d->mLastLoad.isValid() ) {
857 txt += i18n(
"Last loaded: %1",
858 KGlobal::locale()->formatDateTime( d->mLastLoad.toUtc().dateTime() ) );
860 if ( d->mLastSave.isValid() ) {
862 txt += i18n(
"Last saved: %1",
863 KGlobal::locale()->formatDateTime( d->mLastSave.toUtc().dateTime() ) );
869 if ( d->mSavePending ) {
870 d->mSaveTimer.stop();
872 if ( d->mSavePending || d->mSavePolicy == SaveOnExit || d->mSavePolicy == SaveInterval ) {
875 d->mCalendar.close();
880 kDebug() <<
"Opening resource" << resourceName();
886 d->mCalendar.setOwner( owner );
891 return d->mCalendar.owner();
KRES::IdMapper & idMapper()
Returns a reference to the id mapper.
void deleteAllTodos()
Removes all todos from this calendar.
virtual void deleteAllJournals()
Removes all Journals from this calendar.
virtual QString changesCacheFile(const QString &type) const
Functions for keeping the changes persistent.
bool loadFromCache()
Load the resource from the cache.
bool deleteTodo(Todo *)
Remove a todo from the todolist.
void setTimeSpec(const KDateTime::Spec &timeSpec)
Set the time specification (time zone, etc.).
This file is part of the API for handling calendar data and defines the CalendarLocal class...
Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return list of all journals.
int savePolicy() const
Return save policy.
void setSavePolicy(int policy)
Set save policy.
Provides a To-do in the sense of RFC2445.
Event::List rawEventsForDate(const QDate &date, const KDateTime::Spec &timeSpec=KDateTime::Spec(), EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Builds and then returns a list of all events that match for the date specified.
void setOwner(const Person &owner)
Set the owner of the calendar.
KDateTime::Spec timeSpec() const
Get the viewing time specification (time zone etc.) for the calendar.
void calendarIncidenceChanged(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been modified.
void saveToCache()
Save the resource back to the cache.
Journal::List rawJournalsForDate(const QDate &date)
Return list of journals for the given date.
Todo * todo(const QString &uid)
Searches todolist for an event with this unique string identifier, returns a pointer or null...
Alarm::List alarms(const KDateTime &from, const KDateTime &to)
Return all alarms, which occur in the given time interval.
bool inhibitDefaultReload(bool inhibit)
Inhibit or allow cache reloads when using load(DefaultCache).
void setSaveInterval(int minutes)
Set save interval in minutes which is used when save policy is SaveInterval.
This class provides an Event in the sense of RFC2445.
QString uid() const
Returns the unique id (uid) for the incidence.
never reload the resource automatically
never save the resource automatically
void addInfoText(QString &) const
Add info text for concrete resources.
This class provides a calendar stored as a local file.
bool addEvent(Event *event)
Add event to calendar.
Event * event(const QString &UniqueStr)
Retrieves an event on the basis of the unique string ID.
virtual void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
void setReloadInterval(int minutes)
Set reload interval in minutes which is used when reload policy is ReloadInterval.
This class provides the interfaces for a calendar resource.
QString timeZoneId() const
Returns the viewing time zone ID for the resource.
virtual void doClose()
Virtual method from KRES::Resource, called when the last instace of the resource is closed...
virtual bool doOpen()
Opens the resource.
Person owner() const
Return the owner of the calendar's full name.
bool deleteEvent(Event *event)
Deletes an event from this calendar.
Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return unfiltered list of all events in calendar.
Represents a person, by name ane email address.
This file is part of the API for handling calendar data and defines the Todo class.
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
This class provides a template for lists of pointers.
This file is part of the API for handling calendar data and defines the Exception and ErrorFormat cla...
bool addTodo(Todo *todo)
Add a todo to the todolist.
Provides a Journal in the sense of RFC2445.
void calendarIncidenceAdded(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been inserted.
virtual bool doSave(bool syncCache)=0
Do the actual saving of the resource data.
int saveInterval() const
Return save interval in minutes.
int reloadInterval() const
Return reload interval in minutes.
This file is part of the API for handling calendar data and defines the Journal class.
void clearCache()
Clear cache.
Todo::List rawTodosForDate(const QDate &date)
Returns list of todos due on the specified date.
bool checkForReload()
Check if reload required according to reload policy.
Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return list of all todos.
void setReloaded(bool done)
Set the cache-reloaded status.
void calendarIncidenceDeleted(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been removed.
virtual bool load()
Load resource data.
This file is part of the API for handling calendar data and defines the Event class.
bool save(CacheAction action, Incidence *incidence=0)
Save the resource data to cache, and optionally upload the cache file afterwards. ...
This file is part of the API for handling calendar data and defines the Incidence class...
virtual QString cacheFile() const
This method is used by loadFromCache() and saveToCache(), reimplement it to change the location of th...
This class provides a calendar resource using a local CalendarLocal object to cache the calendar data...
bool checkForSave()
Check if save required according to save policy.
void setTimeZoneId(const QString &timeZoneId)
Set id of timezone, e.g.
int reloadPolicy() const
Return reload policy.
void deleteAllEvents()
Removes all Events from this calendar.
void setReloadPolicy(int policy)
Set reload policy.
Alarm::List alarmsTo(const KDateTime &to)
Return all alarms, which occur before given date.
virtual Journal * journal(const QString &uid)
Return Journal with given unique id.
CacheAction
Whether to update the cache file when loading a resource, or whether to upload the cache file after s...
bool reloaded() const
Return whether the resource cache has been reloaded since startup.
virtual KCAL_DEPRECATED bool addJournal(Journal *journal)
Add a Journal entry to calendar.
virtual bool deleteJournal(Journal *)
Remove a Journal from the calendar.