author | zecke <zecke> | 2004-07-29 19:42:59 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-07-29 19:42:59 (UTC) |
commit | 52b1ae9281920cf5a40fe543112d8b00e7699ef6 (patch) (side-by-side diff) | |
tree | 0b0a79ff9a45a66f32fe555ee662b4acc8f6eff9 /libopie2/opiepim | |
parent | c170d1f931ae03c2ec917b7abf4bd5d0e94a3760 (diff) | |
download | opie-52b1ae9281920cf5a40fe543112d8b00e7699ef6.zip opie-52b1ae9281920cf5a40fe543112d8b00e7699ef6.tar.gz opie-52b1ae9281920cf5a40fe543112d8b00e7699ef6.tar.bz2 |
-UTC -> Europe/London when referring to no timezone
-special handling for allDay Event in OPImEvent, avoid setting timezone
as it is by default UTC
-No timezone set by default for an Event
-Recurrence is UTC (no timezone)
-Provide upgrade path from DateBook as by default events were in the current timezone but didn't have the timezone attribute
-unified handling of timezones, compatible with QtopiaDesktop
-do less conversions
-...
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | 105 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.h | 2 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimevent.cpp | 38 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecurrence.cpp | 22 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimtimezone.cpp | 12 |
5 files changed, 99 insertions, 80 deletions
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index 107c178..0f99d50 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp @@ -85,13 +85,13 @@ char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) } } namespace { time_t start, end, created, rp_end; OPimRecurrence* rec; - OPimRecurrence* recur() { + static OPimRecurrence* recur() { if (!rec) rec = new OPimRecurrence; return rec; } int alarmTime; @@ -99,42 +99,44 @@ namespace { enum Attribute{ FDescription = 0, FLocation, FCategories, FUid, FType, - FAlarm, - FSound, - FRType, - FRWeekdays, - FRPosition, - FRFreq, - FRHasEndDate, - FREndDate, - FRStart, - FREnd, - FNote, - FCreated, // Should't this be called FRCreated ? + FAlarm, + FSound, + FRType, + FRWeekdays, + FRPosition, + FRFreq, + FRHasEndDate, + FREndDate, + FRStart, + FREnd, + FNote, + FCreated, // Should't this be called FRCreated ? FTimeZone, FRecParent, FRecChildren, FExceptions }; // FIXME: Use OPimEvent::toMap() here !! (eilers) - inline void save( const OPimEvent& ev, QString& buf ) { + static void save( const OPimEvent& ev, QString& buf ) { owarn << "Saving " << ev.uid() << " " << ev.description() << "" << oendl; buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; if (!ev.location().isEmpty() ) buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; - buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; + if (!ev.categories().isEmpty() ) + buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; + buf += " uid=\"" + QString::number( ev.uid() ) + "\""; if (ev.isAllDay() ) - buf += " type=\"AllDay\""; // is that all ?? (eilers) + buf += " type=\"AllDay\""; // is that all ?? (eilers) if (ev.hasNotifiers() ) { OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; if ( alarm.sound() == OPimAlarm::Loud ) @@ -149,25 +151,32 @@ namespace { /* * fscking timezones :) well, we'll first convert * the QDateTime to a QDateTime in UTC time * and then we'll create a nice time_t */ - OPimTimeZone zone( ev.timeZone().isEmpty() ? OPimTimeZone::current() : ev.timeZone() ); - buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OPimTimeZone::utc() ) ) ) + "\""; - buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OPimTimeZone::utc() ) ) ) + "\""; + OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() ); + buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\""; + buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\""; if (!ev.note().isEmpty() ) { buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; } - buf += " timezone=\""; - if ( ev.timeZone().isEmpty() ) - buf += "None"; - else - buf += ev.timeZone(); - buf += "\""; + /* + * Don't save a timezone if AllDay Events + * as they're UTC only anyway + */ + if (!ev.isAllDay() ) { + + buf += " timezone=\""; + if ( ev.timeZone().isEmpty() ) + buf += "None"; + else + buf += ev.timeZone(); + buf += "\""; + } if (ev.parent() != 0 ) { buf += " recparent=\""+QString::number(ev.parent() )+"\""; } if (ev.children().count() != 0 ) { @@ -180,13 +189,13 @@ namespace { buf+= "\""; } // skip custom writing } - inline bool forAll( const QMap<int, OPimEvent>& list, QFile& file ) { + static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) { QMap<int, OPimEvent>::ConstIterator it; QString buf; QCString str; int total_written; for ( it = list.begin(); it != list.end(); ++it ) { buf = "<event"; @@ -235,18 +244,18 @@ bool ODateBookAccessBackend_XML::save() { if ( total_written != int(str.length() ) ) { f.close(); QFile::remove( strFileNew ); return false; } - if (!forAll( m_raw, f ) ) { + if (!saveEachEvent( m_raw, f ) ) { f.close(); QFile::remove( strFileNew ); return false; } - if (!forAll( m_rep, f ) ) { + if (!saveEachEvent( m_rep, f ) ) { f.close(); QFile::remove( strFileNew ); return false; } buf = "</events>\n</DATEBOOK>\n"; @@ -403,12 +412,16 @@ bool ODateBookAccessBackend_XML::loadFile() { dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? dict.insert( "recparent", new int(FRecParent) ); dict.insert( "recchildren", new int(FRecChildren) ); dict.insert( "exceptions", new int(FExceptions) ); dict.insert( "timezone", new int(FTimeZone) ); + + // initialiaze db hack + m_noTimeZone = true; + char* dt = (char*)map_addr; int len = attribute.st_size; int i = 0; char* point; const char* collectionString = "<event "; int strLen = ::strlen(collectionString); @@ -476,43 +489,49 @@ bool ODateBookAccessBackend_XML::loadFile() { setField( ev, *find, str ); } } /* time to finalize */ finalizeRecord( ev ); delete rec; + m_noTimeZone = true; } ::munmap(map_addr, attribute.st_size ); m_changed = false; // changed during add return true; } // FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers) void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { + + /* + * quirk to import datebook files. They normally don't have a + * timeZone attribute and we treat this as to use OPimTimeZone::current() + */ + if (m_noTimeZone ) + ev.setTimeZone( OPimTimeZone::current().timeZone() ); + + + /* AllDay is alway in UTC */ if ( ev.isAllDay() ) { OPimTimeZone utc = OPimTimeZone::utc(); - ev.setStartDateTime( utc.fromUTCDateTime( start ) ); - ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); - ev.setTimeZone( "UTC"); // make sure it is really utc + ev.setStartDateTime( utc.toDateTime( start ) ); + ev.setEndDateTime ( utc.toDateTime( end ) ); }else { /* to current date time */ - // owarn << " Start is " << start << "" << oendl; - OPimTimeZone zone( ev.timeZone().isEmpty() ? OPimTimeZone::current() : ev.timeZone() ); - QDateTime date = zone.toDateTime( start ); - owarn << " Start is " << date.toString() << "" << oendl; - ev.setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) ); - - date = zone.toDateTime( end ); - ev.setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) ); + OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() ); + + ev.setStartDateTime(to_zone.toDateTime( start)); + ev.setEndDateTime (to_zone.toDateTime( end)); } if ( rec && rec->doesRecur() ) { OPimTimeZone utc = OPimTimeZone::utc(); OPimRecurrence recu( *rec ); // call copy c'tor; - recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); - recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); + recu.setEndDate ( utc.toDateTime( rp_end ).date() ); + recu.setCreatedDateTime( utc.toDateTime( created ) ); recu.setStart( ev.startDateTime().date() ); ev.setRecurrence( recu ); } if (alarmTime != -1 ) { QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); @@ -520,13 +539,13 @@ void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { ev.notifiers().add( al ); } if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { owarn << "already contains assign uid" << oendl; ev.setUid( 1 ); } - owarn << "addind " << ev.uid() << " " << ev.description() << "" << oendl; + if ( ev.hasRecurrence() ) m_rep.insert( ev.uid(), ev ); else m_raw.insert( ev.uid(), ev ); } @@ -545,13 +564,12 @@ void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& case FUid: e.setUid( value.toInt() ); break; case FType: if ( value == "AllDay" ) { e.setAllDay( true ); - e.setTimeZone( "UTC" ); } break; case FAlarm: alarmTime = value.toInt(); break; case FSound: @@ -619,12 +637,13 @@ void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& owarn << "adding exception " << date.toString() << "" << oendl; recur()->exceptions().append( date ); } } break; case FTimeZone: + m_noTimeZone = false; if ( value != "None" ) e.setTimeZone( value ); break; default: break; } diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h index 6823ce6..af5b114 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.h +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h @@ -65,12 +65,14 @@ public: OPimEvent::ValueList directNonRepeats(); OPimEvent::ValueList directRawRepeats(); private: bool m_changed :1 ; + bool m_noTimeZone : 1; + bool loadFile(); inline void finalizeRecord( OPimEvent& ev ); inline void setField( OPimEvent&, int field, const QString& val ); QString m_name; QMap<int, OPimEvent> m_raw; QMap<int, OPimEvent> m_rep; diff --git a/libopie2/opiepim/core/opimevent.cpp b/libopie2/opiepim/core/opimevent.cpp index 8752fce..739cb6f 100644 --- a/libopie2/opiepim/core/opimevent.cpp +++ b/libopie2/opiepim/core/opimevent.cpp @@ -293,14 +293,16 @@ void OPimEvent::setStartDateTime( const QDateTime& dt ) QDateTime OPimEvent::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 ) ); + if ( data->isAllDay ) { + QDate end = data->end.isValid() ? data->end.date() : data->start.date() ; + return QDateTime( end, QTime( 23, 59, 59 ) ); + } return data->end; } QDateTime OPimEvent::endDateTimeInZone() const { @@ -332,26 +334,25 @@ bool OPimEvent::isAllDay() const void OPimEvent::setAllDay( bool allDay ) { changeOrModify(); data->isAllDay = allDay; - if ( allDay ) data->timezone = "UTC"; } void OPimEvent::setTimeZone( const QString& tz ) { changeOrModify(); data->timezone = tz; } QString OPimEvent::timeZone() const { - if ( data->isAllDay ) return QString::fromLatin1( "UTC" ); + if ( data->isAllDay ) return QString::fromLatin1( "Europe/London" ); return data->timezone; } bool OPimEvent::match( const QRegExp& re ) const { @@ -561,15 +562,16 @@ QMap<int, QString> OPimEvent::toMap() const // Currently we just support one alarm.. (eilers) OPimAlarm alarm = notifiers().alarms() [ 0 ]; retMap.insert( OPimEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); retMap.insert( OPimEvent::FSound, ( alarm.sound() == OPimAlarm::Loud ) ? "loud" : "silent" ); } - OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); - retMap.insert( OPimEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OPimTimeZone::utc() ) ) ) ); - retMap.insert( OPimEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OPimTimeZone::utc() ) ) ) ); + /* either use UTC timeZone or current() if there is was a timezone set */ + OPimTimeZone zone( (timeZone().isEmpty()||isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() ); + retMap.insert( OPimEvent::FStart, QString::number( zone.fromDateTime( startDateTime()))); + retMap.insert( OPimEvent::FEnd, QString::number( zone.fromDateTime( endDateTime() ))); retMap.insert( OPimEvent::FNote, Qtopia::escapeString( note() ) ); retMap.insert( OPimEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); if ( parent() ) retMap.insert( OPimEvent::FRecParent, QString::number( parent() ) ); if ( children().count() ) { @@ -627,33 +629,27 @@ void OPimEvent::fromMap( const QMap<int, QString>& map ) if ( !map[ OPimEvent::FTimeZone ].isEmpty() && ( map[ OPimEvent::FTimeZone ] != "None" ) ) { setTimeZone( map[ OPimEvent::FTimeZone ] ); } time_t start = ( time_t ) map[ OPimEvent::FStart ].toLong(); - time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong(); + time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong(); /* AllDay is always in UTC */ if ( isAllDay() ) { OPimTimeZone utc = OPimTimeZone::utc(); - setStartDateTime( utc.fromUTCDateTime( start ) ); - setEndDateTime ( utc.fromUTCDateTime( end ) ); - setTimeZone( "UTC" ); // make sure it is really utc + setStartDateTime(utc.toDateTime( start ) ); + setEndDateTime ( utc.toDateTime( end ) ); } - else - { + else { /* to current date time */ - // owarn << " Start is " << start << "" << oendl; - OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); - QDateTime date = zone.toDateTime( start ); - owarn << " Start is " << date.toString() << "" << oendl; - setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) ); - - date = zone.toDateTime( end ); - setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) ); + OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() ); + + ev.setStartDateTime(to_zone.toDateTime( start)); + ev.setEndDateTime (to_zone.toDateTime( end)); } int alarmTime = -1; if ( !map[ OPimEvent::FAlarm ].isEmpty() ) alarmTime = map[ OPimEvent::FAlarm ].toInt(); diff --git a/libopie2/opiepim/core/opimrecurrence.cpp b/libopie2/opiepim/core/opimrecurrence.cpp index 4b1d886..c3ae350 100644 --- a/libopie2/opiepim/core/opimrecurrence.cpp +++ b/libopie2/opiepim/core/opimrecurrence.cpp @@ -629,63 +629,63 @@ QMap<QString, OPimRecurrence::RepeatType> OPimRecurrence::rTypeValueConvertMap() } QMap<int, QString> OPimRecurrence::toMap() const { QMap<int, QString> retMap; - + retMap.insert( OPimRecurrence::RType, rTypeString() ); retMap.insert( OPimRecurrence::RWeekdays, QString::number( static_cast<int>( data->days ) ) ); retMap.insert( OPimRecurrence::RPosition, QString::number(data->pos ) ); retMap.insert( OPimRecurrence::RFreq, QString::number( data->freq ) ); retMap.insert( OPimRecurrence::RHasEndDate, QString::number( static_cast<int>( data->hasEnd ) ) ); if( data -> hasEnd ) - retMap.insert( OPimRecurrence::EndDate, QString::number( OPimTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) ); - retMap.insert( OPimRecurrence::Created, QString::number( OPimTimeZone::utc().fromUTCDateTime( data->create ) ) ); - + retMap.insert( OPimRecurrence::EndDate, QString::number( OPimTimeZone::current().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) ); + retMap.insert( OPimRecurrence::Created, QString::number( OPimTimeZone::current().fromUTCDateTime( data->create ) ) ); + if ( data->list.isEmpty() ) return retMap; // save exceptions list here!! ExceptionList::ConstIterator it; ExceptionList list = data->list; QString exceptBuf; QDate date; for ( it = list.begin(); it != list.end(); ++it ) { date = (*it); if ( it != list.begin() ) exceptBuf += " "; - + exceptBuf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() ); } retMap.insert( OPimRecurrence::Exceptions, exceptBuf ); return retMap; } void OPimRecurrence::fromMap( const QMap<int, QString>& map ) { - QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap(); + QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap(); data -> type = repTypeMap[ map [OPimRecurrence::RType] ]; data -> days = (char) map[ OPimRecurrence::RWeekdays ].toInt(); data -> pos = map[ OPimRecurrence::RPosition ].toInt(); data -> freq = map[ OPimRecurrence::RFreq ].toInt(); data -> hasEnd= map[ OPimRecurrence::RHasEndDate ].toInt() ? true : false; - OPimTimeZone utc = OPimTimeZone::utc(); + OPimTimeZone cur = OPimTimeZone::current(); if ( data -> hasEnd ){ - data -> end = utc.fromUTCDateTime( (time_t) map[ OPimRecurrence::EndDate ].toLong() ).date(); + data -> end = cur.fromUTCDateTime( (time_t) map[ OPimRecurrence::EndDate ].toLong() ).date(); } - data -> create = utc.fromUTCDateTime( (time_t) map[ OPimRecurrence::Created ].toLong() ).date(); + data -> create = cur.fromUTCDateTime( (time_t) map[ OPimRecurrence::Created ].toLong() ).date(); #if 0 // FIXME: Exceptions currently not supported... // Convert the list of exceptions from QString into ExceptionList data -> list.clear(); QString exceptStr = map[ OPimRecurrence::Exceptions ]; QStringList exceptList = QStringList::split( " ", exceptStr ); ... #endif - - + + } } diff --git a/libopie2/opiepim/core/opimtimezone.cpp b/libopie2/opiepim/core/opimtimezone.cpp index fefceb5..5b32b1f 100644 --- a/libopie2/opiepim/core/opimtimezone.cpp +++ b/libopie2/opiepim/core/opimtimezone.cpp @@ -45,12 +45,13 @@ 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" ); #ifndef Q_OS_MACX // Following line causes bus errors on Mac ::setenv( "TZ", zone.latin1(), true ); @@ -67,12 +68,14 @@ QDateTime utcTime( time_t t, const QString& zone ) 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; @@ -148,27 +151,26 @@ QDateTime OPimTimeZone::toDateTime( time_t t ) /* * convert dt to utc using zone.m_name * convert utc -> timeZoneDT using this->m_name */ QDateTime OPimTimeZone::toDateTime( const QDateTime& dt, const OPimTimeZone& zone ) { - time_t utc = to_Time_t( dt, zone.m_name ); - owarn << "" << utc << " " << zone.m_name << "" << oendl; - return utcTime( utc, m_name ); + time_t utc = to_Time_t( dt, m_name ); + return utcTime( utc, zone.m_name ); } time_t OPimTimeZone::fromDateTime( const QDateTime& time ) { return to_Time_t( time, m_name ); } time_t OPimTimeZone::fromUTCDateTime( const QDateTime& time ) { - return to_Time_t( time, "UTC" ); + return to_Time_t( time, "Europe/London" ); } OPimTimeZone OPimTimeZone::current() { QCString str = ::getenv( "TZ" ); @@ -176,13 +178,13 @@ OPimTimeZone OPimTimeZone::current() return zone; } OPimTimeZone OPimTimeZone::utc() { - return OPimTimeZone( "UTC" ); + return OPimTimeZone( "Europe/London" ); } QString OPimTimeZone::timeZone() const { return m_name; |