summaryrefslogtreecommitdiffabout
path: root/libkcal/recurrence.cpp
Unidiff
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
@@ -273,840 +273,853 @@ QDate Recurrence::endDate() const
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 }