summaryrefslogtreecommitdiff
authorhakan <hakan>2002-03-29 16:32:49 (UTC)
committer hakan <hakan>2002-03-29 16:32:49 (UTC)
commitd31e0363e905aae78034626896b0d6620ffbc8fc (patch) (unidiff)
treee6a98e06b0a76008c1ca8b12a095ce2ab2cabd34
parent6e194663130b9548c4a31afd2798d9ca1dd30be5 (diff)
downloadopie-d31e0363e905aae78034626896b0d6620ffbc8fc.zip
opie-d31e0363e905aae78034626896b0d6620ffbc8fc.tar.gz
opie-d31e0363e905aae78034626896b0d6620ffbc8fc.tar.bz2
Added getEvent(uid) and a fix reassigning uids to events whos uids have been cleared
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/datebookdb.cpp25
-rw-r--r--library/datebookdb.h3
2 files changed, 27 insertions, 1 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp
index bf7fd94..da5a797 100644
--- a/library/datebookdb.cpp
+++ b/library/datebookdb.cpp
@@ -80,943 +80,966 @@ bool nextOccurance(const Event &e, const QDate &from, QDateTime &next)
80 next = e.start(); 80 next = e.start();
81 return TRUE; 81 return TRUE;
82 } 82 }
83 83
84 switch ( e.repeatPattern().type ) { 84 switch ( e.repeatPattern().type ) {
85 case Event::Weekly: 85 case Event::Weekly:
86 /* weekly is just daily by 7 */ 86 /* weekly is just daily by 7 */
87 /* first convert the repeatPattern.Days() mask to the next 87 /* first convert the repeatPattern.Days() mask to the next
88 day of week valid after from */ 88 day of week valid after from */
89 dayOfWeek = from.dayOfWeek(); 89 dayOfWeek = from.dayOfWeek();
90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
91 91
92 /* this is done in case freq > 1 and from in week not 92 /* this is done in case freq > 1 and from in week not
93 for this round */ 93 for this round */
94 // firstOfWeek = 0; this is already done at decl. 94 // firstOfWeek = 0; this is already done at decl.
95 while(!((1 << firstOfWeek) & e.repeatPattern().days)) 95 while(!((1 << firstOfWeek) & e.repeatPattern().days))
96 firstOfWeek++; 96 firstOfWeek++;
97 97
98 /* there is at least one 'day', or there would be no event */ 98 /* there is at least one 'day', or there would be no event */
99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) 99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days))
100 dayOfWeek++; 100 dayOfWeek++;
101 101
102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */ 102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */
103 dayOfWeek -= e.start().date().dayOfWeek() -1; 103 dayOfWeek -= e.start().date().dayOfWeek() -1;
104 104
105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */ 105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */
106 firstOfWeek -= e.start().date().dayOfWeek() -1; 106 firstOfWeek -= e.start().date().dayOfWeek() -1;
107 107
108 // dayOfWeek may be negitive now 108 // dayOfWeek may be negitive now
109 // day of week is number of days to add to start day 109 // day of week is number of days to add to start day
110 110
111 freq *= 7; 111 freq *= 7;
112 // FALL-THROUGH !!!!! 112 // FALL-THROUGH !!!!!
113 case Event::Daily: 113 case Event::Daily:
114 // the add is for the possible fall through from weekly */ 114 // the add is for the possible fall through from weekly */
115 if(e.start().date().addDays(dayOfWeek) > from) { 115 if(e.start().date().addDays(dayOfWeek) > from) {
116 /* first week exception */ 116 /* first week exception */
117 next = QDateTime(e.start().date().addDays(dayOfWeek), 117 next = QDateTime(e.start().date().addDays(dayOfWeek),
118 e.start().time()); 118 e.start().time());
119 if ((next.date() > e.repeatPattern().endDate()) 119 if ((next.date() > e.repeatPattern().endDate())
120 && e.repeatPattern().hasEndDate) 120 && e.repeatPattern().hasEndDate)
121 return FALSE; 121 return FALSE;
122 return TRUE; 122 return TRUE;
123 } 123 }
124 /* if from is middle of a non-week */ 124 /* if from is middle of a non-week */
125 125
126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; 126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq;
127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; 127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq;
128 128
129 if(diff != 0) 129 if(diff != 0)
130 diff = freq - diff; 130 diff = freq - diff;
131 if(diff2 != 0) 131 if(diff2 != 0)
132 diff2 = freq - diff2; 132 diff2 = freq - diff2;
133 diff = QMIN(diff, diff2); 133 diff = QMIN(diff, diff2);
134 134
135 next = QDateTime(from.addDays(diff), e.start().time()); 135 next = QDateTime(from.addDays(diff), e.start().time());
136 if ( (next.date() > e.repeatPattern().endDate()) 136 if ( (next.date() > e.repeatPattern().endDate())
137 && e.repeatPattern().hasEndDate ) 137 && e.repeatPattern().hasEndDate )
138 return FALSE; 138 return FALSE;
139 return TRUE; 139 return TRUE;
140 case Event::MonthlyDay: 140 case Event::MonthlyDay:
141 iday = from.day(); 141 iday = from.day();
142 iyear = from.year(); 142 iyear = from.year();
143 imonth = from.month(); 143 imonth = from.month();
144 /* find equivelent day of month for this month */ 144 /* find equivelent day of month for this month */
145 dayOfWeek = e.start().date().dayOfWeek(); 145 dayOfWeek = e.start().date().dayOfWeek();
146 weekOfMonth = (e.start().date().day() - 1) / 7; 146 weekOfMonth = (e.start().date().day() - 1) / 7;
147 147
148 /* work out when the next valid month is */ 148 /* work out when the next valid month is */
149 a = from.year() - e.start().date().year(); 149 a = from.year() - e.start().date().year();
150 a *= 12; 150 a *= 12;
151 a = a + (imonth - e.start().date().month()); 151 a = a + (imonth - e.start().date().month());
152 /* a is e.start()monthsFrom(from); */ 152 /* a is e.start()monthsFrom(from); */
153 if(a % freq) { 153 if(a % freq) {
154 a = freq - (a % freq); 154 a = freq - (a % freq);
155 imonth = from.month() + a; 155 imonth = from.month() + a;
156 if (imonth > 12) { 156 if (imonth > 12) {
157 imonth--; 157 imonth--;
158 iyear += imonth / 12; 158 iyear += imonth / 12;
159 imonth = imonth % 12; 159 imonth = imonth % 12;
160 imonth++; 160 imonth++;
161 } 161 }
162 } 162 }
163 /* imonth is now the first month after or on 163 /* imonth is now the first month after or on
164 from that matches the frequency given */ 164 from that matches the frequency given */
165 165
166 /* find for this month */ 166 /* find for this month */
167 tmpDate = QDate( iyear, imonth, 1 ); 167 tmpDate = QDate( iyear, imonth, 1 );
168 168
169 iday = 1; 169 iday = 1;
170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
171 iday += 7 * weekOfMonth; 171 iday += 7 * weekOfMonth;
172 while (iday > tmpDate.daysInMonth()) { 172 while (iday > tmpDate.daysInMonth()) {
173 imonth += freq; 173 imonth += freq;
174 if (imonth > 12) { 174 if (imonth > 12) {
175 imonth--; 175 imonth--;
176 iyear += imonth / 12; 176 iyear += imonth / 12;
177 imonth = imonth % 12; 177 imonth = imonth % 12;
178 imonth++; 178 imonth++;
179 } 179 }
180 tmpDate = QDate( iyear, imonth, 1 ); 180 tmpDate = QDate( iyear, imonth, 1 );
181 /* these loops could go for a while, check end case now */ 181 /* these loops could go for a while, check end case now */
182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
183 return FALSE; 183 return FALSE;
184 iday = 1; 184 iday = 1;
185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
186 iday += 7 * weekOfMonth; 186 iday += 7 * weekOfMonth;
187 } 187 }
188 tmpDate = QDate(iyear, imonth, iday); 188 tmpDate = QDate(iyear, imonth, iday);
189 189
190 if (tmpDate >= from) { 190 if (tmpDate >= from) {
191 next = QDateTime(tmpDate, e.start().time()); 191 next = QDateTime(tmpDate, e.start().time());
192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
193 return FALSE; 193 return FALSE;
194 return TRUE; 194 return TRUE;
195 } 195 }
196 196
197 /* need to find the next iteration */ 197 /* need to find the next iteration */
198 do { 198 do {
199 imonth += freq; 199 imonth += freq;
200 if (imonth > 12) { 200 if (imonth > 12) {
201 imonth--; 201 imonth--;
202 iyear += imonth / 12; 202 iyear += imonth / 12;
203 imonth = imonth % 12; 203 imonth = imonth % 12;
204 imonth++; 204 imonth++;
205 } 205 }
206 tmpDate = QDate( iyear, imonth, 1 ); 206 tmpDate = QDate( iyear, imonth, 1 );
207 /* these loops could go for a while, check end case now */ 207 /* these loops could go for a while, check end case now */
208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
209 return FALSE; 209 return FALSE;
210 iday = 1; 210 iday = 1;
211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
212 iday += 7 * weekOfMonth; 212 iday += 7 * weekOfMonth;
213 } while (iday > tmpDate.daysInMonth()); 213 } while (iday > tmpDate.daysInMonth());
214 tmpDate = QDate(iyear, imonth, iday); 214 tmpDate = QDate(iyear, imonth, iday);
215 215
216 next = QDateTime(tmpDate, e.start().time()); 216 next = QDateTime(tmpDate, e.start().time());
217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
218 return FALSE; 218 return FALSE;
219 return TRUE; 219 return TRUE;
220 case Event::MonthlyDate: 220 case Event::MonthlyDate:
221 iday = e.start().date().day(); 221 iday = e.start().date().day();
222 iyear = from.year(); 222 iyear = from.year();
223 imonth = from.month(); 223 imonth = from.month();
224 224
225 a = from.year() - e.start().date().year(); 225 a = from.year() - e.start().date().year();
226 a *= 12; 226 a *= 12;
227 a = a + (imonth - e.start().date().month()); 227 a = a + (imonth - e.start().date().month());
228 /* a is e.start()monthsFrom(from); */ 228 /* a is e.start()monthsFrom(from); */
229 if(a % freq) { 229 if(a % freq) {
230 a = freq - (a % freq); 230 a = freq - (a % freq);
231 imonth = from.month() + a; 231 imonth = from.month() + a;
232 if (imonth > 12) { 232 if (imonth > 12) {
233 imonth--; 233 imonth--;
234 iyear += imonth / 12; 234 iyear += imonth / 12;
235 imonth = imonth % 12; 235 imonth = imonth % 12;
236 imonth++; 236 imonth++;
237 } 237 }
238 } 238 }
239 /* imonth is now the first month after or on 239 /* imonth is now the first month after or on
240 from that matches the frequencey given */ 240 from that matches the frequencey given */
241 241
242 /* this could go for a while, worse case, 4*12 iterations, probably */ 242 /* this could go for a while, worse case, 4*12 iterations, probably */
243 while(!QDate::isValid(iyear, imonth, iday) ) { 243 while(!QDate::isValid(iyear, imonth, iday) ) {
244 imonth += freq; 244 imonth += freq;
245 if (imonth > 12) { 245 if (imonth > 12) {
246 imonth--; 246 imonth--;
247 iyear += imonth / 12; 247 iyear += imonth / 12;
248 imonth = imonth % 12; 248 imonth = imonth % 12;
249 imonth++; 249 imonth++;
250 } 250 }
251 /* these loops could go for a while, check end case now */ 251 /* these loops could go for a while, check end case now */
252 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 252 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
253 return FALSE; 253 return FALSE;
254 } 254 }
255 255
256 if(QDate(iyear, imonth, iday) >= from) { 256 if(QDate(iyear, imonth, iday) >= from) {
257 /* done */ 257 /* done */
258 next = QDateTime(QDate(iyear, imonth, iday), 258 next = QDateTime(QDate(iyear, imonth, iday),
259 e.start().time()); 259 e.start().time());
260 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 260 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
261 return FALSE; 261 return FALSE;
262 return TRUE; 262 return TRUE;
263 } 263 }
264 264
265 /* ok, need to cycle */ 265 /* ok, need to cycle */
266 imonth += freq; 266 imonth += freq;
267 imonth--; 267 imonth--;
268 iyear += imonth / 12; 268 iyear += imonth / 12;
269 imonth = imonth % 12; 269 imonth = imonth % 12;
270 imonth++; 270 imonth++;
271 271
272 while(!QDate::isValid(iyear, imonth, iday) ) { 272 while(!QDate::isValid(iyear, imonth, iday) ) {
273 imonth += freq; 273 imonth += freq;
274 imonth--; 274 imonth--;
275 iyear += imonth / 12; 275 iyear += imonth / 12;
276 imonth = imonth % 12; 276 imonth = imonth % 12;
277 imonth++; 277 imonth++;
278 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 278 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
279 return FALSE; 279 return FALSE;
280 } 280 }
281 281
282 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 282 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
283 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 283 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
284 return FALSE; 284 return FALSE;
285 return TRUE; 285 return TRUE;
286 case Event::Yearly: 286 case Event::Yearly:
287 iday = e.start().date().day(); 287 iday = e.start().date().day();
288 imonth = e.start().date().month(); 288 imonth = e.start().date().month();
289 iyear = from.year(); // after all, we want to start in this year 289 iyear = from.year(); // after all, we want to start in this year
290 290
291 diff = 1; 291 diff = 1;
292 if(imonth == 2 && iday > 28) { 292 if(imonth == 2 && iday > 28) {
293 /* leap year, and it counts, calculate actual frequency */ 293 /* leap year, and it counts, calculate actual frequency */
294 if(freq % 4) 294 if(freq % 4)
295 if (freq % 2) 295 if (freq % 2)
296 freq = freq * 4; 296 freq = freq * 4;
297 else 297 else
298 freq = freq * 2; 298 freq = freq * 2;
299 /* else divides by 4 already, leave freq alone */ 299 /* else divides by 4 already, leave freq alone */
300 diff = 4; 300 diff = 4;
301 } 301 }
302 302
303 a = from.year() - e.start().date().year(); 303 a = from.year() - e.start().date().year();
304 if(a % freq) { 304 if(a % freq) {
305 a = freq - (a % freq); 305 a = freq - (a % freq);
306 iyear = iyear + a; 306 iyear = iyear + a;
307 } 307 }
308 308
309 /* under the assumption we won't hit one of the special not-leap years twice */ 309 /* under the assumption we won't hit one of the special not-leap years twice */
310 if(!QDate::isValid(iyear, imonth, iday)) { 310 if(!QDate::isValid(iyear, imonth, iday)) {
311 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 311 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
312 iyear += freq; 312 iyear += freq;
313 } 313 }
314 314
315 if(QDate(iyear, imonth, iday) >= from) { 315 if(QDate(iyear, imonth, iday) >= from) {
316 next = QDateTime(QDate(iyear, imonth, iday), 316 next = QDateTime(QDate(iyear, imonth, iday),
317 e.start().time()); 317 e.start().time());
318 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 318 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
319 return FALSE; 319 return FALSE;
320 return TRUE; 320 return TRUE;
321 } 321 }
322 /* iyear == from.year(), need to advance again */ 322 /* iyear == from.year(), need to advance again */
323 iyear += freq; 323 iyear += freq;
324 /* under the assumption we won't hit one of the special not-leap years twice */ 324 /* under the assumption we won't hit one of the special not-leap years twice */
325 if(!QDate::isValid(iyear, imonth, iday)) { 325 if(!QDate::isValid(iyear, imonth, iday)) {
326 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 326 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
327 iyear += freq; 327 iyear += freq;
328 } 328 }
329 329
330 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 330 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
331 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 331 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
332 return FALSE; 332 return FALSE;
333 return TRUE; 333 return TRUE;
334 default: 334 default:
335 return FALSE; 335 return FALSE;
336 } 336 }
337} 337}
338 338
339static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) 339static bool nextAlarm( const Event &ev, QDateTime& when, int& warn)
340{ 340{
341 QDateTime now = QDateTime::currentDateTime(); 341 QDateTime now = QDateTime::currentDateTime();
342 if ( ev.hasRepeat() ) { 342 if ( ev.hasRepeat() ) {
343 QDateTime ralarm; 343 QDateTime ralarm;
344 if (nextOccurance(ev, now.date(), ralarm)) { 344 if (nextOccurance(ev, now.date(), ralarm)) {
345 ralarm = ralarm.addSecs(-ev.alarmTime()*60); 345 ralarm = ralarm.addSecs(-ev.alarmTime()*60);
346 if ( ralarm > now ) { 346 if ( ralarm > now ) {
347 when = ralarm; 347 when = ralarm;
348 warn = ev.alarmTime(); 348 warn = ev.alarmTime();
349 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { 349 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) {
350 ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); 350 ralarm = ralarm.addSecs( -ev.alarmTime()*60 );
351 if ( ralarm > now ) { 351 if ( ralarm > now ) {
352 when = ralarm; 352 when = ralarm;
353 warn = ev.alarmTime(); 353 warn = ev.alarmTime();
354 } 354 }
355 } 355 }
356 } 356 }
357 } else { 357 } else {
358 warn = ev.alarmTime(); 358 warn = ev.alarmTime();
359 when = ev.start().addSecs( -ev.alarmTime()*60 ); 359 when = ev.start().addSecs( -ev.alarmTime()*60 );
360 } 360 }
361 return when > now; 361 return when > now;
362} 362}
363 363
364static void addEventAlarm( const Event &ev ) 364static void addEventAlarm( const Event &ev )
365{ 365{
366 QDateTime when; 366 QDateTime when;
367 int warn; 367 int warn;
368 if ( nextAlarm(ev,when,warn) ) 368 if ( nextAlarm(ev,when,warn) )
369 AlarmServer::addAlarm( when, 369 AlarmServer::addAlarm( when,
370 "QPE/Application/datebook", 370 "QPE/Application/datebook",
371 "alarm(QDateTime,int)", warn ); 371 "alarm(QDateTime,int)", warn );
372} 372}
373 373
374static void delEventAlarm( const Event &ev ) 374static void delEventAlarm( const Event &ev )
375{ 375{
376 QDateTime when; 376 QDateTime when;
377 int warn; 377 int warn;
378 if ( nextAlarm(ev,when,warn) ) 378 if ( nextAlarm(ev,when,warn) )
379 AlarmServer::deleteAlarm( when, 379 AlarmServer::deleteAlarm( when,
380 "QPE/Application/datebook", 380 "QPE/Application/datebook",
381 "alarm(QDateTime,int)", warn ); 381 "alarm(QDateTime,int)", warn );
382} 382}
383 383
384 384
385DateBookDB::DateBookDB() 385DateBookDB::DateBookDB()
386{ 386{
387 init(); 387 init();
388} 388}
389 389
390DateBookDB::~DateBookDB() 390DateBookDB::~DateBookDB()
391{ 391{
392 save(); 392 save();
393 eventList.clear(); 393 eventList.clear();
394 repeatEvents.clear(); 394 repeatEvents.clear();
395} 395}
396 396
397 397
398//#### Why is this code duplicated in getEffectiveEvents ????? 398//#### Why is this code duplicated in getEffectiveEvents ?????
399//#### Addendum. Don't use this function, lets faze it out if we can. 399//#### Addendum. Don't use this function, lets faze it out if we can.
400QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) 400QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to )
401{ 401{
402 QValueList<Event> tmpList; 402 QValueList<Event> tmpList;
403 tmpList = getNonRepeatingEvents( from, to ); 403 tmpList = getNonRepeatingEvents( from, to );
404 404
405 // check for repeating events... 405 // check for repeating events...
406 for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); 406 for (QValueList<Event>::ConstIterator it = repeatEvents.begin();
407 it != repeatEvents.end(); ++it) { 407 it != repeatEvents.end(); ++it) {
408 QDate itDate = from; 408 QDate itDate = from;
409 QDateTime due; 409 QDateTime due;
410 410
411 /* create a false end date, to short circuit on hard 411 /* create a false end date, to short circuit on hard
412 MonthlyDay recurences */ 412 MonthlyDay recurences */
413 Event dummy_event = *it; 413 Event dummy_event = *it;
414 Event::RepeatPattern r = dummy_event.repeatPattern(); 414 Event::RepeatPattern r = dummy_event.repeatPattern();
415 if ( !r.hasEndDate || r.endDate() > to ) { 415 if ( !r.hasEndDate || r.endDate() > to ) {
416 r.setEndDate( to ); 416 r.setEndDate( to );
417 r.hasEndDate = TRUE; 417 r.hasEndDate = TRUE;
418 } 418 }
419 dummy_event.setRepeat(TRUE, r); 419 dummy_event.setRepeat(TRUE, r);
420 420
421 while (nextOccurance(dummy_event, itDate, due)) { 421 while (nextOccurance(dummy_event, itDate, due)) {
422 if (due.date() > to) 422 if (due.date() > to)
423 break; 423 break;
424 Event newEvent = *it; 424 Event newEvent = *it;
425 newEvent.setStart(due); 425 newEvent.setStart(due);
426 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); 426 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end())));
427 427
428 tmpList.append(newEvent); 428 tmpList.append(newEvent);
429 itDate = due.date().addDays(1); /* the next event */ 429 itDate = due.date().addDays(1); /* the next event */
430 } 430 }
431 } 431 }
432 qHeapSort(tmpList); 432 qHeapSort(tmpList);
433 return tmpList; 433 return tmpList;
434} 434}
435 435
436QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) 436QValueList<Event> DateBookDB::getEvents( const QDateTime &start )
437{ 437{
438 QValueList<Event> day = getEvents(start.date(),start.date()); 438 QValueList<Event> day = getEvents(start.date(),start.date());
439 439
440 QValueListConstIterator<Event> it; 440 QValueListConstIterator<Event> it;
441 QDateTime dtTmp; 441 QDateTime dtTmp;
442 QValueList<Event> tmpList; 442 QValueList<Event> tmpList;
443 for (it = day.begin(); it != day.end(); ++it ) { 443 for (it = day.begin(); it != day.end(); ++it ) {
444 dtTmp = (*it).start(TRUE); 444 dtTmp = (*it).start(TRUE);
445 if ( dtTmp == start ) 445 if ( dtTmp == start )
446 tmpList.append( *it ); 446 tmpList.append( *it );
447 } 447 }
448 return tmpList; 448 return tmpList;
449} 449}
450 450
451//#### Why is this code duplicated in getEvents ????? 451//#### Why is this code duplicated in getEvents ?????
452 452
453QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, 453QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from,
454 const QDate &to ) 454 const QDate &to )
455{ 455{
456 QValueList<EffectiveEvent> tmpList; 456 QValueList<EffectiveEvent> tmpList;
457 QValueListIterator<Event> it; 457 QValueListIterator<Event> it;
458 458
459 EffectiveEvent effEv; 459 EffectiveEvent effEv;
460 QDateTime dtTmp, 460 QDateTime dtTmp,
461 dtEnd; 461 dtEnd;
462 462
463 for (it = eventList.begin(); it != eventList.end(); ++it ) { 463 for (it = eventList.begin(); it != eventList.end(); ++it ) {
464 if (!(*it).isValidUid())
465 (*it).assignUid(); // FIXME: Hack to restore cleared uids
466
464 dtTmp = (*it).start(TRUE); 467 dtTmp = (*it).start(TRUE);
465 dtEnd = (*it).end(TRUE); 468 dtEnd = (*it).end(TRUE);
466 469
467 if ( dtTmp.date() >= from && dtTmp.date() <= to ) { 470 if ( dtTmp.date() >= from && dtTmp.date() <= to ) {
468 Event tmpEv = *it; 471 Event tmpEv = *it;
469 effEv.setEvent(tmpEv); 472 effEv.setEvent(tmpEv);
470 effEv.setDate( dtTmp.date() ); 473 effEv.setDate( dtTmp.date() );
471 effEv.setStart( dtTmp.time() ); 474 effEv.setStart( dtTmp.time() );
472 if ( dtTmp.date() != dtEnd.date() ) 475 if ( dtTmp.date() != dtEnd.date() )
473 effEv.setEnd( QTime(23, 59, 0) ); 476 effEv.setEnd( QTime(23, 59, 0) );
474 else 477 else
475 effEv.setEnd( dtEnd.time() ); 478 effEv.setEnd( dtEnd.time() );
476 tmpList.append( effEv ); 479 tmpList.append( effEv );
477 } 480 }
478 // we must also check for end date information... 481 // we must also check for end date information...
479 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { 482 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) {
480 QDateTime dt = dtTmp.addDays( 1 ); 483 QDateTime dt = dtTmp.addDays( 1 );
481 dt.setTime( QTime(0, 0, 0) ); 484 dt.setTime( QTime(0, 0, 0) );
482 QDateTime dtStop; 485 QDateTime dtStop;
483 if ( dtEnd > to ) { 486 if ( dtEnd > to ) {
484 dtStop = to; 487 dtStop = to;
485 } else 488 } else
486 dtStop = dtEnd; 489 dtStop = dtEnd;
487 while ( dt <= dtStop ) { 490 while ( dt <= dtStop ) {
488 Event tmpEv = *it; 491 Event tmpEv = *it;
489 effEv.setEvent( tmpEv ); 492 effEv.setEvent( tmpEv );
490 effEv.setDate( dt.date() ); 493 effEv.setDate( dt.date() );
491 if ( dt >= from ) { 494 if ( dt >= from ) {
492 effEv.setStart( QTime(0, 0, 0) ); 495 effEv.setStart( QTime(0, 0, 0) );
493 if ( dt.date() == dtEnd.date() ) 496 if ( dt.date() == dtEnd.date() )
494 effEv.setEnd( dtEnd.time() ); 497 effEv.setEnd( dtEnd.time() );
495 else 498 else
496 effEv.setEnd( QTime(23, 59, 59) ); 499 effEv.setEnd( QTime(23, 59, 59) );
497 tmpList.append( effEv ); 500 tmpList.append( effEv );
498 } 501 }
499 dt = dt.addDays( 1 ); 502 dt = dt.addDays( 1 );
500 } 503 }
501 } 504 }
502 } 505 }
503 // check for repeating events... 506 // check for repeating events...
504 QDateTime repeat; 507 QDateTime repeat;
505 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 508 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
509 if (!(*it).isValidUid())
510 (*it).assignUid(); // FIXME: Hack to restore cleared uids
506 511
507 /* create a false end date, to short circuit on hard 512 /* create a false end date, to short circuit on hard
508 MonthlyDay recurences */ 513 MonthlyDay recurences */
509 Event dummy_event = *it; 514 Event dummy_event = *it;
510 int duration = (*it).start().date().daysTo( (*it).end().date() ); 515 int duration = (*it).start().date().daysTo( (*it).end().date() );
511 QDate itDate = from.addDays(-duration); 516 QDate itDate = from.addDays(-duration);
512 517
513 Event::RepeatPattern r = dummy_event.repeatPattern(); 518 Event::RepeatPattern r = dummy_event.repeatPattern();
514 if ( !r.hasEndDate || r.endDate() > to ) { 519 if ( !r.hasEndDate || r.endDate() > to ) {
515 r.setEndDate( to ); 520 r.setEndDate( to );
516 r.hasEndDate = TRUE; 521 r.hasEndDate = TRUE;
517 } 522 }
518 dummy_event.setRepeat(TRUE, r); 523 dummy_event.setRepeat(TRUE, r);
519 524
520 while (nextOccurance(dummy_event, itDate, repeat)) { 525 while (nextOccurance(dummy_event, itDate, repeat)) {
521 if(repeat.date() > to) 526 if(repeat.date() > to)
522 break; 527 break;
523 effEv.setDate( repeat.date() ); 528 effEv.setDate( repeat.date() );
524 if ((*it).type() == Event::AllDay) { 529 if ((*it).type() == Event::AllDay) {
525 effEv.setStart( QTime(0,0,0) ); 530 effEv.setStart( QTime(0,0,0) );
526 effEv.setEnd( QTime(23,59,59) ); 531 effEv.setEnd( QTime(23,59,59) );
527 } else { 532 } else {
528 /* we only occur by days, not hours/minutes/seconds. Hence 533 /* we only occur by days, not hours/minutes/seconds. Hence
529 the actual end and start times will be the same for 534 the actual end and start times will be the same for
530 every repeated event. For multi day events this is 535 every repeated event. For multi day events this is
531 fixed up later if on wronge day span */ 536 fixed up later if on wronge day span */
532 effEv.setStart( (*it).start().time() ); 537 effEv.setStart( (*it).start().time() );
533 effEv.setEnd( (*it).end().time() ); 538 effEv.setEnd( (*it).end().time() );
534 } 539 }
535 if ( duration != 0 ) { 540 if ( duration != 0 ) {
536 // multi-day repeating events 541 // multi-day repeating events
537 QDate sub_it = QMAX( repeat.date(), from ); 542 QDate sub_it = QMAX( repeat.date(), from );
538 QDate startDate = repeat.date(); 543 QDate startDate = repeat.date();
539 QDate endDate = startDate.addDays( duration ); 544 QDate endDate = startDate.addDays( duration );
540 545
541 while ( sub_it <= endDate && sub_it <= to ) { 546 while ( sub_it <= endDate && sub_it <= to ) {
542 EffectiveEvent tmpEffEv = effEv; 547 EffectiveEvent tmpEffEv = effEv;
543 Event tmpEv = *it; 548 Event tmpEv = *it;
544 tmpEffEv.setEvent( tmpEv ); 549 tmpEffEv.setEvent( tmpEv );
545 550
546 if ( sub_it != startDate ) 551 if ( sub_it != startDate )
547 tmpEffEv.setStart( QTime(0,0,0) ); 552 tmpEffEv.setStart( QTime(0,0,0) );
548 if ( sub_it != endDate ) 553 if ( sub_it != endDate )
549 tmpEffEv.setEnd( QTime(23,59,59) ); 554 tmpEffEv.setEnd( QTime(23,59,59) );
550 tmpEffEv.setDate( sub_it ); 555 tmpEffEv.setDate( sub_it );
551 tmpEffEv.setEffectiveDates( startDate, endDate ); 556 tmpEffEv.setEffectiveDates( startDate, endDate );
552 tmpList.append( tmpEffEv ); 557 tmpList.append( tmpEffEv );
553 sub_it = sub_it.addDays( 1 ); 558 sub_it = sub_it.addDays( 1 );
554 } 559 }
555 itDate = endDate; 560 itDate = endDate;
556 } else { 561 } else {
557 Event tmpEv = *it; 562 Event tmpEv = *it;
558 effEv.setEvent( tmpEv ); 563 effEv.setEvent( tmpEv );
559 tmpList.append( effEv ); 564 tmpList.append( effEv );
560 itDate = repeat.date().addDays( 1 ); 565 itDate = repeat.date().addDays( 1 );
561 } 566 }
562 } 567 }
563 } 568 }
564 569
565 qHeapSort( tmpList ); 570 qHeapSort( tmpList );
566 return tmpList; 571 return tmpList;
567} 572}
568 573
569QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) 574QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt)
570{ 575{
571 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); 576 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date());
572 QValueListConstIterator<EffectiveEvent> it; 577 QValueListConstIterator<EffectiveEvent> it;
573 QValueList<EffectiveEvent> tmpList; 578 QValueList<EffectiveEvent> tmpList;
574 QDateTime dtTmp; 579 QDateTime dtTmp;
575 580
576 for (it = day.begin(); it != day.end(); ++it ) { 581 for (it = day.begin(); it != day.end(); ++it ) {
577 dtTmp = QDateTime( (*it).date(), (*it).start() ); 582 dtTmp = QDateTime( (*it).date(), (*it).start() );
578 // at the moment we don't have second granularity, be nice about that.. 583 // at the moment we don't have second granularity, be nice about that..
579 if ( QABS(dt.secsTo(dtTmp)) < 60 ) 584 if ( QABS(dt.secsTo(dtTmp)) < 60 )
580 tmpList.append( *it ); 585 tmpList.append( *it );
581 } 586 }
582 return tmpList; 587 return tmpList;
583} 588}
584 589
590Event DateBookDB::getEvent( int uid ) {
591 QValueList<Event>::ConstIterator it;
592
593 for (it = eventList.begin(); it != eventList.end(); it++) {
594 if ((*it).uid() == uid) return *it;
595 }
596 for (it = repeatEvents.begin(); it != repeatEvents.end(); it++) {
597 if ((*it).uid() == uid) return *it;
598 }
599
600 qDebug("Event not found: uid=%d\n", uid);
601}
602
585 603
586void DateBookDB::addEvent( const Event &ev, bool doalarm ) 604void DateBookDB::addEvent( const Event &ev, bool doalarm )
587{ 605{
588 // write to the journal... 606 // write to the journal...
589 saveJournalEntry( ev, ACTION_ADD, -1, false ); 607 saveJournalEntry( ev, ACTION_ADD, -1, false );
590 addJFEvent( ev, doalarm ); 608 addJFEvent( ev, doalarm );
591 d->clean = false; 609 d->clean = false;
592} 610}
593 611
594void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) 612void DateBookDB::addJFEvent( const Event &ev, bool doalarm )
595{ 613{
596 if ( doalarm && ev.hasAlarm() ) 614 if ( doalarm && ev.hasAlarm() )
597 addEventAlarm( ev ); 615 addEventAlarm( ev );
598 if ( ev.hasRepeat() ) 616 if ( ev.hasRepeat() )
599 repeatEvents.append( ev ); 617 repeatEvents.append( ev );
600 else 618 else
601 eventList.append( ev ); 619 eventList.append( ev );
602} 620}
603 621
604void DateBookDB::editEvent( const Event &old, Event &editedEv ) 622void DateBookDB::editEvent( const Event &old, Event &editedEv )
605{ 623{
606 int oldIndex=0; 624 int oldIndex=0;
607 bool oldHadRepeat = old.hasRepeat(); 625 bool oldHadRepeat = old.hasRepeat();
608 Event orig; 626 Event orig;
609 627
610 // write to the journal... 628 // write to the journal...
611 if ( oldHadRepeat ) { 629 if ( oldHadRepeat ) {
612 if ( origRepeat( old, orig ) ) // should work always... 630 if ( origRepeat( old, orig ) ) // should work always...
613 oldIndex = repeatEvents.findIndex( orig ); 631 oldIndex = repeatEvents.findIndex( orig );
614 } else 632 } else
615 oldIndex = eventList.findIndex( old ); 633 oldIndex = eventList.findIndex( old );
616 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); 634 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat );
617 635
636 // Delete old event
618 if ( old.hasAlarm() ) 637 if ( old.hasAlarm() )
619 delEventAlarm( old ); 638 delEventAlarm( old );
620 if ( oldHadRepeat ) { 639 if ( oldHadRepeat ) {
621 if ( oldHadRepeat && editedEv.hasRepeat() ) { 640 if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and
641 // orig is initialized
622 // assumption, when someone edits a repeating event, they 642 // assumption, when someone edits a repeating event, they
623 // want to change them all, maybe not perfect, but it works 643 // want to change them all, maybe not perfect, but it works
624 // for the moment... 644 // for the moment...
625 repeatEvents.remove( orig ); 645 repeatEvents.remove( orig );
626 } else 646 } else
627 removeRepeat( old ); 647 removeRepeat( old );
628 } else { 648 } else {
629 QValueList<Event>::Iterator it = eventList.find( old ); 649 QValueList<Event>::Iterator it = eventList.find( old );
630 if ( it != eventList.end() ) 650 if ( it != eventList.end() )
631 eventList.remove( it ); 651 eventList.remove( it );
632 } 652 }
653
654 // Add new event
633 if ( editedEv.hasAlarm() ) 655 if ( editedEv.hasAlarm() )
634 addEventAlarm( editedEv ); 656 addEventAlarm( editedEv );
635 if ( editedEv.hasRepeat() ) 657 if ( editedEv.hasRepeat() )
636 repeatEvents.append( editedEv ); 658 repeatEvents.append( editedEv );
637 else 659 else
638 eventList.append( editedEv ); 660 eventList.append( editedEv );
661
639 d->clean = false; 662 d->clean = false;
640} 663}
641 664
642void DateBookDB::removeEvent( const Event &ev ) 665void DateBookDB::removeEvent( const Event &ev )
643{ 666{
644 // write to the journal... 667 // write to the journal...
645 saveJournalEntry( ev, ACTION_REMOVE, -1, false ); 668 saveJournalEntry( ev, ACTION_REMOVE, -1, false );
646 removeJFEvent( ev ); 669 removeJFEvent( ev );
647 d->clean = false; 670 d->clean = false;
648} 671}
649 672
650void DateBookDB::removeJFEvent( const Event&ev ) 673void DateBookDB::removeJFEvent( const Event&ev )
651{ 674{
652 if ( ev.hasAlarm() ) 675 if ( ev.hasAlarm() )
653 delEventAlarm( ev ); 676 delEventAlarm( ev );
654 if ( ev.hasRepeat() ) { 677 if ( ev.hasRepeat() ) {
655 removeRepeat( ev ); 678 removeRepeat( ev );
656 } else { 679 } else {
657 QValueList<Event>::Iterator it = eventList.find( ev ); 680 QValueList<Event>::Iterator it = eventList.find( ev );
658 if ( it != eventList.end() ) 681 if ( it != eventList.end() )
659 eventList.remove( it ); 682 eventList.remove( it );
660 } 683 }
661} 684}
662 685
663// also handles journaling... 686// also handles journaling...
664void DateBookDB::loadFile( const QString &strFile ) 687void DateBookDB::loadFile( const QString &strFile )
665{ 688{
666 689
667 QFile f( strFile ); 690 QFile f( strFile );
668 if ( !f.open( IO_ReadOnly ) ) 691 if ( !f.open( IO_ReadOnly ) )
669 return; 692 return;
670 693
671 enum Attribute { 694 enum Attribute {
672 FDescription = 0, 695 FDescription = 0,
673 FLocation, 696 FLocation,
674 FCategories, 697 FCategories,
675 FUid, 698 FUid,
676 FType, 699 FType,
677 FAlarm, 700 FAlarm,
678 FSound, 701 FSound,
679 FRType, 702 FRType,
680 FRWeekdays, 703 FRWeekdays,
681 FRPosition, 704 FRPosition,
682 FRFreq, 705 FRFreq,
683 FRHasEndDate, 706 FRHasEndDate,
684 FREndDate, 707 FREndDate,
685 FRStart, 708 FRStart,
686 FREnd, 709 FREnd,
687 FNote, 710 FNote,
688 FCreated, 711 FCreated,
689 FAction, 712 FAction,
690 FActionKey, 713 FActionKey,
691 FJournalOrigHadRepeat 714 FJournalOrigHadRepeat
692 }; 715 };
693 716
694 QAsciiDict<int> dict( 97 ); 717 QAsciiDict<int> dict( 97 );
695 dict.setAutoDelete( TRUE ); 718 dict.setAutoDelete( TRUE );
696 dict.insert( "description", new int(FDescription) ); 719 dict.insert( "description", new int(FDescription) );
697 dict.insert( "location", new int(FLocation) ); 720 dict.insert( "location", new int(FLocation) );
698 dict.insert( "categories", new int(FCategories) ); 721 dict.insert( "categories", new int(FCategories) );
699 dict.insert( "uid", new int(FUid) ); 722 dict.insert( "uid", new int(FUid) );
700 dict.insert( "type", new int(FType) ); 723 dict.insert( "type", new int(FType) );
701 dict.insert( "alarm", new int(FAlarm) ); 724 dict.insert( "alarm", new int(FAlarm) );
702 dict.insert( "sound", new int(FSound) ); 725 dict.insert( "sound", new int(FSound) );
703 dict.insert( "rtype", new int(FRType) ); 726 dict.insert( "rtype", new int(FRType) );
704 dict.insert( "rweekdays", new int(FRWeekdays) ); 727 dict.insert( "rweekdays", new int(FRWeekdays) );
705 dict.insert( "rposition", new int(FRPosition) ); 728 dict.insert( "rposition", new int(FRPosition) );
706 dict.insert( "rfreq", new int(FRFreq) ); 729 dict.insert( "rfreq", new int(FRFreq) );
707 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 730 dict.insert( "rhasenddate", new int(FRHasEndDate) );
708 dict.insert( "enddt", new int(FREndDate) ); 731 dict.insert( "enddt", new int(FREndDate) );
709 dict.insert( "start", new int(FRStart) ); 732 dict.insert( "start", new int(FRStart) );
710 dict.insert( "end", new int(FREnd) ); 733 dict.insert( "end", new int(FREnd) );
711 dict.insert( "note", new int(FNote) ); 734 dict.insert( "note", new int(FNote) );
712 dict.insert( "created", new int(FCreated) ); 735 dict.insert( "created", new int(FCreated) );
713 dict.insert( "action", new int(FAction) ); 736 dict.insert( "action", new int(FAction) );
714 dict.insert( "actionkey", new int(FActionKey) ); 737 dict.insert( "actionkey", new int(FActionKey) );
715 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) ); 738 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) );
716 739
717 740
718 QByteArray ba = f.readAll(); 741 QByteArray ba = f.readAll();
719 char* dt = ba.data(); 742 char* dt = ba.data();
720 int len = ba.size(); 743 int len = ba.size();
721 int currentAction, 744 int currentAction,
722 journalKey, 745 journalKey,
723 origHadRepeat; // should be bool, but we need tri-state(not being used) 746 origHadRepeat; // should be bool, but we need tri-state(not being used)
724 747
725 int i = 0; 748 int i = 0;
726 char *point; 749 char *point;
727 while ( ( point = strstr( dt+i, "<event " ) ) != 0 ) { 750 while ( ( point = strstr( dt+i, "<event " ) ) != 0 ) {
728 i = point - dt; 751 i = point - dt;
729 // if we are reading in events in the general case, 752 // if we are reading in events in the general case,
730 // we are just adding them, so let the actions represent that... 753 // we are just adding them, so let the actions represent that...
731 currentAction = ACTION_ADD; 754 currentAction = ACTION_ADD;
732 journalKey = -1; 755 journalKey = -1;
733 origHadRepeat = -1; 756 origHadRepeat = -1;
734 // some temporary variables for dates and times ... 757 // some temporary variables for dates and times ...
735 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0; 758 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0;
736 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0; 759 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0;
737 //int enddtY = 0, enddtM = 0, enddtD = 0; 760 //int enddtY = 0, enddtM = 0, enddtD = 0;
738 761
739 // ... for the alarm settings ... 762 // ... for the alarm settings ...
740 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent; 763 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent;
741 // ... and for the recurrence 764 // ... and for the recurrence
742 Event::RepeatPattern rp; 765 Event::RepeatPattern rp;
743 Event e; 766 Event e;
744 767
745 i += 7; 768 i += 7;
746 769
747 while( 1 ) { 770 while( 1 ) {
748 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 771 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
749 ++i; 772 ++i;
750 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 773 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
751 break; 774 break;
752 // we have another attribute, read it. 775 // we have another attribute, read it.
753 int j = i; 776 int j = i;
754 while ( j < len && dt[j] != '=' ) 777 while ( j < len && dt[j] != '=' )
755 ++j; 778 ++j;
756 char *attr = dt+i; 779 char *attr = dt+i;
757 dt[j] = '\0'; 780 dt[j] = '\0';
758 i = ++j; // skip = 781 i = ++j; // skip =
759 while ( i < len && dt[i] != '"' ) 782 while ( i < len && dt[i] != '"' )
760 ++i; 783 ++i;
761 j = ++i; 784 j = ++i;
762 bool haveAmp = FALSE; 785 bool haveAmp = FALSE;
763 bool haveUtf = FALSE; 786 bool haveUtf = FALSE;
764 while ( j < len && dt[j] != '"' ) { 787 while ( j < len && dt[j] != '"' ) {
765 if ( dt[j] == '&' ) 788 if ( dt[j] == '&' )
766 haveAmp = TRUE; 789 haveAmp = TRUE;
767 if ( ((unsigned char)dt[j]) > 0x7f ) 790 if ( ((unsigned char)dt[j]) > 0x7f )
768 haveUtf = TRUE; 791 haveUtf = TRUE;
769 ++j; 792 ++j;
770 } 793 }
771 794
772 if ( i == j ) { 795 if ( i == j ) {
773 // leave out empty attributes 796 // leave out empty attributes
774 i = j + 1; 797 i = j + 1;
775 continue; 798 continue;
776 } 799 }
777 800
778 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i ) 801 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i )
779 : QString::fromLatin1( dt+i, j-i ); 802 : QString::fromLatin1( dt+i, j-i );
780 if ( haveAmp ) 803 if ( haveAmp )
781 value = Qtopia::plainString( value ); 804 value = Qtopia::plainString( value );
782 i = j + 1; 805 i = j + 1;
783 806
784 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() ); 807 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() );
785 int * find = dict[ attr ]; 808 int * find = dict[ attr ];
786#if 1 809#if 1
787 if ( !find ) { 810 if ( !find ) {
788 // custom field 811 // custom field
789 e.setCustomField(attr, value); 812 e.setCustomField(attr, value);
790 continue; 813 continue;
791 } 814 }
792 815
793 switch( *find ) { 816 switch( *find ) {
794 case FDescription: 817 case FDescription:
795 e.setDescription( value ); 818 e.setDescription( value );
796 break; 819 break;
797 case FLocation: 820 case FLocation:
798 e.setLocation( value ); 821 e.setLocation( value );
799 break; 822 break;
800 case FCategories: 823 case FCategories:
801 e.setCategories( Qtopia::Record::idsFromString( value ) ); 824 e.setCategories( Qtopia::Record::idsFromString( value ) );
802 break; 825 break;
803 case FUid: 826 case FUid:
804 e.setUid( value.toInt() ); 827 e.setUid( value.toInt() );
805 break; 828 break;
806 case FType: 829 case FType:
807 if ( value == "AllDay" ) 830 if ( value == "AllDay" )
808 e.setType( Event::AllDay ); 831 e.setType( Event::AllDay );
809 else 832 else
810 e.setType( Event::Normal ); 833 e.setType( Event::Normal );
811 break; 834 break;
812 case FAlarm: 835 case FAlarm:
813 alarmTime = value.toInt(); 836 alarmTime = value.toInt();
814 break; 837 break;
815 case FSound: 838 case FSound:
816 alarmSound = value == "loud" ? Event::Loud : Event::Silent; 839 alarmSound = value == "loud" ? Event::Loud : Event::Silent;
817 break; 840 break;
818 // recurrence stuff 841 // recurrence stuff
819 case FRType: 842 case FRType:
820 if ( value == "Daily" ) 843 if ( value == "Daily" )
821 rp.type = Event::Daily; 844 rp.type = Event::Daily;
822 else if ( value == "Weekly" ) 845 else if ( value == "Weekly" )
823 rp.type = Event::Weekly; 846 rp.type = Event::Weekly;
824 else if ( value == "MonthlyDay" ) 847 else if ( value == "MonthlyDay" )
825 rp.type = Event::MonthlyDay; 848 rp.type = Event::MonthlyDay;
826 else if ( value == "MonthlyDate" ) 849 else if ( value == "MonthlyDate" )
827 rp.type = Event::MonthlyDate; 850 rp.type = Event::MonthlyDate;
828 else if ( value == "Yearly" ) 851 else if ( value == "Yearly" )
829 rp.type = Event::Yearly; 852 rp.type = Event::Yearly;
830 else 853 else
831 rp.type = Event::NoRepeat; 854 rp.type = Event::NoRepeat;
832 break; 855 break;
833 case FRWeekdays: 856 case FRWeekdays:
834 rp.days = value.toInt(); 857 rp.days = value.toInt();
835 break; 858 break;
836 case FRPosition: 859 case FRPosition:
837 rp.position = value.toInt(); 860 rp.position = value.toInt();
838 break; 861 break;
839 case FRFreq: 862 case FRFreq:
840 rp.frequency = value.toInt(); 863 rp.frequency = value.toInt();
841 break; 864 break;
842 case FRHasEndDate: 865 case FRHasEndDate:
843 rp.hasEndDate = value.toInt(); 866 rp.hasEndDate = value.toInt();
844 break; 867 break;
845 case FREndDate: { 868 case FREndDate: {
846 rp.endDateUTC = (time_t) value.toLong(); 869 rp.endDateUTC = (time_t) value.toLong();
847 break; 870 break;
848 } 871 }
849 case FRStart: { 872 case FRStart: {
850 e.setStart( (time_t) value.toLong() ); 873 e.setStart( (time_t) value.toLong() );
851 break; 874 break;
852 } 875 }
853 case FREnd: { 876 case FREnd: {
854 e.setEnd( (time_t) value.toLong() ); 877 e.setEnd( (time_t) value.toLong() );
855 break; 878 break;
856 } 879 }
857 case FNote: 880 case FNote:
858 e.setNotes( value ); 881 e.setNotes( value );
859 break; 882 break;
860 case FCreated: 883 case FCreated:
861 rp.createTime = value.toInt(); 884 rp.createTime = value.toInt();
862 break; 885 break;
863 case FAction: 886 case FAction:
864 currentAction = value.toInt(); 887 currentAction = value.toInt();
865 break; 888 break;
866 case FActionKey: 889 case FActionKey:
867 journalKey = value.toInt(); 890 journalKey = value.toInt();
868 break; 891 break;
869 case FJournalOrigHadRepeat: 892 case FJournalOrigHadRepeat:
870 origHadRepeat = value.toInt(); 893 origHadRepeat = value.toInt();
871 break; 894 break;
872 default: 895 default:
873 qDebug( "huh??? missing enum? -- attr.: %s", attr ); 896 qDebug( "huh??? missing enum? -- attr.: %s", attr );
874 break; 897 break;
875 } 898 }
876#endif 899#endif
877 } 900 }
878 // "post processing" (dates, times, alarm, recurrence) 901 // "post processing" (dates, times, alarm, recurrence)
879 // start date/time 902 // start date/time
880 e.setRepeat( rp.type != Event::NoRepeat, rp ); 903 e.setRepeat( rp.type != Event::NoRepeat, rp );
881 904
882 if ( alarmTime != -1 ) 905 if ( alarmTime != -1 )
883 e.setAlarm( TRUE, alarmTime, alarmSound ); 906 e.setAlarm( TRUE, alarmTime, alarmSound );
884 907
885 // now do our action based on the current action... 908 // now do our action based on the current action...
886 switch ( currentAction ) { 909 switch ( currentAction ) {
887 case ACTION_ADD: 910 case ACTION_ADD:
888 addJFEvent( e ); 911 addJFEvent( e );
889 break; 912 break;
890 case ACTION_REMOVE: 913 case ACTION_REMOVE:
891 removeJFEvent( e ); 914 removeJFEvent( e );
892 break; 915 break;
893 case ACTION_REPLACE: 916 case ACTION_REPLACE:
894 // be a little bit careful, 917 // be a little bit careful,
895 // in case of a messed up journal... 918 // in case of a messed up journal...
896 if ( journalKey > -1 && origHadRepeat > -1 ) { 919 if ( journalKey > -1 && origHadRepeat > -1 ) {
897 // get the original from proper list... 920 // get the original from proper list...
898 if ( origHadRepeat ) 921 if ( origHadRepeat )
899 removeJFEvent( *(repeatEvents.at(journalKey)) ); 922 removeJFEvent( *(repeatEvents.at(journalKey)) );
900 else 923 else
901 removeJFEvent( *(eventList.at(journalKey)) ); 924 removeJFEvent( *(eventList.at(journalKey)) );
902 addJFEvent( e ); 925 addJFEvent( e );
903 } 926 }
904 break; 927 break;
905 default: 928 default:
906 break; 929 break;
907 } 930 }
908 } 931 }
909 f.close(); 932 f.close();
910} 933}
911 934
912void DateBookDB::init() 935void DateBookDB::init()
913{ 936{
914 d = new DateBookDBPrivate; 937 d = new DateBookDBPrivate;
915 d->clean = false; 938 d->clean = false;
916 QString str = dateBookFilename(); 939 QString str = dateBookFilename();
917 if ( str.isNull() ) { 940 if ( str.isNull() ) {
918 QMessageBox::warning( 0, QObject::tr("Out of Space"), 941 QMessageBox::warning( 0, QObject::tr("Out of Space"),
919 QObject::tr("Unable to create start up files\n" 942 QObject::tr("Unable to create start up files\n"
920 "Please free up some space\n" 943 "Please free up some space\n"
921 "before entering data") ); 944 "before entering data") );
922 } 945 }
923 // continuing along, we call this datebook filename again, 946 // continuing along, we call this datebook filename again,
924 // because they may fix it before continuing, though it seems 947 // because they may fix it before continuing, though it seems
925 // pretty unlikely... 948 // pretty unlikely...
926 loadFile( dateBookFilename() ); 949 loadFile( dateBookFilename() );
927 950
928 if ( QFile::exists( dateBookJournalFile() ) ) { 951 if ( QFile::exists( dateBookJournalFile() ) ) {
929 // merge the journal 952 // merge the journal
930 loadFile( dateBookJournalFile() ); 953 loadFile( dateBookJournalFile() );
931 // save in our changes and remove the journal... 954 // save in our changes and remove the journal...
932 save(); 955 save();
933 } 956 }
934 d->clean = true; 957 d->clean = true;
935} 958}
936 959
937bool DateBookDB::save() 960bool DateBookDB::save()
938{ 961{
939 if ( d->clean == true ) 962 if ( d->clean == true )
940 return true; 963 return true;
941 QValueListIterator<Event> it; 964 QValueListIterator<Event> it;
942 int total_written; 965 int total_written;
943 QString strFileNew = dateBookFilename() + ".new"; 966 QString strFileNew = dateBookFilename() + ".new";
944 967
945 QFile f( strFileNew ); 968 QFile f( strFileNew );
946 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 969 if ( !f.open( IO_WriteOnly|IO_Raw ) )
947 return FALSE; 970 return FALSE;
948 971
949 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 972 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
950 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 973 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
951 buf += "<events>\n"; 974 buf += "<events>\n";
952 QCString str = buf.utf8(); 975 QCString str = buf.utf8();
953 total_written = f.writeBlock( str.data(), str.length() ); 976 total_written = f.writeBlock( str.data(), str.length() );
954 if ( total_written != int(str.length()) ) { 977 if ( total_written != int(str.length()) ) {
955 f.close(); 978 f.close();
956 QFile::remove( strFileNew ); 979 QFile::remove( strFileNew );
957 return false; 980 return false;
958 } 981 }
959 982
960 for ( it = eventList.begin(); it != eventList.end(); ++it ) { 983 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
961 buf = "<event"; 984 buf = "<event";
962 (*it).save( buf ); 985 (*it).save( buf );
963 buf += " />\n"; 986 buf += " />\n";
964 str = buf.utf8(); 987 str = buf.utf8();
965 total_written = f.writeBlock( str.data(), str.length() ); 988 total_written = f.writeBlock( str.data(), str.length() );
966 if ( total_written != int(str.length()) ) { 989 if ( total_written != int(str.length()) ) {
967 f.close(); 990 f.close();
968 QFile::remove( strFileNew ); 991 QFile::remove( strFileNew );
969 return false; 992 return false;
970 } 993 }
971 } 994 }
972 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 995 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
973 buf = "<event"; 996 buf = "<event";
974 (*it).save( buf ); 997 (*it).save( buf );
975 buf += " />\n"; 998 buf += " />\n";
976 str = buf.utf8(); 999 str = buf.utf8();
977 total_written = f.writeBlock( str.data(), str.length() ); 1000 total_written = f.writeBlock( str.data(), str.length() );
978 if ( total_written != int(str.length()) ) { 1001 if ( total_written != int(str.length()) ) {
979 f.close(); 1002 f.close();
980 QFile::remove( strFileNew ); 1003 QFile::remove( strFileNew );
981 return false; 1004 return false;
982 } 1005 }
983 } 1006 }
984 buf = "</events>\n</DATEBOOK>\n"; 1007 buf = "</events>\n</DATEBOOK>\n";
985 str = buf.utf8(); 1008 str = buf.utf8();
986 total_written = f.writeBlock( str.data(), str.length() ); 1009 total_written = f.writeBlock( str.data(), str.length() );
987 if ( total_written != int(str.length()) ) { 1010 if ( total_written != int(str.length()) ) {
988 f.close(); 1011 f.close();
989 QFile::remove( strFileNew ); 1012 QFile::remove( strFileNew );
990 return false; 1013 return false;
991 } 1014 }
992 f.close(); 1015 f.close();
993 1016
994 // now rename... I like to use the systemcall 1017 // now rename... I like to use the systemcall
995 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) { 1018 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) {
996 qWarning( "problem renaming file %s to %s errno %d", 1019 qWarning( "problem renaming file %s to %s errno %d",
997 strFileNew.latin1(), dateBookFilename().latin1(), errno ); 1020 strFileNew.latin1(), dateBookFilename().latin1(), errno );
998 // remove the file, otherwise it will just stick around... 1021 // remove the file, otherwise it will just stick around...
999 QFile::remove( strFileNew ); 1022 QFile::remove( strFileNew );
1000 } 1023 }
1001 1024
1002 // may as well remove the journal file... 1025 // may as well remove the journal file...
1003 QFile::remove( dateBookJournalFile() ); 1026 QFile::remove( dateBookJournalFile() );
1004 d->clean = true; 1027 d->clean = true;
1005 return true; 1028 return true;
1006} 1029}
1007 1030
1008void DateBookDB::reload() 1031void DateBookDB::reload()
1009{ 1032{
1010 QValueList<Event>::Iterator it = eventList.begin(); 1033 QValueList<Event>::Iterator it = eventList.begin();
1011 for ( ; it != eventList.end(); ++it ) { 1034 for ( ; it != eventList.end(); ++it ) {
1012 if ( (*it).hasAlarm() ) 1035 if ( (*it).hasAlarm() )
1013 delEventAlarm( *it ); 1036 delEventAlarm( *it );
1014 if ( (*it).hasRepeat() ) 1037 if ( (*it).hasRepeat() )
1015 removeRepeat( *it ); 1038 removeRepeat( *it );
1016 } 1039 }
1017 eventList.clear(); 1040 eventList.clear();
1018 repeatEvents.clear(); // should be a NOP 1041 repeatEvents.clear(); // should be a NOP
1019 init(); 1042 init();
1020} 1043}
1021 1044
1022bool DateBookDB::removeRepeat( const Event &ev ) 1045bool DateBookDB::removeRepeat( const Event &ev )
diff --git a/library/datebookdb.h b/library/datebookdb.h
index aadb397..e4c251c 100644
--- a/library/datebookdb.h
+++ b/library/datebookdb.h
@@ -1,85 +1,88 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef DATEBOOKDB_H 21#ifndef DATEBOOKDB_H
22#define DATEBOOKDB_H 22#define DATEBOOKDB_H
23 23
24#include <qdatetime.h> 24#include <qdatetime.h>
25#include <qfile.h> 25#include <qfile.h>
26#include <qvaluelist.h> 26#include <qvaluelist.h>
27#include <qpe/event.h> 27#include <qpe/event.h>
28 28
29// journal actions... 29// journal actions...
30enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 30enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
31 31
32class DateBookDBPrivate; 32class DateBookDBPrivate;
33class DateBookDB 33class DateBookDB
34{ 34{
35public: 35public:
36 DateBookDB(); 36 DateBookDB();
37 ~DateBookDB(); 37 ~DateBookDB();
38 38
39 // very depreciated now!!! 39 // very depreciated now!!!
40 QValueList<Event> getEvents( const QDate &from, const QDate &to ); 40 QValueList<Event> getEvents( const QDate &from, const QDate &to );
41 QValueList<Event> getEvents( const QDateTime &start ); 41 QValueList<Event> getEvents( const QDateTime &start );
42 42
43 // USE THESE!!! 43 // USE THESE!!!
44 QValueList<EffectiveEvent> getEffectiveEvents( const QDate &from, 44 QValueList<EffectiveEvent> getEffectiveEvents( const QDate &from,
45 const QDate &to ); 45 const QDate &to );
46 QValueList<EffectiveEvent> getEffectiveEvents( const QDateTime &start ); 46 QValueList<EffectiveEvent> getEffectiveEvents( const QDateTime &start );
47 Event getEvent( int uid );
47 48
48 QValueList<Event> getRawRepeats() const; 49 QValueList<Event> getRawRepeats() const;
49 QValueList<Event> getNonRepeatingEvents( const QDate &from, 50 QValueList<Event> getNonRepeatingEvents( const QDate &from,
50 const QDate &to ) const; 51 const QDate &to ) const;
51 52
52 // Use these when dealing with adding removing events... 53 // Use these when dealing with adding removing events...
53 void addEvent( const Event &ev, bool doalarm=TRUE ); 54 void addEvent( const Event &ev, bool doalarm=TRUE );
54 void removeEvent( const Event &ev ); 55 void removeEvent( const Event &ev );
55 void editEvent( const Event &old, Event &ev ); 56 void editEvent( const Event &old, Event &ev );
56 // add/remove event without journaling ( these ended up in public by accident, never 57 // add/remove event without journaling ( these ended up in public by accident, never
57 // use them unless you know what you are doing...), 58 // use them unless you know what you are doing...),
58 // please put them in private if we ever can change the class... 59 // please put them in private if we ever can change the class...
59 void addJFEvent( const Event &ev, bool doalarm=TRUE ); 60 void addJFEvent( const Event &ev, bool doalarm=TRUE );
60 void removeJFEvent( const Event &ev ); 61 void removeJFEvent( const Event &ev );
61 62
62 bool save(); 63 bool save();
63 void reload(); 64 void reload();
64private: 65private:
65 //find the real repeat... 66 //find the real repeat...
66 bool origRepeat( const Event &ev, Event &orig ) const; 67 bool origRepeat( const Event &ev, Event &orig ) const;
67 bool removeRepeat( const Event &ev ); 68 bool removeRepeat( const Event &ev );
68 void init(); 69 void init();
69 void loadFile( const QString &strFile ); 70 void loadFile( const QString &strFile );
70 // depreciated... 71 // depreciated...
71 void saveJournalEntry( const Event &ev, journal_action action ); 72 void saveJournalEntry( const Event &ev, journal_action action );
72 // new version, uncomment the "= -1" when we remove the above 73 // new version, uncomment the "= -1" when we remove the above
73 // function.. 74 // function..
74 bool saveJournalEntry( const Event &ev, journal_action action, 75 bool saveJournalEntry( const Event &ev, journal_action action,
75 int key/* = -1*/, bool origHadRepeat = false ); 76 int key/* = -1*/, bool origHadRepeat = false );
76 77
77 QValueList<Event> eventList; // non-repeating events... 78 QValueList<Event> eventList; // non-repeating events...
78 QValueList<Event> repeatEvents; // the repeating events... 79 QValueList<Event> repeatEvents; // the repeating events...
79 DateBookDBPrivate *d; 80 DateBookDBPrivate *d;
80 QFile journalFile; 81 QFile journalFile;
82
83 intrecordIdMax; // ADDITION
81}; 84};
82 85
83/* helper functions, also useful to other apps. */ 86/* helper functions, also useful to other apps. */
84bool nextOccurance( const Event &e, const QDate &from, QDateTime &next); 87bool nextOccurance( const Event &e, const QDate &from, QDateTime &next);
85#endif 88#endif