29 files changed, 1751 insertions, 1104 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro index 675e1fa..2b843c1 100644 --- a/libopie/libopie.pro +++ b/libopie/libopie.pro @@ -1,15 +1,15 @@ TEMPLATE = lib CONFIG += qte warn_on release HEADERS = ofontmenu.h \ ocolorbutton.h \ - ofiledialog.h ofileselector.h tododb.h \ - ocheckitem.h todoevent.h todoresource.h \ - todovcalresource.h xmltree.h \ + ofiledialog.h ofileselector.h \ + ocheckitem.h \ + xmltree.h \ colordialog.h colorpopupmenu.h \ oclickablelabel.h oprocctrl.h \ oprocess.h odevice.h odevicebutton.h \ otimepicker.h otabwidget.h \ otabbar.h otabinfo.h \ ofontselector.h \ pim/opimrecord.h \ pim/otodo.h \ @@ -31,27 +31,29 @@ HEADERS = ofontmenu.h \ pim/opimxrefpartner.h \ pim/opimxref.h \ pim/opimxrefmanager.h \ pim/opimmaintainer.h \ pim/opimnotify.h \ pim/opimnotifymanager.h \ pim/opimmainwindow.h \ pim/opimresolver.h \ + pim/oevent.h \ + pim/otimezone.h \ orecurrancewidget.h \ oticker.h # pim/otodoaccesssql.h \ SOURCES = ofontmenu.cc \ ocolorbutton.cpp \ sharp_compat.cpp \ xmltree.cc \ ofiledialog.cc ofileselector.cc \ - ocheckitem.cpp tododb.cpp todoevent.cpp \ - todovcalresource.cpp colordialog.cpp \ + ocheckitem.cpp \ + colordialog.cpp \ colorpopupmenu.cpp oclickablelabel.cpp \ oprocctrl.cpp oprocess.cpp \ odevice.cpp odevicebutton.cpp otimepicker.cpp \ otabwidget.cpp otabbar.cpp \ ofontselector.cpp \ pim/otodo.cpp \ pim/opimrecord.cpp \ pim/otodoaccess.cpp \ @@ -66,16 +68,18 @@ SOURCES = ofontmenu.cc \ pim/opimxrefpartner.cpp \ pim/opimxref.cpp \ pim/opimxrefmanager.cpp \ pim/opimmaintainer.cpp \ pim/opimnotify.cpp \ pim/opimnotifymanager.cpp \ pim/opimmainwindow.cpp \ pim/opimresolver.cpp \ + pim/oevent.cpp \ + pim/otimezone.cpp \ orecurrancewidget.cpp \ oticker.cpp # pim/otodoaccesssql.cpp \ TARGET = opie INCLUDEPATH += $(OPIEDIR)/include DESTDIR = $(OPIEDIR)/lib$(PROJMAK) #VERSION = 1.0.0 diff --git a/libopie/orecurrancewidget.cpp b/libopie/orecurrancewidget.cpp index 0484ab9..db86184 100644 --- a/libopie/orecurrancewidget.cpp +++ b/libopie/orecurrancewidget.cpp @@ -172,17 +172,17 @@ ORecur ORecurranceWidget::recurrence()const { } } rpTmp.setFrequency(spinFreq->value() ); rpTmp.setHasEndDate( !chkNoEnd->isChecked() ); if ( rpTmp.hasEndDate() ) { rpTmp.setEndDate( end ); } // timestamp it... - rpTmp.setCreateTime( time( NULL ) ); +// rpTmp.setCreateTime( ); current DateTime is already set -zecke return rpTmp; } QDate ORecurranceWidget::endDate()const { return end; } void ORecurranceWidget::slotSetRType(int rtype) { // now call the right function based on the type... currInterval = static_cast<repeatButtons>(rtype); 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 @@ -12,16 +12,25 @@ * ===================================================================== * ToDo: * * ===================================================================== * Version: $Id$ * ===================================================================== * 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 * A Preferred Number is HOME|VOICE * A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test * triggers both * and the cell phone number overrides the other entries.. * * as a temp I check that it's not equal to HOME|VOICE|CELL before setting the @@ -69,17 +78,17 @@ OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString fil bool OContactAccessBackend_VCard::load () { m_map.clear(); m_dirty = false; VObject* obj = 0l; - if ( QFile( m_file ).exists() ){ + if ( QFile::exists(m_file) ){ obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); if ( !obj ) return false; }else{ qWarning("File \"%s\" not found !", m_file.latin1() ); return false; } 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 ¬ifiers(); + + 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 @@ -5,27 +5,27 @@ #include "orecur.h" struct ORecur::Data : public QShared { Data() : QShared() { type = ORecur::NoRepeat; freq = -1; days = 0; pos = 0; - create = -1; + create = QDateTime::currentDateTime(); hasEnd = FALSE; - end = 0; + end = QDate::currentDate(); } char days; // Q_UINT8 for 8 seven days;) ORecur::RepeatType type; int freq; int pos; bool hasEnd : 1; - time_t end; - time_t create; + QDate end; + QDateTime create; int rep; QString app; ExceptionList list; QDate start; }; ORecur::ORecur() { @@ -47,16 +47,18 @@ void ORecur::deref() { delete data; data = 0l; } } bool ORecur::operator==( const ORecur& )const { return false; } ORecur &ORecur::operator=( const ORecur& re) { + if ( *this == re ) return *this; + re.data->ref(); deref(); data = re.data; return *this; } bool ORecur::doesRecur()const { return !( type() == NoRepeat ); @@ -361,25 +363,22 @@ int ORecur::position()const { } char ORecur::days() const{ return data->days; } bool ORecur::hasEndDate()const { return data->hasEnd; } 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; } int ORecur::repetition()const { return data->rep; } QString ORecur::service()const { return data->app; } @@ -399,23 +398,19 @@ void ORecur::setPosition( int pos ) { data->pos = pos; } void ORecur::setDays( char c ) { checkOrModify(); data->days = 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; } void ORecur::setHasEndDate( bool b) { checkOrModify(); data->hasEnd = b; } void ORecur::setRepitition( int rep ) { 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 @@ -30,23 +30,28 @@ public: bool doesRecur( const QDate& ); RepeatType type()const; int frequency()const; int position()const; char days()const; bool hasEndDate()const; 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; /** * FromWhereToStart is not included!!! */ bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); + /** * The module this ORecur belongs to */ QString service()const; /* * reference to the exception list */ @@ -58,18 +63,17 @@ public: int repetition()const; void setType( const RepeatType& ); void setFrequency( int freq ); void setPosition( int pos ); void setDays( char c); 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 ); void setService( const QString& ser ); private: void deref(); inline void checkOrModify(); 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 @@ -335,16 +335,18 @@ void OTodo::deref() { if ( data->deref() ) { // qWarning("deleting"); delete data; data= 0; } } OTodo &OTodo::operator=(const OTodo &item ) { + if ( *this == item ) return *this; + OPimRecord::operator=( item ); //qWarning("operator= ref "); item.data->ref(); deref(); data = item.data; return *this; } 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 diff --git a/libopie/tododb.cpp b/libopie/tododb.cpp deleted file mode 100644 index 17163a0..0000000 --- a/libopie/tododb.cpp +++ b/dev/null @@ -1,268 +0,0 @@ - -#include <qdir.h> -#include <opie/tododb.h> -#include <opie/xmltree.h> -#include <opie/todoresource.h> -#include <qpe/palmtoprecord.h> -#include <qpe/global.h> - -using namespace Opie; - -namespace { - -class FileToDoResource : public ToDoResource { -public: - FileToDoResource() {}; - // FIXME better parsing - bool save(const QString &name, const QValueList<ToDoEvent> &m_todos ){ - // prepare the XML - XMLElement *tasks = new XMLElement( ); - tasks->setTagName("Tasks" ); - for( QValueList<ToDoEvent>::ConstIterator it = m_todos.begin(); it != m_todos.end(); ++it ){ - XMLElement::AttributeMap map; - XMLElement *task = new XMLElement(); - map.insert( "Completed", QString::number((int)(*it).isCompleted() ) ); - map.insert( "HasDate", QString::number((int)(*it).hasDate() ) ); - map.insert( "Priority", QString::number( (*it).priority() ) ); - map.insert( "Progress", QString::number( (*it).progress() ) ); - map.insert( "Summary", (*it).summary() ); - QArray<int> arrat = (*it).categories(); - QString attr; - for(uint i=0; i < arrat.count(); i++ ){ - attr.append(QString::number(arrat[i])+";" ); - } - if(!attr.isEmpty() ) // remove the last ; - attr.remove(attr.length()-1, 1 ); - map.insert( "Categories", attr ); - //else - //map.insert( "Categories", QString::null ); - map.insert( "Description", (*it).description() ); - if( (*it).hasDate() ){ - map.insert("DateYear", QString::number( (*it).date().year() ) ); - map.insert("DateMonth", QString::number( (*it).date().month() ) ); - map.insert("DateDay", QString::number( (*it).date().day() ) ); - } - map.insert("Uid", QString::number( (*it).uid() ) ); - task->setTagName("Task" ); - task->setAttributes( map ); - tasks->appendChild(task); - } - QFile file( name); - if( file.open(IO_WriteOnly ) ){ - QTextStream stream(&file ); - stream.setEncoding( QTextStream::UnicodeUTF8 ); - stream << "<!DOCTYPE Tasks>" << endl; - tasks->save(stream ); - delete tasks; - stream << "</Tasks>" << endl; - file.close(); - return true; - } - return false; - } - QValueList<ToDoEvent> load( const QString &name ){ - qWarning("loading tododb" ); - QValueList<ToDoEvent> m_todos; - XMLElement *root = XMLElement::load( name ); - if(root != 0l ){ // start parsing - qWarning("ToDoDB::load tagName(): %s", root->tagName().latin1() ); - //if( root->tagName() == QString::fromLatin1("Tasks" ) ){// Start - XMLElement *element = root->firstChild(); - if (element == 0 ) - return m_todos; - element = element->firstChild(); - while( element ){ - if( element->tagName() != QString::fromLatin1("Task") ){ - element = element->nextChild(); - continue; - } - qWarning("ToDoDB::load element tagName() : %s", element->tagName().latin1() ); - QString dummy; - ToDoEvent event; - bool ok; - int dumInt; - // completed - dummy = element->attribute("Completed" ); - dumInt = dummy.toInt(&ok ); - if(ok ) event.setCompleted( dumInt == 0 ? false : true ); - // progress - dummy = element->attribute("Progress" ); - { - ushort dumShort = dummy.toUShort(&ok); - event.setProgress( dumShort ); - - } - // hasDate - dummy = element->attribute("HasDate" ); - dumInt = dummy.toInt(&ok ); - if(ok ) event.setHasDate( dumInt == 0 ? false: true ); - // set the date - bool hasDa = dumInt; - if ( hasDa ) { //parse the date - int year, day, month = 0; - year = day = month; - // year - dummy = element->attribute("DateYear" ); - dumInt = dummy.toInt(&ok ); - if( ok ) year = dumInt; - // month - dummy = element->attribute("DateMonth" ); - dumInt = dummy.toInt(&ok ); - if(ok ) month = dumInt; - dummy = element->attribute("DateDay" ); - dumInt = dummy.toInt(&ok ); - if(ok ) day = dumInt; - // set the date - QDate date( year, month, day ); - event.setDate( date); - } - dummy = element->attribute("Priority" ); - dumInt = dummy.toInt(&ok ); - if(!ok ) dumInt = ToDoEvent::NORMAL; - event.setPriority( dumInt ); - //description - dummy = element->attribute("Description" ); - event.setDescription( dummy ); - dummy = element->attribute("Summary" ); - event.setSummary( dummy ); - // category - dummy = element->attribute("Categories" ); - QStringList ids = QStringList::split(";", dummy ); - event.setCategories( ids ); - - //uid - dummy = element->attribute("Uid" ); - dumInt = dummy.toInt(&ok ); - if(ok ) event.setUid( dumInt ); - m_todos.append( event ); - element = element->nextChild(); // next element - } - //} - }else { - qWarning("could not load" ); - } - delete root; - qWarning("returning" ); - return m_todos; - } -}; - -} - -ToDoDB::ToDoDB(const QString &fileName, ToDoResource *res ){ - m_fileName = fileName; - if( fileName.isEmpty() && res == 0 ){ - m_fileName = Global::applicationFileName("todolist","todolist.xml"); - res = new FileToDoResource(); - //qWarning("%s", m_fileName.latin1() ); - }else if(res == 0 ){ // let's create a ToDoResource for xml - res = new FileToDoResource(); - } - m_res = res; - load(); -} -ToDoResource* ToDoDB::resource(){ - return m_res; -}; -void ToDoDB::setResource( ToDoResource *res ) -{ - delete m_res; - m_res = res; -} -ToDoDB::~ToDoDB() -{ - delete m_res; -} -QValueList<ToDoEvent> ToDoDB::effectiveToDos(const QDate &from, const QDate &to, - bool all ) -{ - QValueList<ToDoEvent> events; - for( QValueList<ToDoEvent>::Iterator it = m_todos.begin(); it!= m_todos.end(); ++it ){ - if( (*it).hasDate() ){ - if( (*it).date() >= from && (*it).date() <= to ) - events.append( (*it) ); - }else if( all ){ - events.append( (*it) ); - } - } - return events; -} -QValueList<ToDoEvent> ToDoDB::effectiveToDos(const QDate &from, - bool all) -{ - return effectiveToDos( from, QDate::currentDate(), all ); -} -QValueList<ToDoEvent> ToDoDB::overDue() -{ - QValueList<ToDoEvent> events; - for( QValueList<ToDoEvent>::Iterator it = m_todos.begin(); it!= m_todos.end(); ++it ){ - if( (*it).isOverdue() ) - events.append((*it) ); - } - return events; -} -QValueList<ToDoEvent> ToDoDB::rawToDos() -{ - return m_todos; -} -void ToDoDB::addEvent( const ToDoEvent &event ) -{ - m_todos.append( event ); -} -void ToDoDB::editEvent( const ToDoEvent &event ) -{ - m_todos.remove( event ); - m_todos.append( event ); -} -void ToDoDB::removeEvent( const ToDoEvent &event ) -{ - m_todos.remove( event ); -} -void ToDoDB::replaceEvent(const ToDoEvent &event ) -{ - QValueList<ToDoEvent>::Iterator it; - int uid = event.uid(); - // == is not overloaded as we would like :( so let's search for the uid - for(it = m_todos.begin(); it != m_todos.end(); ++it ){ - if( (*it).uid() == uid ){ - m_todos.remove( (*it) ); - break; // should save us the iterate is now borked - } - } - m_todos.append(event); -} -void ToDoDB::reload() -{ - load(); -} -void ToDoDB::mergeWith(const QValueList<ToDoEvent>& events ) -{ - QValueList<ToDoEvent>::ConstIterator it; - for( it = events.begin(); it != events.end(); ++it ){ - replaceEvent( (*it) ); - } -} -void ToDoDB::setFileName(const QString &file ) -{ - m_fileName =file; -} -QString ToDoDB::fileName()const -{ - return m_fileName; -} -void ToDoDB::load() -{ - m_todos = m_res->load( m_fileName ); -} -bool ToDoDB::save() -{ - return m_res->save( m_fileName, m_todos ); -} - - - - - - - - diff --git a/libopie/tododb.h b/libopie/tododb.h deleted file mode 100644 index 7fd9f96..0000000 --- a/libopie/tododb.h +++ b/dev/null @@ -1,46 +0,0 @@ - -#ifndef tododb_h -#define tododb_h - -#include <qvaluelist.h> - -#include <opie/todoevent.h> - -class ToDoResource; -class ToDoDB -{ - public: - // if no argument is supplied pick the default book - ToDoDB(const QString &fileName = QString::null, ToDoResource* resource= 0 ); - ~ToDoDB(); - QValueList<ToDoEvent> effectiveToDos(const QDate &from, - const QDate &to, - bool includeNoDates = true); - QValueList<ToDoEvent> effectiveToDos(const QDate &start, bool includeNoDates = true ); - QValueList<ToDoEvent> rawToDos(); // all events - QValueList<ToDoEvent> overDue(); - - void addEvent(const ToDoEvent &event ); - void editEvent(const ToDoEvent &editEvent ); - void removeEvent(const ToDoEvent &event); - void replaceEvent(const ToDoEvent &event ); - // QValueList<ToDoEvents will overwrite existing ones no smart code at all ;) - void mergeWith(const QValueList<ToDoEvent>& ); - void reload(); - void setFileName(const QString & ); - QString fileName()const; - bool save(); - ToDoResource *resource(); - void setResource(ToDoResource* res); - - private: - class ToDoDBPrivate; - ToDoDBPrivate *d; - QString m_fileName; - ToDoResource *m_res; - QValueList<ToDoEvent> m_todos; - void load(); -}; - - -#endif diff --git a/libopie/todoevent.cpp b/libopie/todoevent.cpp deleted file mode 100644 index f744550..0000000 --- a/libopie/todoevent.cpp +++ b/dev/null @@ -1,339 +0,0 @@ - -#include <opie/todoevent.h> - - -#include <qpe/palmtopuidgen.h> -#include <qpe/stringutil.h> -#include <qpe/palmtoprecord.h> - -#include <qpe/stringutil.h> -#include <qpe/categories.h> -#include <qpe/categoryselect.h> - -#include <qobject.h> - -ToDoEvent::ToDoEvent(const ToDoEvent &event ) -{ - *this = event; -} - -ToDoEvent::ToDoEvent(bool completed, int priority, - const QStringList &category, - const QString& summary, - const QString &description, - ushort progress, - bool hasDate, QDate date, int uid ) -{ - m_date = date; - m_isCompleted = completed; - m_hasDate = hasDate; - m_priority = priority; - m_category = category; - m_sum = summary; - m_prog = progress; - m_desc = Qtopia::simplifyMultiLineSpace(description ); - if (uid == -1 ) { - Qtopia::UidGen *uidgen = new Qtopia::UidGen(); - uid = uidgen->generate(); - delete uidgen; - }// generate the ids - m_uid = uid; -} -QArray<int> ToDoEvent::categories()const -{ - QArray<int> array(m_category.count() ); // currently the datebook can be only in one category - array = Qtopia::Record::idsFromString( m_category.join(";") ); - return array; -} -bool ToDoEvent::match( const QRegExp ®Exp )const -{ - if( QString::number( m_priority ).find( regExp ) != -1 ){ - return true; - }else if( m_hasDate && m_date.toString().find( regExp) != -1 ){ - return true; - }else if(m_desc.find( regExp ) != -1 ){ - return true; - } - return false; -} -bool ToDoEvent::isCompleted() const -{ - return m_isCompleted; -} -bool ToDoEvent::hasDate() const -{ - return m_hasDate; -} -int ToDoEvent::priority()const -{ - return m_priority; -} -QStringList ToDoEvent::allCategories()const -{ - return m_category; -} -QString ToDoEvent::extra(const QString& )const -{ - return QString::null; -} -QString ToDoEvent::summary() const -{ - return m_sum; -} -ushort ToDoEvent::progress() const -{ - return m_prog; -} -QStringList ToDoEvent::relatedApps() const -{ - QStringList list; - QMap<QString, QArray<int> >::ConstIterator it; - for ( it = m_relations.begin(); it != m_relations.end(); ++it ) { - list << it.key(); - } - return list; -} -QArray<int> ToDoEvent::relations( const QString& app)const -{ - QArray<int> tmp; - QMap<QString, QArray<int> >::ConstIterator it; - it = m_relations.find( app); - if ( it != m_relations.end() ) - tmp = it.data(); - return tmp; -} -void ToDoEvent::insertCategory(const QString &str ) -{ - m_category.append( str ); -} -void ToDoEvent::clearCategories() -{ - m_category.clear(); -} -void ToDoEvent::setCategories(const QStringList &list ) -{ - m_category = list; -} -QDate ToDoEvent::date()const -{ - return m_date; -} - -QString ToDoEvent::description()const -{ - return m_desc; -} -void ToDoEvent::setCompleted( bool completed ) -{ - m_isCompleted = completed; -} -void ToDoEvent::setHasDate( bool hasDate ) -{ - m_hasDate = hasDate; -} -void ToDoEvent::setDescription(const QString &desc ) -{ - m_desc = Qtopia::simplifyMultiLineSpace(desc ); -} -void ToDoEvent::setExtra( const QString&, const QString& ) -{ - -} -void ToDoEvent::setSummary( const QString& sum ) -{ - m_sum = sum; -} -void ToDoEvent::setCategory( const QString &cat ) -{ - qWarning("setCategory %s", cat.latin1() ); - m_category.clear(); - m_category << cat; -} -void ToDoEvent::setPriority(int prio ) -{ - m_priority = prio; -} -void ToDoEvent::setDate( QDate date ) -{ - m_date = date; -} -void ToDoEvent::addRelated( const QString &app, int id ) -{ - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - it = m_relations.find( app ); - if ( it == m_relations.end() ) { - tmp.resize(1 ); - tmp[0] = id; - }else{ - tmp = it.data(); - tmp.resize( tmp.size() + 1 ); - tmp[tmp.size() - 1] = id; - } - m_relations.replace( app, tmp ); -} -void ToDoEvent::addRelated(const QString& app, QArray<int> ids ) -{ - QMap<QString, QArray<int> >::Iterator it; - QArray<int> tmp; - it = m_relations.find( app); - if ( it == m_relations.end() ) { // not there - /** tmp.resize( ids.size() ); stupid?? - */ - tmp = ids; - }else{ - tmp = it.data(); - int offset = tmp.size()-1; - tmp.resize( tmp.size() + ids.size() ); - for (uint i = 0; i < ids.size(); i++ ) { - tmp[offset+i] = ids[i]; - } - - } - m_relations.replace( app, tmp ); -} -void ToDoEvent::clearRelated( const QString& app ) -{ - m_relations.remove( app ); -} -bool ToDoEvent::isOverdue( ) -{ - if( m_hasDate ) - return QDate::currentDate() > m_date; - return false; -} -void ToDoEvent::setProgress(ushort progress ) -{ - m_prog = progress; -} -/*! - Returns a richt text string -*/ -QString ToDoEvent::richText() const -{ - QString text; - QStringList catlist; - - // Description of the todo - if ( !description().isEmpty() ){ - text += "<b>" + QObject::tr( "Summary:") + "</b><br>"; - text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; - text += "<b>" + QObject::tr( "Description:" ) + "</b><br>"; - text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br><br><br>"; - } - text += "<b>" + QObject::tr( "Priority:") +" </b>" - + QString::number( priority() ) + " <br>"; - text += "<b>" + QObject::tr( "Progress:") + " </b>" - + QString::number( progress() ) + " %<br>"; - if (hasDate() ){ - text += "<b>" + QObject::tr( "Deadline:") + " </b>"; - text += date().toString(); - text += "<br>"; - } - - // Open database of all categories and get the list of - // the categories this todoevent belongs to. - // Then print them... - // I am not sure whether there is no better way doing this !? - Categories catdb; - bool firstloop = true; - catdb.load( categoryFileName() ); - catlist = allCategories(); - - text += "<b>" + QObject::tr( "Category:") + "</b> "; - for ( QStringList::Iterator it = catlist.begin(); it != catlist.end(); ++it ) { - if (!firstloop){ - text += ", "; - } - firstloop = false; - text += catdb.label ("todo", (*it).toInt()); - } - text += "<br>"; - return text; -} - -bool ToDoEvent::operator<( const ToDoEvent &toDoEvent )const{ - if( !hasDate() && !toDoEvent.hasDate() ) return true; - if( !hasDate() && toDoEvent.hasDate() ) return false; - if( hasDate() && toDoEvent.hasDate() ){ - if( date() == toDoEvent.date() ){ // let's the priority decide - return priority() < toDoEvent.priority(); - }else{ - return date() < toDoEvent.date(); - } - } - return false; -} -bool ToDoEvent::operator<=(const ToDoEvent &toDoEvent )const -{ - if( !hasDate() && !toDoEvent.hasDate() ) return true; - if( !hasDate() && toDoEvent.hasDate() ) return true; - if( hasDate() && toDoEvent.hasDate() ){ - if( date() == toDoEvent.date() ){ // let's the priority decide - return priority() <= toDoEvent.priority(); - }else{ - return date() <= toDoEvent.date(); - } - } - return true; -} -bool ToDoEvent::operator>(const ToDoEvent &toDoEvent )const -{ - if( !hasDate() && !toDoEvent.hasDate() ) return false; - if( !hasDate() && toDoEvent.hasDate() ) return false; - if( hasDate() && toDoEvent.hasDate() ){ - if( date() == toDoEvent.date() ){ // let's the priority decide - return priority() > toDoEvent.priority(); - }else{ - return date() > toDoEvent.date(); - } - } - return false; -} -bool ToDoEvent::operator>=(const ToDoEvent &toDoEvent )const -{ - if( !hasDate() && !toDoEvent.hasDate() ) return true; - if( !hasDate() && toDoEvent.hasDate() ) return false; - if( hasDate() && toDoEvent.hasDate() ){ - if( date() == toDoEvent.date() ){ // let's the priority decide - return priority() > toDoEvent.priority(); - }else{ - return date() > toDoEvent.date(); - } - } - return true; -} -bool ToDoEvent::operator==(const ToDoEvent &toDoEvent )const -{ - if( m_priority == toDoEvent.m_priority && - m_priority == toDoEvent.m_prog && - m_isCompleted == toDoEvent.m_isCompleted && - m_hasDate == toDoEvent.m_hasDate && - m_date == toDoEvent.m_date && - m_category == toDoEvent.m_category && - m_sum == toDoEvent.m_sum && - m_desc == toDoEvent.m_desc ) - return true; - return false; -} -ToDoEvent &ToDoEvent::operator=(const ToDoEvent &item ) -{ - m_date = item.m_date; - m_isCompleted = item.m_isCompleted; - m_hasDate = item.m_hasDate; - m_priority = item.m_priority; - m_category = item.m_category; - m_desc = item.m_desc; - m_uid = item.m_uid; - m_sum = item.m_sum; - m_prog = item.m_prog; - return *this; -} - - - - - - - - diff --git a/libopie/todoevent.h b/libopie/todoevent.h deleted file mode 100644 index b55a39b..0000000 --- a/libopie/todoevent.h +++ b/dev/null @@ -1,191 +0,0 @@ - -#ifndef todoevent_h -#define todoevent_h - - -#include <qarray.h> -#include <qmap.h> -#include <qregexp.h> -#include <qstringlist.h> -#include <qdatetime.h> - - -class ToDoEvent { - friend class ToDoDB; - public: - // priorities from Very low to very high - enum Priority { VERYHIGH=1, HIGH, NORMAL, LOW, VERYLOW }; - /* Constructs a new ToDoEvent - @param completed Is the TodoEvent completed - @param priority What is the priority of this ToDoEvent - @param category Which category does it belong( uid ) - @param summary A small summary of the todo - @param description What is this ToDoEvent about - @param hasDate Does this Event got a deadline - @param date what is the deadline? - @param uid what is the UUID of this Event - **/ - ToDoEvent( bool completed = false, int priority = NORMAL, - const QStringList &category = QStringList(), - const QString &summary = QString::null , - const QString &description = QString::null, - ushort progress = 0, - bool hasDate = false, QDate date = QDate::currentDate(), int uid = -1 ); - /* Copy c'tor - - **/ - ToDoEvent(const ToDoEvent & ); - - /* - Is this event completed? - **/ - bool isCompleted() const; - - /* - Does this Event have a deadline - **/ - bool hasDate() const; - - /* - What is the priority? - **/ - int priority()const ; - - /** - * progress as ushort 0, 20, 40, 60, 80 or 100% - */ - ushort progress() const; - /* - All category numbers as QString in a List - **/ - QStringList allCategories()const; - - /* - * Same as above but with QArray<int> - */ - QArray<int> categories() const; - - /** - * The end Date - */ - QDate date()const; - - /** - * The description of the todo - */ - QString description()const; - - /** - * A small summary of the todo - */ - QString summary() const; - - /** - * Return this todoevent in a RichText formatted QString - */ - QString richText() const; - - /** - * Returns the UID of the Todo - */ - int uid()const { return m_uid;}; - - - QString extra(const QString& )const; - - /** - * returns a list of apps which have related items - */ - QStringList relatedApps()const; - - /** - * returns all relations for one app - */ - QArray<int> relations( const QString& app )const; - /** - * Set if this Todo is completed - */ - void setCompleted(bool completed ); - - /** - * set if this todo got an end data - */ - void setHasDate( bool hasDate ); - // if the category doesn't exist we will create it - // this sets the the Category after this call category will be the only category - void setCategory( const QString &category ); - // adds a category to the Categories of this event - void insertCategory(const QString &category ); - - /** - * Removes this event from all categories - */ - void clearCategories(); - - /** - * This todo belongs to xxx categories - */ - void setCategories(const QStringList& ); - - /** - * Set the priority of the Todo - */ - void setPriority(int priority ); - - /** - * Set the progress. - */ - void setProgress( ushort progress ); - - /** - * add related function it replaces too ;) - */ - void addRelated( const QString& app, int id ); - - /** - * add related - */ - void addRelated( const QString& app, QArray<int> ids ); - - /** - * clear relations for one app - */ - void clearRelated(const QString& app); - - /** - * set the end date - */ - void setDate( QDate date ); - void setDescription(const QString& ); - void setSummary(const QString& ); - void setExtra( const QString&, const QString& ); - bool isOverdue(); - - bool match( const QRegExp &r )const; - - void setUid(int id) {m_uid = id; }; - bool operator<(const ToDoEvent &toDoEvent )const; - bool operator<=(const ToDoEvent &toDoEvent )const; - bool operator!=(const ToDoEvent &toDoEvent )const { return !(*this == toDoEvent); }; - bool operator>(const ToDoEvent &toDoEvent )const; - bool operator>=(const ToDoEvent &toDoEvent)const; - bool operator==(const ToDoEvent &toDoEvent )const; - ToDoEvent &operator=(const ToDoEvent &toDoEvent ); - private: - class ToDoEventPrivate; - ToDoEventPrivate *d; - QDate m_date; - bool m_isCompleted:1; - bool m_hasDate:1; - int m_priority; - QStringList m_category; - QString m_desc; - QString m_sum; - QMap<QString, QString> m_extra; - QMap<QString, QArray<int> > m_relations; - int m_uid; - ushort m_prog; -}; - - -#endif diff --git a/libopie/todoresource.h b/libopie/todoresource.h deleted file mode 100644 index 34edb04..0000000 --- a/libopie/todoresource.h +++ b/dev/null @@ -1,14 +0,0 @@ - - -#ifndef opietodoresource_h -#define opietodoresource_h - -class ToDoEvent; -class ToDoResource { - public: - ToDoResource( ) {}; - virtual QValueList<ToDoEvent> load(const QString &file ) = 0; - virtual bool save( const QString &file, const QValueList<ToDoEvent> & ) = 0; -}; - -#endif diff --git a/libopie/todovcalresource.cpp b/libopie/todovcalresource.cpp deleted file mode 100644 index 1df5aff..0000000 --- a/libopie/todovcalresource.cpp +++ b/dev/null @@ -1,158 +0,0 @@ -/* - =. This file is part of the OPIE Project - .=l. Copyright (c) 2002 Holger Freyther <freyther@kde.org> - .>+-= the use of vobject was inspired by libkcal - _;:, .> :=|. This library is free software; you can -.> <`_, > . <= redistribute it and/or modify it under -:`=1 )Y*s>-.-- : the terms of the GNU Library General Public -.="- .-=="i, .._ License as published by the Free Software - - . .-<_> .<> Foundation; either version 2 of the License, - ._= =} : or (at your option) any later version. - .%`+i> _;_. - .i_,=:_. -<s. 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 <qfile.h> -#include <qvaluelist.h> -#include <opie/todoevent.h> -#include <opie/todovcalresource.h> - -#include "../library/backend/vobject_p.h" -#include "../library/timeconversion.h" -#include "../library/backend/qfiledirect_p.h" - -static VObject *vobjByEvent( const ToDoEvent &event ) -{ - VObject *task = newVObject( VCTodoProp ); - if( task == 0 ) - return 0l; - if( event.hasDate() ) - addPropValue( task, VCDueProp, TimeConversion::toISO8601( event.date() ) ); - - if( event.isCompleted() ) - addPropValue( task, VCStatusProp, "COMPLETED"); - - QString string = QString::number(event.priority() ); - addPropValue( task, VCPriorityProp, string.local8Bit() ); - addPropValue( task, VCCategoriesProp, event.allCategories().join(";").local8Bit() ); - addPropValue( task, VCDescriptionProp, event.description().local8Bit() ); - addPropValue( task, VCSummaryProp, event.summary().left(15).local8Bit() ); - return task; -}; - -static ToDoEvent eventByVObj( VObject *obj ){ - ToDoEvent event; - VObject *ob; - QCString name; - // no uid, attendees, ... and no fun - // description - if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){ - name = vObjectStringZValue( ob ); - event.setDescription( name ); - } - // summary - if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) { - name = vObjectStringZValue( ob ); - event.setSummary( name ); - } - // completed - if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){ - name = vObjectStringZValue( ob ); - if( name == "COMPLETED" ){ - event.setCompleted( true ); - }else{ - event.setCompleted( false ); - } - }else - event.setCompleted( false ); - // priority - if ((ob = isAPropertyOf(obj, VCPriorityProp))) { - name = vObjectStringZValue( ob ); - bool ok; - event.setPriority(name.toInt(&ok) ); - } - //due date - if((ob = isAPropertyOf(obj, VCDueProp)) ){ - event.setHasDate( true ); - name = vObjectStringZValue( ob ); - event.setDate( TimeConversion::fromISO8601( name).date() ); - } - // categories - if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){ - name = vObjectStringZValue( ob ); - qWarning("Categories:%s", name.data() ); - } - - return event; -}; - - -QValueList<ToDoEvent> ToDoVCalResource::load(const QString &file) -{ - QValueList<ToDoEvent> events; - VObject *vcal = 0l; - vcal = Parse_MIME_FromFileName( (char *)file.utf8().data() ); // from vobject - if(!vcal ) - return events; - // start parsing - - VObjectIterator it; - VObject *vobj; - initPropIterator(&it, vcal); - - while( moreIteration( &it ) ) { - vobj = ::nextVObject( &it ); - QCString name = ::vObjectName( vobj ); - //QCString objVal = ::vObjectStringZValue( vobj ); - // let's find out the type - if( name == VCTodoProp ){ - events.append( eventByVObj( vobj ) ); - - } // parse the value - } - return events; -} -bool ToDoVCalResource::save(const QString &fileName, const QValueList<ToDoEvent>&list ) -{ - QFileDirect file ( fileName ); - if(!file.open(IO_WriteOnly ) ) - return false; - // obj - VObject *obj; - obj = newVObject( VCCalProp ); - addPropValue( obj, VCVersionProp, "1.0" ); - VObject *vo; - for(QValueList<ToDoEvent>::ConstIterator it = list.begin(); it != list.end(); ++it ){ - vo = vobjByEvent( (*it) ); - addVObjectProp(obj, vo ); - } - writeVObject( file.directHandle(), obj ); - cleanVObject( obj ); - cleanStrTbl(); - - return true; -} - - - - - - - - - - diff --git a/libopie/todovcalresource.h b/libopie/todovcalresource.h deleted file mode 100644 index 0663bc2..0000000 --- a/libopie/todovcalresource.h +++ b/dev/null @@ -1,42 +0,0 @@ -/* - =. This file is part of the OPIE Project - .=l. Copyright (c) 2002 Holger Freyther <freyther@kde.org> - .>+-= - _;:, .> :=|. This library is free software; you can -.> <`_, > . <= redistribute it and/or modify it under -:`=1 )Y*s>-.-- : the terms of the GNU Library General Public -.="- .-=="i, .._ License as published by the Free Software - - . .-<_> .<> Foundation; either version 2 of the License, - ._= =} : or (at your option) any later version. - .%`+i> _;_. - .i_,=:_. -<s. 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 opievcaltodoresource_h -#define opievcaltodoresource_h - -#include <opie/todoresource.h> - -class ToDoVCalResource : public ToDoResource { - public: - ToDoVCalResource() { }; - QValueList<ToDoEvent> load(const QString &file ); - bool save( const QString &filename, const QValueList<ToDoEvent> & ); - -}; - -#endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp index 622d40a..e537269 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp @@ -12,16 +12,25 @@ * ===================================================================== * ToDo: * * ===================================================================== * Version: $Id$ * ===================================================================== * 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 * A Preferred Number is HOME|VOICE * A CellPhone is HOME|VOICE|CELL the type & HOME|VOICE test * triggers both * and the cell phone number overrides the other entries.. * * as a temp I check that it's not equal to HOME|VOICE|CELL before setting the @@ -69,17 +78,17 @@ OContactAccessBackend_VCard::OContactAccessBackend_VCard ( QString , QString fil bool OContactAccessBackend_VCard::load () { m_map.clear(); m_dirty = false; VObject* obj = 0l; - if ( QFile( m_file ).exists() ){ + if ( QFile::exists(m_file) ){ obj = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() ); if ( !obj ) return false; }else{ qWarning("File \"%s\" not found !", m_file.latin1() ); return false; } diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp index daf3506..e6a4787 100644 --- a/libopie2/opiepim/core/orecur.cpp +++ b/libopie2/opiepim/core/orecur.cpp @@ -5,27 +5,27 @@ #include "orecur.h" struct ORecur::Data : public QShared { Data() : QShared() { type = ORecur::NoRepeat; freq = -1; days = 0; pos = 0; - create = -1; + create = QDateTime::currentDateTime(); hasEnd = FALSE; - end = 0; + end = QDate::currentDate(); } char days; // Q_UINT8 for 8 seven days;) ORecur::RepeatType type; int freq; int pos; bool hasEnd : 1; - time_t end; - time_t create; + QDate end; + QDateTime create; int rep; QString app; ExceptionList list; QDate start; }; ORecur::ORecur() { @@ -47,16 +47,18 @@ void ORecur::deref() { delete data; data = 0l; } } bool ORecur::operator==( const ORecur& )const { return false; } ORecur &ORecur::operator=( const ORecur& re) { + if ( *this == re ) return *this; + re.data->ref(); deref(); data = re.data; return *this; } bool ORecur::doesRecur()const { return !( type() == NoRepeat ); @@ -361,25 +363,22 @@ int ORecur::position()const { } char ORecur::days() const{ return data->days; } bool ORecur::hasEndDate()const { return data->hasEnd; } 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; } int ORecur::repetition()const { return data->rep; } QString ORecur::service()const { return data->app; } @@ -399,23 +398,19 @@ void ORecur::setPosition( int pos ) { data->pos = pos; } void ORecur::setDays( char c ) { checkOrModify(); data->days = 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; } void ORecur::setHasEndDate( bool b) { checkOrModify(); data->hasEnd = b; } void ORecur::setRepitition( int rep ) { diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h index 8713d97..1e0014b 100644 --- a/libopie2/opiepim/core/orecur.h +++ b/libopie2/opiepim/core/orecur.h @@ -30,23 +30,28 @@ public: bool doesRecur( const QDate& ); RepeatType type()const; int frequency()const; int position()const; char days()const; bool hasEndDate()const; 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; /** * FromWhereToStart is not included!!! */ bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); + /** * The module this ORecur belongs to */ QString service()const; /* * reference to the exception list */ @@ -58,18 +63,17 @@ public: int repetition()const; void setType( const RepeatType& ); void setFrequency( int freq ); void setPosition( int pos ); void setDays( char c); 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 ); void setService( const QString& ser ); private: void deref(); inline void checkOrModify(); diff --git a/libopie2/opiepim/core/otimezone.cpp b/libopie2/opiepim/core/otimezone.cpp new file mode 100644 index 0000000..b2bd3aa --- a/dev/null +++ b/libopie2/opiepim/core/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/libopie2/opiepim/core/otimezone.h b/libopie2/opiepim/core/otimezone.h new file mode 100644 index 0000000..bb08349 --- a/dev/null +++ b/libopie2/opiepim/core/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/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp new file mode 100644 index 0000000..71b9441 --- a/dev/null +++ b/libopie2/opiepim/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/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h new file mode 100644 index 0000000..4489be7 --- a/dev/null +++ b/libopie2/opiepim/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 ¬ifiers(); + + 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/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp index b4d4aa9..049359e 100644 --- a/libopie2/opiepim/otodo.cpp +++ b/libopie2/opiepim/otodo.cpp @@ -335,16 +335,18 @@ void OTodo::deref() { if ( data->deref() ) { // qWarning("deleting"); delete data; data= 0; } } OTodo &OTodo::operator=(const OTodo &item ) { + if ( *this == item ) return *this; + OPimRecord::operator=( item ); //qWarning("operator= ref "); item.data->ref(); deref(); data = item.data; return *this; } |