summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp22
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp22
2 files changed, 44 insertions, 0 deletions
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 661cd51..097142b 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -1,147 +1,150 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.6 2003/07/07 16:19:47 eilers
21 * Fixing serious bug in hasQuerySettings()
22 *
20 * Revision 1.5 2003/04/13 18:07:10 zecke 23 * Revision 1.5 2003/04/13 18:07:10 zecke
21 * More API doc 24 * More API doc
22 * QString -> const QString& 25 * QString -> const QString&
23 * QString = 0l -> QString::null 26 * QString = 0l -> QString::null
24 * 27 *
25 * Revision 1.4 2003/03/21 14:32:54 mickeyl 28 * Revision 1.4 2003/03/21 14:32:54 mickeyl
26 * g++ compliance fix: default arguments belong into the declaration, but not the definition 29 * g++ compliance fix: default arguments belong into the declaration, but not the definition
27 * 30 *
28 * Revision 1.3 2003/03/21 12:26:28 eilers 31 * Revision 1.3 2003/03/21 12:26:28 eilers
29 * Fixing small bug: If we search a birthday from today to today, it returned 32 * Fixing small bug: If we search a birthday from today to today, it returned
30 * every contact .. 33 * every contact ..
31 * 34 *
32 * Revision 1.2 2003/03/21 10:33:09 eilers 35 * Revision 1.2 2003/03/21 10:33:09 eilers
33 * Merged speed optimized xml backend for contacts to main. 36 * Merged speed optimized xml backend for contacts to main.
34 * Added QDateTime to querybyexample. For instance, it is now possible to get 37 * Added QDateTime to querybyexample. For instance, it is now possible to get
35 * all Birthdays/Anniversaries between two dates. This should be used 38 * all Birthdays/Anniversaries between two dates. This should be used
36 * to show all birthdays in the datebook.. 39 * to show all birthdays in the datebook..
37 * This change is sourcecode backward compatible but you have to upgrade 40 * This change is sourcecode backward compatible but you have to upgrade
38 * the binaries for today-addressbook. 41 * the binaries for today-addressbook.
39 * 42 *
40 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 43 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
41 * Speed optimization. Removed the sequential search loops. 44 * Speed optimization. Removed the sequential search loops.
42 * 45 *
43 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 46 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
44 * Writing offsets to debug output.. 47 * Writing offsets to debug output..
45 * 48 *
46 * Revision 1.1 2003/02/09 15:05:01 eilers 49 * Revision 1.1 2003/02/09 15:05:01 eilers
47 * Nothing happened.. Just some cleanup before I will start.. 50 * Nothing happened.. Just some cleanup before I will start..
48 * 51 *
49 * Revision 1.12 2003/01/03 16:58:03 eilers 52 * Revision 1.12 2003/01/03 16:58:03 eilers
50 * Reenable debug output 53 * Reenable debug output
51 * 54 *
52 * Revision 1.11 2003/01/03 12:31:28 eilers 55 * Revision 1.11 2003/01/03 12:31:28 eilers
53 * Bugfix for calculating data diffs.. 56 * Bugfix for calculating data diffs..
54 * 57 *
55 * Revision 1.10 2003/01/02 14:27:12 eilers 58 * Revision 1.10 2003/01/02 14:27:12 eilers
56 * Improved query by example: Search by date is possible.. First step 59 * Improved query by example: Search by date is possible.. First step
57 * for a today plugin for birthdays.. 60 * for a today plugin for birthdays..
58 * 61 *
59 * Revision 1.9 2002/12/08 12:48:57 eilers 62 * Revision 1.9 2002/12/08 12:48:57 eilers
60 * Moved journal-enum from ocontact into i the xml-backend.. 63 * Moved journal-enum from ocontact into i the xml-backend..
61 * 64 *
62 * Revision 1.8 2002/11/14 17:04:24 eilers 65 * Revision 1.8 2002/11/14 17:04:24 eilers
63 * Sorting will now work if fullname is identical on some entries 66 * Sorting will now work if fullname is identical on some entries
64 * 67 *
65 * Revision 1.7 2002/11/13 15:02:46 eilers 68 * Revision 1.7 2002/11/13 15:02:46 eilers
66 * Small Bug in sorted fixed 69 * Small Bug in sorted fixed
67 * 70 *
68 * Revision 1.6 2002/11/13 14:14:51 eilers 71 * Revision 1.6 2002/11/13 14:14:51 eilers
69 * Added sorted for Contacts.. 72 * Added sorted for Contacts..
70 * 73 *
71 * Revision 1.5 2002/11/01 15:10:42 eilers 74 * Revision 1.5 2002/11/01 15:10:42 eilers
72 * Added regExp-search in database for all fields in a contact. 75 * Added regExp-search in database for all fields in a contact.
73 * 76 *
74 * Revision 1.4 2002/10/16 10:52:40 eilers 77 * Revision 1.4 2002/10/16 10:52:40 eilers
75 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 78 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
76 * 79 *
77 * Revision 1.3 2002/10/14 16:21:54 eilers 80 * Revision 1.3 2002/10/14 16:21:54 eilers
78 * Some minor interface updates 81 * Some minor interface updates
79 * 82 *
80 * Revision 1.2 2002/10/07 17:34:24 eilers 83 * Revision 1.2 2002/10/07 17:34:24 eilers
81 * added OBackendFactory for advanced backend access 84 * added OBackendFactory for advanced backend access
82 * 85 *
83 * Revision 1.1 2002/09/27 17:11:44 eilers 86 * Revision 1.1 2002/09/27 17:11:44 eilers
84 * Added API for accessing the Contact-Database ! It is compiling, but 87 * Added API for accessing the Contact-Database ! It is compiling, but
85 * please do not expect that anything is working ! 88 * please do not expect that anything is working !
86 * I will debug that stuff in the next time .. 89 * I will debug that stuff in the next time ..
87 * Please read README_COMPILE for compiling ! 90 * Please read README_COMPILE for compiling !
88 * 91 *
89 * 92 *
90 */ 93 */
91 94
92#include "ocontactaccessbackend_xml.h" 95#include "ocontactaccessbackend_xml.h"
93 96
94#include <qasciidict.h> 97#include <qasciidict.h>
95#include <qdatetime.h> 98#include <qdatetime.h>
96#include <qfile.h> 99#include <qfile.h>
97#include <qfileinfo.h> 100#include <qfileinfo.h>
98#include <qregexp.h> 101#include <qregexp.h>
99#include <qarray.h> 102#include <qarray.h>
100#include <qmap.h> 103#include <qmap.h>
101#include <qdatetime.h> 104#include <qdatetime.h>
102 105
103#include <qpe/global.h> 106#include <qpe/global.h>
104 107
105#include <opie/xmltree.h> 108#include <opie/xmltree.h>
106#include "ocontactaccessbackend.h" 109#include "ocontactaccessbackend.h"
107#include "ocontactaccess.h" 110#include "ocontactaccess.h"
108 111
109#include <stdlib.h> 112#include <stdlib.h>
110#include <errno.h> 113#include <errno.h>
111 114
112using namespace Opie; 115using namespace Opie;
113 116
114 117
115OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): 118OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ):
116 m_changed( false ) 119 m_changed( false )
117{ 120{
118 // Just m_contactlist should call delete if an entry 121 // Just m_contactlist should call delete if an entry
119 // is removed. 122 // is removed.
120 m_contactList.setAutoDelete( true ); 123 m_contactList.setAutoDelete( true );
121 m_uidToContact.setAutoDelete( false ); 124 m_uidToContact.setAutoDelete( false );
122 125
123 m_appName = appname; 126 m_appName = appname;
124 127
125 /* Set journalfile name ... */ 128 /* Set journalfile name ... */
126 m_journalName = getenv("HOME"); 129 m_journalName = getenv("HOME");
127 m_journalName +="/.abjournal" + appname; 130 m_journalName +="/.abjournal" + appname;
128 131
129 /* Expecting to access the default filename if nothing else is set */ 132 /* Expecting to access the default filename if nothing else is set */
130 if ( filename.isEmpty() ){ 133 if ( filename.isEmpty() ){
131 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 134 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
132 } else 135 } else
133 m_fileName = filename; 136 m_fileName = filename;
134 137
135 /* Load Database now */ 138 /* Load Database now */
136 load (); 139 load ();
137} 140}
138 141
139bool OContactAccessBackend_XML::save() 142bool OContactAccessBackend_XML::save()
140{ 143{
141 144
142 if ( !m_changed ) 145 if ( !m_changed )
143 return true; 146 return true;
144 147
145 QString strNewFile = m_fileName + ".new"; 148 QString strNewFile = m_fileName + ".new";
146 QFile f( strNewFile ); 149 QFile f( strNewFile );
147 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 150 if ( !f.open( IO_WriteOnly|IO_Raw ) )
@@ -322,272 +325,291 @@ QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, i
322 325
323 // We have to equalize the year, otherwise 326 // We have to equalize the year, otherwise
324 // the search will fail.. 327 // the search will fail..
325 checkDate->setYMD( current.year(), 328 checkDate->setYMD( current.year(),
326 checkDate->month(), 329 checkDate->month(),
327 checkDate->day() ); 330 checkDate->day() );
328 if ( *checkDate < current ) 331 if ( *checkDate < current )
329 checkDate->setYMD( current.year()+1, 332 checkDate->setYMD( current.year()+1,
330 checkDate->month(), 333 checkDate->month(),
331 checkDate->day() ); 334 checkDate->day() );
332 335
333 // Check whether the birthday/anniversary date is between 336 // Check whether the birthday/anniversary date is between
334 // the current/given date and the maximum date 337 // the current/given date and the maximum date
335 // ( maximum time range ) ! 338 // ( maximum time range ) !
336 qWarning("Checking if %s is between %s and %s ! ", 339 qWarning("Checking if %s is between %s and %s ! ",
337 checkDate->toString().latin1(), 340 checkDate->toString().latin1(),
338 current.toString().latin1(), 341 current.toString().latin1(),
339 queryDate->toString().latin1() ); 342 queryDate->toString().latin1() );
340 if ( current.daysTo( *queryDate ) >= 0 ){ 343 if ( current.daysTo( *queryDate ) >= 0 ){
341 if ( !( ( *checkDate >= current ) && 344 if ( !( ( *checkDate >= current ) &&
342 ( *checkDate <= *queryDate ) ) ){ 345 ( *checkDate <= *queryDate ) ) ){
343 allcorrect = false; 346 allcorrect = false;
344 qWarning (" Nope!.."); 347 qWarning (" Nope!..");
345 } 348 }
346 } 349 }
347 } 350 }
348 } else{ 351 } else{
349 // checkDate is invalid. Therefore this entry is always rejected 352 // checkDate is invalid. Therefore this entry is always rejected
350 allcorrect = false; 353 allcorrect = false;
351 } 354 }
352 } 355 }
353 356
354 delete queryDate; 357 delete queryDate;
355 queryDate = 0l; 358 queryDate = 0l;
356 delete checkDate; 359 delete checkDate;
357 checkDate = 0l; 360 checkDate = 0l;
358 break; 361 break;
359 default: 362 default:
360 /* Just compare fields which are not empty in the query object */ 363 /* Just compare fields which are not empty in the query object */
361 if ( !query.field(i).isEmpty() ){ 364 if ( !query.field(i).isEmpty() ){
362 switch ( settings & ~( OContactAccess::IgnoreCase 365 switch ( settings & ~( OContactAccess::IgnoreCase
363 | OContactAccess::DateDiff 366 | OContactAccess::DateDiff
364 | OContactAccess::DateYear 367 | OContactAccess::DateYear
365 | OContactAccess::DateMonth 368 | OContactAccess::DateMonth
366 | OContactAccess::DateDay 369 | OContactAccess::DateDay
367 | OContactAccess::MatchOne 370 | OContactAccess::MatchOne
368 ) ){ 371 ) ){
369 372
370 case OContactAccess::RegExp:{ 373 case OContactAccess::RegExp:{
371 QRegExp expr ( query.field(i), 374 QRegExp expr ( query.field(i),
372 !(settings & OContactAccess::IgnoreCase), 375 !(settings & OContactAccess::IgnoreCase),
373 false ); 376 false );
374 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 377 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
375 allcorrect = false; 378 allcorrect = false;
376 } 379 }
377 break; 380 break;
378 case OContactAccess::WildCards:{ 381 case OContactAccess::WildCards:{
379 QRegExp expr ( query.field(i), 382 QRegExp expr ( query.field(i),
380 !(settings & OContactAccess::IgnoreCase), 383 !(settings & OContactAccess::IgnoreCase),
381 true ); 384 true );
382 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 385 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
383 allcorrect = false; 386 allcorrect = false;
384 } 387 }
385 break; 388 break;
386 case OContactAccess::ExactMatch:{ 389 case OContactAccess::ExactMatch:{
387 if (settings & OContactAccess::IgnoreCase){ 390 if (settings & OContactAccess::IgnoreCase){
388 if ( query.field(i).upper() != 391 if ( query.field(i).upper() !=
389 (*it)->field(i).upper() ) 392 (*it)->field(i).upper() )
390 allcorrect = false; 393 allcorrect = false;
391 }else{ 394 }else{
392 if ( query.field(i) != (*it)->field(i) ) 395 if ( query.field(i) != (*it)->field(i) )
393 allcorrect = false; 396 allcorrect = false;
394 } 397 }
395 } 398 }
396 break; 399 break;
397 } 400 }
398 } 401 }
399 } 402 }
400 } 403 }
401 if ( allcorrect ){ 404 if ( allcorrect ){
402 m_currentQuery[arraycounter++] = (*it)->uid(); 405 m_currentQuery[arraycounter++] = (*it)->uid();
403 } 406 }
404 } 407 }
405 408
406 // Shrink to fit.. 409 // Shrink to fit..
407 m_currentQuery.resize(arraycounter); 410 m_currentQuery.resize(arraycounter);
408 411
409 return m_currentQuery; 412 return m_currentQuery;
410} 413}
411 414
412QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 415QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
413{ 416{
414 QArray<int> m_currentQuery( m_contactList.count() ); 417 QArray<int> m_currentQuery( m_contactList.count() );
415 QListIterator<OContact> it( m_contactList ); 418 QListIterator<OContact> it( m_contactList );
416 uint arraycounter = 0; 419 uint arraycounter = 0;
417 420
418 for( ; it.current(); ++it ){ 421 for( ; it.current(); ++it ){
419 if ( (*it)->match( r ) ){ 422 if ( (*it)->match( r ) ){
420 m_currentQuery[arraycounter++] = (*it)->uid(); 423 m_currentQuery[arraycounter++] = (*it)->uid();
421 } 424 }
422 425
423 } 426 }
424 // Shrink to fit.. 427 // Shrink to fit..
425 m_currentQuery.resize(arraycounter); 428 m_currentQuery.resize(arraycounter);
426 429
427 return m_currentQuery; 430 return m_currentQuery;
428} 431}
429 432
430const uint OContactAccessBackend_XML::querySettings() 433const uint OContactAccessBackend_XML::querySettings()
431{ 434{
432 return ( OContactAccess::WildCards 435 return ( OContactAccess::WildCards
433 | OContactAccess::IgnoreCase 436 | OContactAccess::IgnoreCase
434 | OContactAccess::RegExp 437 | OContactAccess::RegExp
435 | OContactAccess::ExactMatch 438 | OContactAccess::ExactMatch
436 | OContactAccess::DateDiff 439 | OContactAccess::DateDiff
437 | OContactAccess::DateYear 440 | OContactAccess::DateYear
438 | OContactAccess::DateMonth 441 | OContactAccess::DateMonth
439 | OContactAccess::DateDay 442 | OContactAccess::DateDay
440 ); 443 );
441} 444}
442 445
443bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 446bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
444{ 447{
445 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 448 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
446 * may be added with any of the other settings. IgnoreCase should never used alone. 449 * may be added with any of the other settings. IgnoreCase should never used alone.
447 * Wildcards, RegExp, ExactMatch should never used at the same time... 450 * Wildcards, RegExp, ExactMatch should never used at the same time...
448 */ 451 */
449 452
453 // Step 1: Check whether the given settings are supported by this backend
454 if ( ( querySettings & (
455 OContactAccess::IgnoreCase
456 | OContactAccess::WildCards
457 | OContactAccess::DateDiff
458 | OContactAccess::DateYear
459 | OContactAccess::DateMonth
460 | OContactAccess::DateDay
461 | OContactAccess::RegExp
462 | OContactAccess::ExactMatch
463 ) ) != querySettings )
464 return false;
465
466 // Step 2: Check whether the given combinations are ok..
467
468 // IngoreCase alone is invalid
450 if ( querySettings == OContactAccess::IgnoreCase ) 469 if ( querySettings == OContactAccess::IgnoreCase )
451 return false; 470 return false;
452 471
472 // WildCards, RegExp and ExactMatch should never used at the same time
453 switch ( querySettings & ~( OContactAccess::IgnoreCase 473 switch ( querySettings & ~( OContactAccess::IgnoreCase
454 | OContactAccess::DateDiff 474 | OContactAccess::DateDiff
455 | OContactAccess::DateYear 475 | OContactAccess::DateYear
456 | OContactAccess::DateMonth 476 | OContactAccess::DateMonth
457 | OContactAccess::DateDay 477 | OContactAccess::DateDay
458 ) 478 )
459 ){ 479 ){
460 case OContactAccess::RegExp: 480 case OContactAccess::RegExp:
461 return ( true ); 481 return ( true );
462 case OContactAccess::WildCards: 482 case OContactAccess::WildCards:
463 return ( true ); 483 return ( true );
464 case OContactAccess::ExactMatch: 484 case OContactAccess::ExactMatch:
465 return ( true ); 485 return ( true );
486 case 0: // one of the upper removed bits were set..
487 return ( true );
466 default: 488 default:
467 return ( false ); 489 return ( false );
468 } 490 }
469} 491}
470 492
471// Currently only asc implemented.. 493// Currently only asc implemented..
472QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 494QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
473{ 495{
474 QMap<QString, int> nameToUid; 496 QMap<QString, int> nameToUid;
475 QStringList names; 497 QStringList names;
476 QArray<int> m_currentQuery( m_contactList.count() ); 498 QArray<int> m_currentQuery( m_contactList.count() );
477 499
478 // First fill map and StringList with all Names 500 // First fill map and StringList with all Names
479 // Afterwards sort namelist and use map to fill array to return.. 501 // Afterwards sort namelist and use map to fill array to return..
480 QListIterator<OContact> it( m_contactList ); 502 QListIterator<OContact> it( m_contactList );
481 for( ; it.current(); ++it ){ 503 for( ; it.current(); ++it ){
482 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 504 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
483 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 505 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
484 } 506 }
485 names.sort(); 507 names.sort();
486 508
487 int i = 0; 509 int i = 0;
488 if ( asc ){ 510 if ( asc ){
489 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 511 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
490 m_currentQuery[i++] = nameToUid[ (*it) ]; 512 m_currentQuery[i++] = nameToUid[ (*it) ];
491 }else{ 513 }else{
492 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 514 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
493 m_currentQuery[i++] = nameToUid[ (*it) ]; 515 m_currentQuery[i++] = nameToUid[ (*it) ];
494 } 516 }
495 517
496 return m_currentQuery; 518 return m_currentQuery;
497 519
498} 520}
499 521
500bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 522bool OContactAccessBackend_XML::add ( const OContact &newcontact )
501{ 523{
502 //qWarning("odefaultbackend: ACTION::ADD"); 524 //qWarning("odefaultbackend: ACTION::ADD");
503 updateJournal (newcontact, ACTION_ADD); 525 updateJournal (newcontact, ACTION_ADD);
504 addContact_p( newcontact ); 526 addContact_p( newcontact );
505 527
506 m_changed = true; 528 m_changed = true;
507 529
508 return true; 530 return true;
509} 531}
510 532
511bool OContactAccessBackend_XML::replace ( const OContact &contact ) 533bool OContactAccessBackend_XML::replace ( const OContact &contact )
512{ 534{
513 m_changed = true; 535 m_changed = true;
514 536
515 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 537 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
516 538
517 if ( found ) { 539 if ( found ) {
518 OContact* newCont = new OContact( contact ); 540 OContact* newCont = new OContact( contact );
519 541
520 updateJournal ( *newCont, ACTION_REPLACE); 542 updateJournal ( *newCont, ACTION_REPLACE);
521 m_contactList.removeRef ( found ); 543 m_contactList.removeRef ( found );
522 m_contactList.append ( newCont ); 544 m_contactList.append ( newCont );
523 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 545 m_uidToContact.remove( QString().setNum( contact.uid() ) );
524 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 546 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
525 547
526 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 548 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
527 549
528 return true; 550 return true;
529 } else 551 } else
530 return false; 552 return false;
531} 553}
532 554
533bool OContactAccessBackend_XML::remove ( int uid ) 555bool OContactAccessBackend_XML::remove ( int uid )
534{ 556{
535 m_changed = true; 557 m_changed = true;
536 558
537 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 559 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
538 560
539 if ( found ) { 561 if ( found ) {
540 updateJournal ( *found, ACTION_REMOVE); 562 updateJournal ( *found, ACTION_REMOVE);
541 m_contactList.removeRef ( found ); 563 m_contactList.removeRef ( found );
542 m_uidToContact.remove( QString().setNum( uid ) ); 564 m_uidToContact.remove( QString().setNum( uid ) );
543 565
544 return true; 566 return true;
545 } else 567 } else
546 return false; 568 return false;
547} 569}
548 570
549bool OContactAccessBackend_XML::reload(){ 571bool OContactAccessBackend_XML::reload(){
550 /* Reload is the same as load in this implementation */ 572 /* Reload is the same as load in this implementation */
551 return ( load() ); 573 return ( load() );
552} 574}
553 575
554void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 576void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
555{ 577{
556 OContact* contRef = new OContact( newcontact ); 578 OContact* contRef = new OContact( newcontact );
557 579
558 m_contactList.append ( contRef ); 580 m_contactList.append ( contRef );
559 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 581 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
560} 582}
561 583
562/* This function loads the xml-database and the journalfile */ 584/* This function loads the xml-database and the journalfile */
563bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 585bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
564{ 586{
565 587
566 /* We use the time of the last read to check if the file was 588 /* We use the time of the last read to check if the file was
567 * changed externally. 589 * changed externally.
568 */ 590 */
569 if ( !isJournal ){ 591 if ( !isJournal ){
570 QFileInfo fi( filename ); 592 QFileInfo fi( filename );
571 m_readtime = fi.lastModified (); 593 m_readtime = fi.lastModified ();
572 } 594 }
573 595
574 const int JOURNALACTION = Qtopia::Notes + 1; 596 const int JOURNALACTION = Qtopia::Notes + 1;
575 const int JOURNALROW = JOURNALACTION + 1; 597 const int JOURNALROW = JOURNALACTION + 1;
576 598
577 bool foundAction = false; 599 bool foundAction = false;
578 journal_action action = ACTION_ADD; 600 journal_action action = ACTION_ADD;
579 int journalKey = 0; 601 int journalKey = 0;
580 QMap<int, QString> contactMap; 602 QMap<int, QString> contactMap;
581 QMap<QString, QString> customMap; 603 QMap<QString, QString> customMap;
582 QMap<QString, QString>::Iterator customIt; 604 QMap<QString, QString>::Iterator customIt;
583 QAsciiDict<int> dict( 47 ); 605 QAsciiDict<int> dict( 47 );
584 606
585 dict.setAutoDelete( TRUE ); 607 dict.setAutoDelete( TRUE );
586 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 608 dict.insert( "Uid", new int(Qtopia::AddressUid) );
587 dict.insert( "Title", new int(Qtopia::Title) ); 609 dict.insert( "Title", new int(Qtopia::Title) );
588 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 610 dict.insert( "FirstName", new int(Qtopia::FirstName) );
589 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 611 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
590 dict.insert( "LastName", new int(Qtopia::LastName) ); 612 dict.insert( "LastName", new int(Qtopia::LastName) );
591 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 613 dict.insert( "Suffix", new int(Qtopia::Suffix) );
592 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 614 dict.insert( "FileAs", new int(Qtopia::FileAs) );
593 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 615 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 661cd51..097142b 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,147 +1,150 @@
1/* 1/*
2 * XML Backend for the OPIE-Contact Database. 2 * XML Backend for the OPIE-Contact Database.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * ===================================================================== 11 * =====================================================================
12 * ToDo: XML-Backend: Automatic reload if something was changed... 12 * ToDo: XML-Backend: Automatic reload if something was changed...
13 * 13 *
14 * 14 *
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.6 2003/07/07 16:19:47 eilers
21 * Fixing serious bug in hasQuerySettings()
22 *
20 * Revision 1.5 2003/04/13 18:07:10 zecke 23 * Revision 1.5 2003/04/13 18:07:10 zecke
21 * More API doc 24 * More API doc
22 * QString -> const QString& 25 * QString -> const QString&
23 * QString = 0l -> QString::null 26 * QString = 0l -> QString::null
24 * 27 *
25 * Revision 1.4 2003/03/21 14:32:54 mickeyl 28 * Revision 1.4 2003/03/21 14:32:54 mickeyl
26 * g++ compliance fix: default arguments belong into the declaration, but not the definition 29 * g++ compliance fix: default arguments belong into the declaration, but not the definition
27 * 30 *
28 * Revision 1.3 2003/03/21 12:26:28 eilers 31 * Revision 1.3 2003/03/21 12:26:28 eilers
29 * Fixing small bug: If we search a birthday from today to today, it returned 32 * Fixing small bug: If we search a birthday from today to today, it returned
30 * every contact .. 33 * every contact ..
31 * 34 *
32 * Revision 1.2 2003/03/21 10:33:09 eilers 35 * Revision 1.2 2003/03/21 10:33:09 eilers
33 * Merged speed optimized xml backend for contacts to main. 36 * Merged speed optimized xml backend for contacts to main.
34 * Added QDateTime to querybyexample. For instance, it is now possible to get 37 * Added QDateTime to querybyexample. For instance, it is now possible to get
35 * all Birthdays/Anniversaries between two dates. This should be used 38 * all Birthdays/Anniversaries between two dates. This should be used
36 * to show all birthdays in the datebook.. 39 * to show all birthdays in the datebook..
37 * This change is sourcecode backward compatible but you have to upgrade 40 * This change is sourcecode backward compatible but you have to upgrade
38 * the binaries for today-addressbook. 41 * the binaries for today-addressbook.
39 * 42 *
40 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 43 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
41 * Speed optimization. Removed the sequential search loops. 44 * Speed optimization. Removed the sequential search loops.
42 * 45 *
43 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 46 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
44 * Writing offsets to debug output.. 47 * Writing offsets to debug output..
45 * 48 *
46 * Revision 1.1 2003/02/09 15:05:01 eilers 49 * Revision 1.1 2003/02/09 15:05:01 eilers
47 * Nothing happened.. Just some cleanup before I will start.. 50 * Nothing happened.. Just some cleanup before I will start..
48 * 51 *
49 * Revision 1.12 2003/01/03 16:58:03 eilers 52 * Revision 1.12 2003/01/03 16:58:03 eilers
50 * Reenable debug output 53 * Reenable debug output
51 * 54 *
52 * Revision 1.11 2003/01/03 12:31:28 eilers 55 * Revision 1.11 2003/01/03 12:31:28 eilers
53 * Bugfix for calculating data diffs.. 56 * Bugfix for calculating data diffs..
54 * 57 *
55 * Revision 1.10 2003/01/02 14:27:12 eilers 58 * Revision 1.10 2003/01/02 14:27:12 eilers
56 * Improved query by example: Search by date is possible.. First step 59 * Improved query by example: Search by date is possible.. First step
57 * for a today plugin for birthdays.. 60 * for a today plugin for birthdays..
58 * 61 *
59 * Revision 1.9 2002/12/08 12:48:57 eilers 62 * Revision 1.9 2002/12/08 12:48:57 eilers
60 * Moved journal-enum from ocontact into i the xml-backend.. 63 * Moved journal-enum from ocontact into i the xml-backend..
61 * 64 *
62 * Revision 1.8 2002/11/14 17:04:24 eilers 65 * Revision 1.8 2002/11/14 17:04:24 eilers
63 * Sorting will now work if fullname is identical on some entries 66 * Sorting will now work if fullname is identical on some entries
64 * 67 *
65 * Revision 1.7 2002/11/13 15:02:46 eilers 68 * Revision 1.7 2002/11/13 15:02:46 eilers
66 * Small Bug in sorted fixed 69 * Small Bug in sorted fixed
67 * 70 *
68 * Revision 1.6 2002/11/13 14:14:51 eilers 71 * Revision 1.6 2002/11/13 14:14:51 eilers
69 * Added sorted for Contacts.. 72 * Added sorted for Contacts..
70 * 73 *
71 * Revision 1.5 2002/11/01 15:10:42 eilers 74 * Revision 1.5 2002/11/01 15:10:42 eilers
72 * Added regExp-search in database for all fields in a contact. 75 * Added regExp-search in database for all fields in a contact.
73 * 76 *
74 * Revision 1.4 2002/10/16 10:52:40 eilers 77 * Revision 1.4 2002/10/16 10:52:40 eilers
75 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 78 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
76 * 79 *
77 * Revision 1.3 2002/10/14 16:21:54 eilers 80 * Revision 1.3 2002/10/14 16:21:54 eilers
78 * Some minor interface updates 81 * Some minor interface updates
79 * 82 *
80 * Revision 1.2 2002/10/07 17:34:24 eilers 83 * Revision 1.2 2002/10/07 17:34:24 eilers
81 * added OBackendFactory for advanced backend access 84 * added OBackendFactory for advanced backend access
82 * 85 *
83 * Revision 1.1 2002/09/27 17:11:44 eilers 86 * Revision 1.1 2002/09/27 17:11:44 eilers
84 * Added API for accessing the Contact-Database ! It is compiling, but 87 * Added API for accessing the Contact-Database ! It is compiling, but
85 * please do not expect that anything is working ! 88 * please do not expect that anything is working !
86 * I will debug that stuff in the next time .. 89 * I will debug that stuff in the next time ..
87 * Please read README_COMPILE for compiling ! 90 * Please read README_COMPILE for compiling !
88 * 91 *
89 * 92 *
90 */ 93 */
91 94
92#include "ocontactaccessbackend_xml.h" 95#include "ocontactaccessbackend_xml.h"
93 96
94#include <qasciidict.h> 97#include <qasciidict.h>
95#include <qdatetime.h> 98#include <qdatetime.h>
96#include <qfile.h> 99#include <qfile.h>
97#include <qfileinfo.h> 100#include <qfileinfo.h>
98#include <qregexp.h> 101#include <qregexp.h>
99#include <qarray.h> 102#include <qarray.h>
100#include <qmap.h> 103#include <qmap.h>
101#include <qdatetime.h> 104#include <qdatetime.h>
102 105
103#include <qpe/global.h> 106#include <qpe/global.h>
104 107
105#include <opie/xmltree.h> 108#include <opie/xmltree.h>
106#include "ocontactaccessbackend.h" 109#include "ocontactaccessbackend.h"
107#include "ocontactaccess.h" 110#include "ocontactaccess.h"
108 111
109#include <stdlib.h> 112#include <stdlib.h>
110#include <errno.h> 113#include <errno.h>
111 114
112using namespace Opie; 115using namespace Opie;
113 116
114 117
115OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): 118OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ):
116 m_changed( false ) 119 m_changed( false )
117{ 120{
118 // Just m_contactlist should call delete if an entry 121 // Just m_contactlist should call delete if an entry
119 // is removed. 122 // is removed.
120 m_contactList.setAutoDelete( true ); 123 m_contactList.setAutoDelete( true );
121 m_uidToContact.setAutoDelete( false ); 124 m_uidToContact.setAutoDelete( false );
122 125
123 m_appName = appname; 126 m_appName = appname;
124 127
125 /* Set journalfile name ... */ 128 /* Set journalfile name ... */
126 m_journalName = getenv("HOME"); 129 m_journalName = getenv("HOME");
127 m_journalName +="/.abjournal" + appname; 130 m_journalName +="/.abjournal" + appname;
128 131
129 /* Expecting to access the default filename if nothing else is set */ 132 /* Expecting to access the default filename if nothing else is set */
130 if ( filename.isEmpty() ){ 133 if ( filename.isEmpty() ){
131 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 134 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
132 } else 135 } else
133 m_fileName = filename; 136 m_fileName = filename;
134 137
135 /* Load Database now */ 138 /* Load Database now */
136 load (); 139 load ();
137} 140}
138 141
139bool OContactAccessBackend_XML::save() 142bool OContactAccessBackend_XML::save()
140{ 143{
141 144
142 if ( !m_changed ) 145 if ( !m_changed )
143 return true; 146 return true;
144 147
145 QString strNewFile = m_fileName + ".new"; 148 QString strNewFile = m_fileName + ".new";
146 QFile f( strNewFile ); 149 QFile f( strNewFile );
147 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 150 if ( !f.open( IO_WriteOnly|IO_Raw ) )
@@ -322,272 +325,291 @@ QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, i
322 325
323 // We have to equalize the year, otherwise 326 // We have to equalize the year, otherwise
324 // the search will fail.. 327 // the search will fail..
325 checkDate->setYMD( current.year(), 328 checkDate->setYMD( current.year(),
326 checkDate->month(), 329 checkDate->month(),
327 checkDate->day() ); 330 checkDate->day() );
328 if ( *checkDate < current ) 331 if ( *checkDate < current )
329 checkDate->setYMD( current.year()+1, 332 checkDate->setYMD( current.year()+1,
330 checkDate->month(), 333 checkDate->month(),
331 checkDate->day() ); 334 checkDate->day() );
332 335
333 // Check whether the birthday/anniversary date is between 336 // Check whether the birthday/anniversary date is between
334 // the current/given date and the maximum date 337 // the current/given date and the maximum date
335 // ( maximum time range ) ! 338 // ( maximum time range ) !
336 qWarning("Checking if %s is between %s and %s ! ", 339 qWarning("Checking if %s is between %s and %s ! ",
337 checkDate->toString().latin1(), 340 checkDate->toString().latin1(),
338 current.toString().latin1(), 341 current.toString().latin1(),
339 queryDate->toString().latin1() ); 342 queryDate->toString().latin1() );
340 if ( current.daysTo( *queryDate ) >= 0 ){ 343 if ( current.daysTo( *queryDate ) >= 0 ){
341 if ( !( ( *checkDate >= current ) && 344 if ( !( ( *checkDate >= current ) &&
342 ( *checkDate <= *queryDate ) ) ){ 345 ( *checkDate <= *queryDate ) ) ){
343 allcorrect = false; 346 allcorrect = false;
344 qWarning (" Nope!.."); 347 qWarning (" Nope!..");
345 } 348 }
346 } 349 }
347 } 350 }
348 } else{ 351 } else{
349 // checkDate is invalid. Therefore this entry is always rejected 352 // checkDate is invalid. Therefore this entry is always rejected
350 allcorrect = false; 353 allcorrect = false;
351 } 354 }
352 } 355 }
353 356
354 delete queryDate; 357 delete queryDate;
355 queryDate = 0l; 358 queryDate = 0l;
356 delete checkDate; 359 delete checkDate;
357 checkDate = 0l; 360 checkDate = 0l;
358 break; 361 break;
359 default: 362 default:
360 /* Just compare fields which are not empty in the query object */ 363 /* Just compare fields which are not empty in the query object */
361 if ( !query.field(i).isEmpty() ){ 364 if ( !query.field(i).isEmpty() ){
362 switch ( settings & ~( OContactAccess::IgnoreCase 365 switch ( settings & ~( OContactAccess::IgnoreCase
363 | OContactAccess::DateDiff 366 | OContactAccess::DateDiff
364 | OContactAccess::DateYear 367 | OContactAccess::DateYear
365 | OContactAccess::DateMonth 368 | OContactAccess::DateMonth
366 | OContactAccess::DateDay 369 | OContactAccess::DateDay
367 | OContactAccess::MatchOne 370 | OContactAccess::MatchOne
368 ) ){ 371 ) ){
369 372
370 case OContactAccess::RegExp:{ 373 case OContactAccess::RegExp:{
371 QRegExp expr ( query.field(i), 374 QRegExp expr ( query.field(i),
372 !(settings & OContactAccess::IgnoreCase), 375 !(settings & OContactAccess::IgnoreCase),
373 false ); 376 false );
374 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 377 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
375 allcorrect = false; 378 allcorrect = false;
376 } 379 }
377 break; 380 break;
378 case OContactAccess::WildCards:{ 381 case OContactAccess::WildCards:{
379 QRegExp expr ( query.field(i), 382 QRegExp expr ( query.field(i),
380 !(settings & OContactAccess::IgnoreCase), 383 !(settings & OContactAccess::IgnoreCase),
381 true ); 384 true );
382 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 385 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
383 allcorrect = false; 386 allcorrect = false;
384 } 387 }
385 break; 388 break;
386 case OContactAccess::ExactMatch:{ 389 case OContactAccess::ExactMatch:{
387 if (settings & OContactAccess::IgnoreCase){ 390 if (settings & OContactAccess::IgnoreCase){
388 if ( query.field(i).upper() != 391 if ( query.field(i).upper() !=
389 (*it)->field(i).upper() ) 392 (*it)->field(i).upper() )
390 allcorrect = false; 393 allcorrect = false;
391 }else{ 394 }else{
392 if ( query.field(i) != (*it)->field(i) ) 395 if ( query.field(i) != (*it)->field(i) )
393 allcorrect = false; 396 allcorrect = false;
394 } 397 }
395 } 398 }
396 break; 399 break;
397 } 400 }
398 } 401 }
399 } 402 }
400 } 403 }
401 if ( allcorrect ){ 404 if ( allcorrect ){
402 m_currentQuery[arraycounter++] = (*it)->uid(); 405 m_currentQuery[arraycounter++] = (*it)->uid();
403 } 406 }
404 } 407 }
405 408
406 // Shrink to fit.. 409 // Shrink to fit..
407 m_currentQuery.resize(arraycounter); 410 m_currentQuery.resize(arraycounter);
408 411
409 return m_currentQuery; 412 return m_currentQuery;
410} 413}
411 414
412QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 415QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
413{ 416{
414 QArray<int> m_currentQuery( m_contactList.count() ); 417 QArray<int> m_currentQuery( m_contactList.count() );
415 QListIterator<OContact> it( m_contactList ); 418 QListIterator<OContact> it( m_contactList );
416 uint arraycounter = 0; 419 uint arraycounter = 0;
417 420
418 for( ; it.current(); ++it ){ 421 for( ; it.current(); ++it ){
419 if ( (*it)->match( r ) ){ 422 if ( (*it)->match( r ) ){
420 m_currentQuery[arraycounter++] = (*it)->uid(); 423 m_currentQuery[arraycounter++] = (*it)->uid();
421 } 424 }
422 425
423 } 426 }
424 // Shrink to fit.. 427 // Shrink to fit..
425 m_currentQuery.resize(arraycounter); 428 m_currentQuery.resize(arraycounter);
426 429
427 return m_currentQuery; 430 return m_currentQuery;
428} 431}
429 432
430const uint OContactAccessBackend_XML::querySettings() 433const uint OContactAccessBackend_XML::querySettings()
431{ 434{
432 return ( OContactAccess::WildCards 435 return ( OContactAccess::WildCards
433 | OContactAccess::IgnoreCase 436 | OContactAccess::IgnoreCase
434 | OContactAccess::RegExp 437 | OContactAccess::RegExp
435 | OContactAccess::ExactMatch 438 | OContactAccess::ExactMatch
436 | OContactAccess::DateDiff 439 | OContactAccess::DateDiff
437 | OContactAccess::DateYear 440 | OContactAccess::DateYear
438 | OContactAccess::DateMonth 441 | OContactAccess::DateMonth
439 | OContactAccess::DateDay 442 | OContactAccess::DateDay
440 ); 443 );
441} 444}
442 445
443bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 446bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
444{ 447{
445 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 448 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
446 * may be added with any of the other settings. IgnoreCase should never used alone. 449 * may be added with any of the other settings. IgnoreCase should never used alone.
447 * Wildcards, RegExp, ExactMatch should never used at the same time... 450 * Wildcards, RegExp, ExactMatch should never used at the same time...
448 */ 451 */
449 452
453 // Step 1: Check whether the given settings are supported by this backend
454 if ( ( querySettings & (
455 OContactAccess::IgnoreCase
456 | OContactAccess::WildCards
457 | OContactAccess::DateDiff
458 | OContactAccess::DateYear
459 | OContactAccess::DateMonth
460 | OContactAccess::DateDay
461 | OContactAccess::RegExp
462 | OContactAccess::ExactMatch
463 ) ) != querySettings )
464 return false;
465
466 // Step 2: Check whether the given combinations are ok..
467
468 // IngoreCase alone is invalid
450 if ( querySettings == OContactAccess::IgnoreCase ) 469 if ( querySettings == OContactAccess::IgnoreCase )
451 return false; 470 return false;
452 471
472 // WildCards, RegExp and ExactMatch should never used at the same time
453 switch ( querySettings & ~( OContactAccess::IgnoreCase 473 switch ( querySettings & ~( OContactAccess::IgnoreCase
454 | OContactAccess::DateDiff 474 | OContactAccess::DateDiff
455 | OContactAccess::DateYear 475 | OContactAccess::DateYear
456 | OContactAccess::DateMonth 476 | OContactAccess::DateMonth
457 | OContactAccess::DateDay 477 | OContactAccess::DateDay
458 ) 478 )
459 ){ 479 ){
460 case OContactAccess::RegExp: 480 case OContactAccess::RegExp:
461 return ( true ); 481 return ( true );
462 case OContactAccess::WildCards: 482 case OContactAccess::WildCards:
463 return ( true ); 483 return ( true );
464 case OContactAccess::ExactMatch: 484 case OContactAccess::ExactMatch:
465 return ( true ); 485 return ( true );
486 case 0: // one of the upper removed bits were set..
487 return ( true );
466 default: 488 default:
467 return ( false ); 489 return ( false );
468 } 490 }
469} 491}
470 492
471// Currently only asc implemented.. 493// Currently only asc implemented..
472QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 494QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
473{ 495{
474 QMap<QString, int> nameToUid; 496 QMap<QString, int> nameToUid;
475 QStringList names; 497 QStringList names;
476 QArray<int> m_currentQuery( m_contactList.count() ); 498 QArray<int> m_currentQuery( m_contactList.count() );
477 499
478 // First fill map and StringList with all Names 500 // First fill map and StringList with all Names
479 // Afterwards sort namelist and use map to fill array to return.. 501 // Afterwards sort namelist and use map to fill array to return..
480 QListIterator<OContact> it( m_contactList ); 502 QListIterator<OContact> it( m_contactList );
481 for( ; it.current(); ++it ){ 503 for( ; it.current(); ++it ){
482 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 504 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
483 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 505 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
484 } 506 }
485 names.sort(); 507 names.sort();
486 508
487 int i = 0; 509 int i = 0;
488 if ( asc ){ 510 if ( asc ){
489 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 511 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
490 m_currentQuery[i++] = nameToUid[ (*it) ]; 512 m_currentQuery[i++] = nameToUid[ (*it) ];
491 }else{ 513 }else{
492 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 514 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
493 m_currentQuery[i++] = nameToUid[ (*it) ]; 515 m_currentQuery[i++] = nameToUid[ (*it) ];
494 } 516 }
495 517
496 return m_currentQuery; 518 return m_currentQuery;
497 519
498} 520}
499 521
500bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 522bool OContactAccessBackend_XML::add ( const OContact &newcontact )
501{ 523{
502 //qWarning("odefaultbackend: ACTION::ADD"); 524 //qWarning("odefaultbackend: ACTION::ADD");
503 updateJournal (newcontact, ACTION_ADD); 525 updateJournal (newcontact, ACTION_ADD);
504 addContact_p( newcontact ); 526 addContact_p( newcontact );
505 527
506 m_changed = true; 528 m_changed = true;
507 529
508 return true; 530 return true;
509} 531}
510 532
511bool OContactAccessBackend_XML::replace ( const OContact &contact ) 533bool OContactAccessBackend_XML::replace ( const OContact &contact )
512{ 534{
513 m_changed = true; 535 m_changed = true;
514 536
515 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 537 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
516 538
517 if ( found ) { 539 if ( found ) {
518 OContact* newCont = new OContact( contact ); 540 OContact* newCont = new OContact( contact );
519 541
520 updateJournal ( *newCont, ACTION_REPLACE); 542 updateJournal ( *newCont, ACTION_REPLACE);
521 m_contactList.removeRef ( found ); 543 m_contactList.removeRef ( found );
522 m_contactList.append ( newCont ); 544 m_contactList.append ( newCont );
523 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 545 m_uidToContact.remove( QString().setNum( contact.uid() ) );
524 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 546 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
525 547
526 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 548 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
527 549
528 return true; 550 return true;
529 } else 551 } else
530 return false; 552 return false;
531} 553}
532 554
533bool OContactAccessBackend_XML::remove ( int uid ) 555bool OContactAccessBackend_XML::remove ( int uid )
534{ 556{
535 m_changed = true; 557 m_changed = true;
536 558
537 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 559 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
538 560
539 if ( found ) { 561 if ( found ) {
540 updateJournal ( *found, ACTION_REMOVE); 562 updateJournal ( *found, ACTION_REMOVE);
541 m_contactList.removeRef ( found ); 563 m_contactList.removeRef ( found );
542 m_uidToContact.remove( QString().setNum( uid ) ); 564 m_uidToContact.remove( QString().setNum( uid ) );
543 565
544 return true; 566 return true;
545 } else 567 } else
546 return false; 568 return false;
547} 569}
548 570
549bool OContactAccessBackend_XML::reload(){ 571bool OContactAccessBackend_XML::reload(){
550 /* Reload is the same as load in this implementation */ 572 /* Reload is the same as load in this implementation */
551 return ( load() ); 573 return ( load() );
552} 574}
553 575
554void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 576void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
555{ 577{
556 OContact* contRef = new OContact( newcontact ); 578 OContact* contRef = new OContact( newcontact );
557 579
558 m_contactList.append ( contRef ); 580 m_contactList.append ( contRef );
559 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 581 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
560} 582}
561 583
562/* This function loads the xml-database and the journalfile */ 584/* This function loads the xml-database and the journalfile */
563bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 585bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
564{ 586{
565 587
566 /* We use the time of the last read to check if the file was 588 /* We use the time of the last read to check if the file was
567 * changed externally. 589 * changed externally.
568 */ 590 */
569 if ( !isJournal ){ 591 if ( !isJournal ){
570 QFileInfo fi( filename ); 592 QFileInfo fi( filename );
571 m_readtime = fi.lastModified (); 593 m_readtime = fi.lastModified ();
572 } 594 }
573 595
574 const int JOURNALACTION = Qtopia::Notes + 1; 596 const int JOURNALACTION = Qtopia::Notes + 1;
575 const int JOURNALROW = JOURNALACTION + 1; 597 const int JOURNALROW = JOURNALACTION + 1;
576 598
577 bool foundAction = false; 599 bool foundAction = false;
578 journal_action action = ACTION_ADD; 600 journal_action action = ACTION_ADD;
579 int journalKey = 0; 601 int journalKey = 0;
580 QMap<int, QString> contactMap; 602 QMap<int, QString> contactMap;
581 QMap<QString, QString> customMap; 603 QMap<QString, QString> customMap;
582 QMap<QString, QString>::Iterator customIt; 604 QMap<QString, QString>::Iterator customIt;
583 QAsciiDict<int> dict( 47 ); 605 QAsciiDict<int> dict( 47 );
584 606
585 dict.setAutoDelete( TRUE ); 607 dict.setAutoDelete( TRUE );
586 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 608 dict.insert( "Uid", new int(Qtopia::AddressUid) );
587 dict.insert( "Title", new int(Qtopia::Title) ); 609 dict.insert( "Title", new int(Qtopia::Title) );
588 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 610 dict.insert( "FirstName", new int(Qtopia::FirstName) );
589 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 611 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
590 dict.insert( "LastName", new int(Qtopia::LastName) ); 612 dict.insert( "LastName", new int(Qtopia::LastName) );
591 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 613 dict.insert( "Suffix", new int(Qtopia::Suffix) );
592 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 614 dict.insert( "FileAs", new int(Qtopia::FileAs) );
593 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 615 dict.insert( "Categories", new int(Qtopia::AddressCategory) );