コード例 #1
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::addMonthlyPos( short pos, const QBitArray &days )
{
  // Allow 53 for yearly!
  if ( d->mRecurReadOnly || pos > 53 || pos < -53 ) {
    return;
  }

  RecurrenceRule *rrule = defaultRRule( false );
  if ( !rrule ) {
    return;
  }
  bool changed = false;
  QList<RecurrenceRule::WDayPos> positions = rrule->byDays();

  for ( int i = 0; i < 7; ++i ) {
    if ( days.testBit( i ) ) {
      RecurrenceRule::WDayPos p( pos, i + 1 );
      if ( !positions.contains( p ) ) {
        changed = true;
        positions.append( p );
      }
    }
  }
  if ( changed ) {
    rrule->setByDays( positions );
    updated();
  }
}
コード例 #2
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::setWeekly( int freq, int weekStart )
{
  RecurrenceRule *rrule = setNewRecurrenceType( RecurrenceRule::rWeekly, freq );
  if ( !rrule ) {
    return;
  }
  rrule->setWeekStart( weekStart );
  updated();
}
コード例 #3
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>();
  }
}
コード例 #4
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// Emulate the old behaviour. Make this methods just an interface to the
// first rrule
void Recurrence::setFrequency( int freq )
{
  if ( d->mRecurReadOnly || freq <= 0 ) {
    return;
  }

  RecurrenceRule *rrule = defaultRRule( true );
  if ( rrule ) {
    rrule->setFrequency( freq );
  }
  updated();
}
コード例 #5
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::setEndDateTime( const KDateTime &dateTime )
{
  if ( d->mRecurReadOnly ) {
    return;
  }
  RecurrenceRule *rrule = defaultRRule( true );
  if ( !rrule ) {
    return;
  }
  rrule->setEndDt( dateTime );
  updated();
}
コード例 #6
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::setDuration( int duration )
{
  if ( d->mRecurReadOnly ) {
    return;
  }

  RecurrenceRule *rrule = defaultRRule( true );
  if ( !rrule ) {
    return;
  }
  rrule->setDuration( duration );
  updated();
}
コード例 #7
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// Daynumber within year
void Recurrence::addYearlyDay( int day )
{
  RecurrenceRule *rrule = defaultRRule( false ); // It must already exist!
  if ( !rrule ) {
    return;
  }

  QList<int> days = rrule->byYearDays();
  if ( !days.contains( day ) ) {
    days << day;
    rrule->setByYearDays( days );
    updated();
  }
}
コード例 #8
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
RecurrenceRule *Recurrence::defaultRRule( bool create ) const
{
  if ( d->mRRules.isEmpty() ) {
    if ( !create || d->mRecurReadOnly ) {
      return 0;
    }
    RecurrenceRule *rrule = new RecurrenceRule();
    rrule->setStartDt( startDateTime() );
    const_cast<KCalCore::Recurrence*>( this )->addRRule( rrule );
    return rrule;
  } else {
    return d->mRRules[0];
  }
}
コード例 #9
0
ファイル: compat.cpp プロジェクト: pvuorela/kcalcore
void CompatPre35::fixRecurrence( const Incidence::Ptr &incidence )
{
  Recurrence *recurrence = incidence->recurrence();
  if ( recurrence ) {
    KDateTime start( incidence->dtStart() );
    // kde < 3.5 only had one rrule, so no need to loop over all RRULEs.
    RecurrenceRule *r = recurrence->defaultRRule();
    if ( r && !r->dateMatchesRules( start ) ) {
      recurrence->addExDateTime( start );
    }
  }

  // Call base class method now that everything else is done
  Compat::fixRecurrence( incidence );
}
コード例 #10
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// Emulate the old behavior
QBitArray Recurrence::days() const
{
  QBitArray days( 7 );
  days.fill( 0 );
  RecurrenceRule *rrule = defaultRRuleConst();
  if ( rrule ) {
    QList<RecurrenceRule::WDayPos> bydays = rrule->byDays();
    for ( int i = 0; i < bydays.size(); ++i ) {
      if ( bydays.at( i ).pos() == 0 ) {
        days.setBit( bydays.at( i ).day() - 1 );
      }
    }
  }
  return days;
}
コード例 #11
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
Recurrence::Recurrence( const Recurrence &r )
  : RecurrenceRule::RuleObserver(),
    d( new KCalCore::Recurrence::Private( *r.d ) )
{
  int i, end;
  for ( i = 0, end = r.d->mRRules.count();  i < end;  ++i ) {
    RecurrenceRule *rule = new RecurrenceRule( *r.d->mRRules[i] );
    d->mRRules.append( rule );
    rule->addObserver( this );
  }
  for ( i = 0, end = r.d->mExRules.count();  i < end;  ++i ) {
    RecurrenceRule *rule = new RecurrenceRule( *r.d->mExRules[i] );
    d->mExRules.append( rule );
    rule->addObserver( this );
  }
}
コード例 #12
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
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;
}
コード例 #13
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// month part of date within year
void Recurrence::addYearlyMonth( short month )
{
  if ( d->mRecurReadOnly || month < 1 || month > 12 ) {
    return;
  }

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

  QList<int> months = rrule->byMonths();
  if ( !months.contains( month ) ) {
    months << month;
    rrule->setByMonths( months );
    updated();
  }
}
コード例 #14
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();
  }
}
コード例 #15
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
void Recurrence::addMonthlyPos( short pos, ushort day )
{
  // Allow 53 for yearly!
  if ( d->mRecurReadOnly || pos > 53 || pos < -53 ) {
    return;
  }

  RecurrenceRule *rrule = defaultRRule( false );
  if ( !rrule ) {
    return;
  }
  QList<RecurrenceRule::WDayPos> positions = rrule->byDays();

  RecurrenceRule::WDayPos p( pos, day );
  if ( !positions.contains( p ) ) {
    positions.append( p );
    rrule->setByDays( positions );
    updated();
  }
}
コード例 #16
0
ファイル: compat.cpp プロジェクト: pvuorela/kcalcore
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 );
    }
  }
}
コード例 #17
0
ファイル: karecurrence.cpp プロジェクト: serghei/kde3-kdepim
/******************************************************************************
* 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);
}
コード例 #18
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
int Recurrence::duration() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->duration() : 0;
}
コード例 #19
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
int Recurrence::durationTo( const KDateTime &datetime ) const
{
  // Emulate old behavior: This is just an interface to the first rule!
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->durationTo( datetime ) : 0;
}
コード例 #20
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
int Recurrence::frequency() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->frequency() : 0;
}
コード例 #21
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
QList<int> Recurrence::yearMonths() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->byMonths() : QList<int>();
}
コード例 #22
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
// Emulate the old behavior
QList<RecurrenceRule::WDayPos> Recurrence::monthPositions() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->byDays() : QList<RecurrenceRule::WDayPos>();
}
コード例 #23
0
ファイル: recurrence.cpp プロジェクト: pvuorela/kcalcore
int Recurrence::weekStart() const
{
  RecurrenceRule *rrule = defaultRRuleConst();
  return rrule ? rrule->weekStart() : 1;
}
コード例 #24
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);
}