summaryrefslogtreecommitdiff
authorzecke <zecke>2004-07-29 19:42:59 (UTC)
committer zecke <zecke>2004-07-29 19:42:59 (UTC)
commit52b1ae9281920cf5a40fe543112d8b00e7699ef6 (patch) (unidiff)
tree0b0a79ff9a45a66f32fe555ee662b4acc8f6eff9
parentc170d1f931ae03c2ec917b7abf4bd5d0e94a3760 (diff)
downloadopie-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 -...
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp105
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.h2
-rw-r--r--libopie2/opiepim/core/opimevent.cpp38
-rw-r--r--libopie2/opiepim/core/opimrecurrence.cpp22
-rw-r--r--libopie2/opiepim/core/opimtimezone.cpp12
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
@@ -43,252 +43,261 @@
43#include <qfile.h> 43#include <qfile.h>
44 44
45/* STD */ 45/* STD */
46#include <errno.h> 46#include <errno.h>
47#include <fcntl.h> 47#include <fcntl.h>
48 48
49#include <stdio.h> 49#include <stdio.h>
50#include <stdlib.h> 50#include <stdlib.h>
51 51
52#include <sys/types.h> 52#include <sys/types.h>
53#include <sys/mman.h> 53#include <sys/mman.h>
54#include <sys/stat.h> 54#include <sys/stat.h>
55 55
56#include <unistd.h> 56#include <unistd.h>
57 57
58 58
59using namespace Opie; 59using namespace Opie;
60 60
61namespace { 61namespace {
62 // FROM TT again 62 // FROM TT again
63char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 63char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
64{ 64{
65 char needleChar; 65 char needleChar;
66 char haystackChar; 66 char haystackChar;
67 if (!needle || !haystack || !hLen || !nLen) 67 if (!needle || !haystack || !hLen || !nLen)
68 return 0; 68 return 0;
69 69
70 const char* hsearch = haystack; 70 const char* hsearch = haystack;
71 71
72 if ((needleChar = *needle++) != 0) { 72 if ((needleChar = *needle++) != 0) {
73 nLen--; //(to make up for needle++) 73 nLen--; //(to make up for needle++)
74 do { 74 do {
75 do { 75 do {
76 if ((haystackChar = *hsearch++) == 0) 76 if ((haystackChar = *hsearch++) == 0)
77 return (0); 77 return (0);
78 if (hsearch >= haystack + hLen) 78 if (hsearch >= haystack + hLen)
79 return (0); 79 return (0);
80 } while (haystackChar != needleChar); 80 } while (haystackChar != needleChar);
81 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 81 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
82 hsearch--; 82 hsearch--;
83 } 83 }
84 return ((char *)hsearch); 84 return ((char *)hsearch);
85} 85}
86} 86}
87 87
88namespace { 88namespace {
89 time_t start, end, created, rp_end; 89 time_t start, end, created, rp_end;
90 OPimRecurrence* rec; 90 OPimRecurrence* rec;
91 OPimRecurrence* recur() { 91 static OPimRecurrence* recur() {
92 if (!rec) 92 if (!rec)
93 rec = new OPimRecurrence; 93 rec = new OPimRecurrence;
94 94
95 return rec; 95 return rec;
96 } 96 }
97 int alarmTime; 97 int alarmTime;
98 int snd; 98 int snd;
99 enum Attribute{ 99 enum Attribute{
100 FDescription = 0, 100 FDescription = 0,
101 FLocation, 101 FLocation,
102 FCategories, 102 FCategories,
103 FUid, 103 FUid,
104 FType, 104 FType,
105 FAlarm, 105 FAlarm,
106 FSound, 106 FSound,
107 FRType, 107 FRType,
108 FRWeekdays, 108 FRWeekdays,
109 FRPosition, 109 FRPosition,
110 FRFreq, 110 FRFreq,
111 FRHasEndDate, 111 FRHasEndDate,
112 FREndDate, 112 FREndDate,
113 FRStart, 113 FRStart,
114 FREnd, 114 FREnd,
115 FNote, 115 FNote,
116 FCreated, // Should't this be called FRCreated ? 116 FCreated, // Should't this be called FRCreated ?
117 FTimeZone, 117 FTimeZone,
118 FRecParent, 118 FRecParent,
119 FRecChildren, 119 FRecChildren,
120 FExceptions 120 FExceptions
121 }; 121 };
122 122
123 // FIXME: Use OPimEvent::toMap() here !! (eilers) 123 // FIXME: Use OPimEvent::toMap() here !! (eilers)
124 inline void save( const OPimEvent& ev, QString& buf ) { 124 static void save( const OPimEvent& ev, QString& buf ) {
125 owarn << "Saving " << ev.uid() << " " << ev.description() << "" << oendl; 125 owarn << "Saving " << ev.uid() << " " << ev.description() << "" << oendl;
126 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; 126 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
127 if (!ev.location().isEmpty() ) 127 if (!ev.location().isEmpty() )
128 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; 128 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
129 129
130 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; 130 if (!ev.categories().isEmpty() )
131 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
132
131 buf += " uid=\"" + QString::number( ev.uid() ) + "\""; 133 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
132 134
133 if (ev.isAllDay() ) 135 if (ev.isAllDay() )
134 buf += " type=\"AllDay\""; // is that all ?? (eilers) 136 buf += " type=\"AllDay\""; // is that all ?? (eilers)
135 137
136 if (ev.hasNotifiers() ) { 138 if (ev.hasNotifiers() ) {
137 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first 139 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
138 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; 140 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
139 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; 141 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
140 if ( alarm.sound() == OPimAlarm::Loud ) 142 if ( alarm.sound() == OPimAlarm::Loud )
141 buf += "loud"; 143 buf += "loud";
142 else 144 else
143 buf += "silent"; 145 buf += "silent";
144 buf += "\""; 146 buf += "\"";
145 } 147 }
146 if ( ev.hasRecurrence() ) { 148 if ( ev.hasRecurrence() ) {
147 buf += ev.recurrence().toString(); 149 buf += ev.recurrence().toString();
148 } 150 }
149 151
150 /* 152 /*
151 * fscking timezones :) well, we'll first convert 153 * fscking timezones :) well, we'll first convert
152 * the QDateTime to a QDateTime in UTC time 154 * the QDateTime to a QDateTime in UTC time
153 * and then we'll create a nice time_t 155 * and then we'll create a nice time_t
154 */ 156 */
155 OPimTimeZone zone( ev.timeZone().isEmpty() ? OPimTimeZone::current() : ev.timeZone() ); 157 OPimTimeZone zone( (ev.timeZone().isEmpty()||ev.isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() );
156 buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OPimTimeZone::utc() ) ) ) + "\""; 158 buf += " start=\"" + QString::number( zone.fromDateTime( ev.startDateTime())) + "\"";
157 buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OPimTimeZone::utc() ) ) ) + "\""; 159 buf += " end=\"" + QString::number( zone.fromDateTime( ev.endDateTime() )) + "\"";
158 if (!ev.note().isEmpty() ) { 160 if (!ev.note().isEmpty() ) {
159 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; 161 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\"";
160 } 162 }
161 163
162 buf += " timezone=\""; 164 /*
163 if ( ev.timeZone().isEmpty() ) 165 * Don't save a timezone if AllDay Events
164 buf += "None"; 166 * as they're UTC only anyway
165 else 167 */
166 buf += ev.timeZone(); 168 if (!ev.isAllDay() ) {
167 buf += "\""; 169
170 buf += " timezone=\"";
171 if ( ev.timeZone().isEmpty() )
172 buf += "None";
173 else
174 buf += ev.timeZone();
175 buf += "\"";
176 }
168 177
169 if (ev.parent() != 0 ) { 178 if (ev.parent() != 0 ) {
170 buf += " recparent=\""+QString::number(ev.parent() )+"\""; 179 buf += " recparent=\""+QString::number(ev.parent() )+"\"";
171 } 180 }
172 181
173 if (ev.children().count() != 0 ) { 182 if (ev.children().count() != 0 ) {
174 QArray<int> children = ev.children(); 183 QArray<int> children = ev.children();
175 buf += " recchildren=\""; 184 buf += " recchildren=\"";
176 for ( uint i = 0; i < children.count(); i++ ) { 185 for ( uint i = 0; i < children.count(); i++ ) {
177 if ( i != 0 ) buf += " "; 186 if ( i != 0 ) buf += " ";
178 buf += QString::number( children[i] ); 187 buf += QString::number( children[i] );
179 } 188 }
180 buf+= "\""; 189 buf+= "\"";
181 } 190 }
182 191
183 // skip custom writing 192 // skip custom writing
184 } 193 }
185 194
186 inline bool forAll( const QMap<int, OPimEvent>& list, QFile& file ) { 195 static bool saveEachEvent( const QMap<int, OPimEvent>& list, QFile& file ) {
187 QMap<int, OPimEvent>::ConstIterator it; 196 QMap<int, OPimEvent>::ConstIterator it;
188 QString buf; 197 QString buf;
189 QCString str; 198 QCString str;
190 int total_written; 199 int total_written;
191 for ( it = list.begin(); it != list.end(); ++it ) { 200 for ( it = list.begin(); it != list.end(); ++it ) {
192 buf = "<event"; 201 buf = "<event";
193 save( it.data(), buf ); 202 save( it.data(), buf );
194 buf += " />\n"; 203 buf += " />\n";
195 str = buf.utf8(); 204 str = buf.utf8();
196 205
197 total_written = file.writeBlock(str.data(), str.length() ); 206 total_written = file.writeBlock(str.data(), str.length() );
198 if ( total_written != int(str.length() ) ) 207 if ( total_written != int(str.length() ) )
199 return false; 208 return false;
200 } 209 }
201 return true; 210 return true;
202 } 211 }
203} 212}
204 213
205namespace Opie { 214namespace Opie {
206ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , 215ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
207 const QString& fileName ) 216 const QString& fileName )
208 : ODateBookAccessBackend() { 217 : ODateBookAccessBackend() {
209 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; 218 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
210 m_changed = false; 219 m_changed = false;
211} 220}
212ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { 221ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
213} 222}
214bool ODateBookAccessBackend_XML::load() { 223bool ODateBookAccessBackend_XML::load() {
215 return loadFile(); 224 return loadFile();
216} 225}
217bool ODateBookAccessBackend_XML::reload() { 226bool ODateBookAccessBackend_XML::reload() {
218 clear(); 227 clear();
219 return load(); 228 return load();
220} 229}
221bool ODateBookAccessBackend_XML::save() { 230bool ODateBookAccessBackend_XML::save() {
222 if (!m_changed) return true; 231 if (!m_changed) return true;
223 232
224 int total_written; 233 int total_written;
225 QString strFileNew = m_name + ".new"; 234 QString strFileNew = m_name + ".new";
226 235
227 QFile f( strFileNew ); 236 QFile f( strFileNew );
228 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; 237 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false;
229 238
230 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 239 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
231 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 240 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
232 buf += "<events>\n"; 241 buf += "<events>\n";
233 QCString str = buf.utf8(); 242 QCString str = buf.utf8();
234 total_written = f.writeBlock( str.data(), str.length() ); 243 total_written = f.writeBlock( str.data(), str.length() );
235 if ( total_written != int(str.length() ) ) { 244 if ( total_written != int(str.length() ) ) {
236 f.close(); 245 f.close();
237 QFile::remove( strFileNew ); 246 QFile::remove( strFileNew );
238 return false; 247 return false;
239 } 248 }
240 249
241 if (!forAll( m_raw, f ) ) { 250 if (!saveEachEvent( m_raw, f ) ) {
242 f.close(); 251 f.close();
243 QFile::remove( strFileNew ); 252 QFile::remove( strFileNew );
244 return false; 253 return false;
245 } 254 }
246 if (!forAll( m_rep, f ) ) { 255 if (!saveEachEvent( m_rep, f ) ) {
247 f.close(); 256 f.close();
248 QFile::remove( strFileNew ); 257 QFile::remove( strFileNew );
249 return false; 258 return false;
250 } 259 }
251 260
252 buf = "</events>\n</DATEBOOK>\n"; 261 buf = "</events>\n</DATEBOOK>\n";
253 str = buf.utf8(); 262 str = buf.utf8();
254 total_written = f.writeBlock( str.data(), str.length() ); 263 total_written = f.writeBlock( str.data(), str.length() );
255 if ( total_written != int(str.length() ) ) { 264 if ( total_written != int(str.length() ) ) {
256 f.close(); 265 f.close();
257 QFile::remove( strFileNew ); 266 QFile::remove( strFileNew );
258 return false; 267 return false;
259 } 268 }
260 f.close(); 269 f.close();
261 270
262 if ( ::rename( strFileNew, m_name ) < 0 ) { 271 if ( ::rename( strFileNew, m_name ) < 0 ) {
263 QFile::remove( strFileNew ); 272 QFile::remove( strFileNew );
264 return false; 273 return false;
265 } 274 }
266 275
267 m_changed = false; 276 m_changed = false;
268 return true; 277 return true;
269} 278}
270QArray<int> ODateBookAccessBackend_XML::allRecords()const { 279QArray<int> ODateBookAccessBackend_XML::allRecords()const {
271 QArray<int> ints( m_raw.count()+ m_rep.count() ); 280 QArray<int> ints( m_raw.count()+ m_rep.count() );
272 uint i = 0; 281 uint i = 0;
273 QMap<int, OPimEvent>::ConstIterator it; 282 QMap<int, OPimEvent>::ConstIterator it;
274 283
275 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 284 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
276 ints[i] = it.key(); 285 ints[i] = it.key();
277 i++; 286 i++;
278 } 287 }
279 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 288 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
280 ints[i] = it.key(); 289 ints[i] = it.key();
281 i++; 290 i++;
282 } 291 }
283 292
284 return ints; 293 return ints;
285} 294}
286QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) { 295QArray<int> ODateBookAccessBackend_XML::queryByExample(const OPimEvent&, int, const QDateTime& ) {
287 return QArray<int>(); 296 return QArray<int>();
288} 297}
289void ODateBookAccessBackend_XML::clear() { 298void ODateBookAccessBackend_XML::clear() {
290 m_changed = true; 299 m_changed = true;
291 m_raw.clear(); 300 m_raw.clear();
292 m_rep.clear(); 301 m_rep.clear();
293} 302}
294OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{ 303OPimEvent ODateBookAccessBackend_XML::find( int uid ) const{
@@ -361,291 +370,301 @@ OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
361 return list; 370 return list;
362} 371}
363 372
364// FIXME: Use OPimEvent::fromMap() (eilers) 373// FIXME: Use OPimEvent::fromMap() (eilers)
365bool ODateBookAccessBackend_XML::loadFile() { 374bool ODateBookAccessBackend_XML::loadFile() {
366 m_changed = false; 375 m_changed = false;
367 376
368 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); 377 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
369 if ( fd < 0 ) return false; 378 if ( fd < 0 ) return false;
370 379
371 struct stat attribute; 380 struct stat attribute;
372 if ( ::fstat(fd, &attribute ) == -1 ) { 381 if ( ::fstat(fd, &attribute ) == -1 ) {
373 ::close( fd ); 382 ::close( fd );
374 return false; 383 return false;
375 } 384 }
376 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 385 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
377 if ( map_addr == ( (caddr_t)-1) ) { 386 if ( map_addr == ( (caddr_t)-1) ) {
378 ::close( fd ); 387 ::close( fd );
379 return false; 388 return false;
380 } 389 }
381 390
382 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); 391 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
383 ::close( fd ); 392 ::close( fd );
384 393
385 QAsciiDict<int> dict(FExceptions+1); 394 QAsciiDict<int> dict(FExceptions+1);
386 dict.setAutoDelete( true ); 395 dict.setAutoDelete( true );
387 dict.insert( "description", new int(FDescription) ); 396 dict.insert( "description", new int(FDescription) );
388 dict.insert( "location", new int(FLocation) ); 397 dict.insert( "location", new int(FLocation) );
389 dict.insert( "categories", new int(FCategories) ); 398 dict.insert( "categories", new int(FCategories) );
390 dict.insert( "uid", new int(FUid) ); 399 dict.insert( "uid", new int(FUid) );
391 dict.insert( "type", new int(FType) ); 400 dict.insert( "type", new int(FType) );
392 dict.insert( "alarm", new int(FAlarm) ); 401 dict.insert( "alarm", new int(FAlarm) );
393 dict.insert( "sound", new int(FSound) ); 402 dict.insert( "sound", new int(FSound) );
394 dict.insert( "rtype", new int(FRType) ); 403 dict.insert( "rtype", new int(FRType) );
395 dict.insert( "rweekdays", new int(FRWeekdays) ); 404 dict.insert( "rweekdays", new int(FRWeekdays) );
396 dict.insert( "rposition", new int(FRPosition) ); 405 dict.insert( "rposition", new int(FRPosition) );
397 dict.insert( "rfreq", new int(FRFreq) ); 406 dict.insert( "rfreq", new int(FRFreq) );
398 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 407 dict.insert( "rhasenddate", new int(FRHasEndDate) );
399 dict.insert( "enddt", new int(FREndDate) ); 408 dict.insert( "enddt", new int(FREndDate) );
400 dict.insert( "start", new int(FRStart) ); 409 dict.insert( "start", new int(FRStart) );
401 dict.insert( "end", new int(FREnd) ); 410 dict.insert( "end", new int(FREnd) );
402 dict.insert( "note", new int(FNote) ); 411 dict.insert( "note", new int(FNote) );
403 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ?? 412 dict.insert( "created", new int(FCreated) ); // Shouldn't this be FRCreated ??
404 dict.insert( "recparent", new int(FRecParent) ); 413 dict.insert( "recparent", new int(FRecParent) );
405 dict.insert( "recchildren", new int(FRecChildren) ); 414 dict.insert( "recchildren", new int(FRecChildren) );
406 dict.insert( "exceptions", new int(FExceptions) ); 415 dict.insert( "exceptions", new int(FExceptions) );
407 dict.insert( "timezone", new int(FTimeZone) ); 416 dict.insert( "timezone", new int(FTimeZone) );
408 417
418
419 // initialiaze db hack
420 m_noTimeZone = true;
421
409 char* dt = (char*)map_addr; 422 char* dt = (char*)map_addr;
410 int len = attribute.st_size; 423 int len = attribute.st_size;
411 int i = 0; 424 int i = 0;
412 char* point; 425 char* point;
413 const char* collectionString = "<event "; 426 const char* collectionString = "<event ";
414 int strLen = ::strlen(collectionString); 427 int strLen = ::strlen(collectionString);
415 int *find; 428 int *find;
416 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { 429 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) {
417 i = point -dt; 430 i = point -dt;
418 i+= strLen; 431 i+= strLen;
419 432
420 alarmTime = -1; 433 alarmTime = -1;
421 snd = 0; // silent 434 snd = 0; // silent
422 435
423 OPimEvent ev; 436 OPimEvent ev;
424 rec = 0; 437 rec = 0;
425 438
426 while ( TRUE ) { 439 while ( TRUE ) {
427 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 440 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
428 ++i; 441 ++i;
429 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 442 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
430 break; 443 break;
431 444
432 445
433 // we have another attribute, read it. 446 // we have another attribute, read it.
434 int j = i; 447 int j = i;
435 while ( j < len && dt[j] != '=' ) 448 while ( j < len && dt[j] != '=' )
436 ++j; 449 ++j;
437 QCString attr( dt+i, j-i+1); 450 QCString attr( dt+i, j-i+1);
438 451
439 i = ++j; // skip = 452 i = ++j; // skip =
440 453
441 // find the start of quotes 454 // find the start of quotes
442 while ( i < len && dt[i] != '"' ) 455 while ( i < len && dt[i] != '"' )
443 ++i; 456 ++i;
444 j = ++i; 457 j = ++i;
445 458
446 bool haveUtf = FALSE; 459 bool haveUtf = FALSE;
447 bool haveEnt = FALSE; 460 bool haveEnt = FALSE;
448 while ( j < len && dt[j] != '"' ) { 461 while ( j < len && dt[j] != '"' ) {
449 if ( ((unsigned char)dt[j]) > 0x7f ) 462 if ( ((unsigned char)dt[j]) > 0x7f )
450 haveUtf = TRUE; 463 haveUtf = TRUE;
451 if ( dt[j] == '&' ) 464 if ( dt[j] == '&' )
452 haveEnt = TRUE; 465 haveEnt = TRUE;
453 ++j; 466 ++j;
454 } 467 }
455 if ( i == j ) { 468 if ( i == j ) {
456 // empty value 469 // empty value
457 i = j + 1; 470 i = j + 1;
458 continue; 471 continue;
459 } 472 }
460 473
461 QCString value( dt+i, j-i+1 ); 474 QCString value( dt+i, j-i+1 );
462 i = j + 1; 475 i = j + 1;
463 476
464 QString str = (haveUtf ? QString::fromUtf8( value ) 477 QString str = (haveUtf ? QString::fromUtf8( value )
465 : QString::fromLatin1( value ) ); 478 : QString::fromLatin1( value ) );
466 if ( haveEnt ) 479 if ( haveEnt )
467 str = Qtopia::plainString( str ); 480 str = Qtopia::plainString( str );
468 481
469 /* 482 /*
470 * add key + value 483 * add key + value
471 */ 484 */
472 find = dict[attr.data()]; 485 find = dict[attr.data()];
473 if (!find) 486 if (!find)
474 ev.setCustomField( attr, str ); 487 ev.setCustomField( attr, str );
475 else { 488 else {
476 setField( ev, *find, str ); 489 setField( ev, *find, str );
477 } 490 }
478 } 491 }
479 /* time to finalize */ 492 /* time to finalize */
480 finalizeRecord( ev ); 493 finalizeRecord( ev );
481 delete rec; 494 delete rec;
495 m_noTimeZone = true;
482 } 496 }
483 ::munmap(map_addr, attribute.st_size ); 497 ::munmap(map_addr, attribute.st_size );
484 m_changed = false; // changed during add 498 m_changed = false; // changed during add
485 499
486 return true; 500 return true;
487} 501}
488 502
489// FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers) 503// FIXME: Use OPimEvent::fromMap() which makes this obsolete.. (eilers)
490void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) { 504void ODateBookAccessBackend_XML::finalizeRecord( OPimEvent& ev ) {
505
506 /*
507 * quirk to import datebook files. They normally don't have a
508 * timeZone attribute and we treat this as to use OPimTimeZone::current()
509 */
510 if (m_noTimeZone )
511 ev.setTimeZone( OPimTimeZone::current().timeZone() );
512
513
514
491 /* AllDay is alway in UTC */ 515 /* AllDay is alway in UTC */
492 if ( ev.isAllDay() ) { 516 if ( ev.isAllDay() ) {
493 OPimTimeZone utc = OPimTimeZone::utc(); 517 OPimTimeZone utc = OPimTimeZone::utc();
494 ev.setStartDateTime( utc.fromUTCDateTime( start ) ); 518 ev.setStartDateTime( utc.toDateTime( start ) );
495 ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); 519 ev.setEndDateTime ( utc.toDateTime( end ) );
496 ev.setTimeZone( "UTC"); // make sure it is really utc
497 }else { 520 }else {
498 /* to current date time */ 521 /* to current date time */
499 // owarn << " Start is " << start << "" << oendl; 522 OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() );
500 OPimTimeZone zone( ev.timeZone().isEmpty() ? OPimTimeZone::current() : ev.timeZone() ); 523
501 QDateTime date = zone.toDateTime( start ); 524 ev.setStartDateTime(to_zone.toDateTime( start));
502 owarn << " Start is " << date.toString() << "" << oendl; 525 ev.setEndDateTime (to_zone.toDateTime( end));
503 ev.setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) );
504
505 date = zone.toDateTime( end );
506 ev.setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) );
507 } 526 }
508 if ( rec && rec->doesRecur() ) { 527 if ( rec && rec->doesRecur() ) {
509 OPimTimeZone utc = OPimTimeZone::utc(); 528 OPimTimeZone utc = OPimTimeZone::utc();
510 OPimRecurrence recu( *rec ); // call copy c'tor; 529 OPimRecurrence recu( *rec ); // call copy c'tor;
511 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); 530 recu.setEndDate ( utc.toDateTime( rp_end ).date() );
512 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); 531 recu.setCreatedDateTime( utc.toDateTime( created ) );
513 recu.setStart( ev.startDateTime().date() ); 532 recu.setStart( ev.startDateTime().date() );
514 ev.setRecurrence( recu ); 533 ev.setRecurrence( recu );
515 } 534 }
516 535
517 if (alarmTime != -1 ) { 536 if (alarmTime != -1 ) {
518 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); 537 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
519 OPimAlarm al( snd , dt ); 538 OPimAlarm al( snd , dt );
520 ev.notifiers().add( al ); 539 ev.notifiers().add( al );
521 } 540 }
522 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { 541 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
523 owarn << "already contains assign uid" << oendl; 542 owarn << "already contains assign uid" << oendl;
524 ev.setUid( 1 ); 543 ev.setUid( 1 );
525 } 544 }
526 owarn << "addind " << ev.uid() << " " << ev.description() << "" << oendl; 545
527 if ( ev.hasRecurrence() ) 546 if ( ev.hasRecurrence() )
528 m_rep.insert( ev.uid(), ev ); 547 m_rep.insert( ev.uid(), ev );
529 else 548 else
530 m_raw.insert( ev.uid(), ev ); 549 m_raw.insert( ev.uid(), ev );
531 550
532} 551}
533void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) { 552void ODateBookAccessBackend_XML::setField( OPimEvent& e, int id, const QString& value) {
534// owarn << " setting " << value << "" << oendl; 553// owarn << " setting " << value << "" << oendl;
535 switch( id ) { 554 switch( id ) {
536 case FDescription: 555 case FDescription:
537 e.setDescription( value ); 556 e.setDescription( value );
538 break; 557 break;
539 case FLocation: 558 case FLocation:
540 e.setLocation( value ); 559 e.setLocation( value );
541 break; 560 break;
542 case FCategories: 561 case FCategories:
543 e.setCategories( e.idsFromString( value ) ); 562 e.setCategories( e.idsFromString( value ) );
544 break; 563 break;
545 case FUid: 564 case FUid:
546 e.setUid( value.toInt() ); 565 e.setUid( value.toInt() );
547 break; 566 break;
548 case FType: 567 case FType:
549 if ( value == "AllDay" ) { 568 if ( value == "AllDay" ) {
550 e.setAllDay( true ); 569 e.setAllDay( true );
551 e.setTimeZone( "UTC" );
552 } 570 }
553 break; 571 break;
554 case FAlarm: 572 case FAlarm:
555 alarmTime = value.toInt(); 573 alarmTime = value.toInt();
556 break; 574 break;
557 case FSound: 575 case FSound:
558 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; 576 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
559 break; 577 break;
560 // recurrence stuff 578 // recurrence stuff
561 case FRType: 579 case FRType:
562 if ( value == "Daily" ) 580 if ( value == "Daily" )
563 recur()->setType( OPimRecurrence::Daily ); 581 recur()->setType( OPimRecurrence::Daily );
564 else if ( value == "Weekly" ) 582 else if ( value == "Weekly" )
565 recur()->setType( OPimRecurrence::Weekly); 583 recur()->setType( OPimRecurrence::Weekly);
566 else if ( value == "MonthlyDay" ) 584 else if ( value == "MonthlyDay" )
567 recur()->setType( OPimRecurrence::MonthlyDay ); 585 recur()->setType( OPimRecurrence::MonthlyDay );
568 else if ( value == "MonthlyDate" ) 586 else if ( value == "MonthlyDate" )
569 recur()->setType( OPimRecurrence::MonthlyDate ); 587 recur()->setType( OPimRecurrence::MonthlyDate );
570 else if ( value == "Yearly" ) 588 else if ( value == "Yearly" )
571 recur()->setType( OPimRecurrence::Yearly ); 589 recur()->setType( OPimRecurrence::Yearly );
572 else 590 else
573 recur()->setType( OPimRecurrence::NoRepeat ); 591 recur()->setType( OPimRecurrence::NoRepeat );
574 break; 592 break;
575 case FRWeekdays: 593 case FRWeekdays:
576 recur()->setDays( value.toInt() ); 594 recur()->setDays( value.toInt() );
577 break; 595 break;
578 case FRPosition: 596 case FRPosition:
579 recur()->setPosition( value.toInt() ); 597 recur()->setPosition( value.toInt() );
580 break; 598 break;
581 case FRFreq: 599 case FRFreq:
582 recur()->setFrequency( value.toInt() ); 600 recur()->setFrequency( value.toInt() );
583 break; 601 break;
584 case FRHasEndDate: 602 case FRHasEndDate:
585 recur()->setHasEndDate( value.toInt() ); 603 recur()->setHasEndDate( value.toInt() );
586 break; 604 break;
587 case FREndDate: { 605 case FREndDate: {
588 rp_end = (time_t) value.toLong(); 606 rp_end = (time_t) value.toLong();
589 break; 607 break;
590 } 608 }
591 case FRStart: { 609 case FRStart: {
592 start = (time_t) value.toLong(); 610 start = (time_t) value.toLong();
593 break; 611 break;
594 } 612 }
595 case FREnd: { 613 case FREnd: {
596 end = ( (time_t) value.toLong() ); 614 end = ( (time_t) value.toLong() );
597 break; 615 break;
598 } 616 }
599 case FNote: 617 case FNote:
600 e.setNote( value ); 618 e.setNote( value );
601 break; 619 break;
602 case FCreated: 620 case FCreated:
603 created = value.toInt(); 621 created = value.toInt();
604 break; 622 break;
605 case FRecParent: 623 case FRecParent:
606 e.setParent( value.toInt() ); 624 e.setParent( value.toInt() );
607 break; 625 break;
608 case FRecChildren:{ 626 case FRecChildren:{
609 QStringList list = QStringList::split(' ', value ); 627 QStringList list = QStringList::split(' ', value );
610 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 628 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
611 e.addChild( (*it).toInt() ); 629 e.addChild( (*it).toInt() );
612 } 630 }
613 } 631 }
614 break; 632 break;
615 case FExceptions:{ 633 case FExceptions:{
616 QStringList list = QStringList::split(' ', value ); 634 QStringList list = QStringList::split(' ', value );
617 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 635 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
618 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); 636 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() );
619 owarn << "adding exception " << date.toString() << "" << oendl; 637 owarn << "adding exception " << date.toString() << "" << oendl;
620 recur()->exceptions().append( date ); 638 recur()->exceptions().append( date );
621 } 639 }
622 } 640 }
623 break; 641 break;
624 case FTimeZone: 642 case FTimeZone:
643 m_noTimeZone = false;
625 if ( value != "None" ) 644 if ( value != "None" )
626 e.setTimeZone( value ); 645 e.setTimeZone( value );
627 break; 646 break;
628 default: 647 default:
629 break; 648 break;
630 } 649 }
631} 650}
632QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const 651QArray<int> ODateBookAccessBackend_XML::matchRegexp( const QRegExp &r ) const
633{ 652{
634 QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() ); 653 QArray<int> m_currentQuery( m_raw.count()+ m_rep.count() );
635 uint arraycounter = 0; 654 uint arraycounter = 0;
636 QMap<int, OPimEvent>::ConstIterator it; 655 QMap<int, OPimEvent>::ConstIterator it;
637 656
638 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) 657 for ( it = m_raw.begin(); it != m_raw.end(); ++it )
639 if ( it.data().match( r ) ) 658 if ( it.data().match( r ) )
640 m_currentQuery[arraycounter++] = it.data().uid(); 659 m_currentQuery[arraycounter++] = it.data().uid();
641 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) 660 for ( it = m_rep.begin(); it != m_rep.end(); ++it )
642 if ( it.data().match( r ) ) 661 if ( it.data().match( r ) )
643 m_currentQuery[arraycounter++] = it.data().uid(); 662 m_currentQuery[arraycounter++] = it.data().uid();
644 663
645 // Shrink to fit.. 664 // Shrink to fit..
646 m_currentQuery.resize(arraycounter); 665 m_currentQuery.resize(arraycounter);
647 666
648 return m_currentQuery; 667 return m_currentQuery;
649} 668}
650 669
651} 670}
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
@@ -23,64 +23,66 @@
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H 29#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
30#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H 30#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
31 31
32#include <qmap.h> 32#include <qmap.h>
33 33
34#include <opie2/odatebookaccessbackend.h> 34#include <opie2/odatebookaccessbackend.h>
35 35
36namespace Opie { 36namespace Opie {
37/** 37/**
38 * This is the default XML implementation for DateBoook XML storage 38 * This is the default XML implementation for DateBoook XML storage
39 * It fully implements the interface 39 * It fully implements the interface
40 * @see ODateBookAccessBackend 40 * @see ODateBookAccessBackend
41 * @see OPimAccessBackend 41 * @see OPimAccessBackend
42 */ 42 */
43class ODateBookAccessBackend_XML : public ODateBookAccessBackend { 43class ODateBookAccessBackend_XML : public ODateBookAccessBackend {
44public: 44public:
45 ODateBookAccessBackend_XML( const QString& appName, 45 ODateBookAccessBackend_XML( const QString& appName,
46 const QString& fileName = QString::null); 46 const QString& fileName = QString::null);
47 ~ODateBookAccessBackend_XML(); 47 ~ODateBookAccessBackend_XML();
48 48
49 bool load(); 49 bool load();
50 bool reload(); 50 bool reload();
51 bool save(); 51 bool save();
52 52
53 QArray<int> allRecords()const; 53 QArray<int> allRecords()const;
54 QArray<int> matchRegexp(const QRegExp &r) const; 54 QArray<int> matchRegexp(const QRegExp &r) const;
55 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() ); 55 QArray<int> queryByExample( const OPimEvent&, int, const QDateTime& d = QDateTime() );
56 OPimEvent find( int uid )const; 56 OPimEvent find( int uid )const;
57 void clear(); 57 void clear();
58 bool add( const OPimEvent& ev ); 58 bool add( const OPimEvent& ev );
59 bool remove( int uid ); 59 bool remove( int uid );
60 bool replace( const OPimEvent& ev ); 60 bool replace( const OPimEvent& ev );
61 61
62 QArray<UID> rawEvents()const; 62 QArray<UID> rawEvents()const;
63 QArray<UID> rawRepeats()const; 63 QArray<UID> rawRepeats()const;
64 QArray<UID> nonRepeats()const; 64 QArray<UID> nonRepeats()const;
65 65
66 OPimEvent::ValueList directNonRepeats(); 66 OPimEvent::ValueList directNonRepeats();
67 OPimEvent::ValueList directRawRepeats(); 67 OPimEvent::ValueList directRawRepeats();
68 68
69private: 69private:
70 bool m_changed :1 ; 70 bool m_changed :1 ;
71 bool m_noTimeZone : 1;
72
71 bool loadFile(); 73 bool loadFile();
72 inline void finalizeRecord( OPimEvent& ev ); 74 inline void finalizeRecord( OPimEvent& ev );
73 inline void setField( OPimEvent&, int field, const QString& val ); 75 inline void setField( OPimEvent&, int field, const QString& val );
74 QString m_name; 76 QString m_name;
75 QMap<int, OPimEvent> m_raw; 77 QMap<int, OPimEvent> m_raw;
76 QMap<int, OPimEvent> m_rep; 78 QMap<int, OPimEvent> m_rep;
77 79
78 struct Data; 80 struct Data;
79 Data* data; 81 Data* data;
80 class Private; 82 class Private;
81 Private *d; 83 Private *d;
82}; 84};
83 85
84} 86}
85 87
86#endif 88#endif
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
@@ -251,149 +251,150 @@ void OPimEvent::setNote( const QString& note )
251 data->note = note; 251 data->note = note;
252} 252}
253 253
254 254
255QDateTime OPimEvent::createdDateTime() const 255QDateTime OPimEvent::createdDateTime() const
256{ 256{
257 return data->created; 257 return data->created;
258} 258}
259 259
260 260
261void OPimEvent::setCreatedDateTime( const QDateTime& time ) 261void OPimEvent::setCreatedDateTime( const QDateTime& time )
262{ 262{
263 changeOrModify(); 263 changeOrModify();
264 data->created = time; 264 data->created = time;
265} 265}
266 266
267 267
268QDateTime OPimEvent::startDateTime() const 268QDateTime OPimEvent::startDateTime() const
269{ 269{
270 if ( data->isAllDay ) 270 if ( data->isAllDay )
271 return QDateTime( data->start.date(), QTime( 0, 0, 0 ) ); 271 return QDateTime( data->start.date(), QTime( 0, 0, 0 ) );
272 return data->start; 272 return data->start;
273} 273}
274 274
275 275
276QDateTime OPimEvent::startDateTimeInZone() const 276QDateTime OPimEvent::startDateTimeInZone() const
277{ 277{
278 /* if no timezone, or all day event or if the current and this timeZone match... */ 278 /* if no timezone, or all day event or if the current and this timeZone match... */
279 if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return startDateTime(); 279 if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return startDateTime();
280 280
281 OPimTimeZone zone( data->timezone ); 281 OPimTimeZone zone( data->timezone );
282 return zone.toDateTime( data->start, OPimTimeZone::current() ); 282 return zone.toDateTime( data->start, OPimTimeZone::current() );
283} 283}
284 284
285 285
286void OPimEvent::setStartDateTime( const QDateTime& dt ) 286void OPimEvent::setStartDateTime( const QDateTime& dt )
287{ 287{
288 changeOrModify(); 288 changeOrModify();
289 data->start = dt; 289 data->start = dt;
290} 290}
291 291
292 292
293QDateTime OPimEvent::endDateTime() const 293QDateTime OPimEvent::endDateTime() const
294{ 294{
295 /* 295 /*
296 * if all Day event the end time needs 296 * if all Day event the end time needs
297 * to be on the same day as the start 297 * to be on the same day as the start
298 */ 298 */
299 if ( data->isAllDay ) 299 if ( data->isAllDay ) {
300 return QDateTime( data->start.date(), QTime( 23, 59, 59 ) ); 300 QDate end = data->end.isValid() ? data->end.date() : data->start.date() ;
301 return QDateTime( end, QTime( 23, 59, 59 ) );
302 }
301 return data->end; 303 return data->end;
302} 304}
303 305
304 306
305QDateTime OPimEvent::endDateTimeInZone() const 307QDateTime OPimEvent::endDateTimeInZone() const
306{ 308{
307 /* if no timezone, or all day event or if the current and this timeZone match... */ 309 /* if no timezone, or all day event or if the current and this timeZone match... */
308 if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return endDateTime(); 310 if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return endDateTime();
309 311
310 OPimTimeZone zone( data->timezone ); 312 OPimTimeZone zone( data->timezone );
311 return zone.toDateTime( data->end, OPimTimeZone::current() ); 313 return zone.toDateTime( data->end, OPimTimeZone::current() );
312} 314}
313 315
314 316
315void OPimEvent::setEndDateTime( const QDateTime& dt ) 317void OPimEvent::setEndDateTime( const QDateTime& dt )
316{ 318{
317 changeOrModify(); 319 changeOrModify();
318 data->end = dt; 320 data->end = dt;
319} 321}
320 322
321 323
322bool OPimEvent::isMultipleDay() const 324bool OPimEvent::isMultipleDay() const
323{ 325{
324 return data->end.date().day() - data->start.date().day(); 326 return data->end.date().day() - data->start.date().day();
325} 327}
326 328
327 329
328bool OPimEvent::isAllDay() const 330bool OPimEvent::isAllDay() const
329{ 331{
330 return data->isAllDay; 332 return data->isAllDay;
331} 333}
332 334
333 335
334void OPimEvent::setAllDay( bool allDay ) 336void OPimEvent::setAllDay( bool allDay )
335{ 337{
336 changeOrModify(); 338 changeOrModify();
337 data->isAllDay = allDay; 339 data->isAllDay = allDay;
338 if ( allDay ) data->timezone = "UTC";
339} 340}
340 341
341 342
342void OPimEvent::setTimeZone( const QString& tz ) 343void OPimEvent::setTimeZone( const QString& tz )
343{ 344{
344 changeOrModify(); 345 changeOrModify();
345 data->timezone = tz; 346 data->timezone = tz;
346} 347}
347 348
348 349
349QString OPimEvent::timeZone() const 350QString OPimEvent::timeZone() const
350{ 351{
351 if ( data->isAllDay ) return QString::fromLatin1( "UTC" ); 352 if ( data->isAllDay ) return QString::fromLatin1( "Europe/London" );
352 return data->timezone; 353 return data->timezone;
353} 354}
354 355
355 356
356bool OPimEvent::match( const QRegExp& re ) const 357bool OPimEvent::match( const QRegExp& re ) const
357{ 358{
358 if ( re.match( data->description ) != -1 ) 359 if ( re.match( data->description ) != -1 )
359 { 360 {
360 setLastHitField( Qtopia::DatebookDescription ); 361 setLastHitField( Qtopia::DatebookDescription );
361 return true; 362 return true;
362 } 363 }
363 if ( re.match( data->note ) != -1 ) 364 if ( re.match( data->note ) != -1 )
364 { 365 {
365 setLastHitField( Qtopia::Note ); 366 setLastHitField( Qtopia::Note );
366 return true; 367 return true;
367 } 368 }
368 if ( re.match( data->location ) != -1 ) 369 if ( re.match( data->location ) != -1 )
369 { 370 {
370 setLastHitField( Qtopia::Location ); 371 setLastHitField( Qtopia::Location );
371 return true; 372 return true;
372 } 373 }
373 if ( re.match( data->start.toString() ) != -1 ) 374 if ( re.match( data->start.toString() ) != -1 )
374 { 375 {
375 setLastHitField( Qtopia::StartDateTime ); 376 setLastHitField( Qtopia::StartDateTime );
376 return true; 377 return true;
377 } 378 }
378 if ( re.match( data->end.toString() ) != -1 ) 379 if ( re.match( data->end.toString() ) != -1 )
379 { 380 {
380 setLastHitField( Qtopia::EndDateTime ); 381 setLastHitField( Qtopia::EndDateTime );
381 return true; 382 return true;
382 } 383 }
383 return false; 384 return false;
384} 385}
385 386
386 387
387QString OPimEvent::toRichText() const 388QString OPimEvent::toRichText() const
388{ 389{
389 QString text, value; 390 QString text, value;
390 391
391 // description 392 // description
392 text += "<b><h3><img src=\"datebook/DateBook\">"; 393 text += "<b><h3><img src=\"datebook/DateBook\">";
393 if ( !description().isEmpty() ) 394 if ( !description().isEmpty() )
394 { 395 {
395 text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "" ); 396 text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "" );
396 } 397 }
397 text += "</h3></b><br><hr><br>"; 398 text += "</h3></b><br><hr><br>";
398 399
399 // location 400 // location
@@ -519,183 +520,178 @@ void OPimEvent::changeOrModify()
519 d2->note = data->note; 520 d2->note = data->note;
520 d2->created = data->created; 521 d2->created = data->created;
521 d2->start = data->start; 522 d2->start = data->start;
522 d2->end = data->end; 523 d2->end = data->end;
523 d2->isAllDay = data->isAllDay; 524 d2->isAllDay = data->isAllDay;
524 d2->timezone = data->timezone; 525 d2->timezone = data->timezone;
525 d2->parent = data->parent; 526 d2->parent = data->parent;
526 527
527 if ( data->child ) 528 if ( data->child )
528 { 529 {
529 d2->child = new QArray<int>( *data->child ); 530 d2->child = new QArray<int>( *data->child );
530 d2->child->detach(); 531 d2->child->detach();
531 } 532 }
532 533
533 data = d2; 534 data = d2;
534 } 535 }
535} 536}
536 537
537 538
538void OPimEvent::deref() 539void OPimEvent::deref()
539{ 540{
540 if ( data->deref() ) 541 if ( data->deref() )
541 { 542 {
542 delete data; 543 delete data;
543 data = 0; 544 data = 0;
544 } 545 }
545} 546}
546// Exporting Event data to map. Using the same 547// Exporting Event data to map. Using the same
547// encoding as ODateBookAccessBackend_xml does.. 548// encoding as ODateBookAccessBackend_xml does..
548// Thus, we could remove the stuff there and use this 549// Thus, we could remove the stuff there and use this
549// for it and for all other places.. 550// for it and for all other places..
550// Encoding should happen at one place, only ! (eilers) 551// Encoding should happen at one place, only ! (eilers)
551QMap<int, QString> OPimEvent::toMap() const 552QMap<int, QString> OPimEvent::toMap() const
552{ 553{
553 QMap<int, QString> retMap; 554 QMap<int, QString> retMap;
554 555
555 retMap.insert( OPimEvent::FUid, QString::number( uid() ) ); 556 retMap.insert( OPimEvent::FUid, QString::number( uid() ) );
556 retMap.insert( OPimEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ) ); 557 retMap.insert( OPimEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ) );
557 retMap.insert( OPimEvent::FDescription, Qtopia::escapeString( description() ) ); 558 retMap.insert( OPimEvent::FDescription, Qtopia::escapeString( description() ) );
558 retMap.insert( OPimEvent::FLocation, Qtopia::escapeString( location() ) ); 559 retMap.insert( OPimEvent::FLocation, Qtopia::escapeString( location() ) );
559 retMap.insert( OPimEvent::FType, isAllDay() ? "AllDay" : "" ); 560 retMap.insert( OPimEvent::FType, isAllDay() ? "AllDay" : "" );
560 if ( notifiers().alarms().count() ){ 561 if ( notifiers().alarms().count() ){
561 // Currently we just support one alarm.. (eilers) 562 // Currently we just support one alarm.. (eilers)
562 OPimAlarm alarm = notifiers().alarms() [ 0 ]; 563 OPimAlarm alarm = notifiers().alarms() [ 0 ];
563 retMap.insert( OPimEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); 564 retMap.insert( OPimEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) );
564 retMap.insert( OPimEvent::FSound, ( alarm.sound() == OPimAlarm::Loud ) ? "loud" : "silent" ); 565 retMap.insert( OPimEvent::FSound, ( alarm.sound() == OPimAlarm::Loud ) ? "loud" : "silent" );
565 } 566 }
566 567
567 OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); 568 /* either use UTC timeZone or current() if there is was a timezone set */
568 retMap.insert( OPimEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OPimTimeZone::utc() ) ) ) ); 569 OPimTimeZone zone( (timeZone().isEmpty()||isAllDay()) ? OPimTimeZone::utc() : OPimTimeZone::current() );
569 retMap.insert( OPimEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OPimTimeZone::utc() ) ) ) ); 570 retMap.insert( OPimEvent::FStart, QString::number( zone.fromDateTime( startDateTime())));
571 retMap.insert( OPimEvent::FEnd, QString::number( zone.fromDateTime( endDateTime() )));
570 retMap.insert( OPimEvent::FNote, Qtopia::escapeString( note() ) ); 572 retMap.insert( OPimEvent::FNote, Qtopia::escapeString( note() ) );
571 retMap.insert( OPimEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); 573 retMap.insert( OPimEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() );
572 if ( parent() ) 574 if ( parent() )
573 retMap.insert( OPimEvent::FRecParent, QString::number( parent() ) ); 575 retMap.insert( OPimEvent::FRecParent, QString::number( parent() ) );
574 if ( children().count() ) 576 if ( children().count() )
575 { 577 {
576 QArray<int> childr = children(); 578 QArray<int> childr = children();
577 QString buf; 579 QString buf;
578 for ( uint i = 0; i < childr.count(); i++ ) 580 for ( uint i = 0; i < childr.count(); i++ )
579 { 581 {
580 if ( i != 0 ) buf += " "; 582 if ( i != 0 ) buf += " ";
581 buf += QString::number( childr[ i ] ); 583 buf += QString::number( childr[ i ] );
582 } 584 }
583 retMap.insert( OPimEvent::FRecChildren, buf ); 585 retMap.insert( OPimEvent::FRecChildren, buf );
584 } 586 }
585 587
586 // Add recurrence stuff 588 // Add recurrence stuff
587 if ( hasRecurrence() ) 589 if ( hasRecurrence() )
588 { 590 {
589 OPimRecurrence recur = recurrence(); 591 OPimRecurrence recur = recurrence();
590 QMap<int, QString> recFields = recur.toMap(); 592 QMap<int, QString> recFields = recur.toMap();
591 retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); 593 retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] );
592 retMap.insert( OPimEvent::FRWeekdays, recFields[ OPimRecurrence::RWeekdays ] ); 594 retMap.insert( OPimEvent::FRWeekdays, recFields[ OPimRecurrence::RWeekdays ] );
593 retMap.insert( OPimEvent::FRPosition, recFields[ OPimRecurrence::RPosition ] ); 595 retMap.insert( OPimEvent::FRPosition, recFields[ OPimRecurrence::RPosition ] );
594 retMap.insert( OPimEvent::FRFreq, recFields[ OPimRecurrence::RFreq ] ); 596 retMap.insert( OPimEvent::FRFreq, recFields[ OPimRecurrence::RFreq ] );
595 retMap.insert( OPimEvent::FRHasEndDate, recFields[ OPimRecurrence::RHasEndDate ] ); 597 retMap.insert( OPimEvent::FRHasEndDate, recFields[ OPimRecurrence::RHasEndDate ] );
596 retMap.insert( OPimEvent::FREndDate, recFields[ OPimRecurrence::EndDate ] ); 598 retMap.insert( OPimEvent::FREndDate, recFields[ OPimRecurrence::EndDate ] );
597 retMap.insert( OPimEvent::FRCreated, recFields[ OPimRecurrence::Created ] ); 599 retMap.insert( OPimEvent::FRCreated, recFields[ OPimRecurrence::Created ] );
598 retMap.insert( OPimEvent::FRExceptions, recFields[ OPimRecurrence::Exceptions ] ); 600 retMap.insert( OPimEvent::FRExceptions, recFields[ OPimRecurrence::Exceptions ] );
599 } 601 }
600 else 602 else
601 { 603 {
602 OPimRecurrence recur = recurrence(); 604 OPimRecurrence recur = recurrence();
603 QMap<int, QString> recFields = recur.toMap(); 605 QMap<int, QString> recFields = recur.toMap();
604 retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); 606 retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] );
605 } 607 }
606 608
607 return retMap; 609 return retMap;
608} 610}
609 611
610 612
611void OPimEvent::fromMap( const QMap<int, QString>& map ) 613void OPimEvent::fromMap( const QMap<int, QString>& map )
612{ 614{
613 615
614 // We just want to set the UID if it is really stored. 616 // We just want to set the UID if it is really stored.
615 if ( !map[ OPimEvent::FUid ].isEmpty() ) 617 if ( !map[ OPimEvent::FUid ].isEmpty() )
616 setUid( map[ OPimEvent::FUid ].toInt() ); 618 setUid( map[ OPimEvent::FUid ].toInt() );
617 619
618 setCategories( idsFromString( map[ OPimEvent::FCategories ] ) ); 620 setCategories( idsFromString( map[ OPimEvent::FCategories ] ) );
619 setDescription( map[ OPimEvent::FDescription ] ); 621 setDescription( map[ OPimEvent::FDescription ] );
620 setLocation( map[ OPimEvent::FLocation ] ); 622 setLocation( map[ OPimEvent::FLocation ] );
621 623
622 if ( map[ OPimEvent::FType ] == "AllDay" ) 624 if ( map[ OPimEvent::FType ] == "AllDay" )
623 setAllDay( true ); 625 setAllDay( true );
624 else 626 else
625 setAllDay( false ); 627 setAllDay( false );
626 628
627 if ( !map[ OPimEvent::FTimeZone ].isEmpty() && ( map[ OPimEvent::FTimeZone ] != "None" ) ) 629 if ( !map[ OPimEvent::FTimeZone ].isEmpty() && ( map[ OPimEvent::FTimeZone ] != "None" ) )
628 { 630 {
629 setTimeZone( map[ OPimEvent::FTimeZone ] ); 631 setTimeZone( map[ OPimEvent::FTimeZone ] );
630 } 632 }
631 633
632 time_t start = ( time_t ) map[ OPimEvent::FStart ].toLong(); 634 time_t start = ( time_t ) map[ OPimEvent::FStart ].toLong();
633 time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong(); 635 time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong();
634 636
635 /* AllDay is always in UTC */ 637 /* AllDay is always in UTC */
636 if ( isAllDay() ) 638 if ( isAllDay() )
637 { 639 {
638 OPimTimeZone utc = OPimTimeZone::utc(); 640 OPimTimeZone utc = OPimTimeZone::utc();
639 setStartDateTime( utc.fromUTCDateTime( start ) ); 641 setStartDateTime(utc.toDateTime( start ) );
640 setEndDateTime ( utc.fromUTCDateTime( end ) ); 642 setEndDateTime ( utc.toDateTime( end ) );
641 setTimeZone( "UTC" ); // make sure it is really utc
642 } 643 }
643 else 644 else {
644 {
645 /* to current date time */ 645 /* to current date time */
646 // owarn << " Start is " << start << "" << oendl; 646 OPimTimeZone to_zone( ev.timeZone().isEmpty() ? OPimTimeZone::utc() : OPimTimeZone::current() );
647 OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); 647
648 QDateTime date = zone.toDateTime( start ); 648 ev.setStartDateTime(to_zone.toDateTime( start));
649 owarn << " Start is " << date.toString() << "" << oendl; 649 ev.setEndDateTime (to_zone.toDateTime( end));
650 setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) );
651
652 date = zone.toDateTime( end );
653 setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) );
654 } 650 }
655 651
656 int alarmTime = -1; 652 int alarmTime = -1;
657 if ( !map[ OPimEvent::FAlarm ].isEmpty() ) 653 if ( !map[ OPimEvent::FAlarm ].isEmpty() )
658 alarmTime = map[ OPimEvent::FAlarm ].toInt(); 654 alarmTime = map[ OPimEvent::FAlarm ].toInt();
659 655
660 int sound = ( ( map[ OPimEvent::FSound ] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); 656 int sound = ( ( map[ OPimEvent::FSound ] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent );
661 if ( ( alarmTime != -1 ) ) 657 if ( ( alarmTime != -1 ) )
662 { 658 {
663 QDateTime dt = startDateTime().addSecs( -1 * alarmTime * 60 ); 659 QDateTime dt = startDateTime().addSecs( -1 * alarmTime * 60 );
664 OPimAlarm al( sound , dt ); 660 OPimAlarm al( sound , dt );
665 notifiers().add( al ); 661 notifiers().add( al );
666 } 662 }
667 663
668 664
669 if ( !map[ OPimEvent::FNote ].isEmpty() ) 665 if ( !map[ OPimEvent::FNote ].isEmpty() )
670 setNote( map[ OPimEvent::FNote ] ); 666 setNote( map[ OPimEvent::FNote ] );
671 667
672 if ( !map[ OPimEvent::FRecParent ].isEmpty() ) 668 if ( !map[ OPimEvent::FRecParent ].isEmpty() )
673 setParent( map[ OPimEvent::FRecParent ].toInt() ); 669 setParent( map[ OPimEvent::FRecParent ].toInt() );
674 670
675 if ( !map[ OPimEvent::FRecChildren ].isEmpty() ) 671 if ( !map[ OPimEvent::FRecChildren ].isEmpty() )
676 { 672 {
677 QStringList list = QStringList::split( ' ', map[ OPimEvent::FRecChildren ] ); 673 QStringList list = QStringList::split( ' ', map[ OPimEvent::FRecChildren ] );
678 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) 674 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
679 { 675 {
680 addChild( ( *it ).toInt() ); 676 addChild( ( *it ).toInt() );
681 } 677 }
682 } 678 }
683 679
684 // Fill recurrence stuff and put it directly into the OPimRecurrence-Object using fromMap.. 680 // Fill recurrence stuff and put it directly into the OPimRecurrence-Object using fromMap..
685 if ( !map[ OPimEvent::FRType ].isEmpty() ) 681 if ( !map[ OPimEvent::FRType ].isEmpty() )
686 { 682 {
687 QMap<int, QString> recFields; 683 QMap<int, QString> recFields;
688 recFields.insert( OPimRecurrence::RType, map[ OPimEvent::FRType ] ); 684 recFields.insert( OPimRecurrence::RType, map[ OPimEvent::FRType ] );
689 recFields.insert( OPimRecurrence::RWeekdays, map[ OPimEvent::FRWeekdays ] ); 685 recFields.insert( OPimRecurrence::RWeekdays, map[ OPimEvent::FRWeekdays ] );
690 recFields.insert( OPimRecurrence::RPosition, map[ OPimEvent::FRPosition ] ); 686 recFields.insert( OPimRecurrence::RPosition, map[ OPimEvent::FRPosition ] );
691 recFields.insert( OPimRecurrence::RFreq, map[ OPimEvent::FRFreq ] ); 687 recFields.insert( OPimRecurrence::RFreq, map[ OPimEvent::FRFreq ] );
692 recFields.insert( OPimRecurrence::RHasEndDate, map[ OPimEvent::FRHasEndDate ] ); 688 recFields.insert( OPimRecurrence::RHasEndDate, map[ OPimEvent::FRHasEndDate ] );
693 recFields.insert( OPimRecurrence::EndDate, map[ OPimEvent::FREndDate ] ); 689 recFields.insert( OPimRecurrence::EndDate, map[ OPimEvent::FREndDate ] );
694 recFields.insert( OPimRecurrence::Created, map[ OPimEvent::FRCreated ] ); 690 recFields.insert( OPimRecurrence::Created, map[ OPimEvent::FRCreated ] );
695 recFields.insert( OPimRecurrence::Exceptions, map[ OPimEvent::FRExceptions ] ); 691 recFields.insert( OPimRecurrence::Exceptions, map[ OPimEvent::FRExceptions ] );
696 OPimRecurrence recur( recFields ); 692 OPimRecurrence recur( recFields );
697 setRecurrence( recur ); 693 setRecurrence( recur );
698 } 694 }
699 695
700} 696}
701 697
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
@@ -587,105 +587,105 @@ QString OPimRecurrence::toString()const {
587} 587}
588 588
589QString OPimRecurrence::rTypeString() const 589QString OPimRecurrence::rTypeString() const
590{ 590{
591 QString retString; 591 QString retString;
592 switch ( data->type ) { 592 switch ( data->type ) {
593 case OPimRecurrence::Daily: 593 case OPimRecurrence::Daily:
594 retString = "Daily"; 594 retString = "Daily";
595 break; 595 break;
596 case OPimRecurrence::Weekly: 596 case OPimRecurrence::Weekly:
597 retString = "Weekly"; 597 retString = "Weekly";
598 break; 598 break;
599 case OPimRecurrence::MonthlyDay: 599 case OPimRecurrence::MonthlyDay:
600 retString = "MonthlyDay"; 600 retString = "MonthlyDay";
601 break; 601 break;
602 case OPimRecurrence::MonthlyDate: 602 case OPimRecurrence::MonthlyDate:
603 retString = "MonthlyDate"; 603 retString = "MonthlyDate";
604 break; 604 break;
605 case OPimRecurrence::Yearly: 605 case OPimRecurrence::Yearly:
606 retString = "Yearly"; 606 retString = "Yearly";
607 break; 607 break;
608 default: 608 default:
609 retString = "NoRepeat"; 609 retString = "NoRepeat";
610 break; 610 break;
611 611
612 } 612 }
613 613
614 return retString; 614 return retString;
615} 615}
616 616
617QMap<QString, OPimRecurrence::RepeatType> OPimRecurrence::rTypeValueConvertMap() const 617QMap<QString, OPimRecurrence::RepeatType> OPimRecurrence::rTypeValueConvertMap() const
618{ 618{
619 QMap<QString, RepeatType> convertMap; 619 QMap<QString, RepeatType> convertMap;
620 620
621 convertMap.insert( QString( "Daily" ), OPimRecurrence::Daily ); 621 convertMap.insert( QString( "Daily" ), OPimRecurrence::Daily );
622 convertMap.insert( QString( "Weekly" ), OPimRecurrence::Weekly ); 622 convertMap.insert( QString( "Weekly" ), OPimRecurrence::Weekly );
623 convertMap.insert( QString( "MonthlyDay" ), OPimRecurrence::MonthlyDay ); 623 convertMap.insert( QString( "MonthlyDay" ), OPimRecurrence::MonthlyDay );
624 convertMap.insert( QString( "MonthlyDate" ), OPimRecurrence::MonthlyDate ); 624 convertMap.insert( QString( "MonthlyDate" ), OPimRecurrence::MonthlyDate );
625 convertMap.insert( QString( "Yearly" ), OPimRecurrence::Yearly ); 625 convertMap.insert( QString( "Yearly" ), OPimRecurrence::Yearly );
626 convertMap.insert( QString( "NoRepeat" ), OPimRecurrence::NoRepeat ); 626 convertMap.insert( QString( "NoRepeat" ), OPimRecurrence::NoRepeat );
627 627
628 return convertMap; 628 return convertMap;
629} 629}
630 630
631 631
632QMap<int, QString> OPimRecurrence::toMap() const 632QMap<int, QString> OPimRecurrence::toMap() const
633{ 633{
634 QMap<int, QString> retMap; 634 QMap<int, QString> retMap;
635 635
636 retMap.insert( OPimRecurrence::RType, rTypeString() ); 636 retMap.insert( OPimRecurrence::RType, rTypeString() );
637 retMap.insert( OPimRecurrence::RWeekdays, QString::number( static_cast<int>( data->days ) ) ); 637 retMap.insert( OPimRecurrence::RWeekdays, QString::number( static_cast<int>( data->days ) ) );
638 retMap.insert( OPimRecurrence::RPosition, QString::number(data->pos ) ); 638 retMap.insert( OPimRecurrence::RPosition, QString::number(data->pos ) );
639 retMap.insert( OPimRecurrence::RFreq, QString::number( data->freq ) ); 639 retMap.insert( OPimRecurrence::RFreq, QString::number( data->freq ) );
640 retMap.insert( OPimRecurrence::RHasEndDate, QString::number( static_cast<int>( data->hasEnd ) ) ); 640 retMap.insert( OPimRecurrence::RHasEndDate, QString::number( static_cast<int>( data->hasEnd ) ) );
641 if( data -> hasEnd ) 641 if( data -> hasEnd )
642 retMap.insert( OPimRecurrence::EndDate, QString::number( OPimTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) ); 642 retMap.insert( OPimRecurrence::EndDate, QString::number( OPimTimeZone::current().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) );
643 retMap.insert( OPimRecurrence::Created, QString::number( OPimTimeZone::utc().fromUTCDateTime( data->create ) ) ); 643 retMap.insert( OPimRecurrence::Created, QString::number( OPimTimeZone::current().fromUTCDateTime( data->create ) ) );
644 644
645 if ( data->list.isEmpty() ) return retMap; 645 if ( data->list.isEmpty() ) return retMap;
646 646
647 // save exceptions list here!! 647 // save exceptions list here!!
648 ExceptionList::ConstIterator it; 648 ExceptionList::ConstIterator it;
649 ExceptionList list = data->list; 649 ExceptionList list = data->list;
650 QString exceptBuf; 650 QString exceptBuf;
651 QDate date; 651 QDate date;
652 for ( it = list.begin(); it != list.end(); ++it ) { 652 for ( it = list.begin(); it != list.end(); ++it ) {
653 date = (*it); 653 date = (*it);
654 if ( it != list.begin() ) exceptBuf += " "; 654 if ( it != list.begin() ) exceptBuf += " ";
655 655
656 exceptBuf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() ); 656 exceptBuf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() );
657 } 657 }
658 658
659 retMap.insert( OPimRecurrence::Exceptions, exceptBuf ); 659 retMap.insert( OPimRecurrence::Exceptions, exceptBuf );
660 660
661 return retMap; 661 return retMap;
662} 662}
663 663
664void OPimRecurrence::fromMap( const QMap<int, QString>& map ) 664void OPimRecurrence::fromMap( const QMap<int, QString>& map )
665{ 665{
666 QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap(); 666 QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap();
667 667
668 data -> type = repTypeMap[ map [OPimRecurrence::RType] ]; 668 data -> type = repTypeMap[ map [OPimRecurrence::RType] ];
669 data -> days = (char) map[ OPimRecurrence::RWeekdays ].toInt(); 669 data -> days = (char) map[ OPimRecurrence::RWeekdays ].toInt();
670 data -> pos = map[ OPimRecurrence::RPosition ].toInt(); 670 data -> pos = map[ OPimRecurrence::RPosition ].toInt();
671 data -> freq = map[ OPimRecurrence::RFreq ].toInt(); 671 data -> freq = map[ OPimRecurrence::RFreq ].toInt();
672 data -> hasEnd= map[ OPimRecurrence::RHasEndDate ].toInt() ? true : false; 672 data -> hasEnd= map[ OPimRecurrence::RHasEndDate ].toInt() ? true : false;
673 OPimTimeZone utc = OPimTimeZone::utc(); 673 OPimTimeZone cur = OPimTimeZone::current();
674 if ( data -> hasEnd ){ 674 if ( data -> hasEnd ){
675 data -> end = utc.fromUTCDateTime( (time_t) map[ OPimRecurrence::EndDate ].toLong() ).date(); 675 data -> end = cur.fromUTCDateTime( (time_t) map[ OPimRecurrence::EndDate ].toLong() ).date();
676 } 676 }
677 data -> create = utc.fromUTCDateTime( (time_t) map[ OPimRecurrence::Created ].toLong() ).date(); 677 data -> create = cur.fromUTCDateTime( (time_t) map[ OPimRecurrence::Created ].toLong() ).date();
678 678
679#if 0 679#if 0
680 // FIXME: Exceptions currently not supported... 680 // FIXME: Exceptions currently not supported...
681 // Convert the list of exceptions from QString into ExceptionList 681 // Convert the list of exceptions from QString into ExceptionList
682 data -> list.clear(); 682 data -> list.clear();
683 QString exceptStr = map[ OPimRecurrence::Exceptions ]; 683 QString exceptStr = map[ OPimRecurrence::Exceptions ];
684 QStringList exceptList = QStringList::split( " ", exceptStr ); 684 QStringList exceptList = QStringList::split( " ", exceptStr );
685 ... 685 ...
686#endif 686#endif
687 687
688 688
689} 689}
690 690
691} 691}
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
@@ -3,189 +3,191 @@
3 Copyright (C) The Main Author <main-author@whereever.org> 3 Copyright (C) The Main Author <main-author@whereever.org>
4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 =. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 .=l. 5 .=l.
6 .>+-= 6 .>+-=
7 _;:, .> :=|. This program is free software; you can 7 _;:, .> :=|. This program is free software; you can
8.> <`_, > . <= redistribute it and/or modify it under 8.> <`_, > . <= redistribute it and/or modify it under
9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public 9:`=1 )Y*s>-.-- : the terms of the GNU Library General Public
10.="- .-=="i, .._ License as published by the Free Software 10.="- .-=="i, .._ License as published by the Free Software
11 - . .-<_> .<> Foundation; either version 2 of the License, 11 - . .-<_> .<> Foundation; either version 2 of the License,
12 ._= =} : or (at your option) any later version. 12 ._= =} : or (at your option) any later version.
13 .%`+i> _;_. 13 .%`+i> _;_.
14 .i_,=:_. -<s. This program is distributed in the hope that 14 .i_,=:_. -<s. This program is distributed in the hope that
15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY; 15 + . -:. = it will be useful, but WITHOUT ANY WARRANTY;
16 : .. .:, . . . without even the implied warranty of 16 : .. .:, . . . without even the implied warranty of
17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A 17 =_ + =;=|` MERCHANTABILITY or FITNESS FOR A
18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU 18 _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.= = ; Library General Public License for more 19..}^=.= = ; Library General Public License for more
20++= -. .` .: details. 20++= -. .` .: details.
21 : = ...= . :.=- 21 : = ...= . :.=-
22 -. .:....=;==+<; You should have received a copy of the GNU 22 -. .:....=;==+<; You should have received a copy of the GNU
23 -_. . . )=. = Library General Public License along with 23 -_. . . )=. = Library General Public License along with
24 -- :-=` this library; see the file COPYING.LIB. 24 -- :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30#include "opimtimezone.h" 30#include "opimtimezone.h"
31 31
32/* OPIE */ 32/* OPIE */
33#include <opie2/odebug.h> 33#include <opie2/odebug.h>
34 34
35/* STD */ 35/* STD */
36#include <stdio.h> 36#include <stdio.h>
37#include <stdlib.h> 37#include <stdlib.h>
38#include <sys/types.h> 38#include <sys/types.h>
39 39
40namespace Opie 40namespace Opie
41{ 41{
42 42
43QDateTime utcTime( time_t t ) 43QDateTime utcTime( time_t t )
44{ 44{
45 tm * broken = ::gmtime( &t ); 45 tm * broken = ::gmtime( &t );
46 QDateTime ret; 46 QDateTime ret;
47 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) ); 47 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) );
48 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); 48 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
49 return ret; 49 return ret;
50} 50}
51
51QDateTime utcTime( time_t t, const QString& zone ) 52QDateTime utcTime( time_t t, const QString& zone )
52{ 53{
53 QCString org = ::getenv( "TZ" ); 54 QCString org = ::getenv( "TZ" );
54#ifndef Q_OS_MACX // Following line causes bus errors on Mac 55#ifndef Q_OS_MACX // Following line causes bus errors on Mac
55 56
56 ::setenv( "TZ", zone.latin1(), true ); 57 ::setenv( "TZ", zone.latin1(), true );
57 ::tzset(); 58 ::tzset();
58 59
59 tm* broken = ::localtime( &t ); 60 tm* broken = ::localtime( &t );
60 ::setenv( "TZ", org, true ); 61 ::setenv( "TZ", org, true );
61#else 62#else
62#warning "Need a replacement for MacOSX!!" 63#warning "Need a replacement for MacOSX!!"
63 64
64 tm* broken = ::localtime( &t ); 65 tm* broken = ::localtime( &t );
65#endif 66#endif
66 67
67 QDateTime ret; 68 QDateTime ret;
68 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) ); 69 ret.setDate( QDate( broken->tm_year + 1900, broken->tm_mon + 1, broken->tm_mday ) );
69 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) ); 70 ret.setTime( QTime( broken->tm_hour, broken->tm_min, broken->tm_sec ) );
70 71
71 return ret; 72 return ret;
72} 73}
74
75
73time_t to_Time_t( const QDateTime& utc, const QString& str ) 76time_t to_Time_t( const QDateTime& utc, const QString& str )
74{ 77{
75 QDate d = utc.date(); 78 QDate d = utc.date();
76 QTime t = utc.time(); 79 QTime t = utc.time();
77 80
78 tm broken; 81 tm broken;
79 broken.tm_year = d.year() - 1900; 82 broken.tm_year = d.year() - 1900;
80 broken.tm_mon = d.month() - 1; 83 broken.tm_mon = d.month() - 1;
81 broken.tm_mday = d.day(); 84 broken.tm_mday = d.day();
82 broken.tm_hour = t.hour(); 85 broken.tm_hour = t.hour();
83 broken.tm_min = t.minute(); 86 broken.tm_min = t.minute();
84 broken.tm_sec = t.second(); 87 broken.tm_sec = t.second();
85 88
86 QCString org = ::getenv( "TZ" ); 89 QCString org = ::getenv( "TZ" );
87#ifndef Q_OS_MACX // Following line causes bus errors on Mac 90#ifndef Q_OS_MACX // Following line causes bus errors on Mac
88 91
89 ::setenv( "TZ", str.latin1(), true ); 92 ::setenv( "TZ", str.latin1(), true );
90 ::tzset(); 93 ::tzset();
91 94
92 time_t ti = ::mktime( &broken ); 95 time_t ti = ::mktime( &broken );
93 ::setenv( "TZ", org, true ); 96 ::setenv( "TZ", org, true );
94#else 97#else
95#warning "Need a replacement for MacOSX!!" 98#warning "Need a replacement for MacOSX!!"
96 99
97 time_t ti = ::mktime( &broken ); 100 time_t ti = ::mktime( &broken );
98#endif 101#endif
99 102
100 return ti; 103 return ti;
101} 104}
102} 105}
103 106
104namespace Opie 107namespace Opie
105{ 108{
106OPimTimeZone::OPimTimeZone( const ZoneName& zone ) 109OPimTimeZone::OPimTimeZone( const ZoneName& zone )
107 : m_name( zone ) 110 : m_name( zone )
108{} 111{}
109 112
110 113
111OPimTimeZone::~OPimTimeZone() 114OPimTimeZone::~OPimTimeZone()
112{} 115{}
113 116
114 117
115bool OPimTimeZone::isValid() const 118bool OPimTimeZone::isValid() const
116{ 119{
117 return !m_name.isEmpty(); 120 return !m_name.isEmpty();
118} 121}
119 122
120/* 123/*
121 * we will get the current timezone 124 * we will get the current timezone
122 * and ask it to convert to the timezone date 125 * and ask it to convert to the timezone date
123 */ 126 */
124QDateTime OPimTimeZone::toLocalDateTime( const QDateTime& dt ) 127QDateTime OPimTimeZone::toLocalDateTime( const QDateTime& dt )
125{ 128{
126 return OPimTimeZone::current().toDateTime( dt, *this ); 129 return OPimTimeZone::current().toDateTime( dt, *this );
127} 130}
128 131
129 132
130QDateTime OPimTimeZone::toUTCDateTime( const QDateTime& dt ) 133QDateTime OPimTimeZone::toUTCDateTime( const QDateTime& dt )
131{ 134{
132 return OPimTimeZone::utc().toDateTime( dt, *this ); 135 return OPimTimeZone::utc().toDateTime( dt, *this );
133} 136}
134 137
135 138
136QDateTime OPimTimeZone::fromUTCDateTime( time_t t ) 139QDateTime OPimTimeZone::fromUTCDateTime( time_t t )
137{ 140{
138 return utcTime( t ); 141 return utcTime( t );
139} 142}
140 143
141 144
142QDateTime OPimTimeZone::toDateTime( time_t t ) 145QDateTime OPimTimeZone::toDateTime( time_t t )
143{ 146{
144 return utcTime( t, m_name ); 147 return utcTime( t, m_name );
145} 148}
146 149
147 150
148/* 151/*
149 * convert dt to utc using zone.m_name 152 * convert dt to utc using zone.m_name
150 * convert utc -> timeZoneDT using this->m_name 153 * convert utc -> timeZoneDT using this->m_name
151 */ 154 */
152QDateTime OPimTimeZone::toDateTime( const QDateTime& dt, const OPimTimeZone& zone ) 155QDateTime OPimTimeZone::toDateTime( const QDateTime& dt, const OPimTimeZone& zone )
153{ 156{
154 time_t utc = to_Time_t( dt, zone.m_name ); 157 time_t utc = to_Time_t( dt, m_name );
155 owarn << "" << utc << " " << zone.m_name << "" << oendl; 158 return utcTime( utc, zone.m_name );
156 return utcTime( utc, m_name );
157} 159}
158 160
159 161
160time_t OPimTimeZone::fromDateTime( const QDateTime& time ) 162time_t OPimTimeZone::fromDateTime( const QDateTime& time )
161{ 163{
162 return to_Time_t( time, m_name ); 164 return to_Time_t( time, m_name );
163} 165}
164 166
165 167
166time_t OPimTimeZone::fromUTCDateTime( const QDateTime& time ) 168time_t OPimTimeZone::fromUTCDateTime( const QDateTime& time )
167{ 169{
168 return to_Time_t( time, "UTC" ); 170 return to_Time_t( time, "Europe/London" );
169} 171}
170 172
171 173
172OPimTimeZone OPimTimeZone::current() 174OPimTimeZone OPimTimeZone::current()
173{ 175{
174 QCString str = ::getenv( "TZ" ); 176 QCString str = ::getenv( "TZ" );
175 OPimTimeZone zone( str ); 177 OPimTimeZone zone( str );
176 return zone; 178 return zone;
177} 179}
178 180
179 181
180OPimTimeZone OPimTimeZone::utc() 182OPimTimeZone OPimTimeZone::utc()
181{ 183{
182 return OPimTimeZone( "UTC" ); 184 return OPimTimeZone( "Europe/London" );
183} 185}
184 186
185 187
186QString OPimTimeZone::timeZone() const 188QString OPimTimeZone::timeZone() const
187{ 189{
188 return m_name; 190 return m_name;
189} 191}
190 192
191} 193}