summaryrefslogtreecommitdiff
path: root/libopie
authoreilers <eilers>2003-11-10 08:28:38 (UTC)
committer eilers <eilers>2003-11-10 08:28:38 (UTC)
commitf3326a60ba002b420f33b6132dc1740c0fc4ffef (patch) (unidiff)
tree6809f30857a241cf3334f7d25f60edc6fbb83901 /libopie
parentefa3f9a756fb5a9afd0d35bc783e1331bf40bc6a (diff)
downloadopie-f3326a60ba002b420f33b6132dc1740c0fc4ffef.zip
opie-f3326a60ba002b420f33b6132dc1740c0fc4ffef.tar.gz
opie-f3326a60ba002b420f33b6132dc1740c0fc4ffef.tar.bz2
Platform MacOS-X: Disable backtrce in odebug..
Libopie PIM: Finishing SQL-Backend for Todo. Recurrance events are supported now. What is still missing: Custom entries currently not stored. It isn't easy to implement them with enabled prefetch-cache. LibopieDB2: Adding -lsqlite here instead linking it to libopie
Diffstat (limited to 'libopie') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro2
-rw-r--r--libopie/pim/orecur.cpp147
-rw-r--r--libopie/pim/orecur.h12
-rw-r--r--libopie/pim/otodoaccesssql.cpp31
4 files changed, 150 insertions, 42 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index bf6b78f..94434ae 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -1,132 +1,132 @@
1TEMPLATE = lib 1TEMPLATE = lib
2CONFIG += qte warn_on release 2CONFIG += qte warn_on release
3HEADERS = ofontmenu.h \ 3HEADERS = ofontmenu.h \
4 ocolorbutton.h \ 4 ocolorbutton.h \
5 ofiledialog.h ofileselector.h \ 5 ofiledialog.h ofileselector.h \
6 ofileselector_p.h \ 6 ofileselector_p.h \
7 ocheckitem.h \ 7 ocheckitem.h \
8 xmltree.h \ 8 xmltree.h \
9 colordialog.h colorpopupmenu.h \ 9 colordialog.h colorpopupmenu.h \
10 oclickablelabel.h oprocctrl.h \ 10 oclickablelabel.h oprocctrl.h \
11 oprocess.h odevice.h odevicebutton.h \ 11 oprocess.h odevice.h odevicebutton.h \
12 otimepicker.h otabwidget.h \ 12 otimepicker.h otabwidget.h \
13 otabbar.h otabinfo.h \ 13 otabbar.h otabinfo.h \
14 ofontselector.h \ 14 ofontselector.h \
15 pim/opimrecord.h \ 15 pim/opimrecord.h \
16 pim/otodo.h \ 16 pim/otodo.h \
17 pim/orecordlist.h \ 17 pim/orecordlist.h \
18 pim/opimaccesstemplate.h \ 18 pim/opimaccesstemplate.h \
19 pim/opimaccessbackend.h \ 19 pim/opimaccessbackend.h \
20 pim/otodoaccess.h \ 20 pim/otodoaccess.h \
21 pim/otodoaccessbackend.h \ 21 pim/otodoaccessbackend.h \
22 pim/oconversion.h \ 22 pim/oconversion.h \
23 pim/ocontact.h \ 23 pim/ocontact.h \
24 pim/ocontactfields.h \ 24 pim/ocontactfields.h \
25 pim/ocontactaccess.h \ 25 pim/ocontactaccess.h \
26 pim/ocontactaccessbackend.h \ 26 pim/ocontactaccessbackend.h \
27 pim/ocontactaccessbackend_xml.h \ 27 pim/ocontactaccessbackend_xml.h \
28 pim/ocontactaccessbackend_vcard.h \ 28 pim/ocontactaccessbackend_vcard.h \
29 pim/obackendfactory.h \ 29 pim/obackendfactory.h \
30 pim/opimcache.h \ 30 pim/opimcache.h \
31 pim/otodoaccessvcal.h \ 31 pim/otodoaccessvcal.h \
32 pim/orecur.h \ 32 pim/orecur.h \
33 pim/opimstate.h \ 33 pim/opimstate.h \
34 pim/opimxrefpartner.h \ 34 pim/opimxrefpartner.h \
35 pim/opimxref.h \ 35 pim/opimxref.h \
36 pim/opimxrefmanager.h \ 36 pim/opimxrefmanager.h \
37 pim/opimmaintainer.h \ 37 pim/opimmaintainer.h \
38 pim/opimnotify.h \ 38 pim/opimnotify.h \
39 pim/opimnotifymanager.h \ 39 pim/opimnotifymanager.h \
40 pim/opimmainwindow.h \ 40 pim/opimmainwindow.h \
41 pim/opimresolver.h \ 41 pim/opimresolver.h \
42 pim/oevent.h \ 42 pim/oevent.h \
43 pim/otimezone.h \ 43 pim/otimezone.h \
44 pim/odatebookaccess.h \ 44 pim/odatebookaccess.h \
45 pim/odatebookaccessbackend.h \ 45 pim/odatebookaccessbackend.h \
46 pim/odatebookaccessbackend_xml.h \ 46 pim/odatebookaccessbackend_xml.h \
47 orecurrancewidget.h \ 47 orecurrancewidget.h \
48 oticker.h owait.h 48 oticker.h owait.h
49 49
50SOURCES = ofontmenu.cc \ 50SOURCES = ofontmenu.cc \
51 ocolorbutton.cpp \ 51 ocolorbutton.cpp \
52 sharp_compat.cpp \ 52 sharp_compat.cpp \
53 xmltree.cc \ 53 xmltree.cc \
54 ofiledialog.cc ofileselector.cpp \ 54 ofiledialog.cc ofileselector.cpp \
55 ocheckitem.cpp \ 55 ocheckitem.cpp \
56 colordialog.cpp \ 56 colordialog.cpp \
57 colorpopupmenu.cpp oclickablelabel.cpp \ 57 colorpopupmenu.cpp oclickablelabel.cpp \
58 oprocctrl.cpp oprocess.cpp \ 58 oprocctrl.cpp oprocess.cpp \
59 odevice.cpp odevicebutton.cpp otimepicker.cpp \ 59 odevice.cpp odevicebutton.cpp otimepicker.cpp \
60 otabwidget.cpp otabbar.cpp \ 60 otabwidget.cpp otabbar.cpp \
61 ofontselector.cpp \ 61 ofontselector.cpp \
62 pim/otodo.cpp \ 62 pim/otodo.cpp \
63 pim/opimrecord.cpp \ 63 pim/opimrecord.cpp \
64 pim/otodoaccess.cpp \ 64 pim/otodoaccess.cpp \
65 pim/otodoaccessbackend.cpp \ 65 pim/otodoaccessbackend.cpp \
66 pim/otodoaccessxml.cpp \ 66 pim/otodoaccessxml.cpp \
67 pim/oconversion.cpp \ 67 pim/oconversion.cpp \
68 pim/ocontact.cpp \ 68 pim/ocontact.cpp \
69 pim/ocontactfields.cpp \ 69 pim/ocontactfields.cpp \
70 pim/ocontactaccess.cpp \ 70 pim/ocontactaccess.cpp \
71 pim/ocontactaccessbackend_vcard.cpp \ 71 pim/ocontactaccessbackend_vcard.cpp \
72 pim/ocontactaccessbackend_xml.cpp \ 72 pim/ocontactaccessbackend_xml.cpp \
73 pim/otodoaccessvcal.cpp \ 73 pim/otodoaccessvcal.cpp \
74 pim/orecur.cpp \ 74 pim/orecur.cpp \
75 pim/opimstate.cpp \ 75 pim/opimstate.cpp \
76 pim/opimxrefpartner.cpp \ 76 pim/opimxrefpartner.cpp \
77 pim/opimxref.cpp \ 77 pim/opimxref.cpp \
78 pim/opimxrefmanager.cpp \ 78 pim/opimxrefmanager.cpp \
79 pim/opimmaintainer.cpp \ 79 pim/opimmaintainer.cpp \
80 pim/opimnotify.cpp \ 80 pim/opimnotify.cpp \
81 pim/opimnotifymanager.cpp \ 81 pim/opimnotifymanager.cpp \
82 pim/opimmainwindow.cpp \ 82 pim/opimmainwindow.cpp \
83 pim/opimresolver.cpp \ 83 pim/opimresolver.cpp \
84 pim/oevent.cpp \ 84 pim/oevent.cpp \
85 pim/otimezone.cpp \ 85 pim/otimezone.cpp \
86 pim/odatebookaccess.cpp \ 86 pim/odatebookaccess.cpp \
87 pim/odatebookaccessbackend.cpp \ 87 pim/odatebookaccessbackend.cpp \
88 pim/odatebookaccessbackend_xml.cpp \ 88 pim/odatebookaccessbackend_xml.cpp \
89 orecurrancewidget.cpp \ 89 orecurrancewidget.cpp \
90 oticker.cpp owait.cpp 90 oticker.cpp owait.cpp
91 91
92TARGET = opie 92TARGET = opie
93INCLUDEPATH += $(OPIEDIR)/include 93INCLUDEPATH += $(OPIEDIR)/include
94DESTDIR = $(OPIEDIR)/lib$(PROJMAK) 94DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
95 95
96LIBS += -lqpe 96LIBS += -lqpe
97 97
98# Add SQL-Support if selected by config (eilers) 98# Add SQL-Support if selected by config (eilers)
99CONFTEST = $$system( echo $CONFIG_SQL_PIM_BACKEND ) 99CONFTEST = $$system( echo $CONFIG_SQL_PIM_BACKEND )
100contains( CONFTEST, y ){ 100contains( CONFTEST, y ){
101 101
102DEFINES += __USE_SQL 102DEFINES += __USE_SQL
103LIBS += -lopiedb2 -lsqlite 103LIBS += -lopiedb2
104HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h 104HEADERS += pim/otodoaccesssql.h pim/ocontactaccessbackend_sql.h
105SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp 105SOURCES += pim/otodoaccesssql.cpp pim/ocontactaccessbackend_sql.cpp
106 106
107} 107}
108 108
109INTERFACES = otimepickerbase.ui orecurrancebase.ui 109INTERFACES = otimepickerbase.ui orecurrancebase.ui
110TARGET = opie 110TARGET = opie
111 111
112TRANSLATIONS = ../i18n/de/libopie.ts \ 112TRANSLATIONS = ../i18n/de/libopie.ts \
113 ../i18n/nl/libopie.ts \ 113 ../i18n/nl/libopie.ts \
114 ../i18n/xx/libopie.ts \ 114 ../i18n/xx/libopie.ts \
115 ../i18n/en/libopie.ts \ 115 ../i18n/en/libopie.ts \
116 ../i18n/es/libopie.ts \ 116 ../i18n/es/libopie.ts \
117 ../i18n/fr/libopie.ts \ 117 ../i18n/fr/libopie.ts \
118 ../i18n/hu/libopie.ts \ 118 ../i18n/hu/libopie.ts \
119 ../i18n/ja/libopie.ts \ 119 ../i18n/ja/libopie.ts \
120 ../i18n/ko/libopie.ts \ 120 ../i18n/ko/libopie.ts \
121 ../i18n/no/libopie.ts \ 121 ../i18n/no/libopie.ts \
122 ../i18n/pl/libopie.ts \ 122 ../i18n/pl/libopie.ts \
123 ../i18n/pt/libopie.ts \ 123 ../i18n/pt/libopie.ts \
124 ../i18n/pt_BR/libopie.ts \ 124 ../i18n/pt_BR/libopie.ts \
125 ../i18n/sl/libopie.ts \ 125 ../i18n/sl/libopie.ts \
126 ../i18n/zh_CN/libopie.ts \ 126 ../i18n/zh_CN/libopie.ts \
127 ../i18n/zh_TW/libopie.ts \ 127 ../i18n/zh_TW/libopie.ts \
128 ../i18n/da/libopie.ts 128 ../i18n/da/libopie.ts
129 129
130include ( big-screen/big-screen.pro ) 130include ( big-screen/big-screen.pro )
131 131
132include ( $(OPIEDIR)/include.pro ) 132include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/orecur.cpp b/libopie/pim/orecur.cpp
index eae1fdc..8c9ad46 100644
--- a/libopie/pim/orecur.cpp
+++ b/libopie/pim/orecur.cpp
@@ -1,510 +1,585 @@
1#include <time.h> 1#include <time.h>
2 2
3#include <qshared.h> 3#include <qshared.h>
4 4
5#include <qtopia/timeconversion.h> 5#include <qtopia/timeconversion.h>
6 6
7#include "otimezone.h" 7#include "otimezone.h"
8#include "orecur.h" 8#include "orecur.h"
9 9
10struct ORecur::Data : public QShared { 10struct ORecur::Data : public QShared {
11 Data() : QShared() { 11 Data() : QShared() {
12 type = ORecur::NoRepeat; 12 type = ORecur::NoRepeat;
13 freq = -1; 13 freq = -1;
14 days = 0; 14 days = 0;
15 pos = 0; 15 pos = 0;
16 create = QDateTime::currentDateTime(); 16 create = QDateTime::currentDateTime();
17 hasEnd = FALSE; 17 hasEnd = FALSE;
18 end = QDate::currentDate(); 18 end = QDate::currentDate();
19 } 19 }
20 char days; // Q_UINT8 for 8 seven days;) 20 char days; // Q_UINT8 for 8 seven days;)
21 ORecur::RepeatType type; 21 ORecur::RepeatType type;
22 int freq; 22 int freq;
23 int pos; 23 int pos;
24 bool hasEnd : 1; 24 bool hasEnd : 1;
25 QDate end; 25 QDate end;
26 QDateTime create; 26 QDateTime create;
27 int rep; 27 int rep;
28 QString app; 28 QString app;
29 ExceptionList list; 29 ExceptionList list;
30 QDate start; 30 QDate start;
31}; 31};
32 32
33 33
34ORecur::ORecur() { 34ORecur::ORecur() {
35 data = new Data; 35 data = new Data;
36} 36}
37ORecur::ORecur( const ORecur& rec) 37ORecur::ORecur( const ORecur& rec)
38 : data( rec.data ) 38 : data( rec.data )
39{ 39{
40 data->ref(); 40 data->ref();
41} 41}
42ORecur::~ORecur() { 42ORecur::~ORecur() {
43 if ( data->deref() ) { 43 if ( data->deref() ) {
44 delete data; 44 delete data;
45 data = 0l; 45 data = 0l;
46 } 46 }
47} 47}
48void ORecur::deref() { 48void ORecur::deref() {
49 if ( data->deref() ) { 49 if ( data->deref() ) {
50 delete data; 50 delete data;
51 data = 0l; 51 data = 0l;
52 } 52 }
53} 53}
54bool ORecur::operator==( const ORecur& )const { 54bool ORecur::operator==( const ORecur& )const {
55 return false; 55 return false;
56} 56}
57ORecur &ORecur::operator=( const ORecur& re) { 57ORecur &ORecur::operator=( const ORecur& re) {
58 if ( *this == re ) return *this; 58 if ( *this == re ) return *this;
59 59
60 re.data->ref(); 60 re.data->ref();
61 deref(); 61 deref();
62 data = re.data; 62 data = re.data;
63 63
64 return *this; 64 return *this;
65} 65}
66bool ORecur::doesRecur()const { 66bool ORecur::doesRecur()const {
67 return !( type() == NoRepeat ); 67 return !( type() == NoRepeat );
68} 68}
69/* 69/*
70 * we try to be smart here 70 * we try to be smart here
71 * 71 *
72 */ 72 */
73bool ORecur::doesRecur( const QDate& date ) { 73bool ORecur::doesRecur( const QDate& date ) {
74 /* the day before the recurrance */ 74 /* the day before the recurrance */
75 QDate da = date.addDays(-1); 75 QDate da = date.addDays(-1);
76 76
77 QDate recur; 77 QDate recur;
78 if (!nextOcurrence( da, recur ) ) 78 if (!nextOcurrence( da, recur ) )
79 return false; 79 return false;
80 80
81 return (recur == date); 81 return (recur == date);
82} 82}
83// FIXME unuglify! 83// FIXME unuglify!
84// GPL from Datebookdb.cpp 84// GPL from Datebookdb.cpp
85// FIXME exception list! 85// FIXME exception list!
86bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { 86bool ORecur::nextOcurrence( const QDate& from, QDate& next ) {
87 bool stillLooking; 87 bool stillLooking;
88 stillLooking = p_nextOccurrence( from, next ); 88 stillLooking = p_nextOccurrence( from, next );
89 while ( stillLooking && data->list.contains(next) ) 89 while ( stillLooking && data->list.contains(next) )
90 stillLooking = p_nextOccurrence( next.addDays(1), next ); 90 stillLooking = p_nextOccurrence( next.addDays(1), next );
91 91
92 return stillLooking; 92 return stillLooking;
93} 93}
94bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) { 94bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) {
95 95
96 // easy checks, first are we too far in the future or too far in the past? 96 // easy checks, first are we too far in the future or too far in the past?
97 QDate tmpDate; 97 QDate tmpDate;
98 int freq = frequency(); 98 int freq = frequency();
99 int diff, diff2, a; 99 int diff, diff2, a;
100 int iday, imonth, iyear; 100 int iday, imonth, iyear;
101 int dayOfWeek = 0; 101 int dayOfWeek = 0;
102 int firstOfWeek = 0; 102 int firstOfWeek = 0;
103 int weekOfMonth; 103 int weekOfMonth;
104 104
105 105
106 if (hasEndDate() && endDate() < from) 106 if (hasEndDate() && endDate() < from)
107 return FALSE; 107 return FALSE;
108 108
109 if (start() >= from ) { 109 if (start() >= from ) {
110 next = start(); 110 next = start();
111 return TRUE; 111 return TRUE;
112 } 112 }
113 113
114 switch ( type() ) { 114 switch ( type() ) {
115 case Weekly: 115 case Weekly:
116 /* weekly is just daily by 7 */ 116 /* weekly is just daily by 7 */
117 /* first convert the repeatPattern.Days() mask to the next 117 /* first convert the repeatPattern.Days() mask to the next
118 day of week valid after from */ 118 day of week valid after from */
119 dayOfWeek = from.dayOfWeek(); 119 dayOfWeek = from.dayOfWeek();
120 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 120 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
121 121
122 /* this is done in case freq > 1 and from in week not 122 /* this is done in case freq > 1 and from in week not
123 for this round */ 123 for this round */
124 // firstOfWeek = 0; this is already done at decl. 124 // firstOfWeek = 0; this is already done at decl.
125 while(!((1 << firstOfWeek) & days() )) 125 while(!((1 << firstOfWeek) & days() ))
126 firstOfWeek++; 126 firstOfWeek++;
127 127
128 /* there is at least one 'day', or there would be no event */ 128 /* there is at least one 'day', or there would be no event */
129 while(!((1 << (dayOfWeek % 7)) & days() )) 129 while(!((1 << (dayOfWeek % 7)) & days() ))
130 dayOfWeek++; 130 dayOfWeek++;
131 131
132 dayOfWeek = dayOfWeek % 7; /* the actual day of week */ 132 dayOfWeek = dayOfWeek % 7; /* the actual day of week */
133 dayOfWeek -= start().dayOfWeek() -1; 133 dayOfWeek -= start().dayOfWeek() -1;
134 134
135 firstOfWeek = firstOfWeek % 7; /* the actual first of week */ 135 firstOfWeek = firstOfWeek % 7; /* the actual first of week */
136 firstOfWeek -= start().dayOfWeek() -1; 136 firstOfWeek -= start().dayOfWeek() -1;
137 137
138 // dayOfWeek may be negitive now 138 // dayOfWeek may be negitive now
139 // day of week is number of days to add to start day 139 // day of week is number of days to add to start day
140 140
141 freq *= 7; 141 freq *= 7;
142 // FALL-THROUGH !!!!! 142 // FALL-THROUGH !!!!!
143 case Daily: 143 case Daily:
144 // the add is for the possible fall through from weekly */ 144 // the add is for the possible fall through from weekly */
145 if(start().addDays(dayOfWeek) > from) { 145 if(start().addDays(dayOfWeek) > from) {
146 /* first week exception */ 146 /* first week exception */
147 next = QDate(start().addDays(dayOfWeek) ); 147 next = QDate(start().addDays(dayOfWeek) );
148 if ((next > endDate()) 148 if ((next > endDate())
149 && hasEndDate() ) 149 && hasEndDate() )
150 return FALSE; 150 return FALSE;
151 return TRUE; 151 return TRUE;
152 } 152 }
153 /* if from is middle of a non-week */ 153 /* if from is middle of a non-week */
154 154
155 diff = start().addDays(dayOfWeek).daysTo(from) % freq; 155 diff = start().addDays(dayOfWeek).daysTo(from) % freq;
156 diff2 = start().addDays(firstOfWeek).daysTo(from) % freq; 156 diff2 = start().addDays(firstOfWeek).daysTo(from) % freq;
157 157
158 if(diff != 0) 158 if(diff != 0)
159 diff = freq - diff; 159 diff = freq - diff;
160 if(diff2 != 0) 160 if(diff2 != 0)
161 diff2 = freq - diff2; 161 diff2 = freq - diff2;
162 diff = QMIN(diff, diff2); 162 diff = QMIN(diff, diff2);
163 163
164 next = QDate(from.addDays(diff)); 164 next = QDate(from.addDays(diff));
165 if ( (next > endDate()) 165 if ( (next > endDate())
166 && hasEndDate() ) 166 && hasEndDate() )
167 return FALSE; 167 return FALSE;
168 return TRUE; 168 return TRUE;
169 case MonthlyDay: 169 case MonthlyDay:
170 iday = from.day(); 170 iday = from.day();
171 iyear = from.year(); 171 iyear = from.year();
172 imonth = from.month(); 172 imonth = from.month();
173 /* find equivelent day of month for this month */ 173 /* find equivelent day of month for this month */
174 dayOfWeek = start().dayOfWeek(); 174 dayOfWeek = start().dayOfWeek();
175 weekOfMonth = (start().day() - 1) / 7; 175 weekOfMonth = (start().day() - 1) / 7;
176 176
177 /* work out when the next valid month is */ 177 /* work out when the next valid month is */
178 a = from.year() - start().year(); 178 a = from.year() - start().year();
179 a *= 12; 179 a *= 12;
180 a = a + (imonth - start().month()); 180 a = a + (imonth - start().month());
181 /* a is e.start()monthsFrom(from); */ 181 /* a is e.start()monthsFrom(from); */
182 if(a % freq) { 182 if(a % freq) {
183 a = freq - (a % freq); 183 a = freq - (a % freq);
184 imonth = from.month() + a; 184 imonth = from.month() + a;
185 if (imonth > 12) { 185 if (imonth > 12) {
186 imonth--; 186 imonth--;
187 iyear += imonth / 12; 187 iyear += imonth / 12;
188 imonth = imonth % 12; 188 imonth = imonth % 12;
189 imonth++; 189 imonth++;
190 } 190 }
191 } 191 }
192 /* imonth is now the first month after or on 192 /* imonth is now the first month after or on
193 from that matches the frequency given */ 193 from that matches the frequency given */
194 194
195 /* find for this month */ 195 /* find for this month */
196 tmpDate = QDate( iyear, imonth, 1 ); 196 tmpDate = QDate( iyear, imonth, 1 );
197 197
198 iday = 1; 198 iday = 1;
199 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 199 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
200 iday += 7 * weekOfMonth; 200 iday += 7 * weekOfMonth;
201 while (iday > tmpDate.daysInMonth()) { 201 while (iday > tmpDate.daysInMonth()) {
202 imonth += freq; 202 imonth += freq;
203 if (imonth > 12) { 203 if (imonth > 12) {
204 imonth--; 204 imonth--;
205 iyear += imonth / 12; 205 iyear += imonth / 12;
206 imonth = imonth % 12; 206 imonth = imonth % 12;
207 imonth++; 207 imonth++;
208 } 208 }
209 tmpDate = QDate( iyear, imonth, 1 ); 209 tmpDate = QDate( iyear, imonth, 1 );
210 /* these loops could go for a while, check end case now */ 210 /* these loops could go for a while, check end case now */
211 if ((tmpDate > endDate()) && hasEndDate() ) 211 if ((tmpDate > endDate()) && hasEndDate() )
212 return FALSE; 212 return FALSE;
213 iday = 1; 213 iday = 1;
214 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 214 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
215 iday += 7 * weekOfMonth; 215 iday += 7 * weekOfMonth;
216 } 216 }
217 tmpDate = QDate(iyear, imonth, iday); 217 tmpDate = QDate(iyear, imonth, iday);
218 218
219 if (tmpDate >= from) { 219 if (tmpDate >= from) {
220 next = tmpDate; 220 next = tmpDate;
221 if ((next > endDate() ) && hasEndDate() ) 221 if ((next > endDate() ) && hasEndDate() )
222 return FALSE; 222 return FALSE;
223 return TRUE; 223 return TRUE;
224 } 224 }
225 225
226 /* need to find the next iteration */ 226 /* need to find the next iteration */
227 do { 227 do {
228 imonth += freq; 228 imonth += freq;
229 if (imonth > 12) { 229 if (imonth > 12) {
230 imonth--; 230 imonth--;
231 iyear += imonth / 12; 231 iyear += imonth / 12;
232 imonth = imonth % 12; 232 imonth = imonth % 12;
233 imonth++; 233 imonth++;
234 } 234 }
235 tmpDate = QDate( iyear, imonth, 1 ); 235 tmpDate = QDate( iyear, imonth, 1 );
236 /* these loops could go for a while, check end case now */ 236 /* these loops could go for a while, check end case now */
237 if ((tmpDate > endDate()) && hasEndDate() ) 237 if ((tmpDate > endDate()) && hasEndDate() )
238 return FALSE; 238 return FALSE;
239 iday = 1; 239 iday = 1;
240 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 240 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
241 iday += 7 * weekOfMonth; 241 iday += 7 * weekOfMonth;
242 } while (iday > tmpDate.daysInMonth()); 242 } while (iday > tmpDate.daysInMonth());
243 tmpDate = QDate(iyear, imonth, iday); 243 tmpDate = QDate(iyear, imonth, iday);
244 244
245 next = tmpDate; 245 next = tmpDate;
246 if ((next > endDate()) && hasEndDate() ) 246 if ((next > endDate()) && hasEndDate() )
247 return FALSE; 247 return FALSE;
248 return TRUE; 248 return TRUE;
249 case MonthlyDate: 249 case MonthlyDate:
250 iday = start().day(); 250 iday = start().day();
251 iyear = from.year(); 251 iyear = from.year();
252 imonth = from.month(); 252 imonth = from.month();
253 253
254 a = from.year() - start().year(); 254 a = from.year() - start().year();
255 a *= 12; 255 a *= 12;
256 a = a + (imonth - start().month()); 256 a = a + (imonth - start().month());
257 /* a is e.start()monthsFrom(from); */ 257 /* a is e.start()monthsFrom(from); */
258 if(a % freq) { 258 if(a % freq) {
259 a = freq - (a % freq); 259 a = freq - (a % freq);
260 imonth = from.month() + a; 260 imonth = from.month() + a;
261 if (imonth > 12) { 261 if (imonth > 12) {
262 imonth--; 262 imonth--;
263 iyear += imonth / 12; 263 iyear += imonth / 12;
264 imonth = imonth % 12; 264 imonth = imonth % 12;
265 imonth++; 265 imonth++;
266 } 266 }
267 } 267 }
268 /* imonth is now the first month after or on 268 /* imonth is now the first month after or on
269 from that matches the frequencey given */ 269 from that matches the frequencey given */
270 270
271 /* this could go for a while, worse case, 4*12 iterations, probably */ 271 /* this could go for a while, worse case, 4*12 iterations, probably */
272 while(!QDate::isValid(iyear, imonth, iday) ) { 272 while(!QDate::isValid(iyear, imonth, iday) ) {
273 imonth += freq; 273 imonth += freq;
274 if (imonth > 12) { 274 if (imonth > 12) {
275 imonth--; 275 imonth--;
276 iyear += imonth / 12; 276 iyear += imonth / 12;
277 imonth = imonth % 12; 277 imonth = imonth % 12;
278 imonth++; 278 imonth++;
279 } 279 }
280 /* these loops could go for a while, check end case now */ 280 /* these loops could go for a while, check end case now */
281 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) 281 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
282 return FALSE; 282 return FALSE;
283 } 283 }
284 284
285 if(QDate(iyear, imonth, iday) >= from) { 285 if(QDate(iyear, imonth, iday) >= from) {
286 /* done */ 286 /* done */
287 next = QDate(iyear, imonth, iday); 287 next = QDate(iyear, imonth, iday);
288 if ((next > endDate()) && hasEndDate() ) 288 if ((next > endDate()) && hasEndDate() )
289 return FALSE; 289 return FALSE;
290 return TRUE; 290 return TRUE;
291 } 291 }
292 292
293 /* ok, need to cycle */ 293 /* ok, need to cycle */
294 imonth += freq; 294 imonth += freq;
295 imonth--; 295 imonth--;
296 iyear += imonth / 12; 296 iyear += imonth / 12;
297 imonth = imonth % 12; 297 imonth = imonth % 12;
298 imonth++; 298 imonth++;
299 299
300 while(!QDate::isValid(iyear, imonth, iday) ) { 300 while(!QDate::isValid(iyear, imonth, iday) ) {
301 imonth += freq; 301 imonth += freq;
302 imonth--; 302 imonth--;
303 iyear += imonth / 12; 303 iyear += imonth / 12;
304 imonth = imonth % 12; 304 imonth = imonth % 12;
305 imonth++; 305 imonth++;
306 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() ) 306 if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
307 return FALSE; 307 return FALSE;
308 } 308 }
309 309
310 next = QDate(iyear, imonth, iday); 310 next = QDate(iyear, imonth, iday);
311 if ((next > endDate()) && hasEndDate() ) 311 if ((next > endDate()) && hasEndDate() )
312 return FALSE; 312 return FALSE;
313 return TRUE; 313 return TRUE;
314 case Yearly: 314 case Yearly:
315 iday = start().day(); 315 iday = start().day();
316 imonth = start().month(); 316 imonth = start().month();
317 iyear = from.year(); // after all, we want to start in this year 317 iyear = from.year(); // after all, we want to start in this year
318 318
319 diff = 1; 319 diff = 1;
320 if(imonth == 2 && iday > 28) { 320 if(imonth == 2 && iday > 28) {
321 /* leap year, and it counts, calculate actual frequency */ 321 /* leap year, and it counts, calculate actual frequency */
322 if(freq % 4) 322 if(freq % 4)
323 if (freq % 2) 323 if (freq % 2)
324 freq = freq * 4; 324 freq = freq * 4;
325 else 325 else
326 freq = freq * 2; 326 freq = freq * 2;
327 /* else divides by 4 already, leave freq alone */ 327 /* else divides by 4 already, leave freq alone */
328 diff = 4; 328 diff = 4;
329 } 329 }
330 330
331 a = from.year() - start().year(); 331 a = from.year() - start().year();
332 if(a % freq) { 332 if(a % freq) {
333 a = freq - (a % freq); 333 a = freq - (a % freq);
334 iyear = iyear + a; 334 iyear = iyear + a;
335 } 335 }
336 336
337 /* under the assumption we won't hit one of the special not-leap years twice */ 337 /* under the assumption we won't hit one of the special not-leap years twice */
338 if(!QDate::isValid(iyear, imonth, iday)) { 338 if(!QDate::isValid(iyear, imonth, iday)) {
339 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 339 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
340 iyear += freq; 340 iyear += freq;
341 } 341 }
342 342
343 if(QDate(iyear, imonth, iday) >= from) { 343 if(QDate(iyear, imonth, iday) >= from) {
344 next = QDate(iyear, imonth, iday); 344 next = QDate(iyear, imonth, iday);
345 345
346 if ((next > endDate()) && hasEndDate() ) 346 if ((next > endDate()) && hasEndDate() )
347 return FALSE; 347 return FALSE;
348 return TRUE; 348 return TRUE;
349 } 349 }
350 /* iyear == from.year(), need to advance again */ 350 /* iyear == from.year(), need to advance again */
351 iyear += freq; 351 iyear += freq;
352 /* under the assumption we won't hit one of the special not-leap years twice */ 352 /* under the assumption we won't hit one of the special not-leap years twice */
353 if(!QDate::isValid(iyear, imonth, iday)) { 353 if(!QDate::isValid(iyear, imonth, iday)) {
354 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 354 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
355 iyear += freq; 355 iyear += freq;
356 } 356 }
357 357
358 next = QDate(iyear, imonth, iday); 358 next = QDate(iyear, imonth, iday);
359 if ((next > endDate()) && hasEndDate() ) 359 if ((next > endDate()) && hasEndDate() )
360 return FALSE; 360 return FALSE;
361 return TRUE; 361 return TRUE;
362 default: 362 default:
363 return FALSE; 363 return FALSE;
364 } 364 }
365} 365}
366ORecur::RepeatType ORecur::type()const{ 366ORecur::RepeatType ORecur::type()const{
367 return data->type; 367 return data->type;
368} 368}
369int ORecur::frequency()const { 369int ORecur::frequency()const {
370 return data->freq; 370 return data->freq;
371} 371}
372int ORecur::position()const { 372int ORecur::position()const {
373 return data->pos; 373 return data->pos;
374} 374}
375char ORecur::days() const{ 375char ORecur::days() const{
376 return data->days; 376 return data->days;
377} 377}
378bool ORecur::hasEndDate()const { 378bool ORecur::hasEndDate()const {
379 return data->hasEnd; 379 return data->hasEnd;
380} 380}
381QDate ORecur::endDate()const { 381QDate ORecur::endDate()const {
382 return data->end; 382 return data->end;
383} 383}
384QDate ORecur::start()const{ 384QDate ORecur::start()const{
385 return data->start; 385 return data->start;
386} 386}
387QDateTime ORecur::createdDateTime()const { 387QDateTime ORecur::createdDateTime()const {
388 return data->create; 388 return data->create;
389} 389}
390int ORecur::repetition()const { 390int ORecur::repetition()const {
391 return data->rep; 391 return data->rep;
392} 392}
393QString ORecur::service()const { 393QString ORecur::service()const {
394 return data->app; 394 return data->app;
395} 395}
396ORecur::ExceptionList& ORecur::exceptions() { 396ORecur::ExceptionList& ORecur::exceptions() {
397 return data->list; 397 return data->list;
398} 398}
399void ORecur::setType( const RepeatType& z) { 399void ORecur::setType( const RepeatType& z) {
400 checkOrModify(); 400 checkOrModify();
401 data->type = z; 401 data->type = z;
402} 402}
403void ORecur::setFrequency( int freq ) { 403void ORecur::setFrequency( int freq ) {
404 checkOrModify(); 404 checkOrModify();
405 data->freq = freq; 405 data->freq = freq;
406} 406}
407void ORecur::setPosition( int pos ) { 407void ORecur::setPosition( int pos ) {
408 checkOrModify(); 408 checkOrModify();
409 data->pos = pos; 409 data->pos = pos;
410} 410}
411void ORecur::setDays( char c ) { 411void ORecur::setDays( char c ) {
412 checkOrModify(); 412 checkOrModify();
413 data->days = c; 413 data->days = c;
414} 414}
415void ORecur::setEndDate( const QDate& dt) { 415void ORecur::setEndDate( const QDate& dt) {
416 checkOrModify(); 416 checkOrModify();
417 data->end = dt; 417 data->end = dt;
418} 418}
419void ORecur::setCreatedDateTime( const QDateTime& t) { 419void ORecur::setCreatedDateTime( const QDateTime& t) {
420 checkOrModify(); 420 checkOrModify();
421 data->create = t; 421 data->create = t;
422} 422}
423void ORecur::setHasEndDate( bool b) { 423void ORecur::setHasEndDate( bool b) {
424 checkOrModify(); 424 checkOrModify();
425 data->hasEnd = b; 425 data->hasEnd = b;
426} 426}
427void ORecur::setRepitition( int rep ) { 427void ORecur::setRepitition( int rep ) {
428 checkOrModify(); 428 checkOrModify();
429 data->rep = rep; 429 data->rep = rep;
430} 430}
431void ORecur::setService( const QString& app ) { 431void ORecur::setService( const QString& app ) {
432 checkOrModify(); 432 checkOrModify();
433 data->app = app; 433 data->app = app;
434} 434}
435void ORecur::setStart( const QDate& dt ) { 435void ORecur::setStart( const QDate& dt ) {
436 checkOrModify(); 436 checkOrModify();
437 data->start = dt; 437 data->start = dt;
438} 438}
439void ORecur::checkOrModify() { 439void ORecur::checkOrModify() {
440 if ( data->count != 1 ) { 440 if ( data->count != 1 ) {
441 data->deref(); 441 data->deref();
442 Data* d2 = new Data; 442 Data* d2 = new Data;
443 d2->days = data->days; 443 d2->days = data->days;
444 d2->type = data->type; 444 d2->type = data->type;
445 d2->freq = data->freq; 445 d2->freq = data->freq;
446 d2->pos = data->pos; 446 d2->pos = data->pos;
447 d2->hasEnd = data->hasEnd; 447 d2->hasEnd = data->hasEnd;
448 d2->end = data->end; 448 d2->end = data->end;
449 d2->create = data->create; 449 d2->create = data->create;
450 d2->rep = data->rep; 450 d2->rep = data->rep;
451 d2->app = data->app; 451 d2->app = data->app;
452 d2->list = data->list; 452 d2->list = data->list;
453 d2->start = data->start; 453 d2->start = data->start;
454 data = d2; 454 data = d2;
455 } 455 }
456} 456}
457QString ORecur::toString()const { 457QString ORecur::toString()const {
458 QString buf; 458 QString buf;
459 QMap<int, QString> recMap = toMap();
459 460
460 buf += " rtype=\""; 461 buf += " rtype=\"";
461 switch ( data->type ) { 462 buf += recMap[ORecur::RType];
462 case ORecur::Daily:
463 buf += "Daily";
464 break;
465 case ORecur::Weekly:
466 buf += "Weekly";
467 break;
468 case ORecur::MonthlyDay:
469 buf += "MonthlyDay";
470 break;
471 case ORecur::MonthlyDate:
472 buf += "MonthlyDate";
473 break;
474 case ORecur::Yearly:
475 buf += "Yearly";
476 break;
477 default:
478 buf += "NoRepeat";
479 break;
480 }
481 buf += "\""; 463 buf += "\"";
482 if (data->days > 0 ) 464 if (data->days > 0 )
483 buf += " rweekdays=\"" + QString::number( static_cast<int>( data->days ) ) + "\""; 465 buf += " rweekdays=\"" + recMap[ORecur::RWeekdays] + "\"";
484 if ( data->pos != 0 ) 466 if ( data->pos != 0 )
485 buf += " rposition=\"" + QString::number(data->pos ) + "\""; 467 buf += " rposition=\"" + recMap[ORecur::RPosition] + "\"";
486 468
487 buf += " rfreq=\"" + QString::number( data->freq ) + "\""; 469 buf += " rfreq=\"" + recMap[ORecur::RFreq] + "\"";
488 buf += " rhasenddate=\"" + QString::number( static_cast<int>( data->hasEnd ) ) + "\""; 470 buf += " rhasenddate=\"" + recMap[ORecur::RHasEndDate]+ "\"";
489 if ( data->hasEnd ) 471 if ( data->hasEnd )
490 buf += " enddt=\"" 472 buf += " enddt=\""
491 + QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) 473 + recMap[ORecur::EndDate]
492 + "\""; 474 + "\"";
493 buf += " created=\"" + QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) + "\""; 475 buf += " created=\"" + recMap[ORecur::Created] + "\"";
494 476
495 if ( data->list.isEmpty() ) return buf; 477 if ( data->list.isEmpty() ) return buf;
496 // save exceptions list here!!
497 ExceptionList::ConstIterator it;
498 ExceptionList list = data->list;
499 buf += " exceptions=\""; 478 buf += " exceptions=\"";
500 QDate date; 479 buf += recMap[ORecur::Exceptions];
501 for ( it = list.begin(); it != list.end(); ++it ) {
502 date = (*it);
503 if ( it != list.begin() ) buf += " ";
504
505 buf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() );
506 }
507 buf += "\" "; 480 buf += "\" ";
508 481
509 return buf; 482 return buf;
510} 483}
484
485QString ORecur::rTypeString() const
486{
487 QString retString;
488 switch ( data->type ) {
489 case ORecur::Daily:
490 retString = "Daily";
491 break;
492 case ORecur::Weekly:
493 retString = "Weekly";
494 break;
495 case ORecur::MonthlyDay:
496 retString = "MonthlyDay";
497 break;
498 case ORecur::MonthlyDate:
499 retString = "MonthlyDate";
500 break;
501 case ORecur::Yearly:
502 retString = "Yearly";
503 break;
504 default:
505 retString = "NoRepeat";
506 break;
507
508 }
509
510 return retString;
511}
512
513QMap<QString, ORecur::RepeatType> ORecur::rTypeValueConvertMap() const
514{
515 QMap<QString, RepeatType> convertMap;
516
517 convertMap.insert( QString( "Daily" ), ORecur::Daily );
518 convertMap.insert( QString( "Weekly" ), ORecur::Weekly );
519 convertMap.insert( QString( "MonthlyDay" ), ORecur::MonthlyDay );
520 convertMap.insert( QString( "MonthlyDate" ), ORecur::MonthlyDate );
521 convertMap.insert( QString( "Yearly" ), ORecur::Yearly );
522 convertMap.insert( QString( "NoRepeat" ), ORecur::NoRepeat );
523
524 return convertMap;
525}
526
527
528QMap<int, QString> ORecur::toMap() const
529{
530 QMap<int, QString> retMap;
531
532 retMap.insert( ORecur::RType, rTypeString() );
533 retMap.insert( ORecur::RWeekdays, QString::number( static_cast<int>( data->days ) ) );
534 retMap.insert( ORecur::RPosition, QString::number(data->pos ) );
535 retMap.insert( ORecur::RFreq, QString::number( data->freq ) );
536 retMap.insert( ORecur::RHasEndDate, QString::number( static_cast<int>( data->hasEnd ) ) );
537 if( data -> hasEnd )
538 retMap.insert( ORecur::EndDate, QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) ) );
539 retMap.insert( ORecur::Created, QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) );
540
541 if ( data->list.isEmpty() ) return retMap;
542
543 // save exceptions list here!!
544 ExceptionList::ConstIterator it;
545 ExceptionList list = data->list;
546 QString exceptBuf;
547 QDate date;
548 for ( it = list.begin(); it != list.end(); ++it ) {
549 date = (*it);
550 if ( it != list.begin() ) exceptBuf += " ";
551
552 exceptBuf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() );
553 }
554
555 retMap.insert( ORecur::Exceptions, exceptBuf );
556
557 return retMap;
558}
559
560void ORecur::fromMap( const QMap<int, QString>& map )
561{
562 QMap<QString, RepeatType> repTypeMap = rTypeValueConvertMap();
563
564 data -> type = repTypeMap[ map [ORecur::RType] ];
565 data -> days = (char) map[ ORecur::RWeekdays ].toInt();
566 data -> pos = map[ ORecur::RPosition ].toInt();
567 data -> freq = map[ ORecur::RFreq ].toInt();
568 data -> hasEnd= map[ ORecur::RHasEndDate ].toInt() ? true : false;
569 OTimeZone utc = OTimeZone::utc();
570 if ( data -> hasEnd ){
571 data -> end = utc.fromUTCDateTime( (time_t) map[ ORecur::EndDate ].toLong() ).date();
572 }
573 data -> create = utc.fromUTCDateTime( (time_t) map[ ORecur::Created ].toLong() ).date();
574
575#if 0
576 // FIXME: Exceptions currently not supported...
577 // Convert the list of exceptions from QString into ExceptionList
578 data -> list.clear();
579 QString exceptStr = map[ ORecur::Exceptions ];
580 QStringList exceptList = QStringList::split( " ", exceptStr );
581 ...
582#endif
583
584
585}
diff --git a/libopie/pim/orecur.h b/libopie/pim/orecur.h
index b214b3f..47901b0 100644
--- a/libopie/pim/orecur.h
+++ b/libopie/pim/orecur.h
@@ -1,91 +1,101 @@
1/* 1/*
2 * GPL from TT 2 * GPL from TT
3 */ 3 */
4 4
5#ifndef OPIE_RECUR_H 5#ifndef OPIE_RECUR_H
6#define OPIE_RECUR_H 6#define OPIE_RECUR_H
7 7
8#include <sys/types.h> 8#include <sys/types.h>
9 9
10#include <qdatetime.h> 10#include <qdatetime.h>
11#include <qvaluelist.h> 11#include <qvaluelist.h>
12 12#include <qmap.h>
13 13
14class ORecur { 14class ORecur {
15public: 15public:
16 typedef QValueList<QDate> ExceptionList; 16 typedef QValueList<QDate> ExceptionList;
17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay, 17 enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
18 MonthlyDate, Yearly }; 18 MonthlyDate, Yearly };
19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, 19 enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
20 FRI = 0x10, SAT = 0x20, SUN = 0x40 }; 20 FRI = 0x10, SAT = 0x20, SUN = 0x40 };
21 enum Fields{ RType = 0, RWeekdays, RPosition, RFreq, RHasEndDate,
22 EndDate, Created, Exceptions };
23
21 ORecur(); 24 ORecur();
22 ORecur( const ORecur& ); 25 ORecur( const ORecur& );
23 ~ORecur(); 26 ~ORecur();
24 27
25 ORecur &operator=( const ORecur& ); 28 ORecur &operator=( const ORecur& );
26 bool operator==(const ORecur& )const; 29 bool operator==(const ORecur& )const;
27 30
28 bool doesRecur()const; 31 bool doesRecur()const;
29 /* if it recurrs on that day */ 32 /* if it recurrs on that day */
30 bool doesRecur( const QDate& ); 33 bool doesRecur( const QDate& );
31 RepeatType type()const; 34 RepeatType type()const;
32 int frequency()const; 35 int frequency()const;
33 int position()const; 36 int position()const;
34 char days()const; 37 char days()const;
35 bool hasEndDate()const; 38 bool hasEndDate()const;
36 QDate start()const; 39 QDate start()const;
37 QDate endDate()const; 40 QDate endDate()const;
38 QDateTime createdDateTime()const; 41 QDateTime createdDateTime()const;
39 /** 42 /**
40 * starting on monday=0, sunday=6 43 * starting on monday=0, sunday=6
41 * for convience 44 * for convience
42 */ 45 */
43 bool repeatOnWeekDay( int day )const; 46 bool repeatOnWeekDay( int day )const;
44 47
45 /** 48 /**
46 * FromWhereToStart is not included!!! 49 * FromWhereToStart is not included!!!
47 */ 50 */
48 bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate ); 51 bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate );
49 52
50 /** 53 /**
51 * The module this ORecur belongs to 54 * The module this ORecur belongs to
52 */ 55 */
53 QString service()const; 56 QString service()const;
54 57
55 /* 58 /*
56 * reference to the exception list 59 * reference to the exception list
57 */ 60 */
58 ExceptionList &exceptions(); 61 ExceptionList &exceptions();
59 62
60 /** 63 /**
61 * the current repetition 64 * the current repetition
62 */ 65 */
63 int repetition()const; 66 int repetition()const;
64 67
65 void setType( const RepeatType& ); 68 void setType( const RepeatType& );
66 void setFrequency( int freq ); 69 void setFrequency( int freq );
67 void setPosition( int pos ); 70 void setPosition( int pos );
68 void setDays( char c); 71 void setDays( char c);
69 void setEndDate( const QDate& dt ); 72 void setEndDate( const QDate& dt );
70 void setStart( const QDate& dt ); 73 void setStart( const QDate& dt );
71 void setCreatedDateTime( const QDateTime& ); 74 void setCreatedDateTime( const QDateTime& );
72 void setHasEndDate( bool b ); 75 void setHasEndDate( bool b );
73 void setRepitition(int ); 76 void setRepitition(int );
74 77
75 void setService( const QString& ser ); 78 void setService( const QString& ser );
79
80 QMap<int, QString> toMap() const;
81 void fromMap( const QMap<int, QString>& map );
76 82
77 /* almost internal */ 83 /* almost internal */
78 QString toString()const; 84 QString toString()const;
79private: 85private:
80 bool p_nextOccurrence( const QDate& from, QDate& next ); 86 bool p_nextOccurrence( const QDate& from, QDate& next );
81 void deref(); 87 void deref();
82 inline void checkOrModify(); 88 inline void checkOrModify();
83 89
90 /* Converts rType to String */
91 QString rTypeString() const;
92 /* Returns a map to convert Stringname for RType to RepeatType */
93 QMap<QString, RepeatType> rTypeValueConvertMap() const;
84 94
85 class Data; 95 class Data;
86 Data* data; 96 Data* data;
87 class ORecurPrivate; 97 class ORecurPrivate;
88 ORecurPrivate *d; 98 ORecurPrivate *d;
89}; 99};
90 100
91#endif 101#endif
diff --git a/libopie/pim/otodoaccesssql.cpp b/libopie/pim/otodoaccesssql.cpp
index ebd03bb..3913661 100644
--- a/libopie/pim/otodoaccesssql.cpp
+++ b/libopie/pim/otodoaccesssql.cpp
@@ -1,667 +1,690 @@
1 1
2#include <qdatetime.h> 2#include <qdatetime.h>
3 3
4#include <qpe/global.h> 4#include <qpe/global.h>
5 5
6#include <opie2/osqldriver.h> 6#include <opie2/osqldriver.h>
7#include <opie2/osqlresult.h> 7#include <opie2/osqlresult.h>
8#include <opie2/osqlmanager.h> 8#include <opie2/osqlmanager.h>
9#include <opie2/osqlquery.h> 9#include <opie2/osqlquery.h>
10 10
11#include "otodoaccesssql.h" 11#include "otodoaccesssql.h"
12#include "opimstate.h" 12#include "opimstate.h"
13#include "opimnotifymanager.h" 13#include "opimnotifymanager.h"
14#include "orecur.h" 14#include "orecur.h"
15 15
16/* 16/*
17 * first some query 17 * first some query
18 * CREATE query 18 * CREATE query
19 * LOAD query 19 * LOAD query
20 * INSERT 20 * INSERT
21 * REMOVE 21 * REMOVE
22 * CLEAR 22 * CLEAR
23 */ 23 */
24namespace { 24namespace {
25 /** 25 /**
26 * CreateQuery for the Todolist Table 26 * CreateQuery for the Todolist Table
27 */ 27 */
28 class CreateQuery : public OSQLQuery { 28 class CreateQuery : public OSQLQuery {
29 public: 29 public:
30 CreateQuery(); 30 CreateQuery();
31 ~CreateQuery(); 31 ~CreateQuery();
32 QString query()const; 32 QString query()const;
33 }; 33 };
34 34
35 /** 35 /**
36 * LoadQuery 36 * LoadQuery
37 * this one queries for all uids 37 * this one queries for all uids
38 */ 38 */
39 class LoadQuery : public OSQLQuery { 39 class LoadQuery : public OSQLQuery {
40 public: 40 public:
41 LoadQuery(); 41 LoadQuery();
42 ~LoadQuery(); 42 ~LoadQuery();
43 QString query()const; 43 QString query()const;
44 }; 44 };
45 45
46 /** 46 /**
47 * inserts/adds a OTodo to the table 47 * inserts/adds a OTodo to the table
48 */ 48 */
49 class InsertQuery : public OSQLQuery { 49 class InsertQuery : public OSQLQuery {
50 public: 50 public:
51 InsertQuery(const OTodo& ); 51 InsertQuery(const OTodo& );
52 ~InsertQuery(); 52 ~InsertQuery();
53 QString query()const; 53 QString query()const;
54 private: 54 private:
55 OTodo m_todo; 55 OTodo m_todo;
56 }; 56 };
57 57
58 /** 58 /**
59 * removes one from the table 59 * removes one from the table
60 */ 60 */
61 class RemoveQuery : public OSQLQuery { 61 class RemoveQuery : public OSQLQuery {
62 public: 62 public:
63 RemoveQuery(int uid ); 63 RemoveQuery(int uid );
64 ~RemoveQuery(); 64 ~RemoveQuery();
65 QString query()const; 65 QString query()const;
66 private: 66 private:
67 int m_uid; 67 int m_uid;
68 }; 68 };
69 69
70 /** 70 /**
71 * Clears (delete) a Table 71 * Clears (delete) a Table
72 */ 72 */
73 class ClearQuery : public OSQLQuery { 73 class ClearQuery : public OSQLQuery {
74 public: 74 public:
75 ClearQuery(); 75 ClearQuery();
76 ~ClearQuery(); 76 ~ClearQuery();
77 QString query()const; 77 QString query()const;
78 78
79 }; 79 };
80 80
81 /** 81 /**
82 * a find query 82 * a find query
83 */ 83 */
84 class FindQuery : public OSQLQuery { 84 class FindQuery : public OSQLQuery {
85 public: 85 public:
86 FindQuery(int uid); 86 FindQuery(int uid);
87 FindQuery(const QArray<int>& ); 87 FindQuery(const QArray<int>& );
88 ~FindQuery(); 88 ~FindQuery();
89 QString query()const; 89 QString query()const;
90 private: 90 private:
91 QString single()const; 91 QString single()const;
92 QString multi()const; 92 QString multi()const;
93 QArray<int> m_uids; 93 QArray<int> m_uids;
94 int m_uid; 94 int m_uid;
95 }; 95 };
96 96
97 /** 97 /**
98 * overdue query 98 * overdue query
99 */ 99 */
100 class OverDueQuery : public OSQLQuery { 100 class OverDueQuery : public OSQLQuery {
101 public: 101 public:
102 OverDueQuery(); 102 OverDueQuery();
103 ~OverDueQuery(); 103 ~OverDueQuery();
104 QString query()const; 104 QString query()const;
105 }; 105 };
106 class EffQuery : public OSQLQuery { 106 class EffQuery : public OSQLQuery {
107 public: 107 public:
108 EffQuery( const QDate&, const QDate&, bool inc ); 108 EffQuery( const QDate&, const QDate&, bool inc );
109 ~EffQuery(); 109 ~EffQuery();
110 QString query()const; 110 QString query()const;
111 private: 111 private:
112 QString with()const; 112 QString with()const;
113 QString out()const; 113 QString out()const;
114 QDate m_start; 114 QDate m_start;
115 QDate m_end; 115 QDate m_end;
116 bool m_inc :1; 116 bool m_inc :1;
117 }; 117 };
118 118
119 119
120 CreateQuery::CreateQuery() : OSQLQuery() {} 120 CreateQuery::CreateQuery() : OSQLQuery() {}
121 CreateQuery::~CreateQuery() {} 121 CreateQuery::~CreateQuery() {}
122 QString CreateQuery::query()const { 122 QString CreateQuery::query()const {
123 QString qu; 123 QString qu;
124 qu += "create table todolist( uid PRIMARY KEY, categories, completed, "; 124 qu += "create table todolist( uid PRIMARY KEY, categories, completed, ";
125 qu += "description, summary, priority, DueDate, progress , state, "; 125 qu += "description, summary, priority, DueDate, progress , state, ";
126 qu += "Recurrence, reminders, alarms, maintainer, startdate, completeddate);"; 126 // This is the recurrance-stuff .. Exceptions are currently not supported (see ORecur.cpp) ! (eilers)
127 qu += "RType, RWeekdays, RPosition, RFreq, RHasEndDate, EndDate, Created, Exceptions, ";
128 qu += "reminders, alarms, maintainer, startdate, completeddate);";
127 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );"; 129 qu += "create table custom_data( uid INTEGER, id INTEGER, type VARCHAR(10), value VARCHAR(10), PRIMARY KEY /* identifier */ (uid, id) );";
128 return qu; 130 return qu;
129 } 131 }
130 132
131 LoadQuery::LoadQuery() : OSQLQuery() {} 133 LoadQuery::LoadQuery() : OSQLQuery() {}
132 LoadQuery::~LoadQuery() {} 134 LoadQuery::~LoadQuery() {}
133 QString LoadQuery::query()const { 135 QString LoadQuery::query()const {
134 QString qu; 136 QString qu;
135 // We do not need "distinct" here. The primary key is always unique.. 137 // We do not need "distinct" here. The primary key is always unique..
136 //qu += "select distinct uid from todolist"; 138 //qu += "select distinct uid from todolist";
137 qu += "select uid from todolist"; 139 qu += "select uid from todolist";
138 140
139 return qu; 141 return qu;
140 } 142 }
141 143
142 InsertQuery::InsertQuery( const OTodo& todo ) 144 InsertQuery::InsertQuery( const OTodo& todo )
143 : OSQLQuery(), m_todo( todo ) { 145 : OSQLQuery(), m_todo( todo ) {
144 } 146 }
145 InsertQuery::~InsertQuery() { 147 InsertQuery::~InsertQuery() {
146 } 148 }
147 /* 149 /*
148 * converts from a OTodo to a query 150 * converts from a OTodo to a query
149 * we leave out X-Ref + Alarms 151 * we leave out X-Ref + Alarms
150 */ 152 */
151 QString InsertQuery::query()const{ 153 QString InsertQuery::query()const{
152 154
153 int year, month, day; 155 int year, month, day;
154 year = month = day = 0; 156 year = month = day = 0;
155 if (m_todo.hasDueDate() ) { 157 if (m_todo.hasDueDate() ) {
156 QDate date = m_todo.dueDate(); 158 QDate date = m_todo.dueDate();
157 year = date.year(); 159 year = date.year();
158 month = date.month(); 160 month = date.month();
159 day = date.day(); 161 day = date.day();
160 } 162 }
161 int sYear = 0, sMonth = 0, sDay = 0; 163 int sYear = 0, sMonth = 0, sDay = 0;
162 if( m_todo.hasStartDate() ){ 164 if( m_todo.hasStartDate() ){
163 QDate sDate = m_todo.startDate(); 165 QDate sDate = m_todo.startDate();
164 sYear = sDate.year(); 166 sYear = sDate.year();
165 sMonth= sDate.month(); 167 sMonth= sDate.month();
166 sDay = sDate.day(); 168 sDay = sDate.day();
167 } 169 }
168 170
169 int eYear = 0, eMonth = 0, eDay = 0; 171 int eYear = 0, eMonth = 0, eDay = 0;
170 if( m_todo.hasCompletedDate() ){ 172 if( m_todo.hasCompletedDate() ){
171 QDate eDate = m_todo.completedDate(); 173 QDate eDate = m_todo.completedDate();
172 eYear = eDate.year(); 174 eYear = eDate.year();
173 eMonth= eDate.month(); 175 eMonth= eDate.month();
174 eDay = eDate.day(); 176 eDay = eDate.day();
175 } 177 }
176 QString qu; 178 QString qu;
179 QMap<int, QString> recMap = m_todo.recurrence().toMap();
177 qu = "insert into todolist VALUES(" 180 qu = "insert into todolist VALUES("
178 + QString::number( m_todo.uid() ) + "," 181 + QString::number( m_todo.uid() ) + ","
179 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + "," 182 + "'" + m_todo.idsToString( m_todo.categories() ) + "'" + ","
180 + QString::number( m_todo.isCompleted() ) + "," 183 + QString::number( m_todo.isCompleted() ) + ","
181 + "'" + m_todo.description() + "'" + "," 184 + "'" + m_todo.description() + "'" + ","
182 + "'" + m_todo.summary() + "'" + "," 185 + "'" + m_todo.summary() + "'" + ","
183 + QString::number(m_todo.priority() ) + "," 186 + QString::number(m_todo.priority() ) + ","
184 + "'" + QString::number(year) + "-" 187 + "'" + QString::number(year) + "-"
185 + QString::number(month) 188 + QString::number(month)
186 + "-" + QString::number( day ) + "'" + "," 189 + "-" + QString::number( day ) + "'" + ","
187 + QString::number( m_todo.progress() ) + "," 190 + QString::number( m_todo.progress() ) + ","
188 + QString::number( m_todo.state().state() ) + "," 191 + QString::number( m_todo.state().state() ) + ","
189 + "'" + m_todo.recurrence().toString() + "'"+ ","; 192 + "'" + recMap[ ORecur::RType ] + "'" + ","
193 + "'" + recMap[ ORecur::RWeekdays ] + "'" + ","
194 + "'" + recMap[ ORecur::RPosition ] + "'" + ","
195 + "'" + recMap[ ORecur::RFreq ] + "'" + ","
196 + "'" + recMap[ ORecur::RHasEndDate ] + "'" + ","
197 + "'" + recMap[ ORecur::EndDate ] + "'" + ","
198 + "'" + recMap[ ORecur::Created ] + "'" + ","
199 + "'" + recMap[ ORecur::Exceptions ] + "'" + ",";
190 200
191 if ( m_todo.hasNotifiers() ) { 201 if ( m_todo.hasNotifiers() ) {
192 OPimNotifyManager manager = m_todo.notifiers(); 202 OPimNotifyManager manager = m_todo.notifiers();
193 qu += "'" + manager.remindersToString() + "'" + "," 203 qu += "'" + manager.remindersToString() + "'" + ","
194 + "'" + manager.alarmsToString() + "'" + ","; 204 + "'" + manager.alarmsToString() + "'" + ",";
195 } 205 }
196 else{ 206 else{
197 qu += QString( "''" ) + "," 207 qu += QString( "''" ) + ","
198 + "''" + ","; 208 + "''" + ",";
199 } 209 }
200 210
201 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !) 211 qu += QString( "''" ) + QString( "," ) // Maintainers (cur. not supported !)
202 + "'" + QString::number(sYear) + "-" 212 + "'" + QString::number(sYear) + "-"
203 + QString::number(sMonth) 213 + QString::number(sMonth)
204 + "-" + QString::number(sDay) + "'" + "," 214 + "-" + QString::number(sDay) + "'" + ","
205 + "'" + QString::number(eYear) + "-" 215 + "'" + QString::number(eYear) + "-"
206 + QString::number(eMonth) 216 + QString::number(eMonth)
207 + "-"+QString::number(eDay) + "'" 217 + "-"+QString::number(eDay) + "'"
208 + ")"; 218 + ")";
209 219
210 qWarning("add %s", qu.latin1() ); 220 qWarning("add %s", qu.latin1() );
211 return qu; 221 return qu;
212 } 222 }
213 223
214 RemoveQuery::RemoveQuery(int uid ) 224 RemoveQuery::RemoveQuery(int uid )
215 : OSQLQuery(), m_uid( uid ) {} 225 : OSQLQuery(), m_uid( uid ) {}
216 RemoveQuery::~RemoveQuery() {} 226 RemoveQuery::~RemoveQuery() {}
217 QString RemoveQuery::query()const { 227 QString RemoveQuery::query()const {
218 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid); 228 QString qu = "DELETE from todolist where uid = " + QString::number(m_uid);
219 return qu; 229 return qu;
220 } 230 }
221 231
222 232
223 ClearQuery::ClearQuery() 233 ClearQuery::ClearQuery()
224 : OSQLQuery() {} 234 : OSQLQuery() {}
225 ClearQuery::~ClearQuery() {} 235 ClearQuery::~ClearQuery() {}
226 QString ClearQuery::query()const { 236 QString ClearQuery::query()const {
227 QString qu = "drop table todolist"; 237 QString qu = "drop table todolist";
228 return qu; 238 return qu;
229 } 239 }
230 FindQuery::FindQuery(int uid) 240 FindQuery::FindQuery(int uid)
231 : OSQLQuery(), m_uid(uid ) { 241 : OSQLQuery(), m_uid(uid ) {
232 } 242 }
233 FindQuery::FindQuery(const QArray<int>& ints) 243 FindQuery::FindQuery(const QArray<int>& ints)
234 : OSQLQuery(), m_uids(ints){ 244 : OSQLQuery(), m_uids(ints){
235 } 245 }
236 FindQuery::~FindQuery() { 246 FindQuery::~FindQuery() {
237 } 247 }
238 QString FindQuery::query()const{ 248 QString FindQuery::query()const{
239 if (m_uids.count() == 0 ) 249 if (m_uids.count() == 0 )
240 return single(); 250 return single();
241 else 251 else
242 return multi(); 252 return multi();
243 } 253 }
244 QString FindQuery::single()const{ 254 QString FindQuery::single()const{
245 QString qu = "select * from todolist where uid = " + QString::number(m_uid); 255 QString qu = "select * from todolist where uid = " + QString::number(m_uid);
246 return qu; 256 return qu;
247 } 257 }
248 QString FindQuery::multi()const { 258 QString FindQuery::multi()const {
249 QString qu = "select * from todolist where "; 259 QString qu = "select * from todolist where ";
250 for (uint i = 0; i < m_uids.count(); i++ ) { 260 for (uint i = 0; i < m_uids.count(); i++ ) {
251 qu += " UID = " + QString::number( m_uids[i] ) + " OR"; 261 qu += " UID = " + QString::number( m_uids[i] ) + " OR";
252 } 262 }
253 qu.remove( qu.length()-2, 2 ); 263 qu.remove( qu.length()-2, 2 );
254 return qu; 264 return qu;
255 } 265 }
256 266
257 OverDueQuery::OverDueQuery(): OSQLQuery() {} 267 OverDueQuery::OverDueQuery(): OSQLQuery() {}
258 OverDueQuery::~OverDueQuery() {} 268 OverDueQuery::~OverDueQuery() {}
259 QString OverDueQuery::query()const { 269 QString OverDueQuery::query()const {
260 QDate date = QDate::currentDate(); 270 QDate date = QDate::currentDate();
261 QString str; 271 QString str;
262 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() ); 272 str = QString("select uid from todolist where DueDate ='%1-%2-%3'").arg(date.year() ).arg(date.month() ).arg(date.day() );
263 273
264 return str; 274 return str;
265 } 275 }
266 276
267 277
268 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc ) 278 EffQuery::EffQuery( const QDate& start, const QDate& end, bool inc )
269 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {} 279 : OSQLQuery(), m_start( start ), m_end( end ),m_inc(inc) {}
270 EffQuery::~EffQuery() {} 280 EffQuery::~EffQuery() {}
271 QString EffQuery::query()const { 281 QString EffQuery::query()const {
272 return m_inc ? with() : out(); 282 return m_inc ? with() : out();
273 } 283 }
274 QString EffQuery::with()const { 284 QString EffQuery::with()const {
275 QString str; 285 QString str;
276 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ") 286 str = QString("select uid from todolist where ( DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6' ) OR DueDate = '0-0-0' ")
277 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() ) 287 .arg( m_start.year() ).arg( m_start.month() ).arg( m_start.day() )
278 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() ); 288 .arg( m_end .year() ).arg( m_end .month() ).arg( m_end .day() );
279 return str; 289 return str;
280 } 290 }
281 QString EffQuery::out()const { 291 QString EffQuery::out()const {
282 QString str; 292 QString str;
283 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'") 293 str = QString("select uid from todolist where DueDate >= '%1-%2-%3' AND DueDate <= '%4-%5-%6'")
284 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() ) 294 .arg(m_start.year() ).arg(m_start.month() ).arg( m_start.day() )
285 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() ); 295 .arg(m_end. year() ).arg(m_end. month() ).arg(m_end.day() );
286 296
287 return str; 297 return str;
288 } 298 }
289}; 299};
290 300
291OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file ) 301OTodoAccessBackendSQL::OTodoAccessBackendSQL( const QString& file )
292 : OTodoAccessBackend(), m_dict(15), m_dirty(true) 302 : OTodoAccessBackend(), m_dict(15), m_dirty(true)
293{ 303{
294 QString fi = file; 304 QString fi = file;
295 if ( fi.isEmpty() ) 305 if ( fi.isEmpty() )
296 fi = Global::applicationFileName( "todolist", "todolist.db" ); 306 fi = Global::applicationFileName( "todolist", "todolist.db" );
297 OSQLManager man; 307 OSQLManager man;
298 m_driver = man.standard(); 308 m_driver = man.standard();
299 m_driver->setUrl(fi); 309 m_driver->setUrl(fi);
300 // fillDict(); 310 // fillDict();
301} 311}
302 312
303OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){ 313OTodoAccessBackendSQL::~OTodoAccessBackendSQL(){
304} 314}
305bool OTodoAccessBackendSQL::load(){ 315bool OTodoAccessBackendSQL::load(){
306 if (!m_driver->open() ) 316 if (!m_driver->open() )
307 return false; 317 return false;
308 318
309 CreateQuery creat; 319 CreateQuery creat;
310 OSQLResult res = m_driver->query(&creat ); 320 OSQLResult res = m_driver->query(&creat );
311 321
312 m_dirty = true; 322 m_dirty = true;
313 return true; 323 return true;
314} 324}
315bool OTodoAccessBackendSQL::reload(){ 325bool OTodoAccessBackendSQL::reload(){
316 return load(); 326 return load();
317} 327}
318 328
319bool OTodoAccessBackendSQL::save(){ 329bool OTodoAccessBackendSQL::save(){
320 return m_driver->close(); 330 return m_driver->close();
321} 331}
322QArray<int> OTodoAccessBackendSQL::allRecords()const { 332QArray<int> OTodoAccessBackendSQL::allRecords()const {
323 if (m_dirty ) 333 if (m_dirty )
324 update(); 334 update();
325 335
326 return m_uids; 336 return m_uids;
327} 337}
328QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){ 338QArray<int> OTodoAccessBackendSQL::queryByExample( const OTodo& , int, const QDateTime& ){
329 QArray<int> ints(0); 339 QArray<int> ints(0);
330 return ints; 340 return ints;
331} 341}
332OTodo OTodoAccessBackendSQL::find(int uid ) const{ 342OTodo OTodoAccessBackendSQL::find(int uid ) const{
333 FindQuery query( uid ); 343 FindQuery query( uid );
334 return todo( m_driver->query(&query) ); 344 return todo( m_driver->query(&query) );
335 345
336} 346}
337OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints, 347OTodo OTodoAccessBackendSQL::find( int uid, const QArray<int>& ints,
338 uint cur, Frontend::CacheDirection dir ) const{ 348 uint cur, Frontend::CacheDirection dir ) const{
339 uint CACHE = readAhead(); 349 uint CACHE = readAhead();
340 qWarning("searching for %d", uid ); 350 qWarning("searching for %d", uid );
341 QArray<int> search( CACHE ); 351 QArray<int> search( CACHE );
342 uint size =0; 352 uint size =0;
343 OTodo to; 353 OTodo to;
344 354
345 // we try to cache CACHE items 355 // we try to cache CACHE items
346 switch( dir ) { 356 switch( dir ) {
347 /* forward */ 357 /* forward */
348 case 0: // FIXME: Not a good style to use magic numbers here (eilers) 358 case 0: // FIXME: Not a good style to use magic numbers here (eilers)
349 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) { 359 for (uint i = cur; i < ints.count() && size < CACHE; i++ ) {
350 qWarning("size %d %d", size, ints[i] ); 360 qWarning("size %d %d", size, ints[i] );
351 search[size] = ints[i]; 361 search[size] = ints[i];
352 size++; 362 size++;
353 } 363 }
354 break; 364 break;
355 /* reverse */ 365 /* reverse */
356 case 1: // FIXME: Not a good style to use magic numbers here (eilers) 366 case 1: // FIXME: Not a good style to use magic numbers here (eilers)
357 for (uint i = cur; i != 0 && size < CACHE; i-- ) { 367 for (uint i = cur; i != 0 && size < CACHE; i-- ) {
358 search[size] = ints[i]; 368 search[size] = ints[i];
359 size++; 369 size++;
360 } 370 }
361 break; 371 break;
362 } 372 }
363 search.resize( size ); 373 search.resize( size );
364 FindQuery query( search ); 374 FindQuery query( search );
365 OSQLResult res = m_driver->query( &query ); 375 OSQLResult res = m_driver->query( &query );
366 if ( res.state() != OSQLResult::Success ) 376 if ( res.state() != OSQLResult::Success )
367 return to; 377 return to;
368 378
369 return todo( res ); 379 return todo( res );
370} 380}
371void OTodoAccessBackendSQL::clear() { 381void OTodoAccessBackendSQL::clear() {
372 ClearQuery cle; 382 ClearQuery cle;
373 OSQLResult res = m_driver->query( &cle ); 383 OSQLResult res = m_driver->query( &cle );
374 CreateQuery qu; 384 CreateQuery qu;
375 res = m_driver->query(&qu); 385 res = m_driver->query(&qu);
376} 386}
377bool OTodoAccessBackendSQL::add( const OTodo& t) { 387bool OTodoAccessBackendSQL::add( const OTodo& t) {
378 InsertQuery ins( t ); 388 InsertQuery ins( t );
379 OSQLResult res = m_driver->query( &ins ); 389 OSQLResult res = m_driver->query( &ins );
380 390
381 if ( res.state() == OSQLResult::Failure ) 391 if ( res.state() == OSQLResult::Failure )
382 return false; 392 return false;
383 int c = m_uids.count(); 393 int c = m_uids.count();
384 m_uids.resize( c+1 ); 394 m_uids.resize( c+1 );
385 m_uids[c] = t.uid(); 395 m_uids[c] = t.uid();
386 396
387 return true; 397 return true;
388} 398}
389bool OTodoAccessBackendSQL::remove( int uid ) { 399bool OTodoAccessBackendSQL::remove( int uid ) {
390 RemoveQuery rem( uid ); 400 RemoveQuery rem( uid );
391 OSQLResult res = m_driver->query(&rem ); 401 OSQLResult res = m_driver->query(&rem );
392 402
393 if ( res.state() == OSQLResult::Failure ) 403 if ( res.state() == OSQLResult::Failure )
394 return false; 404 return false;
395 405
396 m_dirty = true; 406 m_dirty = true;
397 return true; 407 return true;
398} 408}
399/* 409/*
400 * FIXME better set query 410 * FIXME better set query
401 * but we need the cache for that 411 * but we need the cache for that
402 * now we remove 412 * now we remove
403 */ 413 */
404bool OTodoAccessBackendSQL::replace( const OTodo& t) { 414bool OTodoAccessBackendSQL::replace( const OTodo& t) {
405 remove( t.uid() ); 415 remove( t.uid() );
406 bool b= add(t); 416 bool b= add(t);
407 m_dirty = false; // we changed some stuff but the UID stayed the same 417 m_dirty = false; // we changed some stuff but the UID stayed the same
408 return b; 418 return b;
409} 419}
410QArray<int> OTodoAccessBackendSQL::overDue() { 420QArray<int> OTodoAccessBackendSQL::overDue() {
411 OverDueQuery qu; 421 OverDueQuery qu;
412 return uids( m_driver->query(&qu ) ); 422 return uids( m_driver->query(&qu ) );
413} 423}
414QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s, 424QArray<int> OTodoAccessBackendSQL::effectiveToDos( const QDate& s,
415 const QDate& t, 425 const QDate& t,
416 bool u) { 426 bool u) {
417 EffQuery ef(s, t, u ); 427 EffQuery ef(s, t, u );
418 return uids (m_driver->query(&ef) ); 428 return uids (m_driver->query(&ef) );
419} 429}
420/* 430/*
421 * 431 *
422 */ 432 */
423QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder, 433QArray<int> OTodoAccessBackendSQL::sorted( bool asc, int sortOrder,
424 int sortFilter, int cat ) { 434 int sortFilter, int cat ) {
425 qWarning("sorted %d, %d", asc, sortOrder ); 435 qWarning("sorted %d, %d", asc, sortOrder );
426 QString query; 436 QString query;
427 query = "select uid from todolist WHERE "; 437 query = "select uid from todolist WHERE ";
428 438
429 /* 439 /*
430 * Sort Filter stuff 440 * Sort Filter stuff
431 * not that straight forward 441 * not that straight forward
432 * FIXME: Replace magic numbers 442 * FIXME: Replace magic numbers
433 * 443 *
434 */ 444 */
435 /* Category */ 445 /* Category */
436 if ( sortFilter & 1 ) { 446 if ( sortFilter & 1 ) {
437 QString str; 447 QString str;
438 if (cat != 0 ) str = QString::number( cat ); 448 if (cat != 0 ) str = QString::number( cat );
439 query += " categories like '%" +str+"%' AND"; 449 query += " categories like '%" +str+"%' AND";
440 } 450 }
441 /* Show only overdue */ 451 /* Show only overdue */
442 if ( sortFilter & 2 ) { 452 if ( sortFilter & 2 ) {
443 QDate date = QDate::currentDate(); 453 QDate date = QDate::currentDate();
444 QString due; 454 QString due;
445 QString base; 455 QString base;
446 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() ); 456 base = QString("DueDate <= '%1-%2-%3' AND completed = 0").arg( date.year() ).arg( date.month() ).arg( date.day() );
447 query += " " + base + " AND"; 457 query += " " + base + " AND";
448 } 458 }
449 /* not show completed */ 459 /* not show completed */
450 if ( sortFilter & 4 ) { 460 if ( sortFilter & 4 ) {
451 query += " completed = 0 AND"; 461 query += " completed = 0 AND";
452 }else{ 462 }else{
453 query += " ( completed = 1 OR completed = 0) AND"; 463 query += " ( completed = 1 OR completed = 0) AND";
454 } 464 }
455 /* srtip the end */ 465 /* srtip the end */
456 query = query.remove( query.length()-3, 3 ); 466 query = query.remove( query.length()-3, 3 );
457 467
458 468
459 /* 469 /*
460 * sort order stuff 470 * sort order stuff
461 * quite straight forward 471 * quite straight forward
462 */ 472 */
463 query += "ORDER BY "; 473 query += "ORDER BY ";
464 switch( sortOrder ) { 474 switch( sortOrder ) {
465 /* completed */ 475 /* completed */
466 case 0: 476 case 0:
467 query += "completed"; 477 query += "completed";
468 break; 478 break;
469 case 1: 479 case 1:
470 query += "priority"; 480 query += "priority";
471 break; 481 break;
472 case 2: 482 case 2:
473 query += "summary"; 483 query += "summary";
474 break; 484 break;
475 case 3: 485 case 3:
476 query += "DueDate"; 486 query += "DueDate";
477 break; 487 break;
478 } 488 }
479 489
480 if ( !asc ) { 490 if ( !asc ) {
481 qWarning("not ascending!"); 491 qWarning("not ascending!");
482 query += " DESC"; 492 query += " DESC";
483 } 493 }
484 494
485 qWarning( query ); 495 qWarning( query );
486 OSQLRawQuery raw(query ); 496 OSQLRawQuery raw(query );
487 return uids( m_driver->query(&raw) ); 497 return uids( m_driver->query(&raw) );
488} 498}
489bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{ 499bool OTodoAccessBackendSQL::date( QDate& da, const QString& str ) const{
490 if ( str == "0-0-0" ) 500 if ( str == "0-0-0" )
491 return false; 501 return false;
492 else{ 502 else{
493 int day, year, month; 503 int day, year, month;
494 QStringList list = QStringList::split("-", str ); 504 QStringList list = QStringList::split("-", str );
495 year = list[0].toInt(); 505 year = list[0].toInt();
496 month = list[1].toInt(); 506 month = list[1].toInt();
497 day = list[2].toInt(); 507 day = list[2].toInt();
498 da.setYMD( year, month, day ); 508 da.setYMD( year, month, day );
499 return true; 509 return true;
500 } 510 }
501} 511}
502OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{ 512OTodo OTodoAccessBackendSQL::todo( const OSQLResult& res) const{
503 if ( res.state() == OSQLResult::Failure ) { 513 if ( res.state() == OSQLResult::Failure ) {
504 OTodo to; 514 OTodo to;
505 return to; 515 return to;
506 } 516 }
507 517
508 OSQLResultItem::ValueList list = res.results(); 518 OSQLResultItem::ValueList list = res.results();
509 OSQLResultItem::ValueList::Iterator it = list.begin(); 519 OSQLResultItem::ValueList::Iterator it = list.begin();
510 qWarning("todo1"); 520 qWarning("todo1");
511 OTodo to = todo( (*it) ); 521 OTodo to = todo( (*it) );
512 cache( to ); 522 cache( to );
513 ++it; 523 ++it;
514 524
515 for ( ; it != list.end(); ++it ) { 525 for ( ; it != list.end(); ++it ) {
516 qWarning("caching"); 526 qWarning("caching");
517 cache( todo( (*it) ) ); 527 cache( todo( (*it) ) );
518 } 528 }
519 return to; 529 return to;
520} 530}
521OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const { 531OTodo OTodoAccessBackendSQL::todo( OSQLResultItem& item )const {
522 qWarning("todo"); 532 qWarning("todo");
523 bool hasDueDate = false; QDate dueDate = QDate::currentDate(); 533 bool hasDueDate = false; QDate dueDate = QDate::currentDate();
524 hasDueDate = date( dueDate, item.data("DueDate") ); 534 hasDueDate = date( dueDate, item.data("DueDate") );
525 QStringList cats = QStringList::split(";", item.data("categories") ); 535 QStringList cats = QStringList::split(";", item.data("categories") );
526 536
537 qWarning("Item is completed: %d", item.data("completed").toInt() );
538
527 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(), 539 OTodo to( (bool)item.data("completed").toInt(), item.data("priority").toInt(),
528 cats, item.data("summary"), item.data("description"), 540 cats, item.data("summary"), item.data("description"),
529 item.data("progress").toUShort(), hasDueDate, dueDate, 541 item.data("progress").toUShort(), hasDueDate, dueDate,
530 item.data("uid").toInt() ); 542 item.data("uid").toInt() );
531 543
532 bool isOk; 544 bool isOk;
533 int prioInt = QString( item.data("priority") ).toInt( &isOk ); 545 int prioInt = QString( item.data("priority") ).toInt( &isOk );
534 if ( isOk ) 546 if ( isOk )
535 to.setPriority( prioInt ); 547 to.setPriority( prioInt );
536 548
537 bool hasStartDate = false; QDate startDate = QDate::currentDate(); 549 bool hasStartDate = false; QDate startDate = QDate::currentDate();
538 hasStartDate = date( startDate, item.data("startdate") ); 550 hasStartDate = date( startDate, item.data("startdate") );
539 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate(); 551 bool hasCompletedDate = false; QDate completedDate = QDate::currentDate();
540 hasCompletedDate = date( completedDate, item.data("completeddate") ); 552 hasCompletedDate = date( completedDate, item.data("completeddate") );
541 553
542 if ( hasStartDate ) 554 if ( hasStartDate )
543 to.setStartDate( startDate ); 555 to.setStartDate( startDate );
544 if ( hasCompletedDate ) 556 if ( hasCompletedDate )
545 to.setCompletedDate( completedDate ); 557 to.setCompletedDate( completedDate );
546 558
547 OPimNotifyManager& manager = to.notifiers(); 559 OPimNotifyManager& manager = to.notifiers();
548 manager.alarmsFromString( item.data("alarms") ); 560 manager.alarmsFromString( item.data("alarms") );
549 manager.remindersFromString( item.data("reminders") ); 561 manager.remindersFromString( item.data("reminders") );
550 562
551 OPimState pimState; 563 OPimState pimState;
552 pimState.setState( QString( item.data("state") ).toInt() ); 564 pimState.setState( QString( item.data("state") ).toInt() );
553 to.setState( pimState ); 565 to.setState( pimState );
554 566
555 // Recurrence not supported yet 567 QMap<int, QString> recMap;
556 // to.setRecurrence( 568 recMap.insert( ORecur::RType , item.data("RType") );
569 recMap.insert( ORecur::RWeekdays , item.data("RWeekdays") );
570 recMap.insert( ORecur::RPosition , item.data("RPosition") );
571 recMap.insert( ORecur::RFreq , item.data("RFreq") );
572 recMap.insert( ORecur::RHasEndDate, item.data("RHasEndDate") );
573 recMap.insert( ORecur::EndDate , item.data("EndDate") );
574 recMap.insert( ORecur::Created , item.data("Created") );
575 recMap.insert( ORecur::Exceptions , item.data("Exceptions") );
576
577 ORecur recur;
578 recur.fromMap( recMap );
579 to.setRecurrence( recur );
557 580
558 return to; 581 return to;
559} 582}
560OTodo OTodoAccessBackendSQL::todo( int uid )const { 583OTodo OTodoAccessBackendSQL::todo( int uid )const {
561 FindQuery find( uid ); 584 FindQuery find( uid );
562 return todo( m_driver->query(&find) ); 585 return todo( m_driver->query(&find) );
563} 586}
564/* 587/*
565 * update the dict 588 * update the dict
566 */ 589 */
567void OTodoAccessBackendSQL::fillDict() { 590void OTodoAccessBackendSQL::fillDict() {
568 /* initialize dict */ 591 /* initialize dict */
569 /* 592 /*
570 * UPDATE dict if you change anything!!! 593 * UPDATE dict if you change anything!!!
571 * FIXME: Isn't this dict obsolete ? (eilers) 594 * FIXME: Isn't this dict obsolete ? (eilers)
572 */ 595 */
573 m_dict.setAutoDelete( TRUE ); 596 m_dict.setAutoDelete( TRUE );
574 m_dict.insert("Categories" , new int(OTodo::Category) ); 597 m_dict.insert("Categories" , new int(OTodo::Category) );
575 m_dict.insert("Uid" , new int(OTodo::Uid) ); 598 m_dict.insert("Uid" , new int(OTodo::Uid) );
576 m_dict.insert("HasDate" , new int(OTodo::HasDate) ); 599 m_dict.insert("HasDate" , new int(OTodo::HasDate) );
577 m_dict.insert("Completed" , new int(OTodo::Completed) ); 600 m_dict.insert("Completed" , new int(OTodo::Completed) );
578 m_dict.insert("Description" , new int(OTodo::Description) ); 601 m_dict.insert("Description" , new int(OTodo::Description) );
579 m_dict.insert("Summary" , new int(OTodo::Summary) ); 602 m_dict.insert("Summary" , new int(OTodo::Summary) );
580 m_dict.insert("Priority" , new int(OTodo::Priority) ); 603 m_dict.insert("Priority" , new int(OTodo::Priority) );
581 m_dict.insert("DateDay" , new int(OTodo::DateDay) ); 604 m_dict.insert("DateDay" , new int(OTodo::DateDay) );
582 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 605 m_dict.insert("DateMonth" , new int(OTodo::DateMonth) );
583 m_dict.insert("DateYear" , new int(OTodo::DateYear) ); 606 m_dict.insert("DateYear" , new int(OTodo::DateYear) );
584 m_dict.insert("Progress" , new int(OTodo::Progress) ); 607 m_dict.insert("Progress" , new int(OTodo::Progress) );
585 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers) 608 m_dict.insert("Completed", new int(OTodo::Completed) ); // Why twice ? (eilers)
586 m_dict.insert("CrossReference", new int(OTodo::CrossReference) ); 609 m_dict.insert("CrossReference", new int(OTodo::CrossReference) );
587// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers) 610// m_dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); // old stuff (eilers)
588// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers) 611// m_dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); // old stuff (eilers)
589} 612}
590/* 613/*
591 * need to be const so let's fool the 614 * need to be const so let's fool the
592 * compiler :( 615 * compiler :(
593 */ 616 */
594void OTodoAccessBackendSQL::update()const { 617void OTodoAccessBackendSQL::update()const {
595 ((OTodoAccessBackendSQL*)this)->m_dirty = false; 618 ((OTodoAccessBackendSQL*)this)->m_dirty = false;
596 LoadQuery lo; 619 LoadQuery lo;
597 OSQLResult res = m_driver->query(&lo); 620 OSQLResult res = m_driver->query(&lo);
598 if ( res.state() != OSQLResult::Success ) 621 if ( res.state() != OSQLResult::Success )
599 return; 622 return;
600 623
601 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res ); 624 ((OTodoAccessBackendSQL*)this)->m_uids = uids( res );
602} 625}
603QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{ 626QArray<int> OTodoAccessBackendSQL::uids( const OSQLResult& res) const{
604 627
605 OSQLResultItem::ValueList list = res.results(); 628 OSQLResultItem::ValueList list = res.results();
606 OSQLResultItem::ValueList::Iterator it; 629 OSQLResultItem::ValueList::Iterator it;
607 QArray<int> ints(list.count() ); 630 QArray<int> ints(list.count() );
608 qWarning(" count = %d", list.count() ); 631 qWarning(" count = %d", list.count() );
609 632
610 int i = 0; 633 int i = 0;
611 for (it = list.begin(); it != list.end(); ++it ) { 634 for (it = list.begin(); it != list.end(); ++it ) {
612 ints[i] = (*it).data("uid").toInt(); 635 ints[i] = (*it).data("uid").toInt();
613 i++; 636 i++;
614 } 637 }
615 return ints; 638 return ints;
616} 639}
617 640
618QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const 641QArray<int> OTodoAccessBackendSQL::matchRegexp( const QRegExp &r ) const
619{ 642{
620 643
621#warning OTodoAccessBackendSQL::matchRegexp() not implemented !! 644#warning OTodoAccessBackendSQL::matchRegexp() not implemented !!
622 645
623#if 0 646#if 0
624 647
625 Copied from xml-backend by not adapted to sql (eilers) 648 Copied from xml-backend by not adapted to sql (eilers)
626 649
627 QArray<int> m_currentQuery( m_events.count() ); 650 QArray<int> m_currentQuery( m_events.count() );
628 uint arraycounter = 0; 651 uint arraycounter = 0;
629 652
630 653
631 654
632 QMap<int, OTodo>::ConstIterator it; 655 QMap<int, OTodo>::ConstIterator it;
633 for (it = m_events.begin(); it != m_events.end(); ++it ) { 656 for (it = m_events.begin(); it != m_events.end(); ++it ) {
634 if ( it.data().match( r ) ) 657 if ( it.data().match( r ) )
635 m_currentQuery[arraycounter++] = it.data().uid(); 658 m_currentQuery[arraycounter++] = it.data().uid();
636 659
637 } 660 }
638 // Shrink to fit.. 661 // Shrink to fit..
639 m_currentQuery.resize(arraycounter); 662 m_currentQuery.resize(arraycounter);
640 663
641 return m_currentQuery; 664 return m_currentQuery;
642#endif 665#endif
643 QArray<int> empty; 666 QArray<int> empty;
644 return empty; 667 return empty;
645} 668}
646QBitArray OTodoAccessBackendSQL::supports()const { 669QBitArray OTodoAccessBackendSQL::supports()const {
647 670
648 return sup(); 671 return sup();
649} 672}
650 673
651QBitArray OTodoAccessBackendSQL::sup() const{ 674QBitArray OTodoAccessBackendSQL::sup() const{
652 675
653 QBitArray ar( OTodo::CompletedDate + 1 ); 676 QBitArray ar( OTodo::CompletedDate + 1 );
654 ar.fill( true ); 677 ar.fill( true );
655 ar[OTodo::CrossReference] = false; 678 ar[OTodo::CrossReference] = false;
656 ar[OTodo::State ] = false; 679 ar[OTodo::State ] = false;
657 ar[OTodo::Reminders] = false; 680 ar[OTodo::Reminders] = false;
658 ar[OTodo::Notifiers] = false; 681 ar[OTodo::Notifiers] = false;
659 ar[OTodo::Maintainer] = false; 682 ar[OTodo::Maintainer] = false;
660 683
661 return ar; 684 return ar;
662} 685}
663 686
664void OTodoAccessBackendSQL::removeAllCompleted(){ 687void OTodoAccessBackendSQL::removeAllCompleted(){
665#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !! 688#warning OTodoAccessBackendSQL::removeAllCompleted() not implemented !!
666 689
667} 690}