summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodoaccessxml.cpp71
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp71
2 files changed, 130 insertions, 12 deletions
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 69b7ab4..2b62f0d 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,212 +1,213 @@
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 "oconversion.h"
19#include "opimstate.h" 19#include "opimstate.h"
20#include "otimezone.h" 20#include "otimezone.h"
21#include "opimnotifymanager.h"
21#include "orecur.h" 22#include "orecur.h"
22#include "otodoaccessxml.h" 23#include "otodoaccessxml.h"
23 24
24namespace { 25namespace {
25 time_t rp_end; 26 time_t rp_end;
26 ORecur* rec; 27 ORecur* rec;
27 ORecur *recur() { 28 ORecur *recur() {
28 if (!rec ) rec = new ORecur; 29 if (!rec ) rec = new ORecur;
29 return rec; 30 return rec;
30 } 31 }
31 int snd; 32 int snd;
32 enum MoreAttributes { 33 enum MoreAttributes {
33 FRType = OTodo::CompletedDate + 2, 34 FRType = OTodo::CompletedDate + 2,
34 FRWeekdays, 35 FRWeekdays,
35 FRPosition, 36 FRPosition,
36 FRFreq, 37 FRFreq,
37 FRHasEndDate, 38 FRHasEndDate,
38 FREndDate, 39 FREndDate,
39 FRStart, 40 FRStart,
40 FREnd 41 FREnd
41 }; 42 };
42 // FROM TT again 43 // FROM TT again
43char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 44char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
44{ 45{
45 char needleChar; 46 char needleChar;
46 char haystackChar; 47 char haystackChar;
47 if (!needle || !haystack || !hLen || !nLen) 48 if (!needle || !haystack || !hLen || !nLen)
48 return 0; 49 return 0;
49 50
50 const char* hsearch = haystack; 51 const char* hsearch = haystack;
51 52
52 if ((needleChar = *needle++) != 0) { 53 if ((needleChar = *needle++) != 0) {
53 nLen--; //(to make up for needle++) 54 nLen--; //(to make up for needle++)
54 do { 55 do {
55 do { 56 do {
56 if ((haystackChar = *hsearch++) == 0) 57 if ((haystackChar = *hsearch++) == 0)
57 return (0); 58 return (0);
58 if (hsearch >= haystack + hLen) 59 if (hsearch >= haystack + hLen)
59 return (0); 60 return (0);
60 } while (haystackChar != needleChar); 61 } while (haystackChar != needleChar);
61 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 62 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
62 hsearch--; 63 hsearch--;
63 } 64 }
64 return ((char *)hsearch); 65 return ((char *)hsearch);
65} 66}
66} 67}
67 68
68 69
69OTodoAccessXML::OTodoAccessXML( const QString& appName, 70OTodoAccessXML::OTodoAccessXML( const QString& appName,
70 const QString& fileName ) 71 const QString& fileName )
71 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 72 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
72{ 73{
73 if (!fileName.isEmpty() ) 74 if (!fileName.isEmpty() )
74 m_file = fileName; 75 m_file = fileName;
75 else 76 else
76 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 77 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
77} 78}
78OTodoAccessXML::~OTodoAccessXML() { 79OTodoAccessXML::~OTodoAccessXML() {
79 80
80} 81}
81bool OTodoAccessXML::load() { 82bool OTodoAccessXML::load() {
82 rec = 0; 83 rec = 0;
83 m_opened = true; 84 m_opened = true;
84 m_changed = false; 85 m_changed = false;
85 /* initialize dict */ 86 /* initialize dict */
86 /* 87 /*
87 * UPDATE dict if you change anything!!! 88 * UPDATE dict if you change anything!!!
88 */ 89 */
89 QAsciiDict<int> dict(21); 90 QAsciiDict<int> dict(21);
90 dict.setAutoDelete( TRUE ); 91 dict.setAutoDelete( TRUE );
91 dict.insert("Categories" , new int(OTodo::Category) ); 92 dict.insert("Categories" , new int(OTodo::Category) );
92 dict.insert("Uid" , new int(OTodo::Uid) ); 93 dict.insert("Uid" , new int(OTodo::Uid) );
93 dict.insert("HasDate" , new int(OTodo::HasDate) ); 94 dict.insert("HasDate" , new int(OTodo::HasDate) );
94 dict.insert("Completed" , new int(OTodo::Completed) ); 95 dict.insert("Completed" , new int(OTodo::Completed) );
95 dict.insert("Description" , new int(OTodo::Description) ); 96 dict.insert("Description" , new int(OTodo::Description) );
96 dict.insert("Summary" , new int(OTodo::Summary) ); 97 dict.insert("Summary" , new int(OTodo::Summary) );
97 dict.insert("Priority" , new int(OTodo::Priority) ); 98 dict.insert("Priority" , new int(OTodo::Priority) );
98 dict.insert("DateDay" , new int(OTodo::DateDay) ); 99 dict.insert("DateDay" , new int(OTodo::DateDay) );
99 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 100 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
100 dict.insert("DateYear" , new int(OTodo::DateYear) ); 101 dict.insert("DateYear" , new int(OTodo::DateYear) );
101 dict.insert("Progress" , new int(OTodo::Progress) ); 102 dict.insert("Progress" , new int(OTodo::Progress) );
102 dict.insert("CompletedDate", new int(OTodo::CompletedDate) ); 103 dict.insert("CompletedDate", new int(OTodo::CompletedDate) );
103 dict.insert("StartDate", new int(OTodo::StartDate) ); 104 dict.insert("StartDate", new int(OTodo::StartDate) );
104 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 105 dict.insert("CrossReference", new int(OTodo::CrossReference) );
105 dict.insert("State", new int(OTodo::State) ); 106 dict.insert("State", new int(OTodo::State) );
106 dict.insert("Alarms", new int(OTodo::Alarms) ); 107 dict.insert("Alarms", new int(OTodo::Alarms) );
107 dict.insert("Reminders", new int(OTodo::Reminders) ); 108 dict.insert("Reminders", new int(OTodo::Reminders) );
108 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 109 dict.insert("Notifiers", new int(OTodo::Notifiers) );
109 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 110 dict.insert("Maintainer", new int(OTodo::Maintainer) );
110 dict.insert("rtype", new int(FRType) ); 111 dict.insert("rtype", new int(FRType) );
111 dict.insert("rweekdays", new int(FRWeekdays) ); 112 dict.insert("rweekdays", new int(FRWeekdays) );
112 dict.insert("rposition", new int(FRPosition) ); 113 dict.insert("rposition", new int(FRPosition) );
113 dict.insert("rfreq", new int(FRFreq) ); 114 dict.insert("rfreq", new int(FRFreq) );
114 dict.insert("start", new int(FRStart) ); 115 dict.insert("start", new int(FRStart) );
115 dict.insert("rhasenddate", new int(FRHasEndDate) ); 116 dict.insert("rhasenddate", new int(FRHasEndDate) );
116 dict.insert("enddt", new int(FREndDate) ); 117 dict.insert("enddt", new int(FREndDate) );
117 118
118 // here the custom XML parser from TT it's GPL 119 // here the custom XML parser from TT it's GPL
119 // but we want to push OpiePIM... to TT..... 120 // but we want to push OpiePIM... to TT.....
120 // mmap part from zecke :) 121 // mmap part from zecke :)
121 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 122 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
122 struct stat attribut; 123 struct stat attribut;
123 if ( fd < 0 ) return false; 124 if ( fd < 0 ) return false;
124 125
125 if ( fstat(fd, &attribut ) == -1 ) { 126 if ( fstat(fd, &attribut ) == -1 ) {
126 ::close( fd ); 127 ::close( fd );
127 return false; 128 return false;
128 } 129 }
129 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 130 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
130 if ( map_addr == ( (caddr_t)-1) ) { 131 if ( map_addr == ( (caddr_t)-1) ) {
131 ::close(fd ); 132 ::close(fd );
132 return false; 133 return false;
133 } 134 }
134 /* advise the kernel who we want to read it */ 135 /* advise the kernel who we want to read it */
135 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 136 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
136 /* we do not the file any more */ 137 /* we do not the file any more */
137 ::close( fd ); 138 ::close( fd );
138 139
139 char* dt = (char*)map_addr; 140 char* dt = (char*)map_addr;
140 int len = attribut.st_size; 141 int len = attribut.st_size;
141 int i = 0; 142 int i = 0;
142 char *point; 143 char *point;
143 const char* collectionString = "<Task "; 144 const char* collectionString = "<Task ";
144 int strLen = strlen(collectionString); 145 int strLen = strlen(collectionString);
145 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 146 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
146 i = point -dt; 147 i = point -dt;
147 i+= strLen; 148 i+= strLen;
148 qWarning("Found a start at %d %d", i, (point-dt) ); 149 qWarning("Found a start at %d %d", i, (point-dt) );
149 150
150 OTodo ev; 151 OTodo ev;
151 m_year = m_month = m_day = 0; 152 m_year = m_month = m_day = 0;
152 153
153 while ( TRUE ) { 154 while ( TRUE ) {
154 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 155 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
155 ++i; 156 ++i;
156 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 157 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
157 break; 158 break;
158 159
159 // we have another attribute, read it. 160 // we have another attribute, read it.
160 int j = i; 161 int j = i;
161 while ( j < len && dt[j] != '=' ) 162 while ( j < len && dt[j] != '=' )
162 ++j; 163 ++j;
163 QCString attr( dt+i, j-i+1); 164 QCString attr( dt+i, j-i+1);
164 165
165 i = ++j; // skip = 166 i = ++j; // skip =
166 167
167 // find the start of quotes 168 // find the start of quotes
168 while ( i < len && dt[i] != '"' ) 169 while ( i < len && dt[i] != '"' )
169 ++i; 170 ++i;
170 j = ++i; 171 j = ++i;
171 172
172 bool haveUtf = FALSE; 173 bool haveUtf = FALSE;
173 bool haveEnt = FALSE; 174 bool haveEnt = FALSE;
174 while ( j < len && dt[j] != '"' ) { 175 while ( j < len && dt[j] != '"' ) {
175 if ( ((unsigned char)dt[j]) > 0x7f ) 176 if ( ((unsigned char)dt[j]) > 0x7f )
176 haveUtf = TRUE; 177 haveUtf = TRUE;
177 if ( dt[j] == '&' ) 178 if ( dt[j] == '&' )
178 haveEnt = TRUE; 179 haveEnt = TRUE;
179 ++j; 180 ++j;
180 } 181 }
181 if ( i == j ) { 182 if ( i == j ) {
182 // empty value 183 // empty value
183 i = j + 1; 184 i = j + 1;
184 continue; 185 continue;
185 } 186 }
186 187
187 QCString value( dt+i, j-i+1 ); 188 QCString value( dt+i, j-i+1 );
188 i = j + 1; 189 i = j + 1;
189 190
190 QString str = (haveUtf ? QString::fromUtf8( value ) 191 QString str = (haveUtf ? QString::fromUtf8( value )
191 : QString::fromLatin1( value ) ); 192 : QString::fromLatin1( value ) );
192 if ( haveEnt ) 193 if ( haveEnt )
193 str = Qtopia::plainString( str ); 194 str = Qtopia::plainString( str );
194 195
195 /* 196 /*
196 * add key + value 197 * add key + value
197 */ 198 */
198 todo( &dict, ev, attr, str ); 199 todo( &dict, ev, attr, str );
199 200
200 } 201 }
201 /* 202 /*
202 * now add it 203 * now add it
203 */ 204 */
204 qWarning("End at %d", i ); 205 qWarning("End at %d", i );
205 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 206 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
206 ev.setUid( 1 ); 207 ev.setUid( 1 );
207 m_changed = true; 208 m_changed = true;
208 } 209 }
209 if ( ev.hasDueDate() ) { 210 if ( ev.hasDueDate() ) {
210 ev.setDueDate( QDate(m_year, m_month, m_day) ); 211 ev.setDueDate( QDate(m_year, m_month, m_day) );
211 } 212 }
212 if ( rec && rec->doesRecur() ) { 213 if ( rec && rec->doesRecur() ) {
@@ -237,556 +238,614 @@ bool OTodoAccessXML::save() {
237// qWarning("not saving"); 238// qWarning("not saving");
238 return true; 239 return true;
239 } 240 }
240 QString strNewFile = m_file + ".new"; 241 QString strNewFile = m_file + ".new";
241 QFile f( strNewFile ); 242 QFile f( strNewFile );
242 if (!f.open( IO_WriteOnly|IO_Raw ) ) 243 if (!f.open( IO_WriteOnly|IO_Raw ) )
243 return false; 244 return false;
244 245
245 int written; 246 int written;
246 QString out; 247 QString out;
247 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 248 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
248 249
249 // for all todos 250 // for all todos
250 QMap<int, OTodo>::Iterator it; 251 QMap<int, OTodo>::Iterator it;
251 for (it = m_events.begin(); it != m_events.end(); ++it ) { 252 for (it = m_events.begin(); it != m_events.end(); ++it ) {
252 out+= "<Task " + toString( (*it) ) + " />\n"; 253 out+= "<Task " + toString( (*it) ) + " />\n";
253 QCString cstr = out.utf8(); 254 QCString cstr = out.utf8();
254 written = f.writeBlock( cstr.data(), cstr.length() ); 255 written = f.writeBlock( cstr.data(), cstr.length() );
255 256
256 /* less written then we wanted */ 257 /* less written then we wanted */
257 if ( written != (int)cstr.length() ) { 258 if ( written != (int)cstr.length() ) {
258 f.close(); 259 f.close();
259 QFile::remove( strNewFile ); 260 QFile::remove( strNewFile );
260 return false; 261 return false;
261 } 262 }
262 out = QString::null; 263 out = QString::null;
263 } 264 }
264 265
265 out += "</Tasks>"; 266 out += "</Tasks>";
266 QCString cstr = out.utf8(); 267 QCString cstr = out.utf8();
267 written = f.writeBlock( cstr.data(), cstr.length() ); 268 written = f.writeBlock( cstr.data(), cstr.length() );
268 269
269 if ( written != (int)cstr.length() ) { 270 if ( written != (int)cstr.length() ) {
270 f.close(); 271 f.close();
271 QFile::remove( strNewFile ); 272 QFile::remove( strNewFile );
272 return false; 273 return false;
273 } 274 }
274 /* flush before renaming */ 275 /* flush before renaming */
275 f.close(); 276 f.close();
276 277
277 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 278 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
278// qWarning("error renaming"); 279// qWarning("error renaming");
279 QFile::remove( strNewFile ); 280 QFile::remove( strNewFile );
280 } 281 }
281 282
282 m_changed = false; 283 m_changed = false;
283 return true; 284 return true;
284} 285}
285QArray<int> OTodoAccessXML::allRecords()const { 286QArray<int> OTodoAccessXML::allRecords()const {
286 QArray<int> ids( m_events.count() ); 287 QArray<int> ids( m_events.count() );
287 QMap<int, OTodo>::ConstIterator it; 288 QMap<int, OTodo>::ConstIterator it;
288 int i = 0; 289 int i = 0;
289 290
290 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 291 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
291 ids[i] = it.key(); 292 ids[i] = it.key();
292 i++; 293 i++;
293 } 294 }
294 return ids; 295 return ids;
295} 296}
296QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { 297QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) {
297 QArray<int> ids(0); 298 QArray<int> ids(0);
298 return ids; 299 return ids;
299} 300}
300OTodo OTodoAccessXML::find( int uid )const { 301OTodo OTodoAccessXML::find( int uid )const {
301 OTodo todo; 302 OTodo todo;
302 todo.setUid( 0 ); // isEmpty() 303 todo.setUid( 0 ); // isEmpty()
303 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 304 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
304 if ( it != m_events.end() ) 305 if ( it != m_events.end() )
305 todo = it.data(); 306 todo = it.data();
306 307
307 return todo; 308 return todo;
308} 309}
309void OTodoAccessXML::clear() { 310void OTodoAccessXML::clear() {
310 if (m_opened ) 311 if (m_opened )
311 m_changed = true; 312 m_changed = true;
312 313
313 m_events.clear(); 314 m_events.clear();
314} 315}
315bool OTodoAccessXML::add( const OTodo& todo ) { 316bool OTodoAccessXML::add( const OTodo& todo ) {
316// qWarning("add"); 317// qWarning("add");
317 m_changed = true; 318 m_changed = true;
318 m_events.insert( todo.uid(), todo ); 319 m_events.insert( todo.uid(), todo );
319 320
320 return true; 321 return true;
321} 322}
322bool OTodoAccessXML::remove( int uid ) { 323bool OTodoAccessXML::remove( int uid ) {
323 m_changed = true; 324 m_changed = true;
324 m_events.remove( uid ); 325 m_events.remove( uid );
325 326
326 return true; 327 return true;
327} 328}
328bool OTodoAccessXML::replace( const OTodo& todo) { 329bool OTodoAccessXML::replace( const OTodo& todo) {
329 m_changed = true; 330 m_changed = true;
330 m_events.replace( todo.uid(), todo ); 331 m_events.replace( todo.uid(), todo );
331 332
332 return true; 333 return true;
333} 334}
334QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 335QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
335 const QDate& end, 336 const QDate& end,
336 bool includeNoDates ) { 337 bool includeNoDates ) {
337 QArray<int> ids( m_events.count() ); 338 QArray<int> ids( m_events.count() );
338 QMap<int, OTodo>::Iterator it; 339 QMap<int, OTodo>::Iterator it;
339 340
340 int i = 0; 341 int i = 0;
341 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 342 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
342 if ( !it.data().hasDueDate() ) { 343 if ( !it.data().hasDueDate() ) {
343 if ( includeNoDates ) { 344 if ( includeNoDates ) {
344 ids[i] = it.key(); 345 ids[i] = it.key();
345 i++; 346 i++;
346 } 347 }
347 }else if ( it.data().dueDate() >= start && 348 }else if ( it.data().dueDate() >= start &&
348 it.data().dueDate() <= end ) { 349 it.data().dueDate() <= end ) {
349 ids[i] = it.key(); 350 ids[i] = it.key();
350 i++; 351 i++;
351 } 352 }
352 } 353 }
353 ids.resize( i ); 354 ids.resize( i );
354 return ids; 355 return ids;
355} 356}
356QArray<int> OTodoAccessXML::overDue() { 357QArray<int> OTodoAccessXML::overDue() {
357 QArray<int> ids( m_events.count() ); 358 QArray<int> ids( m_events.count() );
358 int i = 0; 359 int i = 0;
359 360
360 QMap<int, OTodo>::Iterator it; 361 QMap<int, OTodo>::Iterator it;
361 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 362 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
362 if ( it.data().isOverdue() ) { 363 if ( it.data().isOverdue() ) {
363 ids[i] = it.key(); 364 ids[i] = it.key();
364 i++; 365 i++;
365 } 366 }
366 } 367 }
367 ids.resize( i ); 368 ids.resize( i );
368 return ids; 369 return ids;
369} 370}
370 371
371 372
372/* private */ 373/* private */
373void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 374void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
374 const QCString& attr, const QString& val) { 375 const QCString& attr, const QString& val) {
375// qWarning("parse to do from XMLElement" ); 376// qWarning("parse to do from XMLElement" );
376 377
377 int *find=0; 378 int *find=0;
378 379
379 find = (*dict)[ attr.data() ]; 380 find = (*dict)[ attr.data() ];
380 if (!find ) { 381 if (!find ) {
381// qWarning("Unknown option" + it.key() ); 382// qWarning("Unknown option" + it.key() );
382 ev.setCustomField( attr, val ); 383 ev.setCustomField( attr, val );
383 return; 384 return;
384 } 385 }
385 386
386 switch( *find ) { 387 switch( *find ) {
387 case OTodo::Uid: 388 case OTodo::Uid:
388 ev.setUid( val.toInt() ); 389 ev.setUid( val.toInt() );
389 break; 390 break;
390 case OTodo::Category: 391 case OTodo::Category:
391 ev.setCategories( ev.idsFromString( val ) ); 392 ev.setCategories( ev.idsFromString( val ) );
392 break; 393 break;
393 case OTodo::HasDate: 394 case OTodo::HasDate:
394 ev.setHasDueDate( val.toInt() ); 395 ev.setHasDueDate( val.toInt() );
395 break; 396 break;
396 case OTodo::Completed: 397 case OTodo::Completed:
397 ev.setCompleted( val.toInt() ); 398 ev.setCompleted( val.toInt() );
398 break; 399 break;
399 case OTodo::Description: 400 case OTodo::Description:
400 ev.setDescription( val ); 401 ev.setDescription( val );
401 break; 402 break;
402 case OTodo::Summary: 403 case OTodo::Summary:
403 ev.setSummary( val ); 404 ev.setSummary( val );
404 break; 405 break;
405 case OTodo::Priority: 406 case OTodo::Priority:
406 ev.setPriority( val.toInt() ); 407 ev.setPriority( val.toInt() );
407 break; 408 break;
408 case OTodo::DateDay: 409 case OTodo::DateDay:
409 m_day = val.toInt(); 410 m_day = val.toInt();
410 break; 411 break;
411 case OTodo::DateMonth: 412 case OTodo::DateMonth:
412 m_month = val.toInt(); 413 m_month = val.toInt();
413 break; 414 break;
414 case OTodo::DateYear: 415 case OTodo::DateYear:
415 m_year = val.toInt(); 416 m_year = val.toInt();
416 break; 417 break;
417 case OTodo::Progress: 418 case OTodo::Progress:
418 ev.setProgress( val.toInt() ); 419 ev.setProgress( val.toInt() );
419 break; 420 break;
420 case OTodo::CompletedDate: 421 case OTodo::CompletedDate:
421 ev.setCompletedDate( OConversion::dateFromString( val ) ); 422 ev.setCompletedDate( OConversion::dateFromString( val ) );
422 break; 423 break;
423 case OTodo::StartDate: 424 case OTodo::StartDate:
424 ev.setStartDate( OConversion::dateFromString( val ) ); 425 ev.setStartDate( OConversion::dateFromString( val ) );
425 break; 426 break;
426 case OTodo::State: 427 case OTodo::State:
427 ev.setState( val.toInt() ); 428 ev.setState( val.toInt() );
428 break; 429 break;
430 case OTodo::Alarms:{
431 OPimNotifyManager &manager = ev.notifiers();
432 QStringList als = QStringList::split(";", val );
433 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
434 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
435 qWarning("alarm: %s", alarm.join("___").latin1() );
436 qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() );
437 OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
438 manager.add( al );
439 }
440 }
441 break;
442 case OTodo::Reminders:{
443 OPimNotifyManager &manager = ev.notifiers();
444 QStringList rems = QStringList::split(";", val );
445 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
446 OPimReminder rem( (*it).toInt() );
447 manager.add( rem );
448 }
449 }
450 break;
429 case OTodo::CrossReference: 451 case OTodo::CrossReference:
430 { 452 {
431 /* 453 /*
432 * A cross refernce looks like 454 * A cross refernce looks like
433 * appname,id;appname,id 455 * appname,id;appname,id
434 * we need to split it up 456 * we need to split it up
435 */ 457 */
436 QStringList refs = QStringList::split(';', val ); 458 QStringList refs = QStringList::split(';', val );
437 QStringList::Iterator strIt; 459 QStringList::Iterator strIt;
438 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 460 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
439 int pos = (*strIt).find(','); 461 int pos = (*strIt).find(',');
440 if ( pos > -1 ) 462 if ( pos > -1 )
441 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 463 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
442 464
443 } 465 }
444 break; 466 break;
445 } 467 }
446 /* Recurrence stuff below + post processing later */ 468 /* Recurrence stuff below + post processing later */
447 case FRType: 469 case FRType:
448 if ( val == "Daily" ) 470 if ( val == "Daily" )
449 recur()->setType( ORecur::Daily ); 471 recur()->setType( ORecur::Daily );
450 else if ( val == "Weekly" ) 472 else if ( val == "Weekly" )
451 recur()->setType( ORecur::Weekly); 473 recur()->setType( ORecur::Weekly);
452 else if ( val == "MonthlyDay" ) 474 else if ( val == "MonthlyDay" )
453 recur()->setType( ORecur::MonthlyDay ); 475 recur()->setType( ORecur::MonthlyDay );
454 else if ( val == "MonthlyDate" ) 476 else if ( val == "MonthlyDate" )
455 recur()->setType( ORecur::MonthlyDate ); 477 recur()->setType( ORecur::MonthlyDate );
456 else if ( val == "Yearly" ) 478 else if ( val == "Yearly" )
457 recur()->setType( ORecur::Yearly ); 479 recur()->setType( ORecur::Yearly );
458 else 480 else
459 recur()->setType( ORecur::NoRepeat ); 481 recur()->setType( ORecur::NoRepeat );
460 break; 482 break;
461 case FRWeekdays: 483 case FRWeekdays:
462 recur()->setDays( val.toInt() ); 484 recur()->setDays( val.toInt() );
463 break; 485 break;
464 case FRPosition: 486 case FRPosition:
465 recur()->setPosition( val.toInt() ); 487 recur()->setPosition( val.toInt() );
466 break; 488 break;
467 case FRFreq: 489 case FRFreq:
468 recur()->setFrequency( val.toInt() ); 490 recur()->setFrequency( val.toInt() );
469 break; 491 break;
470 case FRHasEndDate: 492 case FRHasEndDate:
471 recur()->setHasEndDate( val.toInt() ); 493 recur()->setHasEndDate( val.toInt() );
472 break; 494 break;
473 case FREndDate: { 495 case FREndDate: {
474 rp_end = (time_t) val.toLong(); 496 rp_end = (time_t) val.toLong();
475 break; 497 break;
476 } 498 }
477 default: 499 default:
478 break; 500 break;
479 } 501 }
480} 502}
481QString OTodoAccessXML::toString( const OTodo& ev )const { 503QString OTodoAccessXML::toString( const OTodo& ev )const {
482 QString str; 504 QString str;
483 505
484 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 506 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
485 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 507 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
486 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 508 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
487 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 509 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
488 510
489 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 511 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
490 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 512 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
491 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 513 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
492 514
493 if ( ev.hasDueDate() ) { 515 if ( ev.hasDueDate() ) {
494 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 516 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
495 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 517 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
496 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 518 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
497 } 519 }
498// qWarning( "Uid %d", ev.uid() ); 520// qWarning( "Uid %d", ev.uid() );
499 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 521 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
500 522
501// append the extra options 523// append the extra options
502 /* FIXME Qtopia::Record this is currently not 524 /* FIXME Qtopia::Record this is currently not
503 * possible you can set custom fields 525 * possible you can set custom fields
504 * but don' iterate over the list 526 * but don' iterate over the list
505 * I may do #define private protected 527 * I may do #define private protected
506 * for this case - cough --zecke 528 * for this case - cough --zecke
507 */ 529 */
508 /* 530 /*
509 QMap<QString, QString> extras = ev.extras(); 531 QMap<QString, QString> extras = ev.extras();
510 QMap<QString, QString>::Iterator extIt; 532 QMap<QString, QString>::Iterator extIt;
511 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 533 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
512 str += extIt.key() + "=\"" + extIt.data() + "\" "; 534 str += extIt.key() + "=\"" + extIt.data() + "\" ";
513 */ 535 */
514 // cross refernce 536 // cross refernce
515 if ( ev.hasRecurrence() ) { 537 if ( ev.hasRecurrence() ) {
516 str += ev.recurrence().toString(); 538 str += ev.recurrence().toString();
517 } 539 }
518 if ( ev.hasStartDate() ) 540 if ( ev.hasStartDate() )
519 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" "; 541 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" ";
520 if ( ev.hasCompletedDate() ) 542 if ( ev.hasCompletedDate() )
521 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" "; 543 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" ";
522 if ( ev.hasState() ) 544 if ( ev.hasState() )
523 str += "State=\""+QString::number( ev.state().state() )+"\" "; 545 str += "State=\""+QString::number( ev.state().state() )+"\" ";
524 546
547 /*
548 * save reminders and notifiers!
549 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER:DURATION:SOUND:....
550 */
551 if ( ev.hasNotifiers() ) {
552 OPimNotifyManager manager = ev.notifiers();
553 OPimNotifyManager::Alarms alarms = manager.alarms();
554 if (!alarms.isEmpty() ) {
555 QStringList als;
556 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
557 for ( ; it != alarms.end(); ++it ) {
558 /* only if time is valid */
559 if ( (*it).dateTime().isValid() ) {
560 als << OConversion::dateTimeToString( (*it).dateTime() )
561 + ":" + QString::number( (*it).duration() )
562 + ":" + QString::number( (*it).sound() )
563 + ":";
564 }
565 }
566 // now write the list
567 qWarning("als: %s", als.join("____________").latin1() );
568 str += "Alarms=\""+als.join(";") +"\" ";
569 }
570
571 /*
572 * now the same for reminders but more easy. We just save the uid of the OEvent.
573 */
574 OPimNotifyManager::Reminders reminders = manager.reminders();
575 if (!reminders.isEmpty() ) {
576 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
577 QStringList records;
578 for ( ; it != reminders.end(); ++it ) {
579 records << QString::number( (*it).recordUid() );
580 }
581 str += "Reminders=\""+ records.join(";") +"\" ";
582 }
583 }
584
525 585
526 return str; 586 return str;
527} 587}
528QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 588QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
529 return Qtopia::Record::idsToString( ints ); 589 return Qtopia::Record::idsToString( ints );
530} 590}
531 591
532/* internal class for sorting 592/* internal class for sorting
533 * 593 *
534 * Inspired by todoxmlio.cpp from TT 594 * Inspired by todoxmlio.cpp from TT
535 */ 595 */
536 596
537struct OTodoXMLContainer { 597struct OTodoXMLContainer {
538 OTodo todo; 598 OTodo todo;
539}; 599};
540 600
541namespace { 601namespace {
542 inline QString string( const OTodo& todo) { 602 inline QString string( const OTodo& todo) {
543 return todo.summary().isEmpty() ? 603 return todo.summary().isEmpty() ?
544 todo.description().left(20 ) : 604 todo.description().left(20 ) :
545 todo.summary(); 605 todo.summary();
546 } 606 }
547 inline int completed( const OTodo& todo1, const OTodo& todo2) { 607 inline int completed( const OTodo& todo1, const OTodo& todo2) {
548 int ret = 0; 608 int ret = 0;
549 if ( todo1.isCompleted() ) ret++; 609 if ( todo1.isCompleted() ) ret++;
550 if ( todo2.isCompleted() ) ret--; 610 if ( todo2.isCompleted() ) ret--;
551 return ret; 611 return ret;
552 } 612 }
553 inline int priority( const OTodo& t1, const OTodo& t2) { 613 inline int priority( const OTodo& t1, const OTodo& t2) {
554 return ( t1.priority() - t2.priority() ); 614 return ( t1.priority() - t2.priority() );
555 } 615 }
556 inline int description( const OTodo& t1, const OTodo& t2) { 616 inline int description( const OTodo& t1, const OTodo& t2) {
557 return QString::compare( string(t1), string(t2) ); 617 return QString::compare( string(t1), string(t2) );
558 } 618 }
559 inline int deadline( const OTodo& t1, const OTodo& t2) { 619 inline int deadline( const OTodo& t1, const OTodo& t2) {
560 int ret = 0; 620 int ret = 0;
561 if ( t1.hasDueDate() && 621 if ( t1.hasDueDate() &&
562 t2.hasDueDate() ) 622 t2.hasDueDate() )
563 ret = t2.dueDate().daysTo( t1.dueDate() ); 623 ret = t2.dueDate().daysTo( t1.dueDate() );
564 else if ( t1.hasDueDate() ) 624 else if ( t1.hasDueDate() )
565 ret = -1; 625 ret = -1;
566 else if ( t2.hasDueDate() ) 626 else if ( t2.hasDueDate() )
567 ret = 1; 627 ret = 1;
568 else 628 else
569 ret = 0; 629 ret = 0;
570 630
571 return ret; 631 return ret;
572 } 632 }
573 633
574}; 634};
575 635
576/* 636/*
577 * Returns: 637 * Returns:
578 * 0 if item1 == item2 638 * 0 if item1 == item2
579 * 639 *
580 * non-zero if item1 != item2 640 * non-zero if item1 != item2
581 * 641 *
582 * This function returns int rather than bool so that reimplementations 642 * This function returns int rather than bool so that reimplementations
583 * can return one of three values and use it to sort by: 643 * can return one of three values and use it to sort by:
584 * 644 *
585 * 0 if item1 == item2 645 * 0 if item1 == item2
586 * 646 *
587 * > 0 (positive integer) if item1 > item2 647 * > 0 (positive integer) if item1 > item2
588 * 648 *
589 * < 0 (negative integer) if item1 < item2 649 * < 0 (negative integer) if item1 < item2
590 * 650 *
591 */ 651 */
592class OTodoXMLVector : public QVector<OTodoXMLContainer> { 652class OTodoXMLVector : public QVector<OTodoXMLContainer> {
593public: 653public:
594 OTodoXMLVector(int size, bool asc, int sort) 654 OTodoXMLVector(int size, bool asc, int sort)
595 : QVector<OTodoXMLContainer>( size ) 655 : QVector<OTodoXMLContainer>( size )
596 { 656 {
597 setAutoDelete( true ); 657 setAutoDelete( true );
598 m_asc = asc; 658 m_asc = asc;
599 m_sort = sort; 659 m_sort = sort;
600 } 660 }
601 /* return the summary/description */ 661 /* return the summary/description */
602 QString string( const OTodo& todo) { 662 QString string( const OTodo& todo) {
603 return todo.summary().isEmpty() ? 663 return todo.summary().isEmpty() ?
604 todo.description().left(20 ) : 664 todo.description().left(20 ) :
605 todo.summary(); 665 todo.summary();
606 } 666 }
607 /** 667 /**
608 * we take the sortorder( switch on it ) 668 * we take the sortorder( switch on it )
609 * 669 *
610 */ 670 */
611 int compareItems( Item d1, Item d2 ) { 671 int compareItems( Item d1, Item d2 ) {
612 bool seComp, sePrio, seDesc, seDeadline; 672 bool seComp, sePrio, seDesc, seDeadline;
613 seComp = sePrio = seDeadline = seDesc = false; 673 seComp = sePrio = seDeadline = seDesc = false;
614 int ret =0; 674 int ret =0;
615 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 675 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
616 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 676 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
617 677
618 /* same item */ 678 /* same item */
619 if ( con1->todo.uid() == con2->todo.uid() ) 679 if ( con1->todo.uid() == con2->todo.uid() )
620 return 0; 680 return 0;
621 681
622 switch ( m_sort ) { 682 switch ( m_sort ) {
623 /* completed */ 683 /* completed */
624 case 0: { 684 case 0: {
625 ret = completed( con1->todo, con2->todo ); 685 ret = completed( con1->todo, con2->todo );
626 seComp = TRUE; 686 seComp = TRUE;
627 break; 687 break;
628 } 688 }
629 /* priority */ 689 /* priority */
630 case 1: { 690 case 1: {
631 ret = priority( con1->todo, con2->todo ); 691 ret = priority( con1->todo, con2->todo );
632 sePrio = TRUE; 692 sePrio = TRUE;
633 break; 693 break;
634 } 694 }
635 /* description */ 695 /* description */
636 case 2: { 696 case 2: {
637 ret = description( con1->todo, con2->todo ); 697 ret = description( con1->todo, con2->todo );
638 seDesc = TRUE; 698 seDesc = TRUE;
639 break; 699 break;
640 } 700 }
641 /* deadline */ 701 /* deadline */
642 case 3: { 702 case 3: {
643 ret = deadline( con1->todo, con2->todo ); 703 ret = deadline( con1->todo, con2->todo );
644 seDeadline = TRUE; 704 seDeadline = TRUE;
645 break; 705 break;
646 } 706 }
647 default: 707 default:
648 ret = 0; 708 ret = 0;
649 break; 709 break;
650 }; 710 };
651 /* 711 /*
652 * FIXME do better sorting if the first sort criteria 712 * FIXME do better sorting if the first sort criteria
653 * ret equals 0 start with complete and so on... 713 * ret equals 0 start with complete and so on...
654 */ 714 */
655 715
656 /* twist it we're not ascending*/ 716 /* twist it we're not ascending*/
657 if (!m_asc) 717 if (!m_asc)
658 ret = ret * -1; 718 ret = ret * -1;
659 719
660 if ( ret ) 720 if ( ret )
661 return ret; 721 return ret;
662 722
663 // default did not gave difference let's try it other way around 723 // default did not gave difference let's try it other way around
664 /* 724 /*
665 * General try if already checked if not test 725 * General try if already checked if not test
666 * and return 726 * and return
667 * 1.Completed 727 * 1.Completed
668 * 2.Priority 728 * 2.Priority
669 * 3.Description 729 * 3.Description
670 * 4.DueDate 730 * 4.DueDate
671 */ 731 */
672 if (!seComp ) { 732 if (!seComp ) {
673 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 733 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
674 if (!m_asc ) ret *= -1; 734 if (!m_asc ) ret *= -1;
675 return ret; 735 return ret;
676 } 736 }
677 } 737 }
678 if (!sePrio ) { 738 if (!sePrio ) {
679 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 739 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
680 if (!m_asc ) ret *= -1; 740 if (!m_asc ) ret *= -1;
681 return ret; 741 return ret;
682 } 742 }
683 } 743 }
684 if (!seDesc ) { 744 if (!seDesc ) {
685 if ( (ret = description(con1->todo, con2->todo ) ) ) { 745 if ( (ret = description(con1->todo, con2->todo ) ) ) {
686 if (!m_asc) ret *= -1; 746 if (!m_asc) ret *= -1;
687 return ret; 747 return ret;
688 } 748 }
689 } 749 }
690 if (!seDeadline) { 750 if (!seDeadline) {
691 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 751 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
692 if (!m_asc) ret *= -1; 752 if (!m_asc) ret *= -1;
693 return ret; 753 return ret;
694 } 754 }
695 } 755 }
696 756
697 return 0; 757 return 0;
698 } 758 }
699 private: 759 private:
700 bool m_asc; 760 bool m_asc;
701 int m_sort; 761 int m_sort;
702 762
703}; 763};
704 764
705QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 765QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
706 int sortFilter, int cat ) { 766 int sortFilter, int cat ) {
707 qWarning("sorted! %d cat", cat);
708 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 767 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
709 QMap<int, OTodo>::Iterator it; 768 QMap<int, OTodo>::Iterator it;
710 int item = 0; 769 int item = 0;
711 770
712 bool bCat = sortFilter & 1 ? true : false; 771 bool bCat = sortFilter & 1 ? true : false;
713 bool bOnly = sortFilter & 2 ? true : false; 772 bool bOnly = sortFilter & 2 ? true : false;
714 bool comp = sortFilter & 4 ? true : false; 773 bool comp = sortFilter & 4 ? true : false;
715 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 774 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
716 775
717 /* show category */ 776 /* show category */
718 if ( bCat && cat != 0) 777 /* -1 == unfiled */
778 if ( bCat && cat == -1 ) {
779 if(!(*it).categories().isEmpty() )
780 continue;
781 }else if ( bCat && cat != 0)
719 if (!(*it).categories().contains( cat ) ) { 782 if (!(*it).categories().contains( cat ) ) {
720 qWarning("category mis match");
721 continue; 783 continue;
722 } 784 }
723 /* isOverdue but we should not show overdue - why?*/ 785 /* isOverdue but we should not show overdue - why?*/
724/* if ( (*it).isOverdue() && !bOnly ) { 786/* if ( (*it).isOverdue() && !bOnly ) {
725 qWarning("item is overdue but !bOnly"); 787 qWarning("item is overdue but !bOnly");
726 continue; 788 continue;
727 } 789 }
728*/ 790*/
729 if ( !(*it).isOverdue() && bOnly ) { 791 if ( !(*it).isOverdue() && bOnly ) {
730 qWarning("item is not overdue but bOnly checked");
731 continue; 792 continue;
732 } 793 }
733 794
734 if ((*it).isCompleted() && comp ) { 795 if ((*it).isCompleted() && comp ) {
735 qWarning("completed continue!");
736 continue; 796 continue;
737 } 797 }
738 798
739 799
740 OTodoXMLContainer* con = new OTodoXMLContainer(); 800 OTodoXMLContainer* con = new OTodoXMLContainer();
741 con->todo = (*it); 801 con->todo = (*it);
742 vector.insert(item, con ); 802 vector.insert(item, con );
743 item++; 803 item++;
744 } 804 }
745 qWarning("XXX %d Items added", item);
746 vector.resize( item ); 805 vector.resize( item );
747 /* sort it now */ 806 /* sort it now */
748 vector.sort(); 807 vector.sort();
749 /* now get the uids */ 808 /* now get the uids */
750 QArray<int> array( vector.count() ); 809 QArray<int> array( vector.count() );
751 for (uint i= 0; i < vector.count(); i++ ) { 810 for (uint i= 0; i < vector.count(); i++ ) {
752 array[i] = ( vector.at(i) )->todo.uid(); 811 array[i] = ( vector.at(i) )->todo.uid();
753 } 812 }
754 return array; 813 return array;
755}; 814};
756void OTodoAccessXML::removeAllCompleted() { 815void OTodoAccessXML::removeAllCompleted() {
757 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 816 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
758 if ( (*it).isCompleted() ) 817 if ( (*it).isCompleted() )
759 m_events.remove( it ); 818 m_events.remove( it );
760 } 819 }
761} 820}
762QBitArray OTodoAccessXML::supports()const { 821QBitArray OTodoAccessXML::supports()const {
763 static QBitArray ar = sup(); 822 static QBitArray ar = sup();
764 return ar; 823 return ar;
765} 824}
766QBitArray OTodoAccessXML::sup() { 825QBitArray OTodoAccessXML::sup() {
767 QBitArray ar( OTodo::CompletedDate +1 ); 826 QBitArray ar( OTodo::CompletedDate +1 );
768 ar.fill( true ); 827 ar.fill( true );
769 ar[OTodo::CrossReference] = false; 828 ar[OTodo::CrossReference] = false;
770 ar[OTodo::State ] = false; 829 ar[OTodo::State ] = false;
771 ar[OTodo::Reminders] = false; 830 ar[OTodo::Reminders] = false;
772 ar[OTodo::Notifiers] = false; 831 ar[OTodo::Notifiers] = false;
773 ar[OTodo::Maintainer] = false; 832 ar[OTodo::Maintainer] = false;
774 833
775 return ar; 834 return ar;
776} 835}
777QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const 836QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const
778{ 837{
779 QArray<int> m_currentQuery( m_events.count() ); 838 QArray<int> m_currentQuery( m_events.count() );
780 uint arraycounter = 0; 839 uint arraycounter = 0;
781 840
782 QMap<int, OTodo>::ConstIterator it; 841 QMap<int, OTodo>::ConstIterator it;
783 for (it = m_events.begin(); it != m_events.end(); ++it ) { 842 for (it = m_events.begin(); it != m_events.end(); ++it ) {
784 if ( it.data().match( r ) ) 843 if ( it.data().match( r ) )
785 m_currentQuery[arraycounter++] = it.data().uid(); 844 m_currentQuery[arraycounter++] = it.data().uid();
786 845
787 } 846 }
788 // Shrink to fit.. 847 // Shrink to fit..
789 m_currentQuery.resize(arraycounter); 848 m_currentQuery.resize(arraycounter);
790 849
791 return m_currentQuery; 850 return m_currentQuery;
792} 851}
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 69b7ab4..2b62f0d 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,212 +1,213 @@
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 "oconversion.h"
19#include "opimstate.h" 19#include "opimstate.h"
20#include "otimezone.h" 20#include "otimezone.h"
21#include "opimnotifymanager.h"
21#include "orecur.h" 22#include "orecur.h"
22#include "otodoaccessxml.h" 23#include "otodoaccessxml.h"
23 24
24namespace { 25namespace {
25 time_t rp_end; 26 time_t rp_end;
26 ORecur* rec; 27 ORecur* rec;
27 ORecur *recur() { 28 ORecur *recur() {
28 if (!rec ) rec = new ORecur; 29 if (!rec ) rec = new ORecur;
29 return rec; 30 return rec;
30 } 31 }
31 int snd; 32 int snd;
32 enum MoreAttributes { 33 enum MoreAttributes {
33 FRType = OTodo::CompletedDate + 2, 34 FRType = OTodo::CompletedDate + 2,
34 FRWeekdays, 35 FRWeekdays,
35 FRPosition, 36 FRPosition,
36 FRFreq, 37 FRFreq,
37 FRHasEndDate, 38 FRHasEndDate,
38 FREndDate, 39 FREndDate,
39 FRStart, 40 FRStart,
40 FREnd 41 FREnd
41 }; 42 };
42 // FROM TT again 43 // FROM TT again
43char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) 44char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen)
44{ 45{
45 char needleChar; 46 char needleChar;
46 char haystackChar; 47 char haystackChar;
47 if (!needle || !haystack || !hLen || !nLen) 48 if (!needle || !haystack || !hLen || !nLen)
48 return 0; 49 return 0;
49 50
50 const char* hsearch = haystack; 51 const char* hsearch = haystack;
51 52
52 if ((needleChar = *needle++) != 0) { 53 if ((needleChar = *needle++) != 0) {
53 nLen--; //(to make up for needle++) 54 nLen--; //(to make up for needle++)
54 do { 55 do {
55 do { 56 do {
56 if ((haystackChar = *hsearch++) == 0) 57 if ((haystackChar = *hsearch++) == 0)
57 return (0); 58 return (0);
58 if (hsearch >= haystack + hLen) 59 if (hsearch >= haystack + hLen)
59 return (0); 60 return (0);
60 } while (haystackChar != needleChar); 61 } while (haystackChar != needleChar);
61 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); 62 } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0);
62 hsearch--; 63 hsearch--;
63 } 64 }
64 return ((char *)hsearch); 65 return ((char *)hsearch);
65} 66}
66} 67}
67 68
68 69
69OTodoAccessXML::OTodoAccessXML( const QString& appName, 70OTodoAccessXML::OTodoAccessXML( const QString& appName,
70 const QString& fileName ) 71 const QString& fileName )
71 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 72 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
72{ 73{
73 if (!fileName.isEmpty() ) 74 if (!fileName.isEmpty() )
74 m_file = fileName; 75 m_file = fileName;
75 else 76 else
76 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 77 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
77} 78}
78OTodoAccessXML::~OTodoAccessXML() { 79OTodoAccessXML::~OTodoAccessXML() {
79 80
80} 81}
81bool OTodoAccessXML::load() { 82bool OTodoAccessXML::load() {
82 rec = 0; 83 rec = 0;
83 m_opened = true; 84 m_opened = true;
84 m_changed = false; 85 m_changed = false;
85 /* initialize dict */ 86 /* initialize dict */
86 /* 87 /*
87 * UPDATE dict if you change anything!!! 88 * UPDATE dict if you change anything!!!
88 */ 89 */
89 QAsciiDict<int> dict(21); 90 QAsciiDict<int> dict(21);
90 dict.setAutoDelete( TRUE ); 91 dict.setAutoDelete( TRUE );
91 dict.insert("Categories" , new int(OTodo::Category) ); 92 dict.insert("Categories" , new int(OTodo::Category) );
92 dict.insert("Uid" , new int(OTodo::Uid) ); 93 dict.insert("Uid" , new int(OTodo::Uid) );
93 dict.insert("HasDate" , new int(OTodo::HasDate) ); 94 dict.insert("HasDate" , new int(OTodo::HasDate) );
94 dict.insert("Completed" , new int(OTodo::Completed) ); 95 dict.insert("Completed" , new int(OTodo::Completed) );
95 dict.insert("Description" , new int(OTodo::Description) ); 96 dict.insert("Description" , new int(OTodo::Description) );
96 dict.insert("Summary" , new int(OTodo::Summary) ); 97 dict.insert("Summary" , new int(OTodo::Summary) );
97 dict.insert("Priority" , new int(OTodo::Priority) ); 98 dict.insert("Priority" , new int(OTodo::Priority) );
98 dict.insert("DateDay" , new int(OTodo::DateDay) ); 99 dict.insert("DateDay" , new int(OTodo::DateDay) );
99 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 100 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
100 dict.insert("DateYear" , new int(OTodo::DateYear) ); 101 dict.insert("DateYear" , new int(OTodo::DateYear) );
101 dict.insert("Progress" , new int(OTodo::Progress) ); 102 dict.insert("Progress" , new int(OTodo::Progress) );
102 dict.insert("CompletedDate", new int(OTodo::CompletedDate) ); 103 dict.insert("CompletedDate", new int(OTodo::CompletedDate) );
103 dict.insert("StartDate", new int(OTodo::StartDate) ); 104 dict.insert("StartDate", new int(OTodo::StartDate) );
104 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 105 dict.insert("CrossReference", new int(OTodo::CrossReference) );
105 dict.insert("State", new int(OTodo::State) ); 106 dict.insert("State", new int(OTodo::State) );
106 dict.insert("Alarms", new int(OTodo::Alarms) ); 107 dict.insert("Alarms", new int(OTodo::Alarms) );
107 dict.insert("Reminders", new int(OTodo::Reminders) ); 108 dict.insert("Reminders", new int(OTodo::Reminders) );
108 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 109 dict.insert("Notifiers", new int(OTodo::Notifiers) );
109 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 110 dict.insert("Maintainer", new int(OTodo::Maintainer) );
110 dict.insert("rtype", new int(FRType) ); 111 dict.insert("rtype", new int(FRType) );
111 dict.insert("rweekdays", new int(FRWeekdays) ); 112 dict.insert("rweekdays", new int(FRWeekdays) );
112 dict.insert("rposition", new int(FRPosition) ); 113 dict.insert("rposition", new int(FRPosition) );
113 dict.insert("rfreq", new int(FRFreq) ); 114 dict.insert("rfreq", new int(FRFreq) );
114 dict.insert("start", new int(FRStart) ); 115 dict.insert("start", new int(FRStart) );
115 dict.insert("rhasenddate", new int(FRHasEndDate) ); 116 dict.insert("rhasenddate", new int(FRHasEndDate) );
116 dict.insert("enddt", new int(FREndDate) ); 117 dict.insert("enddt", new int(FREndDate) );
117 118
118 // here the custom XML parser from TT it's GPL 119 // here the custom XML parser from TT it's GPL
119 // but we want to push OpiePIM... to TT..... 120 // but we want to push OpiePIM... to TT.....
120 // mmap part from zecke :) 121 // mmap part from zecke :)
121 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 122 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
122 struct stat attribut; 123 struct stat attribut;
123 if ( fd < 0 ) return false; 124 if ( fd < 0 ) return false;
124 125
125 if ( fstat(fd, &attribut ) == -1 ) { 126 if ( fstat(fd, &attribut ) == -1 ) {
126 ::close( fd ); 127 ::close( fd );
127 return false; 128 return false;
128 } 129 }
129 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 130 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
130 if ( map_addr == ( (caddr_t)-1) ) { 131 if ( map_addr == ( (caddr_t)-1) ) {
131 ::close(fd ); 132 ::close(fd );
132 return false; 133 return false;
133 } 134 }
134 /* advise the kernel who we want to read it */ 135 /* advise the kernel who we want to read it */
135 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 136 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
136 /* we do not the file any more */ 137 /* we do not the file any more */
137 ::close( fd ); 138 ::close( fd );
138 139
139 char* dt = (char*)map_addr; 140 char* dt = (char*)map_addr;
140 int len = attribut.st_size; 141 int len = attribut.st_size;
141 int i = 0; 142 int i = 0;
142 char *point; 143 char *point;
143 const char* collectionString = "<Task "; 144 const char* collectionString = "<Task ";
144 int strLen = strlen(collectionString); 145 int strLen = strlen(collectionString);
145 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 146 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
146 i = point -dt; 147 i = point -dt;
147 i+= strLen; 148 i+= strLen;
148 qWarning("Found a start at %d %d", i, (point-dt) ); 149 qWarning("Found a start at %d %d", i, (point-dt) );
149 150
150 OTodo ev; 151 OTodo ev;
151 m_year = m_month = m_day = 0; 152 m_year = m_month = m_day = 0;
152 153
153 while ( TRUE ) { 154 while ( TRUE ) {
154 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 155 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
155 ++i; 156 ++i;
156 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 157 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
157 break; 158 break;
158 159
159 // we have another attribute, read it. 160 // we have another attribute, read it.
160 int j = i; 161 int j = i;
161 while ( j < len && dt[j] != '=' ) 162 while ( j < len && dt[j] != '=' )
162 ++j; 163 ++j;
163 QCString attr( dt+i, j-i+1); 164 QCString attr( dt+i, j-i+1);
164 165
165 i = ++j; // skip = 166 i = ++j; // skip =
166 167
167 // find the start of quotes 168 // find the start of quotes
168 while ( i < len && dt[i] != '"' ) 169 while ( i < len && dt[i] != '"' )
169 ++i; 170 ++i;
170 j = ++i; 171 j = ++i;
171 172
172 bool haveUtf = FALSE; 173 bool haveUtf = FALSE;
173 bool haveEnt = FALSE; 174 bool haveEnt = FALSE;
174 while ( j < len && dt[j] != '"' ) { 175 while ( j < len && dt[j] != '"' ) {
175 if ( ((unsigned char)dt[j]) > 0x7f ) 176 if ( ((unsigned char)dt[j]) > 0x7f )
176 haveUtf = TRUE; 177 haveUtf = TRUE;
177 if ( dt[j] == '&' ) 178 if ( dt[j] == '&' )
178 haveEnt = TRUE; 179 haveEnt = TRUE;
179 ++j; 180 ++j;
180 } 181 }
181 if ( i == j ) { 182 if ( i == j ) {
182 // empty value 183 // empty value
183 i = j + 1; 184 i = j + 1;
184 continue; 185 continue;
185 } 186 }
186 187
187 QCString value( dt+i, j-i+1 ); 188 QCString value( dt+i, j-i+1 );
188 i = j + 1; 189 i = j + 1;
189 190
190 QString str = (haveUtf ? QString::fromUtf8( value ) 191 QString str = (haveUtf ? QString::fromUtf8( value )
191 : QString::fromLatin1( value ) ); 192 : QString::fromLatin1( value ) );
192 if ( haveEnt ) 193 if ( haveEnt )
193 str = Qtopia::plainString( str ); 194 str = Qtopia::plainString( str );
194 195
195 /* 196 /*
196 * add key + value 197 * add key + value
197 */ 198 */
198 todo( &dict, ev, attr, str ); 199 todo( &dict, ev, attr, str );
199 200
200 } 201 }
201 /* 202 /*
202 * now add it 203 * now add it
203 */ 204 */
204 qWarning("End at %d", i ); 205 qWarning("End at %d", i );
205 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 206 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
206 ev.setUid( 1 ); 207 ev.setUid( 1 );
207 m_changed = true; 208 m_changed = true;
208 } 209 }
209 if ( ev.hasDueDate() ) { 210 if ( ev.hasDueDate() ) {
210 ev.setDueDate( QDate(m_year, m_month, m_day) ); 211 ev.setDueDate( QDate(m_year, m_month, m_day) );
211 } 212 }
212 if ( rec && rec->doesRecur() ) { 213 if ( rec && rec->doesRecur() ) {
@@ -237,556 +238,614 @@ bool OTodoAccessXML::save() {
237// qWarning("not saving"); 238// qWarning("not saving");
238 return true; 239 return true;
239 } 240 }
240 QString strNewFile = m_file + ".new"; 241 QString strNewFile = m_file + ".new";
241 QFile f( strNewFile ); 242 QFile f( strNewFile );
242 if (!f.open( IO_WriteOnly|IO_Raw ) ) 243 if (!f.open( IO_WriteOnly|IO_Raw ) )
243 return false; 244 return false;
244 245
245 int written; 246 int written;
246 QString out; 247 QString out;
247 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 248 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
248 249
249 // for all todos 250 // for all todos
250 QMap<int, OTodo>::Iterator it; 251 QMap<int, OTodo>::Iterator it;
251 for (it = m_events.begin(); it != m_events.end(); ++it ) { 252 for (it = m_events.begin(); it != m_events.end(); ++it ) {
252 out+= "<Task " + toString( (*it) ) + " />\n"; 253 out+= "<Task " + toString( (*it) ) + " />\n";
253 QCString cstr = out.utf8(); 254 QCString cstr = out.utf8();
254 written = f.writeBlock( cstr.data(), cstr.length() ); 255 written = f.writeBlock( cstr.data(), cstr.length() );
255 256
256 /* less written then we wanted */ 257 /* less written then we wanted */
257 if ( written != (int)cstr.length() ) { 258 if ( written != (int)cstr.length() ) {
258 f.close(); 259 f.close();
259 QFile::remove( strNewFile ); 260 QFile::remove( strNewFile );
260 return false; 261 return false;
261 } 262 }
262 out = QString::null; 263 out = QString::null;
263 } 264 }
264 265
265 out += "</Tasks>"; 266 out += "</Tasks>";
266 QCString cstr = out.utf8(); 267 QCString cstr = out.utf8();
267 written = f.writeBlock( cstr.data(), cstr.length() ); 268 written = f.writeBlock( cstr.data(), cstr.length() );
268 269
269 if ( written != (int)cstr.length() ) { 270 if ( written != (int)cstr.length() ) {
270 f.close(); 271 f.close();
271 QFile::remove( strNewFile ); 272 QFile::remove( strNewFile );
272 return false; 273 return false;
273 } 274 }
274 /* flush before renaming */ 275 /* flush before renaming */
275 f.close(); 276 f.close();
276 277
277 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 278 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
278// qWarning("error renaming"); 279// qWarning("error renaming");
279 QFile::remove( strNewFile ); 280 QFile::remove( strNewFile );
280 } 281 }
281 282
282 m_changed = false; 283 m_changed = false;
283 return true; 284 return true;
284} 285}
285QArray<int> OTodoAccessXML::allRecords()const { 286QArray<int> OTodoAccessXML::allRecords()const {
286 QArray<int> ids( m_events.count() ); 287 QArray<int> ids( m_events.count() );
287 QMap<int, OTodo>::ConstIterator it; 288 QMap<int, OTodo>::ConstIterator it;
288 int i = 0; 289 int i = 0;
289 290
290 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 291 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
291 ids[i] = it.key(); 292 ids[i] = it.key();
292 i++; 293 i++;
293 } 294 }
294 return ids; 295 return ids;
295} 296}
296QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) { 297QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int, const QDateTime& ) {
297 QArray<int> ids(0); 298 QArray<int> ids(0);
298 return ids; 299 return ids;
299} 300}
300OTodo OTodoAccessXML::find( int uid )const { 301OTodo OTodoAccessXML::find( int uid )const {
301 OTodo todo; 302 OTodo todo;
302 todo.setUid( 0 ); // isEmpty() 303 todo.setUid( 0 ); // isEmpty()
303 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 304 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
304 if ( it != m_events.end() ) 305 if ( it != m_events.end() )
305 todo = it.data(); 306 todo = it.data();
306 307
307 return todo; 308 return todo;
308} 309}
309void OTodoAccessXML::clear() { 310void OTodoAccessXML::clear() {
310 if (m_opened ) 311 if (m_opened )
311 m_changed = true; 312 m_changed = true;
312 313
313 m_events.clear(); 314 m_events.clear();
314} 315}
315bool OTodoAccessXML::add( const OTodo& todo ) { 316bool OTodoAccessXML::add( const OTodo& todo ) {
316// qWarning("add"); 317// qWarning("add");
317 m_changed = true; 318 m_changed = true;
318 m_events.insert( todo.uid(), todo ); 319 m_events.insert( todo.uid(), todo );
319 320
320 return true; 321 return true;
321} 322}
322bool OTodoAccessXML::remove( int uid ) { 323bool OTodoAccessXML::remove( int uid ) {
323 m_changed = true; 324 m_changed = true;
324 m_events.remove( uid ); 325 m_events.remove( uid );
325 326
326 return true; 327 return true;
327} 328}
328bool OTodoAccessXML::replace( const OTodo& todo) { 329bool OTodoAccessXML::replace( const OTodo& todo) {
329 m_changed = true; 330 m_changed = true;
330 m_events.replace( todo.uid(), todo ); 331 m_events.replace( todo.uid(), todo );
331 332
332 return true; 333 return true;
333} 334}
334QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 335QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
335 const QDate& end, 336 const QDate& end,
336 bool includeNoDates ) { 337 bool includeNoDates ) {
337 QArray<int> ids( m_events.count() ); 338 QArray<int> ids( m_events.count() );
338 QMap<int, OTodo>::Iterator it; 339 QMap<int, OTodo>::Iterator it;
339 340
340 int i = 0; 341 int i = 0;
341 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 342 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
342 if ( !it.data().hasDueDate() ) { 343 if ( !it.data().hasDueDate() ) {
343 if ( includeNoDates ) { 344 if ( includeNoDates ) {
344 ids[i] = it.key(); 345 ids[i] = it.key();
345 i++; 346 i++;
346 } 347 }
347 }else if ( it.data().dueDate() >= start && 348 }else if ( it.data().dueDate() >= start &&
348 it.data().dueDate() <= end ) { 349 it.data().dueDate() <= end ) {
349 ids[i] = it.key(); 350 ids[i] = it.key();
350 i++; 351 i++;
351 } 352 }
352 } 353 }
353 ids.resize( i ); 354 ids.resize( i );
354 return ids; 355 return ids;
355} 356}
356QArray<int> OTodoAccessXML::overDue() { 357QArray<int> OTodoAccessXML::overDue() {
357 QArray<int> ids( m_events.count() ); 358 QArray<int> ids( m_events.count() );
358 int i = 0; 359 int i = 0;
359 360
360 QMap<int, OTodo>::Iterator it; 361 QMap<int, OTodo>::Iterator it;
361 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 362 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
362 if ( it.data().isOverdue() ) { 363 if ( it.data().isOverdue() ) {
363 ids[i] = it.key(); 364 ids[i] = it.key();
364 i++; 365 i++;
365 } 366 }
366 } 367 }
367 ids.resize( i ); 368 ids.resize( i );
368 return ids; 369 return ids;
369} 370}
370 371
371 372
372/* private */ 373/* private */
373void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 374void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
374 const QCString& attr, const QString& val) { 375 const QCString& attr, const QString& val) {
375// qWarning("parse to do from XMLElement" ); 376// qWarning("parse to do from XMLElement" );
376 377
377 int *find=0; 378 int *find=0;
378 379
379 find = (*dict)[ attr.data() ]; 380 find = (*dict)[ attr.data() ];
380 if (!find ) { 381 if (!find ) {
381// qWarning("Unknown option" + it.key() ); 382// qWarning("Unknown option" + it.key() );
382 ev.setCustomField( attr, val ); 383 ev.setCustomField( attr, val );
383 return; 384 return;
384 } 385 }
385 386
386 switch( *find ) { 387 switch( *find ) {
387 case OTodo::Uid: 388 case OTodo::Uid:
388 ev.setUid( val.toInt() ); 389 ev.setUid( val.toInt() );
389 break; 390 break;
390 case OTodo::Category: 391 case OTodo::Category:
391 ev.setCategories( ev.idsFromString( val ) ); 392 ev.setCategories( ev.idsFromString( val ) );
392 break; 393 break;
393 case OTodo::HasDate: 394 case OTodo::HasDate:
394 ev.setHasDueDate( val.toInt() ); 395 ev.setHasDueDate( val.toInt() );
395 break; 396 break;
396 case OTodo::Completed: 397 case OTodo::Completed:
397 ev.setCompleted( val.toInt() ); 398 ev.setCompleted( val.toInt() );
398 break; 399 break;
399 case OTodo::Description: 400 case OTodo::Description:
400 ev.setDescription( val ); 401 ev.setDescription( val );
401 break; 402 break;
402 case OTodo::Summary: 403 case OTodo::Summary:
403 ev.setSummary( val ); 404 ev.setSummary( val );
404 break; 405 break;
405 case OTodo::Priority: 406 case OTodo::Priority:
406 ev.setPriority( val.toInt() ); 407 ev.setPriority( val.toInt() );
407 break; 408 break;
408 case OTodo::DateDay: 409 case OTodo::DateDay:
409 m_day = val.toInt(); 410 m_day = val.toInt();
410 break; 411 break;
411 case OTodo::DateMonth: 412 case OTodo::DateMonth:
412 m_month = val.toInt(); 413 m_month = val.toInt();
413 break; 414 break;
414 case OTodo::DateYear: 415 case OTodo::DateYear:
415 m_year = val.toInt(); 416 m_year = val.toInt();
416 break; 417 break;
417 case OTodo::Progress: 418 case OTodo::Progress:
418 ev.setProgress( val.toInt() ); 419 ev.setProgress( val.toInt() );
419 break; 420 break;
420 case OTodo::CompletedDate: 421 case OTodo::CompletedDate:
421 ev.setCompletedDate( OConversion::dateFromString( val ) ); 422 ev.setCompletedDate( OConversion::dateFromString( val ) );
422 break; 423 break;
423 case OTodo::StartDate: 424 case OTodo::StartDate:
424 ev.setStartDate( OConversion::dateFromString( val ) ); 425 ev.setStartDate( OConversion::dateFromString( val ) );
425 break; 426 break;
426 case OTodo::State: 427 case OTodo::State:
427 ev.setState( val.toInt() ); 428 ev.setState( val.toInt() );
428 break; 429 break;
430 case OTodo::Alarms:{
431 OPimNotifyManager &manager = ev.notifiers();
432 QStringList als = QStringList::split(";", val );
433 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
434 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
435 qWarning("alarm: %s", alarm.join("___").latin1() );
436 qWarning("alarm[0]: %s %s", alarm[0].latin1(), OConversion::dateTimeFromString( alarm[0] ).toString().latin1() );
437 OPimAlarm al( alarm[2].toInt(), OConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
438 manager.add( al );
439 }
440 }
441 break;
442 case OTodo::Reminders:{
443 OPimNotifyManager &manager = ev.notifiers();
444 QStringList rems = QStringList::split(";", val );
445 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
446 OPimReminder rem( (*it).toInt() );
447 manager.add( rem );
448 }
449 }
450 break;
429 case OTodo::CrossReference: 451 case OTodo::CrossReference:
430 { 452 {
431 /* 453 /*
432 * A cross refernce looks like 454 * A cross refernce looks like
433 * appname,id;appname,id 455 * appname,id;appname,id
434 * we need to split it up 456 * we need to split it up
435 */ 457 */
436 QStringList refs = QStringList::split(';', val ); 458 QStringList refs = QStringList::split(';', val );
437 QStringList::Iterator strIt; 459 QStringList::Iterator strIt;
438 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 460 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
439 int pos = (*strIt).find(','); 461 int pos = (*strIt).find(',');
440 if ( pos > -1 ) 462 if ( pos > -1 )
441 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 463 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
442 464
443 } 465 }
444 break; 466 break;
445 } 467 }
446 /* Recurrence stuff below + post processing later */ 468 /* Recurrence stuff below + post processing later */
447 case FRType: 469 case FRType:
448 if ( val == "Daily" ) 470 if ( val == "Daily" )
449 recur()->setType( ORecur::Daily ); 471 recur()->setType( ORecur::Daily );
450 else if ( val == "Weekly" ) 472 else if ( val == "Weekly" )
451 recur()->setType( ORecur::Weekly); 473 recur()->setType( ORecur::Weekly);
452 else if ( val == "MonthlyDay" ) 474 else if ( val == "MonthlyDay" )
453 recur()->setType( ORecur::MonthlyDay ); 475 recur()->setType( ORecur::MonthlyDay );
454 else if ( val == "MonthlyDate" ) 476 else if ( val == "MonthlyDate" )
455 recur()->setType( ORecur::MonthlyDate ); 477 recur()->setType( ORecur::MonthlyDate );
456 else if ( val == "Yearly" ) 478 else if ( val == "Yearly" )
457 recur()->setType( ORecur::Yearly ); 479 recur()->setType( ORecur::Yearly );
458 else 480 else
459 recur()->setType( ORecur::NoRepeat ); 481 recur()->setType( ORecur::NoRepeat );
460 break; 482 break;
461 case FRWeekdays: 483 case FRWeekdays:
462 recur()->setDays( val.toInt() ); 484 recur()->setDays( val.toInt() );
463 break; 485 break;
464 case FRPosition: 486 case FRPosition:
465 recur()->setPosition( val.toInt() ); 487 recur()->setPosition( val.toInt() );
466 break; 488 break;
467 case FRFreq: 489 case FRFreq:
468 recur()->setFrequency( val.toInt() ); 490 recur()->setFrequency( val.toInt() );
469 break; 491 break;
470 case FRHasEndDate: 492 case FRHasEndDate:
471 recur()->setHasEndDate( val.toInt() ); 493 recur()->setHasEndDate( val.toInt() );
472 break; 494 break;
473 case FREndDate: { 495 case FREndDate: {
474 rp_end = (time_t) val.toLong(); 496 rp_end = (time_t) val.toLong();
475 break; 497 break;
476 } 498 }
477 default: 499 default:
478 break; 500 break;
479 } 501 }
480} 502}
481QString OTodoAccessXML::toString( const OTodo& ev )const { 503QString OTodoAccessXML::toString( const OTodo& ev )const {
482 QString str; 504 QString str;
483 505
484 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 506 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
485 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 507 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
486 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 508 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
487 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 509 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
488 510
489 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 511 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
490 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 512 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
491 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 513 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
492 514
493 if ( ev.hasDueDate() ) { 515 if ( ev.hasDueDate() ) {
494 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 516 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
495 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 517 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
496 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 518 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
497 } 519 }
498// qWarning( "Uid %d", ev.uid() ); 520// qWarning( "Uid %d", ev.uid() );
499 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 521 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
500 522
501// append the extra options 523// append the extra options
502 /* FIXME Qtopia::Record this is currently not 524 /* FIXME Qtopia::Record this is currently not
503 * possible you can set custom fields 525 * possible you can set custom fields
504 * but don' iterate over the list 526 * but don' iterate over the list
505 * I may do #define private protected 527 * I may do #define private protected
506 * for this case - cough --zecke 528 * for this case - cough --zecke
507 */ 529 */
508 /* 530 /*
509 QMap<QString, QString> extras = ev.extras(); 531 QMap<QString, QString> extras = ev.extras();
510 QMap<QString, QString>::Iterator extIt; 532 QMap<QString, QString>::Iterator extIt;
511 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 533 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
512 str += extIt.key() + "=\"" + extIt.data() + "\" "; 534 str += extIt.key() + "=\"" + extIt.data() + "\" ";
513 */ 535 */
514 // cross refernce 536 // cross refernce
515 if ( ev.hasRecurrence() ) { 537 if ( ev.hasRecurrence() ) {
516 str += ev.recurrence().toString(); 538 str += ev.recurrence().toString();
517 } 539 }
518 if ( ev.hasStartDate() ) 540 if ( ev.hasStartDate() )
519 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" "; 541 str += "StartDate=\""+ OConversion::dateToString( ev.startDate() ) +"\" ";
520 if ( ev.hasCompletedDate() ) 542 if ( ev.hasCompletedDate() )
521 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" "; 543 str += "CompletedDate=\""+ OConversion::dateToString( ev.completedDate() ) +"\" ";
522 if ( ev.hasState() ) 544 if ( ev.hasState() )
523 str += "State=\""+QString::number( ev.state().state() )+"\" "; 545 str += "State=\""+QString::number( ev.state().state() )+"\" ";
524 546
547 /*
548 * save reminders and notifiers!
549 * DATE_TIME:DURATION:SOUND:NOT_USED_YET;OTHER_DATE_TIME:OTHER:DURATION:SOUND:....
550 */
551 if ( ev.hasNotifiers() ) {
552 OPimNotifyManager manager = ev.notifiers();
553 OPimNotifyManager::Alarms alarms = manager.alarms();
554 if (!alarms.isEmpty() ) {
555 QStringList als;
556 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
557 for ( ; it != alarms.end(); ++it ) {
558 /* only if time is valid */
559 if ( (*it).dateTime().isValid() ) {
560 als << OConversion::dateTimeToString( (*it).dateTime() )
561 + ":" + QString::number( (*it).duration() )
562 + ":" + QString::number( (*it).sound() )
563 + ":";
564 }
565 }
566 // now write the list
567 qWarning("als: %s", als.join("____________").latin1() );
568 str += "Alarms=\""+als.join(";") +"\" ";
569 }
570
571 /*
572 * now the same for reminders but more easy. We just save the uid of the OEvent.
573 */
574 OPimNotifyManager::Reminders reminders = manager.reminders();
575 if (!reminders.isEmpty() ) {
576 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
577 QStringList records;
578 for ( ; it != reminders.end(); ++it ) {
579 records << QString::number( (*it).recordUid() );
580 }
581 str += "Reminders=\""+ records.join(";") +"\" ";
582 }
583 }
584
525 585
526 return str; 586 return str;
527} 587}
528QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 588QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
529 return Qtopia::Record::idsToString( ints ); 589 return Qtopia::Record::idsToString( ints );
530} 590}
531 591
532/* internal class for sorting 592/* internal class for sorting
533 * 593 *
534 * Inspired by todoxmlio.cpp from TT 594 * Inspired by todoxmlio.cpp from TT
535 */ 595 */
536 596
537struct OTodoXMLContainer { 597struct OTodoXMLContainer {
538 OTodo todo; 598 OTodo todo;
539}; 599};
540 600
541namespace { 601namespace {
542 inline QString string( const OTodo& todo) { 602 inline QString string( const OTodo& todo) {
543 return todo.summary().isEmpty() ? 603 return todo.summary().isEmpty() ?
544 todo.description().left(20 ) : 604 todo.description().left(20 ) :
545 todo.summary(); 605 todo.summary();
546 } 606 }
547 inline int completed( const OTodo& todo1, const OTodo& todo2) { 607 inline int completed( const OTodo& todo1, const OTodo& todo2) {
548 int ret = 0; 608 int ret = 0;
549 if ( todo1.isCompleted() ) ret++; 609 if ( todo1.isCompleted() ) ret++;
550 if ( todo2.isCompleted() ) ret--; 610 if ( todo2.isCompleted() ) ret--;
551 return ret; 611 return ret;
552 } 612 }
553 inline int priority( const OTodo& t1, const OTodo& t2) { 613 inline int priority( const OTodo& t1, const OTodo& t2) {
554 return ( t1.priority() - t2.priority() ); 614 return ( t1.priority() - t2.priority() );
555 } 615 }
556 inline int description( const OTodo& t1, const OTodo& t2) { 616 inline int description( const OTodo& t1, const OTodo& t2) {
557 return QString::compare( string(t1), string(t2) ); 617 return QString::compare( string(t1), string(t2) );
558 } 618 }
559 inline int deadline( const OTodo& t1, const OTodo& t2) { 619 inline int deadline( const OTodo& t1, const OTodo& t2) {
560 int ret = 0; 620 int ret = 0;
561 if ( t1.hasDueDate() && 621 if ( t1.hasDueDate() &&
562 t2.hasDueDate() ) 622 t2.hasDueDate() )
563 ret = t2.dueDate().daysTo( t1.dueDate() ); 623 ret = t2.dueDate().daysTo( t1.dueDate() );
564 else if ( t1.hasDueDate() ) 624 else if ( t1.hasDueDate() )
565 ret = -1; 625 ret = -1;
566 else if ( t2.hasDueDate() ) 626 else if ( t2.hasDueDate() )
567 ret = 1; 627 ret = 1;
568 else 628 else
569 ret = 0; 629 ret = 0;
570 630
571 return ret; 631 return ret;
572 } 632 }
573 633
574}; 634};
575 635
576/* 636/*
577 * Returns: 637 * Returns:
578 * 0 if item1 == item2 638 * 0 if item1 == item2
579 * 639 *
580 * non-zero if item1 != item2 640 * non-zero if item1 != item2
581 * 641 *
582 * This function returns int rather than bool so that reimplementations 642 * This function returns int rather than bool so that reimplementations
583 * can return one of three values and use it to sort by: 643 * can return one of three values and use it to sort by:
584 * 644 *
585 * 0 if item1 == item2 645 * 0 if item1 == item2
586 * 646 *
587 * > 0 (positive integer) if item1 > item2 647 * > 0 (positive integer) if item1 > item2
588 * 648 *
589 * < 0 (negative integer) if item1 < item2 649 * < 0 (negative integer) if item1 < item2
590 * 650 *
591 */ 651 */
592class OTodoXMLVector : public QVector<OTodoXMLContainer> { 652class OTodoXMLVector : public QVector<OTodoXMLContainer> {
593public: 653public:
594 OTodoXMLVector(int size, bool asc, int sort) 654 OTodoXMLVector(int size, bool asc, int sort)
595 : QVector<OTodoXMLContainer>( size ) 655 : QVector<OTodoXMLContainer>( size )
596 { 656 {
597 setAutoDelete( true ); 657 setAutoDelete( true );
598 m_asc = asc; 658 m_asc = asc;
599 m_sort = sort; 659 m_sort = sort;
600 } 660 }
601 /* return the summary/description */ 661 /* return the summary/description */
602 QString string( const OTodo& todo) { 662 QString string( const OTodo& todo) {
603 return todo.summary().isEmpty() ? 663 return todo.summary().isEmpty() ?
604 todo.description().left(20 ) : 664 todo.description().left(20 ) :
605 todo.summary(); 665 todo.summary();
606 } 666 }
607 /** 667 /**
608 * we take the sortorder( switch on it ) 668 * we take the sortorder( switch on it )
609 * 669 *
610 */ 670 */
611 int compareItems( Item d1, Item d2 ) { 671 int compareItems( Item d1, Item d2 ) {
612 bool seComp, sePrio, seDesc, seDeadline; 672 bool seComp, sePrio, seDesc, seDeadline;
613 seComp = sePrio = seDeadline = seDesc = false; 673 seComp = sePrio = seDeadline = seDesc = false;
614 int ret =0; 674 int ret =0;
615 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 675 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
616 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 676 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
617 677
618 /* same item */ 678 /* same item */
619 if ( con1->todo.uid() == con2->todo.uid() ) 679 if ( con1->todo.uid() == con2->todo.uid() )
620 return 0; 680 return 0;
621 681
622 switch ( m_sort ) { 682 switch ( m_sort ) {
623 /* completed */ 683 /* completed */
624 case 0: { 684 case 0: {
625 ret = completed( con1->todo, con2->todo ); 685 ret = completed( con1->todo, con2->todo );
626 seComp = TRUE; 686 seComp = TRUE;
627 break; 687 break;
628 } 688 }
629 /* priority */ 689 /* priority */
630 case 1: { 690 case 1: {
631 ret = priority( con1->todo, con2->todo ); 691 ret = priority( con1->todo, con2->todo );
632 sePrio = TRUE; 692 sePrio = TRUE;
633 break; 693 break;
634 } 694 }
635 /* description */ 695 /* description */
636 case 2: { 696 case 2: {
637 ret = description( con1->todo, con2->todo ); 697 ret = description( con1->todo, con2->todo );
638 seDesc = TRUE; 698 seDesc = TRUE;
639 break; 699 break;
640 } 700 }
641 /* deadline */ 701 /* deadline */
642 case 3: { 702 case 3: {
643 ret = deadline( con1->todo, con2->todo ); 703 ret = deadline( con1->todo, con2->todo );
644 seDeadline = TRUE; 704 seDeadline = TRUE;
645 break; 705 break;
646 } 706 }
647 default: 707 default:
648 ret = 0; 708 ret = 0;
649 break; 709 break;
650 }; 710 };
651 /* 711 /*
652 * FIXME do better sorting if the first sort criteria 712 * FIXME do better sorting if the first sort criteria
653 * ret equals 0 start with complete and so on... 713 * ret equals 0 start with complete and so on...
654 */ 714 */
655 715
656 /* twist it we're not ascending*/ 716 /* twist it we're not ascending*/
657 if (!m_asc) 717 if (!m_asc)
658 ret = ret * -1; 718 ret = ret * -1;
659 719
660 if ( ret ) 720 if ( ret )
661 return ret; 721 return ret;
662 722
663 // default did not gave difference let's try it other way around 723 // default did not gave difference let's try it other way around
664 /* 724 /*
665 * General try if already checked if not test 725 * General try if already checked if not test
666 * and return 726 * and return
667 * 1.Completed 727 * 1.Completed
668 * 2.Priority 728 * 2.Priority
669 * 3.Description 729 * 3.Description
670 * 4.DueDate 730 * 4.DueDate
671 */ 731 */
672 if (!seComp ) { 732 if (!seComp ) {
673 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 733 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
674 if (!m_asc ) ret *= -1; 734 if (!m_asc ) ret *= -1;
675 return ret; 735 return ret;
676 } 736 }
677 } 737 }
678 if (!sePrio ) { 738 if (!sePrio ) {
679 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 739 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
680 if (!m_asc ) ret *= -1; 740 if (!m_asc ) ret *= -1;
681 return ret; 741 return ret;
682 } 742 }
683 } 743 }
684 if (!seDesc ) { 744 if (!seDesc ) {
685 if ( (ret = description(con1->todo, con2->todo ) ) ) { 745 if ( (ret = description(con1->todo, con2->todo ) ) ) {
686 if (!m_asc) ret *= -1; 746 if (!m_asc) ret *= -1;
687 return ret; 747 return ret;
688 } 748 }
689 } 749 }
690 if (!seDeadline) { 750 if (!seDeadline) {
691 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 751 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
692 if (!m_asc) ret *= -1; 752 if (!m_asc) ret *= -1;
693 return ret; 753 return ret;
694 } 754 }
695 } 755 }
696 756
697 return 0; 757 return 0;
698 } 758 }
699 private: 759 private:
700 bool m_asc; 760 bool m_asc;
701 int m_sort; 761 int m_sort;
702 762
703}; 763};
704 764
705QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 765QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
706 int sortFilter, int cat ) { 766 int sortFilter, int cat ) {
707 qWarning("sorted! %d cat", cat);
708 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 767 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
709 QMap<int, OTodo>::Iterator it; 768 QMap<int, OTodo>::Iterator it;
710 int item = 0; 769 int item = 0;
711 770
712 bool bCat = sortFilter & 1 ? true : false; 771 bool bCat = sortFilter & 1 ? true : false;
713 bool bOnly = sortFilter & 2 ? true : false; 772 bool bOnly = sortFilter & 2 ? true : false;
714 bool comp = sortFilter & 4 ? true : false; 773 bool comp = sortFilter & 4 ? true : false;
715 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 774 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
716 775
717 /* show category */ 776 /* show category */
718 if ( bCat && cat != 0) 777 /* -1 == unfiled */
778 if ( bCat && cat == -1 ) {
779 if(!(*it).categories().isEmpty() )
780 continue;
781 }else if ( bCat && cat != 0)
719 if (!(*it).categories().contains( cat ) ) { 782 if (!(*it).categories().contains( cat ) ) {
720 qWarning("category mis match");
721 continue; 783 continue;
722 } 784 }
723 /* isOverdue but we should not show overdue - why?*/ 785 /* isOverdue but we should not show overdue - why?*/
724/* if ( (*it).isOverdue() && !bOnly ) { 786/* if ( (*it).isOverdue() && !bOnly ) {
725 qWarning("item is overdue but !bOnly"); 787 qWarning("item is overdue but !bOnly");
726 continue; 788 continue;
727 } 789 }
728*/ 790*/
729 if ( !(*it).isOverdue() && bOnly ) { 791 if ( !(*it).isOverdue() && bOnly ) {
730 qWarning("item is not overdue but bOnly checked");
731 continue; 792 continue;
732 } 793 }
733 794
734 if ((*it).isCompleted() && comp ) { 795 if ((*it).isCompleted() && comp ) {
735 qWarning("completed continue!");
736 continue; 796 continue;
737 } 797 }
738 798
739 799
740 OTodoXMLContainer* con = new OTodoXMLContainer(); 800 OTodoXMLContainer* con = new OTodoXMLContainer();
741 con->todo = (*it); 801 con->todo = (*it);
742 vector.insert(item, con ); 802 vector.insert(item, con );
743 item++; 803 item++;
744 } 804 }
745 qWarning("XXX %d Items added", item);
746 vector.resize( item ); 805 vector.resize( item );
747 /* sort it now */ 806 /* sort it now */
748 vector.sort(); 807 vector.sort();
749 /* now get the uids */ 808 /* now get the uids */
750 QArray<int> array( vector.count() ); 809 QArray<int> array( vector.count() );
751 for (uint i= 0; i < vector.count(); i++ ) { 810 for (uint i= 0; i < vector.count(); i++ ) {
752 array[i] = ( vector.at(i) )->todo.uid(); 811 array[i] = ( vector.at(i) )->todo.uid();
753 } 812 }
754 return array; 813 return array;
755}; 814};
756void OTodoAccessXML::removeAllCompleted() { 815void OTodoAccessXML::removeAllCompleted() {
757 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 816 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
758 if ( (*it).isCompleted() ) 817 if ( (*it).isCompleted() )
759 m_events.remove( it ); 818 m_events.remove( it );
760 } 819 }
761} 820}
762QBitArray OTodoAccessXML::supports()const { 821QBitArray OTodoAccessXML::supports()const {
763 static QBitArray ar = sup(); 822 static QBitArray ar = sup();
764 return ar; 823 return ar;
765} 824}
766QBitArray OTodoAccessXML::sup() { 825QBitArray OTodoAccessXML::sup() {
767 QBitArray ar( OTodo::CompletedDate +1 ); 826 QBitArray ar( OTodo::CompletedDate +1 );
768 ar.fill( true ); 827 ar.fill( true );
769 ar[OTodo::CrossReference] = false; 828 ar[OTodo::CrossReference] = false;
770 ar[OTodo::State ] = false; 829 ar[OTodo::State ] = false;
771 ar[OTodo::Reminders] = false; 830 ar[OTodo::Reminders] = false;
772 ar[OTodo::Notifiers] = false; 831 ar[OTodo::Notifiers] = false;
773 ar[OTodo::Maintainer] = false; 832 ar[OTodo::Maintainer] = false;
774 833
775 return ar; 834 return ar;
776} 835}
777QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const 836QArray<int> OTodoAccessXML::matchRegexp( const QRegExp &r ) const
778{ 837{
779 QArray<int> m_currentQuery( m_events.count() ); 838 QArray<int> m_currentQuery( m_events.count() );
780 uint arraycounter = 0; 839 uint arraycounter = 0;
781 840
782 QMap<int, OTodo>::ConstIterator it; 841 QMap<int, OTodo>::ConstIterator it;
783 for (it = m_events.begin(); it != m_events.end(); ++it ) { 842 for (it = m_events.begin(); it != m_events.end(); ++it ) {
784 if ( it.data().match( r ) ) 843 if ( it.data().match( r ) )
785 m_currentQuery[arraycounter++] = it.data().uid(); 844 m_currentQuery[arraycounter++] = it.data().uid();
786 845
787 } 846 }
788 // Shrink to fit.. 847 // Shrink to fit..
789 m_currentQuery.resize(arraycounter); 848 m_currentQuery.resize(arraycounter);
790 849
791 return m_currentQuery; 850 return m_currentQuery;
792} 851}