Diffstat (limited to 'libopie2/opiepim/backend/otodoaccessxml.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 316 |
1 files changed, 61 insertions, 255 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 3e06d88..273f91a 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp | |||
@@ -25,26 +25,29 @@ | |||
25 | If not, write to the Free Software Foundation, | 25 | If not, write to the Free Software Foundation, |
26 | Inc., 59 Temple Place - Suite 330, | 26 | Inc., 59 Temple Place - Suite 330, |
27 | Boston, MA 02111-1307, USA. | 27 | Boston, MA 02111-1307, USA. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* OPIE */ | 30 | /* OPIE */ |
31 | #include <opie2/opimdateconversion.h> | 31 | #include <opie2/opimdateconversion.h> |
32 | #include <opie2/opimstate.h> | 32 | #include <opie2/opimstate.h> |
33 | #include <opie2/opimtimezone.h> | 33 | #include <opie2/opimtimezone.h> |
34 | #include <opie2/opimnotifymanager.h> | 34 | #include <opie2/opimnotifymanager.h> |
35 | #include <opie2/opimrecurrence.h> | 35 | #include <opie2/opimrecurrence.h> |
36 | #include <opie2/otodoaccessxml.h> | 36 | #include <opie2/otodoaccessxml.h> |
37 | #include <opie2/otodoaccess.h> | ||
37 | #include <opie2/odebug.h> | 38 | #include <opie2/odebug.h> |
38 | 39 | ||
40 | #include <opie2/private/opimtodosortvector.h> | ||
41 | |||
39 | #include <qpe/global.h> | 42 | #include <qpe/global.h> |
40 | #include <qpe/stringutil.h> | 43 | #include <qpe/stringutil.h> |
41 | #include <qpe/timeconversion.h> | 44 | #include <qpe/timeconversion.h> |
42 | 45 | ||
43 | /* QT */ | 46 | /* QT */ |
44 | #include <qfile.h> | 47 | #include <qfile.h> |
45 | #include <qvector.h> | 48 | #include <qvector.h> |
46 | 49 | ||
47 | /* STD */ | 50 | /* STD */ |
48 | #include <errno.h> | 51 | #include <errno.h> |
49 | #include <fcntl.h> | 52 | #include <fcntl.h> |
50 | 53 | ||
@@ -133,25 +136,24 @@ bool OPimTodoAccessXML::load() { | |||
133 | dict.insert("Summary" , new int(OPimTodo::Summary) ); | 136 | dict.insert("Summary" , new int(OPimTodo::Summary) ); |
134 | dict.insert("Priority" , new int(OPimTodo::Priority) ); | 137 | dict.insert("Priority" , new int(OPimTodo::Priority) ); |
135 | dict.insert("DateDay" , new int(OPimTodo::DateDay) ); | 138 | dict.insert("DateDay" , new int(OPimTodo::DateDay) ); |
136 | dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); | 139 | dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); |
137 | dict.insert("DateYear" , new int(OPimTodo::DateYear) ); | 140 | dict.insert("DateYear" , new int(OPimTodo::DateYear) ); |
138 | dict.insert("Progress" , new int(OPimTodo::Progress) ); | 141 | dict.insert("Progress" , new int(OPimTodo::Progress) ); |
139 | dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); | 142 | dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); |
140 | dict.insert("StartDate", new int(OPimTodo::StartDate) ); | 143 | dict.insert("StartDate", new int(OPimTodo::StartDate) ); |
141 | dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); | 144 | dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); |
142 | dict.insert("State", new int(OPimTodo::State) ); | 145 | dict.insert("State", new int(OPimTodo::State) ); |
143 | dict.insert("Alarms", new int(OPimTodo::Alarms) ); | 146 | dict.insert("Alarms", new int(OPimTodo::Alarms) ); |
144 | dict.insert("Reminders", new int(OPimTodo::Reminders) ); | 147 | dict.insert("Reminders", new int(OPimTodo::Reminders) ); |
145 | dict.insert("Notifiers", new int(OPimTodo::Notifiers) ); | ||
146 | dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); | 148 | dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); |
147 | dict.insert("rtype", new int(FRType) ); | 149 | dict.insert("rtype", new int(FRType) ); |
148 | dict.insert("rweekdays", new int(FRWeekdays) ); | 150 | dict.insert("rweekdays", new int(FRWeekdays) ); |
149 | dict.insert("rposition", new int(FRPosition) ); | 151 | dict.insert("rposition", new int(FRPosition) ); |
150 | dict.insert("rfreq", new int(FRFreq) ); | 152 | dict.insert("rfreq", new int(FRFreq) ); |
151 | dict.insert("start", new int(FRStart) ); | 153 | dict.insert("start", new int(FRStart) ); |
152 | dict.insert("rhasenddate", new int(FRHasEndDate) ); | 154 | dict.insert("rhasenddate", new int(FRHasEndDate) ); |
153 | dict.insert("enddt", new int(FREndDate) ); | 155 | dict.insert("enddt", new int(FREndDate) ); |
154 | 156 | ||
155 | // here the custom XML parser from TT it's GPL | 157 | // here the custom XML parser from TT it's GPL |
156 | // but we want to push OpiePIM... to TT..... | 158 | // but we want to push OpiePIM... to TT..... |
157 | // mmap part from zecke :) | 159 | // mmap part from zecke :) |
@@ -173,25 +175,24 @@ bool OPimTodoAccessXML::load() { | |||
173 | /* we do not the file any more */ | 175 | /* we do not the file any more */ |
174 | ::close( fd ); | 176 | ::close( fd ); |
175 | 177 | ||
176 | char* dt = (char*)map_addr; | 178 | char* dt = (char*)map_addr; |
177 | int len = attribut.st_size; | 179 | int len = attribut.st_size; |
178 | int i = 0; | 180 | int i = 0; |
179 | char *point; | 181 | char *point; |
180 | const char* collectionString = "<Task "; | 182 | const char* collectionString = "<Task "; |
181 | int strLen = strlen(collectionString); | 183 | int strLen = strlen(collectionString); |
182 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { | 184 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { |
183 | i = point -dt; | 185 | i = point -dt; |
184 | i+= strLen; | 186 | i+= strLen; |
185 | owarn << "Found a start at " << i << " " << (point-dt) << "" << oendl; | ||
186 | 187 | ||
187 | OPimTodo ev; | 188 | OPimTodo ev; |
188 | m_year = m_month = m_day = 0; | 189 | m_year = m_month = m_day = 0; |
189 | 190 | ||
190 | while ( TRUE ) { | 191 | while ( TRUE ) { |
191 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 192 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
192 | ++i; | 193 | ++i; |
193 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 194 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
194 | break; | 195 | break; |
195 | 196 | ||
196 | // we have another attribute, read it. | 197 | // we have another attribute, read it. |
197 | int j = i; | 198 | int j = i; |
@@ -229,58 +230,54 @@ bool OPimTodoAccessXML::load() { | |||
229 | if ( haveEnt ) | 230 | if ( haveEnt ) |
230 | str = Qtopia::plainString( str ); | 231 | str = Qtopia::plainString( str ); |
231 | 232 | ||
232 | /* | 233 | /* |
233 | * add key + value | 234 | * add key + value |
234 | */ | 235 | */ |
235 | todo( &dict, ev, attr, str ); | 236 | todo( &dict, ev, attr, str ); |
236 | 237 | ||
237 | } | 238 | } |
238 | /* | 239 | /* |
239 | * now add it | 240 | * now add it |
240 | */ | 241 | */ |
241 | owarn << "End at " << i << "" << oendl; | ||
242 | if (m_events.contains( ev.uid() ) || ev.uid() == 0) { | 242 | if (m_events.contains( ev.uid() ) || ev.uid() == 0) { |
243 | ev.setUid( 1 ); | 243 | ev.setUid( 1 ); |
244 | m_changed = true; | 244 | m_changed = true; |
245 | } | 245 | } |
246 | if ( ev.hasDueDate() ) { | 246 | if ( ev.hasDueDate() ) { |
247 | ev.setDueDate( QDate(m_year, m_month, m_day) ); | 247 | ev.setDueDate( QDate(m_year, m_month, m_day) ); |
248 | } | 248 | } |
249 | if ( rec && rec->doesRecur() ) { | 249 | if ( rec && rec->doesRecur() ) { |
250 | OPimTimeZone utc = OPimTimeZone::utc(); | 250 | OPimTimeZone utc = OPimTimeZone::utc(); |
251 | OPimRecurrence recu( *rec ); // call copy c'tor | 251 | OPimRecurrence recu( *rec ); // call copy c'tor |
252 | recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); | 252 | recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); |
253 | recu.setStart( ev.dueDate() ); | 253 | recu.setStart( ev.dueDate() ); |
254 | ev.setRecurrence( recu ); | 254 | ev.setRecurrence( recu ); |
255 | } | 255 | } |
256 | m_events.insert(ev.uid(), ev ); | 256 | m_events.insert(ev.uid(), ev ); |
257 | m_year = m_month = m_day = -1; | 257 | m_year = m_month = m_day = -1; |
258 | delete rec; | 258 | delete rec; |
259 | rec = 0; | 259 | rec = 0; |
260 | } | 260 | } |
261 | 261 | ||
262 | munmap(map_addr, attribut.st_size ); | 262 | munmap(map_addr, attribut.st_size ); |
263 | 263 | ||
264 | owarn << "counts " << m_events.count() << " records loaded!" << oendl; | ||
265 | return true; | 264 | return true; |
266 | } | 265 | } |
267 | bool OPimTodoAccessXML::reload() { | 266 | bool OPimTodoAccessXML::reload() { |
268 | m_events.clear(); | 267 | m_events.clear(); |
269 | return load(); | 268 | return load(); |
270 | } | 269 | } |
271 | bool OPimTodoAccessXML::save() { | 270 | bool OPimTodoAccessXML::save() { |
272 | // owarn << "saving" << oendl; | ||
273 | if (!m_opened || !m_changed ) { | 271 | if (!m_opened || !m_changed ) { |
274 | // owarn << "not saving" << oendl; | ||
275 | return true; | 272 | return true; |
276 | } | 273 | } |
277 | QString strNewFile = m_file + ".new"; | 274 | QString strNewFile = m_file + ".new"; |
278 | QFile f( strNewFile ); | 275 | QFile f( strNewFile ); |
279 | if (!f.open( IO_WriteOnly|IO_Raw ) ) | 276 | if (!f.open( IO_WriteOnly|IO_Raw ) ) |
280 | return false; | 277 | return false; |
281 | 278 | ||
282 | int written; | 279 | int written; |
283 | QString out; | 280 | QString out; |
284 | out = "<!DOCTYPE Tasks>\n<Tasks>\n"; | 281 | out = "<!DOCTYPE Tasks>\n<Tasks>\n"; |
285 | 282 | ||
286 | // for all todos | 283 | // for all todos |
@@ -303,128 +300,120 @@ bool OPimTodoAccessXML::save() { | |||
303 | QCString cstr = out.utf8(); | 300 | QCString cstr = out.utf8(); |
304 | written = f.writeBlock( cstr.data(), cstr.length() ); | 301 | written = f.writeBlock( cstr.data(), cstr.length() ); |
305 | 302 | ||
306 | if ( written != (int)cstr.length() ) { | 303 | if ( written != (int)cstr.length() ) { |
307 | f.close(); | 304 | f.close(); |
308 | QFile::remove( strNewFile ); | 305 | QFile::remove( strNewFile ); |
309 | return false; | 306 | return false; |
310 | } | 307 | } |
311 | /* flush before renaming */ | 308 | /* flush before renaming */ |
312 | f.close(); | 309 | f.close(); |
313 | 310 | ||
314 | if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { | 311 | if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { |
315 | // owarn << "error renaming" << oendl; | ||
316 | QFile::remove( strNewFile ); | 312 | QFile::remove( strNewFile ); |
317 | } | 313 | } |
318 | 314 | ||
319 | m_changed = false; | 315 | m_changed = false; |
320 | return true; | 316 | return true; |
321 | } | 317 | } |
322 | QArray<int> OPimTodoAccessXML::allRecords()const { | 318 | QArray<int> OPimTodoAccessXML::allRecords()const { |
323 | QArray<int> ids( m_events.count() ); | 319 | QArray<int> ids( m_events.count() ); |
324 | QMap<int, OPimTodo>::ConstIterator it; | 320 | QMap<int, OPimTodo>::ConstIterator it; |
325 | int i = 0; | 321 | int i = 0; |
326 | 322 | ||
327 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 323 | for ( it = m_events.begin(); it != m_events.end(); ++it ) |
328 | ids[i] = it.key(); | 324 | ids[i++] = it.key(); |
329 | i++; | 325 | |
330 | } | 326 | |
331 | return ids; | 327 | return ids; |
332 | } | 328 | } |
333 | QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { | 329 | QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { |
334 | QArray<int> ids(0); | 330 | QArray<int> ids(0); |
335 | return ids; | 331 | return ids; |
336 | } | 332 | } |
337 | OPimTodo OPimTodoAccessXML::find( int uid )const { | 333 | OPimTodo OPimTodoAccessXML::find( int uid )const { |
338 | OPimTodo todo; | 334 | OPimTodo todo; |
339 | todo.setUid( 0 ); // isEmpty() | 335 | todo.setUid( 0 ); // isEmpty() |
340 | QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); | 336 | QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); |
341 | if ( it != m_events.end() ) | 337 | if ( it != m_events.end() ) |
342 | todo = it.data(); | 338 | todo = it.data(); |
343 | 339 | ||
344 | return todo; | 340 | return todo; |
345 | } | 341 | } |
346 | void OPimTodoAccessXML::clear() { | 342 | void OPimTodoAccessXML::clear() { |
347 | if (m_opened ) | 343 | if (m_opened ) |
348 | m_changed = true; | 344 | m_changed = true; |
349 | 345 | ||
350 | m_events.clear(); | 346 | m_events.clear(); |
351 | } | 347 | } |
352 | bool OPimTodoAccessXML::add( const OPimTodo& todo ) { | 348 | bool OPimTodoAccessXML::add( const OPimTodo& todo ) { |
353 | // owarn << "add" << oendl; | ||
354 | m_changed = true; | 349 | m_changed = true; |
355 | m_events.insert( todo.uid(), todo ); | 350 | m_events.insert( todo.uid(), todo ); |
356 | 351 | ||
357 | return true; | 352 | return true; |
358 | } | 353 | } |
359 | bool OPimTodoAccessXML::remove( int uid ) { | 354 | bool OPimTodoAccessXML::remove( int uid ) { |
360 | m_changed = true; | 355 | m_changed = true; |
361 | m_events.remove( uid ); | 356 | m_events.remove( uid ); |
362 | 357 | ||
363 | return true; | 358 | return true; |
364 | } | 359 | } |
365 | bool OPimTodoAccessXML::replace( const OPimTodo& todo) { | 360 | bool OPimTodoAccessXML::replace( const OPimTodo& todo) { |
366 | m_changed = true; | 361 | m_changed = true; |
367 | m_events.replace( todo.uid(), todo ); | 362 | m_events.replace( todo.uid(), todo ); |
368 | 363 | ||
369 | return true; | 364 | return true; |
370 | } | 365 | } |
371 | QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, | 366 | QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, |
372 | const QDate& end, | 367 | const QDate& end, |
373 | bool includeNoDates ) { | 368 | bool includeNoDates )const { |
374 | QArray<int> ids( m_events.count() ); | 369 | QArray<int> ids( m_events.count() ); |
375 | QMap<int, OPimTodo>::Iterator it; | 370 | QMap<int, OPimTodo>::ConstIterator it; |
376 | 371 | ||
377 | int i = 0; | 372 | int i = 0; |
378 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 373 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
379 | if ( !it.data().hasDueDate() ) { | 374 | if ( !it.data().hasDueDate() && includeNoDates) { |
380 | if ( includeNoDates ) { | 375 | ids[i++] = it.key(); |
381 | ids[i] = it.key(); | ||
382 | i++; | ||
383 | } | ||
384 | }else if ( it.data().dueDate() >= start && | 376 | }else if ( it.data().dueDate() >= start && |
385 | it.data().dueDate() <= end ) { | 377 | it.data().dueDate() <= end ) { |
386 | ids[i] = it.key(); | 378 | ids[i++] = it.key(); |
387 | i++; | ||
388 | } | 379 | } |
389 | } | 380 | } |
390 | ids.resize( i ); | 381 | ids.resize( i ); |
391 | return ids; | 382 | return ids; |
392 | } | 383 | } |
393 | QArray<int> OPimTodoAccessXML::overDue() { | 384 | QArray<int> OPimTodoAccessXML::overDue()const { |
394 | QArray<int> ids( m_events.count() ); | 385 | QArray<int> ids( m_events.count() ); |
395 | int i = 0; | 386 | int i = 0; |
396 | 387 | ||
397 | QMap<int, OPimTodo>::Iterator it; | 388 | QMap<int, OPimTodo>::ConstIterator it; |
398 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | 389 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { |
399 | if ( it.data().isOverdue() ) { | 390 | if ( it.data().isOverdue() ) { |
400 | ids[i] = it.key(); | 391 | ids[i] = it.key(); |
401 | i++; | 392 | i++; |
402 | } | 393 | } |
403 | } | 394 | } |
404 | ids.resize( i ); | 395 | ids.resize( i ); |
405 | return ids; | 396 | return ids; |
406 | } | 397 | } |
407 | 398 | ||
408 | 399 | ||
409 | /* private */ | 400 | /* private */ |
410 | void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, | 401 | void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, |
411 | const QCString& attr, const QString& val) { | 402 | const QCString& attr, const QString& val) { |
412 | // owarn << "parse to do from XMLElement" << oendl; | ||
413 | 403 | ||
414 | int *find=0; | 404 | int *find=0; |
415 | 405 | ||
416 | find = (*dict)[ attr.data() ]; | 406 | find = (*dict)[ attr.data() ]; |
417 | if (!find ) { | 407 | if (!find ) { |
418 | // owarn << "Unknown option" + it.key() << oendl; | ||
419 | ev.setCustomField( attr, val ); | 408 | ev.setCustomField( attr, val ); |
420 | return; | 409 | return; |
421 | } | 410 | } |
422 | 411 | ||
423 | switch( *find ) { | 412 | switch( *find ) { |
424 | case OPimTodo::Uid: | 413 | case OPimTodo::Uid: |
425 | ev.setUid( val.toInt() ); | 414 | ev.setUid( val.toInt() ); |
426 | break; | 415 | break; |
427 | case OPimTodo::Category: | 416 | case OPimTodo::Category: |
428 | ev.setCategories( ev.idsFromString( val ) ); | 417 | ev.setCategories( ev.idsFromString( val ) ); |
429 | break; | 418 | break; |
430 | case OPimTodo::HasDate: | 419 | case OPimTodo::HasDate: |
@@ -459,26 +448,24 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, | |||
459 | break; | 448 | break; |
460 | case OPimTodo::StartDate: | 449 | case OPimTodo::StartDate: |
461 | ev.setStartDate( OPimDateConversion::dateFromString( val ) ); | 450 | ev.setStartDate( OPimDateConversion::dateFromString( val ) ); |
462 | break; | 451 | break; |
463 | case OPimTodo::State: | 452 | case OPimTodo::State: |
464 | ev.setState( val.toInt() ); | 453 | ev.setState( val.toInt() ); |
465 | break; | 454 | break; |
466 | case OPimTodo::Alarms:{ | 455 | case OPimTodo::Alarms:{ |
467 | OPimNotifyManager &manager = ev.notifiers(); | 456 | OPimNotifyManager &manager = ev.notifiers(); |
468 | QStringList als = QStringList::split(";", val ); | 457 | QStringList als = QStringList::split(";", val ); |
469 | for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { | 458 | for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { |
470 | QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty | 459 | QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty |
471 | owarn << "alarm: " << alarm.join("___") << "" << oendl; | ||
472 | owarn << "alarm[0]: " << alarm[0] << " " << OPimDateConversion::dateTimeFromString( alarm[0] ).toString() << "" << oendl; | ||
473 | OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); | 460 | OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); |
474 | manager.add( al ); | 461 | manager.add( al ); |
475 | } | 462 | } |
476 | } | 463 | } |
477 | break; | 464 | break; |
478 | case OPimTodo::Reminders:{ | 465 | case OPimTodo::Reminders:{ |
479 | OPimNotifyManager &manager = ev.notifiers(); | 466 | OPimNotifyManager &manager = ev.notifiers(); |
480 | QStringList rems = QStringList::split(";", val ); | 467 | QStringList rems = QStringList::split(";", val ); |
481 | for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { | 468 | for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { |
482 | OPimReminder rem( (*it).toInt() ); | 469 | OPimReminder rem( (*it).toInt() ); |
483 | manager.add( rem ); | 470 | manager.add( rem ); |
484 | } | 471 | } |
@@ -533,29 +520,27 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, | |||
533 | break; | 520 | break; |
534 | } | 521 | } |
535 | default: | 522 | default: |
536 | ev.setCustomField( attr, val ); | 523 | ev.setCustomField( attr, val ); |
537 | break; | 524 | break; |
538 | } | 525 | } |
539 | } | 526 | } |
540 | 527 | ||
541 | // from PalmtopRecord... GPL ### FIXME | 528 | // from PalmtopRecord... GPL ### FIXME |
542 | namespace { | 529 | namespace { |
543 | QString customToXml(const QMap<QString, QString>& customMap ) | 530 | QString customToXml(const QMap<QString, QString>& customMap ) |
544 | { | 531 | { |
545 | //owarn << QString("writing custom %1").arg(customMap.count()) << oendl; | ||
546 | QString buf(" "); | 532 | QString buf(" "); |
547 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); | 533 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); |
548 | cit != customMap.end(); ++cit) { | 534 | cit != customMap.end(); ++cit) { |
549 | // owarn << ".ITEM." << oendl; | ||
550 | buf += cit.key(); | 535 | buf += cit.key(); |
551 | buf += "=\""; | 536 | buf += "=\""; |
552 | buf += Qtopia::escapeString(cit.data()); | 537 | buf += Qtopia::escapeString(cit.data()); |
553 | buf += "\" "; | 538 | buf += "\" "; |
554 | } | 539 | } |
555 | return buf; | 540 | return buf; |
556 | } | 541 | } |
557 | 542 | ||
558 | 543 | ||
559 | } | 544 | } |
560 | 545 | ||
561 | QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { | 546 | QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { |
@@ -566,25 +551,24 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { | |||
566 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; | 551 | str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; |
567 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; | 552 | str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; |
568 | 553 | ||
569 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; | 554 | str += "Categories=\"" + toString( ev.categories() ) + "\" "; |
570 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; | 555 | str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; |
571 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; | 556 | str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; |
572 | 557 | ||
573 | if ( ev.hasDueDate() ) { | 558 | if ( ev.hasDueDate() ) { |
574 | str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; | 559 | str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; |
575 | str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; | 560 | str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; |
576 | str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; | 561 | str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; |
577 | } | 562 | } |
578 | // owarn << "Uid " << ev.uid() << "" << oendl; | ||
579 | str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; | 563 | str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; |
580 | 564 | ||
581 | // append the extra options | 565 | // append the extra options |
582 | /* FIXME Qtopia::Record this is currently not | 566 | /* FIXME Qtopia::Record this is currently not |
583 | * possible you can set custom fields | 567 | * possible you can set custom fields |
584 | * but don' iterate over the list | 568 | * but don' iterate over the list |
585 | * I may do #define private protected | 569 | * I may do #define private protected |
586 | * for this case - cough --zecke | 570 | * for this case - cough --zecke |
587 | */ | 571 | */ |
588 | /* | 572 | /* |
589 | QMap<QString, QString> extras = ev.extras(); | 573 | QMap<QString, QString> extras = ev.extras(); |
590 | QMap<QString, QString>::Iterator extIt; | 574 | QMap<QString, QString>::Iterator extIt; |
@@ -613,25 +597,24 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { | |||
613 | QStringList als; | 597 | QStringList als; |
614 | OPimNotifyManager::Alarms::Iterator it = alarms.begin(); | 598 | OPimNotifyManager::Alarms::Iterator it = alarms.begin(); |
615 | for ( ; it != alarms.end(); ++it ) { | 599 | for ( ; it != alarms.end(); ++it ) { |
616 | /* only if time is valid */ | 600 | /* only if time is valid */ |
617 | if ( (*it).dateTime().isValid() ) { | 601 | if ( (*it).dateTime().isValid() ) { |
618 | als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) | 602 | als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) |
619 | + ":" + QString::number( (*it).duration() ) | 603 | + ":" + QString::number( (*it).duration() ) |
620 | + ":" + QString::number( (*it).sound() ) | 604 | + ":" + QString::number( (*it).sound() ) |
621 | + ":"; | 605 | + ":"; |
622 | } | 606 | } |
623 | } | 607 | } |
624 | // now write the list | 608 | // now write the list |
625 | owarn << "als: " << als.join("____________") << "" << oendl; | ||
626 | str += "Alarms=\""+als.join(";") +"\" "; | 609 | str += "Alarms=\""+als.join(";") +"\" "; |
627 | } | 610 | } |
628 | 611 | ||
629 | /* | 612 | /* |
630 | * now the same for reminders but more easy. We just save the uid of the OPimEvent. | 613 | * now the same for reminders but more easy. We just save the uid of the OPimEvent. |
631 | */ | 614 | */ |
632 | OPimNotifyManager::Reminders reminders = manager.reminders(); | 615 | OPimNotifyManager::Reminders reminders = manager.reminders(); |
633 | if (!reminders.isEmpty() ) { | 616 | if (!reminders.isEmpty() ) { |
634 | OPimNotifyManager::Reminders::Iterator it = reminders.begin(); | 617 | OPimNotifyManager::Reminders::Iterator it = reminders.begin(); |
635 | QStringList records; | 618 | QStringList records; |
636 | for ( ; it != reminders.end(); ++it ) { | 619 | for ( ; it != reminders.end(); ++it ) { |
637 | records << QString::number( (*it).recordUid() ); | 620 | records << QString::number( (*it).recordUid() ); |
@@ -639,276 +622,99 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { | |||
639 | str += "Reminders=\""+ records.join(";") +"\" "; | 622 | str += "Reminders=\""+ records.join(";") +"\" "; |
640 | } | 623 | } |
641 | } | 624 | } |
642 | str += customToXml( ev.toExtraMap() ); | 625 | str += customToXml( ev.toExtraMap() ); |
643 | 626 | ||
644 | 627 | ||
645 | return str; | 628 | return str; |
646 | } | 629 | } |
647 | QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { | 630 | QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { |
648 | return Qtopia::Record::idsToString( ints ); | 631 | return Qtopia::Record::idsToString( ints ); |
649 | } | 632 | } |
650 | 633 | ||
651 | /* internal class for sorting | ||
652 | * | ||
653 | * Inspired by todoxmlio.cpp from TT | ||
654 | */ | ||
655 | 634 | ||
656 | struct OPimTodoXMLContainer { | 635 | QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc, |
657 | OPimTodo todo; | 636 | int sortOrder,int sortFilter, |
658 | }; | 637 | const QArray<int>& categories )const { |
638 | Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder ); | ||
639 | int item = 0; | ||
659 | 640 | ||
660 | namespace { | 641 | bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false; |
661 | inline QString string( const OPimTodo& todo) { | 642 | bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false; |
662 | return todo.summary().isEmpty() ? | 643 | bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false; |
663 | todo.description().left(20 ) : | 644 | bool catPassed = false; |
664 | todo.summary(); | 645 | int cat; |
665 | } | ||
666 | inline int completed( const OPimTodo& todo1, const OPimTodo& todo2) { | ||
667 | int ret = 0; | ||
668 | if ( todo1.isCompleted() ) ret++; | ||
669 | if ( todo2.isCompleted() ) ret--; | ||
670 | return ret; | ||
671 | } | ||
672 | inline int priority( const OPimTodo& t1, const OPimTodo& t2) { | ||
673 | return ( t1.priority() - t2.priority() ); | ||
674 | } | ||
675 | inline int description( const OPimTodo& t1, const OPimTodo& t2) { | ||
676 | return QString::compare( string(t1), string(t2) ); | ||
677 | } | ||
678 | inline int deadline( const OPimTodo& t1, const OPimTodo& t2) { | ||
679 | int ret = 0; | ||
680 | if ( t1.hasDueDate() && | ||
681 | t2.hasDueDate() ) | ||
682 | ret = t2.dueDate().daysTo( t1.dueDate() ); | ||
683 | else if ( t1.hasDueDate() ) | ||
684 | ret = -1; | ||
685 | else if ( t2.hasDueDate() ) | ||
686 | ret = 1; | ||
687 | else | ||
688 | ret = 0; | ||
689 | 646 | ||
690 | return ret; | 647 | for ( uint i = 0; i < events.count(); ++i ) { |
691 | } | 648 | /* Guard against creating a new item... */ |
649 | if ( !m_events.contains( events[i] ) ) | ||
650 | continue; | ||
692 | 651 | ||
693 | }; | 652 | OPimTodo todo = m_events[events[i]]; |
694 | 653 | ||
695 | /* | 654 | /* show category */ |
696 | * Returns: | 655 | /* -1 == unfiled */ |
697 | * 0 if item1 == item2 | 656 | catPassed = false; |
698 | * | 657 | for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) { |
699 | * non-zero if item1 != item2 | 658 | cat = categories[cat_nu]; |
700 | * | 659 | if ( bCat && cat == -1 ) { |
701 | * This function returns int rather than bool so that reimplementations | 660 | if(!todo.categories().isEmpty() ) |
702 | * can return one of three values and use it to sort by: | 661 | continue; |
703 | * | 662 | } else if ( bCat && cat != 0) |
704 | * 0 if item1 == item2 | 663 | if (!todo.categories().contains( cat ) ) |
705 | * | 664 | continue; |
706 | * > 0 (positive integer) if item1 > item2 | 665 | catPassed = true; |
707 | * | ||
708 | * < 0 (negative integer) if item1 < item2 | ||
709 | * | ||
710 | */ | ||
711 | class OPimTodoXMLVector : public QVector<OPimTodoXMLContainer> { | ||
712 | public: | ||
713 | OPimTodoXMLVector(int size, bool asc, int sort) | ||
714 | : QVector<OPimTodoXMLContainer>( size ) | ||
715 | { | ||
716 | setAutoDelete( true ); | ||
717 | m_asc = asc; | ||
718 | m_sort = sort; | ||
719 | } | ||
720 | /* return the summary/description */ | ||
721 | QString string( const OPimTodo& todo) { | ||
722 | return todo.summary().isEmpty() ? | ||
723 | todo.description().left(20 ) : | ||
724 | todo.summary(); | ||
725 | } | ||
726 | /** | ||
727 | * we take the sortorder( switch on it ) | ||
728 | * | ||
729 | */ | ||
730 | int compareItems( Item d1, Item d2 ) { | ||
731 | bool seComp, sePrio, seDesc, seDeadline; | ||
732 | seComp = sePrio = seDeadline = seDesc = false; | ||
733 | int ret =0; | ||
734 | OPimTodoXMLContainer* con1 = (OPimTodoXMLContainer*)d1; | ||
735 | OPimTodoXMLContainer* con2 = (OPimTodoXMLContainer*)d2; | ||
736 | |||
737 | /* same item */ | ||
738 | if ( con1->todo.uid() == con2->todo.uid() ) | ||
739 | return 0; | ||
740 | |||
741 | switch ( m_sort ) { | ||
742 | /* completed */ | ||
743 | case 0: { | ||
744 | ret = completed( con1->todo, con2->todo ); | ||
745 | seComp = TRUE; | ||
746 | break; | ||
747 | } | ||
748 | /* priority */ | ||
749 | case 1: { | ||
750 | ret = priority( con1->todo, con2->todo ); | ||
751 | sePrio = TRUE; | ||
752 | break; | ||
753 | } | ||
754 | /* description */ | ||
755 | case 2: { | ||
756 | ret = description( con1->todo, con2->todo ); | ||
757 | seDesc = TRUE; | ||
758 | break; | ||
759 | } | ||
760 | /* deadline */ | ||
761 | case 3: { | ||
762 | ret = deadline( con1->todo, con2->todo ); | ||
763 | seDeadline = TRUE; | ||
764 | break; | 666 | break; |
765 | } | 667 | } |
766 | default: | ||
767 | ret = 0; | ||
768 | break; | ||
769 | }; | ||
770 | /* | ||
771 | * FIXME do better sorting if the first sort criteria | ||
772 | * ret equals 0 start with complete and so on... | ||
773 | */ | ||
774 | |||
775 | /* twist it we're not ascending*/ | ||
776 | if (!m_asc) | ||
777 | ret = ret * -1; | ||
778 | 668 | ||
779 | if ( ret ) | ||
780 | return ret; | ||
781 | |||
782 | // default did not gave difference let's try it other way around | ||
783 | /* | 669 | /* |
784 | * General try if already checked if not test | 670 | * If none of the Categories matched |
785 | * and return | 671 | * continue |
786 | * 1.Completed | ||
787 | * 2.Priority | ||
788 | * 3.Description | ||
789 | * 4.DueDate | ||
790 | */ | 672 | */ |
791 | if (!seComp ) { | 673 | if ( !catPassed ) |
792 | if ( (ret = completed( con1->todo, con2->todo ) ) ) { | ||
793 | if (!m_asc ) ret *= -1; | ||
794 | return ret; | ||
795 | } | ||
796 | } | ||
797 | if (!sePrio ) { | ||
798 | if ( (ret = priority( con1->todo, con2->todo ) ) ) { | ||
799 | if (!m_asc ) ret *= -1; | ||
800 | return ret; | ||
801 | } | ||
802 | } | ||
803 | if (!seDesc ) { | ||
804 | if ( (ret = description(con1->todo, con2->todo ) ) ) { | ||
805 | if (!m_asc) ret *= -1; | ||
806 | return ret; | ||
807 | } | ||
808 | } | ||
809 | if (!seDeadline) { | ||
810 | if ( (ret = deadline( con1->todo, con2->todo ) ) ) { | ||
811 | if (!m_asc) ret *= -1; | ||
812 | return ret; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | } | ||
818 | private: | ||
819 | bool m_asc; | ||
820 | int m_sort; | ||
821 | |||
822 | }; | ||
823 | |||
824 | QArray<int> OPimTodoAccessXML::sorted( bool asc, int sortOrder, | ||
825 | int sortFilter, int cat ) { | ||
826 | OPimTodoXMLVector vector(m_events.count(), asc,sortOrder ); | ||
827 | QMap<int, OPimTodo>::Iterator it; | ||
828 | int item = 0; | ||
829 | |||
830 | bool bCat = sortFilter & 1 ? true : false; | ||
831 | bool bOnly = sortFilter & 2 ? true : false; | ||
832 | bool comp = sortFilter & 4 ? true : false; | ||
833 | for ( it = m_events.begin(); it != m_events.end(); ++it ) { | ||
834 | |||
835 | /* show category */ | ||
836 | /* -1 == unfiled */ | ||
837 | if ( bCat && cat == -1 ) { | ||
838 | if(!(*it).categories().isEmpty() ) | ||
839 | continue; | ||
840 | }else if ( bCat && cat != 0) | ||
841 | if (!(*it).categories().contains( cat ) ) { | ||
842 | continue; | ||
843 | } | ||
844 | /* isOverdue but we should not show overdue - why?*/ | ||
845 | /* if ( (*it).isOverdue() && !bOnly ) { | ||
846 | owarn << "item is overdue but !bOnly" << oendl; | ||
847 | continue; | 674 | continue; |
848 | } | 675 | if ( !todo.isOverdue() && bOnly ) |
849 | */ | ||
850 | if ( !(*it).isOverdue() && bOnly ) { | ||
851 | continue; | 676 | continue; |
852 | } | 677 | if (todo.isCompleted() && comp ) |
853 | |||
854 | if ((*it).isCompleted() && comp ) { | ||
855 | continue; | 678 | continue; |
856 | } | ||
857 | 679 | ||
858 | 680 | vector.insert(item++, todo ); | |
859 | OPimTodoXMLContainer* con = new OPimTodoXMLContainer(); | ||
860 | con->todo = (*it); | ||
861 | vector.insert(item, con ); | ||
862 | item++; | ||
863 | } | 681 | } |
682 | |||
864 | vector.resize( item ); | 683 | vector.resize( item ); |
865 | /* sort it now */ | 684 | /* sort it now */ |
866 | vector.sort(); | 685 | vector.sort(); |
867 | /* now get the uids */ | 686 | /* now get the uids */ |
868 | QArray<int> array( vector.count() ); | 687 | UIDArray array( vector.count() ); |
869 | for (uint i= 0; i < vector.count(); i++ ) { | 688 | for (uint i= 0; i < vector.count(); i++ ) |
870 | array[i] = ( vector.at(i) )->todo.uid(); | 689 | array[i] = vector.uidAt( i ); |
871 | } | 690 | |
872 | return array; | 691 | return array; |
873 | }; | 692 | } |
693 | |||
874 | void OPimTodoAccessXML::removeAllCompleted() { | 694 | void OPimTodoAccessXML::removeAllCompleted() { |
875 | QMap<int, OPimTodo> events = m_events; | 695 | QMap<int, OPimTodo> events = m_events; |
876 | for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { | 696 | for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { |
877 | if ( (*it).isCompleted() ) | 697 | if ( (*it).isCompleted() ) |
878 | events.remove( it.key() ); | 698 | events.remove( it.key() ); |
879 | } | 699 | } |
880 | m_events = events; | 700 | m_events = events; |
881 | } | 701 | } |
882 | QBitArray OPimTodoAccessXML::supports()const { | 702 | |
883 | static QBitArray ar = sup(); | ||
884 | return ar; | ||
885 | } | ||
886 | QBitArray OPimTodoAccessXML::sup() { | ||
887 | QBitArray ar( OPimTodo::CompletedDate +1 ); | ||
888 | ar.fill( true ); | ||
889 | ar[OPimTodo::CrossReference] = false; | ||
890 | ar[OPimTodo::State ] = false; | ||
891 | ar[OPimTodo::Reminders] = false; | ||
892 | ar[OPimTodo::Notifiers] = false; | ||
893 | ar[OPimTodo::Maintainer] = false; | ||
894 | |||
895 | return ar; | ||
896 | } | ||
897 | QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const | 703 | QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const |
898 | { | 704 | { |
899 | QArray<int> m_currentQuery( m_events.count() ); | 705 | QArray<int> currentQuery( m_events.count() ); |
900 | uint arraycounter = 0; | 706 | uint arraycounter = 0; |
901 | 707 | ||
902 | QMap<int, OPimTodo>::ConstIterator it; | 708 | QMap<int, OPimTodo>::ConstIterator it; |
903 | for (it = m_events.begin(); it != m_events.end(); ++it ) { | 709 | for (it = m_events.begin(); it != m_events.end(); ++it ) { |
904 | if ( it.data().match( r ) ) | 710 | if ( it.data().match( r ) ) |
905 | m_currentQuery[arraycounter++] = it.data().uid(); | 711 | currentQuery[arraycounter++] = it.data().uid(); |
906 | 712 | ||
907 | } | 713 | } |
908 | // Shrink to fit.. | 714 | // Shrink to fit.. |
909 | m_currentQuery.resize(arraycounter); | 715 | currentQuery.resize(arraycounter); |
910 | 716 | ||
911 | return m_currentQuery; | 717 | return currentQuery; |
912 | } | 718 | } |
913 | 719 | ||
914 | } | 720 | } |