summaryrefslogtreecommitdiff
path: root/library/datebookdb.cpp
Unidiff
Diffstat (limited to 'library/datebookdb.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/datebookdb.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp
index 000ff71..188d8e1 100644
--- a/library/datebookdb.cpp
+++ b/library/datebookdb.cpp
@@ -1,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
39class DateBookDBPrivate 39class DateBookDBPrivate
40{ 40{
41public: 41public:
42 bool clean; // indcate whether we need to write to disk... 42 bool clean; // indcate whether we need to write to disk...
43}; 43};
44 44
45 45
46// Helper functions 46// Helper functions
47 47
48static QString dateBookJournalFile() 48static QString dateBookJournalFile()
49{ 49{
50 QString str = getenv("HOME"); 50 QString str = getenv("HOME");
51 return QString( str +"/.caljournal" ); 51 return QString( str +"/.caljournal" );
52} 52}
53 53
54static QString dateBookFilename() 54static QString dateBookFilename()
55{ 55{
56 return Global::applicationFileName("datebook","datebook.xml"); 56 return Global::applicationFileName("datebook","datebook.xml");
57} 57}
58 58
59/* Calculating the next event of a recuring event is actually 59/* Calculating the next event of a recuring event is actually
60 computationally inexpensive, esp. compared to checking each day 60 computationally inexpensive, esp. compared to checking each day
61 individually. There are bad worse cases for say the 29th of 61 individually. There are bad worse cases for say the 29th of
62 february or the 31st of some other months. However 62 february or the 31st of some other months. However
63 these are still bounded */ 63 these are still bounded */
64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) 64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next)
65{ 65{
66 // easy checks, first are we too far in the future or too far in the past? 66 // easy checks, first are we too far in the future or too far in the past?
67 QDate tmpDate; 67 QDate tmpDate;
68 int freq = e.repeatPattern().frequency; 68 int freq = e.repeatPattern().frequency;
69 int diff, diff2, a; 69 int diff, diff2, a;
70 int iday, imonth, iyear; 70 int iday, imonth, iyear;
71 int dayOfWeek = 0; 71 int dayOfWeek = 0;
72 int firstOfWeek = 0; 72 int firstOfWeek = 0;
73 int weekOfMonth; 73 int weekOfMonth;
74 74
75 75
76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from) 76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from)
77 return FALSE; 77 return FALSE;
78 78
79 if (e.start() >= from) { 79 if (e.start() >= from) {
80 next = e.start(); 80 next = e.start();
81 return TRUE; 81 return TRUE;
82 } 82 }
83 83
84 switch ( e.repeatPattern().type ) { 84 switch ( e.repeatPattern().type ) {
85 case Event::Weekly: 85 case Event::Weekly:
86 /* weekly is just daily by 7 */ 86 /* weekly is just daily by 7 */
87 /* first convert the repeatPattern.Days() mask to the next 87 /* first convert the repeatPattern.Days() mask to the next
88 day of week valid after from */ 88 day of week valid after from */
89 dayOfWeek = from.dayOfWeek(); 89 dayOfWeek = from.dayOfWeek();
90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
91 91
92 /* this is done in case freq > 1 and from in week not 92 /* this is done in case freq > 1 and from in week not
93 for this round */ 93 for this round */
94 // firstOfWeek = 0; this is already done at decl. 94 // firstOfWeek = 0; this is already done at decl.
95 while(!((1 << firstOfWeek) & e.repeatPattern().days)) 95 while(!((1 << firstOfWeek) & e.repeatPattern().days))
96 firstOfWeek++; 96 firstOfWeek++;
97
98
97 99
98 /* there is at least one 'day', or there would be no event */ 100 /* there is at least one 'day', or there would be no event */
99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) 101 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days))
100 dayOfWeek++; 102 dayOfWeek++;
103
101 104
102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */ 105 dayOfWeek = dayOfWeek % 7; /* the actual day of week */
103 dayOfWeek -= e.start().date().dayOfWeek() -1; 106 dayOfWeek -= e.start().date().dayOfWeek() -1;
104 107
105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */ 108 firstOfWeek = firstOfWeek % 7; /* the actual first of week */
106 firstOfWeek -= e.start().date().dayOfWeek() -1; 109 firstOfWeek -= e.start().date().dayOfWeek() -1;
107 110
108 // dayOfWeek may be negitive now 111 // dayOfWeek may be negitive now
109 // day of week is number of days to add to start day 112 // day of week is number of days to add to start day
110 113
111 freq *= 7; 114 freq *= 7;
112 // FALL-THROUGH !!!!! 115 // FALL-THROUGH !!!!!
113 case Event::Daily: 116 case Event::Daily:
114 // the add is for the possible fall through from weekly */ 117 // the add is for the possible fall through from weekly */
115 if(e.start().date().addDays(dayOfWeek) > from) { 118 if(e.start().date().addDays(dayOfWeek) > from) {
116 /* first week exception */ 119 /* first week exception */
117 next = QDateTime(e.start().date().addDays(dayOfWeek), 120 next = QDateTime(e.start().date().addDays(dayOfWeek),
118 e.start().time()); 121 e.start().time());
119 if ((next.date() > e.repeatPattern().endDate()) 122 if ((next.date() > e.repeatPattern().endDate())
120 && e.repeatPattern().hasEndDate) 123 && e.repeatPattern().hasEndDate)
121 return FALSE; 124 return FALSE;
122 return TRUE; 125 return TRUE;
123 } 126 }
124 /* if from is middle of a non-week */ 127 /* if from is middle of a non-week */
125 128
126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; 129 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq;
127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; 130 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq;
128 131
129 if(diff != 0) 132 if(diff != 0)
130 diff = freq - diff; 133 diff = freq - diff;
131 if(diff2 != 0) 134 if(diff2 != 0)
132 diff2 = freq - diff2; 135 diff2 = freq - diff2;
133 diff = QMIN(diff, diff2); 136 diff = QMIN(diff, diff2);
134 137
135 next = QDateTime(from.addDays(diff), e.start().time()); 138 next = QDateTime(from.addDays(diff), e.start().time());
136 if ( (next.date() > e.repeatPattern().endDate()) 139 if ( (next.date() > e.repeatPattern().endDate())
137 && e.repeatPattern().hasEndDate ) 140 && e.repeatPattern().hasEndDate )
138 return FALSE; 141 return FALSE;
139 return TRUE; 142 return TRUE;
140 case Event::MonthlyDay: 143 case Event::MonthlyDay:
141 iday = from.day(); 144 iday = from.day();
142 iyear = from.year(); 145 iyear = from.year();
143 imonth = from.month(); 146 imonth = from.month();
144 /* find equivelent day of month for this month */ 147 /* find equivelent day of month for this month */
145 dayOfWeek = e.start().date().dayOfWeek(); 148 dayOfWeek = e.start().date().dayOfWeek();
146 weekOfMonth = (e.start().date().day() - 1) / 7; 149 weekOfMonth = (e.start().date().day() - 1) / 7;
147 150
148 /* work out when the next valid month is */ 151 /* work out when the next valid month is */
149 a = from.year() - e.start().date().year(); 152 a = from.year() - e.start().date().year();
150 a *= 12; 153 a *= 12;
151 a = a + (imonth - e.start().date().month()); 154 a = a + (imonth - e.start().date().month());
152 /* a is e.start()monthsFrom(from); */ 155 /* a is e.start()monthsFrom(from); */
153 if(a % freq) { 156 if(a % freq) {
154 a = freq - (a % freq); 157 a = freq - (a % freq);
155 imonth = from.month() + a; 158 imonth = from.month() + a;
156 if (imonth > 12) { 159 if (imonth > 12) {
157 imonth--; 160 imonth--;
158 iyear += imonth / 12; 161 iyear += imonth / 12;
159 imonth = imonth % 12; 162 imonth = imonth % 12;
160 imonth++; 163 imonth++;
161 } 164 }
162 } 165 }
163 /* imonth is now the first month after or on 166 /* imonth is now the first month after or on
164 from that matches the frequency given */ 167 from that matches the frequency given */
165 168
166 /* find for this month */ 169 /* find for this month */
167 tmpDate = QDate( iyear, imonth, 1 ); 170 tmpDate = QDate( iyear, imonth, 1 );
168 171
169 iday = 1; 172 iday = 1;
170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 173 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
171 iday += 7 * weekOfMonth; 174 iday += 7 * weekOfMonth;
172 while (iday > tmpDate.daysInMonth()) { 175 while (iday > tmpDate.daysInMonth()) {
173 imonth += freq; 176 imonth += freq;
174 if (imonth > 12) { 177 if (imonth > 12) {
175 imonth--; 178 imonth--;
176 iyear += imonth / 12; 179 iyear += imonth / 12;
177 imonth = imonth % 12; 180 imonth = imonth % 12;
178 imonth++; 181 imonth++;
179 } 182 }
180 tmpDate = QDate( iyear, imonth, 1 ); 183 tmpDate = QDate( iyear, imonth, 1 );
181 /* these loops could go for a while, check end case now */ 184 /* these loops could go for a while, check end case now */
182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 185 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
183 return FALSE; 186 return FALSE;
184 iday = 1; 187 iday = 1;
185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 188 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
186 iday += 7 * weekOfMonth; 189 iday += 7 * weekOfMonth;
187 } 190 }
188 tmpDate = QDate(iyear, imonth, iday); 191 tmpDate = QDate(iyear, imonth, iday);
189 192
190 if (tmpDate >= from) { 193 if (tmpDate >= from) {
191 next = QDateTime(tmpDate, e.start().time()); 194 next = QDateTime(tmpDate, e.start().time());
192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 195 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
193 return FALSE; 196 return FALSE;
194 return TRUE; 197 return TRUE;
195 } 198 }
196 199
197 /* need to find the next iteration */ 200 /* need to find the next iteration */
198 do { 201 do {
199 imonth += freq; 202 imonth += freq;
200 if (imonth > 12) { 203 if (imonth > 12) {
201 imonth--; 204 imonth--;
202 iyear += imonth / 12; 205 iyear += imonth / 12;
203 imonth = imonth % 12; 206 imonth = imonth % 12;
204 imonth++; 207 imonth++;
205 } 208 }
206 tmpDate = QDate( iyear, imonth, 1 ); 209 tmpDate = QDate( iyear, imonth, 1 );
207 /* these loops could go for a while, check end case now */ 210 /* these loops could go for a while, check end case now */
208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 211 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
209 return FALSE; 212 return FALSE;
210 iday = 1; 213 iday = 1;
211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 214 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
212 iday += 7 * weekOfMonth; 215 iday += 7 * weekOfMonth;
213 } while (iday > tmpDate.daysInMonth()); 216 } while (iday > tmpDate.daysInMonth());
214 tmpDate = QDate(iyear, imonth, iday); 217 tmpDate = QDate(iyear, imonth, iday);
215 218
216 next = QDateTime(tmpDate, e.start().time()); 219 next = QDateTime(tmpDate, e.start().time());
217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 220 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
218 return FALSE; 221 return FALSE;
219 return TRUE; 222 return TRUE;
220 case Event::MonthlyDate: 223 case Event::MonthlyDate:
221 iday = e.start().date().day(); 224 iday = e.start().date().day();
222 iyear = from.year(); 225 iyear = from.year();
223 imonth = from.month(); 226 imonth = from.month();
224 227
225 a = from.year() - e.start().date().year(); 228 a = from.year() - e.start().date().year();
226 a *= 12; 229 a *= 12;
227 a = a + (imonth - e.start().date().month()); 230 a = a + (imonth - e.start().date().month());
228 /* a is e.start()monthsFrom(from); */ 231 /* a is e.start()monthsFrom(from); */
@@ -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
927void DateBookDB::init() 937void DateBookDB::init()
928{ 938{
929 d = new DateBookDBPrivate; 939 d = new DateBookDBPrivate;
930 d->clean = false; 940 d->clean = false;
931 QString str = dateBookFilename(); 941 QString str = dateBookFilename();
932 if ( str.isNull() ) { 942 if ( str.isNull() ) {
933 QMessageBox::warning( 0, QObject::tr("Out of Space"), 943 QMessageBox::warning( 0, QObject::tr("Out of Space"),
934 QObject::tr("Unable to create start up files\n" 944 QObject::tr("Unable to create start up files\n"
935 "Please free up some space\n" 945 "Please free up some space\n"
936 "before entering data") ); 946 "before entering data") );
937 } 947 }
938 // continuing along, we call this datebook filename again, 948 // continuing along, we call this datebook filename again,
939 // because they may fix it before continuing, though it seems 949 // because they may fix it before continuing, though it seems
940 // pretty unlikely... 950 // pretty unlikely...
941 loadFile( dateBookFilename() ); 951 loadFile( dateBookFilename() );
942 952
943 if ( QFile::exists( dateBookJournalFile() ) ) { 953 if ( QFile::exists( dateBookJournalFile() ) ) {
944 // merge the journal 954 // merge the journal
945 loadFile( dateBookJournalFile() ); 955 loadFile( dateBookJournalFile() );
946 // save in our changes and remove the journal... 956 // save in our changes and remove the journal...
947 save(); 957 save();
948 } 958 }
949 d->clean = true; 959 d->clean = true;
950} 960}
951 961
952bool DateBookDB::save() 962bool DateBookDB::save()
953{ 963{
954 if ( d->clean == true ) 964 if ( d->clean == true )
955 return true; 965 return true;
956 QValueListIterator<Event> it; 966 QValueListIterator<Event> it;
957 int total_written; 967 int total_written;
958 QString strFileNew = dateBookFilename() + ".new"; 968 QString strFileNew = dateBookFilename() + ".new";
959 969
960 QFile f( strFileNew ); 970 QFile f( strFileNew );
961 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 971 if ( !f.open( IO_WriteOnly|IO_Raw ) )
962 return FALSE; 972 return FALSE;
963 973
964 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 974 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
965 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 975 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
966 buf += "<events>\n"; 976 buf += "<events>\n";
967 QCString str = buf.utf8(); 977 QCString str = buf.utf8();
968 total_written = f.writeBlock( str.data(), str.length() ); 978 total_written = f.writeBlock( str.data(), str.length() );
969 if ( total_written != int(str.length()) ) { 979 if ( total_written != int(str.length()) ) {
970 f.close(); 980 f.close();
971 QFile::remove( strFileNew ); 981 QFile::remove( strFileNew );
972 return false; 982 return false;
973 } 983 }
974 984
975 for ( it = eventList.begin(); it != eventList.end(); ++it ) { 985 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
976 buf = "<event"; 986 buf = "<event";
977 (*it).save( buf ); 987 (*it).save( buf );
978 buf += " />\n"; 988 buf += " />\n";
979 str = buf.utf8(); 989 str = buf.utf8();
980 total_written = f.writeBlock( str.data(), str.length() ); 990 total_written = f.writeBlock( str.data(), str.length() );
981 if ( total_written != int(str.length()) ) { 991 if ( total_written != int(str.length()) ) {
982 f.close(); 992 f.close();
983 QFile::remove( strFileNew ); 993 QFile::remove( strFileNew );
984 return false; 994 return false;
985 } 995 }
986 } 996 }
987 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 997 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
988 buf = "<event"; 998 buf = "<event";
989 (*it).save( buf ); 999 (*it).save( buf );
990 buf += " />\n"; 1000 buf += " />\n";
991 str = buf.utf8(); 1001 str = buf.utf8();
992 total_written = f.writeBlock( str.data(), str.length() ); 1002 total_written = f.writeBlock( str.data(), str.length() );
993 if ( total_written != int(str.length()) ) { 1003 if ( total_written != int(str.length()) ) {
994 f.close(); 1004 f.close();
995 QFile::remove( strFileNew ); 1005 QFile::remove( strFileNew );
996 return false; 1006 return false;
997 } 1007 }
998 } 1008 }
999 buf = "</events>\n</DATEBOOK>\n"; 1009 buf = "</events>\n</DATEBOOK>\n";
1000 str = buf.utf8(); 1010 str = buf.utf8();
1001 total_written = f.writeBlock( str.data(), str.length() ); 1011 total_written = f.writeBlock( str.data(), str.length() );
1002 if ( total_written != int(str.length()) ) { 1012 if ( total_written != int(str.length()) ) {
1003 f.close(); 1013 f.close();
1004 QFile::remove( strFileNew ); 1014 QFile::remove( strFileNew );
1005 return false; 1015 return false;
1006 } 1016 }
1007 f.close(); 1017 f.close();
1008 1018
1009 // now rename... I like to use the systemcall 1019 // now rename... I like to use the systemcall
1010 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) { 1020 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) {
1011 qWarning( "problem renaming file %s to %s errno %d", 1021 qWarning( "problem renaming file %s to %s errno %d",
1012 strFileNew.latin1(), dateBookFilename().latin1(), errno ); 1022 strFileNew.latin1(), dateBookFilename().latin1(), errno );
1013 // remove the file, otherwise it will just stick around... 1023 // remove the file, otherwise it will just stick around...
1014 QFile::remove( strFileNew ); 1024 QFile::remove( strFileNew );
1015 } 1025 }
1016 1026
1017 // may as well remove the journal file... 1027 // may as well remove the journal file...
1018 QFile::remove( dateBookJournalFile() ); 1028 QFile::remove( dateBookJournalFile() );
1019 d->clean = true; 1029 d->clean = true;
1020 return true; 1030 return true;
1021} 1031}