summaryrefslogtreecommitdiff
path: root/library
authorwaspe <waspe>2003-11-04 16:59:55 (UTC)
committer waspe <waspe>2003-11-04 16:59:55 (UTC)
commit5865ec3970cead5b2cf3dd255a55cf2e1869e330 (patch) (unidiff)
tree657cab0ca04a93565ee16e79f0aedda63d1923d0 /library
parentda5c9b06fe0081050ab8165cf3d189dbc8117bf6 (diff)
downloadopie-5865ec3970cead5b2cf3dd255a55cf2e1869e330.zip
opie-5865ec3970cead5b2cf3dd255a55cf2e1869e330.tar.gz
opie-5865ec3970cead5b2cf3dd255a55cf2e1869e330.tar.bz2
resloved merge conflict
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,292 +1,295 @@
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) {
@@ -702,384 +705,391 @@ void DateBookDB::loadFile( const QString &strFile )
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();