-rw-r--r-- | library/datebookdb.cpp | 5 |
1 files changed, 0 insertions, 5 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp index 188d8e1..e4ec2bf 100644 --- a/library/datebookdb.cpp +++ b/library/datebookdb.cpp | |||
@@ -1,801 +1,796 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #include <qasciidict.h> | 21 | #include <qasciidict.h> |
22 | #include <qfile.h> | ||
23 | #include <qmessagebox.h> | 22 | #include <qmessagebox.h> |
24 | #include <qstring.h> | ||
25 | #include <qtextcodec.h> | ||
26 | #include <qtextstream.h> | ||
27 | #include <qtl.h> | 23 | #include <qtl.h> |
28 | 24 | ||
29 | #include <qpe/alarmserver.h> | 25 | #include <qpe/alarmserver.h> |
30 | #include <qpe/global.h> | 26 | #include <qpe/global.h> |
31 | #include "datebookdb.h" | 27 | #include "datebookdb.h" |
32 | #include <qpe/stringutil.h> | 28 | #include <qpe/stringutil.h> |
33 | #include <qpe/timeconversion.h> | ||
34 | 29 | ||
35 | #include <errno.h> | 30 | #include <errno.h> |
36 | #include <stdlib.h> | 31 | #include <stdlib.h> |
37 | 32 | ||
38 | 33 | ||
39 | class DateBookDBPrivate | 34 | class DateBookDBPrivate |
40 | { | 35 | { |
41 | public: | 36 | public: |
42 | bool clean; // indcate whether we need to write to disk... | 37 | bool clean; // indcate whether we need to write to disk... |
43 | }; | 38 | }; |
44 | 39 | ||
45 | 40 | ||
46 | // Helper functions | 41 | // Helper functions |
47 | 42 | ||
48 | static QString dateBookJournalFile() | 43 | static QString dateBookJournalFile() |
49 | { | 44 | { |
50 | QString str = getenv("HOME"); | 45 | QString str = getenv("HOME"); |
51 | return QString( str +"/.caljournal" ); | 46 | return QString( str +"/.caljournal" ); |
52 | } | 47 | } |
53 | 48 | ||
54 | static QString dateBookFilename() | 49 | static QString dateBookFilename() |
55 | { | 50 | { |
56 | return Global::applicationFileName("datebook","datebook.xml"); | 51 | return Global::applicationFileName("datebook","datebook.xml"); |
57 | } | 52 | } |
58 | 53 | ||
59 | /* Calculating the next event of a recuring event is actually | 54 | /* Calculating the next event of a recuring event is actually |
60 | computationally inexpensive, esp. compared to checking each day | 55 | computationally inexpensive, esp. compared to checking each day |
61 | individually. There are bad worse cases for say the 29th of | 56 | individually. There are bad worse cases for say the 29th of |
62 | february or the 31st of some other months. However | 57 | february or the 31st of some other months. However |
63 | these are still bounded */ | 58 | these are still bounded */ |
64 | bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) | 59 | bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) |
65 | { | 60 | { |
66 | // easy checks, first are we too far in the future or too far in the past? | 61 | // easy checks, first are we too far in the future or too far in the past? |
67 | QDate tmpDate; | 62 | QDate tmpDate; |
68 | int freq = e.repeatPattern().frequency; | 63 | int freq = e.repeatPattern().frequency; |
69 | int diff, diff2, a; | 64 | int diff, diff2, a; |
70 | int iday, imonth, iyear; | 65 | int iday, imonth, iyear; |
71 | int dayOfWeek = 0; | 66 | int dayOfWeek = 0; |
72 | int firstOfWeek = 0; | 67 | int firstOfWeek = 0; |
73 | int weekOfMonth; | 68 | int weekOfMonth; |
74 | 69 | ||
75 | 70 | ||
76 | if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from) | 71 | if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from) |
77 | return FALSE; | 72 | return FALSE; |
78 | 73 | ||
79 | if (e.start() >= from) { | 74 | if (e.start() >= from) { |
80 | next = e.start(); | 75 | next = e.start(); |
81 | return TRUE; | 76 | return TRUE; |
82 | } | 77 | } |
83 | 78 | ||
84 | switch ( e.repeatPattern().type ) { | 79 | switch ( e.repeatPattern().type ) { |
85 | case Event::Weekly: | 80 | case Event::Weekly: |
86 | /* weekly is just daily by 7 */ | 81 | /* weekly is just daily by 7 */ |
87 | /* first convert the repeatPattern.Days() mask to the next | 82 | /* first convert the repeatPattern.Days() mask to the next |
88 | day of week valid after from */ | 83 | day of week valid after from */ |
89 | dayOfWeek = from.dayOfWeek(); | 84 | dayOfWeek = from.dayOfWeek(); |
90 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ | 85 | dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ |
91 | 86 | ||
92 | /* this is done in case freq > 1 and from in week not | 87 | /* this is done in case freq > 1 and from in week not |
93 | for this round */ | 88 | for this round */ |
94 | // firstOfWeek = 0; this is already done at decl. | 89 | // firstOfWeek = 0; this is already done at decl. |
95 | while(!((1 << firstOfWeek) & e.repeatPattern().days)) | 90 | while(!((1 << firstOfWeek) & e.repeatPattern().days)) |
96 | firstOfWeek++; | 91 | firstOfWeek++; |
97 | 92 | ||
98 | 93 | ||
99 | 94 | ||
100 | /* there is at least one 'day', or there would be no event */ | 95 | /* there is at least one 'day', or there would be no event */ |
101 | while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) | 96 | while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) |
102 | dayOfWeek++; | 97 | dayOfWeek++; |
103 | 98 | ||
104 | 99 | ||
105 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ | 100 | dayOfWeek = dayOfWeek % 7; /* the actual day of week */ |
106 | dayOfWeek -= e.start().date().dayOfWeek() -1; | 101 | dayOfWeek -= e.start().date().dayOfWeek() -1; |
107 | 102 | ||
108 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ | 103 | firstOfWeek = firstOfWeek % 7; /* the actual first of week */ |
109 | firstOfWeek -= e.start().date().dayOfWeek() -1; | 104 | firstOfWeek -= e.start().date().dayOfWeek() -1; |
110 | 105 | ||
111 | // dayOfWeek may be negitive now | 106 | // dayOfWeek may be negitive now |
112 | // day of week is number of days to add to start day | 107 | // day of week is number of days to add to start day |
113 | 108 | ||
114 | freq *= 7; | 109 | freq *= 7; |
115 | // FALL-THROUGH !!!!! | 110 | // FALL-THROUGH !!!!! |
116 | case Event::Daily: | 111 | case Event::Daily: |
117 | // the add is for the possible fall through from weekly */ | 112 | // the add is for the possible fall through from weekly */ |
118 | if(e.start().date().addDays(dayOfWeek) > from) { | 113 | if(e.start().date().addDays(dayOfWeek) > from) { |
119 | /* first week exception */ | 114 | /* first week exception */ |
120 | next = QDateTime(e.start().date().addDays(dayOfWeek), | 115 | next = QDateTime(e.start().date().addDays(dayOfWeek), |
121 | e.start().time()); | 116 | e.start().time()); |
122 | if ((next.date() > e.repeatPattern().endDate()) | 117 | if ((next.date() > e.repeatPattern().endDate()) |
123 | && e.repeatPattern().hasEndDate) | 118 | && e.repeatPattern().hasEndDate) |
124 | return FALSE; | 119 | return FALSE; |
125 | return TRUE; | 120 | return TRUE; |
126 | } | 121 | } |
127 | /* if from is middle of a non-week */ | 122 | /* if from is middle of a non-week */ |
128 | 123 | ||
129 | diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; | 124 | diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; |
130 | diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; | 125 | diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; |
131 | 126 | ||
132 | if(diff != 0) | 127 | if(diff != 0) |
133 | diff = freq - diff; | 128 | diff = freq - diff; |
134 | if(diff2 != 0) | 129 | if(diff2 != 0) |
135 | diff2 = freq - diff2; | 130 | diff2 = freq - diff2; |
136 | diff = QMIN(diff, diff2); | 131 | diff = QMIN(diff, diff2); |
137 | 132 | ||
138 | next = QDateTime(from.addDays(diff), e.start().time()); | 133 | next = QDateTime(from.addDays(diff), e.start().time()); |
139 | if ( (next.date() > e.repeatPattern().endDate()) | 134 | if ( (next.date() > e.repeatPattern().endDate()) |
140 | && e.repeatPattern().hasEndDate ) | 135 | && e.repeatPattern().hasEndDate ) |
141 | return FALSE; | 136 | return FALSE; |
142 | return TRUE; | 137 | return TRUE; |
143 | case Event::MonthlyDay: | 138 | case Event::MonthlyDay: |
144 | iday = from.day(); | 139 | iday = from.day(); |
145 | iyear = from.year(); | 140 | iyear = from.year(); |
146 | imonth = from.month(); | 141 | imonth = from.month(); |
147 | /* find equivelent day of month for this month */ | 142 | /* find equivelent day of month for this month */ |
148 | dayOfWeek = e.start().date().dayOfWeek(); | 143 | dayOfWeek = e.start().date().dayOfWeek(); |
149 | weekOfMonth = (e.start().date().day() - 1) / 7; | 144 | weekOfMonth = (e.start().date().day() - 1) / 7; |
150 | 145 | ||
151 | /* work out when the next valid month is */ | 146 | /* work out when the next valid month is */ |
152 | a = from.year() - e.start().date().year(); | 147 | a = from.year() - e.start().date().year(); |
153 | a *= 12; | 148 | a *= 12; |
154 | a = a + (imonth - e.start().date().month()); | 149 | a = a + (imonth - e.start().date().month()); |
155 | /* a is e.start()monthsFrom(from); */ | 150 | /* a is e.start()monthsFrom(from); */ |
156 | if(a % freq) { | 151 | if(a % freq) { |
157 | a = freq - (a % freq); | 152 | a = freq - (a % freq); |
158 | imonth = from.month() + a; | 153 | imonth = from.month() + a; |
159 | if (imonth > 12) { | 154 | if (imonth > 12) { |
160 | imonth--; | 155 | imonth--; |
161 | iyear += imonth / 12; | 156 | iyear += imonth / 12; |
162 | imonth = imonth % 12; | 157 | imonth = imonth % 12; |
163 | imonth++; | 158 | imonth++; |
164 | } | 159 | } |
165 | } | 160 | } |
166 | /* imonth is now the first month after or on | 161 | /* imonth is now the first month after or on |
167 | from that matches the frequency given */ | 162 | from that matches the frequency given */ |
168 | 163 | ||
169 | /* find for this month */ | 164 | /* find for this month */ |
170 | tmpDate = QDate( iyear, imonth, 1 ); | 165 | tmpDate = QDate( iyear, imonth, 1 ); |
171 | 166 | ||
172 | iday = 1; | 167 | iday = 1; |
173 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 168 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
174 | iday += 7 * weekOfMonth; | 169 | iday += 7 * weekOfMonth; |
175 | while (iday > tmpDate.daysInMonth()) { | 170 | while (iday > tmpDate.daysInMonth()) { |
176 | imonth += freq; | 171 | imonth += freq; |
177 | if (imonth > 12) { | 172 | if (imonth > 12) { |
178 | imonth--; | 173 | imonth--; |
179 | iyear += imonth / 12; | 174 | iyear += imonth / 12; |
180 | imonth = imonth % 12; | 175 | imonth = imonth % 12; |
181 | imonth++; | 176 | imonth++; |
182 | } | 177 | } |
183 | tmpDate = QDate( iyear, imonth, 1 ); | 178 | tmpDate = QDate( iyear, imonth, 1 ); |
184 | /* these loops could go for a while, check end case now */ | 179 | /* these loops could go for a while, check end case now */ |
185 | if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 180 | if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
186 | return FALSE; | 181 | return FALSE; |
187 | iday = 1; | 182 | iday = 1; |
188 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 183 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
189 | iday += 7 * weekOfMonth; | 184 | iday += 7 * weekOfMonth; |
190 | } | 185 | } |
191 | tmpDate = QDate(iyear, imonth, iday); | 186 | tmpDate = QDate(iyear, imonth, iday); |
192 | 187 | ||
193 | if (tmpDate >= from) { | 188 | if (tmpDate >= from) { |
194 | next = QDateTime(tmpDate, e.start().time()); | 189 | next = QDateTime(tmpDate, e.start().time()); |
195 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 190 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
196 | return FALSE; | 191 | return FALSE; |
197 | return TRUE; | 192 | return TRUE; |
198 | } | 193 | } |
199 | 194 | ||
200 | /* need to find the next iteration */ | 195 | /* need to find the next iteration */ |
201 | do { | 196 | do { |
202 | imonth += freq; | 197 | imonth += freq; |
203 | if (imonth > 12) { | 198 | if (imonth > 12) { |
204 | imonth--; | 199 | imonth--; |
205 | iyear += imonth / 12; | 200 | iyear += imonth / 12; |
206 | imonth = imonth % 12; | 201 | imonth = imonth % 12; |
207 | imonth++; | 202 | imonth++; |
208 | } | 203 | } |
209 | tmpDate = QDate( iyear, imonth, 1 ); | 204 | tmpDate = QDate( iyear, imonth, 1 ); |
210 | /* these loops could go for a while, check end case now */ | 205 | /* these loops could go for a while, check end case now */ |
211 | if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 206 | if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
212 | return FALSE; | 207 | return FALSE; |
213 | iday = 1; | 208 | iday = 1; |
214 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; | 209 | iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; |
215 | iday += 7 * weekOfMonth; | 210 | iday += 7 * weekOfMonth; |
216 | } while (iday > tmpDate.daysInMonth()); | 211 | } while (iday > tmpDate.daysInMonth()); |
217 | tmpDate = QDate(iyear, imonth, iday); | 212 | tmpDate = QDate(iyear, imonth, iday); |
218 | 213 | ||
219 | next = QDateTime(tmpDate, e.start().time()); | 214 | next = QDateTime(tmpDate, e.start().time()); |
220 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 215 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
221 | return FALSE; | 216 | return FALSE; |
222 | return TRUE; | 217 | return TRUE; |
223 | case Event::MonthlyDate: | 218 | case Event::MonthlyDate: |
224 | iday = e.start().date().day(); | 219 | iday = e.start().date().day(); |
225 | iyear = from.year(); | 220 | iyear = from.year(); |
226 | imonth = from.month(); | 221 | imonth = from.month(); |
227 | 222 | ||
228 | a = from.year() - e.start().date().year(); | 223 | a = from.year() - e.start().date().year(); |
229 | a *= 12; | 224 | a *= 12; |
230 | a = a + (imonth - e.start().date().month()); | 225 | a = a + (imonth - e.start().date().month()); |
231 | /* a is e.start()monthsFrom(from); */ | 226 | /* a is e.start()monthsFrom(from); */ |
232 | if(a % freq) { | 227 | if(a % freq) { |
233 | a = freq - (a % freq); | 228 | a = freq - (a % freq); |
234 | imonth = from.month() + a; | 229 | imonth = from.month() + a; |
235 | if (imonth > 12) { | 230 | if (imonth > 12) { |
236 | imonth--; | 231 | imonth--; |
237 | iyear += imonth / 12; | 232 | iyear += imonth / 12; |
238 | imonth = imonth % 12; | 233 | imonth = imonth % 12; |
239 | imonth++; | 234 | imonth++; |
240 | } | 235 | } |
241 | } | 236 | } |
242 | /* imonth is now the first month after or on | 237 | /* imonth is now the first month after or on |
243 | from that matches the frequencey given */ | 238 | from that matches the frequencey given */ |
244 | 239 | ||
245 | /* this could go for a while, worse case, 4*12 iterations, probably */ | 240 | /* this could go for a while, worse case, 4*12 iterations, probably */ |
246 | while(!QDate::isValid(iyear, imonth, iday) ) { | 241 | while(!QDate::isValid(iyear, imonth, iday) ) { |
247 | imonth += freq; | 242 | imonth += freq; |
248 | if (imonth > 12) { | 243 | if (imonth > 12) { |
249 | imonth--; | 244 | imonth--; |
250 | iyear += imonth / 12; | 245 | iyear += imonth / 12; |
251 | imonth = imonth % 12; | 246 | imonth = imonth % 12; |
252 | imonth++; | 247 | imonth++; |
253 | } | 248 | } |
254 | /* these loops could go for a while, check end case now */ | 249 | /* these loops could go for a while, check end case now */ |
255 | if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 250 | if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
256 | return FALSE; | 251 | return FALSE; |
257 | } | 252 | } |
258 | 253 | ||
259 | if(QDate(iyear, imonth, iday) >= from) { | 254 | if(QDate(iyear, imonth, iday) >= from) { |
260 | /* done */ | 255 | /* done */ |
261 | next = QDateTime(QDate(iyear, imonth, iday), | 256 | next = QDateTime(QDate(iyear, imonth, iday), |
262 | e.start().time()); | 257 | e.start().time()); |
263 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 258 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
264 | return FALSE; | 259 | return FALSE; |
265 | return TRUE; | 260 | return TRUE; |
266 | } | 261 | } |
267 | 262 | ||
268 | /* ok, need to cycle */ | 263 | /* ok, need to cycle */ |
269 | imonth += freq; | 264 | imonth += freq; |
270 | imonth--; | 265 | imonth--; |
271 | iyear += imonth / 12; | 266 | iyear += imonth / 12; |
272 | imonth = imonth % 12; | 267 | imonth = imonth % 12; |
273 | imonth++; | 268 | imonth++; |
274 | 269 | ||
275 | while(!QDate::isValid(iyear, imonth, iday) ) { | 270 | while(!QDate::isValid(iyear, imonth, iday) ) { |
276 | imonth += freq; | 271 | imonth += freq; |
277 | imonth--; | 272 | imonth--; |
278 | iyear += imonth / 12; | 273 | iyear += imonth / 12; |
279 | imonth = imonth % 12; | 274 | imonth = imonth % 12; |
280 | imonth++; | 275 | imonth++; |
281 | if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 276 | if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
282 | return FALSE; | 277 | return FALSE; |
283 | } | 278 | } |
284 | 279 | ||
285 | next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); | 280 | next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); |
286 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 281 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
287 | return FALSE; | 282 | return FALSE; |
288 | return TRUE; | 283 | return TRUE; |
289 | case Event::Yearly: | 284 | case Event::Yearly: |
290 | iday = e.start().date().day(); | 285 | iday = e.start().date().day(); |
291 | imonth = e.start().date().month(); | 286 | imonth = e.start().date().month(); |
292 | iyear = from.year(); // after all, we want to start in this year | 287 | iyear = from.year(); // after all, we want to start in this year |
293 | 288 | ||
294 | diff = 1; | 289 | diff = 1; |
295 | if(imonth == 2 && iday > 28) { | 290 | if(imonth == 2 && iday > 28) { |
296 | /* leap year, and it counts, calculate actual frequency */ | 291 | /* leap year, and it counts, calculate actual frequency */ |
297 | if(freq % 4) | 292 | if(freq % 4) |
298 | if (freq % 2) | 293 | if (freq % 2) |
299 | freq = freq * 4; | 294 | freq = freq * 4; |
300 | else | 295 | else |
301 | freq = freq * 2; | 296 | freq = freq * 2; |
302 | /* else divides by 4 already, leave freq alone */ | 297 | /* else divides by 4 already, leave freq alone */ |
303 | diff = 4; | 298 | diff = 4; |
304 | } | 299 | } |
305 | 300 | ||
306 | a = from.year() - e.start().date().year(); | 301 | a = from.year() - e.start().date().year(); |
307 | if(a % freq) { | 302 | if(a % freq) { |
308 | a = freq - (a % freq); | 303 | a = freq - (a % freq); |
309 | iyear = iyear + a; | 304 | iyear = iyear + a; |
310 | } | 305 | } |
311 | 306 | ||
312 | /* under the assumption we won't hit one of the special not-leap years twice */ | 307 | /* under the assumption we won't hit one of the special not-leap years twice */ |
313 | if(!QDate::isValid(iyear, imonth, iday)) { | 308 | if(!QDate::isValid(iyear, imonth, iday)) { |
314 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 309 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
315 | iyear += freq; | 310 | iyear += freq; |
316 | } | 311 | } |
317 | 312 | ||
318 | if(QDate(iyear, imonth, iday) >= from) { | 313 | if(QDate(iyear, imonth, iday) >= from) { |
319 | next = QDateTime(QDate(iyear, imonth, iday), | 314 | next = QDateTime(QDate(iyear, imonth, iday), |
320 | e.start().time()); | 315 | e.start().time()); |
321 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 316 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
322 | return FALSE; | 317 | return FALSE; |
323 | return TRUE; | 318 | return TRUE; |
324 | } | 319 | } |
325 | /* iyear == from.year(), need to advance again */ | 320 | /* iyear == from.year(), need to advance again */ |
326 | iyear += freq; | 321 | iyear += freq; |
327 | /* under the assumption we won't hit one of the special not-leap years twice */ | 322 | /* under the assumption we won't hit one of the special not-leap years twice */ |
328 | if(!QDate::isValid(iyear, imonth, iday)) { | 323 | if(!QDate::isValid(iyear, imonth, iday)) { |
329 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ | 324 | /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ |
330 | iyear += freq; | 325 | iyear += freq; |
331 | } | 326 | } |
332 | 327 | ||
333 | next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); | 328 | next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); |
334 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) | 329 | if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) |
335 | return FALSE; | 330 | return FALSE; |
336 | return TRUE; | 331 | return TRUE; |
337 | default: | 332 | default: |
338 | return FALSE; | 333 | return FALSE; |
339 | } | 334 | } |
340 | } | 335 | } |
341 | 336 | ||
342 | static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) | 337 | static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) |
343 | { | 338 | { |
344 | QDateTime now = QDateTime::currentDateTime(); | 339 | QDateTime now = QDateTime::currentDateTime(); |
345 | if ( ev.hasRepeat() ) { | 340 | if ( ev.hasRepeat() ) { |
346 | QDateTime ralarm; | 341 | QDateTime ralarm; |
347 | if (nextOccurance(ev, now.date(), ralarm)) { | 342 | if (nextOccurance(ev, now.date(), ralarm)) { |
348 | ralarm = ralarm.addSecs(-ev.alarmTime()*60); | 343 | ralarm = ralarm.addSecs(-ev.alarmTime()*60); |
349 | if ( ralarm > now ) { | 344 | if ( ralarm > now ) { |
350 | when = ralarm; | 345 | when = ralarm; |
351 | warn = ev.alarmTime(); | 346 | warn = ev.alarmTime(); |
352 | } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { | 347 | } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { |
353 | ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); | 348 | ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); |
354 | if ( ralarm > now ) { | 349 | if ( ralarm > now ) { |
355 | when = ralarm; | 350 | when = ralarm; |
356 | warn = ev.alarmTime(); | 351 | warn = ev.alarmTime(); |
357 | } | 352 | } |
358 | } | 353 | } |
359 | } | 354 | } |
360 | } else { | 355 | } else { |
361 | warn = ev.alarmTime(); | 356 | warn = ev.alarmTime(); |
362 | when = ev.start().addSecs( -ev.alarmTime()*60 ); | 357 | when = ev.start().addSecs( -ev.alarmTime()*60 ); |
363 | } | 358 | } |
364 | return when > now; | 359 | return when > now; |
365 | } | 360 | } |
366 | 361 | ||
367 | static void addEventAlarm( const Event &ev ) | 362 | static void addEventAlarm( const Event &ev ) |
368 | { | 363 | { |
369 | QDateTime when; | 364 | QDateTime when; |
370 | int warn; | 365 | int warn; |
371 | if ( nextAlarm(ev,when,warn) ) | 366 | if ( nextAlarm(ev,when,warn) ) |
372 | AlarmServer::addAlarm( when, | 367 | AlarmServer::addAlarm( when, |
373 | "QPE/Application/datebook", | 368 | "QPE/Application/datebook", |
374 | "alarm(QDateTime,int)", warn ); | 369 | "alarm(QDateTime,int)", warn ); |
375 | } | 370 | } |
376 | 371 | ||
377 | static void delEventAlarm( const Event &ev ) | 372 | static void delEventAlarm( const Event &ev ) |
378 | { | 373 | { |
379 | QDateTime when; | 374 | QDateTime when; |
380 | int warn; | 375 | int warn; |
381 | if ( nextAlarm(ev,when,warn) ) | 376 | if ( nextAlarm(ev,when,warn) ) |
382 | AlarmServer::deleteAlarm( when, | 377 | AlarmServer::deleteAlarm( when, |
383 | "QPE/Application/datebook", | 378 | "QPE/Application/datebook", |
384 | "alarm(QDateTime,int)", warn ); | 379 | "alarm(QDateTime,int)", warn ); |
385 | } | 380 | } |
386 | 381 | ||
387 | 382 | ||
388 | DateBookDB::DateBookDB() | 383 | DateBookDB::DateBookDB() |
389 | { | 384 | { |
390 | init(); | 385 | init(); |
391 | } | 386 | } |
392 | 387 | ||
393 | DateBookDB::~DateBookDB() | 388 | DateBookDB::~DateBookDB() |
394 | { | 389 | { |
395 | save(); | 390 | save(); |
396 | eventList.clear(); | 391 | eventList.clear(); |
397 | repeatEvents.clear(); | 392 | repeatEvents.clear(); |
398 | } | 393 | } |
399 | 394 | ||
400 | 395 | ||
401 | //#### Why is this code duplicated in getEffectiveEvents ????? | 396 | //#### Why is this code duplicated in getEffectiveEvents ????? |
402 | //#### Addendum. Don't use this function, lets faze it out if we can. | 397 | //#### Addendum. Don't use this function, lets faze it out if we can. |
403 | QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) | 398 | QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) |
404 | { | 399 | { |
405 | QValueList<Event> tmpList; | 400 | QValueList<Event> tmpList; |
406 | tmpList = getNonRepeatingEvents( from, to ); | 401 | tmpList = getNonRepeatingEvents( from, to ); |
407 | 402 | ||
408 | // check for repeating events... | 403 | // check for repeating events... |
409 | for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); | 404 | for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); |
410 | it != repeatEvents.end(); ++it) { | 405 | it != repeatEvents.end(); ++it) { |
411 | QDate itDate = from; | 406 | QDate itDate = from; |
412 | QDateTime due; | 407 | QDateTime due; |
413 | 408 | ||
414 | /* create a false end date, to short circuit on hard | 409 | /* create a false end date, to short circuit on hard |
415 | MonthlyDay recurences */ | 410 | MonthlyDay recurences */ |
416 | Event dummy_event = *it; | 411 | Event dummy_event = *it; |
417 | Event::RepeatPattern r = dummy_event.repeatPattern(); | 412 | Event::RepeatPattern r = dummy_event.repeatPattern(); |
418 | if ( !r.hasEndDate || r.endDate() > to ) { | 413 | if ( !r.hasEndDate || r.endDate() > to ) { |
419 | r.setEndDate( to ); | 414 | r.setEndDate( to ); |
420 | r.hasEndDate = TRUE; | 415 | r.hasEndDate = TRUE; |
421 | } | 416 | } |
422 | dummy_event.setRepeat(TRUE, r); | 417 | dummy_event.setRepeat(TRUE, r); |
423 | 418 | ||
424 | while (nextOccurance(dummy_event, itDate, due)) { | 419 | while (nextOccurance(dummy_event, itDate, due)) { |
425 | if (due.date() > to) | 420 | if (due.date() > to) |
426 | break; | 421 | break; |
427 | Event newEvent = *it; | 422 | Event newEvent = *it; |
428 | newEvent.setStart(due); | 423 | newEvent.setStart(due); |
429 | newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); | 424 | newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); |
430 | 425 | ||
431 | tmpList.append(newEvent); | 426 | tmpList.append(newEvent); |
432 | itDate = due.date().addDays(1); /* the next event */ | 427 | itDate = due.date().addDays(1); /* the next event */ |
433 | } | 428 | } |
434 | } | 429 | } |
435 | qHeapSort(tmpList); | 430 | qHeapSort(tmpList); |
436 | return tmpList; | 431 | return tmpList; |
437 | } | 432 | } |
438 | 433 | ||
439 | QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) | 434 | QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) |
440 | { | 435 | { |
441 | QValueList<Event> day = getEvents(start.date(),start.date()); | 436 | QValueList<Event> day = getEvents(start.date(),start.date()); |
442 | 437 | ||
443 | QValueListConstIterator<Event> it; | 438 | QValueListConstIterator<Event> it; |
444 | QDateTime dtTmp; | 439 | QDateTime dtTmp; |
445 | QValueList<Event> tmpList; | 440 | QValueList<Event> tmpList; |
446 | for (it = day.begin(); it != day.end(); ++it ) { | 441 | for (it = day.begin(); it != day.end(); ++it ) { |
447 | dtTmp = (*it).start(TRUE); | 442 | dtTmp = (*it).start(TRUE); |
448 | if ( dtTmp == start ) | 443 | if ( dtTmp == start ) |
449 | tmpList.append( *it ); | 444 | tmpList.append( *it ); |
450 | } | 445 | } |
451 | return tmpList; | 446 | return tmpList; |
452 | } | 447 | } |
453 | 448 | ||
454 | //#### Why is this code duplicated in getEvents ????? | 449 | //#### Why is this code duplicated in getEvents ????? |
455 | 450 | ||
456 | QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, | 451 | QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, |
457 | const QDate &to ) | 452 | const QDate &to ) |
458 | { | 453 | { |
459 | QValueList<EffectiveEvent> tmpList; | 454 | QValueList<EffectiveEvent> tmpList; |
460 | QValueListIterator<Event> it; | 455 | QValueListIterator<Event> it; |
461 | 456 | ||
462 | EffectiveEvent effEv; | 457 | EffectiveEvent effEv; |
463 | QDateTime dtTmp, | 458 | QDateTime dtTmp, |
464 | dtEnd; | 459 | dtEnd; |
465 | 460 | ||
466 | for (it = eventList.begin(); it != eventList.end(); ++it ) { | 461 | for (it = eventList.begin(); it != eventList.end(); ++it ) { |
467 | if (!(*it).isValidUid()) | 462 | if (!(*it).isValidUid()) |
468 | (*it).assignUid(); // FIXME: Hack to restore cleared uids | 463 | (*it).assignUid(); // FIXME: Hack to restore cleared uids |
469 | 464 | ||
470 | dtTmp = (*it).start(TRUE); | 465 | dtTmp = (*it).start(TRUE); |
471 | dtEnd = (*it).end(TRUE); | 466 | dtEnd = (*it).end(TRUE); |
472 | 467 | ||
473 | if ( dtTmp.date() >= from && dtTmp.date() <= to ) { | 468 | if ( dtTmp.date() >= from && dtTmp.date() <= to ) { |
474 | Event tmpEv = *it; | 469 | Event tmpEv = *it; |
475 | effEv.setEvent(tmpEv); | 470 | effEv.setEvent(tmpEv); |
476 | effEv.setDate( dtTmp.date() ); | 471 | effEv.setDate( dtTmp.date() ); |
477 | effEv.setStart( dtTmp.time() ); | 472 | effEv.setStart( dtTmp.time() ); |
478 | if ( dtTmp.date() != dtEnd.date() ) | 473 | if ( dtTmp.date() != dtEnd.date() ) |
479 | effEv.setEnd( QTime(23, 59, 0) ); | 474 | effEv.setEnd( QTime(23, 59, 0) ); |
480 | else | 475 | else |
481 | effEv.setEnd( dtEnd.time() ); | 476 | effEv.setEnd( dtEnd.time() ); |
482 | tmpList.append( effEv ); | 477 | tmpList.append( effEv ); |
483 | } | 478 | } |
484 | // we must also check for end date information... | 479 | // we must also check for end date information... |
485 | if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { | 480 | if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { |
486 | QDateTime dt = dtTmp.addDays( 1 ); | 481 | QDateTime dt = dtTmp.addDays( 1 ); |
487 | dt.setTime( QTime(0, 0, 0) ); | 482 | dt.setTime( QTime(0, 0, 0) ); |
488 | QDateTime dtStop; | 483 | QDateTime dtStop; |
489 | if ( dtEnd > to ) { | 484 | if ( dtEnd > to ) { |
490 | dtStop = to; | 485 | dtStop = to; |
491 | } else | 486 | } else |
492 | dtStop = dtEnd; | 487 | dtStop = dtEnd; |
493 | while ( dt <= dtStop ) { | 488 | while ( dt <= dtStop ) { |
494 | Event tmpEv = *it; | 489 | Event tmpEv = *it; |
495 | effEv.setEvent( tmpEv ); | 490 | effEv.setEvent( tmpEv ); |
496 | effEv.setDate( dt.date() ); | 491 | effEv.setDate( dt.date() ); |
497 | if ( dt >= from ) { | 492 | if ( dt >= from ) { |
498 | effEv.setStart( QTime(0, 0, 0) ); | 493 | effEv.setStart( QTime(0, 0, 0) ); |
499 | if ( dt.date() == dtEnd.date() ) | 494 | if ( dt.date() == dtEnd.date() ) |
500 | effEv.setEnd( dtEnd.time() ); | 495 | effEv.setEnd( dtEnd.time() ); |
501 | else | 496 | else |
502 | effEv.setEnd( QTime(23, 59, 59) ); | 497 | effEv.setEnd( QTime(23, 59, 59) ); |
503 | tmpList.append( effEv ); | 498 | tmpList.append( effEv ); |
504 | } | 499 | } |
505 | dt = dt.addDays( 1 ); | 500 | dt = dt.addDays( 1 ); |
506 | } | 501 | } |
507 | } | 502 | } |
508 | } | 503 | } |
509 | // check for repeating events... | 504 | // check for repeating events... |
510 | QDateTime repeat; | 505 | QDateTime repeat; |
511 | for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { | 506 | for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { |
512 | if (!(*it).isValidUid()) | 507 | if (!(*it).isValidUid()) |
513 | (*it).assignUid(); // FIXME: Hack to restore cleared uids | 508 | (*it).assignUid(); // FIXME: Hack to restore cleared uids |
514 | 509 | ||
515 | /* create a false end date, to short circuit on hard | 510 | /* create a false end date, to short circuit on hard |
516 | MonthlyDay recurences */ | 511 | MonthlyDay recurences */ |
517 | Event dummy_event = *it; | 512 | Event dummy_event = *it; |
518 | int duration = (*it).start().date().daysTo( (*it).end().date() ); | 513 | int duration = (*it).start().date().daysTo( (*it).end().date() ); |
519 | QDate itDate = from.addDays(-duration); | 514 | QDate itDate = from.addDays(-duration); |
520 | 515 | ||
521 | Event::RepeatPattern r = dummy_event.repeatPattern(); | 516 | Event::RepeatPattern r = dummy_event.repeatPattern(); |
522 | if ( !r.hasEndDate || r.endDate() > to ) { | 517 | if ( !r.hasEndDate || r.endDate() > to ) { |
523 | r.setEndDate( to ); | 518 | r.setEndDate( to ); |
524 | r.hasEndDate = TRUE; | 519 | r.hasEndDate = TRUE; |
525 | } | 520 | } |
526 | dummy_event.setRepeat(TRUE, r); | 521 | dummy_event.setRepeat(TRUE, r); |
527 | 522 | ||
528 | while (nextOccurance(dummy_event, itDate, repeat)) { | 523 | while (nextOccurance(dummy_event, itDate, repeat)) { |
529 | if(repeat.date() > to) | 524 | if(repeat.date() > to) |
530 | break; | 525 | break; |
531 | effEv.setDate( repeat.date() ); | 526 | effEv.setDate( repeat.date() ); |
532 | if ((*it).type() == Event::AllDay) { | 527 | if ((*it).type() == Event::AllDay) { |
533 | effEv.setStart( QTime(0,0,0) ); | 528 | effEv.setStart( QTime(0,0,0) ); |
534 | effEv.setEnd( QTime(23,59,59) ); | 529 | effEv.setEnd( QTime(23,59,59) ); |
535 | } else { | 530 | } else { |
536 | /* we only occur by days, not hours/minutes/seconds. Hence | 531 | /* we only occur by days, not hours/minutes/seconds. Hence |
537 | the actual end and start times will be the same for | 532 | the actual end and start times will be the same for |
538 | every repeated event. For multi day events this is | 533 | every repeated event. For multi day events this is |
539 | fixed up later if on wronge day span */ | 534 | fixed up later if on wronge day span */ |
540 | effEv.setStart( (*it).start().time() ); | 535 | effEv.setStart( (*it).start().time() ); |
541 | effEv.setEnd( (*it).end().time() ); | 536 | effEv.setEnd( (*it).end().time() ); |
542 | } | 537 | } |
543 | if ( duration != 0 ) { | 538 | if ( duration != 0 ) { |
544 | // multi-day repeating events | 539 | // multi-day repeating events |
545 | QDate sub_it = QMAX( repeat.date(), from ); | 540 | QDate sub_it = QMAX( repeat.date(), from ); |
546 | QDate startDate = repeat.date(); | 541 | QDate startDate = repeat.date(); |
547 | QDate endDate = startDate.addDays( duration ); | 542 | QDate endDate = startDate.addDays( duration ); |
548 | 543 | ||
549 | while ( sub_it <= endDate && sub_it <= to ) { | 544 | while ( sub_it <= endDate && sub_it <= to ) { |
550 | EffectiveEvent tmpEffEv = effEv; | 545 | EffectiveEvent tmpEffEv = effEv; |
551 | Event tmpEv = *it; | 546 | Event tmpEv = *it; |
552 | tmpEffEv.setEvent( tmpEv ); | 547 | tmpEffEv.setEvent( tmpEv ); |
553 | 548 | ||
554 | if ( sub_it != startDate ) | 549 | if ( sub_it != startDate ) |
555 | tmpEffEv.setStart( QTime(0,0,0) ); | 550 | tmpEffEv.setStart( QTime(0,0,0) ); |
556 | if ( sub_it != endDate ) | 551 | if ( sub_it != endDate ) |
557 | tmpEffEv.setEnd( QTime(23,59,59) ); | 552 | tmpEffEv.setEnd( QTime(23,59,59) ); |
558 | tmpEffEv.setDate( sub_it ); | 553 | tmpEffEv.setDate( sub_it ); |
559 | tmpEffEv.setEffectiveDates( startDate, endDate ); | 554 | tmpEffEv.setEffectiveDates( startDate, endDate ); |
560 | tmpList.append( tmpEffEv ); | 555 | tmpList.append( tmpEffEv ); |
561 | sub_it = sub_it.addDays( 1 ); | 556 | sub_it = sub_it.addDays( 1 ); |
562 | } | 557 | } |
563 | itDate = endDate; | 558 | itDate = endDate; |
564 | } else { | 559 | } else { |
565 | Event tmpEv = *it; | 560 | Event tmpEv = *it; |
566 | effEv.setEvent( tmpEv ); | 561 | effEv.setEvent( tmpEv ); |
567 | tmpList.append( effEv ); | 562 | tmpList.append( effEv ); |
568 | itDate = repeat.date().addDays( 1 ); | 563 | itDate = repeat.date().addDays( 1 ); |
569 | } | 564 | } |
570 | } | 565 | } |
571 | } | 566 | } |
572 | 567 | ||
573 | qHeapSort( tmpList ); | 568 | qHeapSort( tmpList ); |
574 | return tmpList; | 569 | return tmpList; |
575 | } | 570 | } |
576 | 571 | ||
577 | QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) | 572 | QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) |
578 | { | 573 | { |
579 | QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); | 574 | QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); |
580 | QValueListConstIterator<EffectiveEvent> it; | 575 | QValueListConstIterator<EffectiveEvent> it; |
581 | QValueList<EffectiveEvent> tmpList; | 576 | QValueList<EffectiveEvent> tmpList; |
582 | QDateTime dtTmp; | 577 | QDateTime dtTmp; |
583 | 578 | ||
584 | for (it = day.begin(); it != day.end(); ++it ) { | 579 | for (it = day.begin(); it != day.end(); ++it ) { |
585 | dtTmp = QDateTime( (*it).date(), (*it).start() ); | 580 | dtTmp = QDateTime( (*it).date(), (*it).start() ); |
586 | // at the moment we don't have second granularity, be nice about that.. | 581 | // at the moment we don't have second granularity, be nice about that.. |
587 | if ( QABS(dt.secsTo(dtTmp)) < 60 ) | 582 | if ( QABS(dt.secsTo(dtTmp)) < 60 ) |
588 | tmpList.append( *it ); | 583 | tmpList.append( *it ); |
589 | } | 584 | } |
590 | return tmpList; | 585 | return tmpList; |
591 | } | 586 | } |
592 | 587 | ||
593 | void DateBookDB::addEvent( const Event &ev, bool doalarm ) | 588 | void DateBookDB::addEvent( const Event &ev, bool doalarm ) |
594 | { | 589 | { |
595 | // write to the journal... | 590 | // write to the journal... |
596 | saveJournalEntry( ev, ACTION_ADD, -1, false ); | 591 | saveJournalEntry( ev, ACTION_ADD, -1, false ); |
597 | addJFEvent( ev, doalarm ); | 592 | addJFEvent( ev, doalarm ); |
598 | d->clean = false; | 593 | d->clean = false; |
599 | } | 594 | } |
600 | 595 | ||
601 | void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) | 596 | void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) |
602 | { | 597 | { |
603 | if ( doalarm && ev.hasAlarm() ) | 598 | if ( doalarm && ev.hasAlarm() ) |
604 | addEventAlarm( ev ); | 599 | addEventAlarm( ev ); |
605 | if ( ev.hasRepeat() ) | 600 | if ( ev.hasRepeat() ) |
606 | repeatEvents.append( ev ); | 601 | repeatEvents.append( ev ); |
607 | else | 602 | else |
608 | eventList.append( ev ); | 603 | eventList.append( ev ); |
609 | } | 604 | } |
610 | 605 | ||
611 | void DateBookDB::editEvent( const Event &old, Event &editedEv ) | 606 | void DateBookDB::editEvent( const Event &old, Event &editedEv ) |
612 | { | 607 | { |
613 | int oldIndex=0; | 608 | int oldIndex=0; |
614 | bool oldHadRepeat = old.hasRepeat(); | 609 | bool oldHadRepeat = old.hasRepeat(); |
615 | Event orig; | 610 | Event orig; |
616 | 611 | ||
617 | // write to the journal... | 612 | // write to the journal... |
618 | if ( oldHadRepeat ) { | 613 | if ( oldHadRepeat ) { |
619 | if ( origRepeat( old, orig ) ) // should work always... | 614 | if ( origRepeat( old, orig ) ) // should work always... |
620 | oldIndex = repeatEvents.findIndex( orig ); | 615 | oldIndex = repeatEvents.findIndex( orig ); |
621 | } else | 616 | } else |
622 | oldIndex = eventList.findIndex( old ); | 617 | oldIndex = eventList.findIndex( old ); |
623 | saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); | 618 | saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); |
624 | 619 | ||
625 | // Delete old event | 620 | // Delete old event |
626 | if ( old.hasAlarm() ) | 621 | if ( old.hasAlarm() ) |
627 | delEventAlarm( old ); | 622 | delEventAlarm( old ); |
628 | if ( oldHadRepeat ) { | 623 | if ( oldHadRepeat ) { |
629 | if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and | 624 | if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and |
630 | // orig is initialized | 625 | // orig is initialized |
631 | // assumption, when someone edits a repeating event, they | 626 | // assumption, when someone edits a repeating event, they |
632 | // want to change them all, maybe not perfect, but it works | 627 | // want to change them all, maybe not perfect, but it works |
633 | // for the moment... | 628 | // for the moment... |
634 | repeatEvents.remove( orig ); | 629 | repeatEvents.remove( orig ); |
635 | } else | 630 | } else |
636 | removeRepeat( old ); | 631 | removeRepeat( old ); |
637 | } else { | 632 | } else { |
638 | QValueList<Event>::Iterator it = eventList.find( old ); | 633 | QValueList<Event>::Iterator it = eventList.find( old ); |
639 | if ( it != eventList.end() ) | 634 | if ( it != eventList.end() ) |
640 | eventList.remove( it ); | 635 | eventList.remove( it ); |
641 | } | 636 | } |
642 | 637 | ||
643 | // Add new event | 638 | // Add new event |
644 | if ( editedEv.hasAlarm() ) | 639 | if ( editedEv.hasAlarm() ) |
645 | addEventAlarm( editedEv ); | 640 | addEventAlarm( editedEv ); |
646 | if ( editedEv.hasRepeat() ) | 641 | if ( editedEv.hasRepeat() ) |
647 | repeatEvents.append( editedEv ); | 642 | repeatEvents.append( editedEv ); |
648 | else | 643 | else |
649 | eventList.append( editedEv ); | 644 | eventList.append( editedEv ); |
650 | 645 | ||
651 | d->clean = false; | 646 | d->clean = false; |
652 | } | 647 | } |
653 | 648 | ||
654 | void DateBookDB::removeEvent( const Event &ev ) | 649 | void DateBookDB::removeEvent( const Event &ev ) |
655 | { | 650 | { |
656 | // write to the journal... | 651 | // write to the journal... |
657 | saveJournalEntry( ev, ACTION_REMOVE, -1, false ); | 652 | saveJournalEntry( ev, ACTION_REMOVE, -1, false ); |
658 | removeJFEvent( ev ); | 653 | removeJFEvent( ev ); |
659 | d->clean = false; | 654 | d->clean = false; |
660 | } | 655 | } |
661 | 656 | ||
662 | void DateBookDB::removeJFEvent( const Event&ev ) | 657 | void DateBookDB::removeJFEvent( const Event&ev ) |
663 | { | 658 | { |
664 | if ( ev.hasAlarm() ) | 659 | if ( ev.hasAlarm() ) |
665 | delEventAlarm( ev ); | 660 | delEventAlarm( ev ); |
666 | if ( ev.hasRepeat() ) { | 661 | if ( ev.hasRepeat() ) { |
667 | removeRepeat( ev ); | 662 | removeRepeat( ev ); |
668 | } else { | 663 | } else { |
669 | QValueList<Event>::Iterator it = eventList.find( ev ); | 664 | QValueList<Event>::Iterator it = eventList.find( ev ); |
670 | if ( it != eventList.end() ) | 665 | if ( it != eventList.end() ) |
671 | eventList.remove( it ); | 666 | eventList.remove( it ); |
672 | } | 667 | } |
673 | } | 668 | } |
674 | 669 | ||
675 | // also handles journaling... | 670 | // also handles journaling... |
676 | void DateBookDB::loadFile( const QString &strFile ) | 671 | void DateBookDB::loadFile( const QString &strFile ) |
677 | { | 672 | { |
678 | 673 | ||
679 | QFile f( strFile ); | 674 | QFile f( strFile ); |
680 | if ( !f.open( IO_ReadOnly ) ) | 675 | if ( !f.open( IO_ReadOnly ) ) |
681 | return; | 676 | return; |
682 | 677 | ||
683 | enum Attribute { | 678 | enum Attribute { |
684 | FDescription = 0, | 679 | FDescription = 0, |
685 | FLocation, | 680 | FLocation, |
686 | FCategories, | 681 | FCategories, |
687 | FUid, | 682 | FUid, |
688 | FType, | 683 | FType, |
689 | FAlarm, | 684 | FAlarm, |
690 | FSound, | 685 | FSound, |
691 | FRType, | 686 | FRType, |
692 | FRWeekdays, | 687 | FRWeekdays, |
693 | FRPosition, | 688 | FRPosition, |
694 | FRFreq, | 689 | FRFreq, |
695 | FRHasEndDate, | 690 | FRHasEndDate, |
696 | FREndDate, | 691 | FREndDate, |
697 | FRStart, | 692 | FRStart, |
698 | FREnd, | 693 | FREnd, |
699 | FNote, | 694 | FNote, |
700 | FCreated, | 695 | FCreated, |
701 | FAction, | 696 | FAction, |
702 | FActionKey, | 697 | FActionKey, |
703 | FJournalOrigHadRepeat | 698 | FJournalOrigHadRepeat |
704 | }; | 699 | }; |
705 | 700 | ||
706 | QAsciiDict<int> dict( 97 ); | 701 | QAsciiDict<int> dict( 97 ); |
707 | dict.setAutoDelete( TRUE ); | 702 | dict.setAutoDelete( TRUE ); |
708 | dict.insert( "description", new int(FDescription) ); | 703 | dict.insert( "description", new int(FDescription) ); |
709 | dict.insert( "location", new int(FLocation) ); | 704 | dict.insert( "location", new int(FLocation) ); |
710 | dict.insert( "categories", new int(FCategories) ); | 705 | dict.insert( "categories", new int(FCategories) ); |
711 | dict.insert( "uid", new int(FUid) ); | 706 | dict.insert( "uid", new int(FUid) ); |
712 | dict.insert( "type", new int(FType) ); | 707 | dict.insert( "type", new int(FType) ); |
713 | dict.insert( "alarm", new int(FAlarm) ); | 708 | dict.insert( "alarm", new int(FAlarm) ); |
714 | dict.insert( "sound", new int(FSound) ); | 709 | dict.insert( "sound", new int(FSound) ); |
715 | dict.insert( "rtype", new int(FRType) ); | 710 | dict.insert( "rtype", new int(FRType) ); |
716 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 711 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
717 | dict.insert( "rposition", new int(FRPosition) ); | 712 | dict.insert( "rposition", new int(FRPosition) ); |
718 | dict.insert( "rfreq", new int(FRFreq) ); | 713 | dict.insert( "rfreq", new int(FRFreq) ); |
719 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 714 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
720 | dict.insert( "enddt", new int(FREndDate) ); | 715 | dict.insert( "enddt", new int(FREndDate) ); |
721 | dict.insert( "start", new int(FRStart) ); | 716 | dict.insert( "start", new int(FRStart) ); |
722 | dict.insert( "end", new int(FREnd) ); | 717 | dict.insert( "end", new int(FREnd) ); |
723 | dict.insert( "note", new int(FNote) ); | 718 | dict.insert( "note", new int(FNote) ); |
724 | dict.insert( "created", new int(FCreated) ); | 719 | dict.insert( "created", new int(FCreated) ); |
725 | dict.insert( "action", new int(FAction) ); | 720 | dict.insert( "action", new int(FAction) ); |
726 | dict.insert( "actionkey", new int(FActionKey) ); | 721 | dict.insert( "actionkey", new int(FActionKey) ); |
727 | dict.insert( "actionorig", new int (FJournalOrigHadRepeat) ); | 722 | dict.insert( "actionorig", new int (FJournalOrigHadRepeat) ); |
728 | 723 | ||
729 | 724 | ||
730 | QByteArray ba = f.readAll(); | 725 | QByteArray ba = f.readAll(); |
731 | char* dt = ba.data(); | 726 | char* dt = ba.data(); |
732 | int len = ba.size(); | 727 | int len = ba.size(); |
733 | int currentAction, | 728 | int currentAction, |
734 | journalKey, | 729 | journalKey, |
735 | origHadRepeat; // should be bool, but we need tri-state(not being used) | 730 | origHadRepeat; // should be bool, but we need tri-state(not being used) |
736 | 731 | ||
737 | int i = 0; | 732 | int i = 0; |
738 | char *point; | 733 | char *point; |
739 | // hack to get rid of segfaults after reading </DATEBOOK> | 734 | // hack to get rid of segfaults after reading </DATEBOOK> |
740 | while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) { | 735 | while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) { |
741 | i = point - dt; | 736 | i = point - dt; |
742 | // if we are reading in events in the general case, | 737 | // if we are reading in events in the general case, |
743 | // we are just adding them, so let the actions represent that... | 738 | // we are just adding them, so let the actions represent that... |
744 | currentAction = ACTION_ADD; | 739 | currentAction = ACTION_ADD; |
745 | journalKey = -1; | 740 | journalKey = -1; |
746 | origHadRepeat = -1; | 741 | origHadRepeat = -1; |
747 | // some temporary variables for dates and times ... | 742 | // some temporary variables for dates and times ... |
748 | //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0; | 743 | //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0; |
749 | //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0; | 744 | //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0; |
750 | //int enddtY = 0, enddtM = 0, enddtD = 0; | 745 | //int enddtY = 0, enddtM = 0, enddtD = 0; |
751 | 746 | ||
752 | // ... for the alarm settings ... | 747 | // ... for the alarm settings ... |
753 | int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent; | 748 | int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent; |
754 | // ... and for the recurrence | 749 | // ... and for the recurrence |
755 | Event::RepeatPattern rp; | 750 | Event::RepeatPattern rp; |
756 | Event e; | 751 | Event e; |
757 | 752 | ||
758 | i += 7; | 753 | i += 7; |
759 | 754 | ||
760 | while( 1 ) { | 755 | while( 1 ) { |
761 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 756 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
762 | ++i; | 757 | ++i; |
763 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 758 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
764 | break; | 759 | break; |
765 | // we have another attribute, read it. | 760 | // we have another attribute, read it. |
766 | int j = i; | 761 | int j = i; |
767 | while ( j < len && dt[j] != '=' ) | 762 | while ( j < len && dt[j] != '=' ) |
768 | ++j; | 763 | ++j; |
769 | char *attr = dt+i; | 764 | char *attr = dt+i; |
770 | dt[j] = '\0'; | 765 | dt[j] = '\0'; |
771 | i = ++j; // skip = | 766 | i = ++j; // skip = |
772 | while ( i < len && dt[i] != '"' ) | 767 | while ( i < len && dt[i] != '"' ) |
773 | ++i; | 768 | ++i; |
774 | j = ++i; | 769 | j = ++i; |
775 | bool haveAmp = FALSE; | 770 | bool haveAmp = FALSE; |
776 | bool haveUtf = FALSE; | 771 | bool haveUtf = FALSE; |
777 | while ( j < len && dt[j] != '"' ) { | 772 | while ( j < len && dt[j] != '"' ) { |
778 | if ( dt[j] == '&' ) | 773 | if ( dt[j] == '&' ) |
779 | haveAmp = TRUE; | 774 | haveAmp = TRUE; |
780 | if ( ((unsigned char)dt[j]) > 0x7f ) | 775 | if ( ((unsigned char)dt[j]) > 0x7f ) |
781 | haveUtf = TRUE; | 776 | haveUtf = TRUE; |
782 | ++j; | 777 | ++j; |
783 | } | 778 | } |
784 | 779 | ||
785 | if ( i == j ) { | 780 | if ( i == j ) { |
786 | // leave out empty attributes | 781 | // leave out empty attributes |
787 | i = j + 1; | 782 | i = j + 1; |
788 | continue; | 783 | continue; |
789 | } | 784 | } |
790 | 785 | ||
791 | QString value = haveUtf ? QString::fromUtf8( dt+i, j-i ) | 786 | QString value = haveUtf ? QString::fromUtf8( dt+i, j-i ) |
792 | : QString::fromLatin1( dt+i, j-i ); | 787 | : QString::fromLatin1( dt+i, j-i ); |
793 | if ( haveAmp ) | 788 | if ( haveAmp ) |
794 | value = Qtopia::plainString( value ); | 789 | value = Qtopia::plainString( value ); |
795 | i = j + 1; | 790 | i = j + 1; |
796 | 791 | ||
797 | //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() ); | 792 | //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() ); |
798 | int * find = dict[ attr ]; | 793 | int * find = dict[ attr ]; |
799 | #if 1 | 794 | #if 1 |
800 | if ( !find ) { | 795 | if ( !find ) { |
801 | // custom field | 796 | // custom field |