summaryrefslogtreecommitdiff
path: root/libopie/pim
authorzecke <zecke>2003-05-07 18:02:46 (UTC)
committer zecke <zecke>2003-05-07 18:02:46 (UTC)
commit94371938792c70a40cdb75e37c69020438d450c9 (patch) (unidiff)
tree10b97f156e1b4eee2ec1706e315a87a16b0af3b9 /libopie/pim
parentc13ada0f5e418b25b177e132ff2e1dfe7821577f (diff)
downloadopie-94371938792c70a40cdb75e37c69020438d450c9.zip
opie-94371938792c70a40cdb75e37c69020438d450c9.tar.gz
opie-94371938792c70a40cdb75e37c69020438d450c9.tar.bz2
save and restore CompletedDate and StartDate
Diffstat (limited to 'libopie/pim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodoaccessxml.cpp27
1 files changed, 20 insertions, 7 deletions
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 71b6a7e..a8e1503 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,209 +1,211 @@
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 "oconversion.h"
18#include "otimezone.h" 19#include "otimezone.h"
19#include "orecur.h" 20#include "orecur.h"
20#include "otodoaccessxml.h" 21#include "otodoaccessxml.h"
21 22
22namespace { 23namespace {
23 time_t rp_end; 24 time_t rp_end;
24 ORecur* rec; 25 ORecur* rec;
25 ORecur *recur() { 26 ORecur *recur() {
26 if (!rec ) rec = new ORecur; 27 if (!rec ) rec = new ORecur;
27 return rec; 28 return rec;
28 } 29 }
29 int snd; 30 int snd;
30 enum MoreAttributes { 31 enum MoreAttributes {
31 FRType = OTodo::CompletedDate + 2, 32 FRType = OTodo::CompletedDate + 2,
32 FRWeekdays, 33 FRWeekdays,
33 FRPosition, 34 FRPosition,
34 FRFreq, 35 FRFreq,
35 FRHasEndDate, 36 FRHasEndDate,
36 FREndDate, 37 FREndDate,
37 FRStart, 38 FRStart,
38 FREnd 39 FREnd
39 }; 40 };
40 // FROM TT again 41 // FROM TT again
41char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 42char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
42{ 43{
43 char needleChar; 44 char needleChar;
44 char haystackChar; 45 char haystackChar;
45 if (!needle || !haystack || !hLen || !nLen) 46 if (!needle || !haystack || !hLen || !nLen)
46 return 0; 47 return 0;
47 48
48 const char* hsearch = haystack; 49 const char* hsearch = haystack;
49 50
50 if ((needleChar = *needle++) != 0) { 51 if ((needleChar = *needle++) != 0) {
51 nLen--; //(to make up for needle++) 52 nLen--; //(to make up for needle++)
52 do { 53 do {
53 do { 54 do {
54 if ((haystackChar = *hsearch++) == 0) 55 if ((haystackChar = *hsearch++) == 0)
55 return (0); 56 return (0);
56 if (hsearch >= haystack + hLen) 57 if (hsearch >= haystack + hLen)
57 return (0); 58 return (0);
58 } while (haystackChar != needleChar); 59 } while (haystackChar != needleChar);
59 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 60 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
60 hsearch--; 61 hsearch--;
61 } 62 }
62 return ((char *)hsearch); 63 return ((char *)hsearch);
63} 64}
64} 65}
65 66
66 67
67OTodoAccessXML::OTodoAccessXML( const QString& appName, 68OTodoAccessXML::OTodoAccessXML( const QString& appName,
68 const QString& fileName ) 69 const QString& fileName )
69 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 70 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
70{ 71{
71 if (!fileName.isEmpty() ) 72 if (!fileName.isEmpty() )
72 m_file = fileName; 73 m_file = fileName;
73 else 74 else
74 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 75 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
75} 76}
76OTodoAccessXML::~OTodoAccessXML() { 77OTodoAccessXML::~OTodoAccessXML() {
77 78
78} 79}
79bool OTodoAccessXML::load() { 80bool OTodoAccessXML::load() {
80 rec = 0; 81 rec = 0;
81 m_opened = true; 82 m_opened = true;
82 m_changed = false; 83 m_changed = false;
83 /* initialize dict */ 84 /* initialize dict */
84 /* 85 /*
85 * UPDATE dict if you change anything!!! 86 * UPDATE dict if you change anything!!!
86 */ 87 */
87 QAsciiDict<int> dict(21); 88 QAsciiDict<int> dict(21);
88 dict.setAutoDelete( TRUE ); 89 dict.setAutoDelete( TRUE );
89 dict.insert("Categories" , new int(OTodo::Category) ); 90 dict.insert("Categories" , new int(OTodo::Category) );
90 dict.insert("Uid" , new int(OTodo::Uid) ); 91 dict.insert("Uid" , new int(OTodo::Uid) );
91 dict.insert("HasDate" , new int(OTodo::HasDate) ); 92 dict.insert("HasDate" , new int(OTodo::HasDate) );
92 dict.insert("Completed" , new int(OTodo::Completed) ); 93 dict.insert("Completed" , new int(OTodo::Completed) );
93 dict.insert("Description" , new int(OTodo::Description) ); 94 dict.insert("Description" , new int(OTodo::Description) );
94 dict.insert("Summary" , new int(OTodo::Summary) ); 95 dict.insert("Summary" , new int(OTodo::Summary) );
95 dict.insert("Priority" , new int(OTodo::Priority) ); 96 dict.insert("Priority" , new int(OTodo::Priority) );
96 dict.insert("DateDay" , new int(OTodo::DateDay) ); 97 dict.insert("DateDay" , new int(OTodo::DateDay) );
97 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 98 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
98 dict.insert("DateYear" , new int(OTodo::DateYear) ); 99 dict.insert("DateYear" , new int(OTodo::DateYear) );
99 dict.insert("Progress" , new int(OTodo::Progress) ); 100 dict.insert("Progress" , new int(OTodo::Progress) );
100 dict.insert("CompletedDate", new int(OTodo::CompletedDate) ); 101 dict.insert("CompletedDate", new int(OTodo::CompletedDate) );
102 dict.insert("StartDate", new int(OTodo::StartDate) );
101 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 103 dict.insert("CrossReference", new int(OTodo::CrossReference) );
102 dict.insert("State", new int(OTodo::State) ); 104 dict.insert("State", new int(OTodo::State) );
103 dict.insert("Alarms", new int(OTodo::Alarms) ); 105 dict.insert("Alarms", new int(OTodo::Alarms) );
104 dict.insert("Reminders", new int(OTodo::Reminders) ); 106 dict.insert("Reminders", new int(OTodo::Reminders) );
105 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 107 dict.insert("Notifiers", new int(OTodo::Notifiers) );
106 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 108 dict.insert("Maintainer", new int(OTodo::Maintainer) );
107 dict.insert("rtype", new int(FRType) ); 109 dict.insert("rtype", new int(FRType) );
108 dict.insert("rweekdays", new int(FRWeekdays) ); 110 dict.insert("rweekdays", new int(FRWeekdays) );
109 dict.insert("rposition", new int(FRPosition) ); 111 dict.insert("rposition", new int(FRPosition) );
110 dict.insert("rfreq", new int(FRFreq) ); 112 dict.insert("rfreq", new int(FRFreq) );
111 dict.insert("start", new int(FRStart) ); 113 dict.insert("start", new int(FRStart) );
112 dict.insert("rhasenddate", new int(FRHasEndDate) ); 114 dict.insert("rhasenddate", new int(FRHasEndDate) );
113 dict.insert("enddt", new int(FREndDate) ); 115 dict.insert("enddt", new int(FREndDate) );
114 116
115 // here the custom XML parser from TT it's GPL 117 // here the custom XML parser from TT it's GPL
116 // but we want to push OpiePIM... to TT..... 118 // but we want to push OpiePIM... to TT.....
117 // mmap part from zecke :) 119 // mmap part from zecke :)
118 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 120 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
119 struct stat attribut; 121 struct stat attribut;
120 if ( fd < 0 ) return false; 122 if ( fd < 0 ) return false;
121 123
122 if ( fstat(fd, &attribut ) == -1 ) { 124 if ( fstat(fd, &attribut ) == -1 ) {
123 ::close( fd ); 125 ::close( fd );
124 return false; 126 return false;
125 } 127 }
126 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 128 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
127 if ( map_addr == ( (caddr_t)-1) ) { 129 if ( map_addr == ( (caddr_t)-1) ) {
128 ::close(fd ); 130 ::close(fd );
129 return false; 131 return false;
130 } 132 }
131 /* advise the kernel who we want to read it */ 133 /* advise the kernel who we want to read it */
132 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 134 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
133 /* we do not the file any more */ 135 /* we do not the file any more */
134 ::close( fd ); 136 ::close( fd );
135 137
136 char* dt = (char*)map_addr; 138 char* dt = (char*)map_addr;
137 int len = attribut.st_size; 139 int len = attribut.st_size;
138 int i = 0; 140 int i = 0;
139 char *point; 141 char *point;
140 const char* collectionString = "<Task "; 142 const char* collectionString = "<Task ";
141 int strLen = strlen(collectionString); 143 int strLen = strlen(collectionString);
142 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 144 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
143 i = point -dt; 145 i = point -dt;
144 i+= strLen; 146 i+= strLen;
145 qWarning("Found a start at %d %d", i, (point-dt) ); 147 qWarning("Found a start at %d %d", i, (point-dt) );
146 148
147 OTodo ev; 149 OTodo ev;
148 m_year = m_month = m_day = 0; 150 m_year = m_month = m_day = 0;
149 151
150 while ( TRUE ) { 152 while ( TRUE ) {
151 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 153 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
152 ++i; 154 ++i;
153 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 155 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
154 break; 156 break;
155 157
156 // we have another attribute, read it. 158 // we have another attribute, read it.
157 int j = i; 159 int j = i;
158 while ( j < len && dt[j] != '=' ) 160 while ( j < len && dt[j] != '=' )
159 ++j; 161 ++j;
160 QCString attr( dt+i, j-i+1); 162 QCString attr( dt+i, j-i+1);
161 163
162 i = ++j; // skip = 164 i = ++j; // skip =
163 165
164 // find the start of quotes 166 // find the start of quotes
165 while ( i < len && dt[i] != '"' ) 167 while ( i < len && dt[i] != '"' )
166 ++i; 168 ++i;
167 j = ++i; 169 j = ++i;
168 170
169 bool haveUtf = FALSE; 171 bool haveUtf = FALSE;
170 bool haveEnt = FALSE; 172 bool haveEnt = FALSE;
171 while ( j < len && dt[j] != '"' ) { 173 while ( j < len && dt[j] != '"' ) {
172 if ( ((unsigned char)dt[j]) > 0x7f ) 174 if ( ((unsigned char)dt[j]) > 0x7f )
173 haveUtf = TRUE; 175 haveUtf = TRUE;
174 if ( dt[j] == '&' ) 176 if ( dt[j] == '&' )
175 haveEnt = TRUE; 177 haveEnt = TRUE;
176 ++j; 178 ++j;
177 } 179 }
178 if ( i == j ) { 180 if ( i == j ) {
179 // empty value 181 // empty value
180 i = j + 1; 182 i = j + 1;
181 continue; 183 continue;
182 } 184 }
183 185
184 QCString value( dt+i, j-i+1 ); 186 QCString value( dt+i, j-i+1 );
185 i = j + 1; 187 i = j + 1;
186 188
187 QString str = (haveUtf ? QString::fromUtf8( value ) 189 QString str = (haveUtf ? QString::fromUtf8( value )
188 : QString::fromLatin1( value ) ); 190 : QString::fromLatin1( value ) );
189 if ( haveEnt ) 191 if ( haveEnt )
190 str = Qtopia::plainString( str ); 192 str = Qtopia::plainString( str );
191 193
192 /* 194 /*
193 * add key + value 195 * add key + value
194 */ 196 */
195 todo( &dict, ev, attr, str ); 197 todo( &dict, ev, attr, str );
196 198
197 } 199 }
198 /* 200 /*
199 * now add it 201 * now add it
200 */ 202 */
201 qWarning("End at %d", i ); 203 qWarning("End at %d", i );
202 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 204 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
203 ev.setUid( 1 ); 205 ev.setUid( 1 );
204 m_changed = true; 206 m_changed = true;
205 } 207 }
206 if ( ev.hasDueDate() ) { 208 if ( ev.hasDueDate() ) {
207 ev.setDueDate( QDate(m_year, m_month, m_day) ); 209 ev.setDueDate( QDate(m_year, m_month, m_day) );
208 } 210 }
209 if ( rec && rec->doesRecur() ) { 211 if ( rec && rec->doesRecur() ) {
@@ -321,281 +323,292 @@ bool OTodoAccessXML::remove( int uid ) {
321 m_events.remove( uid ); 323 m_events.remove( uid );
322 324
323 return true; 325 return true;
324} 326}
325bool OTodoAccessXML::replace( const OTodo& todo) { 327bool OTodoAccessXML::replace( const OTodo& todo) {
326 m_changed = true; 328 m_changed = true;
327 m_events.replace( todo.uid(), todo ); 329 m_events.replace( todo.uid(), todo );
328 330
329 return true; 331 return true;
330} 332}
331QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 333QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
332 const QDate& end, 334 const QDate& end,
333 bool includeNoDates ) { 335 bool includeNoDates ) {
334 QArray<int> ids( m_events.count() ); 336 QArray<int> ids( m_events.count() );
335 QMap<int, OTodo>::Iterator it; 337 QMap<int, OTodo>::Iterator it;
336 338
337 int i = 0; 339 int i = 0;
338 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 340 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
339 if ( !it.data().hasDueDate() ) { 341 if ( !it.data().hasDueDate() ) {
340 if ( includeNoDates ) { 342 if ( includeNoDates ) {
341 ids[i] = it.key(); 343 ids[i] = it.key();
342 i++; 344 i++;
343 } 345 }
344 }else if ( it.data().dueDate() >= start && 346 }else if ( it.data().dueDate() >= start &&
345 it.data().dueDate() <= end ) { 347 it.data().dueDate() <= end ) {
346 ids[i] = it.key(); 348 ids[i] = it.key();
347 i++; 349 i++;
348 } 350 }
349 } 351 }
350 ids.resize( i ); 352 ids.resize( i );
351 return ids; 353 return ids;
352} 354}
353QArray<int> OTodoAccessXML::overDue() { 355QArray<int> OTodoAccessXML::overDue() {
354 QArray<int> ids( m_events.count() ); 356 QArray<int> ids( m_events.count() );
355 int i = 0; 357 int i = 0;
356 358
357 QMap<int, OTodo>::Iterator it; 359 QMap<int, OTodo>::Iterator it;
358 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 360 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
359 if ( it.data().isOverdue() ) { 361 if ( it.data().isOverdue() ) {
360 ids[i] = it.key(); 362 ids[i] = it.key();
361 i++; 363 i++;
362 } 364 }
363 } 365 }
364 ids.resize( i ); 366 ids.resize( i );
365 return ids; 367 return ids;
366} 368}
367 369
368 370
369/* private */ 371/* private */
370void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 372void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
371 const QCString& attr, const QString& val) { 373 const QCString& attr, const QString& val) {
372// qWarning("parse to do from XMLElement" ); 374// qWarning("parse to do from XMLElement" );
373 375
374 int *find=0; 376 int *find=0;
375 377
376 find = (*dict)[ attr.data() ]; 378 find = (*dict)[ attr.data() ];
377 if (!find ) { 379 if (!find ) {
378// qWarning("Unknown option" + it.key() ); 380// qWarning("Unknown option" + it.key() );
379 ev.setCustomField( attr, val ); 381 ev.setCustomField( attr, val );
380 return; 382 return;
381 } 383 }
382 384
383 switch( *find ) { 385 switch( *find ) {
384 case OTodo::Uid: 386 case OTodo::Uid:
385 ev.setUid( val.toInt() ); 387 ev.setUid( val.toInt() );
386 break; 388 break;
387 case OTodo::Category: 389 case OTodo::Category:
388 ev.setCategories( ev.idsFromString( val ) ); 390 ev.setCategories( ev.idsFromString( val ) );
389 break; 391 break;
390 case OTodo::HasDate: 392 case OTodo::HasDate:
391 ev.setHasDueDate( val.toInt() ); 393 ev.setHasDueDate( val.toInt() );
392 break; 394 break;
393 case OTodo::Completed: 395 case OTodo::Completed:
394 ev.setCompleted( val.toInt() ); 396 ev.setCompleted( val.toInt() );
395 break; 397 break;
396 case OTodo::Description: 398 case OTodo::Description:
397 ev.setDescription( val ); 399 ev.setDescription( val );
398 break; 400 break;
399 case OTodo::Summary: 401 case OTodo::Summary:
400 ev.setSummary( val ); 402 ev.setSummary( val );
401 break; 403 break;
402 case OTodo::Priority: 404 case OTodo::Priority:
403 ev.setPriority( val.toInt() ); 405 ev.setPriority( val.toInt() );
404 break; 406 break;
405 case OTodo::DateDay: 407 case OTodo::DateDay:
406 m_day = val.toInt(); 408 m_day = val.toInt();
407 break; 409 break;
408 case OTodo::DateMonth: 410 case OTodo::DateMonth:
409 m_month = val.toInt(); 411 m_month = val.toInt();
410 break; 412 break;
411 case OTodo::DateYear: 413 case OTodo::DateYear:
412 m_year = val.toInt(); 414 m_year = val.toInt();
413 break; 415 break;
414 case OTodo::Progress: 416 case OTodo::Progress:
415 ev.setProgress( val.toInt() ); 417 ev.setProgress( val.toInt() );
416 break; 418 break;
419 case OTodo::CompletedDate:
420 ev.setCompletedDate( OConversion::dateFromString( val ) );
421 break;
422 case OTodo::StartDate:
423 ev.setStartDate( OConversion::dateFromString( val ) );
424 break;
417 case OTodo::CrossReference: 425 case OTodo::CrossReference:
418 { 426 {
419 /* 427 /*
420 * A cross refernce looks like 428 * A cross refernce looks like
421 * appname,id;appname,id 429 * appname,id;appname,id
422 * we need to split it up 430 * we need to split it up
423 */ 431 */
424 QStringList refs = QStringList::split(';', val ); 432 QStringList refs = QStringList::split(';', val );
425 QStringList::Iterator strIt; 433 QStringList::Iterator strIt;
426 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 434 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
427 int pos = (*strIt).find(','); 435 int pos = (*strIt).find(',');
428 if ( pos > -1 ) 436 if ( pos > -1 )
429 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 437 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
430 438
431 } 439 }
432 break; 440 break;
433 } 441 }
434 /* Recurrence stuff below + post processing later */ 442 /* Recurrence stuff below + post processing later */
435 case FRType: 443 case FRType:
436 if ( val == "Daily" ) 444 if ( val == "Daily" )
437 recur()->setType( ORecur::Daily ); 445 recur()->setType( ORecur::Daily );
438 else if ( val == "Weekly" ) 446 else if ( val == "Weekly" )
439 recur()->setType( ORecur::Weekly); 447 recur()->setType( ORecur::Weekly);
440 else if ( val == "MonthlyDay" ) 448 else if ( val == "MonthlyDay" )
441 recur()->setType( ORecur::MonthlyDay ); 449 recur()->setType( ORecur::MonthlyDay );
442 else if ( val == "MonthlyDate" ) 450 else if ( val == "MonthlyDate" )
443 recur()->setType( ORecur::MonthlyDate ); 451 recur()->setType( ORecur::MonthlyDate );
444 else if ( val == "Yearly" ) 452 else if ( val == "Yearly" )
445 recur()->setType( ORecur::Yearly ); 453 recur()->setType( ORecur::Yearly );
446 else 454 else
447 recur()->setType( ORecur::NoRepeat ); 455 recur()->setType( ORecur::NoRepeat );
448 break; 456 break;
449 case FRWeekdays: 457 case FRWeekdays:
450 recur()->setDays( val.toInt() ); 458 recur()->setDays( val.toInt() );
451 break; 459 break;
452 case FRPosition: 460 case FRPosition:
453 recur()->setPosition( val.toInt() ); 461 recur()->setPosition( val.toInt() );
454 break; 462 break;
455 case FRFreq: 463 case FRFreq:
456 recur()->setFrequency( val.toInt() ); 464 recur()->setFrequency( val.toInt() );
457 break; 465 break;
458 case FRHasEndDate: 466 case FRHasEndDate:
459 recur()->setHasEndDate( val.toInt() ); 467 recur()->setHasEndDate( val.toInt() );
460 break; 468 break;
461 case FREndDate: { 469 case FREndDate: {
462 rp_end = (time_t) val.toLong(); 470 rp_end = (time_t) val.toLong();
463 break; 471 break;
464 } 472 }
465 default: 473 default:
466 break; 474 break;
467 } 475 }
468} 476}
469QString OTodoAccessXML::toString( const OTodo& ev )const { 477QString OTodoAccessXML::toString( const OTodo& ev )const {
470 QString str; 478 QString str;
471 479
472 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 480 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
473 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 481 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
474 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 482 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
475 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 483 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
476 484
477 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 485 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
478 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 486 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
479 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 487 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
480 488
481 if ( ev.hasDueDate() ) { 489 if ( ev.hasDueDate() ) {
482 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 490 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
483 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 491 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
484 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 492 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
485 } 493 }
486// qWarning( "Uid %d", ev.uid() ); 494// qWarning( "Uid %d", ev.uid() );
487 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 495 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
488 496
489// append the extra options 497// append the extra options
490 /* FIXME Qtopia::Record this is currently not 498 /* FIXME Qtopia::Record this is currently not
491 * possible you can set custom fields 499 * possible you can set custom fields
492 * but don' iterate over the list 500 * but don' iterate over the list
493 * I may do #define private protected 501 * I may do #define private protected
494 * for this case - cough --zecke 502 * for this case - cough --zecke
495 */ 503 */
496 /* 504 /*
497 QMap<QString, QString> extras = ev.extras(); 505 QMap<QString, QString> extras = ev.extras();
498 QMap<QString, QString>::Iterator extIt; 506 QMap<QString, QString>::Iterator extIt;
499 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 507 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
500 str += extIt.key() + "=\"" + extIt.data() + "\" "; 508 str += extIt.key() + "=\"" + extIt.data() + "\" ";
501 */ 509 */
502 // cross refernce 510 // cross refernce
503 if ( ev.hasRecurrence() ) { 511 if ( ev.hasRecurrence() ) {
504 str += ev.recurrence().toString(); 512 str += ev.recurrence().toString();
505 } 513 }
514 if ( ev.hasStartDate() )
515 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" ";
516 if ( ev.hasCompletedDate() )
517 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" ";
518
506 519
507 return str; 520 return str;
508} 521}
509QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 522QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
510 return Qtopia::Record::idsToString( ints ); 523 return Qtopia::Record::idsToString( ints );
511} 524}
512 525
513/* internal class for sorting 526/* internal class for sorting
514 * 527 *
515 * Inspired by todoxmlio.cpp from TT 528 * Inspired by todoxmlio.cpp from TT
516 */ 529 */
517 530
518struct OTodoXMLContainer { 531struct OTodoXMLContainer {
519 OTodo todo; 532 OTodo todo;
520}; 533};
521 534
522namespace { 535namespace {
523 inline QString string( const OTodo& todo) { 536 inline QString string( const OTodo& todo) {
524 return todo.summary().isEmpty() ? 537 return todo.summary().isEmpty() ?
525 todo.description().left(20 ) : 538 todo.description().left(20 ) :
526 todo.summary(); 539 todo.summary();
527 } 540 }
528 inline int completed( const OTodo& todo1, const OTodo& todo2) { 541 inline int completed( const OTodo& todo1, const OTodo& todo2) {
529 int ret = 0; 542 int ret = 0;
530 if ( todo1.isCompleted() ) ret++; 543 if ( todo1.isCompleted() ) ret++;
531 if ( todo2.isCompleted() ) ret--; 544 if ( todo2.isCompleted() ) ret--;
532 return ret; 545 return ret;
533 } 546 }
534 inline int priority( const OTodo& t1, const OTodo& t2) { 547 inline int priority( const OTodo& t1, const OTodo& t2) {
535 return ( t1.priority() - t2.priority() ); 548 return ( t1.priority() - t2.priority() );
536 } 549 }
537 inline int description( const OTodo& t1, const OTodo& t2) { 550 inline int description( const OTodo& t1, const OTodo& t2) {
538 return QString::compare( string(t1), string(t2) ); 551 return QString::compare( string(t1), string(t2) );
539 } 552 }
540 inline int deadline( const OTodo& t1, const OTodo& t2) { 553 inline int deadline( const OTodo& t1, const OTodo& t2) {
541 int ret = 0; 554 int ret = 0;
542 if ( t1.hasDueDate() && 555 if ( t1.hasDueDate() &&
543 t2.hasDueDate() ) 556 t2.hasDueDate() )
544 ret = t2.dueDate().daysTo( t1.dueDate() ); 557 ret = t2.dueDate().daysTo( t1.dueDate() );
545 else if ( t1.hasDueDate() ) 558 else if ( t1.hasDueDate() )
546 ret = -1; 559 ret = -1;
547 else if ( t2.hasDueDate() ) 560 else if ( t2.hasDueDate() )
548 ret = 1; 561 ret = 1;
549 else 562 else
550 ret = 0; 563 ret = 0;
551 564
552 return ret; 565 return ret;
553 } 566 }
554 567
555}; 568};
556 569
557/* 570/*
558 * Returns: 571 * Returns:
559 * 0 if item1 == item2 572 * 0 if item1 == item2
560 * 573 *
561 * non-zero if item1 != item2 574 * non-zero if item1 != item2
562 * 575 *
563 * This function returns int rather than bool so that reimplementations 576 * This function returns int rather than bool so that reimplementations
564 * can return one of three values and use it to sort by: 577 * can return one of three values and use it to sort by:
565 * 578 *
566 * 0 if item1 == item2 579 * 0 if item1 == item2
567 * 580 *
568 * > 0 (positive integer) if item1 > item2 581 * > 0 (positive integer) if item1 > item2
569 * 582 *
570 * < 0 (negative integer) if item1 < item2 583 * < 0 (negative integer) if item1 < item2
571 * 584 *
572 */ 585 */
573class OTodoXMLVector : public QVector<OTodoXMLContainer> { 586class OTodoXMLVector : public QVector<OTodoXMLContainer> {
574public: 587public:
575 OTodoXMLVector(int size, bool asc, int sort) 588 OTodoXMLVector(int size, bool asc, int sort)
576 : QVector<OTodoXMLContainer>( size ) 589 : QVector<OTodoXMLContainer>( size )
577 { 590 {
578 setAutoDelete( true ); 591 setAutoDelete( true );
579 m_asc = asc; 592 m_asc = asc;
580 m_sort = sort; 593 m_sort = sort;
581 } 594 }
582 /* return the summary/description */ 595 /* return the summary/description */
583 QString string( const OTodo& todo) { 596 QString string( const OTodo& todo) {
584 return todo.summary().isEmpty() ? 597 return todo.summary().isEmpty() ?
585 todo.description().left(20 ) : 598 todo.description().left(20 ) :
586 todo.summary(); 599 todo.summary();
587 } 600 }
588 /** 601 /**
589 * we take the sortorder( switch on it ) 602 * we take the sortorder( switch on it )
590 * 603 *
591 */ 604 */
592 int compareItems( Item d1, Item d2 ) { 605 int compareItems( Item d1, Item d2 ) {
593 bool seComp, sePrio, seDesc, seDeadline; 606 bool seComp, sePrio, seDesc, seDeadline;
594 seComp = sePrio = seDeadline = seDesc = false; 607 seComp = sePrio = seDeadline = seDesc = false;
595 int ret =0; 608 int ret =0;
596 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 609 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
597 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 610 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
598 611
599 /* same item */ 612 /* same item */
600 if ( con1->todo.uid() == con2->todo.uid() ) 613 if ( con1->todo.uid() == con2->todo.uid() )
601 return 0; 614 return 0;