summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp29
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp30
2 files changed, 57 insertions, 2 deletions
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
index bc51996..24b69fe 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
@@ -1,555 +1,582 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <stdio.h> 4#include <stdio.h>
5#include <stdlib.h> 5#include <stdlib.h>
6 6
7#include <sys/types.h> 7#include <sys/types.h>
8#include <sys/mman.h> 8#include <sys/mman.h>
9#include <sys/stat.h> 9#include <sys/stat.h>
10 10
11#include <unistd.h> 11#include <unistd.h>
12 12
13#include <qasciidict.h> 13#include <qasciidict.h>
14#include <qfile.h> 14#include <qfile.h>
15 15
16#include <qtopia/global.h> 16#include <qtopia/global.h>
17#include <qtopia/stringutil.h> 17#include <qtopia/stringutil.h>
18#include <qtopia/timeconversion.h> 18#include <qtopia/timeconversion.h>
19 19
20#include "opimnotifymanager.h" 20#include "opimnotifymanager.h"
21#include "orecur.h" 21#include "orecur.h"
22#include "otimezone.h" 22#include "otimezone.h"
23#include "odatebookaccessbackend_xml.h" 23#include "odatebookaccessbackend_xml.h"
24 24
25namespace { 25namespace {
26 // FROM TT again
27char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
28{
29 char needleChar;
30 char haystackChar;
31 if (!needle || !haystack || !hLen || !nLen)
32 return 0;
33
34 const char* hsearch = haystack;
35
36 if ((needleChar = *needle++) != 0) {
37 nLen--; //(to make up for needle++)
38 do {
39 do {
40 if ((haystackChar = *hsearch++) == 0)
41 return (0);
42 if (hsearch >= haystack + hLen)
43 return (0);
44 } while (haystackChar != needleChar);
45 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
46 hsearch--;
47 }
48 return ((char *)hsearch);
49}
50}
51
52namespace {
26 time_t start, end, created, rp_end; 53 time_t start, end, created, rp_end;
27 ORecur* rec; 54 ORecur* rec;
28 ORecur* recur() { 55 ORecur* recur() {
29 if (!rec) 56 if (!rec)
30 rec = new ORecur; 57 rec = new ORecur;
31 58
32 return rec; 59 return rec;
33 } 60 }
34 int alarmTime; 61 int alarmTime;
35 int snd; 62 int snd;
36 enum Attribute{ 63 enum Attribute{
37 FDescription = 0, 64 FDescription = 0,
38 FLocation, 65 FLocation,
39 FCategories, 66 FCategories,
40 FUid, 67 FUid,
41 FType, 68 FType,
42 FAlarm, 69 FAlarm,
43 FSound, 70 FSound,
44 FRType, 71 FRType,
45 FRWeekdays, 72 FRWeekdays,
46 FRPosition, 73 FRPosition,
47 FRFreq, 74 FRFreq,
48 FRHasEndDate, 75 FRHasEndDate,
49 FREndDate, 76 FREndDate,
50 FRStart, 77 FRStart,
51 FREnd, 78 FREnd,
52 FNote, 79 FNote,
53 FCreated, 80 FCreated,
54 FTimeZone, 81 FTimeZone,
55 FRecParent, 82 FRecParent,
56 FRecChildren, 83 FRecChildren,
57 FExceptions 84 FExceptions
58 }; 85 };
59 inline void save( const OEvent& ev, QString& buf ) { 86 inline void save( const OEvent& ev, QString& buf ) {
60 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; 87 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
61 if (!ev.location().isEmpty() ) 88 if (!ev.location().isEmpty() )
62 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; 89 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
63 90
64 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; 91 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
65 buf += " uid=\"" + QString::number( ev.uid() ) + "\""; 92 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
66 93
67 if (ev.isAllDay() ) 94 if (ev.isAllDay() )
68 buf += " type=\"AllDay\""; 95 buf += " type=\"AllDay\"";
69 96
70 if (ev.hasNotifiers() ) { 97 if (ev.hasNotifiers() ) {
71 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first 98 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
72 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; 99 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
73 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; 100 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
74 if ( alarm.sound() == OPimAlarm::Loud ) 101 if ( alarm.sound() == OPimAlarm::Loud )
75 buf += "loud"; 102 buf += "loud";
76 else 103 else
77 buf += "silent"; 104 buf += "silent";
78 buf += "\""; 105 buf += "\"";
79 } 106 }
80 if ( ev.hasRecurrence() ) { 107 if ( ev.hasRecurrence() ) {
81 buf += ev.recurrence().toString(); 108 buf += ev.recurrence().toString();
82 } 109 }
83 110
84 /* 111 /*
85 * fscking timezones :) well, we'll first convert 112 * fscking timezones :) well, we'll first convert
86 * the QDateTime to a QDateTime in UTC time 113 * the QDateTime to a QDateTime in UTC time
87 * and then we'll create a nice time_t 114 * and then we'll create a nice time_t
88 */ 115 */
89 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); 116 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
90 buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\""; 117 buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\"";
91 buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\""; 118 buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\"";
92 if (!ev.note().isEmpty() ) { 119 if (!ev.note().isEmpty() ) {
93 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\""; 120 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\"";
94 } 121 }
95 122
96 buf += " timezone=\""; 123 buf += " timezone=\"";
97 if ( ev.timeZone().isEmpty() ) 124 if ( ev.timeZone().isEmpty() )
98 buf += "None"; 125 buf += "None";
99 else 126 else
100 buf += ev.timeZone(); 127 buf += ev.timeZone();
101 128
102 if (ev.parent() != 0 ) { 129 if (ev.parent() != 0 ) {
103 buf += " recparent=\""+QString::number(ev.parent() )+"\""; 130 buf += " recparent=\""+QString::number(ev.parent() )+"\"";
104 } 131 }
105 132
106 if (ev.children().count() != 0 ) { 133 if (ev.children().count() != 0 ) {
107 QArray<int> children = ev.children(); 134 QArray<int> children = ev.children();
108 buf += " recchildren=\""; 135 buf += " recchildren=\"";
109 for ( uint i = 0; i < children.count(); i++ ) { 136 for ( uint i = 0; i < children.count(); i++ ) {
110 if ( i != 0 ) buf += " "; 137 if ( i != 0 ) buf += " ";
111 buf += QString::number( children[i] ); 138 buf += QString::number( children[i] );
112 } 139 }
113 buf+= "\""; 140 buf+= "\"";
114 } 141 }
115 142
116 // skip custom writing 143 // skip custom writing
117 } 144 }
118 145
119 inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) { 146 inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) {
120 QMap<int, OEvent>::ConstIterator it; 147 QMap<int, OEvent>::ConstIterator it;
121 QString buf; 148 QString buf;
122 QCString str; 149 QCString str;
123 int total_written; 150 int total_written;
124 for ( it = list.begin(); it != list.end(); ++it ) { 151 for ( it = list.begin(); it != list.end(); ++it ) {
125 buf = "<event"; 152 buf = "<event";
126 save( it.data(), buf ); 153 save( it.data(), buf );
127 buf += " />\n"; 154 buf += " />\n";
128 str = buf.utf8(); 155 str = buf.utf8();
129 156
130 total_written = file.writeBlock(str.data(), str.length() ); 157 total_written = file.writeBlock(str.data(), str.length() );
131 if ( total_written != int(str.length() ) ) 158 if ( total_written != int(str.length() ) )
132 return false; 159 return false;
133 } 160 }
134 return true; 161 return true;
135 } 162 }
136} 163}
137 164
138ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , 165ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
139 const QString& fileName ) 166 const QString& fileName )
140 : ODateBookAccessBackend() { 167 : ODateBookAccessBackend() {
141 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; 168 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
142 m_changed = false; 169 m_changed = false;
143} 170}
144ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { 171ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
145} 172}
146bool ODateBookAccessBackend_XML::load() { 173bool ODateBookAccessBackend_XML::load() {
147 return loadFile(); 174 return loadFile();
148} 175}
149bool ODateBookAccessBackend_XML::reload() { 176bool ODateBookAccessBackend_XML::reload() {
150 clear(); 177 clear();
151 return load(); 178 return load();
152} 179}
153bool ODateBookAccessBackend_XML::save() { 180bool ODateBookAccessBackend_XML::save() {
154 if (!m_changed) return true; 181 if (!m_changed) return true;
155 182
156 int total_written; 183 int total_written;
157 QString strFileNew = m_name + ".new"; 184 QString strFileNew = m_name + ".new";
158 185
159 QFile f( strFileNew ); 186 QFile f( strFileNew );
160 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false; 187 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false;
161 188
162 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 189 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
163 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 190 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
164 buf += "<events>\n"; 191 buf += "<events>\n";
165 QCString str = buf.utf8(); 192 QCString str = buf.utf8();
166 total_written = f.writeBlock( str.data(), str.length() ); 193 total_written = f.writeBlock( str.data(), str.length() );
167 if ( total_written != int(str.length() ) ) { 194 if ( total_written != int(str.length() ) ) {
168 f.close(); 195 f.close();
169 QFile::remove( strFileNew ); 196 QFile::remove( strFileNew );
170 return false; 197 return false;
171 } 198 }
172 199
173 if (!forAll( m_raw, f ) ) { 200 if (!forAll( m_raw, f ) ) {
174 f.close(); 201 f.close();
175 QFile::remove( strFileNew ); 202 QFile::remove( strFileNew );
176 return false; 203 return false;
177 } 204 }
178 if (!forAll( m_rep, f ) ) { 205 if (!forAll( m_rep, f ) ) {
179 f.close(); 206 f.close();
180 QFile::remove( strFileNew ); 207 QFile::remove( strFileNew );
181 return false; 208 return false;
182 } 209 }
183 210
184 buf = "</events>\n</DATEBOOK>\n"; 211 buf = "</events>\n</DATEBOOK>\n";
185 str = buf.utf8(); 212 str = buf.utf8();
186 total_written = f.writeBlock( str.data(), str.length() ); 213 total_written = f.writeBlock( str.data(), str.length() );
187 if ( total_written != int(str.length() ) ) { 214 if ( total_written != int(str.length() ) ) {
188 f.close(); 215 f.close();
189 QFile::remove( strFileNew ); 216 QFile::remove( strFileNew );
190 return false; 217 return false;
191 } 218 }
192 f.close(); 219 f.close();
193 220
194 if ( ::rename( strFileNew, m_name ) < 0 ) { 221 if ( ::rename( strFileNew, m_name ) < 0 ) {
195 QFile::remove( strFileNew ); 222 QFile::remove( strFileNew );
196 return false; 223 return false;
197 } 224 }
198 225
199 m_changed = false; 226 m_changed = false;
200 return true; 227 return true;
201} 228}
202QArray<int> ODateBookAccessBackend_XML::allRecords()const { 229QArray<int> ODateBookAccessBackend_XML::allRecords()const {
203 QArray<int> ints( m_raw.count()+ m_rep.count() ); 230 QArray<int> ints( m_raw.count()+ m_rep.count() );
204 uint i = 0; 231 uint i = 0;
205 QMap<int, OEvent>::ConstIterator it; 232 QMap<int, OEvent>::ConstIterator it;
206 233
207 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 234 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
208 ints[i] = it.key(); 235 ints[i] = it.key();
209 i++; 236 i++;
210 } 237 }
211 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 238 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
212 ints[i] = it.key(); 239 ints[i] = it.key();
213 i++; 240 i++;
214 } 241 }
215 242
216 return ints; 243 return ints;
217} 244}
218QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) { 245QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) {
219 return QArray<int>(); 246 return QArray<int>();
220} 247}
221void ODateBookAccessBackend_XML::clear() { 248void ODateBookAccessBackend_XML::clear() {
222 m_raw.clear(); 249 m_raw.clear();
223 m_rep.clear(); 250 m_rep.clear();
224} 251}
225OEvent ODateBookAccessBackend_XML::find( int uid ) const{ 252OEvent ODateBookAccessBackend_XML::find( int uid ) const{
226 if ( m_raw.contains( uid ) ) 253 if ( m_raw.contains( uid ) )
227 return m_raw[uid]; 254 return m_raw[uid];
228 else 255 else
229 return m_rep[uid]; 256 return m_rep[uid];
230} 257}
231bool ODateBookAccessBackend_XML::add( const OEvent& ev ) { 258bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
232 m_changed = true; 259 m_changed = true;
233 if (ev.hasRecurrence() ) 260 if (ev.hasRecurrence() )
234 m_rep.insert( ev.uid(), ev ); 261 m_rep.insert( ev.uid(), ev );
235 else 262 else
236 m_raw.insert( ev.uid(), ev ); 263 m_raw.insert( ev.uid(), ev );
237 264
238 return true; 265 return true;
239} 266}
240bool ODateBookAccessBackend_XML::remove( int uid ) { 267bool ODateBookAccessBackend_XML::remove( int uid ) {
241 m_changed = true; 268 m_changed = true;
242 m_rep.remove( uid ); 269 m_rep.remove( uid );
243 m_rep.remove( uid ); 270 m_rep.remove( uid );
244 271
245 return true; 272 return true;
246} 273}
247bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) { 274bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) {
248 replace( ev.uid() ); 275 replace( ev.uid() );
249 return add( ev ); 276 return add( ev );
250} 277}
251QArray<int> ODateBookAccessBackend_XML::rawEvents()const { 278QArray<int> ODateBookAccessBackend_XML::rawEvents()const {
252 return allRecords(); 279 return allRecords();
253} 280}
254QArray<int> ODateBookAccessBackend_XML::rawRepeats()const { 281QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
255 QArray<int> ints( m_rep.count() ); 282 QArray<int> ints( m_rep.count() );
256 uint i = 0; 283 uint i = 0;
257 QMap<int, OEvent>::ConstIterator it; 284 QMap<int, OEvent>::ConstIterator it;
258 285
259 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 286 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
260 ints[i] = it.key(); 287 ints[i] = it.key();
261 i++; 288 i++;
262 } 289 }
263 290
264 return ints; 291 return ints;
265} 292}
266QArray<int> ODateBookAccessBackend_XML::nonRepeats()const { 293QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
267 QArray<int> ints( m_raw.count() ); 294 QArray<int> ints( m_raw.count() );
268 uint i = 0; 295 uint i = 0;
269 QMap<int, OEvent>::ConstIterator it; 296 QMap<int, OEvent>::ConstIterator it;
270 297
271 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 298 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
272 ints[i] = it.key(); 299 ints[i] = it.key();
273 i++; 300 i++;
274 } 301 }
275 302
276 return ints; 303 return ints;
277} 304}
278OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() { 305OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
279 OEvent::ValueList list; 306 OEvent::ValueList list;
280 QMap<int, OEvent>::ConstIterator it; 307 QMap<int, OEvent>::ConstIterator it;
281 for (it = m_raw.begin(); it != m_raw.end(); ++it ) 308 for (it = m_raw.begin(); it != m_raw.end(); ++it )
282 list.append( it.data() ); 309 list.append( it.data() );
283 310
284 return list; 311 return list;
285} 312}
286OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() { 313OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
287 OEvent::ValueList list; 314 OEvent::ValueList list;
288 QMap<int, OEvent>::ConstIterator it; 315 QMap<int, OEvent>::ConstIterator it;
289 for (it = m_rep.begin(); it != m_rep.end(); ++it ) 316 for (it = m_rep.begin(); it != m_rep.end(); ++it )
290 list.append( it.data() ); 317 list.append( it.data() );
291 318
292 return list; 319 return list;
293} 320}
294bool ODateBookAccessBackend_XML::loadFile() { 321bool ODateBookAccessBackend_XML::loadFile() {
295 m_changed = false; 322 m_changed = false;
296 323
297 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); 324 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
298 if ( fd < 0 ) return false; 325 if ( fd < 0 ) return false;
299 326
300 struct stat attribute; 327 struct stat attribute;
301 if ( ::fstat(fd, &attribute ) == -1 ) { 328 if ( ::fstat(fd, &attribute ) == -1 ) {
302 ::close( fd ); 329 ::close( fd );
303 return false; 330 return false;
304 } 331 }
305 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 332 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
306 if ( map_addr == ( (caddr_t)-1) ) { 333 if ( map_addr == ( (caddr_t)-1) ) {
307 ::close( fd ); 334 ::close( fd );
308 return false; 335 return false;
309 } 336 }
310 337
311 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); 338 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
312 ::close( fd ); 339 ::close( fd );
313 340
314 QAsciiDict<int> dict(FExceptions+1); 341 QAsciiDict<int> dict(FExceptions+1);
315 dict.setAutoDelete( true ); 342 dict.setAutoDelete( true );
316 dict.insert( "description", new int(FDescription) ); 343 dict.insert( "description", new int(FDescription) );
317 dict.insert( "location", new int(FLocation) ); 344 dict.insert( "location", new int(FLocation) );
318 dict.insert( "categories", new int(FCategories) ); 345 dict.insert( "categories", new int(FCategories) );
319 dict.insert( "uid", new int(FUid) ); 346 dict.insert( "uid", new int(FUid) );
320 dict.insert( "type", new int(FType) ); 347 dict.insert( "type", new int(FType) );
321 dict.insert( "alarm", new int(FAlarm) ); 348 dict.insert( "alarm", new int(FAlarm) );
322 dict.insert( "sound", new int(FSound) ); 349 dict.insert( "sound", new int(FSound) );
323 dict.insert( "rtype", new int(FRType) ); 350 dict.insert( "rtype", new int(FRType) );
324 dict.insert( "rweekdays", new int(FRWeekdays) ); 351 dict.insert( "rweekdays", new int(FRWeekdays) );
325 dict.insert( "rposition", new int(FRPosition) ); 352 dict.insert( "rposition", new int(FRPosition) );
326 dict.insert( "rfreq", new int(FRFreq) ); 353 dict.insert( "rfreq", new int(FRFreq) );
327 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 354 dict.insert( "rhasenddate", new int(FRHasEndDate) );
328 dict.insert( "enddt", new int(FREndDate) ); 355 dict.insert( "enddt", new int(FREndDate) );
329 dict.insert( "start", new int(FRStart) ); 356 dict.insert( "start", new int(FRStart) );
330 dict.insert( "end", new int(FREnd) ); 357 dict.insert( "end", new int(FREnd) );
331 dict.insert( "note", new int(FNote) ); 358 dict.insert( "note", new int(FNote) );
332 dict.insert( "created", new int(FCreated) ); 359 dict.insert( "created", new int(FCreated) );
333 dict.insert( "recparent", new int(FRecParent) ); 360 dict.insert( "recparent", new int(FRecParent) );
334 dict.insert( "recchildren", new int(FRecChildren) ); 361 dict.insert( "recchildren", new int(FRecChildren) );
335 dict.insert( "exceptions", new int(FExceptions) ); 362 dict.insert( "exceptions", new int(FExceptions) );
336 dict.insert( "timezone", new int(FTimeZone) ); 363 dict.insert( "timezone", new int(FTimeZone) );
337 364
338 char* dt = (char*)map_addr; 365 char* dt = (char*)map_addr;
339 int len = attribute.st_size; 366 int len = attribute.st_size;
340 int i = 0; 367 int i = 0;
341 char* point; 368 char* point;
342 const char* collectionString = "<event "; 369 const char* collectionString = "<event ";
343 int strLen = ::strlen(collectionString); 370 int strLen = ::strlen(collectionString);
344 int *find; 371 int *find;
345 while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { 372 while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) {
346 i = point -dt; 373 i = point -dt;
347 i+= strLen; 374 i+= strLen;
348 375
349 alarmTime = -1; 376 alarmTime = -1;
350 snd = 0; // silent 377 snd = 0; // silent
351 378
352 OEvent ev; 379 OEvent ev;
353 rec = 0; 380 rec = 0;
354 381
355 while ( TRUE ) { 382 while ( TRUE ) {
356 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 383 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
357 ++i; 384 ++i;
358 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 385 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
359 break; 386 break;
360 387
361 388
362 // we have another attribute, read it. 389 // we have another attribute, read it.
363 int j = i; 390 int j = i;
364 while ( j < len && dt[j] != '=' ) 391 while ( j < len && dt[j] != '=' )
365 ++j; 392 ++j;
366 QCString attr( dt+i, j-i+1); 393 QCString attr( dt+i, j-i+1);
367 394
368 i = ++j; // skip = 395 i = ++j; // skip =
369 396
370 // find the start of quotes 397 // find the start of quotes
371 while ( i < len && dt[i] != '"' ) 398 while ( i < len && dt[i] != '"' )
372 ++i; 399 ++i;
373 j = ++i; 400 j = ++i;
374 401
375 bool haveUtf = FALSE; 402 bool haveUtf = FALSE;
376 bool haveEnt = FALSE; 403 bool haveEnt = FALSE;
377 while ( j < len && dt[j] != '"' ) { 404 while ( j < len && dt[j] != '"' ) {
378 if ( ((unsigned char)dt[j]) > 0x7f ) 405 if ( ((unsigned char)dt[j]) > 0x7f )
379 haveUtf = TRUE; 406 haveUtf = TRUE;
380 if ( dt[j] == '&' ) 407 if ( dt[j] == '&' )
381 haveEnt = TRUE; 408 haveEnt = TRUE;
382 ++j; 409 ++j;
383 } 410 }
384 if ( i == j ) { 411 if ( i == j ) {
385 // empty value 412 // empty value
386 i = j + 1; 413 i = j + 1;
387 continue; 414 continue;
388 } 415 }
389 416
390 QCString value( dt+i, j-i+1 ); 417 QCString value( dt+i, j-i+1 );
391 i = j + 1; 418 i = j + 1;
392 419
393 QString str = (haveUtf ? QString::fromUtf8( value ) 420 QString str = (haveUtf ? QString::fromUtf8( value )
394 : QString::fromLatin1( value ) ); 421 : QString::fromLatin1( value ) );
395 if ( haveEnt ) 422 if ( haveEnt )
396 str = Qtopia::plainString( str ); 423 str = Qtopia::plainString( str );
397 424
398 /* 425 /*
399 * add key + value 426 * add key + value
400 */ 427 */
401 find = dict[attr.data()]; 428 find = dict[attr.data()];
402 if (!find) 429 if (!find)
403 ev.setCustomField( attr, value ); 430 ev.setCustomField( attr, value );
404 else { 431 else {
405 setField( ev, *find, value ); 432 setField( ev, *find, value );
406 } 433 }
407 } 434 }
408 /* time to finalize */ 435 /* time to finalize */
409 finalizeRecord( ev ); 436 finalizeRecord( ev );
410 add( ev ); 437 add( ev );
411 delete rec; 438 delete rec;
412 } 439 }
413 ::munmap(map_addr, attribute.st_size ); 440 ::munmap(map_addr, attribute.st_size );
414 m_changed = false; // changed during add 441 m_changed = false; // changed during add
415 442
416 return true; 443 return true;
417} 444}
418void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { 445void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
419 /* AllDay is alway in UTC */ 446 /* AllDay is alway in UTC */
420 if ( ev.isAllDay() ) { 447 if ( ev.isAllDay() ) {
421 OTimeZone utc = OTimeZone::utc(); 448 OTimeZone utc = OTimeZone::utc();
422 ev.setStartDateTime( utc.fromUTCDateTime( start ) ); 449 ev.setStartDateTime( utc.fromUTCDateTime( start ) );
423 ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); 450 ev.setEndDateTime ( utc.fromUTCDateTime( end ) );
424 ev.setTimeZone( "UTC"); // make sure it is really utc 451 ev.setTimeZone( "UTC"); // make sure it is really utc
425 }else { 452 }else {
426 /* to current date time */ 453 /* to current date time */
427 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); 454 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
428 QDateTime date = zone.toDateTime( start ); 455 QDateTime date = zone.toDateTime( start );
429 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) ); 456 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
430 457
431 date = zone.toDateTime( end ); 458 date = zone.toDateTime( end );
432 ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) ); 459 ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) );
433 } 460 }
434 if ( rec && rec->doesRecur() ) { 461 if ( rec && rec->doesRecur() ) {
435 OTimeZone utc = OTimeZone::utc(); 462 OTimeZone utc = OTimeZone::utc();
436 ORecur recu( *rec ); // call copy c'tor; 463 ORecur recu( *rec ); // call copy c'tor;
437 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); 464 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() );
438 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); 465 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) );
439 recu.setStart( ev.startDateTime().date() ); 466 recu.setStart( ev.startDateTime().date() );
440 ev.setRecurrence( recu ); 467 ev.setRecurrence( recu );
441 } 468 }
442 469
443 if (alarmTime != -1 ) { 470 if (alarmTime != -1 ) {
444 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); 471 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
445 OPimAlarm al( snd , dt ); 472 OPimAlarm al( snd , dt );
446 ev.notifiers().add( al ); 473 ev.notifiers().add( al );
447 } 474 }
448 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) { 475 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
449 ev.setUid( 1 ); 476 ev.setUid( 1 );
450 } 477 }
451 if ( ev.hasRecurrence() ) 478 if ( ev.hasRecurrence() )
452 m_rep.insert( ev.uid(), ev ); 479 m_rep.insert( ev.uid(), ev );
453 else 480 else
454 m_raw.insert( ev.uid(), ev ); 481 m_raw.insert( ev.uid(), ev );
455 482
456} 483}
457void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) { 484void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) {
458// qWarning(" setting %s", value.latin1() ); 485// qWarning(" setting %s", value.latin1() );
459 switch( id ) { 486 switch( id ) {
460 case FDescription: 487 case FDescription:
461 e.setDescription( value ); 488 e.setDescription( value );
462 break; 489 break;
463 case FLocation: 490 case FLocation:
464 e.setLocation( value ); 491 e.setLocation( value );
465 break; 492 break;
466 case FCategories: 493 case FCategories:
467 e.setCategories( e.idsFromString( value ) ); 494 e.setCategories( e.idsFromString( value ) );
468 break; 495 break;
469 case FUid: 496 case FUid:
470 e.setUid( value.toInt() ); 497 e.setUid( value.toInt() );
471 break; 498 break;
472 case FType: 499 case FType:
473 if ( value == "AllDay" ) { 500 if ( value == "AllDay" ) {
474 e.setAllDay( true ); 501 e.setAllDay( true );
475 e.setTimeZone( "UTC" ); 502 e.setTimeZone( "UTC" );
476 } 503 }
477 break; 504 break;
478 case FAlarm: 505 case FAlarm:
479 alarmTime = value.toInt(); 506 alarmTime = value.toInt();
480 break; 507 break;
481 case FSound: 508 case FSound:
482 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent; 509 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
483 break; 510 break;
484 // recurrence stuff 511 // recurrence stuff
485 case FRType: 512 case FRType:
486 if ( value == "Daily" ) 513 if ( value == "Daily" )
487 recur()->setType( ORecur::Daily ); 514 recur()->setType( ORecur::Daily );
488 else if ( value == "Weekly" ) 515 else if ( value == "Weekly" )
489 recur()->setType( ORecur::Weekly); 516 recur()->setType( ORecur::Weekly);
490 else if ( value == "MonthlyDay" ) 517 else if ( value == "MonthlyDay" )
491 recur()->setType( ORecur::MonthlyDay ); 518 recur()->setType( ORecur::MonthlyDay );
492 else if ( value == "MonthlyDate" ) 519 else if ( value == "MonthlyDate" )
493 recur()->setType( ORecur::MonthlyDate ); 520 recur()->setType( ORecur::MonthlyDate );
494 else if ( value == "Yearly" ) 521 else if ( value == "Yearly" )
495 recur()->setType( ORecur::Yearly ); 522 recur()->setType( ORecur::Yearly );
496 else 523 else
497 recur()->setType( ORecur::NoRepeat ); 524 recur()->setType( ORecur::NoRepeat );
498 break; 525 break;
499 case FRWeekdays: 526 case FRWeekdays:
500 recur()->setDays( value.toInt() ); 527 recur()->setDays( value.toInt() );
501 break; 528 break;
502 case FRPosition: 529 case FRPosition:
503 recur()->setPosition( value.toInt() ); 530 recur()->setPosition( value.toInt() );
504 break; 531 break;
505 case FRFreq: 532 case FRFreq:
506 recur()->setFrequency( value.toInt() ); 533 recur()->setFrequency( value.toInt() );
507 break; 534 break;
508 case FRHasEndDate: 535 case FRHasEndDate:
509 recur()->setHasEndDate( value.toInt() ); 536 recur()->setHasEndDate( value.toInt() );
510 break; 537 break;
511 case FREndDate: { 538 case FREndDate: {
512 rp_end = (time_t) value.toLong(); 539 rp_end = (time_t) value.toLong();
513 break; 540 break;
514 } 541 }
515 case FRStart: { 542 case FRStart: {
516 start = (time_t) value.toLong(); 543 start = (time_t) value.toLong();
517 break; 544 break;
518 } 545 }
519 case FREnd: { 546 case FREnd: {
520 end = ( (time_t) value.toLong() ); 547 end = ( (time_t) value.toLong() );
521 break; 548 break;
522 } 549 }
523 case FNote: 550 case FNote:
524 e.setNote( value ); 551 e.setNote( value );
525 break; 552 break;
526 case FCreated: 553 case FCreated:
527 created = value.toInt(); 554 created = value.toInt();
528 break; 555 break;
529 case FRecParent: 556 case FRecParent:
530 e.setParent( value.toInt() ); 557 e.setParent( value.toInt() );
531 break; 558 break;
532 case FRecChildren:{ 559 case FRecChildren:{
533 QStringList list = QStringList::split(' ', value ); 560 QStringList list = QStringList::split(' ', value );
534 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 561 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
535 e.addChild( (*it).toInt() ); 562 e.addChild( (*it).toInt() );
536 } 563 }
537 } 564 }
538 break; 565 break;
539 case FExceptions:{ 566 case FExceptions:{
540 QStringList list = QStringList::split(' ', value ); 567 QStringList list = QStringList::split(' ', value );
541 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 568 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
542 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() ); 569 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() );
543 qWarning("adding exception %s", date.toString().latin1() ); 570 qWarning("adding exception %s", date.toString().latin1() );
544 recur()->exceptions().append( date ); 571 recur()->exceptions().append( date );
545 } 572 }
546 } 573 }
547 break; 574 break;
548 case FTimeZone: 575 case FTimeZone:
549 if ( value != "None" ) 576 if ( value != "None" )
550 e.setTimeZone( value ); 577 e.setTimeZone( value );
551 break; 578 break;
552 default: 579 default:
553 break; 580 break;
554 } 581 }
555} 582}
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 22b2469..cda300b 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,647 +1,675 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <sys/mman.h> 4#include <sys/mman.h>
5#include <sys/stat.h> 5#include <sys/stat.h>
6#include <sys/types.h> 6#include <sys/types.h>
7 7
8#include <unistd.h> 8#include <unistd.h>
9 9
10 10
11#include <qfile.h> 11#include <qfile.h>
12#include <qvector.h> 12#include <qvector.h>
13 13
14#include <qpe/global.h> 14#include <qpe/global.h>
15#include <qpe/stringutil.h> 15#include <qpe/stringutil.h>
16#include <qpe/timeconversion.h> 16#include <qpe/timeconversion.h>
17 17
18#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
19 19
20namespace {
21 // FROM TT again
22char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
23{
24 char needleChar;
25 char haystackChar;
26 if (!needle || !haystack || !hLen || !nLen)
27 return 0;
28
29 const char* hsearch = haystack;
30
31 if ((needleChar = *needle++) != 0) {
32 nLen--; //(to make up for needle++)
33 do {
34 do {
35 if ((haystackChar = *hsearch++) == 0)
36 return (0);
37 if (hsearch >= haystack + hLen)
38 return (0);
39 } while (haystackChar != needleChar);
40 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
41 hsearch--;
42 }
43 return ((char *)hsearch);
44}
45}
46
47
20OTodoAccessXML::OTodoAccessXML( const QString& appName, 48OTodoAccessXML::OTodoAccessXML( const QString& appName,
21 const QString& fileName ) 49 const QString& fileName )
22 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 50 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
23{ 51{
24 if (!fileName.isEmpty() ) 52 if (!fileName.isEmpty() )
25 m_file = fileName; 53 m_file = fileName;
26 else 54 else
27 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 55 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
28} 56}
29OTodoAccessXML::~OTodoAccessXML() { 57OTodoAccessXML::~OTodoAccessXML() {
30 58
31} 59}
32bool OTodoAccessXML::load() { 60bool OTodoAccessXML::load() {
33 m_opened = true; 61 m_opened = true;
34 m_changed = false; 62 m_changed = false;
35 /* initialize dict */ 63 /* initialize dict */
36 /* 64 /*
37 * UPDATE dict if you change anything!!! 65 * UPDATE dict if you change anything!!!
38 */ 66 */
39 QAsciiDict<int> dict(21); 67 QAsciiDict<int> dict(21);
40 dict.setAutoDelete( TRUE ); 68 dict.setAutoDelete( TRUE );
41 dict.insert("Categories" , new int(OTodo::Category) ); 69 dict.insert("Categories" , new int(OTodo::Category) );
42 dict.insert("Uid" , new int(OTodo::Uid) ); 70 dict.insert("Uid" , new int(OTodo::Uid) );
43 dict.insert("HasDate" , new int(OTodo::HasDate) ); 71 dict.insert("HasDate" , new int(OTodo::HasDate) );
44 dict.insert("Completed" , new int(OTodo::Completed) ); 72 dict.insert("Completed" , new int(OTodo::Completed) );
45 dict.insert("Description" , new int(OTodo::Description) ); 73 dict.insert("Description" , new int(OTodo::Description) );
46 dict.insert("Summary" , new int(OTodo::Summary) ); 74 dict.insert("Summary" , new int(OTodo::Summary) );
47 dict.insert("Priority" , new int(OTodo::Priority) ); 75 dict.insert("Priority" , new int(OTodo::Priority) );
48 dict.insert("DateDay" , new int(OTodo::DateDay) ); 76 dict.insert("DateDay" , new int(OTodo::DateDay) );
49 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 77 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
50 dict.insert("DateYear" , new int(OTodo::DateYear) ); 78 dict.insert("DateYear" , new int(OTodo::DateYear) );
51 dict.insert("Progress" , new int(OTodo::Progress) ); 79 dict.insert("Progress" , new int(OTodo::Progress) );
52 dict.insert("Completed", new int(OTodo::Completed) ); 80 dict.insert("Completed", new int(OTodo::Completed) );
53 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 81 dict.insert("CrossReference", new int(OTodo::CrossReference) );
54 dict.insert("State", new int(OTodo::State) ); 82 dict.insert("State", new int(OTodo::State) );
55 dict.insert("Recurrence", new int(OTodo::Recurrence) ); 83 dict.insert("Recurrence", new int(OTodo::Recurrence) );
56 dict.insert("Alarms", new int(OTodo::Alarms) ); 84 dict.insert("Alarms", new int(OTodo::Alarms) );
57 dict.insert("Reminders", new int(OTodo::Reminders) ); 85 dict.insert("Reminders", new int(OTodo::Reminders) );
58 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 86 dict.insert("Notifiers", new int(OTodo::Notifiers) );
59 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 87 dict.insert("Maintainer", new int(OTodo::Maintainer) );
60 88
61 // here the custom XML parser from TT it's GPL 89 // here the custom XML parser from TT it's GPL
62 // but we want to push OpiePIM... to TT..... 90 // but we want to push OpiePIM... to TT.....
63 // mmap part from zecke :) 91 // mmap part from zecke :)
64 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 92 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
65 struct stat attribut; 93 struct stat attribut;
66 if ( fd < 0 ) return false; 94 if ( fd < 0 ) return false;
67 95
68 if ( fstat(fd, &attribut ) == -1 ) { 96 if ( fstat(fd, &attribut ) == -1 ) {
69 ::close( fd ); 97 ::close( fd );
70 return false; 98 return false;
71 } 99 }
72 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 100 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
73 if ( map_addr == ( (caddr_t)-1) ) { 101 if ( map_addr == ( (caddr_t)-1) ) {
74 ::close(fd ); 102 ::close(fd );
75 return false; 103 return false;
76 } 104 }
77 /* advise the kernel who we want to read it */ 105 /* advise the kernel who we want to read it */
78 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 106 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
79 /* we do not the file any more */ 107 /* we do not the file any more */
80 ::close( fd ); 108 ::close( fd );
81 109
82 char* dt = (char*)map_addr; 110 char* dt = (char*)map_addr;
83 int len = attribut.st_size; 111 int len = attribut.st_size;
84 int i = 0; 112 int i = 0;
85 char *point; 113 char *point;
86 const char* collectionString = "<Task "; 114 const char* collectionString = "<Task ";
87 int strLen = strlen(collectionString); 115 int strLen = strlen(collectionString);
88 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { 116 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
89 i = point -dt; 117 i = point -dt;
90 i+= strLen; 118 i+= strLen;
91 qWarning("Found a start at %d %d", i, (point-dt) ); 119 qWarning("Found a start at %d %d", i, (point-dt) );
92 120
93 OTodo ev; 121 OTodo ev;
94 m_year = m_month = m_day = 0; 122 m_year = m_month = m_day = 0;
95 123
96 while ( TRUE ) { 124 while ( TRUE ) {
97 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 125 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
98 ++i; 126 ++i;
99 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 127 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
100 break; 128 break;
101 129
102 // we have another attribute, read it. 130 // we have another attribute, read it.
103 int j = i; 131 int j = i;
104 while ( j < len && dt[j] != '=' ) 132 while ( j < len && dt[j] != '=' )
105 ++j; 133 ++j;
106 QCString attr( dt+i, j-i+1); 134 QCString attr( dt+i, j-i+1);
107 135
108 i = ++j; // skip = 136 i = ++j; // skip =
109 137
110 // find the start of quotes 138 // find the start of quotes
111 while ( i < len && dt[i] != '"' ) 139 while ( i < len && dt[i] != '"' )
112 ++i; 140 ++i;
113 j = ++i; 141 j = ++i;
114 142
115 bool haveUtf = FALSE; 143 bool haveUtf = FALSE;
116 bool haveEnt = FALSE; 144 bool haveEnt = FALSE;
117 while ( j < len && dt[j] != '"' ) { 145 while ( j < len && dt[j] != '"' ) {
118 if ( ((unsigned char)dt[j]) > 0x7f ) 146 if ( ((unsigned char)dt[j]) > 0x7f )
119 haveUtf = TRUE; 147 haveUtf = TRUE;
120 if ( dt[j] == '&' ) 148 if ( dt[j] == '&' )
121 haveEnt = TRUE; 149 haveEnt = TRUE;
122 ++j; 150 ++j;
123 } 151 }
124 if ( i == j ) { 152 if ( i == j ) {
125 // empty value 153 // empty value
126 i = j + 1; 154 i = j + 1;
127 continue; 155 continue;
128 } 156 }
129 157
130 QCString value( dt+i, j-i+1 ); 158 QCString value( dt+i, j-i+1 );
131 i = j + 1; 159 i = j + 1;
132 160
133 QString str = (haveUtf ? QString::fromUtf8( value ) 161 QString str = (haveUtf ? QString::fromUtf8( value )
134 : QString::fromLatin1( value ) ); 162 : QString::fromLatin1( value ) );
135 if ( haveEnt ) 163 if ( haveEnt )
136 str = Qtopia::plainString( str ); 164 str = Qtopia::plainString( str );
137 165
138 /* 166 /*
139 * add key + value 167 * add key + value
140 */ 168 */
141 todo( &dict, ev, attr, str ); 169 todo( &dict, ev, attr, str );
142 170
143 } 171 }
144 /* 172 /*
145 * now add it 173 * now add it
146 */ 174 */
147 qWarning("End at %d", i ); 175 qWarning("End at %d", i );
148 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 176 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
149 ev.setUid( 1 ); 177 ev.setUid( 1 );
150 m_changed = true; 178 m_changed = true;
151 } 179 }
152 if ( ev.hasDueDate() ) { 180 if ( ev.hasDueDate() ) {
153 ev.setDueDate( QDate(m_year, m_month, m_day) ); 181 ev.setDueDate( QDate(m_year, m_month, m_day) );
154 } 182 }
155 m_events.insert(ev.uid(), ev ); 183 m_events.insert(ev.uid(), ev );
156 m_year = m_month = m_day = -1; 184 m_year = m_month = m_day = -1;
157 } 185 }
158 186
159 munmap(map_addr, attribut.st_size ); 187 munmap(map_addr, attribut.st_size );
160 188
161 qWarning("counts %d records loaded!", m_events.count() ); 189 qWarning("counts %d records loaded!", m_events.count() );
162 return true; 190 return true;
163} 191}
164bool OTodoAccessXML::reload() { 192bool OTodoAccessXML::reload() {
165 m_events.clear(); 193 m_events.clear();
166 return load(); 194 return load();
167} 195}
168bool OTodoAccessXML::save() { 196bool OTodoAccessXML::save() {
169// qWarning("saving"); 197// qWarning("saving");
170 if (!m_opened || !m_changed ) { 198 if (!m_opened || !m_changed ) {
171// qWarning("not saving"); 199// qWarning("not saving");
172 return true; 200 return true;
173 } 201 }
174 QString strNewFile = m_file + ".new"; 202 QString strNewFile = m_file + ".new";
175 QFile f( strNewFile ); 203 QFile f( strNewFile );
176 if (!f.open( IO_WriteOnly|IO_Raw ) ) 204 if (!f.open( IO_WriteOnly|IO_Raw ) )
177 return false; 205 return false;
178 206
179 int written; 207 int written;
180 QString out; 208 QString out;
181 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 209 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
182 210
183 // for all todos 211 // for all todos
184 QMap<int, OTodo>::Iterator it; 212 QMap<int, OTodo>::Iterator it;
185 for (it = m_events.begin(); it != m_events.end(); ++it ) { 213 for (it = m_events.begin(); it != m_events.end(); ++it ) {
186 out+= "<Task " + toString( (*it) ) + " />\n"; 214 out+= "<Task " + toString( (*it) ) + " />\n";
187 QCString cstr = out.utf8(); 215 QCString cstr = out.utf8();
188 written = f.writeBlock( cstr.data(), cstr.length() ); 216 written = f.writeBlock( cstr.data(), cstr.length() );
189 217
190 /* less written then we wanted */ 218 /* less written then we wanted */
191 if ( written != (int)cstr.length() ) { 219 if ( written != (int)cstr.length() ) {
192 f.close(); 220 f.close();
193 QFile::remove( strNewFile ); 221 QFile::remove( strNewFile );
194 return false; 222 return false;
195 } 223 }
196 out = QString::null; 224 out = QString::null;
197 } 225 }
198 226
199 out += "</Tasks>"; 227 out += "</Tasks>";
200 QCString cstr = out.utf8(); 228 QCString cstr = out.utf8();
201 written = f.writeBlock( cstr.data(), cstr.length() ); 229 written = f.writeBlock( cstr.data(), cstr.length() );
202 230
203 if ( written != (int)cstr.length() ) { 231 if ( written != (int)cstr.length() ) {
204 f.close(); 232 f.close();
205 QFile::remove( strNewFile ); 233 QFile::remove( strNewFile );
206 return false; 234 return false;
207 } 235 }
208 /* flush before renaming */ 236 /* flush before renaming */
209 f.close(); 237 f.close();
210 238
211 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 239 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
212// qWarning("error renaming"); 240// qWarning("error renaming");
213 QFile::remove( strNewFile ); 241 QFile::remove( strNewFile );
214 } 242 }
215 243
216 m_changed = false; 244 m_changed = false;
217 return true; 245 return true;
218} 246}
219QArray<int> OTodoAccessXML::allRecords()const { 247QArray<int> OTodoAccessXML::allRecords()const {
220 QArray<int> ids( m_events.count() ); 248 QArray<int> ids( m_events.count() );
221 QMap<int, OTodo>::ConstIterator it; 249 QMap<int, OTodo>::ConstIterator it;
222 int i = 0; 250 int i = 0;
223 251
224 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 252 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
225 ids[i] = it.key(); 253 ids[i] = it.key();
226 i++; 254 i++;
227 } 255 }
228 return ids; 256 return ids;
229} 257}
230QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) { 258QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) {
231 QArray<int> ids(0); 259 QArray<int> ids(0);
232 return ids; 260 return ids;
233} 261}
234OTodo OTodoAccessXML::find( int uid )const { 262OTodo OTodoAccessXML::find( int uid )const {
235 OTodo todo; 263 OTodo todo;
236 todo.setUid( 0 ); // isEmpty() 264 todo.setUid( 0 ); // isEmpty()
237 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 265 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
238 if ( it != m_events.end() ) 266 if ( it != m_events.end() )
239 todo = it.data(); 267 todo = it.data();
240 268
241 return todo; 269 return todo;
242} 270}
243void OTodoAccessXML::clear() { 271void OTodoAccessXML::clear() {
244 if (m_opened ) 272 if (m_opened )
245 m_changed = true; 273 m_changed = true;
246 274
247 m_events.clear(); 275 m_events.clear();
248} 276}
249bool OTodoAccessXML::add( const OTodo& todo ) { 277bool OTodoAccessXML::add( const OTodo& todo ) {
250// qWarning("add"); 278// qWarning("add");
251 m_changed = true; 279 m_changed = true;
252 m_events.insert( todo.uid(), todo ); 280 m_events.insert( todo.uid(), todo );
253 281
254 return true; 282 return true;
255} 283}
256bool OTodoAccessXML::remove( int uid ) { 284bool OTodoAccessXML::remove( int uid ) {
257 m_changed = true; 285 m_changed = true;
258 m_events.remove( uid ); 286 m_events.remove( uid );
259 287
260 return true; 288 return true;
261} 289}
262bool OTodoAccessXML::replace( const OTodo& todo) { 290bool OTodoAccessXML::replace( const OTodo& todo) {
263 m_changed = true; 291 m_changed = true;
264 m_events.replace( todo.uid(), todo ); 292 m_events.replace( todo.uid(), todo );
265 293
266 return true; 294 return true;
267} 295}
268QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 296QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
269 const QDate& end, 297 const QDate& end,
270 bool includeNoDates ) { 298 bool includeNoDates ) {
271 QArray<int> ids( m_events.count() ); 299 QArray<int> ids( m_events.count() );
272 QMap<int, OTodo>::Iterator it; 300 QMap<int, OTodo>::Iterator it;
273 301
274 int i = 0; 302 int i = 0;
275 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 303 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
276 if ( !it.data().hasDueDate() ) { 304 if ( !it.data().hasDueDate() ) {
277 if ( includeNoDates ) { 305 if ( includeNoDates ) {
278 ids[i] = it.key(); 306 ids[i] = it.key();
279 i++; 307 i++;
280 } 308 }
281 }else if ( it.data().dueDate() >= start && 309 }else if ( it.data().dueDate() >= start &&
282 it.data().dueDate() <= end ) { 310 it.data().dueDate() <= end ) {
283 ids[i] = it.key(); 311 ids[i] = it.key();
284 i++; 312 i++;
285 } 313 }
286 } 314 }
287 ids.resize( i ); 315 ids.resize( i );
288 return ids; 316 return ids;
289} 317}
290QArray<int> OTodoAccessXML::overDue() { 318QArray<int> OTodoAccessXML::overDue() {
291 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
292 int i = 0; 320 int i = 0;
293 321
294 QMap<int, OTodo>::Iterator it; 322 QMap<int, OTodo>::Iterator it;
295 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 323 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
296 if ( it.data().isOverdue() ) { 324 if ( it.data().isOverdue() ) {
297 ids[i] = it.key(); 325 ids[i] = it.key();
298 i++; 326 i++;
299 } 327 }
300 } 328 }
301 ids.resize( i ); 329 ids.resize( i );
302 return ids; 330 return ids;
303} 331}
304 332
305 333
306/* private */ 334/* private */
307void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 335void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
308 const QCString& attr, const QString& val) { 336 const QCString& attr, const QString& val) {
309// qWarning("parse to do from XMLElement" ); 337// qWarning("parse to do from XMLElement" );
310 338
311 int *find=0; 339 int *find=0;
312 340
313 find = (*dict)[ attr.data() ]; 341 find = (*dict)[ attr.data() ];
314 if (!find ) { 342 if (!find ) {
315// qWarning("Unknown option" + it.key() ); 343// qWarning("Unknown option" + it.key() );
316 ev.setCustomField( attr, val ); 344 ev.setCustomField( attr, val );
317 return; 345 return;
318 } 346 }
319 347
320 switch( *find ) { 348 switch( *find ) {
321 case OTodo::Uid: 349 case OTodo::Uid:
322 ev.setUid( val.toInt() ); 350 ev.setUid( val.toInt() );
323 break; 351 break;
324 case OTodo::Category: 352 case OTodo::Category:
325 ev.setCategories( ev.idsFromString( val ) ); 353 ev.setCategories( ev.idsFromString( val ) );
326 break; 354 break;
327 case OTodo::HasDate: 355 case OTodo::HasDate:
328 ev.setHasDueDate( val.toInt() ); 356 ev.setHasDueDate( val.toInt() );
329 break; 357 break;
330 case OTodo::Completed: 358 case OTodo::Completed:
331 ev.setCompleted( val.toInt() ); 359 ev.setCompleted( val.toInt() );
332 break; 360 break;
333 case OTodo::Description: 361 case OTodo::Description:
334 ev.setDescription( val ); 362 ev.setDescription( val );
335 break; 363 break;
336 case OTodo::Summary: 364 case OTodo::Summary:
337 ev.setSummary( val ); 365 ev.setSummary( val );
338 break; 366 break;
339 case OTodo::Priority: 367 case OTodo::Priority:
340 ev.setPriority( val.toInt() ); 368 ev.setPriority( val.toInt() );
341 break; 369 break;
342 case OTodo::DateDay: 370 case OTodo::DateDay:
343 m_day = val.toInt(); 371 m_day = val.toInt();
344 break; 372 break;
345 case OTodo::DateMonth: 373 case OTodo::DateMonth:
346 m_month = val.toInt(); 374 m_month = val.toInt();
347 break; 375 break;
348 case OTodo::DateYear: 376 case OTodo::DateYear:
349 m_year = val.toInt(); 377 m_year = val.toInt();
350 break; 378 break;
351 case OTodo::Progress: 379 case OTodo::Progress:
352 ev.setProgress( val.toInt() ); 380 ev.setProgress( val.toInt() );
353 break; 381 break;
354 case OTodo::CrossReference: 382 case OTodo::CrossReference:
355 { 383 {
356 /* 384 /*
357 * A cross refernce looks like 385 * A cross refernce looks like
358 * appname,id;appname,id 386 * appname,id;appname,id
359 * we need to split it up 387 * we need to split it up
360 */ 388 */
361 QStringList refs = QStringList::split(';', val ); 389 QStringList refs = QStringList::split(';', val );
362 QStringList::Iterator strIt; 390 QStringList::Iterator strIt;
363 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 391 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
364 int pos = (*strIt).find(','); 392 int pos = (*strIt).find(',');
365 if ( pos > -1 ) 393 if ( pos > -1 )
366 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 394 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
367 395
368 } 396 }
369 break; 397 break;
370 } 398 }
371 default: 399 default:
372 break; 400 break;
373 } 401 }
374} 402}
375QString OTodoAccessXML::toString( const OTodo& ev )const { 403QString OTodoAccessXML::toString( const OTodo& ev )const {
376 QString str; 404 QString str;
377 405
378 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 406 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
379 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 407 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
380 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 408 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
381 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 409 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
382 410
383 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 411 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
384 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 412 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
385 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 413 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
386 414
387 if ( ev.hasDueDate() ) { 415 if ( ev.hasDueDate() ) {
388 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 416 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
389 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 417 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
390 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 418 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
391 } 419 }
392// qWarning( "Uid %d", ev.uid() ); 420// qWarning( "Uid %d", ev.uid() );
393 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 421 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
394 422
395// append the extra options 423// append the extra options
396 /* FIXME Qtopia::Record this is currently not 424 /* FIXME Qtopia::Record this is currently not
397 * possible you can set custom fields 425 * possible you can set custom fields
398 * but don' iterate over the list 426 * but don' iterate over the list
399 * I may do #define private protected 427 * I may do #define private protected
400 * for this case - cough --zecke 428 * for this case - cough --zecke
401 */ 429 */
402 /* 430 /*
403 QMap<QString, QString> extras = ev.extras(); 431 QMap<QString, QString> extras = ev.extras();
404 QMap<QString, QString>::Iterator extIt; 432 QMap<QString, QString>::Iterator extIt;
405 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 433 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
406 str += extIt.key() + "=\"" + extIt.data() + "\" "; 434 str += extIt.key() + "=\"" + extIt.data() + "\" ";
407 */ 435 */
408 // cross refernce 436 // cross refernce
409 437
410 438
411 return str; 439 return str;
412} 440}
413QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 441QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
414 return Qtopia::Record::idsToString( ints ); 442 return Qtopia::Record::idsToString( ints );
415} 443}
416 444
417/* internal class for sorting 445/* internal class for sorting
418 * 446 *
419 * Inspired by todoxmlio.cpp from TT 447 * Inspired by todoxmlio.cpp from TT
420 */ 448 */
421 449
422struct OTodoXMLContainer { 450struct OTodoXMLContainer {
423 OTodo todo; 451 OTodo todo;
424}; 452};
425 453
426namespace { 454namespace {
427 inline QString string( const OTodo& todo) { 455 inline QString string( const OTodo& todo) {
428 return todo.summary().isEmpty() ? 456 return todo.summary().isEmpty() ?
429 todo.description().left(20 ) : 457 todo.description().left(20 ) :
430 todo.summary(); 458 todo.summary();
431 } 459 }
432 inline int completed( const OTodo& todo1, const OTodo& todo2) { 460 inline int completed( const OTodo& todo1, const OTodo& todo2) {
433 int ret = 0; 461 int ret = 0;
434 if ( todo1.isCompleted() ) ret++; 462 if ( todo1.isCompleted() ) ret++;
435 if ( todo2.isCompleted() ) ret--; 463 if ( todo2.isCompleted() ) ret--;
436 return ret; 464 return ret;
437 } 465 }
438 inline int priority( const OTodo& t1, const OTodo& t2) { 466 inline int priority( const OTodo& t1, const OTodo& t2) {
439 return ( t1.priority() - t2.priority() ); 467 return ( t1.priority() - t2.priority() );
440 } 468 }
441 inline int description( const OTodo& t1, const OTodo& t2) { 469 inline int description( const OTodo& t1, const OTodo& t2) {
442 return QString::compare( string(t1), string(t2) ); 470 return QString::compare( string(t1), string(t2) );
443 } 471 }
444 inline int deadline( const OTodo& t1, const OTodo& t2) { 472 inline int deadline( const OTodo& t1, const OTodo& t2) {
445 int ret = 0; 473 int ret = 0;
446 if ( t1.hasDueDate() && 474 if ( t1.hasDueDate() &&
447 t2.hasDueDate() ) 475 t2.hasDueDate() )
448 ret = t2.dueDate().daysTo( t1.dueDate() ); 476 ret = t2.dueDate().daysTo( t1.dueDate() );
449 else if ( t1.hasDueDate() ) 477 else if ( t1.hasDueDate() )
450 ret = -1; 478 ret = -1;
451 else if ( t2.hasDueDate() ) 479 else if ( t2.hasDueDate() )
452 ret = 1; 480 ret = 1;
453 else 481 else
454 ret = 0; 482 ret = 0;
455 483
456 return ret; 484 return ret;
457 } 485 }
458 486
459}; 487};
460 488
461/* 489/*
462 * Returns: 490 * Returns:
463 * 0 if item1 == item2 491 * 0 if item1 == item2
464 * 492 *
465 * non-zero if item1 != item2 493 * non-zero if item1 != item2
466 * 494 *
467 * This function returns int rather than bool so that reimplementations 495 * This function returns int rather than bool so that reimplementations
468 * can return one of three values and use it to sort by: 496 * can return one of three values and use it to sort by:
469 * 497 *
470 * 0 if item1 == item2 498 * 0 if item1 == item2
471 * 499 *
472 * > 0 (positive integer) if item1 > item2 500 * > 0 (positive integer) if item1 > item2
473 * 501 *
474 * < 0 (negative integer) if item1 < item2 502 * < 0 (negative integer) if item1 < item2
475 * 503 *
476 */ 504 */
477class OTodoXMLVector : public QVector<OTodoXMLContainer> { 505class OTodoXMLVector : public QVector<OTodoXMLContainer> {
478public: 506public:
479 OTodoXMLVector(int size, bool asc, int sort) 507 OTodoXMLVector(int size, bool asc, int sort)
480 : QVector<OTodoXMLContainer>( size ) 508 : QVector<OTodoXMLContainer>( size )
481 { 509 {
482 setAutoDelete( true ); 510 setAutoDelete( true );
483 m_asc = asc; 511 m_asc = asc;
484 m_sort = sort; 512 m_sort = sort;
485 } 513 }
486 /* return the summary/description */ 514 /* return the summary/description */
487 QString string( const OTodo& todo) { 515 QString string( const OTodo& todo) {
488 return todo.summary().isEmpty() ? 516 return todo.summary().isEmpty() ?
489 todo.description().left(20 ) : 517 todo.description().left(20 ) :
490 todo.summary(); 518 todo.summary();
491 } 519 }
492 /** 520 /**
493 * we take the sortorder( switch on it ) 521 * we take the sortorder( switch on it )
494 * 522 *
495 */ 523 */
496 int compareItems( Item d1, Item d2 ) { 524 int compareItems( Item d1, Item d2 ) {
497 bool seComp, sePrio, seDesc, seDeadline; 525 bool seComp, sePrio, seDesc, seDeadline;
498 seComp = sePrio = seDeadline = seDesc = false; 526 seComp = sePrio = seDeadline = seDesc = false;
499 int ret =0; 527 int ret =0;
500 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 528 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
501 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 529 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
502 530
503 /* same item */ 531 /* same item */
504 if ( con1->todo.uid() == con2->todo.uid() ) 532 if ( con1->todo.uid() == con2->todo.uid() )
505 return 0; 533 return 0;
506 534
507 switch ( m_sort ) { 535 switch ( m_sort ) {
508 /* completed */ 536 /* completed */
509 case 0: { 537 case 0: {
510 ret = completed( con1->todo, con2->todo ); 538 ret = completed( con1->todo, con2->todo );
511 seComp = TRUE; 539 seComp = TRUE;
512 break; 540 break;
513 } 541 }
514 /* priority */ 542 /* priority */
515 case 1: { 543 case 1: {
516 ret = priority( con1->todo, con2->todo ); 544 ret = priority( con1->todo, con2->todo );
517 sePrio = TRUE; 545 sePrio = TRUE;
518 break; 546 break;
519 } 547 }
520 /* description */ 548 /* description */
521 case 2: { 549 case 2: {
522 ret = description( con1->todo, con2->todo ); 550 ret = description( con1->todo, con2->todo );
523 seDesc = TRUE; 551 seDesc = TRUE;
524 break; 552 break;
525 } 553 }
526 /* deadline */ 554 /* deadline */
527 case 3: { 555 case 3: {
528 ret = deadline( con1->todo, con2->todo ); 556 ret = deadline( con1->todo, con2->todo );
529 seDeadline = TRUE; 557 seDeadline = TRUE;
530 break; 558 break;
531 } 559 }
532 default: 560 default:
533 ret = 0; 561 ret = 0;
534 break; 562 break;
535 }; 563 };
536 /* 564 /*
537 * FIXME do better sorting if the first sort criteria 565 * FIXME do better sorting if the first sort criteria
538 * ret equals 0 start with complete and so on... 566 * ret equals 0 start with complete and so on...
539 */ 567 */
540 568
541 /* twist it we're not ascending*/ 569 /* twist it we're not ascending*/
542 if (!m_asc) 570 if (!m_asc)
543 ret = ret * -1; 571 ret = ret * -1;
544 572
545 if ( ret ) 573 if ( ret )
546 return ret; 574 return ret;
547 575
548 // default did not gave difference let's try it other way around 576 // default did not gave difference let's try it other way around
549 /* 577 /*
550 * General try if already checked if not test 578 * General try if already checked if not test
551 * and return 579 * and return
552 * 1.Completed 580 * 1.Completed
553 * 2.Priority 581 * 2.Priority
554 * 3.Description 582 * 3.Description
555 * 4.DueDate 583 * 4.DueDate
556 */ 584 */
557 if (!seComp ) { 585 if (!seComp ) {
558 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 586 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
559 if (!m_asc ) ret *= -1; 587 if (!m_asc ) ret *= -1;
560 return ret; 588 return ret;
561 } 589 }
562 } 590 }
563 if (!sePrio ) { 591 if (!sePrio ) {
564 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 592 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
565 if (!m_asc ) ret *= -1; 593 if (!m_asc ) ret *= -1;
566 return ret; 594 return ret;
567 } 595 }
568 } 596 }
569 if (!seDesc ) { 597 if (!seDesc ) {
570 if ( (ret = description(con1->todo, con2->todo ) ) ) { 598 if ( (ret = description(con1->todo, con2->todo ) ) ) {
571 if (!m_asc) ret *= -1; 599 if (!m_asc) ret *= -1;
572 return ret; 600 return ret;
573 } 601 }
574 } 602 }
575 if (!seDeadline) { 603 if (!seDeadline) {
576 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 604 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
577 if (!m_asc) ret *= -1; 605 if (!m_asc) ret *= -1;
578 return ret; 606 return ret;
579 } 607 }
580 } 608 }
581 609
582 return 0; 610 return 0;
583 } 611 }
584 private: 612 private:
585 bool m_asc; 613 bool m_asc;
586 int m_sort; 614 int m_sort;
587 615
588}; 616};
589 617
590QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 618QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
591 int sortFilter, int cat ) { 619 int sortFilter, int cat ) {
592 qWarning("sorted! %d cat", cat); 620 qWarning("sorted! %d cat", cat);
593 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 621 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
594 QMap<int, OTodo>::Iterator it; 622 QMap<int, OTodo>::Iterator it;
595 int item = 0; 623 int item = 0;
596 624
597 bool bCat = sortFilter & 1 ? true : false; 625 bool bCat = sortFilter & 1 ? true : false;
598 bool bOnly = sortFilter & 2 ? true : false; 626 bool bOnly = sortFilter & 2 ? true : false;
599 bool comp = sortFilter & 4 ? true : false; 627 bool comp = sortFilter & 4 ? true : false;
600 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 628 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
601 629
602 /* show category */ 630 /* show category */
603 if ( bCat && cat != 0) 631 if ( bCat && cat != 0)
604 if (!(*it).categories().contains( cat ) ) { 632 if (!(*it).categories().contains( cat ) ) {
605 qWarning("category mis match"); 633 qWarning("category mis match");
606 continue; 634 continue;
607 } 635 }
608 /* isOverdue but we should not show overdue - why?*/ 636 /* isOverdue but we should not show overdue - why?*/
609/* if ( (*it).isOverdue() && !bOnly ) { 637/* if ( (*it).isOverdue() && !bOnly ) {
610 qWarning("item is overdue but !bOnly"); 638 qWarning("item is overdue but !bOnly");
611 continue; 639 continue;
612 } 640 }
613*/ 641*/
614 if ( !(*it).isOverdue() && bOnly ) { 642 if ( !(*it).isOverdue() && bOnly ) {
615 qWarning("item is not overdue but bOnly checked"); 643 qWarning("item is not overdue but bOnly checked");
616 continue; 644 continue;
617 } 645 }
618 646
619 if ((*it).isCompleted() && comp ) { 647 if ((*it).isCompleted() && comp ) {
620 qWarning("completed continue!"); 648 qWarning("completed continue!");
621 continue; 649 continue;
622 } 650 }
623 651
624 652
625 OTodoXMLContainer* con = new OTodoXMLContainer(); 653 OTodoXMLContainer* con = new OTodoXMLContainer();
626 con->todo = (*it); 654 con->todo = (*it);
627 vector.insert(item, con ); 655 vector.insert(item, con );
628 item++; 656 item++;
629 } 657 }
630 qWarning("XXX %d Items added", item); 658 qWarning("XXX %d Items added", item);
631 vector.resize( item ); 659 vector.resize( item );
632 /* sort it now */ 660 /* sort it now */
633 vector.sort(); 661 vector.sort();
634 /* now get the uids */ 662 /* now get the uids */
635 QArray<int> array( vector.count() ); 663 QArray<int> array( vector.count() );
636 for (uint i= 0; i < vector.count(); i++ ) { 664 for (uint i= 0; i < vector.count(); i++ ) {
637 array[i] = ( vector.at(i) )->todo.uid(); 665 array[i] = ( vector.at(i) )->todo.uid();
638 } 666 }
639 qWarning("array count = %d %d", array.count(), vector.count() ); 667 qWarning("array count = %d %d", array.count(), vector.count() );
640 return array; 668 return array;
641}; 669};
642void OTodoAccessXML::removeAllCompleted() { 670void OTodoAccessXML::removeAllCompleted() {
643 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 671 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
644 if ( (*it).isCompleted() ) 672 if ( (*it).isCompleted() )
645 m_events.remove( it ); 673 m_events.remove( it );
646 } 674 }
647} 675}