summaryrefslogtreecommitdiff
path: root/libopie/pim
Side-by-side diff
Diffstat (limited to 'libopie/pim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_vcard.cpp11
-rw-r--r--libopie/pim/oevent.cpp427
-rw-r--r--libopie/pim/oevent.h198
-rw-r--r--libopie/pim/orecur.cpp25
-rw-r--r--libopie/pim/orecur.h12
-rw-r--r--libopie/pim/otimezone.cpp104
-rw-r--r--libopie/pim/otimezone.h71
-rw-r--r--libopie/pim/otodo.cpp2
-rw-r--r--libopie/pim/test/oevent_test.cpp23
-rw-r--r--libopie/pim/test/oevent_test.pro11
-rw-r--r--libopie/pim/test/test_todo.cpp36
-rw-r--r--libopie/pim/test/todo_test.pro11
12 files changed, 911 insertions, 20 deletions
diff --git a/libopie/pim/ocontactaccessbackend_vcard.cpp b/libopie/pim/ocontactaccessbackend_vcard.cpp
index 622d40a..e537269 100644
--- a/libopie/pim/ocontactaccessbackend_vcard.cpp
+++ b/libopie/pim/ocontactaccessbackend_vcard.cpp
@@ -18,4 +18,13 @@
* History:
* $Log$
+ * Revision 1.8 2003/02/21 16:52:49 zecke
+ * -Remove old Todo classes they're deprecated and today I already using the
+ * new API
+ * -Guard against self assignment in OTodo
+ * -Add test apps for OPIM
+ * -Opiefied Event classes
+ * -Added TimeZone handling and pinning of TimeZones to OEvent
+ * -Adjust ORecur and the widget to better timezone behaviour
+ *
* Revision 1.7 2003/02/16 22:25:46 zecke
* 0000276 Fix for that bug.. or better temp workaround
@@ -75,5 +84,5 @@ bool OContactAccessBackend_VCard::load ()
VObject* obj = 0l;
- if ( QFile( m_file ).exists() ){
+ if ( QFile::exists(m_file) ){
obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
if ( !obj )
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp
new file mode 100644
index 0000000..71b9441
--- a/dev/null
+++ b/libopie/pim/oevent.cpp
@@ -0,0 +1,427 @@
+#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) {
+ // 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) {
+ // 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 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 ) {
+ 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;
+}
+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 ) {
+ changeOrModify();
+ data->end = dt;
+}
+bool OEvent::isMultipleDay()const {
+ return data->end.date().day() - data->start.date().day();
+}
+bool OEvent::isAllDay()const {
+ return data->isAllDay;
+}
+void OEvent::setTimeZone( const QString& tz ) {
+ changeOrModify();
+ data->timezone = tz;
+}
+QString OEvent::timeZone()const {
+ return data->timezone;
+}
+bool OEvent::match( const QRegExp& )const {
+ // FIXME
+ return false;
+}
+QString OEvent::toRichText()const {
+ // FIXME
+ return "OEvent test";
+}
+QString OEvent::toShortText()const {
+ return "OEvent shotText";
+}
+QString OEvent::type()const {
+ return QString::fromLatin1("OEvent");
+}
+QString OEvent::recordField( int /*id */ )const {
+ return QString::null;
+}
+int OEvent::rtti() {
+ return OPimResolver::DateBook;
+}
+bool OEvent::loadFromStream( QDataStream& ) {
+ return true;
+}
+bool OEvent::saveToStream( QDataStream& )const {
+ return true;
+}
+void OEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->description = data->description;
+ d2->location = data->location;
+ d2->manager = data->manager;
+ d2->recur = data->recur;
+ d2->note = data->note;
+ d2->created = data->created;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->isAllDay = data->isAllDay;
+ d2->timezone = data->timezone;
+
+ data = d2;
+ }
+}
+void OEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+// FIXME
+QMap<int, QString> OEvent::toMap()const {
+ return QMap<int, QString>();
+}
+QMap<QString, QString> OEvent::toExtraMap()const {
+ return QMap<QString, QString>();
+}
+
+
+struct OEffectiveEvent::Data : public QShared {
+ Data() : QShared() {
+ }
+ OEvent event;
+ QDate date;
+ QTime start, end;
+ QDate startDate, endDate;
+ bool dates : 1;
+};
+
+OEffectiveEvent::OEffectiveEvent() {
+ data = new Data;
+ data->date = QDate::currentDate();
+ data->start = data->end = QTime::currentTime();
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
+ Position pos ) {
+ data = new Data;
+ data->event = ev;
+ data->date = startDate;
+ if ( pos & Start )
+ data->start = ev.startDateTime().time();
+ else
+ data->start = QTime( 0, 0, 0 );
+
+ if ( pos & End )
+ data->end = ev.endDateTime().time();
+ else
+ data->end = QTime( 23, 59, 59 );
+
+ data->dates = false;
+}
+OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
+ data = ev.data;
+ data->ref();
+}
+OEffectiveEvent::~OEffectiveEvent() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
+ if ( *this == ev ) return *this;
+
+ ev.data->ref();
+ deref();
+ data = ev.data;
+
+ return *this;
+}
+
+void OEffectiveEvent::setStartTime( const QTime& ti) {
+ changeOrModify();
+ data->start = ti;
+}
+void OEffectiveEvent::setEndTime( const QTime& en) {
+ changeOrModify();
+ data->end = en;
+}
+void OEffectiveEvent::setEvent( const OEvent& ev) {
+ changeOrModify();
+ data->event = ev;
+}
+void OEffectiveEvent::setDate( const QDate& da) {
+ changeOrModify();
+ data->date = da;
+}
+void OEffectiveEvent::setEffectiveDates( const QDate& from,
+ const QDate& to ) {
+ if (!from.isValid() ) {
+ data->dates = false;
+ return;
+ }
+
+ data->startDate = from;
+ data->endDate = to;
+}
+QString OEffectiveEvent::description()const {
+ return data->event.description();
+}
+QString OEffectiveEvent::location()const {
+ return data->event.location();
+}
+QString OEffectiveEvent::note()const {
+ return data->event.note();
+}
+OEvent OEffectiveEvent::event()const {
+ return data->event;
+}
+QTime OEffectiveEvent::startTime()const {
+ return data->start;
+}
+QTime OEffectiveEvent::endTime()const {
+ return data->end;
+}
+QDate OEffectiveEvent::date()const {
+ return data->date;
+}
+int OEffectiveEvent::length()const {
+ return (data->end.hour() * 60 - data->start.hour() * 60)
+ + QABS(data->start.minute() - data->end.minute() );
+}
+int OEffectiveEvent::size()const {
+ return ( data->end.hour() - data->start.hour() ) * 3600
+ + (data->end.minute() - data->start.minute() * 60
+ + data->end.second() - data->start.second() );
+}
+QDate OEffectiveEvent::startDate()const {
+ if ( data->dates )
+ return data->startDate;
+ else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
+ return data->date;
+ else
+ return data->event.startDateTime().date();
+}
+QDate OEffectiveEvent::endDate()const {
+ if ( data->dates )
+ return data->endDate;
+ else if ( data->event.hasRecurrence() )
+ return data->date;
+ else
+ return data->event.endDateTime().date();
+}
+void OEffectiveEvent::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+void OEffectiveEvent::changeOrModify() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* d2 = new Data;
+ d2->event = data->event;
+ d2->date = data->date;
+ d2->start = data->start;
+ d2->end = data->end;
+ d2->startDate = data->startDate;
+ d2->endDate = data->endDate;
+ d2->dates = data->dates;
+ data = d2;
+ }
+}
+bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{
+ if ( data->date < e.date() )
+ return TRUE;
+ if ( data->date == e.date() )
+ return ( startTime() < e.startTime() );
+ else
+ return FALSE;
+}
+bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{
+ return (data->date <= e.date() );
+}
+bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const {
+ return ( date() == e.date()
+ && startTime() == e.startTime()
+ && endTime()== e.endTime()
+ && event() == e.event() );
+}
+bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const {
+ return !(*this == e );
+}
+bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const {
+ return !(*this <= e );
+}
+bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const {
+ return !(*this < e);
+}
diff --git a/libopie/pim/oevent.h b/libopie/pim/oevent.h
new file mode 100644
index 0000000..4489be7
--- a/dev/null
+++ b/libopie/pim/oevent.h
@@ -0,0 +1,198 @@
+// 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 {
+ /** 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 */
+ void setStartDateTime( const QDateTime& );
+ /** returns the datetime in the local timeZone */
+ QDateTime startDateTime()const;
+
+ /** returns the start datetime in the current zone */
+ QDateTime startDateTimeInZone()const;
+
+ /** in current timezone */
+ void setEndDateTime( const QDateTime& );
+ /** in current timezone */
+ QDateTime endDateTime()const;
+ QDateTime endDateTimeInZone()const;
+
+ bool isMultipleDay()const;
+ bool isAllDay()const;
+ void setAllDay( bool isAllDay );
+
+ /* 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;
+ 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();
+ inline void changeOrModify();
+ class Private;
+ Private* priv;
+ struct Data;
+ Data* data;
+
+};
+#endif
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp
index daf3506..e6a4787 100644
--- a/libopie/pim/orecur.cpp
+++ b/libopie/pim/orecur.cpp
@@ -11,7 +11,7 @@ struct ORecur::Data : public QShared {
days = 0;
pos = 0;
- create = -1;
+ create = QDateTime::currentDateTime();
hasEnd = FALSE;
- end = 0;
+ end = QDate::currentDate();
}
char days; // Q_UINT8 for 8 seven days;)
@@ -20,6 +20,6 @@ struct ORecur::Data : public QShared {
int pos;
bool hasEnd : 1;
- time_t end;
- time_t create;
+ QDate end;
+ QDateTime create;
int rep;
QString app;
@@ -53,4 +53,6 @@ bool ORecur::operator==( const ORecur& )const {
}
ORecur &ORecur::operator=( const ORecur& re) {
+ if ( *this == re ) return *this;
+
re.data->ref();
deref();
@@ -367,13 +369,10 @@ bool ORecur::hasEndDate()const {
}
QDate ORecur::endDate()const {
- return TimeConversion::fromUTC( data->end ).date();
+ return data->end;
}
QDate ORecur::start()const{
return data->start;
}
-time_t ORecur::endDateUTC()const {
- return data->end;
-}
-time_t ORecur::createTime()const {
+QDateTime ORecur::createdDateTime()const {
return data->create;
}
@@ -405,11 +404,7 @@ void ORecur::setDays( char c ) {
void ORecur::setEndDate( const QDate& dt) {
checkOrModify();
- data->end = TimeConversion::toUTC( dt );
-}
-void ORecur::setEndDateUTC( time_t t) {
- checkOrModify();
- data->end = t;
+ data->end = dt;
}
-void ORecur::setCreateTime( time_t t) {
+void ORecur::setCreatedDateTime( const QDateTime& t) {
checkOrModify();
data->create = t;
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h
index 8713d97..1e0014b 100644
--- a/libopie/pim/orecur.h
+++ b/libopie/pim/orecur.h
@@ -36,6 +36,10 @@ public:
QDate start()const;
QDate endDate()const;
- time_t endDateUTC()const;
- time_t createTime()const;
+ QDateTime createdDateTime()const;
+ /**
+ * starting on monday=0, sunday=6
+ * for convience
+ */
+ bool repeatOnWeekDay( int day )const;
/**
@@ -43,4 +47,5 @@ public:
*/
bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate );
+
/**
* The module this ORecur belongs to
@@ -64,6 +69,5 @@ public:
void setEndDate( const QDate& dt );
void setStart( const QDate& dt );
- void setEndDateUTC( time_t );
- void setCreateTime( time_t );
+ void setCreatedDateTime( const QDateTime& );
void setHasEndDate( bool b );
void setRepitition(int );
diff --git a/libopie/pim/otimezone.cpp b/libopie/pim/otimezone.cpp
new file mode 100644
index 0000000..b2bd3aa
--- a/dev/null
+++ b/libopie/pim/otimezone.cpp
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+
+#include "otimezone.h"
+
+namespace {
+
+ QDateTime utcTime( time_t t) {
+ tm* broken = ::gmtime( &t );
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+ return ret;
+ }
+ QDateTime utcTime( time_t t, const QString& zone) {
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", zone.latin1(), true );
+ ::tzset();
+
+ tm* broken = ::localtime( &t );
+ ::setenv( "TZ", org, true );
+
+ QDateTime ret;
+ ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon +1, broken->tm_mday ) );
+ ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
+
+ return ret;
+ }
+ time_t to_Time_t( const QDateTime& utc, const QString& str ) {
+ QDate d = utc.date();
+ QTime t = utc.time();
+
+ tm broken;
+ broken.tm_year = d.year() - 1900;
+ broken.tm_mon = d.month() - 1;
+ broken.tm_mday = d.day();
+ broken.tm_hour = t.hour();
+ broken.tm_min = t.minute();
+ broken.tm_sec = t.second();
+
+ QCString org = ::getenv( "TZ" );
+ ::setenv( "TZ", str.latin1(), true );
+ ::tzset();
+
+ time_t ti = ::mktime( &broken );
+ ::setenv( "TZ", org, true );
+
+ return ti;
+ }
+}
+OTimeZone::OTimeZone( const ZoneName& zone )
+ : m_name(zone) {
+}
+OTimeZone::~OTimeZone() {
+}
+
+bool OTimeZone::isValid()const {
+ return !m_name.isEmpty();
+}
+
+/*
+ * we will get the current timezone
+ * and ask it to convert to the timezone date
+ */
+QDateTime OTimeZone::toLocalDateTime( const QDateTime& dt) {
+ return OTimeZone::current().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::toUTCDateTime( const QDateTime& dt ) {
+ return OTimeZone::utc().toDateTime( dt, *this );
+}
+QDateTime OTimeZone::fromUTCDateTime( time_t t) {
+ return utcTime( t );
+}
+QDateTime OTimeZone::toDateTime( time_t t) {
+ return utcTime( t, m_name );
+}
+/*
+ * convert dt to utc using zone.m_name
+ * convert utc -> timeZoneDT using this->m_name
+ */
+QDateTime OTimeZone::toDateTime( const QDateTime& dt, const OTimeZone& zone ) {
+ time_t utc = to_Time_t( dt, zone.m_name );
+ qWarning("%d %s", utc, zone.m_name.latin1() );
+ return utcTime( utc, m_name );
+}
+time_t OTimeZone::fromDateTime( const QDateTime& time ) {
+ return to_Time_t( time, m_name );
+}
+time_t OTimeZone::fromUTCDateTime( const QDateTime& time ) {
+ return to_Time_t( time, "UTC" );
+}
+OTimeZone OTimeZone::current() {
+ QCString str = ::getenv("TZ");
+ OTimeZone zone( str );
+ return zone;
+}
+OTimeZone OTimeZone::utc() {
+ return OTimeZone("UTC");
+}
+QString OTimeZone::timeZone()const {
+ return m_name;
+}
diff --git a/libopie/pim/otimezone.h b/libopie/pim/otimezone.h
new file mode 100644
index 0000000..bb08349
--- a/dev/null
+++ b/libopie/pim/otimezone.h
@@ -0,0 +1,71 @@
+#ifndef OPIE_TIME_ZONE_H
+#define OPIE_TIME_ZONE_H
+
+#include <time.h>
+#include <qdatetime.h>
+
+/**
+ * A very primitive class to convert time
+ * from one timezone to another
+ * and to localtime
+ * and time_t
+ */
+class OTimeZone {
+ public:
+ typedef QString ZoneName;
+ OTimeZone( const ZoneName& = ZoneName::null );
+ virtual ~OTimeZone(); // just in case.
+
+ bool isValid()const;
+
+ /**
+ * converts the QDateTime to a DateTime
+ * in the local timezone
+ * if QDateTime is 25th Jan and takes place in Europe/Berlin at 12h
+ * and the current timezone is Europe/London the returned
+ * time will be 11h.
+ */
+ QDateTime toLocalDateTime( const QDateTime& dt );
+
+ /**
+ * converts the QDateTime to UTC time
+ */
+ QDateTime toUTCDateTime( const QDateTime& dt );
+
+ /**
+ * reads the time_t into a QDateTime using UTC as timezone!
+ */
+ QDateTime fromUTCDateTime( time_t );
+
+ /**
+ * converts the time_t to the time in the timezone
+ */
+ QDateTime toDateTime( time_t );
+
+ /**
+ * converts the QDateTime from one timezone to this timeZone
+ */
+ QDateTime toDateTime( const QDateTime&, const OTimeZone& timeZone );
+
+ /**
+ * converts the date time into a time_t. It takes the timezone into account
+ */
+ time_t fromDateTime( const QDateTime& );
+
+ /**
+ * converts the datetime with timezone UTC
+ */
+ time_t fromUTCDateTime( const QDateTime& );
+
+ static OTimeZone current();
+ static OTimeZone utc();
+
+ QString timeZone()const;
+ private:
+ ZoneName m_name;
+ class Private;
+ Private* d;
+};
+
+
+#endif
diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp
index b4d4aa9..049359e 100644
--- a/libopie/pim/otodo.cpp
+++ b/libopie/pim/otodo.cpp
@@ -341,4 +341,6 @@ void OTodo::deref() {
OTodo &OTodo::operator=(const OTodo &item )
{
+ if ( *this == item ) return *this;
+
OPimRecord::operator=( item );
//qWarning("operator= ref ");
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp
new file mode 100644
index 0000000..50cc032
--- a/dev/null
+++ b/libopie/pim/test/oevent_test.cpp
@@ -0,0 +1,23 @@
+#include <qdatetime.h>
+
+#include "../oevent.h"
+
+int main(int argc, char* argv ) {
+ OEvent ev;
+ ev.setUid( 20 );
+
+ ev.setDescription( "Foo" );
+
+ OEvent ev2 = ev;
+ ev2.setDescription("Foo2");
+ qWarning("%s", ev2.description().latin1() );
+ qWarning("%s", ev.description().latin1() );
+
+ QDateTime time = QDateTime::currentDateTime();
+ ev2.setStartDateTime( time );
+ ev2.setTimeZone( "Europe/London" );
+
+ qWarning("%s", ev2.startDateTime().toString().latin1() );
+ qWarning("%s", ev2.startDateTimeInZone().toString().latin1() );
+ return 0;
+}
diff --git a/libopie/pim/test/oevent_test.pro b/libopie/pim/test/oevent_test.pro
new file mode 100644
index 0000000..3365def
--- a/dev/null
+++ b/libopie/pim/test/oevent_test.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+#HEADERS =
+SOURCES = oevent_test.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopie
+TARGET = oevent_test
+
+include ( $(OPIEDIR)/include.pro ) \ No newline at end of file
diff --git a/libopie/pim/test/test_todo.cpp b/libopie/pim/test/test_todo.cpp
new file mode 100644
index 0000000..7440503
--- a/dev/null
+++ b/libopie/pim/test/test_todo.cpp
@@ -0,0 +1,36 @@
+#include <qdatetime.h>
+#include <qmap.h>
+
+#include <opie/otodo.h>
+#include <opie/otodoaccess.h>
+#include <opie/otodoaccessxml.h>
+
+int main(int argc, char* argv[] ) {
+
+ OTodoAccessXML* xml = new OTodoAccessXML("demo");
+ OTodoAccess ac(xml);
+ int elc;
+ QTime timer;
+ qWarning("start loading");
+ timer.start();
+ ac.load();
+ elc = timer.elapsed();
+ qWarning("Elapsed loading %d %d", elc, elc/1000);
+
+ timer.start();
+ OTodoAccess::List lis = ac.allRecords();
+ elc = timer.elapsed();
+ qWarning("Elapsed allRecords %d %d", elc, elc/1000 );
+ OTodoAccess::List::Iterator it;
+ timer.start();
+ac.save();
+/*
+ for( it = lis.begin(); it != lis.end(); ++it ) {
+ qWarning("Desc: " + (*it).summary() );
+ qWarning("UID %d", (*it).uid() );
+ }
+ */
+elc = timer.elapsed();
+
+ qWarning("elapsed iterating %d %d", elc, elc/1000 );
+};
diff --git a/libopie/pim/test/todo_test.pro b/libopie/pim/test/todo_test.pro
new file mode 100644
index 0000000..3d14dda
--- a/dev/null
+++ b/libopie/pim/test/todo_test.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+#CONFIG = qt warn_on debug
+CONFIG = qt warn_on release
+#HEADERS =
+SOURCES = test_todo.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe -lopie -lopiesql
+TARGET = todo_test
+
+include ( $(OPIEDIR)/ ) \ No newline at end of file