summaryrefslogtreecommitdiff
path: root/libopie2
Side-by-side diff
Diffstat (limited to 'libopie2') (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.cpp156
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend.h32
-rw-r--r--libopie2/opiepim/core/odatebookaccess.cpp37
-rw-r--r--libopie2/opiepim/core/odatebookaccess.h32
-rw-r--r--libopie2/opiepim/oevent.cpp13
-rw-r--r--libopie2/opiepim/oevent.h6
6 files changed, 266 insertions, 10 deletions
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp
new file mode 100644
index 0000000..8fa1a68
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp
@@ -0,0 +1,156 @@
+#include <qtl.h>
+
+#include "orecur.h"
+
+#include "odatebookaccessbackend.h"
+
+namespace {
+/* a small helper to get all NonRepeating events for a range of time */
+ void events( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& events,
+ const QDate& from, const QDate& to ) {
+ QDateTime dtStart, dtEnd;
+
+ for ( OEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) {
+ dtStart = (*it).startDateTime();
+ dtEnd = (*it).endDateTime();
+
+ /*
+ * If in range
+ */
+ if (dtStart.date() >= from && dtEnd.date() <= to ) {
+ OEffectiveEvent eff;
+ eff.setEvent( (*it) );
+ eff.setDate( dtStart.date() );
+ eff.setStartTime( dtStart.time() );
+
+ /* if not on the same day */
+ if ( dtStart.date() != dtEnd.date() )
+ eff.setEndTime( QTime(23, 59, 0 ) );
+ else
+ eff.setEndTime( dtEnd.time() );
+
+ tmpList.append( eff );
+ }
+
+ /* we must also check for end date information... */
+ if ( dtEnd.date() != dtStart.date() && dtEnd.date() >= from ) {
+ QDateTime dt = dtStart.addDays( 1 );
+ dt.setTime( QTime(0, 0, 0 ) );
+ QDateTime dtStop;
+ if ( dtEnd > to )
+ dtStop = to;
+ else
+ dtStop = dtEnd;
+
+ while ( dt <= dtStop ) {
+ OEffectiveEvent eff;
+ eff.setEvent( (*it) );
+ eff.setDate( dt.date() );
+
+ if ( dt >= from ) {
+ eff.setStartTime( QTime(0, 0, 0 ) );
+ if ( dt.date() == dtEnd.date() )
+ eff.setEndTime( dtEnd.time() );
+ else
+ eff.setEndTime( QTime(23, 59, 0 ) );
+ tmpList.append( eff );
+ }
+ dt = dt.addDays( 1 );
+ }
+ }
+ }
+ }
+
+ void repeat( OEffectiveEvent::ValueList& tmpList, const OEvent::ValueList& list,
+ const QDate& from, const QDate& to ) {
+ QDate repeat;
+ for ( OEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) {
+ int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() );
+ QDate itDate = from.addDays(-dur );
+ ORecur rec = (*it).recurrence();
+ if ( !rec.hasEndDate() || rec.endDate() > to ) {
+ rec.setEndDate( to );
+ rec.setHasEndDate( true );
+ }
+ while (rec.nextOcurrence(itDate, repeat ) ) {
+ if (repeat > to ) break;
+ OEffectiveEvent eff;
+ eff.setDate( repeat );
+ if ( (*it).isAllDay() ) {
+ eff.setStartTime( QTime(0, 0, 0 ) );
+ eff.setEndTime( QTime(23, 59, 59 ) );
+ }else {
+ /* we only occur by days, not hours/minutes/seconds. Hence
+ * the actual end and start times will be the same for
+ * every repeated event. For multi day events this is
+ * fixed up later if on wronge day span
+ */
+ eff.setStartTime( (*it).startDateTime().time() );
+ eff.setEndTime( (*it).endDateTime().time() );
+ }
+ if ( dur != 0 ) {
+ // multi-day repeating events
+ QDate sub_it = QMAX( repeat, from );
+ QDate startDate = repeat;
+ QDate endDate = startDate.addDays( dur );
+
+ while ( sub_it <= endDate && sub_it <= to ) {
+ OEffectiveEvent tmpEff = eff;
+ tmpEff.setEvent( (*it) );
+ if ( sub_it != startDate )
+ tmpEff.setStartTime( QTime(0, 0, 0 ) );
+ if ( sub_it != endDate )
+ tmpEff.setEndTime( QTime( 23, 59, 59 ) );
+
+ tmpEff.setDate( sub_it );
+ tmpEff.setEffectiveDates( startDate, endDate );
+ tmpList.append( tmpEff );
+
+ sub_it = sub_it.addDays( 1 );
+ }
+ itDate = endDate;
+ }else {
+ eff.setEvent( (*it) );
+ tmpList.append( eff );
+ itDate = repeat.addDays( 1 );
+ }
+ }
+ }
+ }
+}
+
+ODateBookAccessBackend::ODateBookAccessBackend()
+ : OPimAccessBackend<OEvent>()
+{
+
+}
+ODateBookAccessBackend::~ODateBookAccessBackend() {
+
+}
+OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDate& from,
+ const QDate& to ) {
+ OEffectiveEvent::ValueList tmpList;
+ OEvent::ValueList list = directNonRepeats();
+
+ events( tmpList, list, from, to );
+ repeat( tmpList, directRawRepeats(),from,to );
+
+ list = directRawRepeats();
+
+ qHeapSort( tmpList );
+ return tmpList;
+}
+OEffectiveEvent::ValueList ODateBookAccessBackend::effecticeEvents( const QDateTime& dt ) {
+ OEffectiveEvent::ValueList day = effecticeEvents( dt.date(), dt.date() );
+ OEffectiveEvent::ValueList::Iterator it;
+
+ OEffectiveEvent::ValueList tmpList;
+ QDateTime dtTmp;
+ for ( it = day.begin(); it != day.end(); ++it ) {
+ dtTmp = QDateTime( (*it).date(), (*it).startTime() );
+ if ( QABS(dt.secsTo(dtTmp) ) < 60 )
+ tmpList.append( (*it) );
+ }
+
+ return tmpList;
+}
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.h b/libopie2/opiepim/backend/odatebookaccessbackend.h
new file mode 100644
index 0000000..eb6e8fb
--- a/dev/null
+++ b/libopie2/opiepim/backend/odatebookaccessbackend.h
@@ -0,0 +1,32 @@
+#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_H
+#define OPIE_DATE_BOOK_ACCESS_BACKEND_H
+
+#include <qarray.h>
+
+#include "opimaccessbackend.h"
+#include "oevent.h"
+
+class ODateBookAccessBackend : public OPimAccessBackend<OEvent> {
+public:
+ typedef int UID;
+ ODateBookAccessBackend();
+ ~ODateBookAccessBackend();
+
+ virtual QArray<UID> rawEvents()const = 0;
+ virtual QArray<UID> rawRepeats()const = 0;
+ virtual QArray<UID> nonRepeats() const = 0;
+
+ /**
+ * these two methods are used if you do not implement
+ * effectiveEvents...
+ */
+ virtual OEvent::ValueList directNonRepeats() = 0;
+ virtual OEvent::ValueList directRawRepeats() = 0;
+
+ /* is implemented by default but you can reimplement it*/
+ virtual OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to );
+ virtual OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start );
+
+};
+
+#endif
diff --git a/libopie2/opiepim/core/odatebookaccess.cpp b/libopie2/opiepim/core/odatebookaccess.cpp
new file mode 100644
index 0000000..5f97e7c
--- a/dev/null
+++ b/libopie2/opiepim/core/odatebookaccess.cpp
@@ -0,0 +1,37 @@
+#include "obackendfactory.h"
+#include "odatebookaccess.h"
+
+ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
+ : OPimAccessTemplate<OEvent>( back )
+{
+ if (!back )
+ back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null );
+
+ m_backEnd = back;
+}
+ODateBookAccess::~ODateBookAccess() {
+}
+ODateBookAccess::List ODateBookAccess::rawEvents()const {
+ QArray<int> ints = m_backEnd->rawEvents();
+
+ List lis( ints, this );
+ return lis;
+}
+ODateBookAccess::List ODateBookAccess::rawRepeats()const {
+ QArray<int> ints = m_backEnd->rawRepeats();
+
+ List lis( ints, this );
+ return lis;
+}
+ODateBookAccess::List ODateBookAccess::nonRepeats()const {
+ QArray<int> ints = m_backEnd->nonRepeats();
+
+ List lis( ints, this );
+ return lis;
+}
+OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDate& from, const QDate& to ) {
+ return m_backEnd->effecticeEvents( from, to );
+}
+OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDateTime& start ) {
+ return m_backEnd->effecticeEvents( start );
+}
diff --git a/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h
new file mode 100644
index 0000000..3f2c728
--- a/dev/null
+++ b/libopie2/opiepim/core/odatebookaccess.h
@@ -0,0 +1,32 @@
+#ifndef OPIE_DATE_BOOK_ACCESS_H
+#define OPIE_DATE_BOOK_ACCESS_H
+
+#include "odatebookaccessbackend.h"
+#include "opimaccesstemplate.h"
+
+#include "oevent.h"
+
+class ODateBookAccess : public OPimAccessTemplate<OEvent> {
+public:
+ ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random );
+ ~ODateBookAccess();
+
+ /** return all events */
+ List rawEvents()const;
+
+ /** return repeating events */
+ List rawRepeats()const;
+
+ /** return non repeating events */
+ List nonRepeats()const;
+
+ OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to );
+ OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start );
+
+private:
+ ODateBookAccessBackend* m_backEnd;
+ class Private;
+ Private* d;
+};
+
+#endif
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
index 71b9441..aaae3b2 100644
--- a/libopie2/opiepim/oevent.cpp
+++ b/libopie2/opiepim/oevent.cpp
@@ -1,181 +1,180 @@
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/categories.h>
#include "orecur.h"
#include "opimresolver.h"
#include "opimnotifymanager.h"
#include "oevent.h"
-namespace OCalendarHelper {
- static int week( const QDate& date) {
+int OCalendarHelper::week( const QDate& date) {
// Calculates the week this date is in within that
// month. Equals the "row" is is in in the month view
int week = 1;
QDate tmp( date.year(), date.month(), 1 );
if ( date.dayOfWeek() < tmp.dayOfWeek() )
++week;
week += ( date.day() - 1 ) / 7;
return week;
}
- static int occurence( const QDate& date) {
+int OCalendarHelper::ocurrence( const QDate& date) {
// calculates the number of occurrances of this day of the
// week till the given date (e.g 3rd Wednesday of the month)
return ( date.day() - 1 ) / 7 + 1;
}
- static int dayOfWeek( char day ) {
+int OCalendarHelper::dayOfWeek( char day ) {
int dayOfWeek = 1;
char i = ORecur::MON;
while ( !( i & day ) && i <= ORecur::SUN ) {
i <<= 1;
++dayOfWeek;
}
return dayOfWeek;
}
- static int monthDiff( const QDate& first, const QDate& second ) {
+int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) {
return ( second.year() - first.year() ) * 12 +
second.month() - first.month();
}
-}
struct OEvent::Data : public QShared {
Data() : QShared() {
recur = 0;
manager = 0;
isAllDay = false;
}
~Data() {
delete manager;
delete recur;
}
QString description;
QString location;
OPimNotifyManager* manager;
ORecur* recur;
QString note;
QDateTime created;
QDateTime start;
QDateTime end;
bool isAllDay : 1;
QString timezone;
};
OEvent::OEvent( int uid )
: OPimRecord( uid ) {
data = new Data;
}
OEvent::OEvent( const OEvent& ev)
: OPimRecord( ev ), data( ev.data )
{
data->ref();
}
OEvent::~OEvent() {
if ( data->deref() ) {
delete data;
data = 0;
}
}
OEvent& OEvent::operator=( const OEvent& ev) {
if ( *this == ev ) return *this;
OPimRecord::operator=( ev );
ev.data->ref();
deref();
data = ev.data;
return *this;
}
QString OEvent::description()const {
return data->description;
}
void OEvent::setDescription( const QString& description ) {
changeOrModify();
data->description = description;
}
void OEvent::setLocation( const QString& loc ) {
changeOrModify();
data->location = loc;
}
QString OEvent::location()const {
return data->location;
}
OPimNotifyManager &OEvent::notifiers() {
// I hope we can skip the changeOrModify here
// the notifier should take care of it
// and OPimNotify is shared too
if (!data->manager )
data->manager = new OPimNotifyManager;
return *data->manager;
}
bool OEvent::hasNotifiers()const {
return ( data->manager);
}
ORecur OEvent::recurrence()const {
if (!data->recur)
data->recur = new ORecur;
return *data->recur;
}
void OEvent::setRecurrence( const ORecur& rec) {
changeOrModify();
if (data->recur )
(*data->recur) = rec;
else
data->recur = new ORecur( rec );
}
bool OEvent::hasRecurrence()const {
- return data->recur;
+ if (!data->recur ) return false;
+ return data->recur->doesRecur();
}
QString OEvent::note()const {
return data->note;
}
void OEvent::setNote( const QString& note ) {
changeOrModify();
data->note = note;
}
QDateTime OEvent::createdDateTime()const {
return data->created;
}
void OEvent::setCreatedDateTime( const QDateTime& time ) {
changeOrModify();
data->created = time;
}
QDateTime OEvent::startDateTime()const {
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
return data->start;
}
QDateTime OEvent::startDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->start, OTimeZone::current() );
}
void OEvent::setStartDateTime( const QDateTime& dt ) {
changeOrModify();
data->start = dt;
}
QDateTime OEvent::endDateTime()const {
/*
* if all Day event the end time needs
* to be on the same day as the start
*/
if ( data->isAllDay )
return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
return data->end;
}
QDateTime OEvent::endDateTimeInZone()const {
/* if no timezone, or all day event or if the current and this timeZone match... */
if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
OTimeZone zone(data->timezone );
return zone.toDateTime( data->end, OTimeZone::current() );
}
void OEvent::setEndDateTime( const QDateTime& dt ) {
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h
index 4489be7..c718e2e 100644
--- a/libopie2/opiepim/oevent.h
+++ b/libopie2/opiepim/oevent.h
@@ -1,77 +1,77 @@
// CONTAINS GPLed code of TT
#ifndef OPIE_PIM_EVENT_H
#define OPIE_PIM_EVENT_H
#include <qstring.h>
#include <qdatetime.h>
#include <qvaluelist.h>
#include <qpe/recordfields.h>
#include <qpe/palmtopuidgen.h>
#include "otimezone.h"
#include "opimrecord.h"
-namespace OCalendarHelper {
+struct OCalendarHelper {
/** calculate the week number of the date */
static int week( const QDate& );
/** calculate the occurence of week days since the start of the month */
static int ocurrence( const QDate& );
// returns the dayOfWeek for the *first* day it finds (ignores
// any further days!). Returns 1 (Monday) if there isn't any day found
static int dayOfWeek( char day );
/** returns the diff of month */
static int monthDiff( const QDate& first, const QDate& second );
-}
+};
class OPimNotifyManager;
class ORecur;
class OEvent : public OPimRecord {
public:
typedef QValueList<OEvent> ValueList;
enum RecordFields {
Uid = Qtopia::UID_ID,
Category = Qtopia::CATEGORY_ID,
Description,
Location,
Alarm,
Reminder,
Recurrence,
Note,
Created,
StartDate,
EndDate,
AllDay,
TimeZone
};
OEvent(int uid = 0);
OEvent( const OEvent& );
~OEvent();
OEvent &operator=( const OEvent& );
QString description()const;
void setDescription( const QString& description );
QString location()const;
void setLocation( const QString& loc );
bool hasNotifiers()const;
OPimNotifyManager &notifiers();
ORecur recurrence()const;
void setRecurrence( const ORecur& );
bool hasRecurrence()const;
QString note()const;
void setNote( const QString& note );
QDateTime createdDateTime()const;
void setCreatedDateTime( const QDateTime& dt);
/** set the date to dt. dt is the QDateTime in localtime */
@@ -94,97 +94,97 @@ public:
/* pin this event to a timezone! FIXME */
void setTimeZone( const QString& timeZone );
QString timeZone()const;
bool match( const QRegExp& )const;
/* needed reimp */
QString toRichText()const;
QString toShortText()const;
QString type()const;
QMap<int, QString> toMap()const;
QMap<QString, QString> toExtraMap()const;
QString recordField(int )const;
static int rtti();
bool loadFromStream( QDataStream& );
bool saveToStream( QDataStream& )const;
/* bool operator==( const OEvent& );
bool operator!=( const OEvent& );
bool operator<( const OEvent& );
bool operator<=( const OEvent& );
bool operator>( const OEvent& );
bool operator>=(const OEvent& );
*/
private:
inline void changeOrModify();
void deref();
struct Data;
Data* data;
class Private;
Private* priv;
};
/**
* AN Event can span through multiple days. We split up a multiday eve
*/
class OEffectiveEvent {
public:
- QValueList<OEffectiveEvent> ValueList;
+ typedef QValueList<OEffectiveEvent> ValueList;
enum Position { MidWay, Start, End, StartEnd };
// If we calculate the effective event of a multi-day event
// we have to figure out whether we are at the first day,
// at the end, or anywhere else ("middle"). This is important
// for the start/end times (00:00/23:59)
// MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi-
// day event
// Start: start time -> 23:59
// End: 00:00 -> end time
// Start | End == StartEnd: for single-day events (default)
// here we draw start time -> end time
OEffectiveEvent();
OEffectiveEvent( const OEvent& event, const QDate& startDate, Position pos = StartEnd );
OEffectiveEvent( const OEffectiveEvent& );
OEffectiveEvent &operator=(const OEffectiveEvent& );
~OEffectiveEvent();
void setStartTime( const QTime& );
void setEndTime( const QTime& );
void setEvent( const OEvent& );
void setDate( const QDate& );
void setEffectiveDates( const QDate& from, const QDate& to );
QString description()const;
QString location()const;
QString note()const;
OEvent event()const;
QTime startTime()const;
QTime endTime()const;
QDate date()const;
/* return the length in hours */
int length()const;
int size()const;
QDate startDate()const;
QDate endDate()const;
bool operator<( const OEffectiveEvent &e ) const;
bool operator<=( const OEffectiveEvent &e ) const;
bool operator==( const OEffectiveEvent &e ) const;
bool operator!=( const OEffectiveEvent &e ) const;
bool operator>( const OEffectiveEvent &e ) const;
bool operator>= ( const OEffectiveEvent &e ) const;
private:
void deref();