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>
49class 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;
88ResourceCached::ResourceCached()
92 connect( &d->mReloadTimer, SIGNAL(timeout()), SLOT(slotReload()) );
93 connect( &d->mSaveTimer, SIGNAL(timeout()), SLOT(slotSave()) );
96ResourceCached::ResourceCached(
const KConfigGroup &group )
100 connect( &d->mReloadTimer, SIGNAL(timeout()), SLOT(slotReload()) );
101 connect( &d->mSaveTimer, SIGNAL(timeout()), SLOT(slotSave()) );
104ResourceCached::~ResourceCached()
111 return &d->mCalendar;
114bool 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;
182void 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 );
200void ResourceCached::setupSaveTimer()
203 kDebug() <<
"start save timer (interval " << d->mSaveInterval <<
"mins)";
204 d->mSaveTimer.start( d->mSaveInterval * 60 * 1000 );
206 d->mSaveTimer.stop();
210void ResourceCached::setupReloadTimer()
213 kDebug() <<
"start reload timer (interval " << d->mReloadInterval <<
"mins)";
214 d->mReloadTimer.start( d->mReloadInterval * 60 * 1000 );
216 d->mReloadTimer.stop();
220void 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 );
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 );
375void ResourceCached::clearChanges()
377 d->mAddedIncidences.clear();
378 d->mChangedIncidences.clear();
379 d->mDeletedIncidences.clear();
386 setReceivedLoadError(
false );
396 if ( !d->mReloaded && !d->mInhibitReload ) {
406 success =
doLoad( update );
408 if ( !success && !receivedLoadError() ) {
417 Incidence::List::Iterator it;
418 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
419 (*it)->setReadOnly(
true );
439 setIdMapperIdentifier();
442 if ( !KStandardDirs::exists(
cacheFile() ) ) {
448 Incidence::List::Iterator it;
449 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
450 (*it)->setReadOnly(
true );
459 d->mSaveTimer.stop();
461 d->mSavePending =
false;
468 setReceivedSaveError(
false );
485 if ( !success && !receivedSaveError() ) {
493 kDebug() <<
"Don't save read-only resource" <<
resourceName();
506 return doSave( syncCache );
513 setIdMapperIdentifier();
519void ResourceCached::setIdMapperIdentifier()
526 d->mCalendar.close();
529void ResourceCached::cleanUpEventCache(
const Event::List &eventList )
533 if ( KStandardDirs::exists(
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 );
562void ResourceCached::cleanUpTodoCache(
const Todo::List &todoList )
566 if ( KStandardDirs::exists(
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 );
610void 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 ) {
631void ResourceCached::saveChangesCache()
633 saveChangesCache( d->mAddedIncidences,
"added" );
634 saveChangesCache( d->mDeletedIncidences,
"deleted" );
635 saveChangesCache( d->mChangedIncidences,
"changed" );
638void ResourceCached::loadChangesCache( QMap<Incidence *, bool> &map,
const QString &type )
649 Incidence::List::ConstIterator it;
650 for ( it = list.begin(); it != list.end(); ++it ) {
651 map.insert( (*it)->clone(), true );
657void 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() );
750bool ResourceCached::hasChanges()
const
752 return !( d->mAddedIncidences.isEmpty() && d->mChangedIncidences.isEmpty() &&
753 d->mDeletedIncidences.isEmpty() );
756void ResourceCached::clearChange(
Incidence *incidence )
761void 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 );
787void ResourceCached::enableChangeNotification()
789 d->mCalendar.registerObserver(
this );
792void ResourceCached::disableChangeNotification()
794 d->mCalendar.unregisterObserver(
this );
797void ResourceCached::slotReload()
808void ResourceCached::slotSave()
819void ResourceCached::checkForAutomaticSave()
822 kDebug() <<
"save now";
823 d->mSavePending =
true;
824 d->mSaveTimer.setSingleShot(
true );
825 d->mSaveTimer.start( 1 * 1000 );
827 kDebug() <<
"save delayed";
828 d->mSavePending =
true;
829 d->mSaveTimer.setSingleShot(
true );
830 d->mSaveTimer.start( 15 * 1000 );
840 return !d->mReloaded;
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();
875 d->mCalendar.close();
886 d->mCalendar.setOwner( owner );
891 return d->mCalendar.owner();
TodoSortField
Calendar Todo sort keys.
JournalSortField
Calendar Journal sort keys.
EventSortField
Calendar Event sort keys.
SortDirection
Calendar Incidence sort directions.
This file is part of the API for handling calendar data and defines the CalendarLocal class.
This class provides a calendar stored as a local file.
bool load(const QString &fileName, CalFormat *format=0)
Loads a calendar on disk in vCalendar or iCalendar format into the current calendar.
bool save()
Writes the calendar to disk.
void close()
Clears out the current calendar, freeing all used memory etc.
virtual bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
virtual Incidence::List incidences()
Returns a filtered list of all Incidences for this Calendar.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Returns a sorted, filtered list of all Events for this Calendar.
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Returns a sorted, filtered list of all Todos for this Calendar.
This class provides an Event in the sense of RFC2445.
QString uid() const
Returns the unique id (uid) for the incidence.
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Provides a Journal in the sense of RFC2445.
This class provides a template for lists of pointers.
Represents a person, by name ane email address.
This class provides a calendar resource using a local CalendarLocal object to cache the calendar data...
void setSavePolicy(int policy)
Set save policy.
@ ReloadInterval
reload at regular intervals set by setReloadInterval()
@ ReloadNever
never reload the resource automatically
@ ReloadOnStartup
reload when the resource is opened
void setTimeZoneId(const QString &timeZoneId)
Set id of timezone, e.g.
virtual QString changesCacheFile(const QString &type) const
Functions for keeping the changes persistent.
void setTimeSpec(const KDateTime::Spec &timeSpec)
Set the time specification (time zone, etc.).
@ SaveAlways
save after every change, after a 1 second delay
@ SaveNever
never save the resource automatically
@ SaveDelayed
save after every change, after a 15 second delay
@ SaveOnExit
save when the resource is closed
@ SaveInterval
save at regular intervals set by setSaveInterval()
virtual bool doOpen()
Opens the resource.
void addInfoText(QString &) const
Add info text for concrete resources.
virtual bool deleteJournal(Journal *)
Remove a Journal from the calendar.
int reloadInterval() const
Return reload interval in minutes.
int reloadPolicy() const
Return reload policy.
void setSaveInterval(int minutes)
Set save interval in minutes which is used when save policy is SaveInterval.
Person owner() const
Return the owner of the calendar's full name.
void setReloaded(bool done)
Set the cache-reloaded status.
void deleteAllTodos()
Removes all todos from this calendar.
int savePolicy() const
Return save policy.
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 calendarIncidenceChanged(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been modified.
CacheAction
Whether to update the cache file when loading a resource, or whether to upload the cache file after s...
@ DefaultCache
use the default action set by setReloadPolicy() or setSavePolicy()
@ SyncCache
update the cache file before loading, or upload cache after saving
@ NoSyncCache
perform a cache-only operation, without downloading or uploading
void setOwner(const Person &owner)
Set the owner of the calendar.
void calendarIncidenceAdded(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been inserted.
virtual void deleteAllJournals()
Removes all Journals from this calendar.
bool loadFromCache()
Load the resource from the cache.
Alarm::List alarms(const KDateTime &from, const KDateTime &to)
Return all alarms, which occur in the given time interval.
virtual Journal * journal(const QString &uid)
Return Journal with given unique id.
Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return unfiltered list of all events in calendar.
Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return list of all journals.
KDateTime::Spec timeSpec() const
Get the viewing time specification (time zone etc.) for the calendar.
virtual bool doLoad(bool syncCache)=0
Do the actual loading of the resource data.
void setReloadInterval(int minutes)
Set reload interval in minutes which is used when reload policy is ReloadInterval.
virtual void doClose()
Virtual method from KRES::Resource, called when the last instace of the resource is closed.
Alarm::List alarmsTo(const KDateTime &to)
Return all alarms, which occur before given date.
bool deleteEvent(Event *event)
Deletes an event from this calendar.
bool deleteTodo(Todo *)
Remove a todo from the todolist.
Event * event(const QString &UniqueStr)
Retrieves an event on the basis of the unique string ID.
bool reloaded() const
Return whether the resource cache has been reloaded since startup.
Journal::List rawJournalsForDate(const QDate &date)
Return list of journals for the given date.
void calendarIncidenceDeleted(KCal::Incidence *incidence)
Notify the Observer that an Incidence has been removed.
virtual bool doSave(bool syncCache)=0
Do the actual saving of the resource data.
void saveToCache()
Save the resource back to the cache.
virtual void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
void setReloadPolicy(int policy)
Set reload policy.
virtual KCAL_DEPRECATED bool addJournal(Journal *journal)
Add a Journal entry to calendar.
Todo::List rawTodosForDate(const QDate &date)
Returns list of todos due on the specified date.
bool addEvent(Event *event)
Add event to calendar.
void deleteAllEvents()
Removes all Events from this calendar.
virtual bool load()
Load resource data.
bool inhibitDefaultReload(bool inhibit)
Inhibit or allow cache reloads when using load(DefaultCache).
Todo * todo(const QString &uid)
Searches todolist for an event with this unique string identifier, returns a pointer or null.
bool save(CacheAction action, Incidence *incidence=0)
Save the resource data to cache, and optionally upload the cache file afterwards.
bool checkForSave()
Check if save required according to save policy.
KRES::IdMapper & idMapper()
Returns a reference to the id mapper.
bool checkForReload()
Check if reload required according to reload policy.
virtual QString cacheFile() const
This method is used by loadFromCache() and saveToCache(), reimplement it to change the location of th...
int saveInterval() const
Return save interval in minutes.
bool addTodo(Todo *todo)
Add a todo to the todolist.
Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return list of all todos.
QString timeZoneId() const
Returns the viewing time zone ID for the resource.
void clearCache()
Clear cache.
This class provides the interfaces for a calendar resource.
bool saveInhibited() const
Return whether saves have been inhibited by setInhibitSave().
void resourceLoaded(ResourceCalendar *)
This signal is emitted when loading data into the resource has been finished.
Incidence * incidence(const QString &uid)
Return incidence with given unique id.
void resourceSaved(ResourceCalendar *)
This signal is emitted when saving the data of the resource has been finished.
void loadError(const QString &errorMessage=QString())
A resource should call this function if a load error happens.
bool noReadOnlyOnLoad() const
Return whether individual incidences are inhibited from being set read-only when a read-only resource...
void saveError(const QString &errorMessage=QString())
A resource should call this function if a save error happens.
Incidence::List rawIncidences()
Returns a list of all incideces.
Provides a To-do in the sense of RFC2445.
QString identifier() const
virtual QString resourceName() const
virtual bool readOnly() const
This file is part of the API for handling calendar data and defines the Event class.
This file is part of the API for handling calendar data and defines the Exception and ErrorFormat cla...
This file is part of the API for handling calendar data and defines the Incidence class.
This file is part of the API for handling calendar data and defines the Journal class.
This file is part of the API for handling calendar data and defines the Todo class.