コード例 #1
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// Emulate the old behavior
QList<int> Recurrence::monthDays() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  if ( rrule ) {
    return rrule->byMonthDays();
  } else {
    return QList<int>();
  }
}
コード例 #2
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::addMonthlyDate( short day )
{
  if ( d->mRecurReadOnly || day > 31 || day < -31 ) {
    return;
  }

  RecurrenceRule *rrule = defaultRRule( true );
  if ( !rrule ) {
    return;
  }

  QList<int> monthDays = rrule->byMonthDays();
  if ( !monthDays.contains( day ) ) {
    monthDays.append( day );
    rrule->setByMonthDays( monthDays );
    updated();
  }
}
コード例 #3
0
ファイル: karecurrence.cpp プロジェクト: serghei/kde3-kdepim
/******************************************************************************
* Must be called after presetting with a KCal::Recurrence, to convert the
* recurrence to KARecurrence types:
* - Convert hourly recurrences to minutely.
* - Remove all but the first day in yearly date recurrences.
* - Check for yearly recurrences falling on February 29th and adjust them as
*   necessary. A 29th of the month rule can be combined with either a 60th day
*   of the year rule or a last day of February rule.
*/
void KARecurrence::fix()
{
    mCachedType = -1;
    mFeb29Type = FEB29_FEB29;
    int convert = 0;
    int days[2] = { 0, 0 };
    RecurrenceRule *rrules[2];
    RecurrenceRule::List rrulelist = rRules();
    RecurrenceRule::List::ConstIterator rr = rrulelist.begin();
    for(int i = 0;  i < 2  &&  rr != rrulelist.end();  ++i, ++rr)
    {
        RecurrenceRule *rrule = *rr;
        rrules[i] = rrule;
        bool stop = true;
        int rtype = recurrenceType(rrule);
        switch(rtype)
        {
            case rHourly:
                // Convert an hourly recurrence to a minutely one
                rrule->setRecurrenceType(RecurrenceRule::rMinutely);
                rrule->setFrequency(rrule->frequency() * 60);
            // fall through to rMinutely
            case rMinutely:
            case rDaily:
            case rWeekly:
            case rMonthlyDay:
            case rMonthlyPos:
            case rYearlyPos:
                if(!convert)
                    ++rr;    // remove all rules except the first
                break;
            case rOther:
                if(dailyType(rrule))
                {
                    // it's a daily rule with BYDAYS
                    if(!convert)
                        ++rr;    // remove all rules except the first
                }
                break;
            case rYearlyDay:
            {
                // Ensure that the yearly day number is 60 (i.e. Feb 29th/Mar 1st)
                if(convert)
                {
                    // This is the second rule.
                    // Ensure that it can be combined with the first one.
                    if(days[0] != 29
                            ||  rrule->frequency() != rrules[0]->frequency()
                            ||  rrule->startDt()   != rrules[0]->startDt())
                        break;
                }
                QValueList<int> ds = rrule->byYearDays();
                if(!ds.isEmpty()  &&  ds.first() == 60)
                {
                    ++convert;    // this rule needs to be converted
                    days[i] = 60;
                    stop = false;
                    break;
                }
                break;     // not day 60, so remove this rule
            }
            case rYearlyMonth:
            {
                QValueList<int> ds = rrule->byMonthDays();
                if(!ds.isEmpty())
                {
                    int day = ds.first();
                    if(convert)
                    {
                        // This is the second rule.
                        // Ensure that it can be combined with the first one.
                        if(day == days[0]  ||  day == -1 && days[0] == 60
                                ||  rrule->frequency() != rrules[0]->frequency()
                                ||  rrule->startDt()   != rrules[0]->startDt())
                            break;
                    }
                    if(ds.count() > 1)
                    {
                        ds.clear();   // remove all but the first day
                        ds.append(day);
                        rrule->setByMonthDays(ds);
                    }
                    if(day == -1)
                    {
                        // Last day of the month - only combine if it's February
                        QValueList<int> months = rrule->byMonths();
                        if(months.count() != 1  ||  months.first() != 2)
                            day = 0;
                    }
                    if(day == 29  ||  day == -1)
                    {
                        ++convert;    // this rule may need to be converted
                        days[i] = day;
                        stop = false;
                        break;
                    }
                }
                if(!convert)
                    ++rr;
                break;
            }
            default:
                break;
        }
        if(stop)
            break;
    }

    // Remove surplus rules
    for(;  rr != rrulelist.end();  ++rr)
    {
        removeRRule(*rr);
        delete *rr;
    }

    QDate end;
    int count;
    QValueList<int> months;
    if(convert == 2)
    {
        // There are two yearly recurrence rules to combine into a February 29th recurrence.
        // Combine the two recurrence rules into a single rYearlyMonth rule falling on Feb 29th.
        // Find the duration of the two RRULEs combined, using the shorter of the two if they differ.
        if(days[0] != 29)
        {
            // Swap the two rules so that the 29th rule is the first
            RecurrenceRule *rr = rrules[0];
            rrules[0] = rrules[1];    // the 29th rule
            rrules[1] = rr;
            int d = days[0];
            days[0] = days[1];
            days[1] = d;        // the non-29th day
        }
        // If February is included in the 29th rule, remove it to avoid duplication
        months = rrules[0]->byMonths();
        if(months.remove(2))
            rrules[0]->setByMonths(months);

        count = combineDurations(rrules[0], rrules[1], end);
        mFeb29Type = (days[1] == 60) ? FEB29_MAR1 : FEB29_FEB28;
    }
    else if(convert == 1  &&  days[0] == 60)
    {
        // There is a single 60th day of the year rule.
        // Convert it to a February 29th recurrence.
        count = duration();
        if(!count)
            end = endDate();
        mFeb29Type = FEB29_MAR1;
    }
    else
        return;

    // Create the new February 29th recurrence
    setNewRecurrenceType(RecurrenceRule::rYearly, frequency());
    RecurrenceRule *rrule = defaultRRule();
    months.append(2);
    rrule->setByMonths(months);
    QValueList<int> ds;
    ds.append(29);
    rrule->setByMonthDays(ds);
    if(count)
        setDuration(count);
    else
        setEndDate(end);
}