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
@@ -1,651 +1,670 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
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/* OPIE */ 30/* OPIE */
31#include <opie2/opimnotifymanager.h> 31#include <opie2/opimnotifymanager.h>
32#include <opie2/opimrecurrence.h> 32#include <opie2/opimrecurrence.h>
33#include <opie2/opimtimezone.h> 33#include <opie2/opimtimezone.h>
34#include <opie2/odatebookaccessbackend_xml.h> 34#include <opie2/odatebookaccessbackend_xml.h>
35#include <opie2/odebug.h> 35#include <opie2/odebug.h>
36 36
37#include <qtopia/global.h> 37#include <qtopia/global.h>
38#include <qtopia/stringutil.h> 38#include <qtopia/stringutil.h>
39#include <qtopia/timeconversion.h> 39#include <qtopia/timeconversion.h>
40 40
41/* QT */ 41/* QT */
42#include <qasciidict.h> 42#include <qasciidict.h>
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{
295 if ( m_raw.contains( uid ) ) 304 if ( m_raw.contains( uid ) )
296 return m_raw[uid]; 305 return m_raw[uid];
297 else 306 else
298 return m_rep[uid]; 307 return m_rep[uid];
299} 308}
300bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) { 309bool ODateBookAccessBackend_XML::add( const OPimEvent& ev ) {
301 m_changed = true; 310 m_changed = true;
302 if (ev.hasRecurrence() ) 311 if (ev.hasRecurrence() )
303 m_rep.insert( ev.uid(), ev ); 312 m_rep.insert( ev.uid(), ev );
304 else 313 else
305 m_raw.insert( ev.uid(), ev ); 314 m_raw.insert( ev.uid(), ev );
306 315
307 return true; 316 return true;
308} 317}
309bool ODateBookAccessBackend_XML::remove( int uid ) { 318bool ODateBookAccessBackend_XML::remove( int uid ) {
310 m_changed = true; 319 m_changed = true;
311 m_raw.remove( uid ); 320 m_raw.remove( uid );
312 m_rep.remove( uid ); 321 m_rep.remove( uid );
313 322
314 return true; 323 return true;
315} 324}
316bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) { 325bool ODateBookAccessBackend_XML::replace( const OPimEvent& ev ) {
317 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers) 326 replace( ev.uid() ); // ??? Shouldn't this be "remove( ev.uid() ) ??? (eilers)
318 return add( ev ); 327 return add( ev );
319} 328}
320QArray<int> ODateBookAccessBackend_XML::rawEvents()const { 329QArray<int> ODateBookAccessBackend_XML::rawEvents()const {
321 return allRecords(); 330 return allRecords();
322} 331}
323QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { 332QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
324 QArray<int> ints( m_rep.count() ); 333 QArray<int> ints( m_rep.count() );
325 uint i = 0; 334 uint i = 0;
326 QMap<int, OPimEvent>::ConstIterator it; 335 QMap<int, OPimEvent>::ConstIterator it;
327 336
328 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 337 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
329 ints[i] = it.key(); 338 ints[i] = it.key();
330 i++; 339 i++;
331 } 340 }
332 341
333 return ints; 342 return ints;
334} 343}
335QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { 344QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
336 QArray<int> ints( m_raw.count() ); 345 QArray<int> ints( m_raw.count() );
337 uint i = 0; 346 uint i = 0;
338 QMap<int, OPimEvent>::ConstIterator it; 347 QMap<int, OPimEvent>::ConstIterator it;
339 348
340 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 349 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
341 ints[i] = it.key(); 350 ints[i] = it.key();
342 i++; 351 i++;
343 } 352 }
344 353
345 return ints; 354 return ints;
346} 355}
347OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { 356OPimEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
348 OPimEvent::ValueList list; 357 OPimEvent::ValueList list;
349 QMap<int, OPimEvent>::ConstIterator it; 358 QMap<int, OPimEvent>::ConstIterator it;
350 for (it = m_raw.begin(); it != m_raw.end(); ++it ) 359 for (it = m_raw.begin(); it != m_raw.end(); ++it )
351 list.append( it.data() ); 360 list.append( it.data() );
352 361
353 return list; 362 return list;
354} 363}
355OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { 364OPimEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
356 OPimEvent::ValueList list; 365 OPimEvent::ValueList list;
357 QMap<int, OPimEvent>::ConstIterator it; 366 QMap<int, OPimEvent>::ConstIterator it;
358 for (it = m_rep.begin(); it != m_rep.end(); ++it ) 367 for (it = m_rep.begin(); it != m_rep.end(); ++it )
359 list.append( it.data() ); 368 list.append( it.data() );
360 369
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
@@ -1,86 +1,88 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) 3 Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de)
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#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
@@ -1,1032 +1,1028 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
3 Copyright (C) Stefan Eilers <Eilers.Stefan@epost.de> 3 Copyright (C) Stefan Eilers <Eilers.Stefan@epost.de>
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 "opimevent.h" 30#include "opimevent.h"
31 31
32/* OPIE */ 32/* OPIE */
33#include <opie2/opimrecurrence.h> 33#include <opie2/opimrecurrence.h>
34#include <opie2/opimresolver.h> 34#include <opie2/opimresolver.h>
35#include <opie2/opimnotifymanager.h> 35#include <opie2/opimnotifymanager.h>
36#include <opie2/odebug.h> 36#include <opie2/odebug.h>
37 37
38#include <qpe/categories.h> 38#include <qpe/categories.h>
39#include <qpe/stringutil.h> 39#include <qpe/stringutil.h>
40 40
41/* QT */ 41/* QT */
42 42
43namespace Opie 43namespace Opie
44{ 44{
45 45
46int OCalendarHelper::week( const QDate& date ) 46int OCalendarHelper::week( const QDate& date )
47{ 47{
48 // Calculates the week this date is in within that 48 // Calculates the week this date is in within that
49 // month. Equals the "row" is is in in the month view 49 // month. Equals the "row" is is in in the month view
50 int week = 1; 50 int week = 1;
51 QDate tmp( date.year(), date.month(), 1 ); 51 QDate tmp( date.year(), date.month(), 1 );
52 if ( date.dayOfWeek() < tmp.dayOfWeek() ) 52 if ( date.dayOfWeek() < tmp.dayOfWeek() )
53 ++week; 53 ++week;
54 54
55 week += ( date.day() - 1 ) / 7; 55 week += ( date.day() - 1 ) / 7;
56 56
57 return week; 57 return week;
58} 58}
59 59
60 60
61int OCalendarHelper::ocurrence( const QDate& date ) 61int OCalendarHelper::ocurrence( const QDate& date )
62{ 62{
63 // calculates the number of occurrances of this day of the 63 // calculates the number of occurrances of this day of the
64 // week till the given date (e.g 3rd Wednesday of the month) 64 // week till the given date (e.g 3rd Wednesday of the month)
65 return ( date.day() - 1 ) / 7 + 1; 65 return ( date.day() - 1 ) / 7 + 1;
66} 66}
67 67
68 68
69int OCalendarHelper::dayOfWeek( char day ) 69int OCalendarHelper::dayOfWeek( char day )
70{ 70{
71 int dayOfWeek = 1; 71 int dayOfWeek = 1;
72 char i = OPimRecurrence::MON; 72 char i = OPimRecurrence::MON;
73 while ( !( i & day ) && i <= OPimRecurrence::SUN ) 73 while ( !( i & day ) && i <= OPimRecurrence::SUN )
74 { 74 {
75 i <<= 1; 75 i <<= 1;
76 ++dayOfWeek; 76 ++dayOfWeek;
77 } 77 }
78 return dayOfWeek; 78 return dayOfWeek;
79} 79}
80 80
81 81
82int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) 82int OCalendarHelper::monthDiff( const QDate& first, const QDate& second )
83{ 83{
84 return ( second.year() - first.year() ) * 12 + 84 return ( second.year() - first.year() ) * 12 +
85 second.month() - first.month(); 85 second.month() - first.month();
86} 86}
87 87
88 88
89struct OPimEvent::Data : public QShared 89struct OPimEvent::Data : public QShared
90{ 90{
91 Data() : QShared() 91 Data() : QShared()
92 { 92 {
93 child = 0; 93 child = 0;
94 recur = 0; 94 recur = 0;
95 manager = 0; 95 manager = 0;
96 isAllDay = false; 96 isAllDay = false;
97 parent = 0; 97 parent = 0;
98 } 98 }
99 ~Data() 99 ~Data()
100 { 100 {
101 delete manager; 101 delete manager;
102 delete recur; 102 delete recur;
103 } 103 }
104 QString description; 104 QString description;
105 QString location; 105 QString location;
106 OPimNotifyManager* manager; 106 OPimNotifyManager* manager;
107 OPimRecurrence* recur; 107 OPimRecurrence* recur;
108 QString note; 108 QString note;
109 QDateTime created; 109 QDateTime created;
110 QDateTime start; 110 QDateTime start;
111 QDateTime end; 111 QDateTime end;
112bool isAllDay : 1; 112bool isAllDay : 1;
113 QString timezone; 113 QString timezone;
114 QArray<int>* child; 114 QArray<int>* child;
115 int parent; 115 int parent;
116}; 116};
117 117
118 118
119OPimEvent::OPimEvent( int uid ) 119OPimEvent::OPimEvent( int uid )
120 : OPimRecord( uid ) 120 : OPimRecord( uid )
121{ 121{
122 data = new Data; 122 data = new Data;
123} 123}
124 124
125 125
126OPimEvent::OPimEvent( const OPimEvent& ev ) 126OPimEvent::OPimEvent( const OPimEvent& ev )
127 : OPimRecord( ev ), data( ev.data ) 127 : OPimRecord( ev ), data( ev.data )
128{ 128{
129 data->ref(); 129 data->ref();
130} 130}
131 131
132 132
133OPimEvent::OPimEvent( const QMap<int, QString> map ) 133OPimEvent::OPimEvent( const QMap<int, QString> map )
134 : OPimRecord( 0 ) 134 : OPimRecord( 0 )
135{ 135{
136 data = new Data; 136 data = new Data;
137 137
138 fromMap( map ); 138 fromMap( map );
139} 139}
140 140
141 141
142OPimEvent::~OPimEvent() 142OPimEvent::~OPimEvent()
143{ 143{
144 if ( data->deref() ) 144 if ( data->deref() )
145 { 145 {
146 delete data; 146 delete data;
147 data = 0; 147 data = 0;
148 } 148 }
149} 149}
150 150
151 151
152OPimEvent& OPimEvent::operator=( const OPimEvent& ev ) 152OPimEvent& OPimEvent::operator=( const OPimEvent& ev )
153{ 153{
154 if ( this == &ev ) return * this; 154 if ( this == &ev ) return * this;
155 155
156 OPimRecord::operator=( ev ); 156 OPimRecord::operator=( ev );
157 ev.data->ref(); 157 ev.data->ref();
158 deref(); 158 deref();
159 data = ev.data; 159 data = ev.data;
160 160
161 161
162 return *this; 162 return *this;
163} 163}
164 164
165 165
166QString OPimEvent::description() const 166QString OPimEvent::description() const
167{ 167{
168 return data->description; 168 return data->description;
169} 169}
170 170
171 171
172void OPimEvent::setDescription( const QString& description ) 172void OPimEvent::setDescription( const QString& description )
173{ 173{
174 changeOrModify(); 174 changeOrModify();
175 data->description = description; 175 data->description = description;
176} 176}
177 177
178 178
179void OPimEvent::setLocation( const QString& loc ) 179void OPimEvent::setLocation( const QString& loc )
180{ 180{
181 changeOrModify(); 181 changeOrModify();
182 data->location = loc; 182 data->location = loc;
183} 183}
184 184
185 185
186QString OPimEvent::location() const 186QString OPimEvent::location() const
187{ 187{
188 return data->location; 188 return data->location;
189} 189}
190 190
191 191
192OPimNotifyManager &OPimEvent::notifiers() const 192OPimNotifyManager &OPimEvent::notifiers() const
193{ 193{
194 // I hope we can skip the changeOrModify here 194 // I hope we can skip the changeOrModify here
195 // the notifier should take care of it 195 // the notifier should take care of it
196 // and OPimNotify is shared too 196 // and OPimNotify is shared too
197 if ( !data->manager ) 197 if ( !data->manager )
198 data->manager = new OPimNotifyManager; 198 data->manager = new OPimNotifyManager;
199 199
200 return *data->manager; 200 return *data->manager;
201} 201}
202 202
203 203
204bool OPimEvent::hasNotifiers() const 204bool OPimEvent::hasNotifiers() const
205{ 205{
206 if ( !data->manager ) 206 if ( !data->manager )
207 return false; 207 return false;
208 if ( data->manager->reminders().isEmpty() && 208 if ( data->manager->reminders().isEmpty() &&
209 data->manager->alarms().isEmpty() ) 209 data->manager->alarms().isEmpty() )
210 return false; 210 return false;
211 211
212 return true; 212 return true;
213} 213}
214 214
215 215
216OPimRecurrence OPimEvent::recurrence() const 216OPimRecurrence OPimEvent::recurrence() const
217{ 217{
218 if ( !data->recur ) 218 if ( !data->recur )
219 data->recur = new OPimRecurrence; 219 data->recur = new OPimRecurrence;
220 220
221 return *data->recur; 221 return *data->recur;
222} 222}
223 223
224 224
225void OPimEvent::setRecurrence( const OPimRecurrence& rec ) 225void OPimEvent::setRecurrence( const OPimRecurrence& rec )
226{ 226{
227 changeOrModify(); 227 changeOrModify();
228 if ( data->recur ) 228 if ( data->recur )
229 ( *data->recur ) = rec; 229 ( *data->recur ) = rec;
230 else 230 else
231 data->recur = new OPimRecurrence( rec ); 231 data->recur = new OPimRecurrence( rec );
232} 232}
233 233
234 234
235bool OPimEvent::hasRecurrence() const 235bool OPimEvent::hasRecurrence() const
236{ 236{
237 if ( !data->recur ) return false; 237 if ( !data->recur ) return false;
238 return data->recur->doesRecur(); 238 return data->recur->doesRecur();
239} 239}
240 240
241 241
242QString OPimEvent::note() const 242QString OPimEvent::note() const
243{ 243{
244 return data->note; 244 return data->note;
245} 245}
246 246
247 247
248void OPimEvent::setNote( const QString& note ) 248void OPimEvent::setNote( const QString& note )
249{ 249{
250 changeOrModify(); 250 changeOrModify();
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
400 if ( !( value = location() ).isEmpty() ) 401 if ( !( value = location() ).isEmpty() )
401 { 402 {
402 text += "<b>" + QObject::tr( "Location:" ) + "</b> "; 403 text += "<b>" + QObject::tr( "Location:" ) + "</b> ";
403 text += Qtopia::escapeString( value ) + "<br>"; 404 text += Qtopia::escapeString( value ) + "<br>";
404 } 405 }
405 406
406 // all day event 407 // all day event
407 if ( isAllDay() ) 408 if ( isAllDay() )
408 { 409 {
409 text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; 410 text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>";
410 } 411 }
411 // multiple day event 412 // multiple day event
412 else if ( isMultipleDay () ) 413 else if ( isMultipleDay () )
413 { 414 {
414 text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; 415 text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>";
415 } 416 }
416 // start & end times 417 // start & end times
417 else 418 else
418 { 419 {
419 // start time 420 // start time
420 if ( startDateTime().isValid() ) 421 if ( startDateTime().isValid() )
421 { 422 {
422 text += "<b>" + QObject::tr( "Start:" ) + "</b> "; 423 text += "<b>" + QObject::tr( "Start:" ) + "</b> ";
423 text += Qtopia::escapeString( startDateTime().toString() ). 424 text += Qtopia::escapeString( startDateTime().toString() ).
424 replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; 425 replace( QRegExp( "[\n]" ), "<br>" ) + "<br>";
425 } 426 }
426 427
427 // end time 428 // end time
428 if ( endDateTime().isValid() ) 429 if ( endDateTime().isValid() )
429 { 430 {
430 text += "<b>" + QObject::tr( "End:" ) + "</b> "; 431 text += "<b>" + QObject::tr( "End:" ) + "</b> ";
431 text += Qtopia::escapeString( endDateTime().toString() ). 432 text += Qtopia::escapeString( endDateTime().toString() ).
432 replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; 433 replace( QRegExp( "[\n]" ), "<br>" ) + "<br>";
433 } 434 }
434 } 435 }
435 436
436 // categories 437 // categories
437 if ( categoryNames( "Calendar" ).count() ) 438 if ( categoryNames( "Calendar" ).count() )
438 { 439 {
439 text += "<b>" + QObject::tr( "Category:" ) + "</b> "; 440 text += "<b>" + QObject::tr( "Category:" ) + "</b> ";
440 text += categoryNames( "Calendar" ).join( ", " ); 441 text += categoryNames( "Calendar" ).join( ", " );
441 text += "<br>"; 442 text += "<br>";
442 } 443 }
443 444
444 //notes 445 //notes
445 if ( !note().isEmpty() ) 446 if ( !note().isEmpty() )
446 { 447 {
447 text += "<b>" + QObject::tr( "Note:" ) + "</b><br>"; 448 text += "<b>" + QObject::tr( "Note:" ) + "</b><br>";
448 text += note(); 449 text += note();
449 // text += Qtopia::escapeString(note() ). 450 // text += Qtopia::escapeString(note() ).
450 // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; 451 // replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
451 } 452 }
452 return text; 453 return text;
453} 454}
454 455
455 456
456QString OPimEvent::toShortText() const 457QString OPimEvent::toShortText() const
457{ 458{
458 QString text; 459 QString text;
459 text += QString::number( startDateTime().date().day() ); 460 text += QString::number( startDateTime().date().day() );
460 text += "."; 461 text += ".";
461 text += QString::number( startDateTime().date().month() ); 462 text += QString::number( startDateTime().date().month() );
462 text += "."; 463 text += ".";
463 text += QString::number( startDateTime().date().year() ); 464 text += QString::number( startDateTime().date().year() );
464 text += " "; 465 text += " ";
465 text += QString::number( startDateTime().time().hour() ); 466 text += QString::number( startDateTime().time().hour() );
466 text += ":"; 467 text += ":";
467 text += QString::number( startDateTime().time().minute() ); 468 text += QString::number( startDateTime().time().minute() );
468 text += " - "; 469 text += " - ";
469 text += description(); 470 text += description();
470 return text; 471 return text;
471} 472}
472 473
473 474
474QString OPimEvent::type() const 475QString OPimEvent::type() const
475{ 476{
476 return QString::fromLatin1( "OPimEvent" ); 477 return QString::fromLatin1( "OPimEvent" );
477} 478}
478 479
479 480
480QString OPimEvent::recordField( int /*id */ ) const 481QString OPimEvent::recordField( int /*id */ ) const
481{ 482{
482 return QString::null; 483 return QString::null;
483} 484}
484 485
485 486
486int OPimEvent::rtti() const 487int OPimEvent::rtti() const
487{ 488{
488 return OPimResolver::DateBook; 489 return OPimResolver::DateBook;
489} 490}
490 491
491 492
492bool OPimEvent::loadFromStream( QDataStream& ) 493bool OPimEvent::loadFromStream( QDataStream& )
493{ 494{
494 return true; 495 return true;
495} 496}
496 497
497 498
498bool OPimEvent::saveToStream( QDataStream& ) const 499bool OPimEvent::saveToStream( QDataStream& ) const
499{ 500{
500 return true; 501 return true;
501} 502}
502 503
503 504
504void OPimEvent::changeOrModify() 505void OPimEvent::changeOrModify()
505{ 506{
506 if ( data->count != 1 ) 507 if ( data->count != 1 )
507 { 508 {
508 data->deref(); 509 data->deref();
509 Data* d2 = new Data; 510 Data* d2 = new Data;
510 d2->description = data->description; 511 d2->description = data->description;
511 d2->location = data->location; 512 d2->location = data->location;
512 513
513 if ( data->manager ) 514 if ( data->manager )
514 d2->manager = new OPimNotifyManager( *data->manager ); 515 d2->manager = new OPimNotifyManager( *data->manager );
515 516
516 if ( data->recur ) 517 if ( data->recur )
517 d2->recur = new OPimRecurrence( *data->recur ); 518 d2->recur = new OPimRecurrence( *data->recur );
518 519
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
702 698
703int OPimEvent::parent() const 699int OPimEvent::parent() const
704{ 700{
705 return data->parent; 701 return data->parent;
706} 702}
707 703
708 704
709void OPimEvent::setParent( int uid ) 705void OPimEvent::setParent( int uid )
710{ 706{
711 changeOrModify(); 707 changeOrModify();
712 data->parent = uid; 708 data->parent = uid;
713} 709}
714 710
715 711
716QArray<int> OPimEvent::children() const 712QArray<int> OPimEvent::children() const
717{ 713{
718 if ( !data->child ) return QArray<int>(); 714 if ( !data->child ) return QArray<int>();
719 else 715 else
720 return data->child->copy(); 716 return data->child->copy();
721} 717}
722 718
723 719
724void OPimEvent::setChildren( const QArray<int>& arr ) 720void OPimEvent::setChildren( const QArray<int>& arr )
725{ 721{
726 changeOrModify(); 722 changeOrModify();
727 if ( data->child ) delete data->child; 723 if ( data->child ) delete data->child;
728 724
729 data->child = new QArray<int>( arr ); 725 data->child = new QArray<int>( arr );
730 data->child->detach(); 726 data->child->detach();
731} 727}
732 728
733 729
734void OPimEvent::addChild( int uid ) 730void OPimEvent::addChild( int uid )
735{ 731{
736 changeOrModify(); 732 changeOrModify();
737 if ( !data->child ) 733 if ( !data->child )
738 { 734 {
739 data->child = new QArray<int>( 1 ); 735 data->child = new QArray<int>( 1 );
740 ( *data->child ) [ 0 ] = uid; 736 ( *data->child ) [ 0 ] = uid;
741 } 737 }
742 else 738 else
743 { 739 {
744 int count = data->child->count(); 740 int count = data->child->count();
745 data->child->resize( count + 1 ); 741 data->child->resize( count + 1 );
746 ( *data->child ) [ count ] = uid; 742 ( *data->child ) [ count ] = uid;
747 } 743 }
748} 744}
749 745
750 746
751void OPimEvent::removeChild( int uid ) 747void OPimEvent::removeChild( int uid )
752{ 748{
753 if ( !data->child || !data->child->contains( uid ) ) return ; 749 if ( !data->child || !data->child->contains( uid ) ) return ;
754 changeOrModify(); 750 changeOrModify();
755 QArray<int> newAr( data->child->count() - 1 ); 751 QArray<int> newAr( data->child->count() - 1 );
756 int j = 0; 752 int j = 0;
757 uint count = data->child->count(); 753 uint count = data->child->count();
758 for ( uint i = 0; i < count; i++ ) 754 for ( uint i = 0; i < count; i++ )
759 { 755 {
760 if ( ( *data->child ) [ i ] != uid ) 756 if ( ( *data->child ) [ i ] != uid )
761 { 757 {
762 newAr[ j ] = ( *data->child ) [ i ]; 758 newAr[ j ] = ( *data->child ) [ i ];
763 j++; 759 j++;
764 } 760 }
765 } 761 }
766 ( *data->child ) = newAr; 762 ( *data->child ) = newAr;
767} 763}
768 764
769 765
770struct OEffectiveEvent::Data : public QShared 766struct OEffectiveEvent::Data : public QShared
771{ 767{
772 Data() : QShared() 768 Data() : QShared()
773 {} 769 {}
774 OPimEvent event; 770 OPimEvent event;
775 QDate date; 771 QDate date;
776 QTime start, end; 772 QTime start, end;
777 QDate startDate, endDate; 773 QDate startDate, endDate;
778bool dates : 1; 774bool dates : 1;
779}; 775};
780 776
781 777
782OEffectiveEvent::OEffectiveEvent() 778OEffectiveEvent::OEffectiveEvent()
783{ 779{
784 data = new Data; 780 data = new Data;
785 data->date = QDate::currentDate(); 781 data->date = QDate::currentDate();
786 data->start = data->end = QTime::currentTime(); 782 data->start = data->end = QTime::currentTime();
787 data->dates = false; 783 data->dates = false;
788} 784}
789 785
790 786
791OEffectiveEvent::OEffectiveEvent( const OPimEvent& ev, const QDate& startDate, 787OEffectiveEvent::OEffectiveEvent( const OPimEvent& ev, const QDate& startDate,
792 Position pos ) 788 Position pos )
793{ 789{
794 data = new Data; 790 data = new Data;
795 data->event = ev; 791 data->event = ev;
796 data->date = startDate; 792 data->date = startDate;
797 if ( pos & Start ) 793 if ( pos & Start )
798 data->start = ev.startDateTime().time(); 794 data->start = ev.startDateTime().time();
799 else 795 else
800 data->start = QTime( 0, 0, 0 ); 796 data->start = QTime( 0, 0, 0 );
801 797
802 if ( pos & End ) 798 if ( pos & End )
803 data->end = ev.endDateTime().time(); 799 data->end = ev.endDateTime().time();
804 else 800 else
805 data->end = QTime( 23, 59, 59 ); 801 data->end = QTime( 23, 59, 59 );
806 802
807 data->dates = false; 803 data->dates = false;
808} 804}
809 805
810 806
811OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev ) 807OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev )
812{ 808{
813 data = ev.data; 809 data = ev.data;
814 data->ref(); 810 data->ref();
815} 811}
816 812
817 813
818OEffectiveEvent::~OEffectiveEvent() 814OEffectiveEvent::~OEffectiveEvent()
819{ 815{
820 if ( data->deref() ) 816 if ( data->deref() )
821 { 817 {
822 delete data; 818 delete data;
823 data = 0; 819 data = 0;
824 } 820 }
825} 821}
826 822
827 823
828OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) 824OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev )
829{ 825{
830 if ( *this == ev ) return * this; 826 if ( *this == ev ) return * this;
831 827
832 ev.data->ref(); 828 ev.data->ref();
833 deref(); 829 deref();
834 data = ev.data; 830 data = ev.data;
835 831
836 return *this; 832 return *this;
837} 833}
838 834
839 835
840void OEffectiveEvent::setStartTime( const QTime& ti ) 836void OEffectiveEvent::setStartTime( const QTime& ti )
841{ 837{
842 changeOrModify(); 838 changeOrModify();
843 data->start = ti; 839 data->start = ti;
844} 840}
845 841
846 842
847void OEffectiveEvent::setEndTime( const QTime& en ) 843void OEffectiveEvent::setEndTime( const QTime& en )
848{ 844{
849 changeOrModify(); 845 changeOrModify();
850 data->end = en; 846 data->end = en;
851} 847}
852 848
853 849
854void OEffectiveEvent::setEvent( const OPimEvent& ev ) 850void OEffectiveEvent::setEvent( const OPimEvent& ev )
855{ 851{
856 changeOrModify(); 852 changeOrModify();
857 data->event = ev; 853 data->event = ev;
858} 854}
859 855
860 856
861void OEffectiveEvent::setDate( const QDate& da ) 857void OEffectiveEvent::setDate( const QDate& da )
862{ 858{
863 changeOrModify(); 859 changeOrModify();
864 data->date = da; 860 data->date = da;
865} 861}
866 862
867 863
868void OEffectiveEvent::setEffectiveDates( const QDate& from, 864void OEffectiveEvent::setEffectiveDates( const QDate& from,
869 const QDate& to ) 865 const QDate& to )
870{ 866{
871 if ( !from.isValid() ) 867 if ( !from.isValid() )
872 { 868 {
873 data->dates = false; 869 data->dates = false;
874 return ; 870 return ;
875 } 871 }
876 872
877 data->startDate = from; 873 data->startDate = from;
878 data->endDate = to; 874 data->endDate = to;
879} 875}
880 876
881 877
882QString OEffectiveEvent::description() const 878QString OEffectiveEvent::description() const
883{ 879{
884 return data->event.description(); 880 return data->event.description();
885} 881}
886 882
887 883
888QString OEffectiveEvent::location() const 884QString OEffectiveEvent::location() const
889{ 885{
890 return data->event.location(); 886 return data->event.location();
891} 887}
892 888
893 889
894QString OEffectiveEvent::note() const 890QString OEffectiveEvent::note() const
895{ 891{
896 return data->event.note(); 892 return data->event.note();
897} 893}
898 894
899 895
900OPimEvent OEffectiveEvent::event() const 896OPimEvent OEffectiveEvent::event() const
901{ 897{
902 return data->event; 898 return data->event;
903} 899}
904 900
905 901
906QTime OEffectiveEvent::startTime() const 902QTime OEffectiveEvent::startTime() const
907{ 903{
908 return data->start; 904 return data->start;
909} 905}
910 906
911 907
912QTime OEffectiveEvent::endTime() const 908QTime OEffectiveEvent::endTime() const
913{ 909{
914 return data->end; 910 return data->end;
915} 911}
916 912
917 913
918QDate OEffectiveEvent::date() const 914QDate OEffectiveEvent::date() const
919{ 915{
920 return data->date; 916 return data->date;
921} 917}
922 918
923 919
924int OEffectiveEvent::length() const 920int OEffectiveEvent::length() const
925{ 921{
926 return ( data->end.hour() * 60 - data->start.hour() * 60 ) 922 return ( data->end.hour() * 60 - data->start.hour() * 60 )
927 + QABS( data->start.minute() - data->end.minute() ); 923 + QABS( data->start.minute() - data->end.minute() );
928} 924}
929 925
930 926
931int OEffectiveEvent::size() const 927int OEffectiveEvent::size() const
932{ 928{
933 return ( data->end.hour() - data->start.hour() ) * 3600 929 return ( data->end.hour() - data->start.hour() ) * 3600
934 + ( data->end.minute() - data->start.minute() * 60 930 + ( data->end.minute() - data->start.minute() * 60
935 + data->end.second() - data->start.second() ); 931 + data->end.second() - data->start.second() );
936} 932}
937 933
938 934
939QDate OEffectiveEvent::startDate() const 935QDate OEffectiveEvent::startDate() const
940{ 936{
941 if ( data->dates ) 937 if ( data->dates )
942 return data->startDate; 938 return data->startDate;
943 else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer 939 else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
944 return data->date; 940 return data->date;
945 else 941 else
946 return data->event.startDateTime().date(); 942 return data->event.startDateTime().date();
947} 943}
948 944
949 945
950QDate OEffectiveEvent::endDate() const 946QDate OEffectiveEvent::endDate() const
951{ 947{
952 if ( data->dates ) 948 if ( data->dates )
953 return data->endDate; 949 return data->endDate;
954 else if ( data->event.hasRecurrence() ) 950 else if ( data->event.hasRecurrence() )
955 return data->date; 951 return data->date;
956 else 952 else
957 return data->event.endDateTime().date(); 953 return data->event.endDateTime().date();
958} 954}
959 955
960 956
961void OEffectiveEvent::deref() 957void OEffectiveEvent::deref()
962{ 958{
963 if ( data->deref() ) 959 if ( data->deref() )
964 { 960 {
965 delete data; 961 delete data;
966 data = 0; 962 data = 0;
967 } 963 }
968} 964}
969 965
970 966
971void OEffectiveEvent::changeOrModify() 967void OEffectiveEvent::changeOrModify()
972{ 968{
973 if ( data->count != 1 ) 969 if ( data->count != 1 )
974 { 970 {
975 data->deref(); 971 data->deref();
976 Data* d2 = new Data; 972 Data* d2 = new Data;
977 d2->event = data->event; 973 d2->event = data->event;
978 d2->date = data->date; 974 d2->date = data->date;
979 d2->start = data->start; 975 d2->start = data->start;
980 d2->end = data->end; 976 d2->end = data->end;
981 d2->startDate = data->startDate; 977 d2->startDate = data->startDate;
982 d2->endDate = data->endDate; 978 d2->endDate = data->endDate;
983 d2->dates = data->dates; 979 d2->dates = data->dates;
984 data = d2; 980 data = d2;
985 } 981 }
986} 982}
987 983
988 984
989bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const 985bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const
990{ 986{
991 if ( data->date < e.date() ) 987 if ( data->date < e.date() )
992 return TRUE; 988 return TRUE;
993 if ( data->date == e.date() ) 989 if ( data->date == e.date() )
994 return ( startTime() < e.startTime() ); 990 return ( startTime() < e.startTime() );
995 else 991 else
996 return FALSE; 992 return FALSE;
997} 993}
998 994
999 995
1000bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const 996bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const
1001{ 997{
1002 return ( data->date <= e.date() ); 998 return ( data->date <= e.date() );
1003} 999}
1004 1000
1005 1001
1006bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const 1002bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const
1007{ 1003{
1008 return ( date() == e.date() 1004 return ( date() == e.date()
1009 && startTime() == e.startTime() 1005 && startTime() == e.startTime()
1010 && endTime() == e.endTime() 1006 && endTime() == e.endTime()
1011 && event() == e.event() ); 1007 && event() == e.event() );
1012} 1008}
1013 1009
1014 1010
1015bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const 1011bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const
1016{ 1012{
1017 return !( *this == e ); 1013 return !( *this == e );
1018} 1014}
1019 1015
1020 1016
1021bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const 1017bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const
1022{ 1018{
1023 return !( *this <= e ); 1019 return !( *this <= e );
1024} 1020}
1025 1021
1026 1022
1027bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const 1023bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const
1028{ 1024{
1029 return !( *this < e ); 1025 return !( *this < e );
1030} 1026}
1031 1027
1032} 1028}
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
@@ -251,441 +251,441 @@ bool OPimRecurrence::p_nextOccurrence( const QDate& from, QDate& next ) {
251 from that matches the frequency given */ 251 from that matches the frequency given */
252 252
253 /* find for this month */ 253 /* find for this month */
254 tmpDate = QDate( iyear, imonth, 1 ); 254 tmpDate = QDate( iyear, imonth, 1 );
255 255
256 iday = 1; 256 iday = 1;
257 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 257 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
258 iday += 7 * weekOfMonth; 258 iday += 7 * weekOfMonth;
259 while (iday > tmpDate.daysInMonth()) { 259 while (iday > tmpDate.daysInMonth()) {
260 imonth += freq; 260 imonth += freq;
261 if (imonth > 12) { 261 if (imonth > 12) {
262 imonth--; 262 imonth--;
263 iyear += imonth / 12; 263 iyear += imonth / 12;
264 imonth = imonth % 12; 264 imonth = imonth % 12;
265 imonth++; 265 imonth++;
266 } 266 }
267 tmpDate = QDate( iyear, imonth, 1 ); 267 tmpDate = QDate( iyear, imonth, 1 );
268 /* these loops could go for a while, check end case now */ 268 /* these loops could go for a while, check end case now */
269 if ((tmpDate > endDate()) && hasEndDate() ) 269 if ((tmpDate > endDate()) && hasEndDate() )
270 return FALSE; 270 return FALSE;
271 iday = 1; 271 iday = 1;
272 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 272 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
273 iday += 7 * weekOfMonth; 273 iday += 7 * weekOfMonth;
274 } 274 }
275 tmpDate = QDate(iyear, imonth, iday); 275 tmpDate = QDate(iyear, imonth, iday);
276 276
277 if (tmpDate >= from) { 277 if (tmpDate >= from) {
278 next = tmpDate; 278 next = tmpDate;
279 if ((next > endDate() ) && hasEndDate() ) 279 if ((next > endDate() ) && hasEndDate() )
280 return FALSE; 280 return FALSE;
281 return TRUE; 281 return TRUE;
282 } 282 }
283 283
284 /* need to find the next iteration */ 284 /* need to find the next iteration */
285 do { 285 do {
286 imonth += freq; 286 imonth += freq;
287 if (imonth > 12) { 287 if (imonth > 12) {
288 imonth--; 288 imonth--;
289 iyear += imonth / 12; 289 iyear += imonth / 12;
290 imonth = imonth % 12; 290 imonth = imonth % 12;
291 imonth++; 291 imonth++;
292 } 292 }
293 tmpDate = QDate( iyear, imonth, 1 ); 293 tmpDate = QDate( iyear, imonth, 1 );
294 /* these loops could go for a while, check end case now */ 294 /* these loops could go for a while, check end case now */
295 if ((tmpDate > endDate()) && hasEndDate() ) 295 if ((tmpDate > endDate()) && hasEndDate() )
296 return FALSE; 296 return FALSE;
297 iday = 1; 297 iday = 1;
298 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 298 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
299 iday += 7 * weekOfMonth; 299 iday += 7 * weekOfMonth;
300 } while (iday > tmpDate.daysInMonth()); 300 } while (iday > tmpDate.daysInMonth());
301 tmpDate = QDate(iyear, imonth, iday); 301 tmpDate = QDate(iyear, imonth, iday);
302 302
303 next = tmpDate; 303 next = tmpDate;
304 if ((next > endDate()) && hasEndDate() ) 304 if ((next > endDate()) && hasEndDate() )
305 return FALSE; 305 return FALSE;
306 return TRUE; 306 return TRUE;
307 case MonthlyDate: 307 case MonthlyDate:
308 iday = start().day(); 308 iday = start().day();
309 iyear = from.year(); 309 iyear = from.year();
310 imonth = from.month(); 310 imonth = from.month();
311 311
312 a = from.year() - start().year(); 312 a = from.year() - start().year();
313 a *= 12; 313 a *= 12;
314 a = a + (imonth - start().month()); 314 a = a + (imonth - start().month());
315 /* a is e.start()monthsFrom(from); */ 315 /* a is e.start()monthsFrom(from); */
316 if(a % freq) { 316 if(a % freq) {
317 a = freq - (a % freq); 317 a = freq - (a % freq);
318 imonth = from.month() + a; 318 imonth = from.month() + a;
319 if (imonth > 12) { 319 if (imonth > 12) {
320 imonth--; 320 imonth--;
321 iyear += imonth / 12; 321 iyear += imonth / 12;
322 imonth = imonth % 12; 322 imonth = imonth % 12;
323 imonth++; 323 imonth++;
324 } 324 }
325 } 325 }
326 /* imonth is now the first month after or on 326 /* imonth is now the first month after or on
327 from that matches the frequencey given */ 327 from that matches the frequencey given */
328 328
329 /* this could go for a while, worse case, 4*12 iterations, probably */ 329 /* this could go for a while, worse case, 4*12 iterations, probably */
330 while(!QDate::isValid(iyear, imonth, iday) ) { 330 while(!QDate::isValid(iyear, imonth, iday) ) {
331 imonth += freq; 331 imonth += freq;
332 if (imonth > 12) { 332 if (imonth > 12) {
333 imonth--; 333 imonth--;
334 iyear += imonth / 12; 334 iyear += imonth / 12;
335 imonth = imonth % 12; 335 imonth = imonth % 12;
336 imonth++; 336 imonth++;
337 } 337 }
338 /* these loops could go for a while, check end case now */ 338 /* these loops could go for a while, check end case now */
339 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) 339 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
340 return FALSE; 340 return FALSE;
341 } 341 }
342 342
343 if(QDate(iyear, imonth, iday) >= from) { 343 if(QDate(iyear, imonth, iday) >= from) {
344 /* done */ 344 /* done */
345 next = QDate(iyear, imonth, iday); 345 next = QDate(iyear, imonth, iday);
346 if ((next > endDate()) && hasEndDate() ) 346 if ((next > endDate()) && hasEndDate() )
347 return FALSE; 347 return FALSE;
348 return TRUE; 348 return TRUE;
349 } 349 }
350 350
351 /* ok, need to cycle */ 351 /* ok, need to cycle */
352 imonth += freq; 352 imonth += freq;
353 imonth--; 353 imonth--;
354 iyear += imonth / 12; 354 iyear += imonth / 12;
355 imonth = imonth % 12; 355 imonth = imonth % 12;
356 imonth++; 356 imonth++;
357 357
358 while(!QDate::isValid(iyear, imonth, iday) ) { 358 while(!QDate::isValid(iyear, imonth, iday) ) {
359 imonth += freq; 359 imonth += freq;
360 imonth--; 360 imonth--;
361 iyear += imonth / 12; 361 iyear += imonth / 12;
362 imonth = imonth % 12; 362 imonth = imonth % 12;
363 imonth++; 363 imonth++;
364 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) 364 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
365 return FALSE; 365 return FALSE;
366 } 366 }
367 367
368 next = QDate(iyear, imonth, iday); 368 next = QDate(iyear, imonth, iday);
369 if ((next > endDate()) && hasEndDate() ) 369 if ((next > endDate()) && hasEndDate() )
370 return FALSE; 370 return FALSE;
371 return TRUE; 371 return TRUE;
372 case Yearly: 372 case Yearly:
373 iday = start().day(); 373 iday = start().day();
374 imonth = start().month(); 374 imonth = start().month();
375 iyear = from.year(); // after all, we want to start in this year 375 iyear = from.year(); // after all, we want to start in this year
376 376
377 diff = 1; 377 diff = 1;
378 if(imonth == 2 && iday > 28) { 378 if(imonth == 2 && iday > 28) {
379 /* leap year, and it counts, calculate actual frequency */ 379 /* leap year, and it counts, calculate actual frequency */
380 if(freq % 4) 380 if(freq % 4)
381 if (freq % 2) 381 if (freq % 2)
382 freq = freq * 4; 382 freq = freq * 4;
383 else 383 else
384 freq = freq * 2; 384 freq = freq * 2;
385 /* else divides by 4 already, leave freq alone */ 385 /* else divides by 4 already, leave freq alone */
386 diff = 4; 386 diff = 4;
387 } 387 }
388 388
389 a = from.year() - start().year(); 389 a = from.year() - start().year();
390 if(a % freq) { 390 if(a % freq) {
391 a = freq - (a % freq); 391 a = freq - (a % freq);
392 iyear = iyear + a; 392 iyear = iyear + a;
393 } 393 }
394 394
395 /* under the assumption we won't hit one of the special not-leap years twice */ 395 /* under the assumption we won't hit one of the special not-leap years twice */
396 if(!QDate::isValid(iyear, imonth, iday)) { 396 if(!QDate::isValid(iyear, imonth, iday)) {
397 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 397 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
398 iyear += freq; 398 iyear += freq;
399 } 399 }
400 400
401 if(QDate(iyear, imonth, iday) >= from) { 401 if(QDate(iyear, imonth, iday) >= from) {
402 next = QDate(iyear, imonth, iday); 402 next = QDate(iyear, imonth, iday);
403 403
404 if ((next > endDate()) && hasEndDate() ) 404 if ((next > endDate()) && hasEndDate() )
405 return FALSE; 405 return FALSE;
406 return TRUE; 406 return TRUE;
407 } 407 }
408 /* iyear == from.year(), need to advance again */ 408 /* iyear == from.year(), need to advance again */
409 iyear += freq; 409 iyear += freq;
410 /* under the assumption we won't hit one of the special not-leap years twice */ 410 /* under the assumption we won't hit one of the special not-leap years twice */
411 if(!QDate::isValid(iyear, imonth, iday)) { 411 if(!QDate::isValid(iyear, imonth, iday)) {
412 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 412 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
413 iyear += freq; 413 iyear += freq;
414 } 414 }
415 415
416 next = QDate(iyear, imonth, iday); 416 next = QDate(iyear, imonth, iday);
417 if ((next > endDate()) && hasEndDate() ) 417 if ((next > endDate()) && hasEndDate() )
418 return FALSE; 418 return FALSE;
419 return TRUE; 419 return TRUE;
420 default: 420 default:
421 return FALSE; 421 return FALSE;
422 } 422 }
423} 423}
424 424
425 425
426OPimRecurrence::RepeatType OPimRecurrence::type()const{ 426OPimRecurrence::RepeatType OPimRecurrence::type()const{
427 return data->type; 427 return data->type;
428} 428}
429 429
430 430
431int OPimRecurrence::frequency()const { 431int OPimRecurrence::frequency()const {
432 return data->freq; 432 return data->freq;
433} 433}
434 434
435 435
436int OPimRecurrence::position()const { 436int OPimRecurrence::position()const {
437 return data->pos; 437 return data->pos;
438} 438}
439 439
440 440
441char OPimRecurrence::days() const{ 441char OPimRecurrence::days() const{
442 return data->days; 442 return data->days;
443} 443}
444 444
445 445
446bool OPimRecurrence::hasEndDate()const { 446bool OPimRecurrence::hasEndDate()const {
447 return data->hasEnd; 447 return data->hasEnd;
448} 448}
449 449
450 450
451QDate OPimRecurrence::endDate()const { 451QDate OPimRecurrence::endDate()const {
452 return data->end; 452 return data->end;
453} 453}
454 454
455 455
456QDate OPimRecurrence::start()const{ 456QDate OPimRecurrence::start()const{
457 return data->start; 457 return data->start;
458} 458}
459 459
460 460
461QDateTime OPimRecurrence::createdDateTime()const { 461QDateTime OPimRecurrence::createdDateTime()const {
462 return data->create; 462 return data->create;
463} 463}
464 464
465 465
466int OPimRecurrence::repetition()const { 466int OPimRecurrence::repetition()const {
467 return data->rep; 467 return data->rep;
468} 468}
469 469
470 470
471QString OPimRecurrence::service()const { 471QString OPimRecurrence::service()const {
472 return data->app; 472 return data->app;
473} 473}
474 474
475 475
476OPimRecurrence::ExceptionList& OPimRecurrence::exceptions() { 476OPimRecurrence::ExceptionList& OPimRecurrence::exceptions() {
477 return data->list; 477 return data->list;
478} 478}
479 479
480 480
481void OPimRecurrence::setType( const RepeatType& z) { 481void OPimRecurrence::setType( const RepeatType& z) {
482 checkOrModify(); 482 checkOrModify();
483 data->type = z; 483 data->type = z;
484} 484}
485 485
486 486
487void OPimRecurrence::setFrequency( int freq ) { 487void OPimRecurrence::setFrequency( int freq ) {
488 checkOrModify(); 488 checkOrModify();
489 data->freq = freq; 489 data->freq = freq;
490} 490}
491 491
492 492
493void OPimRecurrence::setPosition( int pos ) { 493void OPimRecurrence::setPosition( int pos ) {
494 checkOrModify(); 494 checkOrModify();
495 data->pos = pos; 495 data->pos = pos;
496} 496}
497 497
498 498
499void OPimRecurrence::setDays( char c ) { 499void OPimRecurrence::setDays( char c ) {
500 checkOrModify(); 500 checkOrModify();
501 data->days = c; 501 data->days = c;
502} 502}
503 503
504 504
505void OPimRecurrence::setEndDate( const QDate& dt) { 505void OPimRecurrence::setEndDate( const QDate& dt) {
506 checkOrModify(); 506 checkOrModify();
507 data->end = dt; 507 data->end = dt;
508} 508}
509 509
510 510
511void OPimRecurrence::setCreatedDateTime( const QDateTime& t) { 511void OPimRecurrence::setCreatedDateTime( const QDateTime& t) {
512 checkOrModify(); 512 checkOrModify();
513 data->create = t; 513 data->create = t;
514} 514}
515 515
516 516
517void OPimRecurrence::setHasEndDate( bool b) { 517void OPimRecurrence::setHasEndDate( bool b) {
518 checkOrModify(); 518 checkOrModify();
519 data->hasEnd = b; 519 data->hasEnd = b;
520} 520}
521 521
522 522
523void OPimRecurrence::setRepitition( int rep ) { 523void OPimRecurrence::setRepitition( int rep ) {
524 checkOrModify(); 524 checkOrModify();
525 data->rep = rep; 525 data->rep = rep;
526} 526}
527 527
528 528
529void OPimRecurrence::setService( const QString& app ) { 529void OPimRecurrence::setService( const QString& app ) {
530 checkOrModify(); 530 checkOrModify();
531 data->app = app; 531 data->app = app;
532} 532}
533 533
534 534
535void OPimRecurrence::setStart( const QDate& dt ) { 535void OPimRecurrence::setStart( const QDate& dt ) {
536 checkOrModify(); 536 checkOrModify();
537 data->start = dt; 537 data->start = dt;
538} 538}
539 539
540 540
541void OPimRecurrence::checkOrModify() { 541void OPimRecurrence::checkOrModify() {
542 if ( data->count != 1 ) { 542 if ( data->count != 1 ) {
543 data->deref(); 543 data->deref();
544 Data* d2 = new Data; 544 Data* d2 = new Data;
545 d2->days = data->days; 545 d2->days = data->days;
546 d2->type = data->type; 546 d2->type = data->type;
547 d2->freq = data->freq; 547 d2->freq = data->freq;
548 d2->pos = data->pos; 548 d2->pos = data->pos;
549 d2->hasEnd = data->hasEnd; 549 d2->hasEnd = data->hasEnd;
550 d2->end = data->end; 550 d2->end = data->end;
551 d2->create = data->create; 551 d2->create = data->create;
552 d2->rep = data->rep; 552 d2->rep = data->rep;
553 d2->app = data->app; 553 d2->app = data->app;
554 d2->list = data->list; 554 d2->list = data->list;
555 d2->start = data->start; 555 d2->start = data->start;
556 data = d2; 556 data = d2;
557 } 557 }
558} 558}
559 559
560 560
561QString OPimRecurrence::toString()const { 561QString OPimRecurrence::toString()const {
562 QString buf; 562 QString buf;
563 QMap<int, QString> recMap = toMap(); 563 QMap<int, QString> recMap = toMap();
564 564
565 buf += " rtype=\""; 565 buf += " rtype=\"";
566 buf += recMap[OPimRecurrence::RType]; 566 buf += recMap[OPimRecurrence::RType];
567 buf += "\""; 567 buf += "\"";
568 if (data->days > 0 ) 568 if (data->days > 0 )
569 buf += " rweekdays=\"" + recMap[OPimRecurrence::RWeekdays] + "\""; 569 buf += " rweekdays=\"" + recMap[OPimRecurrence::RWeekdays] + "\"";
570 if ( data->pos != 0 ) 570 if ( data->pos != 0 )
571 buf += " rposition=\"" + recMap[OPimRecurrence::RPosition] + "\""; 571 buf += " rposition=\"" + recMap[OPimRecurrence::RPosition] + "\"";
572 572
573 buf += " rfreq=\"" + recMap[OPimRecurrence::RFreq] + "\""; 573 buf += " rfreq=\"" + recMap[OPimRecurrence::RFreq] + "\"";
574 buf += " rhasenddate=\"" + recMap[OPimRecurrence::RHasEndDate]+ "\""; 574 buf += " rhasenddate=\"" + recMap[OPimRecurrence::RHasEndDate]+ "\"";
575 if ( data->hasEnd ) 575 if ( data->hasEnd )
576 buf += " enddt=\"" 576 buf += " enddt=\""
577 + recMap[OPimRecurrence::EndDate] 577 + recMap[OPimRecurrence::EndDate]
578 + "\""; 578 + "\"";
579 buf += " created=\"" + recMap[OPimRecurrence::Created] + "\""; 579 buf += " created=\"" + recMap[OPimRecurrence::Created] + "\"";
580 580
581 if ( data->list.isEmpty() ) return buf; 581 if ( data->list.isEmpty() ) return buf;
582 buf += " exceptions=\""; 582 buf += " exceptions=\"";
583 buf += recMap[OPimRecurrence::Exceptions]; 583 buf += recMap[OPimRecurrence::Exceptions];
584 buf += "\" "; 584 buf += "\" ";
585 585
586 return buf; 586 return buf;
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
@@ -1,191 +1,193 @@
1/* 1/*
2 This file is part of the Opie Project 2 This file is part of the Opie Project
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}