-rw-r--r-- | library/datebookdb.cpp | 14 |
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,228 +1,231 @@ | |||
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 | ||
39 | class DateBookDBPrivate | 39 | class DateBookDBPrivate |
40 | { | 40 | { |
41 | public: | 41 | public: |
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 | ||
48 | static QString dateBookJournalFile() | 48 | static 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 | ||
54 | static QString dateBookFilename() | 54 | static 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 */ |
64 | bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) | 64 | bool 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); */ |
@@ -766,256 +769,263 @@ void DateBookDB::loadFile( const QString &strFile ) | |||
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 | ||
927 | void DateBookDB::init() | 937 | void 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 | ||
952 | bool DateBookDB::save() | 962 | bool 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 | } |