void Recurrence::setDuration( int duration ) { if ( d->mRecurReadOnly ) { return; } RecurrenceRule *rrule = defaultRRule( true ); if ( !rrule ) { return; } rrule->setDuration( duration ); updated(); }
RecurrenceRule *Recurrence::setNewRecurrenceType( RecurrenceRule::PeriodType type, int freq ) { if ( d->mRecurReadOnly || freq <= 0 ) { return 0; } d->mRRules.clearAll(); updated(); RecurrenceRule *rrule = defaultRRule( true ); if ( !rrule ) { return 0; } rrule->setRecurrenceType( type ); rrule->setFrequency( freq ); rrule->setDuration( -1 ); return rrule; }
void CompatPre31::fixRecurrence( const Incidence::Ptr &incidence ) { CompatPre32::fixRecurrence( incidence ); Recurrence *recur = incidence->recurrence(); RecurrenceRule *r = 0; if ( recur ) { r = recur->defaultRRule(); } if ( recur && r ) { int duration = r->duration(); if ( duration > 0 ) { // Backwards compatibility for KDE < 3.1. // rDuration was set to the number of time periods to recur, // with week start always on a Monday. // Convert this to the number of occurrences. r->setDuration( -1 ); QDate end( r->startDt().date() ); bool doNothing = false; // # of periods: int tmp = ( duration - 1 ) * r->frequency(); switch ( r->recurrenceType() ) { case RecurrenceRule::rWeekly: { end = end.addDays( tmp * 7 + 7 - end.dayOfWeek() ); break; } case RecurrenceRule::rMonthly: { int month = end.month() - 1 + tmp; end.setDate( end.year() + month / 12, month % 12 + 1, 31 ); break; } case RecurrenceRule::rYearly: { end.setDate( end.year() + tmp, 12, 31 ); break; } default: doNothing = true; break; } if ( !doNothing ) { duration = r->durationTo( KDateTime( end, QTime( 0, 0, 0 ), incidence->dtStart().timeSpec() ) ); r->setDuration( duration ); } } /* addYearlyNum */ // Dates were stored as day numbers, with a fiddle to take account of // leap years. Convert the day number to a month. QList<int> days = r->byYearDays(); if ( !days.isEmpty() ) { QList<int> months = r->byMonths(); for ( int i = 0; i < months.size(); ++i ) { int newmonth = QDate( r->startDt().date().year(), 1, 1 ).addDays( months.at( i ) - 1 ).month(); if ( !months.contains( newmonth ) ) { months.append( newmonth ); } } r->setByMonths( months ); days.clear(); r->setByYearDays( days ); } } }
/****************************************************************************** * Return the date/time of the last recurrence. */ QDateTime KARecurrence::endDateTime() const { if(mFeb29Type == FEB29_FEB29 || duration() <= 1) { /* Either it doesn't have any special February 29th treatment, * it's infinite (count = -1), the end date is specified * (count = 0), or it ends on the start date (count = 1). * So just use the normal KCal end date calculation. */ return Recurrence::endDateTime(); } /* Create a temporary recurrence rule to find the end date. * In a standard KCal recurrence, the 29th February only occurs once every * 4 years. So shift the temporary recurrence date to the 28th to ensure * that it occurs every year, thus giving the correct occurrence count. */ RecurrenceRule *rrule = new RecurrenceRule(); rrule->setRecurrenceType(RecurrenceRule::rYearly); QDateTime dt = startDateTime(); QDate d = dt.date(); switch(d.day()) { case 29: // The start date is definitely a recurrence date, so shift // start date to the temporary recurrence date of the 28th d.setYMD(d.year(), d.month(), 28); break; case 28: if(d.month() != 2 || mFeb29Type != FEB29_FEB28 || QDate::leapYear(d.year())) { // Start date is not a recurrence date, so shift it to 27th d.setYMD(d.year(), d.month(), 27); } break; case 1: if(d.month() == 3 && mFeb29Type == FEB29_MAR1 && !QDate::leapYear(d.year())) { // Start date is a March 1st recurrence date, so shift // start date to the temporary recurrence date of the 28th d.setYMD(d.year(), 2, 28); } break; default: break; } dt.setDate(d); rrule->setStartDt(dt); rrule->setFloats(doesFloat()); rrule->setFrequency(frequency()); rrule->setDuration(duration()); QValueList<int> ds; ds.append(28); rrule->setByMonthDays(ds); rrule->setByMonths(defaultRRuleConst()->byMonths()); dt = rrule->endDt(); delete rrule; // We've found the end date for a recurrence on the 28th. Unless that date // is a real February 28th recurrence, adjust to the actual recurrence date. if(mFeb29Type == FEB29_FEB28 && dt.date().month() == 2 && !QDate::leapYear(dt.date().year())) return dt; return dt.addDays(1); }