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