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
@@ -32,133 +32,136 @@
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 */
@@ -830,128 +833,135 @@ void DateBookDB::loadFile( const QString &strFile )
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;