-rw-r--r-- | libkcal/alarm.cpp | 2 | ||||
-rw-r--r-- | libkcal/calendar.cpp | 54 | ||||
-rw-r--r-- | libkcal/calendar.h | 1 | ||||
-rw-r--r-- | libkcal/calendarlocal.cpp | 56 | ||||
-rw-r--r-- | libkcal/calendarlocal.h | 1 |
5 files changed, 87 insertions, 27 deletions
diff --git a/libkcal/alarm.cpp b/libkcal/alarm.cpp index 0afa0a7..79e0464 100644 --- a/libkcal/alarm.cpp +++ b/libkcal/alarm.cpp @@ -1,481 +1,483 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <kdebug.h> #include <klocale.h> #include "incidence.h" #include "todo.h" #include "alarm.h" using namespace KCal; #include <qwidget.h> Alarm::Alarm(Incidence *parent) : mParent(parent), mType(Audio), mDescription(""), // to make operator==() not fail mFile(""), // to make operator==() not fail mMailSubject(""), // to make operator==() not fail mAlarmSnoozeTime(5), mAlarmRepeatCount(0), mEndOffset(false), mHasTime(false), mAlarmEnabled(false) { } Alarm::~Alarm() { } bool Alarm::operator==( const Alarm& rhs ) const { if ( mType != rhs.mType || mAlarmSnoozeTime != rhs.mAlarmSnoozeTime || mAlarmRepeatCount != rhs.mAlarmRepeatCount || mAlarmEnabled != rhs.mAlarmEnabled || mHasTime != rhs.mHasTime) return false; #if 0 if ( mType != rhs.mType ) { qDebug("aaa1 "); return false; } if ( mAlarmSnoozeTime != rhs.mAlarmSnoozeTime ) { qDebug("aaa2 "); return false; } if ( mAlarmRepeatCount != rhs.mAlarmRepeatCount ) { qDebug("aaa3 "); return false; } if ( mAlarmEnabled != rhs.mAlarmEnabled ) { qDebug("aaa4 "); return false; } if ( mHasTime != rhs.mHasTime ) { qDebug("aaa5 "); return false; } #endif if (mHasTime) { if (mAlarmTime != rhs.mAlarmTime) return false; } else { if (mOffset != rhs.mOffset || mEndOffset != rhs.mEndOffset) return false; } switch (mType) { case Display: return mDescription == rhs.mDescription; case Email: return mDescription == rhs.mDescription && mMailAttachFiles == rhs.mMailAttachFiles && mMailAddresses == rhs.mMailAddresses && mMailSubject == rhs.mMailSubject; case Procedure: return mFile == rhs.mFile && mDescription == rhs.mDescription; case Audio: return mFile == rhs.mFile; case Invalid: break; } return false; } void Alarm::setType(Alarm::Type type) { if (type == mType) return; switch (type) { case Display: mDescription = ""; break; case Procedure: mFile = mDescription = ""; break; case Audio: mFile = ""; break; case Email: mMailSubject = mDescription = ""; mMailAddresses.clear(); mMailAttachFiles.clear(); break; case Invalid: break; default: return; } mType = type; mParent->updated(); } Alarm::Type Alarm::type() const { return mType; } void Alarm::setAudioAlarm(const QString &audioFile) { mType = Audio; mFile = audioFile; mParent->updated(); } void Alarm::setAudioFile(const QString &audioFile) { if (mType == Audio) { mFile = audioFile; mParent->updated(); } } QString Alarm::audioFile() const { return (mType == Audio) ? mFile : QString::null; } void Alarm::setProcedureAlarm(const QString &programFile, const QString &arguments) { mType = Procedure; mFile = programFile; mDescription = arguments; mParent->updated(); } void Alarm::setProgramFile(const QString &programFile) { if (mType == Procedure) { mFile = programFile; mParent->updated(); } } QString Alarm::programFile() const { return (mType == Procedure) ? mFile : QString::null; } void Alarm::setProgramArguments(const QString &arguments) { if (mType == Procedure) { mDescription = arguments; mParent->updated(); } } QString Alarm::programArguments() const { return (mType == Procedure) ? mDescription : QString::null; } void Alarm::setEmailAlarm(const QString &subject, const QString &text, const QValueList<Person> &addressees, const QStringList &attachments) { mType = Email; mMailSubject = subject; mDescription = text; mMailAddresses = addressees; mMailAttachFiles = attachments; mParent->updated(); } void Alarm::setMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses.clear(); mMailAddresses += mailAddress; mParent->updated(); } } void Alarm::setMailAddresses(const QValueList<Person> &mailAddresses) { if (mType == Email) { mMailAddresses = mailAddresses; mParent->updated(); } } void Alarm::addMailAddress(const Person &mailAddress) { if (mType == Email) { mMailAddresses += mailAddress; mParent->updated(); } } QValueList<Person> Alarm::mailAddresses() const { return (mType == Email) ? mMailAddresses : QValueList<Person>(); } void Alarm::setMailSubject(const QString &mailAlarmSubject) { if (mType == Email) { mMailSubject = mailAlarmSubject; mParent->updated(); } } QString Alarm::mailSubject() const { return (mType == Email) ? mMailSubject : QString::null; } void Alarm::setMailAttachment(const QString &mailAttachFile) { if (mType == Email) { mMailAttachFiles.clear(); mMailAttachFiles += mailAttachFile; mParent->updated(); } } void Alarm::setMailAttachments(const QStringList &mailAttachFiles) { if (mType == Email) { mMailAttachFiles = mailAttachFiles; mParent->updated(); } } void Alarm::addMailAttachment(const QString &mailAttachFile) { if (mType == Email) { mMailAttachFiles += mailAttachFile; mParent->updated(); } } QStringList Alarm::mailAttachments() const { return (mType == Email) ? mMailAttachFiles : QStringList(); } void Alarm::setMailText(const QString &text) { if (mType == Email) { mDescription = text; mParent->updated(); } } QString Alarm::mailText() const { return (mType == Email) ? mDescription : QString::null; } void Alarm::setDisplayAlarm(const QString &text) { mType = Display; mDescription = text; mParent->updated(); } void Alarm::setText(const QString &text) { if (mType == Display) { mDescription = text; mParent->updated(); } } QString Alarm::text() const { return (mType == Display) ? mDescription : QString::null; } void Alarm::setTime(const QDateTime &alarmTime) { mAlarmTime = alarmTime; mHasTime = true; mParent->updated(); } int Alarm::offset() { if ( hasTime() ) { if (mParent->typeID() == todoID ) { Todo *t = static_cast<Todo*>(mParent); return t->dtDue().secsTo( mAlarmTime ) ; } else return mParent->dtStart().secsTo( mAlarmTime ) ; } else { return mOffset.asSeconds(); } } QString Alarm::offsetText() { int min = -offset()/60; int hours = min /60; min = min % 60; int days = hours /24; hours = hours % 24; QString message; //qDebug("%d %d %d ", days, hours, min ); if ( days > 0 ) message += i18n("%1d").arg( days ); if ( hours > 0 ) { if ( !message.isEmpty() ) message += "/"; message += i18n("%1h").arg( hours ); } if ( min > 0 ) { if ( !message.isEmpty() ) message += "/"; message += i18n("%1min").arg( min ); } if ( message.isEmpty() ) message = i18n("%1min").arg( 0 ); + if ( !mParent->alarmEnabled() ) + return "!"+message + i18n("(disabled)"); return message; } QDateTime Alarm::time() const { if ( hasTime() ) return mAlarmTime; else { if (mParent->typeID() == todoID ) { Todo *t = static_cast<Todo*>(mParent); return mOffset.end( t->dtDue() ); } else if (mEndOffset) { return mOffset.end( mParent->dtEnd() ); } else { return mOffset.end( mParent->dtStart() ); } } } bool Alarm::hasTime() const { return mHasTime; } void Alarm::setSnoozeTime(int alarmSnoozeTime) { mAlarmSnoozeTime = alarmSnoozeTime; mParent->updated(); } int Alarm::snoozeTime() const { return mAlarmSnoozeTime; } void Alarm::setRepeatCount(int alarmRepeatCount) { kdDebug(5800) << "Alarm::setRepeatCount(): " << alarmRepeatCount << endl; mAlarmRepeatCount = alarmRepeatCount; mParent->updated(); } int Alarm::repeatCount() const { kdDebug(5800) << "Alarm::repeatCount(): " << mAlarmRepeatCount << endl; return mAlarmRepeatCount; } void Alarm::toggleAlarm() { mAlarmEnabled = !mAlarmEnabled; mParent->updated(); } void Alarm::setEnabled(bool enable) { mAlarmEnabled = enable; mParent->updated(); } bool Alarm::enabled() const { return mAlarmEnabled; } void Alarm::setStartOffset( const Duration &offset ) { mOffset = offset; mEndOffset = false; mHasTime = false; mParent->updated(); } Duration Alarm::startOffset() const { return (mHasTime || mEndOffset) ? 0 : mOffset; } bool Alarm::hasStartOffset() const { return !mHasTime && !mEndOffset; } bool Alarm::hasEndOffset() const { return !mHasTime && mEndOffset; } void Alarm::setEndOffset( const Duration &offset ) { mOffset = offset; mEndOffset = true; mHasTime = false; mParent->updated(); } Duration Alarm::endOffset() const { return (mHasTime || !mEndOffset) ? 0 : mOffset; } void Alarm::setParent( Incidence *parent ) { mParent = parent; } diff --git a/libkcal/calendar.cpp b/libkcal/calendar.cpp index 5092d1a..a662eeb 100644 --- a/libkcal/calendar.cpp +++ b/libkcal/calendar.cpp @@ -1,488 +1,488 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdlib.h> #include <time.h> #include <kdebug.h> #include <kglobal.h> #include <klocale.h> #include "exceptions.h" #include "calfilter.h" #include "calendar.h" #include "syncdefines.h" using namespace KCal; Calendar::Calendar() { init(); setTimeZoneId( " 00:00 Europe/London(UTC)" ); } Calendar::Calendar( const QString &timeZoneId ) { init(); setTimeZoneId(timeZoneId); } void Calendar::init() { mObserver = 0; mNewObserver = false; mUndoIncidence = 0; mDeleteIncidencesOnClose = true; mModified = false; mDefaultCalendar = 1; // Setup default filter, which does nothing mDefaultFilter = new CalFilter; mFilter = mDefaultFilter; mFilter->setEnabled(false); // initialize random numbers. This is a hack, and not // even that good of one at that. // srandom(time(0)); // user information... setOwner(i18n("Unknown Name")); setEmail(i18n("unknown@nowhere")); #if 0 tmpStr = KOPrefs::instance()->mTimeZone; // kdDebug(5800) << "Calendar::Calendar(): TimeZone: " << tmpStr << endl; int dstSetting = KOPrefs::instance()->mDaylightSavings; extern long int timezone; struct tm *now; time_t curtime; curtime = time(0); now = localtime(&curtime); int hourOff = - ((timezone / 60) / 60); if (now->tm_isdst) hourOff += 1; QString tzStr; tzStr.sprintf("%.2d%.2d", hourOff, abs((timezone / 60) % 60)); // if no time zone was in the config file, write what we just discovered. if (tmpStr.isEmpty()) { // KOPrefs::instance()->mTimeZone = tzStr; } else { tzStr = tmpStr; } // if daylight savings has changed since last load time, we need // to rewrite these settings to the config file. if ((now->tm_isdst && !dstSetting) || (!now->tm_isdst && dstSetting)) { KOPrefs::instance()->mTimeZone = tzStr; KOPrefs::instance()->mDaylightSavings = now->tm_isdst; } setTimeZone(tzStr); #endif // KOPrefs::instance()->writeConfig(); } Calendar::~Calendar() { delete mDefaultFilter; if ( mUndoIncidence ) delete mUndoIncidence; } void Calendar::setDontDeleteIncidencesOnClose () { mDeleteIncidencesOnClose = false; } void Calendar::setDefaultCalendar( int d ) { mDefaultCalendar = d; } int Calendar::defaultCalendar() { return mDefaultCalendar; } const QString &Calendar::getOwner() const { return mOwner; } bool Calendar::undoDeleteIncidence() { if (!mUndoIncidence) return false; addIncidence(mUndoIncidence); mUndoIncidence = 0; return true; } void Calendar::setOwner(const QString &os) { int i; mOwner = os; i = mOwner.find(','); if (i != -1) mOwner = mOwner.left(i); setModified( true ); } void Calendar::setTimeZone(const QString & tz) { bool neg = FALSE; int hours, minutes; QString tmpStr(tz); if (tmpStr.left(1) == "-") neg = TRUE; if (tmpStr.left(1) == "-" || tmpStr.left(1) == "+") tmpStr.remove(0, 1); hours = tmpStr.left(2).toInt(); if (tmpStr.length() > 2) minutes = tmpStr.right(2).toInt(); else minutes = 0; mTimeZone = (60*hours+minutes); if (neg) mTimeZone = -mTimeZone; mLocalTime = false; setModified( true ); } QString Calendar::getTimeZoneStr() const { if (mLocalTime) return ""; QString tmpStr; int hours = abs(mTimeZone / 60); int minutes = abs(mTimeZone % 60); bool neg = mTimeZone < 0; tmpStr.sprintf("%c%.2d%.2d", (neg ? '-' : '+'), hours, minutes); return tmpStr; } void Calendar::setTimeZone(int tz) { mTimeZone = tz; mLocalTime = false; setModified( true ); } int Calendar::getTimeZone() const { return mTimeZone; } void Calendar::setTimeZoneId(const QString &id) { mTimeZoneId = id; mLocalTime = false; mTimeZone = KGlobal::locale()->timezoneOffset(mTimeZoneId); if ( mTimeZone > 1000) setLocalTime(); //qDebug("Calendar::setTimeZoneOffset %s %d ",mTimeZoneId.latin1(), mTimeZone); setModified( true ); } QString Calendar::timeZoneId() const { return mTimeZoneId; } void Calendar::setLocalTime() { //qDebug("Calendar::setLocalTime() "); mLocalTime = true; mTimeZone = 0; mTimeZoneId = ""; setModified( true ); } bool Calendar::isLocalTime() const { return mLocalTime; } const QString &Calendar::getEmail() { return mOwnerEmail; } void Calendar::setEmail(const QString &e) { mOwnerEmail = e; setModified( true ); } void Calendar::setFilter(CalFilter *filter) { mFilter = filter; } CalFilter *Calendar::filter() { return mFilter; } QPtrList<Incidence> Calendar::incidences() { QPtrList<Incidence> incidences; Incidence *i; QPtrList<Event> e = events(); for( i = e.first(); i; i = e.next() ) incidences.append( i ); QPtrList<Todo> t = todos(); for( i = t.first(); i; i = t.next() ) incidences.append( i ); QPtrList<Journal> j = journals(); for( i = j.first(); i; i = j.next() ) incidences.append( i ); return incidences; } void Calendar::resetPilotStat(int id ) { QPtrList<Incidence> incidences; Incidence *i; QPtrList<Event> e = rawEvents(); for( i = e.first(); i; i = e.next() ) i->setPilotId( id ); QPtrList<Todo> t = rawTodos(); for( i = t.first(); i; i = t.next() ) i->setPilotId( id ); QPtrList<Journal> j = journals(); for( i = j.first(); i; i = j.next() ) i->setPilotId( id ); } void Calendar::resetTempSyncStat() { QPtrList<Incidence> incidences; Incidence *i; QPtrList<Event> e = rawEvents(); for( i = e.first(); i; i = e.next() ) i->setTempSyncStat( SYNC_TEMPSTATE_INITIAL ); QPtrList<Todo> t = rawTodos(); for( i = t.first(); i; i = t.next() ) i->setTempSyncStat( SYNC_TEMPSTATE_INITIAL ); QPtrList<Journal> j = journals(); for( i = j.first(); i; i = j.next() ) i->setTempSyncStat( SYNC_TEMPSTATE_INITIAL ); } QPtrList<Incidence> Calendar::rawIncidences() { QPtrList<Incidence> incidences; Incidence *i; QPtrList<Event> e = rawEvents(); for( i = e.first(); i; i = e.next() ) incidences.append( i ); QPtrList<Todo> t = rawTodos(); for( i = t.first(); i; i = t.next() ) incidences.append( i ); QPtrList<Journal> j = journals(); for( i = j.first(); i; i = j.next() ) incidences.append( i ); return incidences; } QPtrList<Event> Calendar::events( const QDate &date, bool sorted ) { QPtrList<Event> el = rawEventsForDate(date,sorted); mFilter->apply(&el); return el; } QPtrList<Event> Calendar::events( const QDateTime &qdt ) { QPtrList<Event> el = rawEventsForDate(qdt); mFilter->apply(&el); return el; } QPtrList<Event> Calendar::events( const QDate &start, const QDate &end, bool inclusive) { QPtrList<Event> el = rawEvents(start,end,inclusive); mFilter->apply(&el); return el; } QPtrList<Event> Calendar::events() { QPtrList<Event> el = rawEvents(); mFilter->apply(&el); return el; } void Calendar::addIncidenceBranch(Incidence *i) { addIncidence( i ); Incidence * inc; QPtrList<Incidence> Relations = i->relations(); for (inc=Relations.first();inc;inc=Relations.next()) { addIncidenceBranch( inc ); } } bool Calendar::addIncidence(Incidence *i) { Incidence::AddVisitor<Calendar> v(this); i->setCalID( mDefaultCalendar ); i->setCalEnabled( true ); return i->accept(v); } void Calendar::deleteIncidence(Incidence *in) { if ( in->typeID() == eventID ) deleteEvent( (Event*) in ); else if ( in->typeID() == todoID ) deleteTodo( (Todo*) in); else if ( in->typeID() == journalID ) deleteJournal( (Journal*) in ); } Incidence* Calendar::incidence( const QString& uid ) { Incidence* i; if( (i = todo( uid )) != 0 ) return i; if( (i = event( uid )) != 0 ) return i; if( (i = journal( uid )) != 0 ) return i; return 0; } QPtrList<Todo> Calendar::todos() { QPtrList<Todo> tl = rawTodos(); mFilter->apply( &tl ); return tl; } // When this is called, the todo have already been added to the calendar. // This method is only about linking related todos void Calendar::setupRelations( Incidence *incidence ) { QString uid = incidence->uid(); //qDebug("Calendar::setupRelations "); // First, go over the list of orphans and see if this is their parent while( Incidence* i = mOrphans[ uid ] ) { mOrphans.remove( uid ); i->setRelatedTo( incidence ); incidence->addRelation( i ); mOrphanUids.remove( i->uid() ); } // Now see about this incidences parent if( !incidence->relatedTo() && !incidence->relatedToUid().isEmpty() ) { // This incidence has a uid it is related to, but is not registered to it yet // Try to find it Incidence* parent = this->incidence( incidence->relatedToUid() ); if( parent ) { // Found it incidence->setRelatedTo( parent ); parent->addRelation( incidence ); } else { // Not found, put this in the mOrphans list mOrphans.insert( incidence->relatedToUid(), incidence ); mOrphanUids.insert( incidence->uid(), incidence ); } } } // If a task with subtasks is deleted, move it's subtasks to the orphans list void Calendar::removeRelations( Incidence *incidence ) { // qDebug("Calendar::removeRelations "); - QString uid = incidence->uid(); - - QPtrList<Incidence> relations = incidence->relations(); - for( Incidence* i = relations.first(); i; i = relations.next() ) - if( !mOrphanUids.find( i->uid() ) ) { - mOrphans.insert( uid, i ); - mOrphanUids.insert( i->uid(), i ); - i->setRelatedTo( 0 ); - i->setRelatedToUid( uid ); - } - - // If this incidence is related to something else, tell that about it - if( incidence->relatedTo() ) - incidence->relatedTo()->removeRelation( incidence ); - - // Remove this one from the orphans list - if( mOrphanUids.remove( uid ) ) - // This incidence is located in the orphans list - it should be removed - if( !( incidence->relatedTo() != 0 && mOrphans.remove( incidence->relatedTo()->uid() ) ) ) { - // Removing wasn't that easy - for( QDictIterator<Incidence> it( mOrphans ); it.current(); ++it ) { - if( it.current()->uid() == uid ) { - mOrphans.remove( it.currentKey() ); - break; - } - } - } + QString uid = incidence->uid(); + + QPtrList<Incidence> relations = incidence->relations(); + for( Incidence* i = relations.first(); i; i = relations.next() ) + if( !mOrphanUids.find( i->uid() ) ) { + mOrphans.insert( uid, i ); + mOrphanUids.insert( i->uid(), i ); + i->setRelatedTo( 0 ); + i->setRelatedToUid( uid ); + } + + // If this incidence is related to something else, tell that about it + if( incidence->relatedTo() ) + incidence->relatedTo()->removeRelation( incidence ); + + // Remove this one from the orphans list + if( mOrphanUids.remove( uid ) ) + // This incidence is located in the orphans list - it should be removed + if( !( incidence->relatedTo() != 0 && mOrphans.remove( incidence->relatedTo()->uid() ) ) ) { + // Removing wasn't that easy + for( QDictIterator<Incidence> it( mOrphans ); it.current(); ++it ) { + if( it.current()->uid() == uid ) { + mOrphans.remove( it.currentKey() ); + break; + } + } + } } void Calendar::registerObserver( Observer *observer ) { mObserver = observer; mNewObserver = true; } void Calendar::setModified( bool modified ) { if ( mObserver ) mObserver->calendarModified( modified, this ); if ( modified != mModified || mNewObserver ) { mNewObserver = false; // if ( mObserver ) mObserver->calendarModified( modified, this ); mModified = modified; } } void Calendar::setLoadedProductId( const QString &id ) { mLoadedProductId = id; } QString Calendar::loadedProductId() { return mLoadedProductId; } //#include "calendar.moc" diff --git a/libkcal/calendar.h b/libkcal/calendar.h index 73f82bb..2243e28 100644 --- a/libkcal/calendar.h +++ b/libkcal/calendar.h @@ -1,373 +1,374 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef CALENDAR_H #define CALENDAR_H #include <qobject.h> #include <qstring.h> #include <qdatetime.h> #include <qptrlist.h> #include <qdict.h> #include "customproperties.h" #include "event.h" #include "todo.h" #include "journal.h" #include "calfilter.h" //#define _TIME_ZONE "-0500" /* hardcoded, overridden in config file. */ class KConfig; namespace KCal { /** This is the main "calendar" object class for KOrganizer. It holds information like all appointments/events, user information, etc. etc. one calendar is associated with each CalendarView (@see calendarview.h). This is an abstract base class defining the interface to a calendar. It is implemented by subclasses like @see CalendarLocal, which use different methods to store and access the data. Ownership of events etc. is handled by the following policy: As soon as an event (or any other subclass of IncidenceBase) object is added to the Calendar by addEvent() it is owned by the Calendar object. The Calendar takes care of deleting it. All Events returned by the query functions are returned as pointers, that means all changes to the returned events are immediately visible in the Calendar. You shouldn't delete any Event object you get from Calendar. */ class Calendar : public QObject, public CustomProperties, public IncidenceBase::Observer { Q_OBJECT public: Calendar(); Calendar(const QString &timeZoneId); virtual ~Calendar(); Incidence * undoIncidence() { return mUndoIncidence; }; bool undoDeleteIncidence(); void deleteIncidence(Incidence *in); void resetTempSyncStat(); void resetPilotStat(int id); /** Clears out the current calendar, freeing all used memory etc. */ virtual void close() = 0; virtual void addCalendar( Calendar* ) = 0; virtual bool addCalendarFile( QString name, int id ) = 0; /** Sync changes in memory to persistant storage. */ virtual void save() = 0; virtual QPtrList<Event> getExternLastSyncEvents() = 0; virtual void removeSyncInfo( QString syncProfile) = 0; virtual bool isSaving() { return false; } /** Return the owner of the calendar's full name. */ const QString &getOwner() const; /** Set the owner of the calendar. Should be owner's full name. */ void setOwner( const QString &os ); /** Return the email address of the calendar owner. */ const QString &getEmail(); /** Set the email address of the calendar owner. */ void setEmail( const QString & ); /** Set time zone from a timezone string (e.g. -2:00) */ void setTimeZone( const QString &tz ); /** Set time zone from a minutes value (e.g. -60) */ void setTimeZone( int tz ); /** Return time zone as offest in minutes. */ int getTimeZone() const; /** Compute an ISO 8601 format string from the time zone. */ QString getTimeZoneStr() const; /** Set time zone id (see /usr/share/zoneinfo/zone.tab for list of legal values). */ void setTimeZoneId( const QString & ); /** Return time zone id. */ QString timeZoneId() const; /** Use local time, not UTC or a time zone. */ void setLocalTime(); /** Return whether local time is being used. */ bool isLocalTime() const; /** Add an incidence to calendar. @return true on success, false on error. */ virtual bool addIncidence( Incidence * ); // Adds an incidence and all relatedto incidences to the cal void addIncidenceBranch( Incidence * ); /** Return filtered list of all incidences of this calendar. */ virtual QPtrList<Incidence> incidences(); /** Return unfiltered list of all incidences of this calendar. */ virtual QPtrList<Incidence> rawIncidences(); /** Adds a Event to this calendar object. @param anEvent a pointer to the event to add @return true on success, false on error. */ virtual bool addEventNoDup( Event *event ) = 0; virtual bool addAnniversaryNoDup( Event *event ) = 0; virtual bool addEvent( Event *anEvent ) = 0; /** Delete event from calendar. */ virtual void deleteEvent( Event * ) = 0; /** Retrieves an event on the basis of the unique string ID. */ virtual Event *event( const QString &UniqueStr ) = 0; virtual Event *event( QString, QString ) = 0; /** Builds and then returns a list of all events that match for the date specified. useful for dayView, etc. etc. The calendar filter is applied. */ QPtrList<Event> events( const QDate &date, bool sorted = false); /** Get events, which occur on the given date. The calendar filter is applied. */ QPtrList<Event> events( const QDateTime &qdt ); /** Get events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. The calendar filter is applied. */ QPtrList<Event> events( const QDate &start, const QDate &end, bool inclusive = false); /** Return filtered list of all events in calendar. */ virtual QPtrList<Event> events(); /** Return unfiltered list of all events in calendar. */ virtual QPtrList<Event> rawEvents() = 0; /** Add a todo to the todolist. @return true on success, false on error. */ virtual bool addTodo( Todo *todo ) = 0; virtual bool addTodoNoDup( Todo *todo ) = 0; /** Remove a todo from the todolist. */ virtual void deleteTodo( Todo * ) = 0; virtual void deleteJournal( Journal * ) = 0; /** Return filterd list of todos. */ virtual QPtrList<Todo> todos(); /** Searches todolist for an event with this unique string identifier, returns a pointer or null. */ virtual Todo *todo( const QString &uid ) = 0; virtual Todo *todo( QString, QString ) = 0; /** Returns list of todos due on the specified date. */ virtual QPtrList<Todo> todos( const QDate &date ) = 0; /** Return unfiltered list of todos. */ virtual QPtrList<Todo> rawTodos() = 0; /** Add a Journal entry to calendar. @return true on success, false on error. */ virtual bool addJournal( Journal * ) = 0; /** Return Journal for given date. */ virtual Journal *journal( const QDate & ) = 0; /** Return Journal with given UID. */ virtual Journal *journal( const QString &UID ) = 0; /** Return list of all Journal entries. */ virtual QPtrList<Journal> journals() = 0; /** Searches all incidence types for an incidence with this unique string identifier, returns a pointer or null. */ Incidence* incidence( const QString&UID ); /** Setup relations for an incidence. */ virtual void setupRelations( Incidence * ); /** Remove all relations to an incidence */ virtual void removeRelations( Incidence * ); /** Set calendar filter, which filters events for the events() functions. The Filter object is owned by the caller. */ void setFilter( CalFilter * ); /** Return calendar filter. */ CalFilter *filter(); virtual QDateTime nextAlarm( int daysTo ) = 0; virtual QString nextSummary( ) const = 0; virtual void reInitAlarmSettings() = 0; virtual QDateTime nextAlarmEventDateTime() const = 0; virtual void checkAlarmForIncidence( Incidence *, bool ) = 0; /** Return all alarms, which ocur in the given time interval. */ virtual Alarm::List alarms( const QDateTime &from, const QDateTime &to ) = 0; class Observer { public: virtual void calendarModified( bool, Calendar * ) = 0; }; void registerObserver( Observer * ); void setModified( bool ); /** Set product id returned by loadedProductId(). This function is only useful for the calendar loading code. */ void setLoadedProductId( const QString & ); /** Return product id taken from file that has been loaded. Returns QString::null, if no calendar has been loaded. */ QString loadedProductId(); int defaultCalendar(); void setDontDeleteIncidencesOnClose (); public slots: void setDefaultCalendar( int ); virtual void setCalendarEnabled( int id, bool enable ) = 0; virtual void setAlarmEnabled( int id, bool enable ) = 0; virtual void setReadOnly( int id, bool enable ) = 0; virtual void setDefaultCalendarEnabledOnly() = 0; + virtual void setCalendarRemove( int id ) = 0; signals: void calendarChanged(); void calendarSaved(); void calendarLoaded(); void addAlarm(const QDateTime &qdt, const QString ¬i ); void removeAlarm(const QDateTime &qdt, const QString ¬i ); protected: /** Get unfiltered events, which occur on the given date. */ virtual QPtrList<Event> rawEventsForDate( const QDateTime &qdt ) = 0; /** Get unfiltered events, which occur on the given date. */ virtual QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false ) = 0; /** Get events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. */ virtual QPtrList<Event> rawEvents( const QDate &start, const QDate &end, bool inclusive = false ) = 0; Incidence *mNextAlarmIncidence; Incidence *mUndoIncidence; int mDefaultCalendar; bool mDeleteIncidencesOnClose; private: void init(); QString mOwner; // who the calendar belongs to QString mOwnerEmail; // email address of the owner int mTimeZone; // timezone OFFSET from GMT (MINUTES) bool mLocalTime; // use local time, not UTC or a time zone CalFilter *mFilter; CalFilter *mDefaultFilter; QString mTimeZoneId; Observer *mObserver; bool mNewObserver; bool mModified; QString mLoadedProductId; // This list is used to put together related todos QDict<Incidence> mOrphans; QDict<Incidence> mOrphanUids; }; } #endif diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp index e48122a..749d9f6 100644 --- a/libkcal/calendarlocal.cpp +++ b/libkcal/calendarlocal.cpp @@ -1,834 +1,890 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <kdebug.h> #include <kconfig.h> #include <kglobal.h> #include <klocale.h> #include "vcaldrag.h" #include "vcalformat.h" #include "icalformat.h" #include "exceptions.h" #include "incidence.h" #include "journal.h" #include "filestorage.h" #include "calfilter.h" #include "calendarlocal.h" // #ifndef DESKTOP_VERSION // #include <qtopia/alarmserver.h> // #endif using namespace KCal; CalendarLocal::CalendarLocal() : Calendar() { init(); } CalendarLocal::CalendarLocal(const QString &timeZoneId) : Calendar(timeZoneId) { init(); } void CalendarLocal::init() { mNextAlarmIncidence = 0; } CalendarLocal::~CalendarLocal() { if ( mDeleteIncidencesOnClose ) close(); } bool CalendarLocal::addCalendarFile( QString name, int id ) { CalendarLocal calendar( timeZoneId() ); calendar.setDefaultCalendar( id ); if ( calendar.load( name ) ) { addCalendar( &calendar ); return true; } return false; } void CalendarLocal::addCalendar( Calendar* cal ) { cal->setDontDeleteIncidencesOnClose(); { QPtrList<Event> EventList = cal->rawEvents(); Event * ev = EventList.first(); while ( ev ) { + ev->unRegisterObserver( cal ); + ev->registerObserver( this ); mEventList.append( ev ); ev = EventList.next(); } } { + QPtrList<Todo> TodoList = cal->rawTodos(); Todo * ev = TodoList.first(); while ( ev ) { + QString rel = ev->relatedToUid(); + if ( !rel.isEmpty() ){ + ev->setRelatedTo ( 0 ); + ev->setRelatedToUid( rel ); + } + ev = TodoList.next(); + } + //TodoList = cal->rawTodos(); + ev = TodoList.first(); + while ( ev ) { + ev->unRegisterObserver( cal ); + ev->registerObserver( this ); mTodoList.append( ev ); + setupRelations( ev ); ev = TodoList.next(); } } { QPtrList<Journal> JournalList = cal->journals(); Journal * ev = JournalList.first(); while ( ev ) { + ev->unRegisterObserver( cal ); + ev->registerObserver( this ); mJournalList.append( ev ); ev = JournalList.next(); } } + setModified( true ); } bool CalendarLocal::load( const QString &fileName ) { FileStorage storage( this, fileName ); return storage.load(); } bool CalendarLocal::save( const QString &fileName, CalFormat *format ) { FileStorage storage( this, fileName, format ); return storage.save(); } void CalendarLocal::close() { Todo * i; for( i = mTodoList.first(); i; i = mTodoList.next() ) i->setRunning(false); mEventList.setAutoDelete( true ); mTodoList.setAutoDelete( true ); mJournalList.setAutoDelete( false ); mEventList.clear(); mTodoList.clear(); mJournalList.clear(); mEventList.setAutoDelete( false ); mTodoList.setAutoDelete( false ); mJournalList.setAutoDelete( false ); setModified( false ); } bool CalendarLocal::addAnniversaryNoDup( Event *event ) { QString cat; bool isBirthday = true; if( event->categoriesStr() == i18n( "Anniversary" ) ) { isBirthday = false; cat = i18n( "Anniversary" ); } else if( event->categoriesStr() == i18n( "Birthday" ) ) { isBirthday = true; cat = i18n( "Birthday" ); } else { qDebug("addAnniversaryNoDup called without fitting category! "); return false; } Event * eve; for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) { if ( !(eve->categories().contains( cat ) )) continue; // now we have an event with fitting category if ( eve->dtStart().date() != event->dtStart().date() ) continue; // now we have an event with fitting category+date if ( eve->summary() != event->summary() ) continue; // now we have an event with fitting category+date+summary return false; } return addEvent( event ); } bool CalendarLocal::addEventNoDup( Event *event ) { Event * eve; for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) { if ( *eve == *event ) { //qDebug("CalendarLocal::Duplicate event found! Not inserted! "); return false; } } return addEvent( event ); } bool CalendarLocal::addEvent( Event *event ) { insertEvent( event ); event->registerObserver( this ); setModified( true ); event->setCalID( mDefaultCalendar ); event->setCalEnabled( true ); return true; } void CalendarLocal::deleteEvent( Event *event ) { if ( mUndoIncidence ) delete mUndoIncidence; mUndoIncidence = event->clone(); if ( mEventList.removeRef( event ) ) { setModified( true ); } } Event *CalendarLocal::event( const QString &uid ) { Event *event; for ( event = mEventList.first(); event; event = mEventList.next() ) { if ( event->uid() == uid && event->calEnabled() ) { return event; } } return 0; } bool CalendarLocal::addTodoNoDup( Todo *todo ) { Todo * eve; for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) { if ( *eve == *todo ) { //qDebug("duplicate todo found! not inserted! "); return false; } } return addTodo( todo ); } bool CalendarLocal::addTodo( Todo *todo ) { mTodoList.append( todo ); todo->registerObserver( this ); // Set up subtask relations setupRelations( todo ); setModified( true ); todo->setCalID( mDefaultCalendar ); todo->setCalEnabled( true ); return true; } void CalendarLocal::deleteTodo( Todo *todo ) { // Handle orphaned children if ( mUndoIncidence ) delete mUndoIncidence; removeRelations( todo ); mUndoIncidence = todo->clone(); if ( mTodoList.removeRef( todo ) ) { setModified( true ); } } QPtrList<Todo> CalendarLocal::rawTodos() { QPtrList<Todo> el; for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() ) if ( it->calEnabled() ) el.append( it ); return el; } Todo *CalendarLocal::todo( QString syncProf, QString id ) { Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo; } return 0; } void CalendarLocal::removeSyncInfo( QString syncProfile) { QPtrList<Incidence> all = rawIncidences() ; Incidence *inc; for ( inc = all.first(); inc; inc = all.next() ) { inc->removeID( syncProfile ); } if ( syncProfile.isEmpty() ) { QPtrList<Event> el; Event *todo; for ( todo = mEventList.first(); todo; todo = mEventList.next() ) { if ( todo->uid().left( 15 ) == QString("last-syncEvent-") ) el.append( todo ); } for ( todo = el.first(); todo; todo = el.next() ) { deleteIncidence ( todo ); } } else { Event *lse = event( "last-syncEvent-"+ syncProfile); if ( lse ) deleteIncidence ( lse ); } } QPtrList<Event> CalendarLocal::getExternLastSyncEvents() { QPtrList<Event> el; Event *todo; for ( todo = mEventList.first(); todo; todo = mEventList.next() ) { if ( todo->uid().left( 15 ) == QString("last-syncEvent-") ) if ( todo->summary().left(3) == "E: " ) el.append( todo ); } return el; } Event *CalendarLocal::event( QString syncProf, QString id ) { Event *todo; for ( todo = mEventList.first(); todo; todo = mEventList.next() ) { if ( todo->calEnabled() && todo->getID( syncProf ) == id ) return todo; } return 0; } Todo *CalendarLocal::todo( const QString &uid ) { Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( todo->calEnabled() && todo->uid() == uid ) return todo; } return 0; } QString CalendarLocal::nextSummary() const { return mNextSummary; } QDateTime CalendarLocal::nextAlarmEventDateTime() const { return mNextAlarmEventDateTime; } void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted) { //mNextAlarmIncidence //mNextAlarmDateTime //return mNextSummary; //return mNextAlarmEventDateTime; bool newNextAlarm = false; bool computeNextAlarm = false; bool ok; int offset; QDateTime nextA; // QString nextSum; //QDateTime nextEvent; if ( mNextAlarmIncidence == 0 || incidence == 0 ) { computeNextAlarm = true; } else { if ( ! deleted ) { nextA = incidence->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ; if ( ok ) { if ( nextA < mNextAlarmDateTime ) { deRegisterAlarm(); mNextAlarmDateTime = nextA; mNextSummary = incidence->summary(); mNextAlarmEventDateTime = nextA.addSecs(offset ) ; mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); newNextAlarm = true; mNextAlarmIncidence = incidence; } else { if ( incidence == mNextAlarmIncidence ) { computeNextAlarm = true; } } } else { if ( mNextAlarmIncidence == incidence ) { computeNextAlarm = true; } } } else { // deleted if ( incidence == mNextAlarmIncidence ) { computeNextAlarm = true; } } } if ( computeNextAlarm ) { deRegisterAlarm(); nextA = nextAlarm( 1000 ); if (! mNextAlarmIncidence ) { return; } newNextAlarm = true; } if ( newNextAlarm ) registerAlarm(); } QString CalendarLocal:: getAlarmNotification() { QString ret; // this should not happen if (! mNextAlarmIncidence ) return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString; Alarm* alarm = mNextAlarmIncidence->alarms().first(); if ( alarm->type() == Alarm::Procedure ) { ret = "proc_alarm" + alarm->programFile()+"+++"; } else { ret = "audio_alarm" +alarm->audioFile() +"+++"; } ret += "cal_alarm"+ mNextSummary.left( 25 ); if ( mNextSummary.length() > 25 ) ret += "\n" + mNextSummary.mid(25, 25 ); ret+= "\n"+mNextAlarmEventDateTimeString; return ret; } void CalendarLocal::registerAlarm() { mLastAlarmNotificationString = getAlarmNotification(); // qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() ); emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); // #ifndef DESKTOP_VERSION // AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() ); // #endif } void CalendarLocal::deRegisterAlarm() { if ( mLastAlarmNotificationString.isNull() ) return; //qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() ); emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); mNextAlarmEventDateTime = QDateTime(); // #ifndef DESKTOP_VERSION // AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() ); // #endif } QPtrList<Todo> CalendarLocal::todos( const QDate &date ) { QPtrList<Todo> todos; Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( !todo->calEnabled() ) continue; if ( todo->hasDueDate() && todo->dtDue().date() == date ) { todos.append( todo ); } } filter()->apply( &todos ); return todos; } void CalendarLocal::reInitAlarmSettings() { if ( !mNextAlarmIncidence ) { nextAlarm( 1000 ); } deRegisterAlarm(); mNextAlarmIncidence = 0; checkAlarmForIncidence( 0, false ); } QDateTime CalendarLocal::nextAlarm( int daysTo ) { QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo ); QDateTime start = QDateTime::currentDateTime().addSecs( 30 ); QDateTime next; Event *e; bool ok; bool found = false; int offset; mNextAlarmIncidence = 0; for( e = mEventList.first(); e; e = mEventList.next() ) { if ( !e->calEnabled() ) continue; next = e->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ; if ( ok ) { if ( next < nextA ) { nextA = next; found = true; mNextSummary = e->summary(); mNextAlarmEventDateTime = next.addSecs(offset ) ; mNextAlarmIncidence = (Incidence *) e; } } } Todo *t; for( t = mTodoList.first(); t; t = mTodoList.next() ) { if ( !t->calEnabled() ) continue; next = t->getNextAlarmDateTime(& ok, &offset, QDateTime::currentDateTime() ) ; if ( ok ) { if ( next < nextA ) { nextA = next; found = true; mNextSummary = t->summary(); mNextAlarmEventDateTime = next.addSecs(offset ); mNextAlarmIncidence = (Incidence *) t; } } } if ( mNextAlarmIncidence ) { mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); mNextAlarmDateTime = nextA; } return nextA; } Alarm::List CalendarLocal::alarmsTo( const QDateTime &to ) { return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to ); } Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to ) { Alarm::List alarms; Event *e; for( e = mEventList.first(); e; e = mEventList.next() ) { if ( !e->calEnabled() ) continue; if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to ); else appendAlarms( alarms, e, from, to ); } Todo *t; for( t = mTodoList.first(); t; t = mTodoList.next() ) { if ( !t->calEnabled() ) continue; appendAlarms( alarms, t, from, to ); } return alarms; } void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ) { QPtrList<Alarm> alarmList = incidence->alarms(); Alarm *alarm; for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { // kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text() // << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl; if ( alarm->enabled() ) { if ( alarm->time() >= from && alarm->time() <= to ) { alarms.append( alarm ); } } } } void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ) { QPtrList<Alarm> alarmList = incidence->alarms(); Alarm *alarm; QDateTime qdt; for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { if (incidence->recursOn(from.date())) { qdt.setTime(alarm->time().time()); qdt.setDate(from.date()); } else qdt = alarm->time(); // qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1()); if ( alarm->enabled() ) { if ( qdt >= from && qdt <= to ) { alarms.append( alarm ); } } } } /****************************** PROTECTED METHODS ****************************/ // after changes are made to an event, this should be called. void CalendarLocal::update( IncidenceBase *incidence ) { incidence->setSyncStatus( Event::SYNCMOD ); incidence->setLastModified( QDateTime::currentDateTime() ); // we should probably update the revision number here, // or internally in the Event itself when certain things change. // need to verify with ical documentation. setModified( true ); } void CalendarLocal::insertEvent( Event *event ) { if ( mEventList.findRef( event ) < 0 ) mEventList.append( event ); } QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted ) { QPtrList<Event> eventList; Event *event; for( event = mEventList.first(); event; event = mEventList.next() ) { if ( !event->calEnabled() ) continue; if ( event->doesRecur() ) { if ( event->isMultiDay() ) { int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() ); int i; for ( i = 0; i <= extraDays; i++ ) { if ( event->recursOn( qd.addDays( -i ) ) ) { eventList.append( event ); break; } } } else { if ( event->recursOn( qd ) ) eventList.append( event ); } } else { if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) { eventList.append( event ); } } } if ( !sorted ) { return eventList; } // kdDebug(5800) << "Sorting events for date\n" << endl; // now, we have to sort it based on dtStart.time() QPtrList<Event> eventListSorted; Event *sortEvent; for ( event = eventList.first(); event; event = eventList.next() ) { sortEvent = eventListSorted.first(); int i = 0; while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() ) { i++; sortEvent = eventListSorted.next(); } eventListSorted.insert( i, event ); } return eventListSorted; } QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end, bool inclusive ) { Event *event = 0; QPtrList<Event> eventList; // Get non-recurring events for( event = mEventList.first(); event; event = mEventList.next() ) { if ( !event->calEnabled() ) continue; if ( event->doesRecur() ) { QDate rStart = event->dtStart().date(); bool found = false; if ( inclusive ) { if ( rStart >= start && rStart <= end ) { // Start date of event is in range. Now check for end date. // if duration is negative, event recurs forever, so do not include it. if ( event->recurrence()->duration() == 0 ) { // End date set QDate rEnd = event->recurrence()->endDate(); if ( rEnd >= start && rEnd <= end ) { // End date within range found = true; } } else if ( event->recurrence()->duration() > 0 ) { // Duration set // TODO: Calculate end date from duration. Should be done in Event // For now exclude all events with a duration. } } } else { bool founOne; QDate next = event->getNextOccurence( start, &founOne ).date(); if ( founOne ) { if ( next <= end ) { found = true; } } /* // crap !!! if ( rStart <= end ) { // Start date not after range if ( rStart >= start ) { // Start date within range found = true; } else if ( event->recurrence()->duration() == -1 ) { // Recurs forever found = true; } else if ( event->recurrence()->duration() == 0 ) { // End date set QDate rEnd = event->recurrence()->endDate(); if ( rEnd >= start && rEnd <= end ) { // End date within range found = true; } } else { // Duration set // TODO: Calculate end date from duration. Should be done in Event // For now include all events with a duration. found = true; } } */ } if ( found ) eventList.append( event ); } else { QDate s = event->dtStart().date(); QDate e = event->dtEnd().date(); if ( inclusive ) { if ( s >= start && e <= end ) { eventList.append( event ); } } else { if ( ( s >= start && s <= end ) || ( e >= start && e <= end ) ) { eventList.append( event ); } } } } return eventList; } QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt ) { return rawEventsForDate( qdt.date() ); } QPtrList<Event> CalendarLocal::rawEvents() { QPtrList<Event> el; for ( Event *it = mEventList.first(); it; it = mEventList.next() ) if ( it->calEnabled() ) el.append( it ); return el; } bool CalendarLocal::addJournal(Journal *journal) { if ( journal->dtStart().isValid()) kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl; else kdDebug(5800) << "Adding Journal without a DTSTART" << endl; mJournalList.append(journal); journal->registerObserver( this ); setModified( true ); journal->setCalID( mDefaultCalendar ); journal->setCalEnabled( true ); return true; } void CalendarLocal::deleteJournal( Journal *journal ) { if ( mUndoIncidence ) delete mUndoIncidence; mUndoIncidence = journal->clone(); mUndoIncidence->setSummary( mUndoIncidence->description().left(25)); if ( mJournalList.removeRef(journal) ) { setModified( true ); } } Journal *CalendarLocal::journal( const QDate &date ) { // kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl; for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calEnabled() && it->dtStart().date() == date ) return it; return 0; } Journal *CalendarLocal::journal( const QString &uid ) { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calEnabled() && it->uid() == uid ) return it; return 0; } QPtrList<Journal> CalendarLocal::journals() { QPtrList<Journal> el; for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calEnabled() ) el.append( it ); return el; } +void CalendarLocal::setCalendarRemove( int id ) +{ + + { + QPtrList<Event> EventList = mEventList; + Event * ev = EventList.first(); + while ( ev ) { + if ( ev->calID() == id ) + deleteEvent( ev ); + ev = EventList.next(); + } + } + { + + QPtrList<Todo> TodoList = mTodoList; + Todo * ev = TodoList.first(); + while ( ev ) { + if ( ev->calID() == id ) + deleteTodo( ev ); + ev = TodoList.next(); + } + } + { + QPtrList<Journal> JournalList = mJournalList; + Journal * ev = JournalList.first(); + while ( ev ) { + if ( ev->calID() == id ) + deleteJournal( ev ); + ev = JournalList.next(); + } + } + + if ( mUndoIncidence ) delete mUndoIncidence; + mUndoIncidence = 0; + +} void CalendarLocal::setCalendarEnabled( int id, bool enable ) { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calID() == id ) it->setCalEnabled( enable ); for ( Event *it = mEventList.first(); it; it = mEventList.next() ) if ( it->calID() == id ) it->setCalEnabled( enable ); for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() ) if ( it->calID() == id ) it->setCalEnabled( enable ); } void CalendarLocal::setReadOnly( int id, bool enable ) { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calID() == id ) it->setReadOnly( enable ); for ( Event *it = mEventList.first(); it; it = mEventList.next() ) if ( it->calID() == id ) it->setReadOnly( enable ); for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() ) if ( it->calID() == id ) it->setReadOnly( enable ); } void CalendarLocal::setAlarmEnabled( int id, bool enable ) { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->calID() == id ) it->setAlarmEnabled( enable ); for ( Event *it = mEventList.first(); it; it = mEventList.next() ) if ( it->calID() == id ) it->setAlarmEnabled( enable ); for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() ) if ( it->calID() == id ) it->setAlarmEnabled( enable ); + reInitAlarmSettings(); } void CalendarLocal::setDefaultCalendarEnabledOnly() { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) it->setCalEnabled( it->calID() == mDefaultCalendar ); for ( Event *it = mEventList.first(); it; it = mEventList.next() ) it->setCalEnabled( it->calID() == mDefaultCalendar); for ( Todo *it = mTodoList.first(); it; it = mTodoList.next() ) it->setCalEnabled( it->calID() == mDefaultCalendar); } diff --git a/libkcal/calendarlocal.h b/libkcal/calendarlocal.h index 65f6aa7..5bbe55f 100644 --- a/libkcal/calendarlocal.h +++ b/libkcal/calendarlocal.h @@ -1,223 +1,224 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef KCAL_CALENDARLOCAL_H #define KCAL_CALENDARLOCAL_H #include "calendar.h" namespace KCal { class CalFormat; /** This class provides a calendar stored as a local file. */ class CalendarLocal : public Calendar { public: /** Constructs a new calendar, with variables initialized to sane values. */ CalendarLocal(); /** Constructs a new calendar, with variables initialized to sane values. */ CalendarLocal( const QString &timeZoneId ); ~CalendarLocal(); void addCalendar( Calendar* ); bool addCalendarFile( QString name, int id ); /** Loads a calendar on disk in vCalendar or iCalendar format into the current calendar. Any information already present is lost. @return true, if successfull, false on error. @param fileName the name of the calendar on disk. */ bool load( const QString &fileName ); /** Writes out the calendar to disk in the specified \a format. CalendarLocal takes ownership of the CalFormat object. @return true, if successfull, false on error. @param fileName the name of the file */ bool save( const QString &fileName, CalFormat *format = 0 ); /** Clears out the current calendar, freeing all used memory etc. etc. */ void close(); void save() {} /** Add Event to calendar. */ void removeSyncInfo( QString syncProfile); bool addAnniversaryNoDup( Event *event ); bool addEventNoDup( Event *event ); bool addEvent( Event *event ); /** Deletes an event from this calendar. */ void deleteEvent( Event *event ); /** Retrieves an event on the basis of the unique string ID. */ Event *event( const QString &uid ); /** Return unfiltered list of all events in calendar. */ QPtrList<Event> rawEvents(); QPtrList<Event> getExternLastSyncEvents(); /** Add a todo to the todolist. */ bool addTodo( Todo *todo ); bool addTodoNoDup( Todo *todo ); /** Remove a todo from the todolist. */ void deleteTodo( Todo * ); /** Searches todolist for an event with this unique string identifier, returns a pointer or null. */ Todo *todo( const QString &uid ); /** Return list of all todos. */ QPtrList<Todo> rawTodos(); /** Returns list of todos due on the specified date. */ QPtrList<Todo> todos( const QDate &date ); /** Return list of all todos. Workaround because compiler does not recognize function of base class. */ QPtrList<Todo> todos() { return Calendar::todos(); } /** Add a Journal entry to calendar. */ bool addJournal( Journal * ); /** Remove a Journal from the calendar. */ void deleteJournal( Journal * ); /** Return Journal for given date. */ Journal *journal( const QDate & ); /** Return Journal with given UID. */ Journal *journal( const QString &uid ); /** Return list of all Journals stored in calendar. */ QPtrList<Journal> journals(); /** Return all alarms, which ocur in the given time interval. */ Alarm::List alarms( const QDateTime &from, const QDateTime &to ); /** Return all alarms, which ocur before given date. */ Alarm::List alarmsTo( const QDateTime &to ); QDateTime nextAlarm( int daysTo ) ; QDateTime nextAlarmEventDateTime() const; void checkAlarmForIncidence( Incidence *, bool deleted ) ; void registerAlarm(); void deRegisterAlarm(); QString getAlarmNotification(); QString nextSummary() const ; /** This method should be called whenever a Event is modified directly via it's pointer. It makes sure that the calendar is internally consistent. */ void update( IncidenceBase *incidence ); /** Builds and then returns a list of all events that match for the date specified. useful for dayView, etc. etc. */ QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false ); /** Get unfiltered events for date \a qdt. */ QPtrList<Event> rawEventsForDate( const QDateTime &qdt ); /** Get unfiltered events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. */ QPtrList<Event> rawEvents( const QDate &start, const QDate &end, bool inclusive = false ); Todo *todo( QString, QString ); Event *event( QString, QString ); public slots: void setCalendarEnabled( int id, bool enable ); void setAlarmEnabled( int id, bool enable ); void setReadOnly( int id, bool enable ); void setDefaultCalendarEnabledOnly(); + void setCalendarRemove( int id ); protected: // Event* mNextAlarmEvent; QString mNextSummary; QString mNextAlarmEventDateTimeString; QString mLastAlarmNotificationString; QDateTime mNextAlarmEventDateTime; QDateTime mNextAlarmDateTime; void reInitAlarmSettings(); /** Notification function of IncidenceBase::Observer. */ void incidenceUpdated( IncidenceBase *i ) { update( i ); } /** inserts an event into its "proper place" in the calendar. */ void insertEvent( Event *event ); /** Append alarms of incidence in interval to list of alarms. */ void appendAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ); /** Append alarms of recurring events in interval to list of alarms. */ void appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ); private: void init(); QPtrList<Event> mEventList; QPtrList<Todo> mTodoList; QPtrList<Journal> mJournalList; }; } #endif |