summaryrefslogtreecommitdiff
path: root/library
Unidiff
Diffstat (limited to 'library') (more/less context) (ignore whitespace changes)
-rw-r--r--library/datebookdb.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp
index 000ff71..188d8e1 100644
--- a/library/datebookdb.cpp
+++ b/library/datebookdb.cpp
@@ -1,1136 +1,1146 @@
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> 22#include <qfile.h>
23#include <qmessagebox.h> 23#include <qmessagebox.h>
24#include <qstring.h> 24#include <qstring.h>
25#include <qtextcodec.h> 25#include <qtextcodec.h>
26#include <qtextstream.h> 26#include <qtextstream.h>
27#include <qtl.h> 27#include <qtl.h>
28 28
29#include <qpe/alarmserver.h> 29#include <qpe/alarmserver.h>
30#include <qpe/global.h> 30#include <qpe/global.h>
31#include "datebookdb.h" 31#include "datebookdb.h"
32#include <qpe/stringutil.h> 32#include <qpe/stringutil.h>
33#include <qpe/timeconversion.h> 33#include <qpe/timeconversion.h>
34 34
35#include <errno.h> 35#include <errno.h>
36#include <stdlib.h> 36#include <stdlib.h>
37 37
38 38
39class DateBookDBPrivate 39class DateBookDBPrivate
40{ 40{
41public: 41public:
42 bool clean; // indcate whether we need to write to disk... 42 bool clean; // indcate whether we need to write to disk...
43}; 43};
44 44
45 45
46// Helper functions 46// Helper functions
47 47
48static QString dateBookJournalFile() 48static QString dateBookJournalFile()
49{ 49{
50 QString str = getenv("HOME"); 50 QString str = getenv("HOME");
51 return QString( str +"/.caljournal" ); 51 return QString( str +"/.caljournal" );
52} 52}
53 53
54static QString dateBookFilename() 54static QString dateBookFilename()
55{ 55{
56 return Global::applicationFileName("datebook","datebook.xml"); 56 return Global::applicationFileName("datebook","datebook.xml");
57} 57}
58 58
59/* Calculating the next event of a recuring event is actually 59/* Calculating the next event of a recuring event is actually
60 computationally inexpensive, esp. compared to checking each day 60 computationally inexpensive, esp. compared to checking each day
61 individually. There are bad worse cases for say the 29th of 61 individually. There are bad worse cases for say the 29th of
62 february or the 31st of some other months. However 62 february or the 31st of some other months. However
63 these are still bounded */ 63 these are still bounded */
64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) 64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next)
65{ 65{
66 // easy checks, first are we too far in the future or too far in the past? 66 // easy checks, first are we too far in the future or too far in the past?
67 QDate tmpDate; 67 QDate tmpDate;
68 int freq = e.repeatPattern().frequency; 68 int freq = e.repeatPattern().frequency;
69 int diff, diff2, a; 69 int diff, diff2, a;
70 int iday, imonth, iyear; 70 int iday, imonth, iyear;
71 int dayOfWeek = 0; 71 int dayOfWeek = 0;
72 int firstOfWeek = 0; 72 int firstOfWeek = 0;
73 int weekOfMonth; 73 int weekOfMonth;
74 74
75 75
76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from) 76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from)
77 return FALSE; 77 return FALSE;
78 78
79 if (e.start() >= from) { 79 if (e.start() >= from) {
80 next = e.start(); 80 next = e.start();
81 return TRUE; 81 return TRUE;
82 } 82 }
83 83
84 switch ( e.repeatPattern().type ) { 84 switch ( e.repeatPattern().type ) {
85 case Event::Weekly: 85 case Event::Weekly:
86 /* weekly is just daily by 7 */ 86 /* weekly is just daily by 7 */
87 /* first convert the repeatPattern.Days() mask to the next 87 /* first convert the repeatPattern.Days() mask to the next
88 day of week valid after from */ 88 day of week valid after from */
89 dayOfWeek = from.dayOfWeek(); 89 dayOfWeek = from.dayOfWeek();
90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
91 91
92 /* this is done in case freq > 1 and from in week not 92 /* this is done in case freq > 1 and from in week not
93 for this round */ 93 for this round */
94 // firstOfWeek = 0; this is already done at decl. 94 // firstOfWeek = 0; this is already done at decl.
95 while(!((1 << firstOfWeek) & e.repeatPattern().days)) 95 while(!((1 << firstOfWeek) & e.repeatPattern().days))
96 firstOfWeek++; 96 firstOfWeek++;
97
98
97 99
98 /* there is at least one 'day', or there would be no event */ 100 /* there is at least one 'day', or there would be no event */
99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) 101 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days))
100 dayOfWeek++; 102 dayOfWeek++;
103
101 104
102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */ 105 dayOfWeek = dayOfWeek % 7; /* the actual day of week */
103 dayOfWeek -= e.start().date().dayOfWeek() -1; 106 dayOfWeek -= e.start().date().dayOfWeek() -1;
104 107
105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */ 108 firstOfWeek = firstOfWeek % 7; /* the actual first of week */
106 firstOfWeek -= e.start().date().dayOfWeek() -1; 109 firstOfWeek -= e.start().date().dayOfWeek() -1;
107 110
108 // dayOfWeek may be negitive now 111 // dayOfWeek may be negitive now
109 // day of week is number of days to add to start day 112 // day of week is number of days to add to start day
110 113
111 freq *= 7; 114 freq *= 7;
112 // FALL-THROUGH !!!!! 115 // FALL-THROUGH !!!!!
113 case Event::Daily: 116 case Event::Daily:
114 // the add is for the possible fall through from weekly */ 117 // the add is for the possible fall through from weekly */
115 if(e.start().date().addDays(dayOfWeek) > from) { 118 if(e.start().date().addDays(dayOfWeek) > from) {
116 /* first week exception */ 119 /* first week exception */
117 next = QDateTime(e.start().date().addDays(dayOfWeek), 120 next = QDateTime(e.start().date().addDays(dayOfWeek),
118 e.start().time()); 121 e.start().time());
119 if ((next.date() > e.repeatPattern().endDate()) 122 if ((next.date() > e.repeatPattern().endDate())
120 && e.repeatPattern().hasEndDate) 123 && e.repeatPattern().hasEndDate)
121 return FALSE; 124 return FALSE;
122 return TRUE; 125 return TRUE;
123 } 126 }
124 /* if from is middle of a non-week */ 127 /* if from is middle of a non-week */
125 128
126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; 129 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq;
127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; 130 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq;
128 131
129 if(diff != 0) 132 if(diff != 0)
130 diff = freq - diff; 133 diff = freq - diff;
131 if(diff2 != 0) 134 if(diff2 != 0)
132 diff2 = freq - diff2; 135 diff2 = freq - diff2;
133 diff = QMIN(diff, diff2); 136 diff = QMIN(diff, diff2);
134 137
135 next = QDateTime(from.addDays(diff), e.start().time()); 138 next = QDateTime(from.addDays(diff), e.start().time());
136 if ( (next.date() > e.repeatPattern().endDate()) 139 if ( (next.date() > e.repeatPattern().endDate())
137 && e.repeatPattern().hasEndDate ) 140 && e.repeatPattern().hasEndDate )
138 return FALSE; 141 return FALSE;
139 return TRUE; 142 return TRUE;
140 case Event::MonthlyDay: 143 case Event::MonthlyDay:
141 iday = from.day(); 144 iday = from.day();
142 iyear = from.year(); 145 iyear = from.year();
143 imonth = from.month(); 146 imonth = from.month();
144 /* find equivelent day of month for this month */ 147 /* find equivelent day of month for this month */
145 dayOfWeek = e.start().date().dayOfWeek(); 148 dayOfWeek = e.start().date().dayOfWeek();
146 weekOfMonth = (e.start().date().day() - 1) / 7; 149 weekOfMonth = (e.start().date().day() - 1) / 7;
147 150
148 /* work out when the next valid month is */ 151 /* work out when the next valid month is */
149 a = from.year() - e.start().date().year(); 152 a = from.year() - e.start().date().year();
150 a *= 12; 153 a *= 12;
151 a = a + (imonth - e.start().date().month()); 154 a = a + (imonth - e.start().date().month());
152 /* a is e.start()monthsFrom(from); */ 155 /* a is e.start()monthsFrom(from); */
153 if(a % freq) { 156 if(a % freq) {
154 a = freq - (a % freq); 157 a = freq - (a % freq);
155 imonth = from.month() + a; 158 imonth = from.month() + a;
156 if (imonth > 12) { 159 if (imonth > 12) {
157 imonth--; 160 imonth--;
158 iyear += imonth / 12; 161 iyear += imonth / 12;
159 imonth = imonth % 12; 162 imonth = imonth % 12;
160 imonth++; 163 imonth++;
161 } 164 }
162 } 165 }
163 /* imonth is now the first month after or on 166 /* imonth is now the first month after or on
164 from that matches the frequency given */ 167 from that matches the frequency given */
165 168
166 /* find for this month */ 169 /* find for this month */
167 tmpDate = QDate( iyear, imonth, 1 ); 170 tmpDate = QDate( iyear, imonth, 1 );
168 171
169 iday = 1; 172 iday = 1;
170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 173 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
171 iday += 7 * weekOfMonth; 174 iday += 7 * weekOfMonth;
172 while (iday > tmpDate.daysInMonth()) { 175 while (iday > tmpDate.daysInMonth()) {
173 imonth += freq; 176 imonth += freq;
174 if (imonth > 12) { 177 if (imonth > 12) {
175 imonth--; 178 imonth--;
176 iyear += imonth / 12; 179 iyear += imonth / 12;
177 imonth = imonth % 12; 180 imonth = imonth % 12;
178 imonth++; 181 imonth++;
179 } 182 }
180 tmpDate = QDate( iyear, imonth, 1 ); 183 tmpDate = QDate( iyear, imonth, 1 );
181 /* these loops could go for a while, check end case now */ 184 /* these loops could go for a while, check end case now */
182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 185 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
183 return FALSE; 186 return FALSE;
184 iday = 1; 187 iday = 1;
185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 188 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
186 iday += 7 * weekOfMonth; 189 iday += 7 * weekOfMonth;
187 } 190 }
188 tmpDate = QDate(iyear, imonth, iday); 191 tmpDate = QDate(iyear, imonth, iday);
189 192
190 if (tmpDate >= from) { 193 if (tmpDate >= from) {
191 next = QDateTime(tmpDate, e.start().time()); 194 next = QDateTime(tmpDate, e.start().time());
192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 195 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
193 return FALSE; 196 return FALSE;
194 return TRUE; 197 return TRUE;
195 } 198 }
196 199
197 /* need to find the next iteration */ 200 /* need to find the next iteration */
198 do { 201 do {
199 imonth += freq; 202 imonth += freq;
200 if (imonth > 12) { 203 if (imonth > 12) {
201 imonth--; 204 imonth--;
202 iyear += imonth / 12; 205 iyear += imonth / 12;
203 imonth = imonth % 12; 206 imonth = imonth % 12;
204 imonth++; 207 imonth++;
205 } 208 }
206 tmpDate = QDate( iyear, imonth, 1 ); 209 tmpDate = QDate( iyear, imonth, 1 );
207 /* these loops could go for a while, check end case now */ 210 /* these loops could go for a while, check end case now */
208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 211 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
209 return FALSE; 212 return FALSE;
210 iday = 1; 213 iday = 1;
211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 214 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
212 iday += 7 * weekOfMonth; 215 iday += 7 * weekOfMonth;
213 } while (iday > tmpDate.daysInMonth()); 216 } while (iday > tmpDate.daysInMonth());
214 tmpDate = QDate(iyear, imonth, iday); 217 tmpDate = QDate(iyear, imonth, iday);
215 218
216 next = QDateTime(tmpDate, e.start().time()); 219 next = QDateTime(tmpDate, e.start().time());
217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 220 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
218 return FALSE; 221 return FALSE;
219 return TRUE; 222 return TRUE;
220 case Event::MonthlyDate: 223 case Event::MonthlyDate:
221 iday = e.start().date().day(); 224 iday = e.start().date().day();
222 iyear = from.year(); 225 iyear = from.year();
223 imonth = from.month(); 226 imonth = from.month();
224 227
225 a = from.year() - e.start().date().year(); 228 a = from.year() - e.start().date().year();
226 a *= 12; 229 a *= 12;
227 a = a + (imonth - e.start().date().month()); 230 a = a + (imonth - e.start().date().month());
228 /* a is e.start()monthsFrom(from); */ 231 /* a is e.start()monthsFrom(from); */
229 if(a % freq) { 232 if(a % freq) {
230 a = freq - (a % freq); 233 a = freq - (a % freq);
231 imonth = from.month() + a; 234 imonth = from.month() + a;
232 if (imonth > 12) { 235 if (imonth > 12) {
233 imonth--; 236 imonth--;
234 iyear += imonth / 12; 237 iyear += imonth / 12;
235 imonth = imonth % 12; 238 imonth = imonth % 12;
236 imonth++; 239 imonth++;
237 } 240 }
238 } 241 }
239 /* imonth is now the first month after or on 242 /* imonth is now the first month after or on
240 from that matches the frequencey given */ 243 from that matches the frequencey given */
241 244
242 /* this could go for a while, worse case, 4*12 iterations, probably */ 245 /* this could go for a while, worse case, 4*12 iterations, probably */
243 while(!QDate::isValid(iyear, imonth, iday) ) { 246 while(!QDate::isValid(iyear, imonth, iday) ) {
244 imonth += freq; 247 imonth += freq;
245 if (imonth > 12) { 248 if (imonth > 12) {
246 imonth--; 249 imonth--;
247 iyear += imonth / 12; 250 iyear += imonth / 12;
248 imonth = imonth % 12; 251 imonth = imonth % 12;
249 imonth++; 252 imonth++;
250 } 253 }
251 /* these loops could go for a while, check end case now */ 254 /* these loops could go for a while, check end case now */
252 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 255 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
253 return FALSE; 256 return FALSE;
254 } 257 }
255 258
256 if(QDate(iyear, imonth, iday) >= from) { 259 if(QDate(iyear, imonth, iday) >= from) {
257 /* done */ 260 /* done */
258 next = QDateTime(QDate(iyear, imonth, iday), 261 next = QDateTime(QDate(iyear, imonth, iday),
259 e.start().time()); 262 e.start().time());
260 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 263 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
261 return FALSE; 264 return FALSE;
262 return TRUE; 265 return TRUE;
263 } 266 }
264 267
265 /* ok, need to cycle */ 268 /* ok, need to cycle */
266 imonth += freq; 269 imonth += freq;
267 imonth--; 270 imonth--;
268 iyear += imonth / 12; 271 iyear += imonth / 12;
269 imonth = imonth % 12; 272 imonth = imonth % 12;
270 imonth++; 273 imonth++;
271 274
272 while(!QDate::isValid(iyear, imonth, iday) ) { 275 while(!QDate::isValid(iyear, imonth, iday) ) {
273 imonth += freq; 276 imonth += freq;
274 imonth--; 277 imonth--;
275 iyear += imonth / 12; 278 iyear += imonth / 12;
276 imonth = imonth % 12; 279 imonth = imonth % 12;
277 imonth++; 280 imonth++;
278 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 281 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
279 return FALSE; 282 return FALSE;
280 } 283 }
281 284
282 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 285 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
283 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 286 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
284 return FALSE; 287 return FALSE;
285 return TRUE; 288 return TRUE;
286 case Event::Yearly: 289 case Event::Yearly:
287 iday = e.start().date().day(); 290 iday = e.start().date().day();
288 imonth = e.start().date().month(); 291 imonth = e.start().date().month();
289 iyear = from.year(); // after all, we want to start in this year 292 iyear = from.year(); // after all, we want to start in this year
290 293
291 diff = 1; 294 diff = 1;
292 if(imonth == 2 && iday > 28) { 295 if(imonth == 2 && iday > 28) {
293 /* leap year, and it counts, calculate actual frequency */ 296 /* leap year, and it counts, calculate actual frequency */
294 if(freq % 4) 297 if(freq % 4)
295 if (freq % 2) 298 if (freq % 2)
296 freq = freq * 4; 299 freq = freq * 4;
297 else 300 else
298 freq = freq * 2; 301 freq = freq * 2;
299 /* else divides by 4 already, leave freq alone */ 302 /* else divides by 4 already, leave freq alone */
300 diff = 4; 303 diff = 4;
301 } 304 }
302 305
303 a = from.year() - e.start().date().year(); 306 a = from.year() - e.start().date().year();
304 if(a % freq) { 307 if(a % freq) {
305 a = freq - (a % freq); 308 a = freq - (a % freq);
306 iyear = iyear + a; 309 iyear = iyear + a;
307 } 310 }
308 311
309 /* under the assumption we won't hit one of the special not-leap years twice */ 312 /* under the assumption we won't hit one of the special not-leap years twice */
310 if(!QDate::isValid(iyear, imonth, iday)) { 313 if(!QDate::isValid(iyear, imonth, iday)) {
311 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 314 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
312 iyear += freq; 315 iyear += freq;
313 } 316 }
314 317
315 if(QDate(iyear, imonth, iday) >= from) { 318 if(QDate(iyear, imonth, iday) >= from) {
316 next = QDateTime(QDate(iyear, imonth, iday), 319 next = QDateTime(QDate(iyear, imonth, iday),
317 e.start().time()); 320 e.start().time());
318 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 321 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
319 return FALSE; 322 return FALSE;
320 return TRUE; 323 return TRUE;
321 } 324 }
322 /* iyear == from.year(), need to advance again */ 325 /* iyear == from.year(), need to advance again */
323 iyear += freq; 326 iyear += freq;
324 /* under the assumption we won't hit one of the special not-leap years twice */ 327 /* under the assumption we won't hit one of the special not-leap years twice */
325 if(!QDate::isValid(iyear, imonth, iday)) { 328 if(!QDate::isValid(iyear, imonth, iday)) {
326 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 329 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
327 iyear += freq; 330 iyear += freq;
328 } 331 }
329 332
330 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 333 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
331 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 334 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
332 return FALSE; 335 return FALSE;
333 return TRUE; 336 return TRUE;
334 default: 337 default:
335 return FALSE; 338 return FALSE;
336 } 339 }
337} 340}
338 341
339static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) 342static bool nextAlarm( const Event &ev, QDateTime& when, int& warn)
340{ 343{
341 QDateTime now = QDateTime::currentDateTime(); 344 QDateTime now = QDateTime::currentDateTime();
342 if ( ev.hasRepeat() ) { 345 if ( ev.hasRepeat() ) {
343 QDateTime ralarm; 346 QDateTime ralarm;
344 if (nextOccurance(ev, now.date(), ralarm)) { 347 if (nextOccurance(ev, now.date(), ralarm)) {
345 ralarm = ralarm.addSecs(-ev.alarmTime()*60); 348 ralarm = ralarm.addSecs(-ev.alarmTime()*60);
346 if ( ralarm > now ) { 349 if ( ralarm > now ) {
347 when = ralarm; 350 when = ralarm;
348 warn = ev.alarmTime(); 351 warn = ev.alarmTime();
349 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { 352 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) {
350 ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); 353 ralarm = ralarm.addSecs( -ev.alarmTime()*60 );
351 if ( ralarm > now ) { 354 if ( ralarm > now ) {
352 when = ralarm; 355 when = ralarm;
353 warn = ev.alarmTime(); 356 warn = ev.alarmTime();
354 } 357 }
355 } 358 }
356 } 359 }
357 } else { 360 } else {
358 warn = ev.alarmTime(); 361 warn = ev.alarmTime();
359 when = ev.start().addSecs( -ev.alarmTime()*60 ); 362 when = ev.start().addSecs( -ev.alarmTime()*60 );
360 } 363 }
361 return when > now; 364 return when > now;
362} 365}
363 366
364static void addEventAlarm( const Event &ev ) 367static void addEventAlarm( const Event &ev )
365{ 368{
366 QDateTime when; 369 QDateTime when;
367 int warn; 370 int warn;
368 if ( nextAlarm(ev,when,warn) ) 371 if ( nextAlarm(ev,when,warn) )
369 AlarmServer::addAlarm( when, 372 AlarmServer::addAlarm( when,
370 "QPE/Application/datebook", 373 "QPE/Application/datebook",
371 "alarm(QDateTime,int)", warn ); 374 "alarm(QDateTime,int)", warn );
372} 375}
373 376
374static void delEventAlarm( const Event &ev ) 377static void delEventAlarm( const Event &ev )
375{ 378{
376 QDateTime when; 379 QDateTime when;
377 int warn; 380 int warn;
378 if ( nextAlarm(ev,when,warn) ) 381 if ( nextAlarm(ev,when,warn) )
379 AlarmServer::deleteAlarm( when, 382 AlarmServer::deleteAlarm( when,
380 "QPE/Application/datebook", 383 "QPE/Application/datebook",
381 "alarm(QDateTime,int)", warn ); 384 "alarm(QDateTime,int)", warn );
382} 385}
383 386
384 387
385DateBookDB::DateBookDB() 388DateBookDB::DateBookDB()
386{ 389{
387 init(); 390 init();
388} 391}
389 392
390DateBookDB::~DateBookDB() 393DateBookDB::~DateBookDB()
391{ 394{
392 save(); 395 save();
393 eventList.clear(); 396 eventList.clear();
394 repeatEvents.clear(); 397 repeatEvents.clear();
395} 398}
396 399
397 400
398//#### Why is this code duplicated in getEffectiveEvents ????? 401//#### Why is this code duplicated in getEffectiveEvents ?????
399//#### Addendum. Don't use this function, lets faze it out if we can. 402//#### Addendum. Don't use this function, lets faze it out if we can.
400QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) 403QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to )
401{ 404{
402 QValueList<Event> tmpList; 405 QValueList<Event> tmpList;
403 tmpList = getNonRepeatingEvents( from, to ); 406 tmpList = getNonRepeatingEvents( from, to );
404 407
405 // check for repeating events... 408 // check for repeating events...
406 for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); 409 for (QValueList<Event>::ConstIterator it = repeatEvents.begin();
407 it != repeatEvents.end(); ++it) { 410 it != repeatEvents.end(); ++it) {
408 QDate itDate = from; 411 QDate itDate = from;
409 QDateTime due; 412 QDateTime due;
410 413
411 /* create a false end date, to short circuit on hard 414 /* create a false end date, to short circuit on hard
412 MonthlyDay recurences */ 415 MonthlyDay recurences */
413 Event dummy_event = *it; 416 Event dummy_event = *it;
414 Event::RepeatPattern r = dummy_event.repeatPattern(); 417 Event::RepeatPattern r = dummy_event.repeatPattern();
415 if ( !r.hasEndDate || r.endDate() > to ) { 418 if ( !r.hasEndDate || r.endDate() > to ) {
416 r.setEndDate( to ); 419 r.setEndDate( to );
417 r.hasEndDate = TRUE; 420 r.hasEndDate = TRUE;
418 } 421 }
419 dummy_event.setRepeat(TRUE, r); 422 dummy_event.setRepeat(TRUE, r);
420 423
421 while (nextOccurance(dummy_event, itDate, due)) { 424 while (nextOccurance(dummy_event, itDate, due)) {
422 if (due.date() > to) 425 if (due.date() > to)
423 break; 426 break;
424 Event newEvent = *it; 427 Event newEvent = *it;
425 newEvent.setStart(due); 428 newEvent.setStart(due);
426 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); 429 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end())));
427 430
428 tmpList.append(newEvent); 431 tmpList.append(newEvent);
429 itDate = due.date().addDays(1); /* the next event */ 432 itDate = due.date().addDays(1); /* the next event */
430 } 433 }
431 } 434 }
432 qHeapSort(tmpList); 435 qHeapSort(tmpList);
433 return tmpList; 436 return tmpList;
434} 437}
435 438
436QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) 439QValueList<Event> DateBookDB::getEvents( const QDateTime &start )
437{ 440{
438 QValueList<Event> day = getEvents(start.date(),start.date()); 441 QValueList<Event> day = getEvents(start.date(),start.date());
439 442
440 QValueListConstIterator<Event> it; 443 QValueListConstIterator<Event> it;
441 QDateTime dtTmp; 444 QDateTime dtTmp;
442 QValueList<Event> tmpList; 445 QValueList<Event> tmpList;
443 for (it = day.begin(); it != day.end(); ++it ) { 446 for (it = day.begin(); it != day.end(); ++it ) {
444 dtTmp = (*it).start(TRUE); 447 dtTmp = (*it).start(TRUE);
445 if ( dtTmp == start ) 448 if ( dtTmp == start )
446 tmpList.append( *it ); 449 tmpList.append( *it );
447 } 450 }
448 return tmpList; 451 return tmpList;
449} 452}
450 453
451//#### Why is this code duplicated in getEvents ????? 454//#### Why is this code duplicated in getEvents ?????
452 455
453QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, 456QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from,
454 const QDate &to ) 457 const QDate &to )
455{ 458{
456 QValueList<EffectiveEvent> tmpList; 459 QValueList<EffectiveEvent> tmpList;
457 QValueListIterator<Event> it; 460 QValueListIterator<Event> it;
458 461
459 EffectiveEvent effEv; 462 EffectiveEvent effEv;
460 QDateTime dtTmp, 463 QDateTime dtTmp,
461 dtEnd; 464 dtEnd;
462 465
463 for (it = eventList.begin(); it != eventList.end(); ++it ) { 466 for (it = eventList.begin(); it != eventList.end(); ++it ) {
464 if (!(*it).isValidUid()) 467 if (!(*it).isValidUid())
465 (*it).assignUid(); // FIXME: Hack to restore cleared uids 468 (*it).assignUid(); // FIXME: Hack to restore cleared uids
466 469
467 dtTmp = (*it).start(TRUE); 470 dtTmp = (*it).start(TRUE);
468 dtEnd = (*it).end(TRUE); 471 dtEnd = (*it).end(TRUE);
469 472
470 if ( dtTmp.date() >= from && dtTmp.date() <= to ) { 473 if ( dtTmp.date() >= from && dtTmp.date() <= to ) {
471 Event tmpEv = *it; 474 Event tmpEv = *it;
472 effEv.setEvent(tmpEv); 475 effEv.setEvent(tmpEv);
473 effEv.setDate( dtTmp.date() ); 476 effEv.setDate( dtTmp.date() );
474 effEv.setStart( dtTmp.time() ); 477 effEv.setStart( dtTmp.time() );
475 if ( dtTmp.date() != dtEnd.date() ) 478 if ( dtTmp.date() != dtEnd.date() )
476 effEv.setEnd( QTime(23, 59, 0) ); 479 effEv.setEnd( QTime(23, 59, 0) );
477 else 480 else
478 effEv.setEnd( dtEnd.time() ); 481 effEv.setEnd( dtEnd.time() );
479 tmpList.append( effEv ); 482 tmpList.append( effEv );
480 } 483 }
481 // we must also check for end date information... 484 // we must also check for end date information...
482 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { 485 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) {
483 QDateTime dt = dtTmp.addDays( 1 ); 486 QDateTime dt = dtTmp.addDays( 1 );
484 dt.setTime( QTime(0, 0, 0) ); 487 dt.setTime( QTime(0, 0, 0) );
485 QDateTime dtStop; 488 QDateTime dtStop;
486 if ( dtEnd > to ) { 489 if ( dtEnd > to ) {
487 dtStop = to; 490 dtStop = to;
488 } else 491 } else
489 dtStop = dtEnd; 492 dtStop = dtEnd;
490 while ( dt <= dtStop ) { 493 while ( dt <= dtStop ) {
491 Event tmpEv = *it; 494 Event tmpEv = *it;
492 effEv.setEvent( tmpEv ); 495 effEv.setEvent( tmpEv );
493 effEv.setDate( dt.date() ); 496 effEv.setDate( dt.date() );
494 if ( dt >= from ) { 497 if ( dt >= from ) {
495 effEv.setStart( QTime(0, 0, 0) ); 498 effEv.setStart( QTime(0, 0, 0) );
496 if ( dt.date() == dtEnd.date() ) 499 if ( dt.date() == dtEnd.date() )
497 effEv.setEnd( dtEnd.time() ); 500 effEv.setEnd( dtEnd.time() );
498 else 501 else
499 effEv.setEnd( QTime(23, 59, 59) ); 502 effEv.setEnd( QTime(23, 59, 59) );
500 tmpList.append( effEv ); 503 tmpList.append( effEv );
501 } 504 }
502 dt = dt.addDays( 1 ); 505 dt = dt.addDays( 1 );
503 } 506 }
504 } 507 }
505 } 508 }
506 // check for repeating events... 509 // check for repeating events...
507 QDateTime repeat; 510 QDateTime repeat;
508 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 511 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
509 if (!(*it).isValidUid()) 512 if (!(*it).isValidUid())
510 (*it).assignUid(); // FIXME: Hack to restore cleared uids 513 (*it).assignUid(); // FIXME: Hack to restore cleared uids
511 514
512 /* create a false end date, to short circuit on hard 515 /* create a false end date, to short circuit on hard
513 MonthlyDay recurences */ 516 MonthlyDay recurences */
514 Event dummy_event = *it; 517 Event dummy_event = *it;
515 int duration = (*it).start().date().daysTo( (*it).end().date() ); 518 int duration = (*it).start().date().daysTo( (*it).end().date() );
516 QDate itDate = from.addDays(-duration); 519 QDate itDate = from.addDays(-duration);
517 520
518 Event::RepeatPattern r = dummy_event.repeatPattern(); 521 Event::RepeatPattern r = dummy_event.repeatPattern();
519 if ( !r.hasEndDate || r.endDate() > to ) { 522 if ( !r.hasEndDate || r.endDate() > to ) {
520 r.setEndDate( to ); 523 r.setEndDate( to );
521 r.hasEndDate = TRUE; 524 r.hasEndDate = TRUE;
522 } 525 }
523 dummy_event.setRepeat(TRUE, r); 526 dummy_event.setRepeat(TRUE, r);
524 527
525 while (nextOccurance(dummy_event, itDate, repeat)) { 528 while (nextOccurance(dummy_event, itDate, repeat)) {
526 if(repeat.date() > to) 529 if(repeat.date() > to)
527 break; 530 break;
528 effEv.setDate( repeat.date() ); 531 effEv.setDate( repeat.date() );
529 if ((*it).type() == Event::AllDay) { 532 if ((*it).type() == Event::AllDay) {
530 effEv.setStart( QTime(0,0,0) ); 533 effEv.setStart( QTime(0,0,0) );
531 effEv.setEnd( QTime(23,59,59) ); 534 effEv.setEnd( QTime(23,59,59) );
532 } else { 535 } else {
533 /* we only occur by days, not hours/minutes/seconds. Hence 536 /* we only occur by days, not hours/minutes/seconds. Hence
534 the actual end and start times will be the same for 537 the actual end and start times will be the same for
535 every repeated event. For multi day events this is 538 every repeated event. For multi day events this is
536 fixed up later if on wronge day span */ 539 fixed up later if on wronge day span */
537 effEv.setStart( (*it).start().time() ); 540 effEv.setStart( (*it).start().time() );
538 effEv.setEnd( (*it).end().time() ); 541 effEv.setEnd( (*it).end().time() );
539 } 542 }
540 if ( duration != 0 ) { 543 if ( duration != 0 ) {
541 // multi-day repeating events 544 // multi-day repeating events
542 QDate sub_it = QMAX( repeat.date(), from ); 545 QDate sub_it = QMAX( repeat.date(), from );
543 QDate startDate = repeat.date(); 546 QDate startDate = repeat.date();
544 QDate endDate = startDate.addDays( duration ); 547 QDate endDate = startDate.addDays( duration );
545 548
546 while ( sub_it <= endDate && sub_it <= to ) { 549 while ( sub_it <= endDate && sub_it <= to ) {
547 EffectiveEvent tmpEffEv = effEv; 550 EffectiveEvent tmpEffEv = effEv;
548 Event tmpEv = *it; 551 Event tmpEv = *it;
549 tmpEffEv.setEvent( tmpEv ); 552 tmpEffEv.setEvent( tmpEv );
550 553
551 if ( sub_it != startDate ) 554 if ( sub_it != startDate )
552 tmpEffEv.setStart( QTime(0,0,0) ); 555 tmpEffEv.setStart( QTime(0,0,0) );
553 if ( sub_it != endDate ) 556 if ( sub_it != endDate )
554 tmpEffEv.setEnd( QTime(23,59,59) ); 557 tmpEffEv.setEnd( QTime(23,59,59) );
555 tmpEffEv.setDate( sub_it ); 558 tmpEffEv.setDate( sub_it );
556 tmpEffEv.setEffectiveDates( startDate, endDate ); 559 tmpEffEv.setEffectiveDates( startDate, endDate );
557 tmpList.append( tmpEffEv ); 560 tmpList.append( tmpEffEv );
558 sub_it = sub_it.addDays( 1 ); 561 sub_it = sub_it.addDays( 1 );
559 } 562 }
560 itDate = endDate; 563 itDate = endDate;
561 } else { 564 } else {
562 Event tmpEv = *it; 565 Event tmpEv = *it;
563 effEv.setEvent( tmpEv ); 566 effEv.setEvent( tmpEv );
564 tmpList.append( effEv ); 567 tmpList.append( effEv );
565 itDate = repeat.date().addDays( 1 ); 568 itDate = repeat.date().addDays( 1 );
566 } 569 }
567 } 570 }
568 } 571 }
569 572
570 qHeapSort( tmpList ); 573 qHeapSort( tmpList );
571 return tmpList; 574 return tmpList;
572} 575}
573 576
574QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) 577QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt)
575{ 578{
576 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); 579 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date());
577 QValueListConstIterator<EffectiveEvent> it; 580 QValueListConstIterator<EffectiveEvent> it;
578 QValueList<EffectiveEvent> tmpList; 581 QValueList<EffectiveEvent> tmpList;
579 QDateTime dtTmp; 582 QDateTime dtTmp;
580 583
581 for (it = day.begin(); it != day.end(); ++it ) { 584 for (it = day.begin(); it != day.end(); ++it ) {
582 dtTmp = QDateTime( (*it).date(), (*it).start() ); 585 dtTmp = QDateTime( (*it).date(), (*it).start() );
583 // at the moment we don't have second granularity, be nice about that.. 586 // at the moment we don't have second granularity, be nice about that..
584 if ( QABS(dt.secsTo(dtTmp)) < 60 ) 587 if ( QABS(dt.secsTo(dtTmp)) < 60 )
585 tmpList.append( *it ); 588 tmpList.append( *it );
586 } 589 }
587 return tmpList; 590 return tmpList;
588} 591}
589 592
590void DateBookDB::addEvent( const Event &ev, bool doalarm ) 593void DateBookDB::addEvent( const Event &ev, bool doalarm )
591{ 594{
592 // write to the journal... 595 // write to the journal...
593 saveJournalEntry( ev, ACTION_ADD, -1, false ); 596 saveJournalEntry( ev, ACTION_ADD, -1, false );
594 addJFEvent( ev, doalarm ); 597 addJFEvent( ev, doalarm );
595 d->clean = false; 598 d->clean = false;
596} 599}
597 600
598void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) 601void DateBookDB::addJFEvent( const Event &ev, bool doalarm )
599{ 602{
600 if ( doalarm && ev.hasAlarm() ) 603 if ( doalarm && ev.hasAlarm() )
601 addEventAlarm( ev ); 604 addEventAlarm( ev );
602 if ( ev.hasRepeat() ) 605 if ( ev.hasRepeat() )
603 repeatEvents.append( ev ); 606 repeatEvents.append( ev );
604 else 607 else
605 eventList.append( ev ); 608 eventList.append( ev );
606} 609}
607 610
608void DateBookDB::editEvent( const Event &old, Event &editedEv ) 611void DateBookDB::editEvent( const Event &old, Event &editedEv )
609{ 612{
610 int oldIndex=0; 613 int oldIndex=0;
611 bool oldHadRepeat = old.hasRepeat(); 614 bool oldHadRepeat = old.hasRepeat();
612 Event orig; 615 Event orig;
613 616
614 // write to the journal... 617 // write to the journal...
615 if ( oldHadRepeat ) { 618 if ( oldHadRepeat ) {
616 if ( origRepeat( old, orig ) ) // should work always... 619 if ( origRepeat( old, orig ) ) // should work always...
617 oldIndex = repeatEvents.findIndex( orig ); 620 oldIndex = repeatEvents.findIndex( orig );
618 } else 621 } else
619 oldIndex = eventList.findIndex( old ); 622 oldIndex = eventList.findIndex( old );
620 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); 623 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat );
621 624
622 // Delete old event 625 // Delete old event
623 if ( old.hasAlarm() ) 626 if ( old.hasAlarm() )
624 delEventAlarm( old ); 627 delEventAlarm( old );
625 if ( oldHadRepeat ) { 628 if ( oldHadRepeat ) {
626 if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and 629 if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and
627 // orig is initialized 630 // orig is initialized
628 // assumption, when someone edits a repeating event, they 631 // assumption, when someone edits a repeating event, they
629 // want to change them all, maybe not perfect, but it works 632 // want to change them all, maybe not perfect, but it works
630 // for the moment... 633 // for the moment...
631 repeatEvents.remove( orig ); 634 repeatEvents.remove( orig );
632 } else 635 } else
633 removeRepeat( old ); 636 removeRepeat( old );
634 } else { 637 } else {
635 QValueList<Event>::Iterator it = eventList.find( old ); 638 QValueList<Event>::Iterator it = eventList.find( old );
636 if ( it != eventList.end() ) 639 if ( it != eventList.end() )
637 eventList.remove( it ); 640 eventList.remove( it );
638 } 641 }
639 642
640 // Add new event 643 // Add new event
641 if ( editedEv.hasAlarm() ) 644 if ( editedEv.hasAlarm() )
642 addEventAlarm( editedEv ); 645 addEventAlarm( editedEv );
643 if ( editedEv.hasRepeat() ) 646 if ( editedEv.hasRepeat() )
644 repeatEvents.append( editedEv ); 647 repeatEvents.append( editedEv );
645 else 648 else
646 eventList.append( editedEv ); 649 eventList.append( editedEv );
647 650
648 d->clean = false; 651 d->clean = false;
649} 652}
650 653
651void DateBookDB::removeEvent( const Event &ev ) 654void DateBookDB::removeEvent( const Event &ev )
652{ 655{
653 // write to the journal... 656 // write to the journal...
654 saveJournalEntry( ev, ACTION_REMOVE, -1, false ); 657 saveJournalEntry( ev, ACTION_REMOVE, -1, false );
655 removeJFEvent( ev ); 658 removeJFEvent( ev );
656 d->clean = false; 659 d->clean = false;
657} 660}
658 661
659void DateBookDB::removeJFEvent( const Event&ev ) 662void DateBookDB::removeJFEvent( const Event&ev )
660{ 663{
661 if ( ev.hasAlarm() ) 664 if ( ev.hasAlarm() )
662 delEventAlarm( ev ); 665 delEventAlarm( ev );
663 if ( ev.hasRepeat() ) { 666 if ( ev.hasRepeat() ) {
664 removeRepeat( ev ); 667 removeRepeat( ev );
665 } else { 668 } else {
666 QValueList<Event>::Iterator it = eventList.find( ev ); 669 QValueList<Event>::Iterator it = eventList.find( ev );
667 if ( it != eventList.end() ) 670 if ( it != eventList.end() )
668 eventList.remove( it ); 671 eventList.remove( it );
669 } 672 }
670} 673}
671 674
672// also handles journaling... 675// also handles journaling...
673void DateBookDB::loadFile( const QString &strFile ) 676void DateBookDB::loadFile( const QString &strFile )
674{ 677{
675 678
676 QFile f( strFile ); 679 QFile f( strFile );
677 if ( !f.open( IO_ReadOnly ) ) 680 if ( !f.open( IO_ReadOnly ) )
678 return; 681 return;
679 682
680 enum Attribute { 683 enum Attribute {
681 FDescription = 0, 684 FDescription = 0,
682 FLocation, 685 FLocation,
683 FCategories, 686 FCategories,
684 FUid, 687 FUid,
685 FType, 688 FType,
686 FAlarm, 689 FAlarm,
687 FSound, 690 FSound,
688 FRType, 691 FRType,
689 FRWeekdays, 692 FRWeekdays,
690 FRPosition, 693 FRPosition,
691 FRFreq, 694 FRFreq,
692 FRHasEndDate, 695 FRHasEndDate,
693 FREndDate, 696 FREndDate,
694 FRStart, 697 FRStart,
695 FREnd, 698 FREnd,
696 FNote, 699 FNote,
697 FCreated, 700 FCreated,
698 FAction, 701 FAction,
699 FActionKey, 702 FActionKey,
700 FJournalOrigHadRepeat 703 FJournalOrigHadRepeat
701 }; 704 };
702 705
703 QAsciiDict<int> dict( 97 ); 706 QAsciiDict<int> dict( 97 );
704 dict.setAutoDelete( TRUE ); 707 dict.setAutoDelete( TRUE );
705 dict.insert( "description", new int(FDescription) ); 708 dict.insert( "description", new int(FDescription) );
706 dict.insert( "location", new int(FLocation) ); 709 dict.insert( "location", new int(FLocation) );
707 dict.insert( "categories", new int(FCategories) ); 710 dict.insert( "categories", new int(FCategories) );
708 dict.insert( "uid", new int(FUid) ); 711 dict.insert( "uid", new int(FUid) );
709 dict.insert( "type", new int(FType) ); 712 dict.insert( "type", new int(FType) );
710 dict.insert( "alarm", new int(FAlarm) ); 713 dict.insert( "alarm", new int(FAlarm) );
711 dict.insert( "sound", new int(FSound) ); 714 dict.insert( "sound", new int(FSound) );
712 dict.insert( "rtype", new int(FRType) ); 715 dict.insert( "rtype", new int(FRType) );
713 dict.insert( "rweekdays", new int(FRWeekdays) ); 716 dict.insert( "rweekdays", new int(FRWeekdays) );
714 dict.insert( "rposition", new int(FRPosition) ); 717 dict.insert( "rposition", new int(FRPosition) );
715 dict.insert( "rfreq", new int(FRFreq) ); 718 dict.insert( "rfreq", new int(FRFreq) );
716 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 719 dict.insert( "rhasenddate", new int(FRHasEndDate) );
717 dict.insert( "enddt", new int(FREndDate) ); 720 dict.insert( "enddt", new int(FREndDate) );
718 dict.insert( "start", new int(FRStart) ); 721 dict.insert( "start", new int(FRStart) );
719 dict.insert( "end", new int(FREnd) ); 722 dict.insert( "end", new int(FREnd) );
720 dict.insert( "note", new int(FNote) ); 723 dict.insert( "note", new int(FNote) );
721 dict.insert( "created", new int(FCreated) ); 724 dict.insert( "created", new int(FCreated) );
722 dict.insert( "action", new int(FAction) ); 725 dict.insert( "action", new int(FAction) );
723 dict.insert( "actionkey", new int(FActionKey) ); 726 dict.insert( "actionkey", new int(FActionKey) );
724 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) ); 727 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) );
725 728
726 729
727 QByteArray ba = f.readAll(); 730 QByteArray ba = f.readAll();
728 char* dt = ba.data(); 731 char* dt = ba.data();
729 int len = ba.size(); 732 int len = ba.size();
730 int currentAction, 733 int currentAction,
731 journalKey, 734 journalKey,
732 origHadRepeat; // should be bool, but we need tri-state(not being used) 735 origHadRepeat; // should be bool, but we need tri-state(not being used)
733 736
734 int i = 0; 737 int i = 0;
735 char *point; 738 char *point;
736 // hack to get rid of segfaults after reading </DATEBOOK> 739 // hack to get rid of segfaults after reading </DATEBOOK>
737 while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) { 740 while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) {
738 i = point - dt; 741 i = point - dt;
739 // if we are reading in events in the general case, 742 // if we are reading in events in the general case,
740 // we are just adding them, so let the actions represent that... 743 // we are just adding them, so let the actions represent that...
741 currentAction = ACTION_ADD; 744 currentAction = ACTION_ADD;
742 journalKey = -1; 745 journalKey = -1;
743 origHadRepeat = -1; 746 origHadRepeat = -1;
744 // some temporary variables for dates and times ... 747 // some temporary variables for dates and times ...
745 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0; 748 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0;
746 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0; 749 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0;
747 //int enddtY = 0, enddtM = 0, enddtD = 0; 750 //int enddtY = 0, enddtM = 0, enddtD = 0;
748 751
749 // ... for the alarm settings ... 752 // ... for the alarm settings ...
750 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent; 753 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent;
751 // ... and for the recurrence 754 // ... and for the recurrence
752 Event::RepeatPattern rp; 755 Event::RepeatPattern rp;
753 Event e; 756 Event e;
754 757
755 i += 7; 758 i += 7;
756 759
757 while( 1 ) { 760 while( 1 ) {
758 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 761 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
759 ++i; 762 ++i;
760 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 763 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
761 break; 764 break;
762 // we have another attribute, read it. 765 // we have another attribute, read it.
763 int j = i; 766 int j = i;
764 while ( j < len && dt[j] != '=' ) 767 while ( j < len && dt[j] != '=' )
765 ++j; 768 ++j;
766 char *attr = dt+i; 769 char *attr = dt+i;
767 dt[j] = '\0'; 770 dt[j] = '\0';
768 i = ++j; // skip = 771 i = ++j; // skip =
769 while ( i < len && dt[i] != '"' ) 772 while ( i < len && dt[i] != '"' )
770 ++i; 773 ++i;
771 j = ++i; 774 j = ++i;
772 bool haveAmp = FALSE; 775 bool haveAmp = FALSE;
773 bool haveUtf = FALSE; 776 bool haveUtf = FALSE;
774 while ( j < len && dt[j] != '"' ) { 777 while ( j < len && dt[j] != '"' ) {
775 if ( dt[j] == '&' ) 778 if ( dt[j] == '&' )
776 haveAmp = TRUE; 779 haveAmp = TRUE;
777 if ( ((unsigned char)dt[j]) > 0x7f ) 780 if ( ((unsigned char)dt[j]) > 0x7f )
778 haveUtf = TRUE; 781 haveUtf = TRUE;
779 ++j; 782 ++j;
780 } 783 }
781 784
782 if ( i == j ) { 785 if ( i == j ) {
783 // leave out empty attributes 786 // leave out empty attributes
784 i = j + 1; 787 i = j + 1;
785 continue; 788 continue;
786 } 789 }
787 790
788 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i ) 791 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i )
789 : QString::fromLatin1( dt+i, j-i ); 792 : QString::fromLatin1( dt+i, j-i );
790 if ( haveAmp ) 793 if ( haveAmp )
791 value = Qtopia::plainString( value ); 794 value = Qtopia::plainString( value );
792 i = j + 1; 795 i = j + 1;
793 796
794 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() ); 797 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() );
795 int * find = dict[ attr ]; 798 int * find = dict[ attr ];
796#if 1 799#if 1
797 if ( !find ) { 800 if ( !find ) {
798 // custom field 801 // custom field
799 e.setCustomField(attr, value); 802 e.setCustomField(attr, value);
800 continue; 803 continue;
801 } 804 }
802 805
803 switch( *find ) { 806 switch( *find ) {
804 case FDescription: 807 case FDescription:
805 e.setDescription( value ); 808 e.setDescription( value );
806 break; 809 break;
807 case FLocation: 810 case FLocation:
808 e.setLocation( value ); 811 e.setLocation( value );
809 break; 812 break;
810 case FCategories: 813 case FCategories:
811 e.setCategories( Qtopia::Record::idsFromString( value ) ); 814 e.setCategories( Qtopia::Record::idsFromString( value ) );
812 break; 815 break;
813 case FUid: 816 case FUid:
814 e.setUid( value.toInt() ); 817 e.setUid( value.toInt() );
815 break; 818 break;
816 case FType: 819 case FType:
817 if ( value == "AllDay" ) 820 if ( value == "AllDay" )
818 e.setType( Event::AllDay ); 821 e.setType( Event::AllDay );
819 else 822 else
820 e.setType( Event::Normal ); 823 e.setType( Event::Normal );
821 break; 824 break;
822 case FAlarm: 825 case FAlarm:
823 alarmTime = value.toInt(); 826 alarmTime = value.toInt();
824 break; 827 break;
825 case FSound: 828 case FSound:
826 alarmSound = value == "loud" ? Event::Loud : Event::Silent; 829 alarmSound = value == "loud" ? Event::Loud : Event::Silent;
827 break; 830 break;
828 // recurrence stuff 831 // recurrence stuff
829 case FRType: 832 case FRType:
830 if ( value == "Daily" ) 833 if ( value == "Daily" )
831 rp.type = Event::Daily; 834 rp.type = Event::Daily;
832 else if ( value == "Weekly" ) 835 else if ( value == "Weekly" )
833 rp.type = Event::Weekly; 836 rp.type = Event::Weekly;
834 else if ( value == "MonthlyDay" ) 837 else if ( value == "MonthlyDay" )
835 rp.type = Event::MonthlyDay; 838 rp.type = Event::MonthlyDay;
836 else if ( value == "MonthlyDate" ) 839 else if ( value == "MonthlyDate" )
837 rp.type = Event::MonthlyDate; 840 rp.type = Event::MonthlyDate;
838 else if ( value == "Yearly" ) 841 else if ( value == "Yearly" )
839 rp.type = Event::Yearly; 842 rp.type = Event::Yearly;
840 else 843 else
841 rp.type = Event::NoRepeat; 844 rp.type = Event::NoRepeat;
842 break; 845 break;
843 case FRWeekdays: 846 case FRWeekdays:
844 // QtopiaDesktop 1.6 sometimes creates 'rweekdays="0"' 847 // QtopiaDesktop 1.6 sometimes creates 'rweekdays="0"'
845 // when it goes mad. This causes datebook to crash.. (se) 848 // when it goes mad. This causes datebook to crash.. (se)
846 if ( value.toInt() != 0 ) 849 if ( value.toInt() != 0 )
847 rp.days = value.toInt(); 850 rp.days = value.toInt();
848 else 851 else
849 rp.days = 1; 852 rp.days = 1;
850 break; 853 break;
851 case FRPosition: 854 case FRPosition:
852 rp.position = value.toInt(); 855 rp.position = value.toInt();
853 break; 856 break;
854 case FRFreq: 857 case FRFreq:
855 rp.frequency = value.toInt(); 858 rp.frequency = value.toInt();
856 break; 859 break;
857 case FRHasEndDate: 860 case FRHasEndDate:
858 rp.hasEndDate = value.toInt(); 861 rp.hasEndDate = value.toInt();
859 break; 862 break;
860 case FREndDate: { 863 case FREndDate: {
861 rp.endDateUTC = (time_t) value.toLong(); 864 rp.endDateUTC = (time_t) value.toLong();
862 break; 865 break;
863 } 866 }
864 case FRStart: { 867 case FRStart: {
865 e.setStart( (time_t) value.toLong() ); 868 e.setStart( (time_t) value.toLong() );
866 break; 869 break;
867 } 870 }
868 case FREnd: { 871 case FREnd: {
869 e.setEnd( (time_t) value.toLong() ); 872 e.setEnd( (time_t) value.toLong() );
870 break; 873 break;
871 } 874 }
872 case FNote: 875 case FNote:
873 e.setNotes( value ); 876 e.setNotes( value );
874 break; 877 break;
875 case FCreated: 878 case FCreated:
876 rp.createTime = value.toInt(); 879 rp.createTime = value.toInt();
877 break; 880 break;
878 case FAction: 881 case FAction:
879 currentAction = value.toInt(); 882 currentAction = value.toInt();
880 break; 883 break;
881 case FActionKey: 884 case FActionKey:
882 journalKey = value.toInt(); 885 journalKey = value.toInt();
883 break; 886 break;
884 case FJournalOrigHadRepeat: 887 case FJournalOrigHadRepeat:
885 origHadRepeat = value.toInt(); 888 origHadRepeat = value.toInt();
886 break; 889 break;
887 default: 890 default:
888 qDebug( "huh??? missing enum? -- attr.: %s", attr ); 891 qDebug( "huh??? missing enum? -- attr.: %s", attr );
889 break; 892 break;
890 } 893 }
891#endif 894#endif
892 } 895 }
893 // "post processing" (dates, times, alarm, recurrence) 896 // "post processing" (dates, times, alarm, recurrence)
897
898 // other half of 1169 fixlet without getting into regression
899 // if rp.days == 0 and rp.type == Event::Weekly
900 if ( rp.type == Event::Weekly && rp.days == 0 )
901 rp.days = Event::day( e.start().date().dayOfWeek() );
902
903
894 // start date/time 904 // start date/time
895 e.setRepeat( rp.type != Event::NoRepeat, rp ); 905 e.setRepeat( rp.type != Event::NoRepeat, rp );
896 906
897 if ( alarmTime != -1 ) 907 if ( alarmTime != -1 )
898 e.setAlarm( TRUE, alarmTime, alarmSound ); 908 e.setAlarm( TRUE, alarmTime, alarmSound );
899 909
900 // now do our action based on the current action... 910 // now do our action based on the current action...
901 switch ( currentAction ) { 911 switch ( currentAction ) {
902 case ACTION_ADD: 912 case ACTION_ADD:
903 addJFEvent( e ); 913 addJFEvent( e );
904 break; 914 break;
905 case ACTION_REMOVE: 915 case ACTION_REMOVE:
906 removeJFEvent( e ); 916 removeJFEvent( e );
907 break; 917 break;
908 case ACTION_REPLACE: 918 case ACTION_REPLACE:
909 // be a little bit careful, 919 // be a little bit careful,
910 // in case of a messed up journal... 920 // in case of a messed up journal...
911 if ( journalKey > -1 && origHadRepeat > -1 ) { 921 if ( journalKey > -1 && origHadRepeat > -1 ) {
912 // get the original from proper list... 922 // get the original from proper list...
913 if ( origHadRepeat ) 923 if ( origHadRepeat )
914 removeJFEvent( *(repeatEvents.at(journalKey)) ); 924 removeJFEvent( *(repeatEvents.at(journalKey)) );
915 else 925 else
916 removeJFEvent( *(eventList.at(journalKey)) ); 926 removeJFEvent( *(eventList.at(journalKey)) );
917 addJFEvent( e ); 927 addJFEvent( e );
918 } 928 }
919 break; 929 break;
920 default: 930 default:
921 break; 931 break;
922 } 932 }
923 } 933 }
924 f.close(); 934 f.close();
925} 935}
926 936
927void DateBookDB::init() 937void DateBookDB::init()
928{ 938{
929 d = new DateBookDBPrivate; 939 d = new DateBookDBPrivate;
930 d->clean = false; 940 d->clean = false;
931 QString str = dateBookFilename(); 941 QString str = dateBookFilename();
932 if ( str.isNull() ) { 942 if ( str.isNull() ) {
933 QMessageBox::warning( 0, QObject::tr("Out of Space"), 943 QMessageBox::warning( 0, QObject::tr("Out of Space"),
934 QObject::tr("Unable to create start up files\n" 944 QObject::tr("Unable to create start up files\n"
935 "Please free up some space\n" 945 "Please free up some space\n"
936 "before entering data") ); 946 "before entering data") );
937 } 947 }
938 // continuing along, we call this datebook filename again, 948 // continuing along, we call this datebook filename again,
939 // because they may fix it before continuing, though it seems 949 // because they may fix it before continuing, though it seems
940 // pretty unlikely... 950 // pretty unlikely...
941 loadFile( dateBookFilename() ); 951 loadFile( dateBookFilename() );
942 952
943 if ( QFile::exists( dateBookJournalFile() ) ) { 953 if ( QFile::exists( dateBookJournalFile() ) ) {
944 // merge the journal 954 // merge the journal
945 loadFile( dateBookJournalFile() ); 955 loadFile( dateBookJournalFile() );
946 // save in our changes and remove the journal... 956 // save in our changes and remove the journal...
947 save(); 957 save();
948 } 958 }
949 d->clean = true; 959 d->clean = true;
950} 960}
951 961
952bool DateBookDB::save() 962bool DateBookDB::save()
953{ 963{
954 if ( d->clean == true ) 964 if ( d->clean == true )
955 return true; 965 return true;
956 QValueListIterator<Event> it; 966 QValueListIterator<Event> it;
957 int total_written; 967 int total_written;
958 QString strFileNew = dateBookFilename() + ".new"; 968 QString strFileNew = dateBookFilename() + ".new";
959 969
960 QFile f( strFileNew ); 970 QFile f( strFileNew );
961 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 971 if ( !f.open( IO_WriteOnly|IO_Raw ) )
962 return FALSE; 972 return FALSE;
963 973
964 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 974 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
965 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 975 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
966 buf += "<events>\n"; 976 buf += "<events>\n";
967 QCString str = buf.utf8(); 977 QCString str = buf.utf8();
968 total_written = f.writeBlock( str.data(), str.length() ); 978 total_written = f.writeBlock( str.data(), str.length() );
969 if ( total_written != int(str.length()) ) { 979 if ( total_written != int(str.length()) ) {
970 f.close(); 980 f.close();
971 QFile::remove( strFileNew ); 981 QFile::remove( strFileNew );
972 return false; 982 return false;
973 } 983 }
974 984
975 for ( it = eventList.begin(); it != eventList.end(); ++it ) { 985 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
976 buf = "<event"; 986 buf = "<event";
977 (*it).save( buf ); 987 (*it).save( buf );
978 buf += " />\n"; 988 buf += " />\n";
979 str = buf.utf8(); 989 str = buf.utf8();
980 total_written = f.writeBlock( str.data(), str.length() ); 990 total_written = f.writeBlock( str.data(), str.length() );
981 if ( total_written != int(str.length()) ) { 991 if ( total_written != int(str.length()) ) {
982 f.close(); 992 f.close();
983 QFile::remove( strFileNew ); 993 QFile::remove( strFileNew );
984 return false; 994 return false;
985 } 995 }
986 } 996 }
987 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 997 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
988 buf = "<event"; 998 buf = "<event";
989 (*it).save( buf ); 999 (*it).save( buf );
990 buf += " />\n"; 1000 buf += " />\n";
991 str = buf.utf8(); 1001 str = buf.utf8();
992 total_written = f.writeBlock( str.data(), str.length() ); 1002 total_written = f.writeBlock( str.data(), str.length() );
993 if ( total_written != int(str.length()) ) { 1003 if ( total_written != int(str.length()) ) {
994 f.close(); 1004 f.close();
995 QFile::remove( strFileNew ); 1005 QFile::remove( strFileNew );
996 return false; 1006 return false;
997 } 1007 }
998 } 1008 }
999 buf = "</events>\n</DATEBOOK>\n"; 1009 buf = "</events>\n</DATEBOOK>\n";
1000 str = buf.utf8(); 1010 str = buf.utf8();
1001 total_written = f.writeBlock( str.data(), str.length() ); 1011 total_written = f.writeBlock( str.data(), str.length() );
1002 if ( total_written != int(str.length()) ) { 1012 if ( total_written != int(str.length()) ) {
1003 f.close(); 1013 f.close();
1004 QFile::remove( strFileNew ); 1014 QFile::remove( strFileNew );
1005 return false; 1015 return false;
1006 } 1016 }
1007 f.close(); 1017 f.close();
1008 1018
1009 // now rename... I like to use the systemcall 1019 // now rename... I like to use the systemcall
1010 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) { 1020 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) {
1011 qWarning( "problem renaming file %s to %s errno %d", 1021 qWarning( "problem renaming file %s to %s errno %d",
1012 strFileNew.latin1(), dateBookFilename().latin1(), errno ); 1022 strFileNew.latin1(), dateBookFilename().latin1(), errno );
1013 // remove the file, otherwise it will just stick around... 1023 // remove the file, otherwise it will just stick around...
1014 QFile::remove( strFileNew ); 1024 QFile::remove( strFileNew );
1015 } 1025 }
1016 1026
1017 // may as well remove the journal file... 1027 // may as well remove the journal file...
1018 QFile::remove( dateBookJournalFile() ); 1028 QFile::remove( dateBookJournalFile() );
1019 d->clean = true; 1029 d->clean = true;
1020 return true; 1030 return true;
1021} 1031}
1022 1032
1023void DateBookDB::reload() 1033void DateBookDB::reload()
1024{ 1034{
1025 QValueList<Event>::Iterator it = eventList.begin(); 1035 QValueList<Event>::Iterator it = eventList.begin();
1026 for ( ; it != eventList.end(); ++it ) { 1036 for ( ; it != eventList.end(); ++it ) {
1027 if ( (*it).hasAlarm() ) 1037 if ( (*it).hasAlarm() )
1028 delEventAlarm( *it ); 1038 delEventAlarm( *it );
1029 if ( (*it).hasRepeat() ) 1039 if ( (*it).hasRepeat() )
1030 removeRepeat( *it ); 1040 removeRepeat( *it );
1031 } 1041 }
1032 eventList.clear(); 1042 eventList.clear();
1033 repeatEvents.clear(); // should be a NOP 1043 repeatEvents.clear(); // should be a NOP
1034 init(); 1044 init();
1035} 1045}
1036 1046
1037bool DateBookDB::removeRepeat( const Event &ev ) 1047bool DateBookDB::removeRepeat( const Event &ev )
1038{ 1048{
1039 time_t removeMe = ev.repeatPattern().createTime; 1049 time_t removeMe = ev.repeatPattern().createTime;
1040 QValueListIterator<Event> it; 1050 QValueListIterator<Event> it;
1041 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 1051 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
1042 if ( removeMe == (*it).repeatPattern().createTime ) { 1052 if ( removeMe == (*it).repeatPattern().createTime ) {
1043 (void)repeatEvents.remove( it ); 1053 (void)repeatEvents.remove( it );
1044 // best break, or we are going into undefined territory! 1054 // best break, or we are going into undefined territory!
1045 return TRUE; 1055 return TRUE;
1046 } 1056 }
1047 } 1057 }
1048 return FALSE; 1058 return FALSE;
1049} 1059}
1050 1060
1051bool DateBookDB::origRepeat( const Event &ev, Event &orig ) const 1061bool DateBookDB::origRepeat( const Event &ev, Event &orig ) const
1052{ 1062{
1053 time_t removeMe = ev.repeatPattern().createTime; 1063 time_t removeMe = ev.repeatPattern().createTime;
1054 QValueListConstIterator<Event> it; 1064 QValueListConstIterator<Event> it;
1055 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 1065 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
1056 if ( removeMe == (*it).repeatPattern().createTime ) { 1066 if ( removeMe == (*it).repeatPattern().createTime ) {
1057 orig = (*it); 1067 orig = (*it);
1058 return TRUE; 1068 return TRUE;
1059 } 1069 }
1060 } 1070 }
1061 return FALSE; 1071 return FALSE;
1062} 1072}
1063 1073
1064void DateBookDB::saveJournalEntry( const Event &ev, journal_action action ) 1074void DateBookDB::saveJournalEntry( const Event &ev, journal_action action )
1065{ 1075{
1066 saveJournalEntry( ev, action, -1, false ); 1076 saveJournalEntry( ev, action, -1, false );
1067} 1077}
1068 1078
1069bool DateBookDB::saveJournalEntry( const Event &evOld, journal_action action, 1079bool DateBookDB::saveJournalEntry( const Event &evOld, journal_action action,
1070 int key, bool origHadRepeat ) 1080 int key, bool origHadRepeat )
1071{ 1081{
1072 bool status = false; 1082 bool status = false;
1073 Event ev = evOld; 1083 Event ev = evOld;
1074 // write our log based on the action 1084 // write our log based on the action
1075 QFile f( dateBookJournalFile() ); 1085 QFile f( dateBookJournalFile() );
1076 if ( !f.open( IO_WriteOnly|IO_Append ) ) 1086 if ( !f.open( IO_WriteOnly|IO_Append ) )
1077 return false; 1087 return false;
1078 QString buf = "<event"; 1088 QString buf = "<event";
1079 ev.save( buf ); 1089 ev.save( buf );
1080 buf += " action="; 1090 buf += " action=";
1081 buf += "\"" + QString::number(action) + "\""; 1091 buf += "\"" + QString::number(action) + "\"";
1082 buf += " actionkey=\"" + QString::number(key) + "\""; 1092 buf += " actionkey=\"" + QString::number(key) + "\"";
1083 buf += " actionorig=\"" + QString::number(origHadRepeat) +"\""; 1093 buf += " actionorig=\"" + QString::number(origHadRepeat) +"\"";
1084 buf += " />\n"; 1094 buf += " />\n";
1085 QString str = buf.utf8(); 1095 QString str = buf.utf8();
1086 status = ( f.writeBlock( str.data(), str.length() ) == int(str.length()) ); 1096 status = ( f.writeBlock( str.data(), str.length() ) == int(str.length()) );
1087 f.close(); 1097 f.close();
1088 return status; 1098 return status;
1089} 1099}
1090 1100
1091QValueList<Event> DateBookDB::getRawRepeats() const 1101QValueList<Event> DateBookDB::getRawRepeats() const
1092{ 1102{
1093 return repeatEvents; 1103 return repeatEvents;
1094} 1104}
1095 1105
1096QValueList<Event> DateBookDB::getNonRepeatingEvents( const QDate &from, 1106QValueList<Event> DateBookDB::getNonRepeatingEvents( const QDate &from,
1097 const QDate &to ) const 1107 const QDate &to ) const
1098{ 1108{
1099 QValueListConstIterator<Event> it; 1109 QValueListConstIterator<Event> it;
1100 QDateTime dtTmp, dtEnd; 1110 QDateTime dtTmp, dtEnd;
1101 QValueList<Event> tmpList; 1111 QValueList<Event> tmpList;
1102 for (it = eventList.begin(); it != eventList.end(); ++it ) { 1112 for (it = eventList.begin(); it != eventList.end(); ++it ) {
1103 dtTmp = (*it).start(TRUE); 1113 dtTmp = (*it).start(TRUE);
1104 dtEnd = (*it).end(TRUE); 1114 dtEnd = (*it).end(TRUE);
1105 1115
1106 if ( dtTmp.date() >= from && dtTmp.date() <= to ) { 1116 if ( dtTmp.date() >= from && dtTmp.date() <= to ) {
1107 Event e = *it; 1117 Event e = *it;
1108 if ( dtTmp.date() != dtEnd.date() ) 1118 if ( dtTmp.date() != dtEnd.date() )
1109 e.setEnd( QDateTime(dtTmp.date(), QTime(23, 59, 0)) ); 1119 e.setEnd( QDateTime(dtTmp.date(), QTime(23, 59, 0)) );
1110 tmpList.append( e ); 1120 tmpList.append( e );
1111 } 1121 }
1112 // we must also check for end date information... 1122 // we must also check for end date information...
1113 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { 1123 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) {
1114 QDateTime dt = dtTmp.addDays( 1 ); 1124 QDateTime dt = dtTmp.addDays( 1 );
1115 dt.setTime( QTime(0, 0, 0) ); 1125 dt.setTime( QTime(0, 0, 0) );
1116 QDateTime dtStop; 1126 QDateTime dtStop;
1117 if ( dtEnd > to ) { 1127 if ( dtEnd > to ) {
1118 dtStop = to; 1128 dtStop = to;
1119 } else 1129 } else
1120 dtStop = dtEnd; 1130 dtStop = dtEnd;
1121 while ( dt <= dtStop ) { 1131 while ( dt <= dtStop ) {
1122 Event ev = *it; 1132 Event ev = *it;
1123 if ( dt >= from ) { 1133 if ( dt >= from ) {
1124 ev.setStart( QDateTime(dt.date(), QTime(0, 0, 0)) ); 1134 ev.setStart( QDateTime(dt.date(), QTime(0, 0, 0)) );
1125 if ( dt.date() == dtEnd.date() ) 1135 if ( dt.date() == dtEnd.date() )
1126 ev.setEnd( QDateTime(dt.date(), dtEnd.time()) ); 1136 ev.setEnd( QDateTime(dt.date(), dtEnd.time()) );
1127 else 1137 else
1128 ev.setEnd( QDateTime(dt.date(), QTime(23, 59, 0)) ); 1138 ev.setEnd( QDateTime(dt.date(), QTime(23, 59, 0)) );
1129 tmpList.append( ev ); 1139 tmpList.append( ev );
1130 } 1140 }
1131 dt = dt.addDays( 1 ); 1141 dt = dt.addDays( 1 );
1132 } 1142 }
1133 } 1143 }
1134 } 1144 }
1135 return tmpList; 1145 return tmpList;
1136} 1146}