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