summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontact.h2
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.h24
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.h24
-rw-r--r--libopie2/opiepim/ocontact.h2
4 files changed, 30 insertions, 22 deletions
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h
index 65ba43e..1fd1c75 100644
--- a/libopie/pim/ocontact.h
+++ b/libopie/pim/ocontact.h
@@ -23,50 +23,48 @@
23#define __OCONTACT_H__ 23#define __OCONTACT_H__
24 24
25#include <opie/opimrecord.h> 25#include <opie/opimrecord.h>
26#include <qpe/recordfields.h> 26#include <qpe/recordfields.h>
27 27
28#include <qdatetime.h> 28#include <qdatetime.h>
29#include <qstringlist.h> 29#include <qstringlist.h>
30 30
31#if defined(QPC_TEMPLATEDLL) 31#if defined(QPC_TEMPLATEDLL)
32// MOC_SKIP_BEGIN 32// MOC_SKIP_BEGIN
33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; 33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
34// MOC_SKIP_END 34// MOC_SKIP_END
35#endif 35#endif
36 36
37class ContactPrivate; 37class ContactPrivate;
38 38
39class QPC_EXPORT OContact : public OPimRecord 39class QPC_EXPORT OContact : public OPimRecord
40{ 40{
41 friend class DataSet; 41 friend class DataSet;
42public: 42public:
43 OContact(); 43 OContact();
44 OContact( const QMap<int, QString> &fromMap ); 44 OContact( const QMap<int, QString> &fromMap );
45 virtual ~OContact(); 45 virtual ~OContact();
46 46
47 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
48
49 /* 47 /*
50 * do we need to inline them 48 * do we need to inline them
51 * if yes do we need to inline them this way? 49 * if yes do we need to inline them this way?
52 * -zecke 50 * -zecke
53 */ 51 */
54 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } 52 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
55 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } 53 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
56 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } 54 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
57 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } 55 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
58 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } 56 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
59 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } 57 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
60 void setFileAs(); 58 void setFileAs();
61 59
62 // default email address 60 // default email address
63 void setDefaultEmail( const QString &v ); 61 void setDefaultEmail( const QString &v );
64 // inserts email to list and ensure's doesn't already exist 62 // inserts email to list and ensure's doesn't already exist
65 void insertEmail( const QString &v ); 63 void insertEmail( const QString &v );
66 void removeEmail( const QString &v ); 64 void removeEmail( const QString &v );
67 void clearEmails(); 65 void clearEmails();
68 void insertEmails( const QStringList &v ); 66 void insertEmails( const QStringList &v );
69 67
70 // home 68 // home
71 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } 69 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
72 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } 70 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h
index ae6ec9e..c765ff5 100644
--- a/libopie/pim/ocontactaccessbackend_xml.h
+++ b/libopie/pim/ocontactaccessbackend_xml.h
@@ -1,43 +1,46 @@
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.9 2002/12/08 12:48:57 eilers
21 * Moved journal-enum from ocontact into i the xml-backend..
22 *
20 * Revision 1.8 2002/11/14 17:04:24 eilers 23 * Revision 1.8 2002/11/14 17:04:24 eilers
21 * Sorting will now work if fullname is identical on some entries 24 * Sorting will now work if fullname is identical on some entries
22 * 25 *
23 * Revision 1.7 2002/11/13 15:02:46 eilers 26 * Revision 1.7 2002/11/13 15:02:46 eilers
24 * Small Bug in sorted fixed 27 * Small Bug in sorted fixed
25 * 28 *
26 * Revision 1.6 2002/11/13 14:14:51 eilers 29 * Revision 1.6 2002/11/13 14:14:51 eilers
27 * Added sorted for Contacts.. 30 * Added sorted for Contacts..
28 * 31 *
29 * Revision 1.5 2002/11/01 15:10:42 eilers 32 * Revision 1.5 2002/11/01 15:10:42 eilers
30 * Added regExp-search in database for all fields in a contact. 33 * Added regExp-search in database for all fields in a contact.
31 * 34 *
32 * Revision 1.4 2002/10/16 10:52:40 eilers 35 * Revision 1.4 2002/10/16 10:52:40 eilers
33 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 36 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
34 * 37 *
35 * Revision 1.3 2002/10/14 16:21:54 eilers 38 * Revision 1.3 2002/10/14 16:21:54 eilers
36 * Some minor interface updates 39 * Some minor interface updates
37 * 40 *
38 * Revision 1.2 2002/10/07 17:34:24 eilers 41 * Revision 1.2 2002/10/07 17:34:24 eilers
39 * added OBackendFactory for advanced backend access 42 * added OBackendFactory for advanced backend access
40 * 43 *
41 * Revision 1.1 2002/09/27 17:11:44 eilers 44 * Revision 1.1 2002/09/27 17:11:44 eilers
42 * Added API for accessing the Contact-Database ! It is compiling, but 45 * Added API for accessing the Contact-Database ! It is compiling, but
43 * please do not expect that anything is working ! 46 * please do not expect that anything is working !
@@ -321,124 +324,127 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
321 // First fill map and StringList with all Names 324 // First fill map and StringList with all Names
322 // Afterwards sort namelist and use map to fill array to return.. 325 // Afterwards sort namelist and use map to fill array to return..
323 QValueListConstIterator<OContact> it; 326 QValueListConstIterator<OContact> it;
324 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 327 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
325 names.append( (*it).fileAs() + QString::number( (*it).uid() ) ); 328 names.append( (*it).fileAs() + QString::number( (*it).uid() ) );
326 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() ); 329 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() );
327 } 330 }
328 names.sort(); 331 names.sort();
329 332
330 int i = 0; 333 int i = 0;
331 if ( asc ){ 334 if ( asc ){
332 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 335 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
333 m_currentQuery[i++] = nameToUid[ (*it) ]; 336 m_currentQuery[i++] = nameToUid[ (*it) ];
334 }else{ 337 }else{
335 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 338 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
336 m_currentQuery[i++] = nameToUid[ (*it) ]; 339 m_currentQuery[i++] = nameToUid[ (*it) ];
337 } 340 }
338 341
339 return m_currentQuery; 342 return m_currentQuery;
340 343
341 } 344 }
342 bool add ( const OContact &newcontact ) 345 bool add ( const OContact &newcontact )
343 { 346 {
344 //qWarning("odefaultbackend: ACTION::ADD"); 347 //qWarning("odefaultbackend: ACTION::ADD");
345 updateJournal (newcontact, OContact::ACTION_ADD); 348 updateJournal (newcontact, ACTION_ADD);
346 addContact_p( newcontact ); 349 addContact_p( newcontact );
347 350
348 m_changed = true; 351 m_changed = true;
349 352
350 return true; 353 return true;
351 } 354 }
352 355
353 bool replace ( const OContact &contact ) 356 bool replace ( const OContact &contact )
354 { 357 {
355 m_changed = true; 358 m_changed = true;
356 359
357 bool found = false; 360 bool found = false;
358 361
359 QValueListIterator<OContact> it; 362 QValueListIterator<OContact> it;
360 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 363 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
361 if ( (*it).uid() == contact.uid() ){ 364 if ( (*it).uid() == contact.uid() ){
362 found = true; 365 found = true;
363 break; 366 break;
364 } 367 }
365 } 368 }
366 if (found) { 369 if (found) {
367 updateJournal (contact, OContact::ACTION_REPLACE); 370 updateJournal (contact, ACTION_REPLACE);
368 m_contactList.remove (it); 371 m_contactList.remove (it);
369 m_contactList.append (contact); 372 m_contactList.append (contact);
370 return true; 373 return true;
371 } else 374 } else
372 return false; 375 return false;
373 } 376 }
374 377
375 bool remove ( int uid ) 378 bool remove ( int uid )
376 { 379 {
377 m_changed = true; 380 m_changed = true;
378 381
379 bool found = false; 382 bool found = false;
380 QValueListIterator<OContact> it; 383 QValueListIterator<OContact> it;
381 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 384 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
382 if ((*it).uid() == uid){ 385 if ((*it).uid() == uid){
383 found = true; 386 found = true;
384 break; 387 break;
385 } 388 }
386 } 389 }
387 if (found) { 390 if (found) {
388 updateJournal ( *it, OContact::ACTION_REMOVE); 391 updateJournal ( *it, ACTION_REMOVE);
389 m_contactList.remove (it); 392 m_contactList.remove (it);
390 return true; 393 return true;
391 } else 394 } else
392 return false; 395 return false;
393 } 396 }
394 397
395 bool reload(){ 398 bool reload(){
396 /* Reload is the same as load in this implementation */ 399 /* Reload is the same as load in this implementation */
397 return ( load() ); 400 return ( load() );
398 } 401 }
399 402
400 private: 403 private:
404
405 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
406
401 void addContact_p( const OContact &newcontact ){ 407 void addContact_p( const OContact &newcontact ){
402 m_contactList.append (newcontact); 408 m_contactList.append (newcontact);
403 } 409 }
404 410
405 /* This function loads the xml-database and the journalfile */ 411 /* This function loads the xml-database and the journalfile */
406 bool load( const QString filename, bool isJournal ) { 412 bool load( const QString filename, bool isJournal ) {
407 413
408 /* We use the time of the last read to check if the file was 414 /* We use the time of the last read to check if the file was
409 * changed externally. 415 * changed externally.
410 */ 416 */
411 if ( !isJournal ){ 417 if ( !isJournal ){
412 QFileInfo fi( filename ); 418 QFileInfo fi( filename );
413 m_readtime = fi.lastModified (); 419 m_readtime = fi.lastModified ();
414 } 420 }
415 421
416 const int JOURNALACTION = Qtopia::Notes + 1; 422 const int JOURNALACTION = Qtopia::Notes + 1;
417 const int JOURNALROW = JOURNALACTION + 1; 423 const int JOURNALROW = JOURNALACTION + 1;
418 424
419 bool foundAction = false; 425 bool foundAction = false;
420 OContact::journal_action action = OContact::ACTION_ADD; 426 journal_action action = ACTION_ADD;
421 int journalKey = 0; 427 int journalKey = 0;
422 QMap<int, QString> contactMap; 428 QMap<int, QString> contactMap;
423 QMap<QString, QString> customMap; 429 QMap<QString, QString> customMap;
424 QMap<QString, QString>::Iterator customIt; 430 QMap<QString, QString>::Iterator customIt;
425 QAsciiDict<int> dict( 47 ); 431 QAsciiDict<int> dict( 47 );
426 432
427 dict.setAutoDelete( TRUE ); 433 dict.setAutoDelete( TRUE );
428 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 434 dict.insert( "Uid", new int(Qtopia::AddressUid) );
429 dict.insert( "Title", new int(Qtopia::Title) ); 435 dict.insert( "Title", new int(Qtopia::Title) );
430 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 436 dict.insert( "FirstName", new int(Qtopia::FirstName) );
431 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 437 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
432 dict.insert( "LastName", new int(Qtopia::LastName) ); 438 dict.insert( "LastName", new int(Qtopia::LastName) );
433 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 439 dict.insert( "Suffix", new int(Qtopia::Suffix) );
434 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 440 dict.insert( "FileAs", new int(Qtopia::FileAs) );
435 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 441 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
436 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 442 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
437 dict.insert( "Emails", new int(Qtopia::Emails) ); 443 dict.insert( "Emails", new int(Qtopia::Emails) );
438 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 444 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
439 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 445 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
440 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 446 dict.insert( "HomeState", new int(Qtopia::HomeState) );
441 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 447 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
442 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 448 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
443 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 449 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
444 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 450 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
@@ -517,106 +523,106 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
517 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 523 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
518 524
519 int *find = dict[ it.key() ]; 525 int *find = dict[ it.key() ];
520 /* Unknown attributes will be stored as "Custom" elements */ 526 /* Unknown attributes will be stored as "Custom" elements */
521 if ( !find ) { 527 if ( !find ) {
522 qWarning("Attribute %s not known.", it.key().latin1()); 528 qWarning("Attribute %s not known.", it.key().latin1());
523 //contact.setCustomField(it.key(), it.data()); 529 //contact.setCustomField(it.key(), it.data());
524 customMap.insert( it.key(), it.data() ); 530 customMap.insert( it.key(), it.data() );
525 continue; 531 continue;
526 } 532 }
527 533
528 /* Check if special conversion is needed and add attribute 534 /* Check if special conversion is needed and add attribute
529 * into Contact class 535 * into Contact class
530 */ 536 */
531 switch( *find ) { 537 switch( *find ) {
532 /* 538 /*
533 case Qtopia::AddressUid: 539 case Qtopia::AddressUid:
534 contact.setUid( it.data().toInt() ); 540 contact.setUid( it.data().toInt() );
535 break; 541 break;
536 case Qtopia::AddressCategory: 542 case Qtopia::AddressCategory:
537 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 543 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
538 break; 544 break;
539 */ 545 */
540 case JOURNALACTION: 546 case JOURNALACTION:
541 action = OContact::journal_action(it.data().toInt()); 547 action = journal_action(it.data().toInt());
542 foundAction = true; 548 foundAction = true;
543 qWarning ("ODefBack(journal)::ACTION found: %d", action); 549 qWarning ("ODefBack(journal)::ACTION found: %d", action);
544 break; 550 break;
545 case JOURNALROW: 551 case JOURNALROW:
546 journalKey = it.data().toInt(); 552 journalKey = it.data().toInt();
547 break; 553 break;
548 default: // no conversion needed add them to the map 554 default: // no conversion needed add them to the map
549 contactMap.insert( *find, it.data() ); 555 contactMap.insert( *find, it.data() );
550 break; 556 break;
551 } 557 }
552 } 558 }
553 /* now generate the Contact contact */ 559 /* now generate the Contact contact */
554 OContact contact( contactMap ); 560 OContact contact( contactMap );
555 561
556 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 562 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
557 contact.setCustomField( customIt.key(), customIt.data() ); 563 contact.setCustomField( customIt.key(), customIt.data() );
558 } 564 }
559 565
560 if (foundAction){ 566 if (foundAction){
561 foundAction = false; 567 foundAction = false;
562 switch ( action ) { 568 switch ( action ) {
563 case OContact::ACTION_ADD: 569 case ACTION_ADD:
564 addContact_p (contact); 570 addContact_p (contact);
565 break; 571 break;
566 case OContact::ACTION_REMOVE: 572 case ACTION_REMOVE:
567 if ( !remove (contact.uid()) ) 573 if ( !remove (contact.uid()) )
568 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 574 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
569 contact.uid() ); 575 contact.uid() );
570 break; 576 break;
571 case OContact::ACTION_REPLACE: 577 case ACTION_REPLACE:
572 if ( !replace ( contact ) ) 578 if ( !replace ( contact ) )
573 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 579 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
574 contact.uid() ); 580 contact.uid() );
575 break; 581 break;
576 default: 582 default:
577 qWarning ("Unknown action: ignored !"); 583 qWarning ("Unknown action: ignored !");
578 break; 584 break;
579 } 585 }
580 }else{ 586 }else{
581 /* Add contact to list */ 587 /* Add contact to list */
582 addContact_p (contact); 588 addContact_p (contact);
583 } 589 }
584 590
585 /* Move to next element */ 591 /* Move to next element */
586 element = element->nextChild(); 592 element = element->nextChild();
587 } 593 }
588 }else { 594 }else {
589 qWarning("ODefBack::could not load"); 595 qWarning("ODefBack::could not load");
590 } 596 }
591 delete root; 597 delete root;
592 qWarning("returning from loading" ); 598 qWarning("returning from loading" );
593 return true; 599 return true;
594 } 600 }
595 601
596 602
597 void updateJournal( const OContact& cnt, 603 void updateJournal( const OContact& cnt,
598 OContact::journal_action action ) { 604 journal_action action ) {
599 QFile f( m_journalName ); 605 QFile f( m_journalName );
600 bool created = !f.exists(); 606 bool created = !f.exists();
601 if ( !f.open(IO_WriteOnly|IO_Append) ) 607 if ( !f.open(IO_WriteOnly|IO_Append) )
602 return; 608 return;
603 609
604 QString buf; 610 QString buf;
605 QCString str; 611 QCString str;
606 612
607 // if the file was created, we have to set the Tag "<CONTACTS>" to 613 // if the file was created, we have to set the Tag "<CONTACTS>" to
608 // get a XML-File which is readable by our parser. 614 // get a XML-File which is readable by our parser.
609 // This is just a cheat, but better than rewrite the parser. 615 // This is just a cheat, but better than rewrite the parser.
610 if ( created ){ 616 if ( created ){
611 buf = "<Contacts>"; 617 buf = "<Contacts>";
612 QCString cstr = buf.utf8(); 618 QCString cstr = buf.utf8();
613 f.writeBlock( cstr.data(), cstr.length() ); 619 f.writeBlock( cstr.data(), cstr.length() );
614 } 620 }
615 621
616 buf = "<Contact "; 622 buf = "<Contact ";
617 cnt.save( buf ); 623 cnt.save( buf );
618 buf += " action=\"" + QString::number( (int)action ) + "\" "; 624 buf += " action=\"" + QString::number( (int)action ) + "\" ";
619 buf += "/>\n"; 625 buf += "/>\n";
620 QCString cstr = buf.utf8(); 626 QCString cstr = buf.utf8();
621 f.writeBlock( cstr.data(), cstr.length() ); 627 f.writeBlock( cstr.data(), cstr.length() );
622 } 628 }
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
index ae6ec9e..c765ff5 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h
@@ -1,43 +1,46 @@
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.9 2002/12/08 12:48:57 eilers
21 * Moved journal-enum from ocontact into i the xml-backend..
22 *
20 * Revision 1.8 2002/11/14 17:04:24 eilers 23 * Revision 1.8 2002/11/14 17:04:24 eilers
21 * Sorting will now work if fullname is identical on some entries 24 * Sorting will now work if fullname is identical on some entries
22 * 25 *
23 * Revision 1.7 2002/11/13 15:02:46 eilers 26 * Revision 1.7 2002/11/13 15:02:46 eilers
24 * Small Bug in sorted fixed 27 * Small Bug in sorted fixed
25 * 28 *
26 * Revision 1.6 2002/11/13 14:14:51 eilers 29 * Revision 1.6 2002/11/13 14:14:51 eilers
27 * Added sorted for Contacts.. 30 * Added sorted for Contacts..
28 * 31 *
29 * Revision 1.5 2002/11/01 15:10:42 eilers 32 * Revision 1.5 2002/11/01 15:10:42 eilers
30 * Added regExp-search in database for all fields in a contact. 33 * Added regExp-search in database for all fields in a contact.
31 * 34 *
32 * Revision 1.4 2002/10/16 10:52:40 eilers 35 * Revision 1.4 2002/10/16 10:52:40 eilers
33 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 36 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
34 * 37 *
35 * Revision 1.3 2002/10/14 16:21:54 eilers 38 * Revision 1.3 2002/10/14 16:21:54 eilers
36 * Some minor interface updates 39 * Some minor interface updates
37 * 40 *
38 * Revision 1.2 2002/10/07 17:34:24 eilers 41 * Revision 1.2 2002/10/07 17:34:24 eilers
39 * added OBackendFactory for advanced backend access 42 * added OBackendFactory for advanced backend access
40 * 43 *
41 * Revision 1.1 2002/09/27 17:11:44 eilers 44 * Revision 1.1 2002/09/27 17:11:44 eilers
42 * Added API for accessing the Contact-Database ! It is compiling, but 45 * Added API for accessing the Contact-Database ! It is compiling, but
43 * please do not expect that anything is working ! 46 * please do not expect that anything is working !
@@ -321,124 +324,127 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
321 // First fill map and StringList with all Names 324 // First fill map and StringList with all Names
322 // Afterwards sort namelist and use map to fill array to return.. 325 // Afterwards sort namelist and use map to fill array to return..
323 QValueListConstIterator<OContact> it; 326 QValueListConstIterator<OContact> it;
324 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 327 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
325 names.append( (*it).fileAs() + QString::number( (*it).uid() ) ); 328 names.append( (*it).fileAs() + QString::number( (*it).uid() ) );
326 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() ); 329 nameToUid.insert( (*it).fileAs() + QString::number( (*it).uid() ), (*it).uid() );
327 } 330 }
328 names.sort(); 331 names.sort();
329 332
330 int i = 0; 333 int i = 0;
331 if ( asc ){ 334 if ( asc ){
332 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 335 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
333 m_currentQuery[i++] = nameToUid[ (*it) ]; 336 m_currentQuery[i++] = nameToUid[ (*it) ];
334 }else{ 337 }else{
335 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 338 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
336 m_currentQuery[i++] = nameToUid[ (*it) ]; 339 m_currentQuery[i++] = nameToUid[ (*it) ];
337 } 340 }
338 341
339 return m_currentQuery; 342 return m_currentQuery;
340 343
341 } 344 }
342 bool add ( const OContact &newcontact ) 345 bool add ( const OContact &newcontact )
343 { 346 {
344 //qWarning("odefaultbackend: ACTION::ADD"); 347 //qWarning("odefaultbackend: ACTION::ADD");
345 updateJournal (newcontact, OContact::ACTION_ADD); 348 updateJournal (newcontact, ACTION_ADD);
346 addContact_p( newcontact ); 349 addContact_p( newcontact );
347 350
348 m_changed = true; 351 m_changed = true;
349 352
350 return true; 353 return true;
351 } 354 }
352 355
353 bool replace ( const OContact &contact ) 356 bool replace ( const OContact &contact )
354 { 357 {
355 m_changed = true; 358 m_changed = true;
356 359
357 bool found = false; 360 bool found = false;
358 361
359 QValueListIterator<OContact> it; 362 QValueListIterator<OContact> it;
360 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 363 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
361 if ( (*it).uid() == contact.uid() ){ 364 if ( (*it).uid() == contact.uid() ){
362 found = true; 365 found = true;
363 break; 366 break;
364 } 367 }
365 } 368 }
366 if (found) { 369 if (found) {
367 updateJournal (contact, OContact::ACTION_REPLACE); 370 updateJournal (contact, ACTION_REPLACE);
368 m_contactList.remove (it); 371 m_contactList.remove (it);
369 m_contactList.append (contact); 372 m_contactList.append (contact);
370 return true; 373 return true;
371 } else 374 } else
372 return false; 375 return false;
373 } 376 }
374 377
375 bool remove ( int uid ) 378 bool remove ( int uid )
376 { 379 {
377 m_changed = true; 380 m_changed = true;
378 381
379 bool found = false; 382 bool found = false;
380 QValueListIterator<OContact> it; 383 QValueListIterator<OContact> it;
381 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ 384 for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){
382 if ((*it).uid() == uid){ 385 if ((*it).uid() == uid){
383 found = true; 386 found = true;
384 break; 387 break;
385 } 388 }
386 } 389 }
387 if (found) { 390 if (found) {
388 updateJournal ( *it, OContact::ACTION_REMOVE); 391 updateJournal ( *it, ACTION_REMOVE);
389 m_contactList.remove (it); 392 m_contactList.remove (it);
390 return true; 393 return true;
391 } else 394 } else
392 return false; 395 return false;
393 } 396 }
394 397
395 bool reload(){ 398 bool reload(){
396 /* Reload is the same as load in this implementation */ 399 /* Reload is the same as load in this implementation */
397 return ( load() ); 400 return ( load() );
398 } 401 }
399 402
400 private: 403 private:
404
405 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
406
401 void addContact_p( const OContact &newcontact ){ 407 void addContact_p( const OContact &newcontact ){
402 m_contactList.append (newcontact); 408 m_contactList.append (newcontact);
403 } 409 }
404 410
405 /* This function loads the xml-database and the journalfile */ 411 /* This function loads the xml-database and the journalfile */
406 bool load( const QString filename, bool isJournal ) { 412 bool load( const QString filename, bool isJournal ) {
407 413
408 /* We use the time of the last read to check if the file was 414 /* We use the time of the last read to check if the file was
409 * changed externally. 415 * changed externally.
410 */ 416 */
411 if ( !isJournal ){ 417 if ( !isJournal ){
412 QFileInfo fi( filename ); 418 QFileInfo fi( filename );
413 m_readtime = fi.lastModified (); 419 m_readtime = fi.lastModified ();
414 } 420 }
415 421
416 const int JOURNALACTION = Qtopia::Notes + 1; 422 const int JOURNALACTION = Qtopia::Notes + 1;
417 const int JOURNALROW = JOURNALACTION + 1; 423 const int JOURNALROW = JOURNALACTION + 1;
418 424
419 bool foundAction = false; 425 bool foundAction = false;
420 OContact::journal_action action = OContact::ACTION_ADD; 426 journal_action action = ACTION_ADD;
421 int journalKey = 0; 427 int journalKey = 0;
422 QMap<int, QString> contactMap; 428 QMap<int, QString> contactMap;
423 QMap<QString, QString> customMap; 429 QMap<QString, QString> customMap;
424 QMap<QString, QString>::Iterator customIt; 430 QMap<QString, QString>::Iterator customIt;
425 QAsciiDict<int> dict( 47 ); 431 QAsciiDict<int> dict( 47 );
426 432
427 dict.setAutoDelete( TRUE ); 433 dict.setAutoDelete( TRUE );
428 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 434 dict.insert( "Uid", new int(Qtopia::AddressUid) );
429 dict.insert( "Title", new int(Qtopia::Title) ); 435 dict.insert( "Title", new int(Qtopia::Title) );
430 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 436 dict.insert( "FirstName", new int(Qtopia::FirstName) );
431 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 437 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
432 dict.insert( "LastName", new int(Qtopia::LastName) ); 438 dict.insert( "LastName", new int(Qtopia::LastName) );
433 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 439 dict.insert( "Suffix", new int(Qtopia::Suffix) );
434 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 440 dict.insert( "FileAs", new int(Qtopia::FileAs) );
435 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 441 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
436 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 442 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
437 dict.insert( "Emails", new int(Qtopia::Emails) ); 443 dict.insert( "Emails", new int(Qtopia::Emails) );
438 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 444 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
439 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 445 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
440 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 446 dict.insert( "HomeState", new int(Qtopia::HomeState) );
441 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 447 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
442 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 448 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
443 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 449 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
444 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 450 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
@@ -517,106 +523,106 @@ class OContactAccessBackend_XML : public OContactAccessBackend {
517 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 523 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
518 524
519 int *find = dict[ it.key() ]; 525 int *find = dict[ it.key() ];
520 /* Unknown attributes will be stored as "Custom" elements */ 526 /* Unknown attributes will be stored as "Custom" elements */
521 if ( !find ) { 527 if ( !find ) {
522 qWarning("Attribute %s not known.", it.key().latin1()); 528 qWarning("Attribute %s not known.", it.key().latin1());
523 //contact.setCustomField(it.key(), it.data()); 529 //contact.setCustomField(it.key(), it.data());
524 customMap.insert( it.key(), it.data() ); 530 customMap.insert( it.key(), it.data() );
525 continue; 531 continue;
526 } 532 }
527 533
528 /* Check if special conversion is needed and add attribute 534 /* Check if special conversion is needed and add attribute
529 * into Contact class 535 * into Contact class
530 */ 536 */
531 switch( *find ) { 537 switch( *find ) {
532 /* 538 /*
533 case Qtopia::AddressUid: 539 case Qtopia::AddressUid:
534 contact.setUid( it.data().toInt() ); 540 contact.setUid( it.data().toInt() );
535 break; 541 break;
536 case Qtopia::AddressCategory: 542 case Qtopia::AddressCategory:
537 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 543 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
538 break; 544 break;
539 */ 545 */
540 case JOURNALACTION: 546 case JOURNALACTION:
541 action = OContact::journal_action(it.data().toInt()); 547 action = journal_action(it.data().toInt());
542 foundAction = true; 548 foundAction = true;
543 qWarning ("ODefBack(journal)::ACTION found: %d", action); 549 qWarning ("ODefBack(journal)::ACTION found: %d", action);
544 break; 550 break;
545 case JOURNALROW: 551 case JOURNALROW:
546 journalKey = it.data().toInt(); 552 journalKey = it.data().toInt();
547 break; 553 break;
548 default: // no conversion needed add them to the map 554 default: // no conversion needed add them to the map
549 contactMap.insert( *find, it.data() ); 555 contactMap.insert( *find, it.data() );
550 break; 556 break;
551 } 557 }
552 } 558 }
553 /* now generate the Contact contact */ 559 /* now generate the Contact contact */
554 OContact contact( contactMap ); 560 OContact contact( contactMap );
555 561
556 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 562 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
557 contact.setCustomField( customIt.key(), customIt.data() ); 563 contact.setCustomField( customIt.key(), customIt.data() );
558 } 564 }
559 565
560 if (foundAction){ 566 if (foundAction){
561 foundAction = false; 567 foundAction = false;
562 switch ( action ) { 568 switch ( action ) {
563 case OContact::ACTION_ADD: 569 case ACTION_ADD:
564 addContact_p (contact); 570 addContact_p (contact);
565 break; 571 break;
566 case OContact::ACTION_REMOVE: 572 case ACTION_REMOVE:
567 if ( !remove (contact.uid()) ) 573 if ( !remove (contact.uid()) )
568 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 574 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
569 contact.uid() ); 575 contact.uid() );
570 break; 576 break;
571 case OContact::ACTION_REPLACE: 577 case ACTION_REPLACE:
572 if ( !replace ( contact ) ) 578 if ( !replace ( contact ) )
573 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 579 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
574 contact.uid() ); 580 contact.uid() );
575 break; 581 break;
576 default: 582 default:
577 qWarning ("Unknown action: ignored !"); 583 qWarning ("Unknown action: ignored !");
578 break; 584 break;
579 } 585 }
580 }else{ 586 }else{
581 /* Add contact to list */ 587 /* Add contact to list */
582 addContact_p (contact); 588 addContact_p (contact);
583 } 589 }
584 590
585 /* Move to next element */ 591 /* Move to next element */
586 element = element->nextChild(); 592 element = element->nextChild();
587 } 593 }
588 }else { 594 }else {
589 qWarning("ODefBack::could not load"); 595 qWarning("ODefBack::could not load");
590 } 596 }
591 delete root; 597 delete root;
592 qWarning("returning from loading" ); 598 qWarning("returning from loading" );
593 return true; 599 return true;
594 } 600 }
595 601
596 602
597 void updateJournal( const OContact& cnt, 603 void updateJournal( const OContact& cnt,
598 OContact::journal_action action ) { 604 journal_action action ) {
599 QFile f( m_journalName ); 605 QFile f( m_journalName );
600 bool created = !f.exists(); 606 bool created = !f.exists();
601 if ( !f.open(IO_WriteOnly|IO_Append) ) 607 if ( !f.open(IO_WriteOnly|IO_Append) )
602 return; 608 return;
603 609
604 QString buf; 610 QString buf;
605 QCString str; 611 QCString str;
606 612
607 // if the file was created, we have to set the Tag "<CONTACTS>" to 613 // if the file was created, we have to set the Tag "<CONTACTS>" to
608 // get a XML-File which is readable by our parser. 614 // get a XML-File which is readable by our parser.
609 // This is just a cheat, but better than rewrite the parser. 615 // This is just a cheat, but better than rewrite the parser.
610 if ( created ){ 616 if ( created ){
611 buf = "<Contacts>"; 617 buf = "<Contacts>";
612 QCString cstr = buf.utf8(); 618 QCString cstr = buf.utf8();
613 f.writeBlock( cstr.data(), cstr.length() ); 619 f.writeBlock( cstr.data(), cstr.length() );
614 } 620 }
615 621
616 buf = "<Contact "; 622 buf = "<Contact ";
617 cnt.save( buf ); 623 cnt.save( buf );
618 buf += " action=\"" + QString::number( (int)action ) + "\" "; 624 buf += " action=\"" + QString::number( (int)action ) + "\" ";
619 buf += "/>\n"; 625 buf += "/>\n";
620 QCString cstr = buf.utf8(); 626 QCString cstr = buf.utf8();
621 f.writeBlock( cstr.data(), cstr.length() ); 627 f.writeBlock( cstr.data(), cstr.length() );
622 } 628 }
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h
index 65ba43e..1fd1c75 100644
--- a/libopie2/opiepim/ocontact.h
+++ b/libopie2/opiepim/ocontact.h
@@ -23,50 +23,48 @@
23#define __OCONTACT_H__ 23#define __OCONTACT_H__
24 24
25#include <opie/opimrecord.h> 25#include <opie/opimrecord.h>
26#include <qpe/recordfields.h> 26#include <qpe/recordfields.h>
27 27
28#include <qdatetime.h> 28#include <qdatetime.h>
29#include <qstringlist.h> 29#include <qstringlist.h>
30 30
31#if defined(QPC_TEMPLATEDLL) 31#if defined(QPC_TEMPLATEDLL)
32// MOC_SKIP_BEGIN 32// MOC_SKIP_BEGIN
33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; 33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
34// MOC_SKIP_END 34// MOC_SKIP_END
35#endif 35#endif
36 36
37class ContactPrivate; 37class ContactPrivate;
38 38
39class QPC_EXPORT OContact : public OPimRecord 39class QPC_EXPORT OContact : public OPimRecord
40{ 40{
41 friend class DataSet; 41 friend class DataSet;
42public: 42public:
43 OContact(); 43 OContact();
44 OContact( const QMap<int, QString> &fromMap ); 44 OContact( const QMap<int, QString> &fromMap );
45 virtual ~OContact(); 45 virtual ~OContact();
46 46
47 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
48
49 /* 47 /*
50 * do we need to inline them 48 * do we need to inline them
51 * if yes do we need to inline them this way? 49 * if yes do we need to inline them this way?
52 * -zecke 50 * -zecke
53 */ 51 */
54 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } 52 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
55 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } 53 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
56 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } 54 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
57 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } 55 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
58 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } 56 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
59 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } 57 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
60 void setFileAs(); 58 void setFileAs();
61 59
62 // default email address 60 // default email address
63 void setDefaultEmail( const QString &v ); 61 void setDefaultEmail( const QString &v );
64 // inserts email to list and ensure's doesn't already exist 62 // inserts email to list and ensure's doesn't already exist
65 void insertEmail( const QString &v ); 63 void insertEmail( const QString &v );
66 void removeEmail( const QString &v ); 64 void removeEmail( const QString &v );
67 void clearEmails(); 65 void clearEmails();
68 void insertEmails( const QStringList &v ); 66 void insertEmails( const QStringList &v );
69 67
70 // home 68 // home
71 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } 69 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
72 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } 70 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }