summaryrefslogtreecommitdiffabout
path: root/libkcal/recurrence.cpp
Unidiff
Diffstat (limited to 'libkcal/recurrence.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/recurrence.cpp56
1 files changed, 44 insertions, 12 deletions
diff --git a/libkcal/recurrence.cpp b/libkcal/recurrence.cpp
index dd74e10..e84f672 100644
--- a/libkcal/recurrence.cpp
+++ b/libkcal/recurrence.cpp
@@ -1,264 +1,296 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 1998 Preston Brown 3 Copyright (c) 1998 Preston Brown
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2002 David Jarvie <software@astrojar.org.uk> 5 Copyright (c) 2002 David Jarvie <software@astrojar.org.uk>
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public 8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This library is distributed in the hope that it will be useful, 12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details. 15 Library General Public License for more details.
16 16
17 You should have received a copy of the GNU Library General Public License 17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to 18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#include <limits.h> 23#include <limits.h>
24 24
25#include <kdebug.h> 25#include <kdebug.h>
26#include <kglobal.h> 26#include <kglobal.h>
27#include <klocale.h> 27#include <klocale.h>
28 28
29#include "incidence.h" 29#include "incidence.h"
30 30
31#include "recurrence.h" 31#include "recurrence.h"
32 32
33using namespace KCal; 33using namespace KCal;
34 34
35Recurrence::Feb29Type Recurrence::mFeb29YearlyDefaultType = Recurrence::rMar1; 35Recurrence::Feb29Type Recurrence::mFeb29YearlyDefaultType = Recurrence::rMar1;
36 36
37 37
38Recurrence::Recurrence(Incidence *parent, int compatVersion) 38Recurrence::Recurrence(Incidence *parent, int compatVersion)
39: recurs(rNone), // by default, it's not a recurring event 39: recurs(rNone), // by default, it's not a recurring event
40 rWeekStart(1), // default is Monday 40 rWeekStart(1), // default is Monday
41 rDays(7), 41 rDays(7),
42 mFloats(parent ? parent->doesFloat() : false), 42 mFloats(parent ? parent->doesFloat() : false),
43 mRecurReadOnly(false), 43 mRecurReadOnly(false),
44 mRecurExDatesCount(0), 44 mRecurExDatesCount(0),
45 mFeb29YearlyType(mFeb29YearlyDefaultType), 45 mFeb29YearlyType(mFeb29YearlyDefaultType),
46 mCompatVersion(compatVersion ? compatVersion : INT_MAX), 46 mCompatVersion(compatVersion ? compatVersion : INT_MAX),
47 mCompatRecurs(rNone), 47 mCompatRecurs(rNone),
48 mCompatDuration(0), 48 mCompatDuration(0),
49 mParent(parent) 49 mParent(parent)
50{ 50{
51 rMonthDays.setAutoDelete( true ); 51 rMonthDays.setAutoDelete( true );
52 rMonthPositions.setAutoDelete( true ); 52 rMonthPositions.setAutoDelete( true );
53 rYearNums.setAutoDelete( true ); 53 rYearNums.setAutoDelete( true );
54} 54}
55 55
56Recurrence::Recurrence(const Recurrence &r, Incidence *parent) 56Recurrence::Recurrence(const Recurrence &r, Incidence *parent)
57: recurs(r.recurs), 57: recurs(r.recurs),
58 rWeekStart(r.rWeekStart), 58 rWeekStart(r.rWeekStart),
59 rDays(r.rDays.copy()), 59 rDays(r.rDays.copy()),
60 rFreq(r.rFreq), 60 rFreq(r.rFreq),
61 rDuration(r.rDuration), 61 rDuration(r.rDuration),
62 rEndDateTime(r.rEndDateTime), 62 rEndDateTime(r.rEndDateTime),
63 mRecurStart(r.mRecurStart), 63 mRecurStart(r.mRecurStart),
64 mFloats(r.mFloats), 64 mFloats(r.mFloats),
65 mRecurReadOnly(r.mRecurReadOnly), 65 mRecurReadOnly(r.mRecurReadOnly),
66 mRecurExDatesCount(r.mRecurExDatesCount), 66 mRecurExDatesCount(r.mRecurExDatesCount),
67 mFeb29YearlyType(r.mFeb29YearlyType), 67 mFeb29YearlyType(r.mFeb29YearlyType),
68 mCompatVersion(r.mCompatVersion), 68 mCompatVersion(r.mCompatVersion),
69 mCompatRecurs(r.mCompatRecurs), 69 mCompatRecurs(r.mCompatRecurs),
70 mCompatDuration(r.mCompatDuration), 70 mCompatDuration(r.mCompatDuration),
71 mParent(parent) 71 mParent(parent)
72{ 72{
73 for (QPtrListIterator<rMonthPos> mp(r.rMonthPositions); mp.current(); ++mp) { 73 for (QPtrListIterator<rMonthPos> mp(r.rMonthPositions); mp.current(); ++mp) {
74 rMonthPos *tmp = new rMonthPos; 74 rMonthPos *tmp = new rMonthPos;
75 tmp->rPos = mp.current()->rPos; 75 tmp->rPos = mp.current()->rPos;
76 tmp->negative = mp.current()->negative; 76 tmp->negative = mp.current()->negative;
77 tmp->rDays = mp.current()->rDays.copy(); 77 tmp->rDays = mp.current()->rDays.copy();
78 rMonthPositions.append(tmp); 78 rMonthPositions.append(tmp);
79 } 79 }
80 for (QPtrListIterator<int> md(r.rMonthDays); md.current(); ++md) { 80 for (QPtrListIterator<int> md(r.rMonthDays); md.current(); ++md) {
81 int *tmp = new int; 81 int *tmp = new int;
82 *tmp = *md.current(); 82 *tmp = *md.current();
83 rMonthDays.append(tmp); 83 rMonthDays.append(tmp);
84 } 84 }
85 for (QPtrListIterator<int> yn(r.rYearNums); yn.current(); ++yn) { 85 for (QPtrListIterator<int> yn(r.rYearNums); yn.current(); ++yn) {
86 int *tmp = new int; 86 int *tmp = new int;
87 *tmp = *yn.current(); 87 *tmp = *yn.current();
88 rYearNums.append(tmp); 88 rYearNums.append(tmp);
89 } 89 }
90 rMonthDays.setAutoDelete( true ); 90 rMonthDays.setAutoDelete( true );
91 rMonthPositions.setAutoDelete( true ); 91 rMonthPositions.setAutoDelete( true );
92 rYearNums.setAutoDelete( true ); 92 rYearNums.setAutoDelete( true );
93} 93}
94 94
95Recurrence::~Recurrence() 95Recurrence::~Recurrence()
96{ 96{
97} 97}
98 98
99 99
100bool Recurrence::operator==( const Recurrence& r2 ) const 100bool Recurrence::operator==( const Recurrence& r2 ) const
101{ 101{
102 102
103 // the following line is obvious 103 // the following line is obvious
104 if ( recurs == rNone && r2.recurs == rNone ) 104 if ( recurs == rNone && r2.recurs == rNone )
105 return true; 105 return true;
106 // we need the above line, because two non recurring events may 106 // we need the above line, because two non recurring events may
107 // differ in the other settings, because one (or both) 107 // differ in the other settings, because one (or both)
108 // may be not initialized properly 108 // may be not initialized properly
109
109 if ( recurs != r2.recurs 110 if ( recurs != r2.recurs
110 || rFreq != r2.rFreq 111 || rFreq != r2.rFreq
111 || rDuration != r2.rDuration 112 || rDuration != r2.rDuration
112 || !rDuration && rEndDateTime != r2.rEndDateTime 113 || !rDuration && rEndDateTime != r2.rEndDateTime
113 || mRecurStart != r2.mRecurStart 114 || mRecurStart != r2.mRecurStart
114 || mFloats != r2.mFloats 115 || mFloats != r2.mFloats
115 || mRecurReadOnly != r2.mRecurReadOnly 116 || mRecurReadOnly != r2.mRecurReadOnly
116 || mRecurExDatesCount != r2.mRecurExDatesCount ) 117 || mRecurExDatesCount != r2.mRecurExDatesCount )
117 return false; 118 return false;
118 // no need to compare mCompat* and mParent 119 // no need to compare mCompat* and mParent
119 // OK to compare the pointers 120 // OK to compare the pointers
120 switch ( recurs ) 121 switch ( recurs )
121 { 122 {
122 case rWeekly: 123 case rWeekly:
123 return rDays == r2.rDays 124 return rDays == r2.rDays
124 && rWeekStart == r2.rWeekStart; 125 && rWeekStart == r2.rWeekStart;
125 case rMonthlyPos: 126 case rMonthlyPos: {
126 return rMonthPositions.count() == r2.rMonthPositions.count(); 127 QPtrList<rMonthPos> MonthPositions = rMonthPositions;
127 case rMonthlyDay: 128 QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions;
128 return rMonthDays.count() == r2.rMonthDays.count(); 129 if ( !MonthPositions.count() )
129 case rYearlyPos: 130 return false;
130 return rYearNums.count() == r2.rYearNums.count() 131 if ( !MonthPositions2.count() )
131 && rMonthPositions.count() == r2.rMonthPositions.count(); 132 return false;
132 case rYearlyMonth: 133 return MonthPositions.first()->rPos == MonthPositions2.first()->rPos;
133 return rYearNums.count() == r2.rYearNums.count() 134 }
134 && mFeb29YearlyType == r2.mFeb29YearlyType; 135 case rMonthlyDay: {
135 case rYearlyDay: 136 QPtrList<int> MonthDays = rMonthDays ;
136 return rYearNums == r2.rYearNums; 137 QPtrList<int> MonthDays2 = r2.rMonthDays ;
138 if ( !MonthDays.count() )
139 return false;
140 if ( !MonthDays2.count() )
141 return false;
142 return *MonthDays.first() == *MonthDays2.first() ;
143 }
144 case rYearlyPos: {
145
146 QPtrList<int> YearNums = rYearNums;
147 QPtrList<int> YearNums2 = r2.rYearNums;
148 if ( *YearNums.first() != *YearNums2.first() )
149 return false;
150 QPtrList<rMonthPos> MonthPositions = rMonthPositions;
151 QPtrList<rMonthPos> MonthPositions2 = r2.rMonthPositions;
152 if ( !MonthPositions.count() )
153 return false;
154 if ( !MonthPositions2.count() )
155 return false;
156 return MonthPositions.first()->rPos == MonthPositions2.first()->rPos;
157
158 }
159 case rYearlyMonth: {
160 QPtrList<int> YearNums = rYearNums;
161 QPtrList<int> YearNums2 = r2.rYearNums;
162 return ( *YearNums.first() == *YearNums2.first() && mFeb29YearlyType == r2.mFeb29YearlyType);
163 }
164 case rYearlyDay: {
165 QPtrList<int> YearNums = rYearNums;
166 QPtrList<int> YearNums2 = r2.rYearNums;
167 return ( *YearNums.first() == *YearNums2.first() );
168 }
137 case rNone: 169 case rNone:
138 case rMinutely: 170 case rMinutely:
139 case rHourly: 171 case rHourly:
140 case rDaily: 172 case rDaily:
141 default: 173 default:
142 return true; 174 return true;
143 } 175 }
144} 176}
145/* 177/*
146bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2) 178bool Recurrence::compareLists( const QPtrList<int> &l1 ,const QPtrList<int> &l2)
147{ 179{
148 if ( l1.count() != l2.count() ) 180 if ( l1.count() != l2.count() )
149 return false; 181 return false;
150 int count = l1.count(); 182 int count = l1.count();
151 int i; 183 int i;
152 for ( i = 0; i < count ; ++i ) { 184 for ( i = 0; i < count ; ++i ) {
153 // if ( l1.at(i) != l2.at(i) ) 185 // if ( l1.at(i) != l2.at(i) )
154 return false; 186 return false;
155 qDebug("compüare "); 187 qDebug("compüare ");
156 } 188 }
157 return true; 189 return true;
158} 190}
159*/ 191*/
160QString Recurrence::recurrenceText() const 192QString Recurrence::recurrenceText() const
161{ 193{
162 QString recurText = i18n("No"); 194 QString recurText = i18n("No");
163 if ( recurs == Recurrence::rMinutely ) 195 if ( recurs == Recurrence::rMinutely )
164 recurText = i18n("minutely"); 196 recurText = i18n("minutely");
165 else if ( recurs == Recurrence::rHourly ) 197 else if ( recurs == Recurrence::rHourly )
166 recurText = i18n("hourly"); 198 recurText = i18n("hourly");
167 else if ( recurs == Recurrence::rDaily ) 199 else if ( recurs == Recurrence::rDaily )
168 recurText = i18n("daily"); 200 recurText = i18n("daily");
169 else if ( recurs == Recurrence::rWeekly ) 201 else if ( recurs == Recurrence::rWeekly )
170 recurText = i18n("weekly"); 202 recurText = i18n("weekly");
171 else if ( recurs == Recurrence::rMonthlyPos ) 203 else if ( recurs == Recurrence::rMonthlyPos )
172 recurText = i18n("monthly"); 204 recurText = i18n("monthly");
173 else if ( recurs == Recurrence::rMonthlyDay ) 205 else if ( recurs == Recurrence::rMonthlyDay )
174 recurText = i18n("day-monthly"); 206 recurText = i18n("day-monthly");
175 else if ( recurs == Recurrence::rYearlyMonth ) 207 else if ( recurs == Recurrence::rYearlyMonth )
176 recurText = i18n("month-yearly"); 208 recurText = i18n("month-yearly");
177 else if ( recurs == Recurrence::rYearlyDay ) 209 else if ( recurs == Recurrence::rYearlyDay )
178 recurText = i18n("day-yearly"); 210 recurText = i18n("day-yearly");
179 else if ( recurs == Recurrence::rYearlyPos ) 211 else if ( recurs == Recurrence::rYearlyPos )
180 recurText = i18n("position-yearly"); 212 recurText = i18n("position-yearly");
181 return recurText; 213 return recurText;
182} 214}
183 215
184void Recurrence::setCompatVersion(int version) 216void Recurrence::setCompatVersion(int version)
185{ 217{
186 mCompatVersion = version ? version : INT_MAX; 218 mCompatVersion = version ? version : INT_MAX;
187} 219}
188 220
189ushort Recurrence::doesRecur() const 221ushort Recurrence::doesRecur() const
190{ 222{
191 return recurs; 223 return recurs;
192} 224}
193 225
194bool Recurrence::recursOnPure(const QDate &qd) const 226bool Recurrence::recursOnPure(const QDate &qd) const
195{ 227{
196 switch(recurs) { 228 switch(recurs) {
197 case rMinutely: 229 case rMinutely:
198 return recursSecondly(qd, rFreq*60); 230 return recursSecondly(qd, rFreq*60);
199 case rHourly: 231 case rHourly:
200 return recursSecondly(qd, rFreq*3600); 232 return recursSecondly(qd, rFreq*3600);
201 case rDaily: 233 case rDaily:
202 return recursDaily(qd); 234 return recursDaily(qd);
203 case rWeekly: 235 case rWeekly:
204 return recursWeekly(qd); 236 return recursWeekly(qd);
205 case rMonthlyPos: 237 case rMonthlyPos:
206 case rMonthlyDay: 238 case rMonthlyDay:
207 return recursMonthly(qd); 239 return recursMonthly(qd);
208 case rYearlyMonth: 240 case rYearlyMonth:
209 return recursYearlyByMonth(qd); 241 return recursYearlyByMonth(qd);
210 case rYearlyDay: 242 case rYearlyDay:
211 return recursYearlyByDay(qd); 243 return recursYearlyByDay(qd);
212 case rYearlyPos: 244 case rYearlyPos:
213 return recursYearlyByPos(qd); 245 return recursYearlyByPos(qd);
214 default: 246 default:
215 return false; 247 return false;
216 case rNone: 248 case rNone:
217 return false; 249 return false;
218 } // case 250 } // case
219 return false; 251 return false;
220} 252}
221 253
222bool Recurrence::recursAtPure(const QDateTime &dt) const 254bool Recurrence::recursAtPure(const QDateTime &dt) const
223{ 255{
224 switch(recurs) { 256 switch(recurs) {
225 case rMinutely: 257 case rMinutely:
226 return recursMinutelyAt(dt, rFreq); 258 return recursMinutelyAt(dt, rFreq);
227 case rHourly: 259 case rHourly:
228 return recursMinutelyAt(dt, rFreq*60); 260 return recursMinutelyAt(dt, rFreq*60);
229 default: 261 default:
230 if (dt.time() != mRecurStart.time()) 262 if (dt.time() != mRecurStart.time())
231 return false; 263 return false;
232 switch(recurs) { 264 switch(recurs) {
233 case rDaily: 265 case rDaily:
234 return recursDaily(dt.date()); 266 return recursDaily(dt.date());
235 case rWeekly: 267 case rWeekly:
236 return recursWeekly(dt.date()); 268 return recursWeekly(dt.date());
237 case rMonthlyPos: 269 case rMonthlyPos:
238 case rMonthlyDay: 270 case rMonthlyDay:
239 return recursMonthly(dt.date()); 271 return recursMonthly(dt.date());
240 case rYearlyMonth: 272 case rYearlyMonth:
241 return recursYearlyByMonth(dt.date()); 273 return recursYearlyByMonth(dt.date());
242 case rYearlyDay: 274 case rYearlyDay:
243 return recursYearlyByDay(dt.date()); 275 return recursYearlyByDay(dt.date());
244 case rYearlyPos: 276 case rYearlyPos:
245 return recursYearlyByPos(dt.date()); 277 return recursYearlyByPos(dt.date());
246 default: 278 default:
247 return false; 279 return false;
248 case rNone: 280 case rNone:
249 return false; 281 return false;
250 } 282 }
251 } // case 283 } // case
252 return false; 284 return false;
253} 285}
254 286
255QDate Recurrence::endDate() const 287QDate Recurrence::endDate() const
256{ 288{
257 int count = 0; 289 int count = 0;
258 QDate end; 290 QDate end;
259 if (recurs != rNone) { 291 if (recurs != rNone) {
260 if (rDuration < 0) 292 if (rDuration < 0)
261 return QDate(); // infinite recurrence 293 return QDate(); // infinite recurrence
262 if (rDuration == 0) 294 if (rDuration == 0)
263 return rEndDateTime.date(); 295 return rEndDateTime.date();
264 296