summaryrefslogtreecommitdiffabout
path: root/libkcal/recurrence.cpp
authorzautrix <zautrix>2004-07-10 17:03:16 (UTC)
committer zautrix <zautrix>2004-07-10 17:03:16 (UTC)
commitcf2f3f98a4811668f9e9d0d5f44ea5b51d268cef (patch) (unidiff)
tree963322cd4c539c084feb43dfde5eabe52ae4385f /libkcal/recurrence.cpp
parent8cc6d456812b5a9a386e81c9e46baccd56029537 (diff)
downloadkdepimpi-cf2f3f98a4811668f9e9d0d5f44ea5b51d268cef.zip
kdepimpi-cf2f3f98a4811668f9e9d0d5f44ea5b51d268cef.tar.gz
kdepimpi-cf2f3f98a4811668f9e9d0d5f44ea5b51d268cef.tar.bz2
Fixed some problems with the recurrence
Diffstat (limited to 'libkcal/recurrence.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/recurrence.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/libkcal/recurrence.cpp b/libkcal/recurrence.cpp
index 5fc5d1f..dd74e10 100644
--- a/libkcal/recurrence.cpp
+++ b/libkcal/recurrence.cpp
@@ -145,1096 +145,1109 @@ bool Recurrence::operator==( const Recurrence& r2 ) const
145/* 145/*
146bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2) 146bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2)
147{ 147{
148 if ( l1.count() != l2.count() ) 148 if ( l1.count() != l2.count() )
149 return false; 149 return false;
150 int count = l1.count(); 150 int count = l1.count();
151 int i; 151 int i;
152 for ( i = 0; i < count ; ++i ) { 152 for ( i = 0; i < count ; ++i ) {
153 // if ( l1.at(i) != l2.at(i) ) 153 // if ( l1.at(i) != l2.at(i) )
154 return false; 154 return false;
155 qDebug("compüare "); 155 qDebug("compüare ");
156 } 156 }
157 return true; 157 return true;
158} 158}
159*/ 159*/
160QString Recurrence::recurrenceText() const 160QString Recurrence::recurrenceText() const
161{ 161{
162 QString recurText = i18n("No"); 162 QString recurText = i18n("No");
163 if ( recurs == Recurrence::rMinutely ) 163 if ( recurs == Recurrence::rMinutely )
164 recurText = i18n("minutely"); 164 recurText = i18n("minutely");
165 else if ( recurs == Recurrence::rHourly ) 165 else if ( recurs == Recurrence::rHourly )
166 recurText = i18n("hourly"); 166 recurText = i18n("hourly");
167 else if ( recurs == Recurrence::rDaily ) 167 else if ( recurs == Recurrence::rDaily )
168 recurText = i18n("daily"); 168 recurText = i18n("daily");
169 else if ( recurs == Recurrence::rWeekly ) 169 else if ( recurs == Recurrence::rWeekly )
170 recurText = i18n("weekly"); 170 recurText = i18n("weekly");
171 else if ( recurs == Recurrence::rMonthlyPos ) 171 else if ( recurs == Recurrence::rMonthlyPos )
172 recurText = i18n("monthly"); 172 recurText = i18n("monthly");
173 else if ( recurs == Recurrence::rMonthlyDay ) 173 else if ( recurs == Recurrence::rMonthlyDay )
174 recurText = i18n("day-monthly"); 174 recurText = i18n("day-monthly");
175 else if ( recurs == Recurrence::rYearlyMonth ) 175 else if ( recurs == Recurrence::rYearlyMonth )
176 recurText = i18n("month-yearly"); 176 recurText = i18n("month-yearly");
177 else if ( recurs == Recurrence::rYearlyDay ) 177 else if ( recurs == Recurrence::rYearlyDay )
178 recurText = i18n("day-yearly"); 178 recurText = i18n("day-yearly");
179 else if ( recurs == Recurrence::rYearlyPos ) 179 else if ( recurs == Recurrence::rYearlyPos )
180 recurText = i18n("position-yearly"); 180 recurText = i18n("position-yearly");
181 return recurText; 181 return recurText;
182} 182}
183 183
184void Recurrence::setCompatVersion(int version) 184void Recurrence::setCompatVersion(int version)
185{ 185{
186 mCompatVersion = version ? version : INT_MAX; 186 mCompatVersion = version ? version : INT_MAX;
187} 187}
188 188
189ushort Recurrence::doesRecur() const 189ushort Recurrence::doesRecur() const
190{ 190{
191 return recurs; 191 return recurs;
192} 192}
193 193
194bool Recurrence::recursOnPure(const QDate &qd) const 194bool Recurrence::recursOnPure(const QDate &qd) const
195{ 195{
196 switch(recurs) { 196 switch(recurs) {
197 case rMinutely: 197 case rMinutely:
198 return recursSecondly(qd, rFreq*60); 198 return recursSecondly(qd, rFreq*60);
199 case rHourly: 199 case rHourly:
200 return recursSecondly(qd, rFreq*3600); 200 return recursSecondly(qd, rFreq*3600);
201 case rDaily: 201 case rDaily:
202 return recursDaily(qd); 202 return recursDaily(qd);
203 case rWeekly: 203 case rWeekly:
204 return recursWeekly(qd); 204 return recursWeekly(qd);
205 case rMonthlyPos: 205 case rMonthlyPos:
206 case rMonthlyDay: 206 case rMonthlyDay:
207 return recursMonthly(qd); 207 return recursMonthly(qd);
208 case rYearlyMonth: 208 case rYearlyMonth:
209 return recursYearlyByMonth(qd); 209 return recursYearlyByMonth(qd);
210 case rYearlyDay: 210 case rYearlyDay:
211 return recursYearlyByDay(qd); 211 return recursYearlyByDay(qd);
212 case rYearlyPos: 212 case rYearlyPos:
213 return recursYearlyByPos(qd); 213 return recursYearlyByPos(qd);
214 default: 214 default:
215 return false; 215 return false;
216 case rNone: 216 case rNone:
217 return false; 217 return false;
218 } // case 218 } // case
219 return false; 219 return false;
220} 220}
221 221
222bool Recurrence::recursAtPure(const QDateTime &dt) const 222bool Recurrence::recursAtPure(const QDateTime &dt) const
223{ 223{
224 switch(recurs) { 224 switch(recurs) {
225 case rMinutely: 225 case rMinutely:
226 return recursMinutelyAt(dt, rFreq); 226 return recursMinutelyAt(dt, rFreq);
227 case rHourly: 227 case rHourly:
228 return recursMinutelyAt(dt, rFreq*60); 228 return recursMinutelyAt(dt, rFreq*60);
229 default: 229 default:
230 if (dt.time() != mRecurStart.time()) 230 if (dt.time() != mRecurStart.time())
231 return false; 231 return false;
232 switch(recurs) { 232 switch(recurs) {
233 case rDaily: 233 case rDaily:
234 return recursDaily(dt.date()); 234 return recursDaily(dt.date());
235 case rWeekly: 235 case rWeekly:
236 return recursWeekly(dt.date()); 236 return recursWeekly(dt.date());
237 case rMonthlyPos: 237 case rMonthlyPos:
238 case rMonthlyDay: 238 case rMonthlyDay:
239 return recursMonthly(dt.date()); 239 return recursMonthly(dt.date());
240 case rYearlyMonth: 240 case rYearlyMonth:
241 return recursYearlyByMonth(dt.date()); 241 return recursYearlyByMonth(dt.date());
242 case rYearlyDay: 242 case rYearlyDay:
243 return recursYearlyByDay(dt.date()); 243 return recursYearlyByDay(dt.date());
244 case rYearlyPos: 244 case rYearlyPos:
245 return recursYearlyByPos(dt.date()); 245 return recursYearlyByPos(dt.date());
246 default: 246 default:
247 return false; 247 return false;
248 case rNone: 248 case rNone:
249 return false; 249 return false;
250 } 250 }
251 } // case 251 } // case
252 return false; 252 return false;
253} 253}
254 254
255QDate Recurrence::endDate() const 255QDate Recurrence::endDate() const
256{ 256{
257 int count = 0; 257 int count = 0;
258 QDate end; 258 QDate end;
259 if (recurs != rNone) { 259 if (recurs != rNone) {
260 if (rDuration < 0) 260 if (rDuration < 0)
261 return QDate(); // infinite recurrence 261 return QDate(); // infinite recurrence
262 if (rDuration == 0) 262 if (rDuration == 0)
263 return rEndDateTime.date(); 263 return rEndDateTime.date();
264 264
265 // The end date is determined by the recurrence count 265 // The end date is determined by the recurrence count
266 QDate dStart = mRecurStart.date(); 266 QDate dStart = mRecurStart.date();
267 switch (recurs) 267 switch (recurs)
268 { 268 {
269 case rMinutely: 269 case rMinutely:
270 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60).date(); 270 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60).date();
271 case rHourly: 271 case rHourly:
272 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600).date(); 272 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600).date();
273 case rDaily: 273 case rDaily:
274 return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); 274 return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq);
275 275
276 case rWeekly: 276 case rWeekly:
277 count = weeklyCalc(END_DATE_AND_COUNT, end); 277 count = weeklyCalc(END_DATE_AND_COUNT, end);
278 break; 278 break;
279 case rMonthlyPos: 279 case rMonthlyPos:
280 case rMonthlyDay: 280 case rMonthlyDay:
281 count = monthlyCalc(END_DATE_AND_COUNT, end); 281 count = monthlyCalc(END_DATE_AND_COUNT, end);
282 break; 282 break;
283 case rYearlyMonth: 283 case rYearlyMonth:
284 count = yearlyMonthCalc(END_DATE_AND_COUNT, end); 284 count = yearlyMonthCalc(END_DATE_AND_COUNT, end);
285 break; 285 break;
286 case rYearlyDay: 286 case rYearlyDay:
287 count = yearlyDayCalc(END_DATE_AND_COUNT, end); 287 count = yearlyDayCalc(END_DATE_AND_COUNT, end);
288 break; 288 break;
289 case rYearlyPos: 289 case rYearlyPos:
290 count = yearlyPosCalc(END_DATE_AND_COUNT, end); 290 count = yearlyPosCalc(END_DATE_AND_COUNT, end);
291 break; 291 break;
292 default: 292 default:
293 // catch-all. Should never get here. 293 // catch-all. Should never get here.
294 kdDebug(5800) << "Control should never reach here in endDate()!" << endl; 294 kdDebug(5800) << "Control should never reach here in endDate()!" << endl;
295 break; 295 break;
296 } 296 }
297 } 297 }
298 if (!count) 298 if (!count)
299 return QDate(); // error - there is no recurrence 299 return QDate(); // error - there is no recurrence
300 return end; 300 return end;
301} 301}
302 302
303QDateTime Recurrence::endDateTime() const 303QDateTime Recurrence::endDateTime() const
304{ 304{
305 int count = 0; 305 int count = 0;
306 QDate end; 306 QDate end;
307 if (recurs != rNone) { 307 if (recurs != rNone) {
308 if (rDuration < 0) 308 if (rDuration < 0)
309 return QDateTime(); // infinite recurrence 309 return QDateTime(); // infinite recurrence
310 if (rDuration == 0) 310 if (rDuration == 0)
311 return rEndDateTime; 311 return rEndDateTime;
312 312
313 // The end date is determined by the recurrence count 313 // The end date is determined by the recurrence count
314 QDate dStart = mRecurStart.date(); 314 QDate dStart = mRecurStart.date();
315 switch (recurs) 315 switch (recurs)
316 { 316 {
317 case rMinutely: 317 case rMinutely:
318 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60); 318 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60);
319 case rHourly: 319 case rHourly:
320 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600); 320 return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600);
321 case rDaily: 321 case rDaily:
322 return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); 322 return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq);
323 323
324 case rWeekly: 324 case rWeekly:
325 count = weeklyCalc(END_DATE_AND_COUNT, end); 325 count = weeklyCalc(END_DATE_AND_COUNT, end);
326 break; 326 break;
327 case rMonthlyPos: 327 case rMonthlyPos:
328 case rMonthlyDay: 328 case rMonthlyDay:
329 count = monthlyCalc(END_DATE_AND_COUNT, end); 329 count = monthlyCalc(END_DATE_AND_COUNT, end);
330 break; 330 break;
331 case rYearlyMonth: 331 case rYearlyMonth:
332 count = yearlyMonthCalc(END_DATE_AND_COUNT, end); 332 count = yearlyMonthCalc(END_DATE_AND_COUNT, end);
333 break; 333 break;
334 case rYearlyDay: 334 case rYearlyDay:
335 count = yearlyDayCalc(END_DATE_AND_COUNT, end); 335 count = yearlyDayCalc(END_DATE_AND_COUNT, end);
336 break; 336 break;
337 case rYearlyPos: 337 case rYearlyPos:
338 count = yearlyPosCalc(END_DATE_AND_COUNT, end); 338 count = yearlyPosCalc(END_DATE_AND_COUNT, end);
339 break; 339 break;
340 default: 340 default:
341 // catch-all. Should never get here. 341 // catch-all. Should never get here.
342 kdDebug(5800) << "Control should never reach here in endDate()!" << endl; 342 kdDebug(5800) << "Control should never reach here in endDate()!" << endl;
343 break; 343 break;
344 } 344 }
345 } 345 }
346 if (!count) 346 if (!count)
347 return QDateTime(); // error - there is no recurrence 347 return QDateTime(); // error - there is no recurrence
348 return QDateTime(end, mRecurStart.time()); 348 return QDateTime(end, mRecurStart.time());
349} 349}
350 350
351int Recurrence::durationTo(const QDate &date) const 351int Recurrence::durationTo(const QDate &date) const
352{ 352{
353 QDate d = date; 353 QDate d = date;
354 return recurCalc(COUNT_TO_DATE, d); 354 return recurCalc(COUNT_TO_DATE, d);
355} 355}
356 356
357int Recurrence::durationTo(const QDateTime &datetime) const 357int Recurrence::durationTo(const QDateTime &datetime) const
358{ 358{
359 QDateTime dt = datetime; 359 QDateTime dt = datetime;
360 return recurCalc(COUNT_TO_DATE, dt); 360 return recurCalc(COUNT_TO_DATE, dt);
361} 361}
362 362
363void Recurrence::unsetRecurs() 363void Recurrence::unsetRecurs()
364{ 364{
365 if (mRecurReadOnly) return; 365 if (mRecurReadOnly) return;
366 recurs = rNone; 366 recurs = rNone;
367 rMonthPositions.clear(); 367 rMonthPositions.clear();
368 rMonthDays.clear(); 368 rMonthDays.clear();
369 rYearNums.clear(); 369 rYearNums.clear();
370} 370}
371 371
372void Recurrence::setRecurStart(const QDateTime &start) 372void Recurrence::setRecurStart(const QDateTime &start)
373{ 373{
374 mRecurStart = start; 374 mRecurStart = start;
375 mFloats = false; 375 mFloats = false;
376 switch (recurs) 376 switch (recurs)
377 { 377 {
378 case rMinutely: 378 case rMinutely:
379 case rHourly: 379 case rHourly:
380 break; 380 break;
381 case rDaily: 381 case rDaily:
382 case rWeekly: 382 case rWeekly:
383 case rMonthlyPos: 383 case rMonthlyPos:
384 case rMonthlyDay: 384 case rMonthlyDay:
385 case rYearlyMonth: 385 case rYearlyMonth:
386 case rYearlyDay: 386 case rYearlyDay:
387 case rYearlyPos: 387 case rYearlyPos:
388 default: 388 default:
389 rEndDateTime.setTime(start.time()); 389 rEndDateTime.setTime(start.time());
390 break; 390 break;
391 } 391 }
392} 392}
393 393
394void Recurrence::setRecurStart(const QDate &start) 394void Recurrence::setRecurStart(const QDate &start)
395{ 395{
396 mRecurStart.setDate(start); 396 mRecurStart.setDate(start);
397 mRecurStart.setTime(QTime(0,0,0)); 397 mRecurStart.setTime(QTime(0,0,0));
398 switch (recurs) 398 switch (recurs)
399 { 399 {
400 case rMinutely: 400 case rMinutely:
401 case rHourly: 401 case rHourly:
402 break; 402 break;
403 case rDaily: 403 case rDaily:
404 case rWeekly: 404 case rWeekly:
405 case rMonthlyPos: 405 case rMonthlyPos:
406 case rMonthlyDay: 406 case rMonthlyDay:
407 case rYearlyMonth: 407 case rYearlyMonth:
408 case rYearlyDay: 408 case rYearlyDay:
409 case rYearlyPos: 409 case rYearlyPos:
410 default: 410 default:
411 mFloats = true; 411 mFloats = true;
412 break; 412 break;
413 } 413 }
414} 414}
415 415
416void Recurrence::setFloats(bool f) 416void Recurrence::setFloats(bool f)
417{ 417{
418 switch (recurs) 418 switch (recurs)
419 { 419 {
420 case rDaily: 420 case rDaily:
421 case rWeekly: 421 case rWeekly:
422 case rMonthlyPos: 422 case rMonthlyPos:
423 case rMonthlyDay: 423 case rMonthlyDay:
424 case rYearlyMonth: 424 case rYearlyMonth:
425 case rYearlyDay: 425 case rYearlyDay:
426 case rYearlyPos: 426 case rYearlyPos:
427 break; 427 break;
428 case rMinutely: 428 case rMinutely:
429 case rHourly: 429 case rHourly:
430 default: 430 default:
431 return; // can't set sub-daily to floating 431 return; // can't set sub-daily to floating
432 } 432 }
433 mFloats = f; 433 mFloats = f;
434 if (f) { 434 if (f) {
435 mRecurStart.setTime(QTime(0,0,0)); 435 mRecurStart.setTime(QTime(0,0,0));
436 rEndDateTime.setTime(QTime(0,0,0)); 436 rEndDateTime.setTime(QTime(0,0,0));
437 } 437 }
438} 438}
439 439
440int Recurrence::frequency() const 440int Recurrence::frequency() const
441{ 441{
442 return rFreq; 442 return rFreq;
443} 443}
444 444
445int Recurrence::duration() const 445int Recurrence::duration() const
446{ 446{
447 return rDuration; 447 return rDuration;
448} 448}
449 449
450void Recurrence::setDuration(int _rDuration) 450void Recurrence::setDuration(int _rDuration)
451{ 451{
452 if (mRecurReadOnly) return; 452 if (mRecurReadOnly) return;
453 if (_rDuration > 0) { 453 if (_rDuration > 0) {
454 rDuration = _rDuration; 454 rDuration = _rDuration;
455 // Compatibility mode is only needed when reading the calendar in ICalFormatImpl, 455 // Compatibility mode is only needed when reading the calendar in ICalFormatImpl,
456 // so explicitly setting the duration means no backwards compatibility is needed. 456 // so explicitly setting the duration means no backwards compatibility is needed.
457 mCompatDuration = 0; 457 mCompatDuration = 0;
458 } 458 }
459} 459}
460 460
461QString Recurrence::endDateStr(bool shortfmt) const 461QString Recurrence::endDateStr(bool shortfmt) const
462{ 462{
463 return KGlobal::locale()->formatDate(rEndDateTime.date(),shortfmt); 463 return KGlobal::locale()->formatDate(rEndDateTime.date(),shortfmt);
464} 464}
465 465
466const QBitArray &Recurrence::days() const 466const QBitArray &Recurrence::days() const
467{ 467{
468 return rDays; 468 return rDays;
469} 469}
470 470
471const QPtrList<Recurrence::rMonthPos> &Recurrence::monthPositions() const 471const QPtrList<Recurrence::rMonthPos> &Recurrence::monthPositions() const
472{ 472{
473 return rMonthPositions; 473 return rMonthPositions;
474} 474}
475 475
476const QPtrList<Recurrence::rMonthPos> &Recurrence::yearMonthPositions() const 476const QPtrList<Recurrence::rMonthPos> &Recurrence::yearMonthPositions() const
477{ 477{
478 return rMonthPositions; 478 return rMonthPositions;
479} 479}
480 480
481const QPtrList<int> &Recurrence::monthDays() const 481const QPtrList<int> &Recurrence::monthDays() const
482{ 482{
483 return rMonthDays; 483 return rMonthDays;
484} 484}
485 485
486void Recurrence::setMinutely(int _rFreq, int _rDuration) 486void Recurrence::setMinutely(int _rFreq, int _rDuration)
487{ 487{
488 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 488 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
489 return; 489 return;
490 setDailySub(rMinutely, _rFreq, _rDuration); 490 setDailySub(rMinutely, _rFreq, _rDuration);
491} 491}
492 492
493void Recurrence::setMinutely(int _rFreq, const QDateTime &_rEndDateTime) 493void Recurrence::setMinutely(int _rFreq, const QDateTime &_rEndDateTime)
494{ 494{
495 if (mRecurReadOnly) return; 495 if (mRecurReadOnly) return;
496 rEndDateTime = _rEndDateTime; 496 rEndDateTime = _rEndDateTime;
497 setDailySub(rMinutely, _rFreq, 0); 497 setDailySub(rMinutely, _rFreq, 0);
498} 498}
499 499
500void Recurrence::setHourly(int _rFreq, int _rDuration) 500void Recurrence::setHourly(int _rFreq, int _rDuration)
501{ 501{
502 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 502 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
503 return; 503 return;
504 setDailySub(rHourly, _rFreq, _rDuration); 504 setDailySub(rHourly, _rFreq, _rDuration);
505} 505}
506 506
507void Recurrence::setHourly(int _rFreq, const QDateTime &_rEndDateTime) 507void Recurrence::setHourly(int _rFreq, const QDateTime &_rEndDateTime)
508{ 508{
509 if (mRecurReadOnly) return; 509 if (mRecurReadOnly) return;
510 rEndDateTime = _rEndDateTime; 510 rEndDateTime = _rEndDateTime;
511 setDailySub(rHourly, _rFreq, 0); 511 setDailySub(rHourly, _rFreq, 0);
512} 512}
513 513
514void Recurrence::setDaily(int _rFreq, int _rDuration) 514void Recurrence::setDaily(int _rFreq, int _rDuration)
515{ 515{
516 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 516 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
517 return; 517 return;
518 setDailySub(rDaily, _rFreq, _rDuration); 518 setDailySub(rDaily, _rFreq, _rDuration);
519} 519}
520 520
521void Recurrence::setDaily(int _rFreq, const QDate &_rEndDate) 521void Recurrence::setDaily(int _rFreq, const QDate &_rEndDate)
522{ 522{
523 if (mRecurReadOnly) return; 523 if (mRecurReadOnly) return;
524 rEndDateTime.setDate(_rEndDate); 524 rEndDateTime.setDate(_rEndDate);
525 rEndDateTime.setTime(mRecurStart.time()); 525 rEndDateTime.setTime(mRecurStart.time());
526 setDailySub(rDaily, _rFreq, 0); 526 setDailySub(rDaily, _rFreq, 0);
527} 527}
528 528
529void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, 529void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays,
530 int _rDuration, int _rWeekStart) 530 int _rDuration, int _rWeekStart)
531{ 531{
532 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 532 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
533 return; 533 return;
534 recurs = rWeekly; 534 recurs = rWeekly;
535 535
536 rFreq = _rFreq; 536 rFreq = _rFreq;
537 rDays = _rDays; 537 rDays = _rDays;
538 rWeekStart = _rWeekStart; 538 rWeekStart = _rWeekStart;
539 rDuration = _rDuration; 539 rDuration = _rDuration;
540 if (mCompatVersion < 310 && _rDuration > 0) { 540 if (mCompatVersion < 310 && _rDuration > 0) {
541 // Backwards compatibility for KDE < 3.1. 541 // Backwards compatibility for KDE < 3.1.
542 // rDuration was set to the number of time periods to recur, 542 // rDuration was set to the number of time periods to recur,
543 // with week start always on a Monday. 543 // with week start always on a Monday.
544 // Convert this to the number of occurrences. 544 // Convert this to the number of occurrences.
545 mCompatDuration = _rDuration; 545 mCompatDuration = _rDuration;
546 int weeks = ((mCompatDuration-1+mRecurExDatesCount)*7) + (7 - mRecurStart.date().dayOfWeek()); 546 int weeks = ((mCompatDuration-1+mRecurExDatesCount)*7) + (7 - mRecurStart.date().dayOfWeek());
547 QDate end(mRecurStart.date().addDays(weeks * rFreq)); 547 QDate end(mRecurStart.date().addDays(weeks * rFreq));
548 rDuration = INT_MAX; // ensure that weeklyCalc() does its job correctly 548 rDuration = INT_MAX; // ensure that weeklyCalc() does its job correctly
549 rDuration = weeklyCalc(COUNT_TO_DATE, end); 549 rDuration = weeklyCalc(COUNT_TO_DATE, end);
550 } else { 550 } else {
551 mCompatDuration = 0; 551 mCompatDuration = 0;
552 } 552 }
553 rMonthPositions.clear(); 553 rMonthPositions.clear();
554 rMonthDays.clear(); 554 rMonthDays.clear();
555 if (mParent) mParent->updated(); 555 if (mParent) mParent->updated();
556} 556}
557 557
558void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, 558void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays,
559 const QDate &_rEndDate, int _rWeekStart) 559 const QDate &_rEndDate, int _rWeekStart)
560{ 560{
561 if (mRecurReadOnly) return; 561 if (mRecurReadOnly) return;
562 recurs = rWeekly; 562 recurs = rWeekly;
563 563
564 rFreq = _rFreq; 564 rFreq = _rFreq;
565 rDays = _rDays; 565 rDays = _rDays;
566 rWeekStart = _rWeekStart; 566 rWeekStart = _rWeekStart;
567 rEndDateTime.setDate(_rEndDate); 567 rEndDateTime.setDate(_rEndDate);
568 rEndDateTime.setTime(mRecurStart.time()); 568 rEndDateTime.setTime(mRecurStart.time());
569 rDuration = 0; // set to 0 because there is an end date 569 rDuration = 0; // set to 0 because there is an end date
570 mCompatDuration = 0; 570 mCompatDuration = 0;
571 rMonthPositions.clear(); 571 rMonthPositions.clear();
572 rMonthDays.clear(); 572 rMonthDays.clear();
573 rYearNums.clear(); 573 rYearNums.clear();
574 if (mParent) mParent->updated(); 574 if (mParent) mParent->updated();
575} 575}
576 576
577void Recurrence::setMonthly(short type, int _rFreq, int _rDuration) 577void Recurrence::setMonthly(short type, int _rFreq, int _rDuration)
578{ 578{
579 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 579 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
580 return; 580 return;
581 recurs = type; 581 recurs = type;
582 582
583 rFreq = _rFreq; 583 rFreq = _rFreq;
584 rDuration = _rDuration; 584 rDuration = _rDuration;
585 if (mCompatVersion < 310) 585 if (mCompatVersion < 310)
586 mCompatDuration = (_rDuration > 0) ? _rDuration : 0; 586 mCompatDuration = (_rDuration > 0) ? _rDuration : 0;
587 rYearNums.clear(); 587 rYearNums.clear();
588 if (mParent) mParent->updated(); 588 if (mParent) mParent->updated();
589} 589}
590 590
591void Recurrence::setMonthly(short type, int _rFreq, 591void Recurrence::setMonthly(short type, int _rFreq,
592 const QDate &_rEndDate) 592 const QDate &_rEndDate)
593{ 593{
594 if (mRecurReadOnly) return; 594 if (mRecurReadOnly) return;
595 recurs = type; 595 recurs = type;
596 596
597 rFreq = _rFreq; 597 rFreq = _rFreq;
598 rEndDateTime.setDate(_rEndDate); 598 rEndDateTime.setDate(_rEndDate);
599 rEndDateTime.setTime(mRecurStart.time()); 599 rEndDateTime.setTime(mRecurStart.time());
600 rDuration = 0; // set to 0 because there is an end date 600 rDuration = 0; // set to 0 because there is an end date
601 mCompatDuration = 0; 601 mCompatDuration = 0;
602 rYearNums.clear(); 602 rYearNums.clear();
603 if (mParent) mParent->updated(); 603 if (mParent) mParent->updated();
604} 604}
605 605
606void Recurrence::addMonthlyPos(short _rPos, const QBitArray &_rDays) 606void Recurrence::addMonthlyPos(short _rPos, const QBitArray &_rDays)
607{ 607{
608 if (recurs == rMonthlyPos) 608 if (recurs == rMonthlyPos)
609 addMonthlyPos_(_rPos, _rDays); 609 addMonthlyPos_(_rPos, _rDays);
610} 610}
611 611
612void Recurrence::addMonthlyPos_(short _rPos, const QBitArray &_rDays) 612void Recurrence::addMonthlyPos_(short _rPos, const QBitArray &_rDays)
613{ 613{
614 if (mRecurReadOnly 614 if (mRecurReadOnly
615 || _rPos == 0 || _rPos > 5 || _rPos < -5) // invalid week number 615 || _rPos == 0 || _rPos > 5 || _rPos < -5) // invalid week number
616 return; 616 return;
617 617
618 for (rMonthPos* it = rMonthPositions.first(); it; it = rMonthPositions.next()) { 618 for (rMonthPos* it = rMonthPositions.first(); it; it = rMonthPositions.next()) {
619 int itPos = it->negative ? -it->rPos : it->rPos; 619 int itPos = it->negative ? -it->rPos : it->rPos;
620 if (_rPos == itPos) { 620 if (_rPos == itPos) {
621 // This week is already in the list. 621 // This week is already in the list.
622 // Combine the specified days with those in the list. 622 // Combine the specified days with those in the list.
623 it->rDays |= _rDays; 623 it->rDays |= _rDays;
624 if (mParent) mParent->updated(); 624 if (mParent) mParent->updated();
625 return; 625 return;
626 } 626 }
627 } 627 }
628 // Add the new position to the list 628 // Add the new position to the list
629 rMonthPos *tmpPos = new rMonthPos; 629 rMonthPos *tmpPos = new rMonthPos;
630 if (_rPos > 0) { 630 if (_rPos > 0) {
631 tmpPos->rPos = _rPos; 631 tmpPos->rPos = _rPos;
632 tmpPos->negative = false; 632 tmpPos->negative = false;
633 } else { 633 } else {
634 tmpPos->rPos = -_rPos; // take abs() 634 tmpPos->rPos = -_rPos; // take abs()
635 tmpPos->negative = true; 635 tmpPos->negative = true;
636 } 636 }
637 tmpPos->rDays = _rDays; 637 tmpPos->rDays = _rDays;
638 tmpPos->rDays.detach(); 638 tmpPos->rDays.detach();
639 rMonthPositions.append(tmpPos); 639 rMonthPositions.append(tmpPos);
640 640
641 if (mCompatVersion < 310 && mCompatDuration > 0) { 641 if (mCompatVersion < 310 && mCompatDuration > 0) {
642 // Backwards compatibility for KDE < 3.1. 642 // Backwards compatibility for KDE < 3.1.
643 // rDuration was set to the number of time periods to recur. 643 // rDuration was set to the number of time periods to recur.
644 // Convert this to the number of occurrences. 644 // Convert this to the number of occurrences.
645 int monthsAhead = (mCompatDuration-1+mRecurExDatesCount) * rFreq; 645 int monthsAhead = (mCompatDuration-1+mRecurExDatesCount) * rFreq;
646 int month = mRecurStart.date().month() - 1 + monthsAhead; 646 int month = mRecurStart.date().month() - 1 + monthsAhead;
647 QDate end(mRecurStart.date().year() + month/12, month%12 + 1, 31); 647 QDate end(mRecurStart.date().year() + month/12, month%12 + 1, 31);
648 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly 648 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly
649 rDuration = recurCalc(COUNT_TO_DATE, end); 649 rDuration = recurCalc(COUNT_TO_DATE, end);
650 } 650 }
651 651
652 if (mParent) mParent->updated(); 652 if (mParent) mParent->updated();
653} 653}
654 654
655void Recurrence::addMonthlyDay(short _rDay) 655void Recurrence::addMonthlyDay(short _rDay)
656{ 656{
657 if (mRecurReadOnly || recurs != rMonthlyDay 657 if (mRecurReadOnly || (recurs != rMonthlyDay && recurs != rYearlyMonth)
658 || _rDay == 0 || _rDay > 31 || _rDay < -31) // invalid day number 658 || _rDay == 0 || _rDay > 31 || _rDay < -31) // invalid day number
659 return; 659 return;
660 for (int* it = rMonthDays.first(); it; it = rMonthDays.next()) { 660 for (int* it = rMonthDays.first(); it; it = rMonthDays.next()) {
661 if (_rDay == *it) 661 if (_rDay == *it)
662 return; // this day is already in the list - avoid duplication 662 return; // this day is already in the list - avoid duplication
663 } 663 }
664 int *tmpDay = new int; 664 int *tmpDay = new int;
665 *tmpDay = _rDay; 665 *tmpDay = _rDay;
666 rMonthDays.append(tmpDay); 666 rMonthDays.append(tmpDay);
667 667
668 if (mCompatVersion < 310 && mCompatDuration > 0) { 668 if (mCompatVersion < 310 && mCompatDuration > 0) {
669 // Backwards compatibility for KDE < 3.1. 669 // Backwards compatibility for KDE < 3.1.
670 // rDuration was set to the number of time periods to recur. 670 // rDuration was set to the number of time periods to recur.
671 // Convert this to the number of occurrences. 671 // Convert this to the number of occurrences.
672 int monthsAhead = (mCompatDuration-1+mRecurExDatesCount) * rFreq; 672 int monthsAhead = (mCompatDuration-1+mRecurExDatesCount) * rFreq;
673 int month = mRecurStart.date().month() - 1 + monthsAhead; 673 int month = mRecurStart.date().month() - 1 + monthsAhead;
674 QDate end(mRecurStart.date().year() + month/12, month%12 + 1, 31); 674 QDate end(mRecurStart.date().year() + month/12, month%12 + 1, 31);
675 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly 675 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly
676 rDuration = recurCalc(COUNT_TO_DATE, end); 676 rDuration = recurCalc(COUNT_TO_DATE, end);
677 } 677 }
678 678
679 if (mParent) mParent->updated(); 679 if (mParent) mParent->updated();
680} 680}
681 681
682void Recurrence::setYearly(int type, int _rFreq, int _rDuration) 682void Recurrence::setYearly(int type, int _rFreq, int _rDuration)
683{ 683{
684 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 684 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
685 return; 685 return;
686 if (mCompatVersion < 310) 686 if (mCompatVersion < 310)
687 mCompatDuration = (_rDuration > 0) ? _rDuration : 0; 687 mCompatDuration = (_rDuration > 0) ? _rDuration : 0;
688 setYearly_(type, mFeb29YearlyDefaultType, _rFreq, _rDuration); 688 setYearly_(type, mFeb29YearlyDefaultType, _rFreq, _rDuration);
689} 689}
690 690
691void Recurrence::setYearly(int type, int _rFreq, const QDate &_rEndDate) 691void Recurrence::setYearly(int type, int _rFreq, const QDate &_rEndDate)
692{ 692{
693 if (mRecurReadOnly) return; 693 if (mRecurReadOnly) return;
694 rEndDateTime.setDate(_rEndDate); 694 rEndDateTime.setDate(_rEndDate);
695 rEndDateTime.setTime(mRecurStart.time()); 695 rEndDateTime.setTime(mRecurStart.time());
696 mCompatDuration = 0; 696 mCompatDuration = 0;
697 setYearly_(type, mFeb29YearlyDefaultType, _rFreq, 0); 697 setYearly_(type, mFeb29YearlyDefaultType, _rFreq, 0);
698} 698}
699 699
700void Recurrence::setYearlyByDate(Feb29Type type, int _rFreq, int _rDuration) 700void Recurrence::setYearlyByDate(Feb29Type type, int _rFreq, int _rDuration)
701{ 701{
702 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) 702 if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1)
703 return; 703 return;
704 if (mCompatVersion < 310) 704 if (mCompatVersion < 310)
705 mCompatDuration = (_rDuration > 0) ? _rDuration : 0; 705 mCompatDuration = (_rDuration > 0) ? _rDuration : 0;
706 setYearly_(rYearlyMonth, type, _rFreq, _rDuration); 706 setYearly_(rYearlyMonth, type, _rFreq, _rDuration);
707} 707}
708 708
709void Recurrence::setYearlyByDate(Feb29Type type, int _rFreq, const QDate &_rEndDate) 709void Recurrence::setYearlyByDate(Feb29Type type, int _rFreq, const QDate &_rEndDate)
710{ 710{
711 if (mRecurReadOnly) return; 711 if (mRecurReadOnly) return;
712 rEndDateTime.setDate(_rEndDate); 712 rEndDateTime.setDate(_rEndDate);
713 rEndDateTime.setTime(mRecurStart.time()); 713 rEndDateTime.setTime(mRecurStart.time());
714 mCompatDuration = 0; 714 mCompatDuration = 0;
715 setYearly_(rYearlyMonth, type, _rFreq, 0); 715 setYearly_(rYearlyMonth, type, _rFreq, 0);
716} 716}
717 717
718void Recurrence::addYearlyMonthPos(short _rPos, const QBitArray &_rDays) 718void Recurrence::addYearlyMonthPos(short _rPos, const QBitArray &_rDays)
719{ 719{
720 if (recurs == rYearlyPos) 720 if (recurs == rYearlyPos)
721 addMonthlyPos_(_rPos, _rDays); 721 addMonthlyPos_(_rPos, _rDays);
722} 722}
723 723
724const QPtrList<int> &Recurrence::yearNums() const 724const QPtrList<int> &Recurrence::yearNums() const
725{ 725{
726 return rYearNums; 726 return rYearNums;
727} 727}
728 728void Recurrence::addYearlyMonth(short _rPos )
729{
730 if (mRecurReadOnly || recurs != rYearlyMonth) // invalid day/month number
731 return;
732 rMonthPos *tmpPos = new rMonthPos;
733 if ( _rPos > 0) {
734 tmpPos->rPos = _rPos;
735 tmpPos->negative = false;
736 } else {
737 tmpPos->rPos = -_rPos; // take abs()
738 tmpPos->negative = true;
739 }
740 rMonthPositions.append(tmpPos);
741}
729void Recurrence::addYearlyNum(short _rNum) 742void Recurrence::addYearlyNum(short _rNum)
730{ 743{
731 if (mRecurReadOnly 744 if (mRecurReadOnly
732 || (recurs != rYearlyMonth && recurs != rYearlyDay && recurs != rYearlyPos) 745 || (recurs != rYearlyMonth && recurs != rYearlyDay && recurs != rYearlyPos)
733 || _rNum <= 0) // invalid day/month number 746 || _rNum <= 0) // invalid day/month number
734 return; 747 return;
735 748
736 if (mCompatVersion < 310 && mCompatRecurs == rYearlyDay) { 749 if (mCompatVersion < 310 && mCompatRecurs == rYearlyDay) {
737 // Backwards compatibility for KDE < 3.1. 750 // Backwards compatibility for KDE < 3.1.
738 // Dates were stored as day numbers, with a fiddle to take account of leap years. 751 // Dates were stored as day numbers, with a fiddle to take account of leap years.
739 // Convert the day number to a month. 752 // Convert the day number to a month.
740 if (_rNum <= 0 || _rNum > 366 || (_rNum == 366 && mRecurStart.date().daysInYear() < 366)) 753 if (_rNum <= 0 || _rNum > 366 || (_rNum == 366 && mRecurStart.date().daysInYear() < 366))
741 return; // invalid day number 754 return; // invalid day number
742 _rNum = QDate(mRecurStart.date().year(), 1, 1).addDays(_rNum - 1).month(); 755 _rNum = QDate(mRecurStart.date().year(), 1, 1).addDays(_rNum - 1).month();
743 } else 756 } else
744 if ((recurs == rYearlyMonth || recurs == rYearlyPos) && _rNum > 12 757 if ((recurs == rYearlyMonth || recurs == rYearlyPos) && _rNum > 12
745 || recurs == rYearlyDay && _rNum > 366) 758 || recurs == rYearlyDay && _rNum > 366)
746 return; // invalid day number 759 return; // invalid day number
747 760
748 uint i = 0; 761 uint i = 0;
749 for (int* it = rYearNums.first(); it && _rNum >= *it; it = rYearNums.next()) { 762 for (int* it = rYearNums.first(); it && _rNum >= *it; it = rYearNums.next()) {
750 if (_rNum == *it) 763 if (_rNum == *it)
751 return; // this day/month is already in the list - avoid duplication 764 return; // this day/month is already in the list - avoid duplication
752 ++i; 765 ++i;
753 } 766 }
754 767
755 int *tmpNum = new int; 768 int *tmpNum = new int;
756 *tmpNum = _rNum; 769 *tmpNum = _rNum;
757 rYearNums.insert(i, tmpNum); // insert the day/month in a sorted position 770 rYearNums.insert(i, tmpNum); // insert the day/month in a sorted position
758 771
759 if (mCompatVersion < 310 && mCompatDuration > 0) { 772 if (mCompatVersion < 310 && mCompatDuration > 0) {
760 // Backwards compatibility for KDE < 3.1. 773 // Backwards compatibility for KDE < 3.1.
761 // rDuration was set to the number of time periods to recur. 774 // rDuration was set to the number of time periods to recur.
762 // Convert this to the number of occurrences. 775 // Convert this to the number of occurrences.
763 QDate end(mRecurStart.date().year() + (mCompatDuration-1+mRecurExDatesCount)*rFreq, 12, 31); 776 QDate end(mRecurStart.date().year() + (mCompatDuration-1+mRecurExDatesCount)*rFreq, 12, 31);
764 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly 777 rDuration = INT_MAX; // ensure that recurCalc() does its job correctly
765 rDuration = recurCalc(COUNT_TO_DATE, end); 778 rDuration = recurCalc(COUNT_TO_DATE, end);
766 } 779 }
767 780
768 if (mParent) mParent->updated(); 781 if (mParent) mParent->updated();
769} 782}
770 783
771 784
772QDateTime Recurrence::getNextDateTime(const QDateTime &preDateTime, bool *last) const 785QDateTime Recurrence::getNextDateTime(const QDateTime &preDateTime, bool *last) const
773{ 786{
774 if (last) 787 if (last)
775 *last = false; 788 *last = false;
776 int freq; 789 int freq;
777 switch (recurs) 790 switch (recurs)
778 { 791 {
779 case rMinutely: 792 case rMinutely:
780 freq = rFreq * 60; 793 freq = rFreq * 60;
781 break; 794 break;
782 case rHourly: 795 case rHourly:
783 freq = rFreq * 3600; 796 freq = rFreq * 3600;
784 break; 797 break;
785 case rDaily: 798 case rDaily:
786 case rWeekly: 799 case rWeekly:
787 case rMonthlyPos: 800 case rMonthlyPos:
788 case rMonthlyDay: 801 case rMonthlyDay:
789 case rYearlyMonth: 802 case rYearlyMonth:
790 case rYearlyDay: 803 case rYearlyDay:
791 case rYearlyPos: { 804 case rYearlyPos: {
792 QDate preDate = preDateTime.date(); 805 QDate preDate = preDateTime.date();
793 if (!mFloats && mRecurStart.time() > preDateTime.time()) 806 if (!mFloats && mRecurStart.time() > preDateTime.time())
794 preDate = preDate.addDays(-1); 807 preDate = preDate.addDays(-1);
795 return QDateTime(getNextDateNoTime(preDate, last), mRecurStart.time()); 808 return QDateTime(getNextDateNoTime(preDate, last), mRecurStart.time());
796 } 809 }
797 default: 810 default:
798 return QDateTime(); 811 return QDateTime();
799 } 812 }
800 813
801 // It's a sub-daily recurrence 814 // It's a sub-daily recurrence
802 if (preDateTime < mRecurStart) 815 if (preDateTime < mRecurStart)
803 return mRecurStart; 816 return mRecurStart;
804 int count = mRecurStart.secsTo(preDateTime) / freq + 2; 817 int count = mRecurStart.secsTo(preDateTime) / freq + 2;
805 if (rDuration > 0) { 818 if (rDuration > 0) {
806 if (count > rDuration) 819 if (count > rDuration)
807 return QDateTime(); 820 return QDateTime();
808 if (last && count == rDuration) 821 if (last && count == rDuration)
809 *last = true; 822 *last = true;
810 } 823 }
811 QDateTime endtime = mRecurStart.addSecs((count - 1)*freq); 824 QDateTime endtime = mRecurStart.addSecs((count - 1)*freq);
812 if (rDuration == 0) { 825 if (rDuration == 0) {
813 if (endtime > rEndDateTime) 826 if (endtime > rEndDateTime)
814 return QDateTime(); 827 return QDateTime();
815 if (last && endtime == rEndDateTime) 828 if (last && endtime == rEndDateTime)
816 *last = true; 829 *last = true;
817 } 830 }
818 return endtime; 831 return endtime;
819} 832}
820 833
821QDate Recurrence::getNextDate(const QDate &preDate, bool *last) const 834QDate Recurrence::getNextDate(const QDate &preDate, bool *last) const
822{ 835{
823 if (last) 836 if (last)
824 *last = false; 837 *last = false;
825 switch (recurs) 838 switch (recurs)
826 { 839 {
827 case rMinutely: 840 case rMinutely:
828 case rHourly: 841 case rHourly:
829 return getNextDateTime(QDateTime(preDate, QTime(23,59,59)), last).date(); 842 return getNextDateTime(QDateTime(preDate, QTime(23,59,59)), last).date();
830 case rDaily: 843 case rDaily:
831 case rWeekly: 844 case rWeekly:
832 case rMonthlyPos: 845 case rMonthlyPos:
833 case rMonthlyDay: 846 case rMonthlyDay:
834 case rYearlyMonth: 847 case rYearlyMonth:
835 case rYearlyDay: 848 case rYearlyDay:
836 case rYearlyPos: 849 case rYearlyPos:
837 return getNextDateNoTime(preDate, last); 850 return getNextDateNoTime(preDate, last);
838 default: 851 default:
839 return QDate(); 852 return QDate();
840 } 853 }
841} 854}
842 855
843 856
844QDateTime Recurrence::getPreviousDateTime(const QDateTime &afterDateTime, bool *last) const 857QDateTime Recurrence::getPreviousDateTime(const QDateTime &afterDateTime, bool *last) const
845{ 858{
846 if (last) 859 if (last)
847 *last = false; 860 *last = false;
848 int freq; 861 int freq;
849 switch (recurs) 862 switch (recurs)
850 { 863 {
851 case rMinutely: 864 case rMinutely:
852 freq = rFreq * 60; 865 freq = rFreq * 60;
853 break; 866 break;
854 case rHourly: 867 case rHourly:
855 freq = rFreq * 3600; 868 freq = rFreq * 3600;
856 break; 869 break;
857 case rDaily: 870 case rDaily:
858 case rWeekly: 871 case rWeekly:
859 case rMonthlyPos: 872 case rMonthlyPos:
860 case rMonthlyDay: 873 case rMonthlyDay:
861 case rYearlyMonth: 874 case rYearlyMonth:
862 case rYearlyDay: 875 case rYearlyDay:
863 case rYearlyPos: { 876 case rYearlyPos: {
864 QDate afterDate = afterDateTime.date(); 877 QDate afterDate = afterDateTime.date();
865 if (!mFloats && mRecurStart.time() < afterDateTime.time()) 878 if (!mFloats && mRecurStart.time() < afterDateTime.time())
866 afterDate = afterDate.addDays(1); 879 afterDate = afterDate.addDays(1);
867 return QDateTime(getPreviousDateNoTime(afterDate, last), mRecurStart.time()); 880 return QDateTime(getPreviousDateNoTime(afterDate, last), mRecurStart.time());
868 } 881 }
869 default: 882 default:
870 return QDateTime(); 883 return QDateTime();
871 } 884 }
872 885
873 // It's a sub-daily recurrence 886 // It's a sub-daily recurrence
874 if (afterDateTime <= mRecurStart) 887 if (afterDateTime <= mRecurStart)
875 return QDateTime(); 888 return QDateTime();
876 int count = (mRecurStart.secsTo(afterDateTime) - 1) / freq + 1; 889 int count = (mRecurStart.secsTo(afterDateTime) - 1) / freq + 1;
877 if (rDuration > 0) { 890 if (rDuration > 0) {
878 if (count > rDuration) 891 if (count > rDuration)
879 count = rDuration; 892 count = rDuration;
880 if (last && count == rDuration) 893 if (last && count == rDuration)
881 *last = true; 894 *last = true;
882 } 895 }
883 QDateTime endtime = mRecurStart.addSecs((count - 1)*freq); 896 QDateTime endtime = mRecurStart.addSecs((count - 1)*freq);
884 if (rDuration == 0) { 897 if (rDuration == 0) {
885 if (endtime > rEndDateTime) 898 if (endtime > rEndDateTime)
886 endtime = rEndDateTime; 899 endtime = rEndDateTime;
887 if (last && endtime == rEndDateTime) 900 if (last && endtime == rEndDateTime)
888 *last = true; 901 *last = true;
889 } 902 }
890 return endtime; 903 return endtime;
891} 904}
892 905
893QDate Recurrence::getPreviousDate(const QDate &afterDate, bool *last) const 906QDate Recurrence::getPreviousDate(const QDate &afterDate, bool *last) const
894{ 907{
895 if (last) 908 if (last)
896 *last = false; 909 *last = false;
897 switch (recurs) 910 switch (recurs)
898 { 911 {
899 case rMinutely: 912 case rMinutely:
900 case rHourly: 913 case rHourly:
901 return getPreviousDateTime(QDateTime(afterDate, QTime(0,0,0)), last).date(); 914 return getPreviousDateTime(QDateTime(afterDate, QTime(0,0,0)), last).date();
902 case rDaily: 915 case rDaily:
903 case rWeekly: 916 case rWeekly:
904 case rMonthlyPos: 917 case rMonthlyPos:
905 case rMonthlyDay: 918 case rMonthlyDay:
906 case rYearlyMonth: 919 case rYearlyMonth:
907 case rYearlyDay: 920 case rYearlyDay:
908 case rYearlyPos: 921 case rYearlyPos:
909 return getPreviousDateNoTime(afterDate, last); 922 return getPreviousDateNoTime(afterDate, last);
910 default: 923 default:
911 return QDate(); 924 return QDate();
912 } 925 }
913} 926}
914 927
915 928
916/***************************** PROTECTED FUNCTIONS ***************************/ 929/***************************** PROTECTED FUNCTIONS ***************************/
917 930
918bool Recurrence::recursSecondly(const QDate &qd, int secondFreq) const 931bool Recurrence::recursSecondly(const QDate &qd, int secondFreq) const
919{ 932{
920 if ((qd >= mRecurStart.date()) && 933 if ((qd >= mRecurStart.date()) &&
921 ((rDuration > 0) && (qd <= endDate()) || 934 ((rDuration > 0) && (qd <= endDate()) ||
922 ((rDuration == 0) && (qd <= rEndDateTime.date())) || 935 ((rDuration == 0) && (qd <= rEndDateTime.date())) ||
923 (rDuration == -1))) { 936 (rDuration == -1))) {
924 // The date queried falls within the range of the event. 937 // The date queried falls within the range of the event.
925 if (secondFreq < 24*3600) 938 if (secondFreq < 24*3600)
926 return true; // the event recurs at least once each day 939 return true; // the event recurs at least once each day
927 int after = mRecurStart.secsTo(QDateTime(qd)); 940 int after = mRecurStart.secsTo(QDateTime(qd));
928 if (after / secondFreq != (after + 24*3600) / secondFreq) 941 if (after / secondFreq != (after + 24*3600) / secondFreq)
929 return true; 942 return true;
930 } 943 }
931 return false; 944 return false;
932} 945}
933 946
934bool Recurrence::recursMinutelyAt(const QDateTime &dt, int minuteFreq) const 947bool Recurrence::recursMinutelyAt(const QDateTime &dt, int minuteFreq) const
935{ 948{
936 if ((dt >= mRecurStart) && 949 if ((dt >= mRecurStart) &&
937 ((rDuration > 0) && (dt <= endDateTime()) || 950 ((rDuration > 0) && (dt <= endDateTime()) ||
938 ((rDuration == 0) && (dt <= rEndDateTime)) || 951 ((rDuration == 0) && (dt <= rEndDateTime)) ||
939 (rDuration == -1))) { 952 (rDuration == -1))) {
940 // The time queried falls within the range of the event. 953 // The time queried falls within the range of the event.
941 if (((mRecurStart.secsTo(dt) / 60) % minuteFreq) == 0) 954 if (((mRecurStart.secsTo(dt) / 60) % minuteFreq) == 0)
942 return true; 955 return true;
943 } 956 }
944 return false; 957 return false;
945} 958}
946 959
947bool Recurrence::recursDaily(const QDate &qd) const 960bool Recurrence::recursDaily(const QDate &qd) const
948{ 961{
949 QDate dStart = mRecurStart.date(); 962 QDate dStart = mRecurStart.date();
950 if ((dStart.daysTo(qd) % rFreq) == 0) { 963 if ((dStart.daysTo(qd) % rFreq) == 0) {
951 // The date is a day which recurs 964 // The date is a day which recurs
952 if (qd >= dStart 965 if (qd >= dStart
953 && ((rDuration > 0 && qd <= endDate()) || 966 && ((rDuration > 0 && qd <= endDate()) ||
954 (rDuration == 0 && qd <= rEndDateTime.date()) || 967 (rDuration == 0 && qd <= rEndDateTime.date()) ||
955 rDuration == -1)) { 968 rDuration == -1)) {
956 // The date queried falls within the range of the event. 969 // The date queried falls within the range of the event.
957 return true; 970 return true;
958 } 971 }
959 } 972 }
960 return false; 973 return false;
961} 974}
962 975
963bool Recurrence::recursWeekly(const QDate &qd) const 976bool Recurrence::recursWeekly(const QDate &qd) const
964{ 977{
965 QDate dStart = mRecurStart.date(); 978 QDate dStart = mRecurStart.date();
966 if ((dStart.daysTo(qd)/7) % rFreq == 0) { 979 if ((dStart.daysTo(qd)/7) % rFreq == 0) {
967 // The date is in a week which recurs 980 // The date is in a week which recurs
968 if (qd >= dStart 981 if (qd >= dStart
969 && ((rDuration > 0 && qd <= endDate()) || 982 && ((rDuration > 0 && qd <= endDate()) ||
970 (rDuration == 0 && qd <= rEndDateTime.date()) || 983 (rDuration == 0 && qd <= rEndDateTime.date()) ||
971 rDuration == -1)) { 984 rDuration == -1)) {
972 // The date queried falls within the range of the event. 985 // The date queried falls within the range of the event.
973 // check if the bits set match today. 986 // check if the bits set match today.
974 int i = qd.dayOfWeek()-1; 987 int i = qd.dayOfWeek()-1;
975 if (rDays.testBit((uint) i)) 988 if (rDays.testBit((uint) i))
976 return true; 989 return true;
977 } 990 }
978 } 991 }
979 return false; 992 return false;
980} 993}
981 994
982bool Recurrence::recursMonthly(const QDate &qd) const 995bool Recurrence::recursMonthly(const QDate &qd) const
983{ 996{
984 QDate dStart = mRecurStart.date(); 997 QDate dStart = mRecurStart.date();
985 int year = qd.year(); 998 int year = qd.year();
986 int month = qd.month(); 999 int month = qd.month();
987 int day = qd.day(); 1000 int day = qd.day();
988 // calculate how many months ahead this date is from the original 1001 // calculate how many months ahead this date is from the original
989 // event's date 1002 // event's date
990 int monthsAhead = (year - dStart.year()) * 12 + (month - dStart.month()); 1003 int monthsAhead = (year - dStart.year()) * 12 + (month - dStart.month());
991 if ((monthsAhead % rFreq) == 0) { 1004 if ((monthsAhead % rFreq) == 0) {
992 // The date is in a month which recurs 1005 // The date is in a month which recurs
993 if (qd >= dStart 1006 if (qd >= dStart
994 && ((rDuration > 0 && qd <= endDate()) || 1007 && ((rDuration > 0 && qd <= endDate()) ||
995 (rDuration == 0 && qd <= rEndDateTime.date()) || 1008 (rDuration == 0 && qd <= rEndDateTime.date()) ||
996 rDuration == -1)) { 1009 rDuration == -1)) {
997 // The date queried falls within the range of the event. 1010 // The date queried falls within the range of the event.
998 QValueList<int> days; 1011 QValueList<int> days;
999 int daysInMonth = qd.daysInMonth(); 1012 int daysInMonth = qd.daysInMonth();
1000 if (recurs == rMonthlyDay) 1013 if (recurs == rMonthlyDay)
1001 getMonthlyDayDays(days, daysInMonth); 1014 getMonthlyDayDays(days, daysInMonth);
1002 else if (recurs == rMonthlyPos) 1015 else if (recurs == rMonthlyPos)
1003 getMonthlyPosDays(days, daysInMonth, QDate(year, month, 1).dayOfWeek()); 1016 getMonthlyPosDays(days, daysInMonth, QDate(year, month, 1).dayOfWeek());
1004 for (QValueList<int>::Iterator it = days.begin(); it != days.end(); ++it) { 1017 for (QValueList<int>::Iterator it = days.begin(); it != days.end(); ++it) {
1005 if (*it == day) 1018 if (*it == day)
1006 return true; 1019 return true;
1007 } 1020 }
1008 // no dates matched 1021 // no dates matched
1009 } 1022 }
1010 } 1023 }
1011 return false; 1024 return false;
1012} 1025}
1013 1026
1014bool Recurrence::recursYearlyByMonth(const QDate &qd) const 1027bool Recurrence::recursYearlyByMonth(const QDate &qd) const
1015{ 1028{
1016 QDate dStart = mRecurStart.date(); 1029 QDate dStart = mRecurStart.date();
1017 int startDay = dStart.day(); 1030 int startDay = dStart.day();
1018 int qday = qd.day(); 1031 int qday = qd.day();
1019 int qmonth = qd.month(); 1032 int qmonth = qd.month();
1020 int qyear = qd.year(); 1033 int qyear = qd.year();
1021 bool match = (qday == startDay); 1034 bool match = (qday == startDay);
1022 if (!match && startDay == 29 && dStart.month() == 2) { 1035 if (!match && startDay == 29 && dStart.month() == 2) {
1023 // It's a recurrence on February 29th 1036 // It's a recurrence on February 29th
1024 switch (mFeb29YearlyType) { 1037 switch (mFeb29YearlyType) {
1025 case rFeb28: 1038 case rFeb28:
1026 if (qday == 28 && qmonth == 2 && !QDate::leapYear(qyear)) 1039 if (qday == 28 && qmonth == 2 && !QDate::leapYear(qyear))
1027 match = true; 1040 match = true;
1028 break; 1041 break;
1029 case rMar1: 1042 case rMar1:
1030 if (qday == 1 && qmonth == 3 && !QDate::leapYear(qyear)) { 1043 if (qday == 1 && qmonth == 3 && !QDate::leapYear(qyear)) {
1031 qmonth = 2; 1044 qmonth = 2;
1032 match = true; 1045 match = true;
1033 } 1046 }
1034 break; 1047 break;
1035 case rFeb29: 1048 case rFeb29:
1036 break; 1049 break;
1037 } 1050 }
1038 } 1051 }
1039 1052
1040 if (match) { 1053 if (match) {
1041 // The day of the month matches. Calculate how many years ahead 1054 // The day of the month matches. Calculate how many years ahead
1042 // this date is from the original event's date. 1055 // this date is from the original event's date.
1043 int yearsAhead = (qyear - dStart.year()); 1056 int yearsAhead = (qyear - dStart.year());
1044 if (yearsAhead % rFreq == 0) { 1057 if (yearsAhead % rFreq == 0) {
1045 // The date is in a year which recurs 1058 // The date is in a year which recurs
1046 if (qd >= dStart 1059 if (qd >= dStart
1047 && ((rDuration > 0 && qd <= endDate()) || 1060 && ((rDuration > 0 && qd <= endDate()) ||
1048 (rDuration == 0 && qd <= rEndDateTime.date()) || 1061 (rDuration == 0 && qd <= rEndDateTime.date()) ||
1049 rDuration == -1)) { 1062 rDuration == -1)) {
1050 // The date queried falls within the range of the event. 1063 // The date queried falls within the range of the event.
1051 int i = qmonth; 1064 int i = qmonth;
1052 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) { 1065 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) {
1053 if (i == *qlin.current()) 1066 if (i == *qlin.current())
1054 return true; 1067 return true;
1055 } 1068 }
1056 } 1069 }
1057 } 1070 }
1058 } 1071 }
1059 return false; 1072 return false;
1060} 1073}
1061 1074
1062bool Recurrence::recursYearlyByPos(const QDate &qd) const 1075bool Recurrence::recursYearlyByPos(const QDate &qd) const
1063{ 1076{
1064 QDate dStart = mRecurStart.date(); 1077 QDate dStart = mRecurStart.date();
1065 int year = qd.year(); 1078 int year = qd.year();
1066 int month = qd.month(); 1079 int month = qd.month();
1067 int day = qd.day(); 1080 int day = qd.day();
1068 // calculate how many years ahead this date is from the original 1081 // calculate how many years ahead this date is from the original
1069 // event's date 1082 // event's date
1070 int yearsAhead = (year - dStart.year()); 1083 int yearsAhead = (year - dStart.year());
1071 if (yearsAhead % rFreq == 0) { 1084 if (yearsAhead % rFreq == 0) {
1072 // The date is in a year which recurs 1085 // The date is in a year which recurs
1073 if (qd >= dStart 1086 if (qd >= dStart
1074 && ((rDuration > 0 && qd <= endDate()) || 1087 && ((rDuration > 0 && qd <= endDate()) ||
1075 (rDuration == 0 && qd <= rEndDateTime.date()) || 1088 (rDuration == 0 && qd <= rEndDateTime.date()) ||
1076 rDuration == -1)) { 1089 rDuration == -1)) {
1077 // The date queried falls within the range of the event. 1090 // The date queried falls within the range of the event.
1078 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) { 1091 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) {
1079 if (month == *qlin.current()) { 1092 if (month == *qlin.current()) {
1080 // The month recurs 1093 // The month recurs
1081 QValueList<int> days; 1094 QValueList<int> days;
1082 getMonthlyPosDays(days, qd.daysInMonth(), QDate(year, month, 1).dayOfWeek()); 1095 getMonthlyPosDays(days, qd.daysInMonth(), QDate(year, month, 1).dayOfWeek());
1083 for (QValueList<int>::Iterator it = days.begin(); it != days.end(); ++it) { 1096 for (QValueList<int>::Iterator it = days.begin(); it != days.end(); ++it) {
1084 if (*it == day) 1097 if (*it == day)
1085 return true; 1098 return true;
1086 } 1099 }
1087 } 1100 }
1088 } 1101 }
1089 } 1102 }
1090 } 1103 }
1091 return false; 1104 return false;
1092} 1105}
1093 1106
1094bool Recurrence::recursYearlyByDay(const QDate &qd) const 1107bool Recurrence::recursYearlyByDay(const QDate &qd) const
1095{ 1108{
1096 QDate dStart = mRecurStart.date(); 1109 QDate dStart = mRecurStart.date();
1097 // calculate how many years ahead this date is from the original 1110 // calculate how many years ahead this date is from the original
1098 // event's date 1111 // event's date
1099 int yearsAhead = (qd.year() - dStart.year()); 1112 int yearsAhead = (qd.year() - dStart.year());
1100 if (yearsAhead % rFreq == 0) { 1113 if (yearsAhead % rFreq == 0) {
1101 // The date is in a year which recurs 1114 // The date is in a year which recurs
1102 if (qd >= dStart 1115 if (qd >= dStart
1103 && ((rDuration > 0 && qd <= endDate()) || 1116 && ((rDuration > 0 && qd <= endDate()) ||
1104 (rDuration == 0 && qd <= rEndDateTime.date()) || 1117 (rDuration == 0 && qd <= rEndDateTime.date()) ||
1105 rDuration == -1)) { 1118 rDuration == -1)) {
1106 // The date queried falls within the range of the event. 1119 // The date queried falls within the range of the event.
1107 int i = qd.dayOfYear(); 1120 int i = qd.dayOfYear();
1108 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) { 1121 for (QPtrListIterator<int> qlin(rYearNums); qlin.current(); ++qlin) {
1109 if (i == *qlin.current()) 1122 if (i == *qlin.current())
1110 return true; 1123 return true;
1111 } 1124 }
1112 } 1125 }
1113 } 1126 }
1114 return false; 1127 return false;
1115} 1128}
1116 1129
1117/* Get the date of the next recurrence, after the specified date. 1130/* Get the date of the next recurrence, after the specified date.
1118 * If 'last' is non-null, '*last' is set to true if the next recurrence is the 1131 * If 'last' is non-null, '*last' is set to true if the next recurrence is the
1119 * last recurrence, else false. 1132 * last recurrence, else false.
1120 * Reply = date of next recurrence, or invalid date if none. 1133 * Reply = date of next recurrence, or invalid date if none.
1121 */ 1134 */
1122QDate Recurrence::getNextDateNoTime(const QDate &preDate, bool *last) const 1135QDate Recurrence::getNextDateNoTime(const QDate &preDate, bool *last) const
1123{ 1136{
1124 if (last) 1137 if (last)
1125 *last = false; 1138 *last = false;
1126 QDate dStart = mRecurStart.date(); 1139 QDate dStart = mRecurStart.date();
1127 if (preDate < dStart) 1140 if (preDate < dStart)
1128 return dStart; 1141 return dStart;
1129 QDate earliestDate = preDate.addDays(1); 1142 QDate earliestDate = preDate.addDays(1);
1130 QDate nextDate; 1143 QDate nextDate;
1131 1144
1132 switch (recurs) { 1145 switch (recurs) {
1133 case rDaily: 1146 case rDaily:
1134 nextDate = dStart.addDays((dStart.daysTo(preDate)/rFreq + 1) * rFreq); 1147 nextDate = dStart.addDays((dStart.daysTo(preDate)/rFreq + 1) * rFreq);
1135 break; 1148 break;
1136 1149
1137 case rWeekly: { 1150 case rWeekly: {
1138 QDate start = dStart.addDays(1 - dStart.dayOfWeek()); // start of week for dStart 1151 QDate start = dStart.addDays(1 - dStart.dayOfWeek()); // start of week for dStart
1139 int earliestDayOfWeek = earliestDate.dayOfWeek(); 1152 int earliestDayOfWeek = earliestDate.dayOfWeek();
1140 int weeksAhead = start.daysTo(earliestDate) / 7; 1153 int weeksAhead = start.daysTo(earliestDate) / 7;
1141 int notThisWeek = weeksAhead % rFreq; // zero if this week is a recurring week 1154 int notThisWeek = weeksAhead % rFreq; // zero if this week is a recurring week
1142 weeksAhead -= notThisWeek; // latest week which recurred 1155 weeksAhead -= notThisWeek; // latest week which recurred
1143 int weekday = 0; 1156 int weekday = 0;
1144 // First check for any remaining day this week, if this week is a recurring week 1157 // First check for any remaining day this week, if this week is a recurring week
1145 if (!notThisWeek) 1158 if (!notThisWeek)
1146 weekday = getFirstDayInWeek(earliestDayOfWeek); 1159 weekday = getFirstDayInWeek(earliestDayOfWeek);
1147 // Check for a day in the next scheduled week 1160 // Check for a day in the next scheduled week
1148 if (!weekday && earliestDayOfWeek > 1) 1161 if (!weekday && earliestDayOfWeek > 1)
1149 weekday = getFirstDayInWeek(rWeekStart) + rFreq*7; 1162 weekday = getFirstDayInWeek(rWeekStart) + rFreq*7;
1150 if (weekday) 1163 if (weekday)
1151 nextDate = start.addDays(weeksAhead*7 + weekday - 1); 1164 nextDate = start.addDays(weeksAhead*7 + weekday - 1);
1152 break; 1165 break;
1153 } 1166 }
1154 case rMonthlyDay: 1167 case rMonthlyDay:
1155 case rMonthlyPos: { 1168 case rMonthlyPos: {
1156 int startYear = dStart.year(); 1169 int startYear = dStart.year();
1157 int startMonth = dStart.month(); // 1..12 1170 int startMonth = dStart.month(); // 1..12
1158 int earliestYear = earliestDate.year(); 1171 int earliestYear = earliestDate.year();
1159 int monthsAhead = (earliestYear - startYear)*12 + earliestDate.month() - startMonth; 1172 int monthsAhead = (earliestYear - startYear)*12 + earliestDate.month() - startMonth;
1160 int notThisMonth = monthsAhead % rFreq; // zero if this month is a recurring month 1173 int notThisMonth = monthsAhead % rFreq; // zero if this month is a recurring month
1161 monthsAhead -= notThisMonth; // latest month which recurred 1174 monthsAhead -= notThisMonth; // latest month which recurred
1162 // Check for the first later day in the current month 1175 // Check for the first later day in the current month
1163 if (!notThisMonth) 1176 if (!notThisMonth)
1164 nextDate = getFirstDateInMonth(earliestDate); 1177 nextDate = getFirstDateInMonth(earliestDate);
1165 if (!nextDate.isValid() && earliestDate.day() > 1) { 1178 if (!nextDate.isValid() && earliestDate.day() > 1) {
1166 // Check for a day in the next scheduled month 1179 // Check for a day in the next scheduled month
1167 int months = startMonth - 1 + monthsAhead + rFreq; 1180 int months = startMonth - 1 + monthsAhead + rFreq;
1168 nextDate = getFirstDateInMonth(QDate(startYear + months/12, months%12 + 1, 1)); 1181 nextDate = getFirstDateInMonth(QDate(startYear + months/12, months%12 + 1, 1));
1169 } 1182 }
1170 break; 1183 break;
1171 } 1184 }
1172 case rYearlyMonth: 1185 case rYearlyMonth:
1173 case rYearlyPos: 1186 case rYearlyPos:
1174 case rYearlyDay: { 1187 case rYearlyDay: {
1175 int startYear = dStart.year(); 1188 int startYear = dStart.year();
1176 int yearsAhead = earliestDate.year() - startYear; 1189 int yearsAhead = earliestDate.year() - startYear;
1177 int notThisYear = yearsAhead % rFreq; // zero if this year is a recurring year 1190 int notThisYear = yearsAhead % rFreq; // zero if this year is a recurring year
1178 yearsAhead -= notThisYear; // latest year which recurred 1191 yearsAhead -= notThisYear; // latest year which recurred
1179 // Check for the first later date in the current year 1192 // Check for the first later date in the current year
1180 if (!notThisYear) 1193 if (!notThisYear)
1181 nextDate = getFirstDateInYear(earliestDate); 1194 nextDate = getFirstDateInYear(earliestDate);
1182 // Check for a date in the next scheduled year 1195 // Check for a date in the next scheduled year
1183 if (!nextDate.isValid() && earliestDate.dayOfYear() > 1) 1196 if (!nextDate.isValid() && earliestDate.dayOfYear() > 1)
1184 nextDate = getFirstDateInYear(QDate(startYear + yearsAhead + rFreq, 1, 1)); 1197 nextDate = getFirstDateInYear(QDate(startYear + yearsAhead + rFreq, 1, 1));
1185 break; 1198 break;
1186 } 1199 }
1187 case rNone: 1200 case rNone:
1188 default: 1201 default:
1189 return QDate(); 1202 return QDate();
1190 } 1203 }
1191 1204
1192 if (rDuration >= 0 && nextDate.isValid()) { 1205 if (rDuration >= 0 && nextDate.isValid()) {
1193 // Check that the date found is within the range of the recurrence 1206 // Check that the date found is within the range of the recurrence
1194 QDate end = endDate(); 1207 QDate end = endDate();
1195 if (nextDate > end) 1208 if (nextDate > end)
1196 return QDate(); 1209 return QDate();
1197 if (last && nextDate == end) 1210 if (last && nextDate == end)
1198 *last = true; 1211 *last = true;
1199 } 1212 }
1200 return nextDate; 1213 return nextDate;
1201} 1214}
1202 1215
1203/* Get the date of the last previous recurrence, before the specified date. 1216/* Get the date of the last previous recurrence, before the specified date.
1204 * Reply = date of previous recurrence, or invalid date if none. 1217 * Reply = date of previous recurrence, or invalid date if none.
1205 */ 1218 */
1206QDate Recurrence::getPreviousDateNoTime(const QDate &afterDate, bool *last) const 1219QDate Recurrence::getPreviousDateNoTime(const QDate &afterDate, bool *last) const
1207{ 1220{
1208 if (last) 1221 if (last)
1209 *last = false; 1222 *last = false;
1210 QDate dStart = mRecurStart.date(); 1223 QDate dStart = mRecurStart.date();
1211 QDate latestDate = afterDate.addDays(-1); 1224 QDate latestDate = afterDate.addDays(-1);
1212 if (latestDate < dStart) 1225 if (latestDate < dStart)
1213 return QDate(); 1226 return QDate();
1214 QDate prevDate; 1227 QDate prevDate;
1215 1228
1216 switch (recurs) { 1229 switch (recurs) {
1217 case rDaily: 1230 case rDaily:
1218 prevDate = dStart.addDays((dStart.daysTo(latestDate) / rFreq) * rFreq); 1231 prevDate = dStart.addDays((dStart.daysTo(latestDate) / rFreq) * rFreq);
1219 break; 1232 break;
1220 1233
1221 case rWeekly: { 1234 case rWeekly: {
1222 QDate start = dStart.addDays(1 - dStart.dayOfWeek()); // start of week for dStart 1235 QDate start = dStart.addDays(1 - dStart.dayOfWeek()); // start of week for dStart
1223 int latestDayOfWeek = latestDate.dayOfWeek(); 1236 int latestDayOfWeek = latestDate.dayOfWeek();
1224 int weeksAhead = start.daysTo(latestDate) / 7; 1237 int weeksAhead = start.daysTo(latestDate) / 7;
1225 int notThisWeek = weeksAhead % rFreq; // zero if this week is a recurring week 1238 int notThisWeek = weeksAhead % rFreq; // zero if this week is a recurring week
1226 weeksAhead -= notThisWeek; // latest week which recurred 1239 weeksAhead -= notThisWeek; // latest week which recurred
1227 int weekday = 0; 1240 int weekday = 0;
1228 // First check for any previous day this week, if this week is a recurring week 1241 // First check for any previous day this week, if this week is a recurring week
1229 if (!notThisWeek) 1242 if (!notThisWeek)
1230 weekday = getLastDayInWeek(latestDayOfWeek); 1243 weekday = getLastDayInWeek(latestDayOfWeek);
1231 // Check for a day in the previous scheduled week 1244 // Check for a day in the previous scheduled week
1232 if (!weekday) { 1245 if (!weekday) {
1233 int weekEnd = (rWeekStart + 5)%7 + 1; 1246 int weekEnd = (rWeekStart + 5)%7 + 1;
1234 if (latestDayOfWeek < weekEnd) { 1247 if (latestDayOfWeek < weekEnd) {
1235 if (!notThisWeek) 1248 if (!notThisWeek)
1236 weeksAhead -= rFreq; 1249 weeksAhead -= rFreq;
1237 weekday = getLastDayInWeek(weekEnd); 1250 weekday = getLastDayInWeek(weekEnd);
1238 } 1251 }
1239 } 1252 }
1240 if (weekday) 1253 if (weekday)