-rw-r--r-- | libkcal/recurrence.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/libkcal/recurrence.cpp b/libkcal/recurrence.cpp index 5181eaf..8a175c9 100644 --- a/libkcal/recurrence.cpp +++ b/libkcal/recurrence.cpp @@ -1,596 +1,602 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> Copyright (c) 2002 David Jarvie <software@astrojar.org.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <limits.h> #include <kdebug.h> #include <kglobal.h> #include <klocale.h> #include "incidence.h" #include "recurrence.h" using namespace KCal; Recurrence::Feb29Type Recurrence::mFeb29YearlyDefaultType = Recurrence::rMar1; Recurrence::Recurrence(Incidence *parent, int compatVersion) : recurs(rNone), // by default, it's not a recurring event rWeekStart(1), // default is Monday rDays(7), mFloats(parent ? parent->doesFloat() : false), mRecurReadOnly(false), mRecurExDatesCount(0), mFeb29YearlyType(mFeb29YearlyDefaultType), mCompatVersion(compatVersion ? compatVersion : INT_MAX), mCompatRecurs(rNone), mCompatDuration(0), mParent(parent) { rMonthDays.setAutoDelete( true ); rMonthPositions.setAutoDelete( true ); rYearNums.setAutoDelete( true ); } Recurrence::Recurrence(const Recurrence &r, Incidence *parent) : recurs(r.recurs), rWeekStart(r.rWeekStart), rDays(r.rDays.copy()), rFreq(r.rFreq), rDuration(r.rDuration), rEndDateTime(r.rEndDateTime), mRecurStart(r.mRecurStart), mFloats(r.mFloats), mRecurReadOnly(r.mRecurReadOnly), mRecurExDatesCount(r.mRecurExDatesCount), mFeb29YearlyType(r.mFeb29YearlyType), mCompatVersion(r.mCompatVersion), mCompatRecurs(r.mCompatRecurs), mCompatDuration(r.mCompatDuration), mParent(parent) { for (QPtrListIterator<rMonthPos> mp(r.rMonthPositions); mp.current(); ++mp) { rMonthPos *tmp = new rMonthPos; tmp->rPos = mp.current()->rPos; tmp->negative = mp.current()->negative; tmp->rDays = mp.current()->rDays.copy(); rMonthPositions.append(tmp); } for (QPtrListIterator<int> md(r.rMonthDays); md.current(); ++md) { int *tmp = new int; *tmp = *md.current(); rMonthDays.append(tmp); } for (QPtrListIterator<int> yn(r.rYearNums); yn.current(); ++yn) { int *tmp = new int; *tmp = *yn.current(); rYearNums.append(tmp); } rMonthDays.setAutoDelete( true ); rMonthPositions.setAutoDelete( true ); rYearNums.setAutoDelete( true ); } Recurrence::~Recurrence() { } bool Recurrence::operator==( const Recurrence& r2 ) const { // the following line is obvious if ( recurs == rNone && r2.recurs == rNone ) return true; // we need the above line, because two non recurring events may // differ in the other settings, because one (or both) // may be not initialized properly if ( recurs != r2.recurs || rFreq != r2.rFreq || rDuration != r2.rDuration || !rDuration && rEndDateTime != r2.rEndDateTime || mRecurStart != r2.mRecurStart || mFloats != r2.mFloats || mRecurReadOnly != r2.mRecurReadOnly || mRecurExDatesCount != r2.mRecurExDatesCount ) return false; // no need to compare mCompat* and mParent // OK to compare the pointers switch ( recurs ) { case rWeekly: return rDays == r2.rDays && rWeekStart == r2.rWeekStart; case rMonthlyPos: { QPtrList<rMonthPos> MonthPositions = rMonthPositions; QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions; if ( !MonthPositions.count() ) return false; if ( !MonthPositions2.count() ) return false; return MonthPositions.first()->rPos == MonthPositions2.first()->rPos; } case rMonthlyDay: { QPtrList<int> MonthDays = rMonthDays ; QPtrList<int> MonthDays2 = r2.rMonthDays ; if ( !MonthDays.count() ) return false; if ( !MonthDays2.count() ) return false; return *MonthDays.first() == *MonthDays2.first() ; } case rYearlyPos: { QPtrList<int> YearNums = rYearNums; QPtrList<int> YearNums2 = r2.rYearNums; if ( *YearNums.first() != *YearNums2.first() ) return false; QPtrList<rMonthPos> MonthPositions = rMonthPositions; QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions; if ( !MonthPositions.count() ) return false; if ( !MonthPositions2.count() ) return false; return MonthPositions.first()->rPos == MonthPositions2.first()->rPos; } case rYearlyMonth: { QPtrList<int> YearNums = rYearNums; QPtrList<int> YearNums2 = r2.rYearNums; return ( *YearNums.first() == *YearNums2.first() && mFeb29YearlyType == r2.mFeb29YearlyType); } case rYearlyDay: { QPtrList<int> YearNums = rYearNums; QPtrList<int> YearNums2 = r2.rYearNums; return ( *YearNums.first() == *YearNums2.first() ); } case rNone: case rMinutely: case rHourly: case rDaily: default: return true; } } /* bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2) { if ( l1.count() != l2.count() ) return false; int count = l1.count(); int i; for ( i = 0; i < count ; ++i ) { // if ( l1.at(i) != l2.at(i) ) return false; qDebug("compüare "); } return true; } */ QString Recurrence::recurrenceText() const { - QString recurText = i18n("No"); + QString recurText; if ( recurs == Recurrence::rMinutely ) recurText = i18n("minutely"); else if ( recurs == Recurrence::rHourly ) recurText = i18n("hourly"); else if ( recurs == Recurrence::rDaily ) recurText = i18n("daily"); else if ( recurs == Recurrence::rWeekly ) recurText = i18n("weekly"); else if ( recurs == Recurrence::rMonthlyPos ) recurText = i18n("monthly"); else if ( recurs == Recurrence::rMonthlyDay ) - recurText = i18n("day-monthly"); + recurText = i18n("monthly"); else if ( recurs == Recurrence::rYearlyMonth ) - recurText = i18n("month-yearly"); + recurText = i18n("yearly"); else if ( recurs == Recurrence::rYearlyDay ) recurText = i18n("day-yearly"); else if ( recurs == Recurrence::rYearlyPos ) recurText = i18n("position-yearly"); + if ( !recurText.isEmpty() ) { + if ( rFreq > 1 ){ + recurText = i18n("(%1) ").arg(rFreq ) + recurText; + } + } else + recurText = i18n("No"); return recurText; } void Recurrence::setCompatVersion(int version) { mCompatVersion = version ? version : INT_MAX; } ushort Recurrence::doesRecur() const { return recurs; } bool Recurrence::recursOnPure(const QDate &qd) const { switch(recurs) { case rMinutely: return recursSecondly(qd, rFreq*60); case rHourly: return recursSecondly(qd, rFreq*3600); case rDaily: return recursDaily(qd); case rWeekly: return recursWeekly(qd); case rMonthlyPos: case rMonthlyDay: return recursMonthly(qd); case rYearlyMonth: return recursYearlyByMonth(qd); case rYearlyDay: return recursYearlyByDay(qd); case rYearlyPos: return recursYearlyByPos(qd); default: return false; case rNone: return false; } // case return false; } bool Recurrence::recursAtPure(const QDateTime &dt) const { switch(recurs) { case rMinutely: return recursMinutelyAt(dt, rFreq); case rHourly: return recursMinutelyAt(dt, rFreq*60); default: if (dt.time() != mRecurStart.time()) return false; switch(recurs) { case rDaily: return recursDaily(dt.date()); case rWeekly: return recursWeekly(dt.date()); case rMonthlyPos: case rMonthlyDay: return recursMonthly(dt.date()); case rYearlyMonth: return recursYearlyByMonth(dt.date()); case rYearlyDay: return recursYearlyByDay(dt.date()); case rYearlyPos: return recursYearlyByPos(dt.date()); default: return false; case rNone: return false; } } // case return false; } QDate Recurrence::endDate() const { int count = 0; QDate end; if (recurs != rNone) { if (rDuration < 0) return QDate(); // infinite recurrence if (rDuration == 0) return rEndDateTime.date(); // The end date is determined by the recurrence count QDate dStart = mRecurStart.date(); switch (recurs) { case rMinutely: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60).date(); case rHourly: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600).date(); case rDaily: return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); case rWeekly: count = weeklyCalc(END_DATE_AND_COUNT, end); break; case rMonthlyPos: case rMonthlyDay: count = monthlyCalc(END_DATE_AND_COUNT, end); break; case rYearlyMonth: count = yearlyMonthCalc(END_DATE_AND_COUNT, end); break; case rYearlyDay: count = yearlyDayCalc(END_DATE_AND_COUNT, end); break; case rYearlyPos: count = yearlyPosCalc(END_DATE_AND_COUNT, end); break; default: // catch-all. Should never get here. kdDebug(5800) << "Control should never reach here in endDate()!" << endl; break; } } if (!count) return QDate(); // error - there is no recurrence return end; } QDateTime Recurrence::endDateTime() const { int count = 0; QDate end; if (recurs != rNone) { if (rDuration < 0) return QDateTime(); // infinite recurrence if (rDuration == 0) return rEndDateTime; // The end date is determined by the recurrence count QDate dStart = mRecurStart.date(); switch (recurs) { case rMinutely: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*60); case rHourly: return mRecurStart.addSecs((rDuration-1+mRecurExDatesCount)*rFreq*3600); case rDaily: return dStart.addDays((rDuration-1+mRecurExDatesCount)*rFreq); case rWeekly: count = weeklyCalc(END_DATE_AND_COUNT, end); break; case rMonthlyPos: case rMonthlyDay: count = monthlyCalc(END_DATE_AND_COUNT, end); break; case rYearlyMonth: count = yearlyMonthCalc(END_DATE_AND_COUNT, end); break; case rYearlyDay: count = yearlyDayCalc(END_DATE_AND_COUNT, end); break; case rYearlyPos: count = yearlyPosCalc(END_DATE_AND_COUNT, end); break; default: // catch-all. Should never get here. kdDebug(5800) << "Control should never reach here in endDate()!" << endl; break; } } if (!count) return QDateTime(); // error - there is no recurrence return QDateTime(end, mRecurStart.time()); } int Recurrence::durationTo(const QDate &date) const { QDate d = date; return recurCalc(COUNT_TO_DATE, d); } int Recurrence::durationTo(const QDateTime &datetime) const { QDateTime dt = datetime; return recurCalc(COUNT_TO_DATE, dt); } void Recurrence::unsetRecurs() { if (mRecurReadOnly) return; recurs = rNone; rMonthPositions.clear(); rMonthDays.clear(); rYearNums.clear(); } void Recurrence::setRecurStart(const QDateTime &start) { mRecurStart = start; mFloats = false; switch (recurs) { case rMinutely: case rHourly: break; case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: default: rEndDateTime.setTime(start.time()); break; } } void Recurrence::setRecurStart(const QDate &start) { mRecurStart.setDate(start); mRecurStart.setTime(QTime(0,0,0)); switch (recurs) { case rMinutely: case rHourly: break; case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: default: mFloats = true; break; } } void Recurrence::setFloats(bool f) { switch (recurs) { case rDaily: case rWeekly: case rMonthlyPos: case rMonthlyDay: case rYearlyMonth: case rYearlyDay: case rYearlyPos: break; case rMinutely: case rHourly: default: return; // can't set sub-daily to floating } mFloats = f; if (f) { mRecurStart.setTime(QTime(0,0,0)); rEndDateTime.setTime(QTime(0,0,0)); } } int Recurrence::frequency() const { return rFreq; } int Recurrence::duration() const { return rDuration; } void Recurrence::setDuration(int _rDuration) { if (mRecurReadOnly) return; if (_rDuration > 0) { rDuration = _rDuration; // Compatibility mode is only needed when reading the calendar in ICalFormatImpl, // so explicitly setting the duration means no backwards compatibility is needed. mCompatDuration = 0; } } QString Recurrence::endDateStr(bool shortfmt) const { return KGlobal::locale()->formatDate(rEndDateTime.date(),shortfmt); } const QBitArray &Recurrence::days() const { return rDays; } const QPtrList<Recurrence::rMonthPos> &Recurrence::monthPositions() const { return rMonthPositions; } const QPtrList<Recurrence::rMonthPos> &Recurrence::yearMonthPositions() const { return rMonthPositions; } const QPtrList<int> &Recurrence::monthDays() const { return rMonthDays; } void Recurrence::setMinutely(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rMinutely, _rFreq, _rDuration); } void Recurrence::setMinutely(int _rFreq, const QDateTime &_rEndDateTime) { if (mRecurReadOnly) return; rEndDateTime = _rEndDateTime; setDailySub(rMinutely, _rFreq, 0); } void Recurrence::setHourly(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rHourly, _rFreq, _rDuration); } void Recurrence::setHourly(int _rFreq, const QDateTime &_rEndDateTime) { if (mRecurReadOnly) return; rEndDateTime = _rEndDateTime; setDailySub(rHourly, _rFreq, 0); } void Recurrence::setDaily(int _rFreq, int _rDuration) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; setDailySub(rDaily, _rFreq, _rDuration); } void Recurrence::setDaily(int _rFreq, const QDate &_rEndDate) { if (mRecurReadOnly) return; rEndDateTime.setDate(_rEndDate); rEndDateTime.setTime(mRecurStart.time()); setDailySub(rDaily, _rFreq, 0); } void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, int _rDuration, int _rWeekStart) { if (mRecurReadOnly || _rDuration == 0 || _rDuration < -1) return; recurs = rWeekly; rFreq = _rFreq; rDays = _rDays; rWeekStart = _rWeekStart; rDuration = _rDuration; if (mCompatVersion < 310 && _rDuration > 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. mCompatDuration = _rDuration; int weeks = ((mCompatDuration-1+mRecurExDatesCount)*7) + (7 - mRecurStart.date().dayOfWeek()); QDate end(mRecurStart.date().addDays(weeks * rFreq)); rDuration = INT_MAX; // ensure that weeklyCalc() does its job correctly rDuration = weeklyCalc(COUNT_TO_DATE, end); } else { mCompatDuration = 0; } rMonthPositions.clear(); rMonthDays.clear(); if (mParent) mParent->updated(); } void Recurrence::setWeekly(int _rFreq, const QBitArray &_rDays, const QDate &_rEndDate, int _rWeekStart) { if (mRecurReadOnly) return; recurs = rWeekly; rFreq = _rFreq; |