summaryrefslogtreecommitdiffabout
path: root/libkcal
Side-by-side diff
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/calendar.cpp11
-rw-r--r--libkcal/calendar.h3
-rw-r--r--libkcal/calendarlocal.cpp17
-rw-r--r--libkcal/incidence.cpp14
-rw-r--r--libkcal/incidence.h1
5 files changed, 39 insertions, 7 deletions
diff --git a/libkcal/calendar.cpp b/libkcal/calendar.cpp
index 52daaaa..88351eb 100644
--- a/libkcal/calendar.cpp
+++ b/libkcal/calendar.cpp
@@ -7,160 +7,169 @@
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( i18n (" 00:00 Europe/London(UTC)") );
}
Calendar::Calendar( const QString &timeZoneId )
{
init();
setTimeZoneId(timeZoneId);
}
void Calendar::init()
{
mObserver = 0;
mNewObserver = false;
-
+ mUndoIncidence = 0;
mModified = false;
// 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;
}
const QString &Calendar::getOwner() const
{
return mOwner;
}
+bool Calendar::undoDeleteIncidence()
+{
+ if (!mUndoIncidence)
+ return false;
+ addIncidence(mUndoIncidence);
+ mUndoIncidence = 0;
+}
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;
}
diff --git a/libkcal/calendar.h b/libkcal/calendar.h
index b7d6a1f..2f2c3aa 100644
--- a/libkcal/calendar.h
+++ b/libkcal/calendar.h
@@ -20,96 +20,98 @@
*/
#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;
/**
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.
*/
@@ -277,77 +279,78 @@ public:
*/
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();
signals:
void calendarChanged();
void calendarSaved();
void calendarLoaded();
void addAlarm(const QDateTime &qdt, const QString &noti );
void removeAlarm(const QDateTime &qdt, const QString &noti );
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;
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 3f46d53..12294c0 100644
--- a/libkcal/calendarlocal.cpp
+++ b/libkcal/calendarlocal.cpp
@@ -107,146 +107,148 @@ bool CalendarLocal::addAnniversaryNoDup( Event *event )
} 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 );
return true;
}
void CalendarLocal::deleteEvent( Event *event )
{
-
-
- if ( mEventList.removeRef( event ) ) {
- setModified( true );
- }
+ 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 ) {
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 );
return true;
}
void CalendarLocal::deleteTodo( Todo *todo )
{
// Handle orphaned children
- removeRelations( todo );
+ if ( mUndoIncidence ) delete mUndoIncidence;
+ mUndoIncidence = todo->clone();
+ removeRelations( todo );
if ( mTodoList.removeRef( todo ) ) {
setModified( true );
}
}
QPtrList<Todo> CalendarLocal::rawTodos()
{
return mTodoList;
}
Todo *CalendarLocal::todo( QString syncProf, QString id )
{
Todo *todo;
for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
if ( 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);
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: " )
@@ -642,78 +644,81 @@ QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end,
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()
{
return mEventList;
}
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 );
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->dtStart().date() == date )
return it;
return 0;
}
Journal *CalendarLocal::journal( const QString &uid )
{
for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
if ( it->uid() == uid )
return it;
return 0;
}
QPtrList<Journal> CalendarLocal::journals()
{
return mJournalList;
}
diff --git a/libkcal/incidence.cpp b/libkcal/incidence.cpp
index 5a9ef0e..28402ae 100644
--- a/libkcal/incidence.cpp
+++ b/libkcal/incidence.cpp
@@ -128,96 +128,110 @@ bool KCal::operator==( const Incidence& i1, const Incidence& i2 )
{
qDebug("alarm not equal ");
return false;
}
}
#if 0
QPtrListIterator<Alarm> a1( i1.alarms() );
QPtrListIterator<Alarm> a2( i2.alarms() );
for( ; a1.current() && a2.current(); ++a1, ++a2 ) {
if( *a1.current() == *a2.current() ) {
continue;
}
else {
return false;
}
}
#endif
if ( ! operator==( (const IncidenceBase&)i1, (const IncidenceBase&)i2 ) )
return false;
if ( i1.hasStartDate() == i2.hasStartDate() ) {
if ( i1.hasStartDate() ) {
if ( i1.dtStart() != i2.dtStart() )
return false;
}
} else {
return false;
}
if (!( *i1.recurrence() == *i2.recurrence()) ) {
qDebug("recurrence is NOT equal ");
return false;
}
return
// i1.created() == i2.created() &&
stringCompare( i1.description(), i2.description() ) &&
stringCompare( i1.summary(), i2.summary() ) &&
i1.categories() == i2.categories() &&
// no need to compare mRelatedTo
stringCompare( i1.relatedToUid(), i2.relatedToUid() ) &&
// i1.relations() == i2.relations() &&
i1.exDates() == i2.exDates() &&
i1.attachments() == i2.attachments() &&
i1.resources() == i2.resources() &&
i1.secrecy() == i2.secrecy() &&
i1.priority() == i2.priority() &&
stringCompare( i1.location(), i2.location() );
}
+Incidence* Incidence::recreateCloneException( QDate d )
+{
+ Incidence* newInc = clone();
+ newInc->recreate();
+ if ( doesRecur() ) {
+ addExDate( d );
+ newInc->recurrence()->unsetRecurs();
+ int len = dtStart().secsTo( ((Event*)this)->dtEnd());
+ QTime tim = dtStart().time();
+ newInc->setDtStart( QDateTime(d, tim) );
+ ((Event*)newInc)->setDtEnd( newInc->dtStart().addSecs( len ) );
+ }
+ return newInc;
+}
void Incidence::recreate()
{
setCreated(QDateTime::currentDateTime());
setUid(CalFormat::createUniqueId());
setRevision(0);
setIDStr( ":" );
setLastModified(QDateTime::currentDateTime());
}
void Incidence::setReadOnly( bool readOnly )
{
IncidenceBase::setReadOnly( readOnly );
recurrence()->setRecurReadOnly( readOnly);
}
void Incidence::setCreated(QDateTime created)
{
if (mReadOnly) return;
mCreated = getEvenTime(created);
}
QDateTime Incidence::created() const
{
return mCreated;
}
void Incidence::setRevision(int rev)
{
if (mReadOnly) return;
mRevision = rev;
updated();
}
int Incidence::revision() const
{
return mRevision;
}
void Incidence::setDtStart(const QDateTime &dtStart)
{
QDateTime dt = getEvenTime(dtStart);
recurrence()->setRecurStart( dt);
IncidenceBase::setDtStart( dt );
diff --git a/libkcal/incidence.h b/libkcal/incidence.h
index 7dc6f10..1807bc4 100644
--- a/libkcal/incidence.h
+++ b/libkcal/incidence.h
@@ -77,96 +77,97 @@ class Incidence : public IncidenceBase
/** Constructor is protected to prevent direct creation of visitor base class. */
Visitor() {}
};
/**
This class implements a visitor for adding an Incidence to a resource
supporting addEvent(), addTodo() and addJournal() calls.
*/
template<class T>
class AddVisitor : public Visitor
{
public:
AddVisitor( T *r ) : mResource( r ) {}
bool visit( Event *e ) { return mResource->addEvent( e ); }
bool visit( Todo *t ) { return mResource->addTodo( t ); }
bool visit( Journal *j ) { return mResource->addJournal( j ); }
private:
T *mResource;
};
/** enumeration for describing an event's secrecy. */
enum { SecrecyPublic = 0, SecrecyPrivate = 1, SecrecyConfidential = 2 };
typedef ListBase<Incidence> List;
Incidence();
Incidence(const Incidence &);
~Incidence();
/**
Accept IncidenceVisitor. A class taking part in the visitor mechanism has to
provide this implementation:
<pre>
bool accept(Visitor &v) { return v.visit(this); }
</pre>
*/
virtual bool accept(Visitor &) { return false; }
virtual Incidence *clone() = 0;
virtual QDateTime getNextAlarmDateTime( bool * ok, int * offset ) const = 0;
void setReadOnly( bool );
/**
Recreate event. The event is made a new unique event, but already stored
event information is preserved. Sets uniquie id, creation date, last
modification date and revision number.
*/
void recreate();
+ Incidence* recreateCloneException(QDate);
/** set creation date */
void setCreated(QDateTime);
/** return time and date of creation. */
QDateTime created() const;
/** set the number of revisions this event has seen */
void setRevision(int rev);
/** return the number of revisions this event has seen */
int revision() const;
/** Set starting date/time. */
virtual void setDtStart(const QDateTime &dtStart);
/** Return the incidence's ending date/time as a QDateTime. */
virtual QDateTime dtEnd() const { return QDateTime(); }
/** sets the event's lengthy description. */
void setDescription(const QString &description);
/** returns a reference to the event's description. */
QString description() const;
/** sets the event's short summary. */
void setSummary(const QString &summary);
/** returns a reference to the event's summary. */
QString summary() const;
/** set event's applicable categories */
void setCategories(const QStringList &categories);
/** set event's categories based on a comma delimited string */
void setCategories(const QString &catStr);
/** return categories in a list */
QStringList categories() const;
/** return categories as a comma separated string */
QString categoriesStr();
/** point at some other event to which the event relates. This function should
* only be used when constructing a calendar before the related Event
* exists. */
void setRelatedToUid(const QString &);
/** what event does this one relate to? This function should
* only be used when constructing a calendar before the related Event
* exists. */
QString relatedToUid() const;
/** point at some other event to which the event relates */
void setRelatedTo(Incidence *relatedTo);
/** what event does this one relate to? */
Incidence *relatedTo() const;
/** All events that are related to this event */