summaryrefslogtreecommitdiff
authoreilers <eilers>2003-08-30 15:28:26 (UTC)
committer eilers <eilers>2003-08-30 15:28:26 (UTC)
commit9f07321949f8baf1a64db0e4caec58041d3f775f (patch) (unidiff)
treec80bf99717bd81ce4393aa40bbbdf11fbb3f7457
parentd9b5fcc45b1fef5ac11ef549a47561c7382ff451 (diff)
downloadopie-9f07321949f8baf1a64db0e4caec58041d3f775f.zip
opie-9f07321949f8baf1a64db0e4caec58041d3f775f.tar.gz
opie-9f07321949f8baf1a64db0e4caec58041d3f775f.tar.bz2
Removed some unimportant debug output which causes slow down..
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontact.cpp4
-rw-r--r--libopie/pim/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp7
-rw-r--r--libopie2/opiepim/ocontact.cpp4
4 files changed, 14 insertions, 8 deletions
diff --git a/libopie/pim/ocontact.cpp b/libopie/pim/ocontact.cpp
index e34feeb..0f05b65 100644
--- a/libopie/pim/ocontact.cpp
+++ b/libopie/pim/ocontact.cpp
@@ -598,614 +598,614 @@ QString OContact::toRichText() const
598 text += "<br>" + Qtopia::escapeString(state); 598 text += "<br>" + Qtopia::escapeString(state);
599 marker = true; 599 marker = true;
600 } 600 }
601 break; 601 break;
602 } 602 }
603 case City_State_Zip:{ // City, State Zip_Code 603 case City_State_Zip:{ // City, State Zip_Code
604 state = homeState(); 604 state = homeState();
605 if ( !(value = homeCity()).isEmpty() ) { 605 if ( !(value = homeCity()).isEmpty() ) {
606 marker = true; 606 marker = true;
607 text += "<br>" + Qtopia::escapeString(value); 607 text += "<br>" + Qtopia::escapeString(value);
608 if ( state ) 608 if ( state )
609 text += ", " + Qtopia::escapeString(state); 609 text += ", " + Qtopia::escapeString(state);
610 } else if ( !state.isEmpty() ){ 610 } else if ( !state.isEmpty() ){
611 text += "<br>" + Qtopia::escapeString(state); 611 text += "<br>" + Qtopia::escapeString(state);
612 marker = true; 612 marker = true;
613 } 613 }
614 if ( !(value = homeZip()).isEmpty() ){ 614 if ( !(value = homeZip()).isEmpty() ){
615 text += " " + Qtopia::escapeString(value); 615 text += " " + Qtopia::escapeString(value);
616 marker = true; 616 marker = true;
617 } 617 }
618 break; 618 break;
619 } 619 }
620 } 620 }
621 621
622 if ( !(value = homeCountry()).isEmpty() ){ 622 if ( !(value = homeCountry()).isEmpty() ){
623 text += "<br>" + Qtopia::escapeString(value); 623 text += "<br>" + Qtopia::escapeString(value);
624 marker = true; 624 marker = true;
625 } 625 }
626 626
627 // rest of Home data 627 // rest of Home data
628 str = homeWebpage(); 628 str = homeWebpage();
629 if ( !str.isEmpty() ){ 629 if ( !str.isEmpty() ){
630 text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr("Home Web Page: ") + "</b>" 630 text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr("Home Web Page: ") + "</b>"
631 + Qtopia::escapeString(str); 631 + Qtopia::escapeString(str);
632 marker = true; 632 marker = true;
633 } 633 }
634 str = homePhone(); 634 str = homePhone();
635 if ( !str.isEmpty() ){ 635 if ( !str.isEmpty() ){
636 text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr("Home Phone: ") + "</b>" 636 text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr("Home Phone: ") + "</b>"
637 + Qtopia::escapeString(str); 637 + Qtopia::escapeString(str);
638 marker = true; 638 marker = true;
639 } 639 }
640 str = homeFax(); 640 str = homeFax();
641 if ( !str.isEmpty() ){ 641 if ( !str.isEmpty() ){
642 text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr("Home Fax: ") + "</b>" 642 text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr("Home Fax: ") + "</b>"
643 + Qtopia::escapeString(str); 643 + Qtopia::escapeString(str);
644 marker = true; 644 marker = true;
645 } 645 }
646 str = homeMobile(); 646 str = homeMobile();
647 if ( !str.isEmpty() ){ 647 if ( !str.isEmpty() ){
648 text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr("Home Mobile: ") + "</b>" 648 text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr("Home Mobile: ") + "</b>"
649 + Qtopia::escapeString(str); 649 + Qtopia::escapeString(str);
650 marker = true; 650 marker = true;
651 } 651 }
652 652
653 if ( marker ) 653 if ( marker )
654 text += "<br><hr>"; 654 text += "<br><hr>";
655 655
656 // the rest... 656 // the rest...
657 str = emails(); 657 str = emails();
658 if ( !str.isEmpty() && ( str != defEmail ) ) 658 if ( !str.isEmpty() && ( str != defEmail ) )
659 text += "<br><b>" + QObject::tr("All Emails: ") + "</b>" 659 text += "<br><b>" + QObject::tr("All Emails: ") + "</b>"
660 + Qtopia::escapeString(str); 660 + Qtopia::escapeString(str);
661 str = profession(); 661 str = profession();
662 if ( !str.isEmpty() ) 662 if ( !str.isEmpty() )
663 text += "<br><b>" + QObject::tr("Profession: ") + "</b>" 663 text += "<br><b>" + QObject::tr("Profession: ") + "</b>"
664 + Qtopia::escapeString(str); 664 + Qtopia::escapeString(str);
665 str = assistant(); 665 str = assistant();
666 if ( !str.isEmpty() ) 666 if ( !str.isEmpty() )
667 text += "<br><b>" + QObject::tr("Assistant: ") + "</b>" 667 text += "<br><b>" + QObject::tr("Assistant: ") + "</b>"
668 + Qtopia::escapeString(str); 668 + Qtopia::escapeString(str);
669 str = manager(); 669 str = manager();
670 if ( !str.isEmpty() ) 670 if ( !str.isEmpty() )
671 text += "<br><b>" + QObject::tr("Manager: ") + "</b>" 671 text += "<br><b>" + QObject::tr("Manager: ") + "</b>"
672 + Qtopia::escapeString(str); 672 + Qtopia::escapeString(str);
673 str = gender(); 673 str = gender();
674 if ( !str.isEmpty() && str.toInt() != 0 ) { 674 if ( !str.isEmpty() && str.toInt() != 0 ) {
675 text += "<br>"; 675 text += "<br>";
676 if ( str.toInt() == 1 ) 676 if ( str.toInt() == 1 )
677 str = QObject::tr( "Male" ); 677 str = QObject::tr( "Male" );
678 else if ( str.toInt() == 2 ) 678 else if ( str.toInt() == 2 )
679 str = QObject::tr( "Female" ); 679 str = QObject::tr( "Female" );
680 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str; 680 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str;
681 } 681 }
682 str = spouse(); 682 str = spouse();
683 if ( !str.isEmpty() ) 683 if ( !str.isEmpty() )
684 text += "<br><b>" + QObject::tr("Spouse: ") + "</b>" 684 text += "<br><b>" + QObject::tr("Spouse: ") + "</b>"
685 + Qtopia::escapeString(str); 685 + Qtopia::escapeString(str);
686 if ( birthday().isValid() ){ 686 if ( birthday().isValid() ){
687 str = TimeString::numberDateString( birthday() ); 687 str = TimeString::numberDateString( birthday() );
688 text += "<br><b>" + QObject::tr("Birthday: ") + "</b>" 688 text += "<br><b>" + QObject::tr("Birthday: ") + "</b>"
689 + Qtopia::escapeString(str); 689 + Qtopia::escapeString(str);
690 } 690 }
691 if ( anniversary().isValid() ){ 691 if ( anniversary().isValid() ){
692 str = TimeString::numberDateString( anniversary() ); 692 str = TimeString::numberDateString( anniversary() );
693 text += "<br><b>" + QObject::tr("Anniversary: ") + "</b>" 693 text += "<br><b>" + QObject::tr("Anniversary: ") + "</b>"
694 + Qtopia::escapeString(str); 694 + Qtopia::escapeString(str);
695 } 695 }
696 str = children(); 696 str = children();
697 if ( !str.isEmpty() ) 697 if ( !str.isEmpty() )
698 text += "<br><b>" + QObject::tr("Children: ") + "</b>" 698 text += "<br><b>" + QObject::tr("Children: ") + "</b>"
699 + Qtopia::escapeString(str); 699 + Qtopia::escapeString(str);
700 700
701 str = nickname(); 701 str = nickname();
702 if ( !str.isEmpty() ) 702 if ( !str.isEmpty() )
703 text += "<br><b>" + QObject::tr("Nickname: ") + "</b>" 703 text += "<br><b>" + QObject::tr("Nickname: ") + "</b>"
704 + Qtopia::escapeString(str); 704 + Qtopia::escapeString(str);
705 705
706 // categories 706 // categories
707 if ( categoryNames("Contacts").count() ){ 707 if ( categoryNames("Contacts").count() ){
708 text += "<br><b>" + QObject::tr( "Category:") + "</b> "; 708 text += "<br><b>" + QObject::tr( "Category:") + "</b> ";
709 text += categoryNames("Contacts").join(", "); 709 text += categoryNames("Contacts").join(", ");
710 } 710 }
711 711
712 // notes last 712 // notes last
713 if ( !(value = notes()).isEmpty() ) { 713 if ( !(value = notes()).isEmpty() ) {
714 text += "<br><hr><b>" + QObject::tr( "Notes:") + "</b> "; 714 text += "<br><hr><b>" + QObject::tr( "Notes:") + "</b> ";
715 QRegExp reg("\n"); 715 QRegExp reg("\n");
716 716
717 //QString tmp = Qtopia::escapeString(value); 717 //QString tmp = Qtopia::escapeString(value);
718 QString tmp = QStyleSheet::convertFromPlainText(value); 718 QString tmp = QStyleSheet::convertFromPlainText(value);
719 //tmp.replace( reg, "<br>" ); 719 //tmp.replace( reg, "<br>" );
720 text += "<br>" + tmp + "<br>"; 720 text += "<br>" + tmp + "<br>";
721 } 721 }
722 return text; 722 return text;
723} 723}
724 724
725/*! 725/*!
726 \internal 726 \internal
727*/ 727*/
728void OContact::insert( int key, const QString &v ) 728void OContact::insert( int key, const QString &v )
729{ 729{
730 QString value = v.stripWhiteSpace(); 730 QString value = v.stripWhiteSpace();
731 if ( value.isEmpty() ) 731 if ( value.isEmpty() )
732 mMap.remove( key ); 732 mMap.remove( key );
733 else 733 else
734 mMap.insert( key, value ); 734 mMap.insert( key, value );
735} 735}
736 736
737/*! 737/*!
738 \internal 738 \internal
739*/ 739*/
740void OContact::replace( int key, const QString & v ) 740void OContact::replace( int key, const QString & v )
741{ 741{
742 QString value = v.stripWhiteSpace(); 742 QString value = v.stripWhiteSpace();
743 if ( value.isEmpty() ) 743 if ( value.isEmpty() )
744 mMap.remove( key ); 744 mMap.remove( key );
745 else 745 else
746 mMap.replace( key, value ); 746 mMap.replace( key, value );
747} 747}
748 748
749/*! 749/*!
750 \internal 750 \internal
751*/ 751*/
752QString OContact::find( int key ) const 752QString OContact::find( int key ) const
753{ 753{
754 return mMap[key]; 754 return mMap[key];
755} 755}
756 756
757/*! 757/*!
758 \internal 758 \internal
759*/ 759*/
760QString OContact::displayAddress( const QString &street, 760QString OContact::displayAddress( const QString &street,
761 const QString &city, 761 const QString &city,
762 const QString &state, 762 const QString &state,
763 const QString &zip, 763 const QString &zip,
764 const QString &country ) const 764 const QString &country ) const
765{ 765{
766 QString s = street; 766 QString s = street;
767 if ( !street.isEmpty() ) 767 if ( !street.isEmpty() )
768 s+= "\n"; 768 s+= "\n";
769 s += city; 769 s += city;
770 if ( !city.isEmpty() && !state.isEmpty() ) 770 if ( !city.isEmpty() && !state.isEmpty() )
771 s += ", "; 771 s += ", ";
772 s += state; 772 s += state;
773 if ( !state.isEmpty() && !zip.isEmpty() ) 773 if ( !state.isEmpty() && !zip.isEmpty() )
774 s += " "; 774 s += " ";
775 s += zip; 775 s += zip;
776 if ( !country.isEmpty() && !s.isEmpty() ) 776 if ( !country.isEmpty() && !s.isEmpty() )
777 s += "\n"; 777 s += "\n";
778 s += country; 778 s += country;
779 return s; 779 return s;
780} 780}
781 781
782/*! 782/*!
783 \internal 783 \internal
784*/ 784*/
785QString OContact::displayBusinessAddress() const 785QString OContact::displayBusinessAddress() const
786{ 786{
787 return displayAddress( businessStreet(), businessCity(), 787 return displayAddress( businessStreet(), businessCity(),
788 businessState(), businessZip(), 788 businessState(), businessZip(),
789 businessCountry() ); 789 businessCountry() );
790} 790}
791 791
792/*! 792/*!
793 \internal 793 \internal
794*/ 794*/
795QString OContact::displayHomeAddress() const 795QString OContact::displayHomeAddress() const
796{ 796{
797 return displayAddress( homeStreet(), homeCity(), 797 return displayAddress( homeStreet(), homeCity(),
798 homeState(), homeZip(), 798 homeState(), homeZip(),
799 homeCountry() ); 799 homeCountry() );
800} 800}
801 801
802/*! 802/*!
803 Returns the full name of the contact 803 Returns the full name of the contact
804*/ 804*/
805QString OContact::fullName() const 805QString OContact::fullName() const
806{ 806{
807 QString title = find( Qtopia::Title ); 807 QString title = find( Qtopia::Title );
808 QString firstName = find( Qtopia::FirstName ); 808 QString firstName = find( Qtopia::FirstName );
809 QString middleName = find( Qtopia::MiddleName ); 809 QString middleName = find( Qtopia::MiddleName );
810 QString lastName = find( Qtopia::LastName ); 810 QString lastName = find( Qtopia::LastName );
811 QString suffix = find( Qtopia::Suffix ); 811 QString suffix = find( Qtopia::Suffix );
812 812
813 QString name = title; 813 QString name = title;
814 if ( !firstName.isEmpty() ) { 814 if ( !firstName.isEmpty() ) {
815 if ( !name.isEmpty() ) 815 if ( !name.isEmpty() )
816 name += " "; 816 name += " ";
817 name += firstName; 817 name += firstName;
818 } 818 }
819 if ( !middleName.isEmpty() ) { 819 if ( !middleName.isEmpty() ) {
820 if ( !name.isEmpty() ) 820 if ( !name.isEmpty() )
821 name += " "; 821 name += " ";
822 name += middleName; 822 name += middleName;
823 } 823 }
824 if ( !lastName.isEmpty() ) { 824 if ( !lastName.isEmpty() ) {
825 if ( !name.isEmpty() ) 825 if ( !name.isEmpty() )
826 name += " "; 826 name += " ";
827 name += lastName; 827 name += lastName;
828 } 828 }
829 if ( !suffix.isEmpty() ) { 829 if ( !suffix.isEmpty() ) {
830 if ( !name.isEmpty() ) 830 if ( !name.isEmpty() )
831 name += " "; 831 name += " ";
832 name += suffix; 832 name += suffix;
833 } 833 }
834 return name.simplifyWhiteSpace(); 834 return name.simplifyWhiteSpace();
835} 835}
836 836
837/*! 837/*!
838 Returns a list of the names of the children of the contact. 838 Returns a list of the names of the children of the contact.
839*/ 839*/
840QStringList OContact::childrenList() const 840QStringList OContact::childrenList() const
841{ 841{
842 return QStringList::split( " ", find( Qtopia::Children ) ); 842 return QStringList::split( " ", find( Qtopia::Children ) );
843} 843}
844 844
845/*! \fn void OContact::insertEmail( const QString &email ) 845/*! \fn void OContact::insertEmail( const QString &email )
846 846
847 Insert \a email into the email list. Ensures \a email can only be added 847 Insert \a email into the email list. Ensures \a email can only be added
848 once. If there is no default email address set, it sets it to the \a email. 848 once. If there is no default email address set, it sets it to the \a email.
849*/ 849*/
850 850
851/*! \fn void OContact::removeEmail( const QString &email ) 851/*! \fn void OContact::removeEmail( const QString &email )
852 852
853 Removes the \a email from the email list. If the default email was \a email, 853 Removes the \a email from the email list. If the default email was \a email,
854 then the default email address is assigned to the first email in the 854 then the default email address is assigned to the first email in the
855 email list 855 email list
856*/ 856*/
857 857
858/*! \fn void OContact::clearEmails() 858/*! \fn void OContact::clearEmails()
859 859
860 Clears the email list. 860 Clears the email list.
861 */ 861 */
862 862
863/*! \fn void OContact::insertEmails( const QStringList &emailList ) 863/*! \fn void OContact::insertEmails( const QStringList &emailList )
864 864
865 Appends the \a emailList to the exiting email list 865 Appends the \a emailList to the exiting email list
866 */ 866 */
867 867
868/*! 868/*!
869 Returns a list of email addresses belonging to the contact, including 869 Returns a list of email addresses belonging to the contact, including
870 the default email address. 870 the default email address.
871*/ 871*/
872QStringList OContact::emailList() const 872QStringList OContact::emailList() const
873{ 873{
874 QString emailStr = emails(); 874 QString emailStr = emails();
875 875
876 QStringList r; 876 QStringList r;
877 if ( !emailStr.isEmpty() ) { 877 if ( !emailStr.isEmpty() ) {
878 qDebug(" emailstr "); 878 qDebug(" emailstr ");
879 QStringList l = QStringList::split( emailSeparator(), emailStr ); 879 QStringList l = QStringList::split( emailSeparator(), emailStr );
880 for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) 880 for ( QStringList::ConstIterator it = l.begin();it != l.end();++it )
881 r += (*it).simplifyWhiteSpace(); 881 r += (*it).simplifyWhiteSpace();
882 } 882 }
883 883
884 return r; 884 return r;
885} 885}
886 886
887/*! 887/*!
888 \overload 888 \overload
889 889
890 Generates the string for the contact to be filed as from the first, 890 Generates the string for the contact to be filed as from the first,
891 middle and last name of the contact. 891 middle and last name of the contact.
892*/ 892*/
893void OContact::setFileAs() 893void OContact::setFileAs()
894{ 894{
895 QString lastName, firstName, middleName, fileas; 895 QString lastName, firstName, middleName, fileas;
896 896
897 lastName = find( Qtopia::LastName ); 897 lastName = find( Qtopia::LastName );
898 firstName = find( Qtopia::FirstName ); 898 firstName = find( Qtopia::FirstName );
899 middleName = find( Qtopia::MiddleName ); 899 middleName = find( Qtopia::MiddleName );
900 if ( !lastName.isEmpty() && !firstName.isEmpty() 900 if ( !lastName.isEmpty() && !firstName.isEmpty()
901 && !middleName.isEmpty() ) 901 && !middleName.isEmpty() )
902 fileas = lastName + ", " + firstName + " " + middleName; 902 fileas = lastName + ", " + firstName + " " + middleName;
903 else if ( !lastName.isEmpty() && !firstName.isEmpty() ) 903 else if ( !lastName.isEmpty() && !firstName.isEmpty() )
904 fileas = lastName + ", " + firstName; 904 fileas = lastName + ", " + firstName;
905 else if ( !lastName.isEmpty() || !firstName.isEmpty() || 905 else if ( !lastName.isEmpty() || !firstName.isEmpty() ||
906 !middleName.isEmpty() ) 906 !middleName.isEmpty() )
907 fileas = firstName + ( firstName.isEmpty() ? "" : " " ) 907 fileas = firstName + ( firstName.isEmpty() ? "" : " " )
908 + middleName + ( middleName.isEmpty() ? "" : " " ) 908 + middleName + ( middleName.isEmpty() ? "" : " " )
909 + lastName; 909 + lastName;
910 910
911 replace( Qtopia::FileAs, fileas ); 911 replace( Qtopia::FileAs, fileas );
912} 912}
913 913
914/*! 914/*!
915 \internal 915 \internal
916 Appends the contact information to \a buf. 916 Appends the contact information to \a buf.
917*/ 917*/
918void OContact::save( QString &buf ) const 918void OContact::save( QString &buf ) const
919{ 919{
920 static const QStringList SLFIELDS = fields(); 920 static const QStringList SLFIELDS = fields();
921 // I'm expecting "<Contact " in front of this... 921 // I'm expecting "<Contact " in front of this...
922 for ( QMap<int, QString>::ConstIterator it = mMap.begin(); 922 for ( QMap<int, QString>::ConstIterator it = mMap.begin();
923 it != mMap.end(); ++it ) { 923 it != mMap.end(); ++it ) {
924 const QString &value = it.data(); 924 const QString &value = it.data();
925 int key = it.key(); 925 int key = it.key();
926 if ( !value.isEmpty() ) { 926 if ( !value.isEmpty() ) {
927 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) 927 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid)
928 continue; 928 continue;
929 929
930 key -= Qtopia::AddressCategory+1; 930 key -= Qtopia::AddressCategory+1;
931 buf += SLFIELDS[key]; 931 buf += SLFIELDS[key];
932 buf += "=\"" + Qtopia::escapeString(value) + "\" "; 932 buf += "=\"" + Qtopia::escapeString(value) + "\" ";
933 } 933 }
934 } 934 }
935 buf += customToXml(); 935 buf += customToXml();
936 if ( categories().count() > 0 ) 936 if ( categories().count() > 0 )
937 buf += "Categories=\"" + idsToString( categories() ) + "\" "; 937 buf += "Categories=\"" + idsToString( categories() ) + "\" ";
938 buf += "Uid=\"" + QString::number( uid() ) + "\" "; 938 buf += "Uid=\"" + QString::number( uid() ) + "\" ";
939 // You need to close this yourself 939 // You need to close this yourself
940} 940}
941 941
942 942
943/*! 943/*!
944 \internal 944 \internal
945 Returns the list of fields belonging to a contact 945 Returns the list of fields belonging to a contact
946 Never change order of this list ! It has to be regarding 946 Never change order of this list ! It has to be regarding
947 enum AddressBookFields !! 947 enum AddressBookFields !!
948*/ 948*/
949QStringList OContact::fields() 949QStringList OContact::fields()
950{ 950{
951 QStringList list; 951 QStringList list;
952 952
953 list.append( "Title" ); // Not Used! 953 list.append( "Title" ); // Not Used!
954 list.append( "FirstName" ); 954 list.append( "FirstName" );
955 list.append( "MiddleName" ); 955 list.append( "MiddleName" );
956 list.append( "LastName" ); 956 list.append( "LastName" );
957 list.append( "Suffix" ); 957 list.append( "Suffix" );
958 list.append( "FileAs" ); 958 list.append( "FileAs" );
959 959
960 list.append( "JobTitle" ); 960 list.append( "JobTitle" );
961 list.append( "Department" ); 961 list.append( "Department" );
962 list.append( "Company" ); 962 list.append( "Company" );
963 list.append( "BusinessPhone" ); 963 list.append( "BusinessPhone" );
964 list.append( "BusinessFax" ); 964 list.append( "BusinessFax" );
965 list.append( "BusinessMobile" ); 965 list.append( "BusinessMobile" );
966 966
967 list.append( "DefaultEmail" ); 967 list.append( "DefaultEmail" );
968 list.append( "Emails" ); 968 list.append( "Emails" );
969 969
970 list.append( "HomePhone" ); 970 list.append( "HomePhone" );
971 list.append( "HomeFax" ); 971 list.append( "HomeFax" );
972 list.append( "HomeMobile" ); 972 list.append( "HomeMobile" );
973 973
974 list.append( "BusinessStreet" ); 974 list.append( "BusinessStreet" );
975 list.append( "BusinessCity" ); 975 list.append( "BusinessCity" );
976 list.append( "BusinessState" ); 976 list.append( "BusinessState" );
977 list.append( "BusinessZip" ); 977 list.append( "BusinessZip" );
978 list.append( "BusinessCountry" ); 978 list.append( "BusinessCountry" );
979 list.append( "BusinessPager" ); 979 list.append( "BusinessPager" );
980 list.append( "BusinessWebPage" ); 980 list.append( "BusinessWebPage" );
981 981
982 list.append( "Office" ); 982 list.append( "Office" );
983 list.append( "Profession" ); 983 list.append( "Profession" );
984 list.append( "Assistant" ); 984 list.append( "Assistant" );
985 list.append( "Manager" ); 985 list.append( "Manager" );
986 986
987 list.append( "HomeStreet" ); 987 list.append( "HomeStreet" );
988 list.append( "HomeCity" ); 988 list.append( "HomeCity" );
989 list.append( "HomeState" ); 989 list.append( "HomeState" );
990 list.append( "HomeZip" ); 990 list.append( "HomeZip" );
991 list.append( "HomeCountry" ); 991 list.append( "HomeCountry" );
992 list.append( "HomeWebPage" ); 992 list.append( "HomeWebPage" );
993 993
994 list.append( "Spouse" ); 994 list.append( "Spouse" );
995 list.append( "Gender" ); 995 list.append( "Gender" );
996 list.append( "Birthday" ); 996 list.append( "Birthday" );
997 list.append( "Anniversary" ); 997 list.append( "Anniversary" );
998 list.append( "Nickname" ); 998 list.append( "Nickname" );
999 list.append( "Children" ); 999 list.append( "Children" );
1000 1000
1001 list.append( "Notes" ); 1001 list.append( "Notes" );
1002 list.append( "Groups" ); 1002 list.append( "Groups" );
1003 1003
1004 return list; 1004 return list;
1005} 1005}
1006 1006
1007 1007
1008/*! 1008/*!
1009 Sets the list of email address for contact to those contained in \a str. 1009 Sets the list of email address for contact to those contained in \a str.
1010 Email address should be separated by ';'s. 1010 Email address should be separated by ';'s.
1011*/ 1011*/
1012void OContact::setEmails( const QString &str ) 1012void OContact::setEmails( const QString &str )
1013{ 1013{
1014 replace( Qtopia::Emails, str ); 1014 replace( Qtopia::Emails, str );
1015 if ( str.isEmpty() ) 1015 if ( str.isEmpty() )
1016 setDefaultEmail( QString::null ); 1016 setDefaultEmail( QString::null );
1017} 1017}
1018 1018
1019/*! 1019/*!
1020 Sets the list of children for the contact to those contained in \a str. 1020 Sets the list of children for the contact to those contained in \a str.
1021*/ 1021*/
1022void OContact::setChildren( const QString &str ) 1022void OContact::setChildren( const QString &str )
1023{ 1023{
1024 replace( Qtopia::Children, str ); 1024 replace( Qtopia::Children, str );
1025} 1025}
1026 1026
1027/*! 1027/*!
1028 \overload 1028 \overload
1029 Returns TRUE if the contact matches the regular expression \a regexp. 1029 Returns TRUE if the contact matches the regular expression \a regexp.
1030 Otherwise returns FALSE. 1030 Otherwise returns FALSE.
1031*/ 1031*/
1032bool OContact::match( const QRegExp &r ) const 1032bool OContact::match( const QRegExp &r ) const
1033{ 1033{
1034 setLastHitField( -1 ); 1034 setLastHitField( -1 );
1035 bool match; 1035 bool match;
1036 match = false; 1036 match = false;
1037 QMap<int, QString>::ConstIterator it; 1037 QMap<int, QString>::ConstIterator it;
1038 for ( it = mMap.begin(); it != mMap.end(); ++it ) { 1038 for ( it = mMap.begin(); it != mMap.end(); ++it ) {
1039 if ( (*it).find( r ) > -1 ) { 1039 if ( (*it).find( r ) > -1 ) {
1040 setLastHitField( it.key() ); 1040 setLastHitField( it.key() );
1041 match = true; 1041 match = true;
1042 break; 1042 break;
1043 } 1043 }
1044 } 1044 }
1045 return match; 1045 return match;
1046} 1046}
1047 1047
1048 1048
1049QString OContact::toShortText() const 1049QString OContact::toShortText() const
1050{ 1050{
1051 return ( fullName() ); 1051 return ( fullName() );
1052} 1052}
1053QString OContact::type() const 1053QString OContact::type() const
1054{ 1054{
1055 return QString::fromLatin1( "OContact" ); 1055 return QString::fromLatin1( "OContact" );
1056} 1056}
1057 1057
1058 1058
1059 1059
1060class QString OContact::recordField( int pos ) const 1060class QString OContact::recordField( int pos ) const
1061{ 1061{
1062 QStringList SLFIELDS = fields(); // ?? why this ? (se) 1062 QStringList SLFIELDS = fields(); // ?? why this ? (se)
1063 return SLFIELDS[pos]; 1063 return SLFIELDS[pos];
1064} 1064}
1065 1065
1066// In future releases, we should store birthday and anniversary 1066// In future releases, we should store birthday and anniversary
1067// internally as QDate instead of QString ! 1067// internally as QDate instead of QString !
1068// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) 1068// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se)
1069 1069
1070/*! \fn void OContact::setBirthday( const QDate& date ) 1070/*! \fn void OContact::setBirthday( const QDate& date )
1071 Sets the birthday for the contact to \a date. If date is null 1071 Sets the birthday for the contact to \a date. If date is null
1072 the current stored date will be removed. 1072 the current stored date will be removed.
1073*/ 1073*/
1074void OContact::setBirthday( const QDate &v ) 1074void OContact::setBirthday( const QDate &v )
1075{ 1075{
1076 if ( v.isNull() ){ 1076 if ( v.isNull() ){
1077 qWarning( "Remove Birthday"); 1077 qWarning( "Remove Birthday");
1078 replace( Qtopia::Birthday, QString::null ); 1078 replace( Qtopia::Birthday, QString::null );
1079 return; 1079 return;
1080 } 1080 }
1081 1081
1082 if ( v.isValid() ) 1082 if ( v.isValid() )
1083 replace( Qtopia::Birthday, OConversion::dateToString( v ) ); 1083 replace( Qtopia::Birthday, OConversion::dateToString( v ) );
1084 1084
1085} 1085}
1086 1086
1087 1087
1088/*! \fn void OContact::setAnniversary( const QDate &date ) 1088/*! \fn void OContact::setAnniversary( const QDate &date )
1089 Sets the anniversary of the contact to \a date. If date is 1089 Sets the anniversary of the contact to \a date. If date is
1090 null, the current stored date will be removed. 1090 null, the current stored date will be removed.
1091*/ 1091*/
1092void OContact::setAnniversary( const QDate &v ) 1092void OContact::setAnniversary( const QDate &v )
1093{ 1093{
1094 if ( v.isNull() ){ 1094 if ( v.isNull() ){
1095 qWarning( "Remove Anniversary"); 1095 qWarning( "Remove Anniversary");
1096 replace( Qtopia::Anniversary, QString::null ); 1096 replace( Qtopia::Anniversary, QString::null );
1097 return; 1097 return;
1098 } 1098 }
1099 1099
1100 if ( v.isValid() ) 1100 if ( v.isValid() )
1101 replace( Qtopia::Anniversary, OConversion::dateToString( v ) ); 1101 replace( Qtopia::Anniversary, OConversion::dateToString( v ) );
1102} 1102}
1103 1103
1104/*! \fn QDate OContact::birthday() const 1104/*! \fn QDate OContact::birthday() const
1105 Returns the birthday of the contact. 1105 Returns the birthday of the contact.
1106*/ 1106*/
1107QDate OContact::birthday() const 1107QDate OContact::birthday() const
1108{ 1108{
1109 QString str = find( Qtopia::Birthday ); 1109 QString str = find( Qtopia::Birthday );
1110 qWarning ("Birthday %s", str.latin1() ); 1110 // qWarning ("Birthday %s", str.latin1() );
1111 if ( !str.isEmpty() ) 1111 if ( !str.isEmpty() )
1112 return OConversion::dateFromString ( str ); 1112 return OConversion::dateFromString ( str );
1113 else 1113 else
1114 return QDate(); 1114 return QDate();
1115} 1115}
1116 1116
1117 1117
1118/*! \fn QDate OContact::anniversary() const 1118/*! \fn QDate OContact::anniversary() const
1119 Returns the anniversary of the contact. 1119 Returns the anniversary of the contact.
1120*/ 1120*/
1121QDate OContact::anniversary() const 1121QDate OContact::anniversary() const
1122{ 1122{
1123 QDate empty; 1123 QDate empty;
1124 QString str = find( Qtopia::Anniversary ); 1124 QString str = find( Qtopia::Anniversary );
1125 qWarning ("Anniversary %s", str.latin1() ); 1125 // qWarning ("Anniversary %s", str.latin1() );
1126 if ( !str.isEmpty() ) 1126 if ( !str.isEmpty() )
1127 return OConversion::dateFromString ( str ); 1127 return OConversion::dateFromString ( str );
1128 else 1128 else
1129 return empty; 1129 return empty;
1130} 1130}
1131 1131
1132 1132
1133void OContact::insertEmail( const QString &v ) 1133void OContact::insertEmail( const QString &v )
1134{ 1134{
1135 //qDebug("insertEmail %s", v.latin1()); 1135 //qDebug("insertEmail %s", v.latin1());
1136 QString e = v.simplifyWhiteSpace(); 1136 QString e = v.simplifyWhiteSpace();
1137 QString def = defaultEmail(); 1137 QString def = defaultEmail();
1138 1138
1139 // if no default, set it as the default email and don't insert 1139 // if no default, set it as the default email and don't insert
1140 if ( def.isEmpty() ) { 1140 if ( def.isEmpty() ) {
1141 setDefaultEmail( e ); // will insert into the list for us 1141 setDefaultEmail( e ); // will insert into the list for us
1142 return; 1142 return;
1143 } 1143 }
1144 1144
1145 // otherwise, insert assuming doesn't already exist 1145 // otherwise, insert assuming doesn't already exist
1146 QString emailsStr = find( Qtopia::Emails ); 1146 QString emailsStr = find( Qtopia::Emails );
1147 if ( emailsStr.contains( e )) 1147 if ( emailsStr.contains( e ))
1148 return; 1148 return;
1149 if ( !emailsStr.isEmpty() ) 1149 if ( !emailsStr.isEmpty() )
1150 emailsStr += emailSeparator(); 1150 emailsStr += emailSeparator();
1151 emailsStr += e; 1151 emailsStr += e;
1152 replace( Qtopia::Emails, emailsStr ); 1152 replace( Qtopia::Emails, emailsStr );
1153} 1153}
1154 1154
1155void OContact::removeEmail( const QString &v ) 1155void OContact::removeEmail( const QString &v )
1156{ 1156{
1157 QString e = v.simplifyWhiteSpace(); 1157 QString e = v.simplifyWhiteSpace();
1158 QString def = defaultEmail(); 1158 QString def = defaultEmail();
1159 QString emailsStr = find( Qtopia::Emails ); 1159 QString emailsStr = find( Qtopia::Emails );
1160 QStringList emails = emailList(); 1160 QStringList emails = emailList();
1161 1161
1162 // otherwise, must first contain it 1162 // otherwise, must first contain it
1163 if ( !emailsStr.contains( e ) ) 1163 if ( !emailsStr.contains( e ) )
1164 return; 1164 return;
1165 1165
1166 // remove it 1166 // remove it
1167 //qDebug(" removing email from list %s", e.latin1()); 1167 //qDebug(" removing email from list %s", e.latin1());
1168 emails.remove( e ); 1168 emails.remove( e );
1169 // reset the string 1169 // reset the string
1170 emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator 1170 emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator
1171 replace( Qtopia::Emails, emailsStr ); 1171 replace( Qtopia::Emails, emailsStr );
1172 1172
1173 // if default, then replace the default email with the first one 1173 // if default, then replace the default email with the first one
1174 if ( def == e ) { 1174 if ( def == e ) {
1175 //qDebug("removeEmail is default; setting new default"); 1175 //qDebug("removeEmail is default; setting new default");
1176 if ( !emails.count() ) 1176 if ( !emails.count() )
1177 clearEmails(); 1177 clearEmails();
1178 else // setDefaultEmail will remove e from the list 1178 else // setDefaultEmail will remove e from the list
1179 setDefaultEmail( emails.first() ); 1179 setDefaultEmail( emails.first() );
1180 } 1180 }
1181} 1181}
1182void OContact::clearEmails() 1182void OContact::clearEmails()
1183{ 1183{
1184 mMap.remove( Qtopia::DefaultEmail ); 1184 mMap.remove( Qtopia::DefaultEmail );
1185 mMap.remove( Qtopia::Emails ); 1185 mMap.remove( Qtopia::Emails );
1186} 1186}
1187void OContact::setDefaultEmail( const QString &v ) 1187void OContact::setDefaultEmail( const QString &v )
1188{ 1188{
1189 QString e = v.simplifyWhiteSpace(); 1189 QString e = v.simplifyWhiteSpace();
1190 1190
1191 //qDebug("OContact::setDefaultEmail %s", e.latin1()); 1191 //qDebug("OContact::setDefaultEmail %s", e.latin1());
1192 replace( Qtopia::DefaultEmail, e ); 1192 replace( Qtopia::DefaultEmail, e );
1193 1193
1194 if ( !e.isEmpty() ) 1194 if ( !e.isEmpty() )
1195 insertEmail( e ); 1195 insertEmail( e );
1196 1196
1197} 1197}
1198 1198
1199void OContact::insertEmails( const QStringList &v ) 1199void OContact::insertEmails( const QStringList &v )
1200{ 1200{
1201 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) 1201 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it )
1202 insertEmail( *it ); 1202 insertEmail( *it );
1203} 1203}
1204int OContact::rtti() { 1204int OContact::rtti() {
1205 return OPimResolver::AddressBook; 1205 return OPimResolver::AddressBook;
1206} 1206}
1207void OContact::setUid( int i ) 1207void OContact::setUid( int i )
1208{ 1208{
1209 OPimRecord::setUid(i); 1209 OPimRecord::setUid(i);
1210 replace( Qtopia::AddressUid , QString::number(i)); 1210 replace( Qtopia::AddressUid , QString::number(i));
1211} 1211}
diff --git a/libopie/pim/ocontactaccessbackend_xml.cpp b/libopie/pim/ocontactaccessbackend_xml.cpp
index 1c21619..1b5af2f 100644
--- a/libopie/pim/ocontactaccessbackend_xml.cpp
+++ b/libopie/pim/ocontactaccessbackend_xml.cpp
@@ -1,814 +1,817 @@
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.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down..
22 *
20 * Revision 1.7 2003/08/01 12:30:16 eilers 23 * Revision 1.7 2003/08/01 12:30:16 eilers
21 * Merging changes from BRANCH_1_0 to HEAD 24 * Merging changes from BRANCH_1_0 to HEAD
22 * 25 *
23 * Revision 1.6 2003/07/07 16:19:47 eilers 26 * Revision 1.6 2003/07/07 16:19:47 eilers
24 * Fixing serious bug in hasQuerySettings() 27 * Fixing serious bug in hasQuerySettings()
25 * 28 *
26 * Revision 1.5 2003/04/13 18:07:10 zecke 29 * Revision 1.5 2003/04/13 18:07:10 zecke
27 * More API doc 30 * More API doc
28 * QString -> const QString& 31 * QString -> const QString&
29 * QString = 0l -> QString::null 32 * QString = 0l -> QString::null
30 * 33 *
31 * Revision 1.4 2003/03/21 14:32:54 mickeyl 34 * Revision 1.4 2003/03/21 14:32:54 mickeyl
32 * g++ compliance fix: default arguments belong into the declaration, but not the definition 35 * g++ compliance fix: default arguments belong into the declaration, but not the definition
33 * 36 *
34 * Revision 1.3 2003/03/21 12:26:28 eilers 37 * Revision 1.3 2003/03/21 12:26:28 eilers
35 * Fixing small bug: If we search a birthday from today to today, it returned 38 * Fixing small bug: If we search a birthday from today to today, it returned
36 * every contact .. 39 * every contact ..
37 * 40 *
38 * Revision 1.2 2003/03/21 10:33:09 eilers 41 * Revision 1.2 2003/03/21 10:33:09 eilers
39 * Merged speed optimized xml backend for contacts to main. 42 * Merged speed optimized xml backend for contacts to main.
40 * Added QDateTime to querybyexample. For instance, it is now possible to get 43 * Added QDateTime to querybyexample. For instance, it is now possible to get
41 * all Birthdays/Anniversaries between two dates. This should be used 44 * all Birthdays/Anniversaries between two dates. This should be used
42 * to show all birthdays in the datebook.. 45 * to show all birthdays in the datebook..
43 * This change is sourcecode backward compatible but you have to upgrade 46 * This change is sourcecode backward compatible but you have to upgrade
44 * the binaries for today-addressbook. 47 * the binaries for today-addressbook.
45 * 48 *
46 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 49 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
47 * Speed optimization. Removed the sequential search loops. 50 * Speed optimization. Removed the sequential search loops.
48 * 51 *
49 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 52 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
50 * Writing offsets to debug output.. 53 * Writing offsets to debug output..
51 * 54 *
52 * Revision 1.1 2003/02/09 15:05:01 eilers 55 * Revision 1.1 2003/02/09 15:05:01 eilers
53 * Nothing happened.. Just some cleanup before I will start.. 56 * Nothing happened.. Just some cleanup before I will start..
54 * 57 *
55 * Revision 1.12 2003/01/03 16:58:03 eilers 58 * Revision 1.12 2003/01/03 16:58:03 eilers
56 * Reenable debug output 59 * Reenable debug output
57 * 60 *
58 * Revision 1.11 2003/01/03 12:31:28 eilers 61 * Revision 1.11 2003/01/03 12:31:28 eilers
59 * Bugfix for calculating data diffs.. 62 * Bugfix for calculating data diffs..
60 * 63 *
61 * Revision 1.10 2003/01/02 14:27:12 eilers 64 * Revision 1.10 2003/01/02 14:27:12 eilers
62 * Improved query by example: Search by date is possible.. First step 65 * Improved query by example: Search by date is possible.. First step
63 * for a today plugin for birthdays.. 66 * for a today plugin for birthdays..
64 * 67 *
65 * Revision 1.9 2002/12/08 12:48:57 eilers 68 * Revision 1.9 2002/12/08 12:48:57 eilers
66 * Moved journal-enum from ocontact into i the xml-backend.. 69 * Moved journal-enum from ocontact into i the xml-backend..
67 * 70 *
68 * Revision 1.8 2002/11/14 17:04:24 eilers 71 * Revision 1.8 2002/11/14 17:04:24 eilers
69 * Sorting will now work if fullname is identical on some entries 72 * Sorting will now work if fullname is identical on some entries
70 * 73 *
71 * Revision 1.7 2002/11/13 15:02:46 eilers 74 * Revision 1.7 2002/11/13 15:02:46 eilers
72 * Small Bug in sorted fixed 75 * Small Bug in sorted fixed
73 * 76 *
74 * Revision 1.6 2002/11/13 14:14:51 eilers 77 * Revision 1.6 2002/11/13 14:14:51 eilers
75 * Added sorted for Contacts.. 78 * Added sorted for Contacts..
76 * 79 *
77 * Revision 1.5 2002/11/01 15:10:42 eilers 80 * Revision 1.5 2002/11/01 15:10:42 eilers
78 * Added regExp-search in database for all fields in a contact. 81 * Added regExp-search in database for all fields in a contact.
79 * 82 *
80 * Revision 1.4 2002/10/16 10:52:40 eilers 83 * Revision 1.4 2002/10/16 10:52:40 eilers
81 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 84 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
82 * 85 *
83 * Revision 1.3 2002/10/14 16:21:54 eilers 86 * Revision 1.3 2002/10/14 16:21:54 eilers
84 * Some minor interface updates 87 * Some minor interface updates
85 * 88 *
86 * Revision 1.2 2002/10/07 17:34:24 eilers 89 * Revision 1.2 2002/10/07 17:34:24 eilers
87 * added OBackendFactory for advanced backend access 90 * added OBackendFactory for advanced backend access
88 * 91 *
89 * Revision 1.1 2002/09/27 17:11:44 eilers 92 * Revision 1.1 2002/09/27 17:11:44 eilers
90 * Added API for accessing the Contact-Database ! It is compiling, but 93 * Added API for accessing the Contact-Database ! It is compiling, but
91 * please do not expect that anything is working ! 94 * please do not expect that anything is working !
92 * I will debug that stuff in the next time .. 95 * I will debug that stuff in the next time ..
93 * Please read README_COMPILE for compiling ! 96 * Please read README_COMPILE for compiling !
94 * 97 *
95 * 98 *
96 */ 99 */
97 100
98#include "ocontactaccessbackend_xml.h" 101#include "ocontactaccessbackend_xml.h"
99 102
100#include <qasciidict.h> 103#include <qasciidict.h>
101#include <qdatetime.h> 104#include <qdatetime.h>
102#include <qfile.h> 105#include <qfile.h>
103#include <qfileinfo.h> 106#include <qfileinfo.h>
104#include <qregexp.h> 107#include <qregexp.h>
105#include <qarray.h> 108#include <qarray.h>
106#include <qmap.h> 109#include <qmap.h>
107#include <qdatetime.h> 110#include <qdatetime.h>
108 111
109#include <qpe/global.h> 112#include <qpe/global.h>
110 113
111#include <opie/xmltree.h> 114#include <opie/xmltree.h>
112#include "ocontactaccessbackend.h" 115#include "ocontactaccessbackend.h"
113#include "ocontactaccess.h" 116#include "ocontactaccess.h"
114 117
115#include <stdlib.h> 118#include <stdlib.h>
116#include <errno.h> 119#include <errno.h>
117 120
118using namespace Opie; 121using namespace Opie;
119 122
120 123
121OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): 124OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ):
122 m_changed( false ) 125 m_changed( false )
123{ 126{
124 // Just m_contactlist should call delete if an entry 127 // Just m_contactlist should call delete if an entry
125 // is removed. 128 // is removed.
126 m_contactList.setAutoDelete( true ); 129 m_contactList.setAutoDelete( true );
127 m_uidToContact.setAutoDelete( false ); 130 m_uidToContact.setAutoDelete( false );
128 131
129 m_appName = appname; 132 m_appName = appname;
130 133
131 /* Set journalfile name ... */ 134 /* Set journalfile name ... */
132 m_journalName = getenv("HOME"); 135 m_journalName = getenv("HOME");
133 m_journalName +="/.abjournal" + appname; 136 m_journalName +="/.abjournal" + appname;
134 137
135 /* Expecting to access the default filename if nothing else is set */ 138 /* Expecting to access the default filename if nothing else is set */
136 if ( filename.isEmpty() ){ 139 if ( filename.isEmpty() ){
137 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 140 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
138 } else 141 } else
139 m_fileName = filename; 142 m_fileName = filename;
140 143
141 /* Load Database now */ 144 /* Load Database now */
142 load (); 145 load ();
143} 146}
144 147
145bool OContactAccessBackend_XML::save() 148bool OContactAccessBackend_XML::save()
146{ 149{
147 150
148 if ( !m_changed ) 151 if ( !m_changed )
149 return true; 152 return true;
150 153
151 QString strNewFile = m_fileName + ".new"; 154 QString strNewFile = m_fileName + ".new";
152 QFile f( strNewFile ); 155 QFile f( strNewFile );
153 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 156 if ( !f.open( IO_WriteOnly|IO_Raw ) )
154 return false; 157 return false;
155 158
156 int total_written; 159 int total_written;
157 int idx_offset = 0; 160 int idx_offset = 0;
158 QString out; 161 QString out;
159 162
160 // Write Header 163 // Write Header
161 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 164 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
162 " <Groups>\n" 165 " <Groups>\n"
163 " </Groups>\n" 166 " </Groups>\n"
164 " <Contacts>\n"; 167 " <Contacts>\n";
165 QCString cstr = out.utf8(); 168 QCString cstr = out.utf8();
166 f.writeBlock( cstr.data(), cstr.length() ); 169 f.writeBlock( cstr.data(), cstr.length() );
167 idx_offset += cstr.length(); 170 idx_offset += cstr.length();
168 out = ""; 171 out = "";
169 172
170 // Write all contacts 173 // Write all contacts
171 QListIterator<OContact> it( m_contactList ); 174 QListIterator<OContact> it( m_contactList );
172 for ( ; it.current(); ++it ) { 175 for ( ; it.current(); ++it ) {
173 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 176 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
174 out += "<Contact "; 177 out += "<Contact ";
175 (*it)->save( out ); 178 (*it)->save( out );
176 out += "/>\n"; 179 out += "/>\n";
177 cstr = out.utf8(); 180 cstr = out.utf8();
178 total_written = f.writeBlock( cstr.data(), cstr.length() ); 181 total_written = f.writeBlock( cstr.data(), cstr.length() );
179 idx_offset += cstr.length(); 182 idx_offset += cstr.length();
180 if ( total_written != int(cstr.length()) ) { 183 if ( total_written != int(cstr.length()) ) {
181 f.close(); 184 f.close();
182 QFile::remove( strNewFile ); 185 QFile::remove( strNewFile );
183 return false; 186 return false;
184 } 187 }
185 out = ""; 188 out = "";
186 } 189 }
187 out += " </Contacts>\n</AddressBook>\n"; 190 out += " </Contacts>\n</AddressBook>\n";
188 191
189 // Write Footer 192 // Write Footer
190 cstr = out.utf8(); 193 cstr = out.utf8();
191 total_written = f.writeBlock( cstr.data(), cstr.length() ); 194 total_written = f.writeBlock( cstr.data(), cstr.length() );
192 if ( total_written != int( cstr.length() ) ) { 195 if ( total_written != int( cstr.length() ) ) {
193 f.close(); 196 f.close();
194 QFile::remove( strNewFile ); 197 QFile::remove( strNewFile );
195 return false; 198 return false;
196 } 199 }
197 f.close(); 200 f.close();
198 201
199 // move the file over, I'm just going to use the system call 202 // move the file over, I'm just going to use the system call
200 // because, I don't feel like using QDir. 203 // because, I don't feel like using QDir.
201 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 204 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
202 qWarning( "problem renaming file %s to %s, errno: %d", 205 qWarning( "problem renaming file %s to %s, errno: %d",
203 strNewFile.latin1(), m_journalName.latin1(), errno ); 206 strNewFile.latin1(), m_journalName.latin1(), errno );
204 // remove the tmp file... 207 // remove the tmp file...
205 QFile::remove( strNewFile ); 208 QFile::remove( strNewFile );
206 } 209 }
207 210
208 /* The journalfile should be removed now... */ 211 /* The journalfile should be removed now... */
209 removeJournal(); 212 removeJournal();
210 213
211 m_changed = false; 214 m_changed = false;
212 return true; 215 return true;
213} 216}
214 217
215bool OContactAccessBackend_XML::load () 218bool OContactAccessBackend_XML::load ()
216{ 219{
217 m_contactList.clear(); 220 m_contactList.clear();
218 m_uidToContact.clear(); 221 m_uidToContact.clear();
219 222
220 /* Load XML-File and journal if it exists */ 223 /* Load XML-File and journal if it exists */
221 if ( !load ( m_fileName, false ) ) 224 if ( !load ( m_fileName, false ) )
222 return false; 225 return false;
223 /* The returncode of the journalfile is ignored due to the 226 /* The returncode of the journalfile is ignored due to the
224 * fact that it does not exist when this class is instantiated ! 227 * fact that it does not exist when this class is instantiated !
225 * But there may such a file exist, if the application crashed. 228 * But there may such a file exist, if the application crashed.
226 * Therefore we try to load it to get the changes before the # 229 * Therefore we try to load it to get the changes before the #
227 * crash happened... 230 * crash happened...
228 */ 231 */
229 load (m_journalName, true); 232 load (m_journalName, true);
230 233
231 return true; 234 return true;
232} 235}
233 236
234void OContactAccessBackend_XML::clear () 237void OContactAccessBackend_XML::clear ()
235{ 238{
236 m_contactList.clear(); 239 m_contactList.clear();
237 m_uidToContact.clear(); 240 m_uidToContact.clear();
238 241
239 m_changed = false; 242 m_changed = false;
240} 243}
241 244
242bool OContactAccessBackend_XML::wasChangedExternally() 245bool OContactAccessBackend_XML::wasChangedExternally()
243{ 246{
244 QFileInfo fi( m_fileName ); 247 QFileInfo fi( m_fileName );
245 248
246 QDateTime lastmod = fi.lastModified (); 249 QDateTime lastmod = fi.lastModified ();
247 250
248 return (lastmod != m_readtime); 251 return (lastmod != m_readtime);
249} 252}
250 253
251QArray<int> OContactAccessBackend_XML::allRecords() const 254QArray<int> OContactAccessBackend_XML::allRecords() const
252{ 255{
253 QArray<int> uid_list( m_contactList.count() ); 256 QArray<int> uid_list( m_contactList.count() );
254 257
255 uint counter = 0; 258 uint counter = 0;
256 QListIterator<OContact> it( m_contactList ); 259 QListIterator<OContact> it( m_contactList );
257 for( ; it.current(); ++it ){ 260 for( ; it.current(); ++it ){
258 uid_list[counter++] = (*it)->uid(); 261 uid_list[counter++] = (*it)->uid();
259 } 262 }
260 263
261 return ( uid_list ); 264 return ( uid_list );
262} 265}
263 266
264OContact OContactAccessBackend_XML::find ( int uid ) const 267OContact OContactAccessBackend_XML::find ( int uid ) const
265{ 268{
266 OContact foundContact; //Create empty contact 269 OContact foundContact; //Create empty contact
267 270
268 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 271 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
269 272
270 if ( found ){ 273 if ( found ){
271 foundContact = *found; 274 foundContact = *found;
272 } 275 }
273 276
274 return ( foundContact ); 277 return ( foundContact );
275} 278}
276 279
277QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 280QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
278 const QDateTime& d ) 281 const QDateTime& d )
279{ 282{
280 283
281 QArray<int> m_currentQuery( m_contactList.count() ); 284 QArray<int> m_currentQuery( m_contactList.count() );
282 QListIterator<OContact> it( m_contactList ); 285 QListIterator<OContact> it( m_contactList );
283 uint arraycounter = 0; 286 uint arraycounter = 0;
284 287
285 for( ; it.current(); ++it ){ 288 for( ; it.current(); ++it ){
286 /* Search all fields and compare them with query object. Store them into list 289 /* Search all fields and compare them with query object. Store them into list
287 * if all fields matches. 290 * if all fields matches.
288 */ 291 */
289 QDate* queryDate = 0l; 292 QDate* queryDate = 0l;
290 QDate* checkDate = 0l; 293 QDate* checkDate = 0l;
291 bool allcorrect = true; 294 bool allcorrect = true;
292 for ( int i = 0; i < Qtopia::Groups; i++ ) { 295 for ( int i = 0; i < Qtopia::Groups; i++ ) {
293 // Birthday and anniversary are special nonstring fields and should 296 // Birthday and anniversary are special nonstring fields and should
294 // be handled specially 297 // be handled specially
295 switch ( i ){ 298 switch ( i ){
296 case Qtopia::Birthday: 299 case Qtopia::Birthday:
297 queryDate = new QDate( query.birthday() ); 300 queryDate = new QDate( query.birthday() );
298 checkDate = new QDate( (*it)->birthday() ); 301 checkDate = new QDate( (*it)->birthday() );
299 case Qtopia::Anniversary: 302 case Qtopia::Anniversary:
300 if ( queryDate == 0l ){ 303 if ( queryDate == 0l ){
301 queryDate = new QDate( query.anniversary() ); 304 queryDate = new QDate( query.anniversary() );
302 checkDate = new QDate( (*it)->anniversary() ); 305 checkDate = new QDate( (*it)->anniversary() );
303 } 306 }
304 307
305 if ( queryDate->isValid() ){ 308 if ( queryDate->isValid() ){
306 if( checkDate->isValid() ){ 309 if( checkDate->isValid() ){
307 if ( settings & OContactAccess::DateYear ){ 310 if ( settings & OContactAccess::DateYear ){
308 if ( queryDate->year() != checkDate->year() ) 311 if ( queryDate->year() != checkDate->year() )
309 allcorrect = false; 312 allcorrect = false;
310 } 313 }
311 if ( settings & OContactAccess::DateMonth ){ 314 if ( settings & OContactAccess::DateMonth ){
312 if ( queryDate->month() != checkDate->month() ) 315 if ( queryDate->month() != checkDate->month() )
313 allcorrect = false; 316 allcorrect = false;
314 } 317 }
315 if ( settings & OContactAccess::DateDay ){ 318 if ( settings & OContactAccess::DateDay ){
316 if ( queryDate->day() != checkDate->day() ) 319 if ( queryDate->day() != checkDate->day() )
317 allcorrect = false; 320 allcorrect = false;
318 } 321 }
319 if ( settings & OContactAccess::DateDiff ) { 322 if ( settings & OContactAccess::DateDiff ) {
320 QDate current; 323 QDate current;
321 // If we get an additional date, we 324 // If we get an additional date, we
322 // will take this date instead of 325 // will take this date instead of
323 // the current one.. 326 // the current one..
324 if ( !d.date().isValid() ) 327 if ( !d.date().isValid() )
325 current = QDate::currentDate(); 328 current = QDate::currentDate();
326 else 329 else
327 current = d.date(); 330 current = d.date();
328 331
329 // We have to equalize the year, otherwise 332 // We have to equalize the year, otherwise
330 // the search will fail.. 333 // the search will fail..
331 checkDate->setYMD( current.year(), 334 checkDate->setYMD( current.year(),
332 checkDate->month(), 335 checkDate->month(),
333 checkDate->day() ); 336 checkDate->day() );
334 if ( *checkDate < current ) 337 if ( *checkDate < current )
335 checkDate->setYMD( current.year()+1, 338 checkDate->setYMD( current.year()+1,
336 checkDate->month(), 339 checkDate->month(),
337 checkDate->day() ); 340 checkDate->day() );
338 341
339 // Check whether the birthday/anniversary date is between 342 // Check whether the birthday/anniversary date is between
340 // the current/given date and the maximum date 343 // the current/given date and the maximum date
341 // ( maximum time range ) ! 344 // ( maximum time range ) !
342 qWarning("Checking if %s is between %s and %s ! ", 345 qWarning("Checking if %s is between %s and %s ! ",
343 checkDate->toString().latin1(), 346 checkDate->toString().latin1(),
344 current.toString().latin1(), 347 current.toString().latin1(),
345 queryDate->toString().latin1() ); 348 queryDate->toString().latin1() );
346 if ( current.daysTo( *queryDate ) >= 0 ){ 349 if ( current.daysTo( *queryDate ) >= 0 ){
347 if ( !( ( *checkDate >= current ) && 350 if ( !( ( *checkDate >= current ) &&
348 ( *checkDate <= *queryDate ) ) ){ 351 ( *checkDate <= *queryDate ) ) ){
349 allcorrect = false; 352 allcorrect = false;
350 qWarning (" Nope!.."); 353 qWarning (" Nope!..");
351 } 354 }
352 } 355 }
353 } 356 }
354 } else{ 357 } else{
355 // checkDate is invalid. Therefore this entry is always rejected 358 // checkDate is invalid. Therefore this entry is always rejected
356 allcorrect = false; 359 allcorrect = false;
357 } 360 }
358 } 361 }
359 362
360 delete queryDate; 363 delete queryDate;
361 queryDate = 0l; 364 queryDate = 0l;
362 delete checkDate; 365 delete checkDate;
363 checkDate = 0l; 366 checkDate = 0l;
364 break; 367 break;
365 default: 368 default:
366 /* Just compare fields which are not empty in the query object */ 369 /* Just compare fields which are not empty in the query object */
367 if ( !query.field(i).isEmpty() ){ 370 if ( !query.field(i).isEmpty() ){
368 switch ( settings & ~( OContactAccess::IgnoreCase 371 switch ( settings & ~( OContactAccess::IgnoreCase
369 | OContactAccess::DateDiff 372 | OContactAccess::DateDiff
370 | OContactAccess::DateYear 373 | OContactAccess::DateYear
371 | OContactAccess::DateMonth 374 | OContactAccess::DateMonth
372 | OContactAccess::DateDay 375 | OContactAccess::DateDay
373 | OContactAccess::MatchOne 376 | OContactAccess::MatchOne
374 ) ){ 377 ) ){
375 378
376 case OContactAccess::RegExp:{ 379 case OContactAccess::RegExp:{
377 QRegExp expr ( query.field(i), 380 QRegExp expr ( query.field(i),
378 !(settings & OContactAccess::IgnoreCase), 381 !(settings & OContactAccess::IgnoreCase),
379 false ); 382 false );
380 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 383 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
381 allcorrect = false; 384 allcorrect = false;
382 } 385 }
383 break; 386 break;
384 case OContactAccess::WildCards:{ 387 case OContactAccess::WildCards:{
385 QRegExp expr ( query.field(i), 388 QRegExp expr ( query.field(i),
386 !(settings & OContactAccess::IgnoreCase), 389 !(settings & OContactAccess::IgnoreCase),
387 true ); 390 true );
388 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 391 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
389 allcorrect = false; 392 allcorrect = false;
390 } 393 }
391 break; 394 break;
392 case OContactAccess::ExactMatch:{ 395 case OContactAccess::ExactMatch:{
393 if (settings & OContactAccess::IgnoreCase){ 396 if (settings & OContactAccess::IgnoreCase){
394 if ( query.field(i).upper() != 397 if ( query.field(i).upper() !=
395 (*it)->field(i).upper() ) 398 (*it)->field(i).upper() )
396 allcorrect = false; 399 allcorrect = false;
397 }else{ 400 }else{
398 if ( query.field(i) != (*it)->field(i) ) 401 if ( query.field(i) != (*it)->field(i) )
399 allcorrect = false; 402 allcorrect = false;
400 } 403 }
401 } 404 }
402 break; 405 break;
403 } 406 }
404 } 407 }
405 } 408 }
406 } 409 }
407 if ( allcorrect ){ 410 if ( allcorrect ){
408 m_currentQuery[arraycounter++] = (*it)->uid(); 411 m_currentQuery[arraycounter++] = (*it)->uid();
409 } 412 }
410 } 413 }
411 414
412 // Shrink to fit.. 415 // Shrink to fit..
413 m_currentQuery.resize(arraycounter); 416 m_currentQuery.resize(arraycounter);
414 417
415 return m_currentQuery; 418 return m_currentQuery;
416} 419}
417 420
418QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 421QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
419{ 422{
420 QArray<int> m_currentQuery( m_contactList.count() ); 423 QArray<int> m_currentQuery( m_contactList.count() );
421 QListIterator<OContact> it( m_contactList ); 424 QListIterator<OContact> it( m_contactList );
422 uint arraycounter = 0; 425 uint arraycounter = 0;
423 426
424 for( ; it.current(); ++it ){ 427 for( ; it.current(); ++it ){
425 if ( (*it)->match( r ) ){ 428 if ( (*it)->match( r ) ){
426 m_currentQuery[arraycounter++] = (*it)->uid(); 429 m_currentQuery[arraycounter++] = (*it)->uid();
427 } 430 }
428 431
429 } 432 }
430 // Shrink to fit.. 433 // Shrink to fit..
431 m_currentQuery.resize(arraycounter); 434 m_currentQuery.resize(arraycounter);
432 435
433 return m_currentQuery; 436 return m_currentQuery;
434} 437}
435 438
436const uint OContactAccessBackend_XML::querySettings() 439const uint OContactAccessBackend_XML::querySettings()
437{ 440{
438 return ( OContactAccess::WildCards 441 return ( OContactAccess::WildCards
439 | OContactAccess::IgnoreCase 442 | OContactAccess::IgnoreCase
440 | OContactAccess::RegExp 443 | OContactAccess::RegExp
441 | OContactAccess::ExactMatch 444 | OContactAccess::ExactMatch
442 | OContactAccess::DateDiff 445 | OContactAccess::DateDiff
443 | OContactAccess::DateYear 446 | OContactAccess::DateYear
444 | OContactAccess::DateMonth 447 | OContactAccess::DateMonth
445 | OContactAccess::DateDay 448 | OContactAccess::DateDay
446 ); 449 );
447} 450}
448 451
449bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 452bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
450{ 453{
451 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 454 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
452 * may be added with any of the other settings. IgnoreCase should never used alone. 455 * may be added with any of the other settings. IgnoreCase should never used alone.
453 * Wildcards, RegExp, ExactMatch should never used at the same time... 456 * Wildcards, RegExp, ExactMatch should never used at the same time...
454 */ 457 */
455 458
456 // Step 1: Check whether the given settings are supported by this backend 459 // Step 1: Check whether the given settings are supported by this backend
457 if ( ( querySettings & ( 460 if ( ( querySettings & (
458 OContactAccess::IgnoreCase 461 OContactAccess::IgnoreCase
459 | OContactAccess::WildCards 462 | OContactAccess::WildCards
460 | OContactAccess::DateDiff 463 | OContactAccess::DateDiff
461 | OContactAccess::DateYear 464 | OContactAccess::DateYear
462 | OContactAccess::DateMonth 465 | OContactAccess::DateMonth
463 | OContactAccess::DateDay 466 | OContactAccess::DateDay
464 | OContactAccess::RegExp 467 | OContactAccess::RegExp
465 | OContactAccess::ExactMatch 468 | OContactAccess::ExactMatch
466 ) ) != querySettings ) 469 ) ) != querySettings )
467 return false; 470 return false;
468 471
469 // Step 2: Check whether the given combinations are ok.. 472 // Step 2: Check whether the given combinations are ok..
470 473
471 // IngoreCase alone is invalid 474 // IngoreCase alone is invalid
472 if ( querySettings == OContactAccess::IgnoreCase ) 475 if ( querySettings == OContactAccess::IgnoreCase )
473 return false; 476 return false;
474 477
475 // WildCards, RegExp and ExactMatch should never used at the same time 478 // WildCards, RegExp and ExactMatch should never used at the same time
476 switch ( querySettings & ~( OContactAccess::IgnoreCase 479 switch ( querySettings & ~( OContactAccess::IgnoreCase
477 | OContactAccess::DateDiff 480 | OContactAccess::DateDiff
478 | OContactAccess::DateYear 481 | OContactAccess::DateYear
479 | OContactAccess::DateMonth 482 | OContactAccess::DateMonth
480 | OContactAccess::DateDay 483 | OContactAccess::DateDay
481 ) 484 )
482 ){ 485 ){
483 case OContactAccess::RegExp: 486 case OContactAccess::RegExp:
484 return ( true ); 487 return ( true );
485 case OContactAccess::WildCards: 488 case OContactAccess::WildCards:
486 return ( true ); 489 return ( true );
487 case OContactAccess::ExactMatch: 490 case OContactAccess::ExactMatch:
488 return ( true ); 491 return ( true );
489 case 0: // one of the upper removed bits were set.. 492 case 0: // one of the upper removed bits were set..
490 return ( true ); 493 return ( true );
491 default: 494 default:
492 return ( false ); 495 return ( false );
493 } 496 }
494} 497}
495 498
496// Currently only asc implemented.. 499// Currently only asc implemented..
497QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 500QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
498{ 501{
499 QMap<QString, int> nameToUid; 502 QMap<QString, int> nameToUid;
500 QStringList names; 503 QStringList names;
501 QArray<int> m_currentQuery( m_contactList.count() ); 504 QArray<int> m_currentQuery( m_contactList.count() );
502 505
503 // First fill map and StringList with all Names 506 // First fill map and StringList with all Names
504 // Afterwards sort namelist and use map to fill array to return.. 507 // Afterwards sort namelist and use map to fill array to return..
505 QListIterator<OContact> it( m_contactList ); 508 QListIterator<OContact> it( m_contactList );
506 for( ; it.current(); ++it ){ 509 for( ; it.current(); ++it ){
507 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 510 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
508 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 511 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
509 } 512 }
510 names.sort(); 513 names.sort();
511 514
512 int i = 0; 515 int i = 0;
513 if ( asc ){ 516 if ( asc ){
514 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 517 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
515 m_currentQuery[i++] = nameToUid[ (*it) ]; 518 m_currentQuery[i++] = nameToUid[ (*it) ];
516 }else{ 519 }else{
517 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 520 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
518 m_currentQuery[i++] = nameToUid[ (*it) ]; 521 m_currentQuery[i++] = nameToUid[ (*it) ];
519 } 522 }
520 523
521 return m_currentQuery; 524 return m_currentQuery;
522 525
523} 526}
524 527
525bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 528bool OContactAccessBackend_XML::add ( const OContact &newcontact )
526{ 529{
527 //qWarning("odefaultbackend: ACTION::ADD"); 530 //qWarning("odefaultbackend: ACTION::ADD");
528 updateJournal (newcontact, ACTION_ADD); 531 updateJournal (newcontact, ACTION_ADD);
529 addContact_p( newcontact ); 532 addContact_p( newcontact );
530 533
531 m_changed = true; 534 m_changed = true;
532 535
533 return true; 536 return true;
534} 537}
535 538
536bool OContactAccessBackend_XML::replace ( const OContact &contact ) 539bool OContactAccessBackend_XML::replace ( const OContact &contact )
537{ 540{
538 m_changed = true; 541 m_changed = true;
539 542
540 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 543 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
541 544
542 if ( found ) { 545 if ( found ) {
543 OContact* newCont = new OContact( contact ); 546 OContact* newCont = new OContact( contact );
544 547
545 updateJournal ( *newCont, ACTION_REPLACE); 548 updateJournal ( *newCont, ACTION_REPLACE);
546 m_contactList.removeRef ( found ); 549 m_contactList.removeRef ( found );
547 m_contactList.append ( newCont ); 550 m_contactList.append ( newCont );
548 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 551 m_uidToContact.remove( QString().setNum( contact.uid() ) );
549 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 552 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
550 553
551 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 554 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
552 555
553 return true; 556 return true;
554 } else 557 } else
555 return false; 558 return false;
556} 559}
557 560
558bool OContactAccessBackend_XML::remove ( int uid ) 561bool OContactAccessBackend_XML::remove ( int uid )
559{ 562{
560 m_changed = true; 563 m_changed = true;
561 564
562 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 565 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
563 566
564 if ( found ) { 567 if ( found ) {
565 updateJournal ( *found, ACTION_REMOVE); 568 updateJournal ( *found, ACTION_REMOVE);
566 m_contactList.removeRef ( found ); 569 m_contactList.removeRef ( found );
567 m_uidToContact.remove( QString().setNum( uid ) ); 570 m_uidToContact.remove( QString().setNum( uid ) );
568 571
569 return true; 572 return true;
570 } else 573 } else
571 return false; 574 return false;
572} 575}
573 576
574bool OContactAccessBackend_XML::reload(){ 577bool OContactAccessBackend_XML::reload(){
575 /* Reload is the same as load in this implementation */ 578 /* Reload is the same as load in this implementation */
576 return ( load() ); 579 return ( load() );
577} 580}
578 581
579void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 582void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
580{ 583{
581 OContact* contRef = new OContact( newcontact ); 584 OContact* contRef = new OContact( newcontact );
582 585
583 m_contactList.append ( contRef ); 586 m_contactList.append ( contRef );
584 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 587 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
585} 588}
586 589
587/* This function loads the xml-database and the journalfile */ 590/* This function loads the xml-database and the journalfile */
588bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 591bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
589{ 592{
590 593
591 /* We use the time of the last read to check if the file was 594 /* We use the time of the last read to check if the file was
592 * changed externally. 595 * changed externally.
593 */ 596 */
594 if ( !isJournal ){ 597 if ( !isJournal ){
595 QFileInfo fi( filename ); 598 QFileInfo fi( filename );
596 m_readtime = fi.lastModified (); 599 m_readtime = fi.lastModified ();
597 } 600 }
598 601
599 const int JOURNALACTION = Qtopia::Notes + 1; 602 const int JOURNALACTION = Qtopia::Notes + 1;
600 const int JOURNALROW = JOURNALACTION + 1; 603 const int JOURNALROW = JOURNALACTION + 1;
601 604
602 bool foundAction = false; 605 bool foundAction = false;
603 journal_action action = ACTION_ADD; 606 journal_action action = ACTION_ADD;
604 int journalKey = 0; 607 int journalKey = 0;
605 QMap<int, QString> contactMap; 608 QMap<int, QString> contactMap;
606 QMap<QString, QString> customMap; 609 QMap<QString, QString> customMap;
607 QMap<QString, QString>::Iterator customIt; 610 QMap<QString, QString>::Iterator customIt;
608 QAsciiDict<int> dict( 47 ); 611 QAsciiDict<int> dict( 47 );
609 612
610 dict.setAutoDelete( TRUE ); 613 dict.setAutoDelete( TRUE );
611 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 614 dict.insert( "Uid", new int(Qtopia::AddressUid) );
612 dict.insert( "Title", new int(Qtopia::Title) ); 615 dict.insert( "Title", new int(Qtopia::Title) );
613 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 616 dict.insert( "FirstName", new int(Qtopia::FirstName) );
614 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 617 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
615 dict.insert( "LastName", new int(Qtopia::LastName) ); 618 dict.insert( "LastName", new int(Qtopia::LastName) );
616 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 619 dict.insert( "Suffix", new int(Qtopia::Suffix) );
617 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 620 dict.insert( "FileAs", new int(Qtopia::FileAs) );
618 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 621 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
619 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 622 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
620 dict.insert( "Emails", new int(Qtopia::Emails) ); 623 dict.insert( "Emails", new int(Qtopia::Emails) );
621 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 624 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
622 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 625 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
623 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 626 dict.insert( "HomeState", new int(Qtopia::HomeState) );
624 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 627 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
625 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 628 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
626 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 629 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
627 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 630 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
628 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 631 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
629 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 632 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
630 dict.insert( "Company", new int(Qtopia::Company) ); 633 dict.insert( "Company", new int(Qtopia::Company) );
631 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 634 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
632 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 635 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
633 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 636 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
634 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 637 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
635 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 638 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
636 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 639 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
637 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 640 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
638 dict.insert( "Department", new int(Qtopia::Department) ); 641 dict.insert( "Department", new int(Qtopia::Department) );
639 dict.insert( "Office", new int(Qtopia::Office) ); 642 dict.insert( "Office", new int(Qtopia::Office) );
640 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 643 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
641 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 644 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
642 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 645 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
643 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 646 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
644 dict.insert( "Profession", new int(Qtopia::Profession) ); 647 dict.insert( "Profession", new int(Qtopia::Profession) );
645 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 648 dict.insert( "Assistant", new int(Qtopia::Assistant) );
646 dict.insert( "Manager", new int(Qtopia::Manager) ); 649 dict.insert( "Manager", new int(Qtopia::Manager) );
647 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 650 dict.insert( "Spouse", new int(Qtopia::Spouse) );
648 dict.insert( "Children", new int(Qtopia::Children) ); 651 dict.insert( "Children", new int(Qtopia::Children) );
649 dict.insert( "Gender", new int(Qtopia::Gender) ); 652 dict.insert( "Gender", new int(Qtopia::Gender) );
650 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 653 dict.insert( "Birthday", new int(Qtopia::Birthday) );
651 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 654 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
652 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 655 dict.insert( "Nickname", new int(Qtopia::Nickname) );
653 dict.insert( "Notes", new int(Qtopia::Notes) ); 656 dict.insert( "Notes", new int(Qtopia::Notes) );
654 dict.insert( "action", new int(JOURNALACTION) ); 657 dict.insert( "action", new int(JOURNALACTION) );
655 dict.insert( "actionrow", new int(JOURNALROW) ); 658 dict.insert( "actionrow", new int(JOURNALROW) );
656 659
657 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 660 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
658 661
659 XMLElement *root = XMLElement::load( filename ); 662 XMLElement *root = XMLElement::load( filename );
660 if(root != 0l ){ // start parsing 663 if(root != 0l ){ // start parsing
661 /* Parse all XML-Elements and put the data into the 664 /* Parse all XML-Elements and put the data into the
662 * Contact-Class 665 * Contact-Class
663 */ 666 */
664 XMLElement *element = root->firstChild(); 667 XMLElement *element = root->firstChild();
665 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 668 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
666 element = element->firstChild(); 669 element = element->firstChild();
667 670
668 /* Search Tag "Contacts" which is the parent of all Contacts */ 671 /* Search Tag "Contacts" which is the parent of all Contacts */
669 while( element && !isJournal ){ 672 while( element && !isJournal ){
670 if( element->tagName() != QString::fromLatin1("Contacts") ){ 673 if( element->tagName() != QString::fromLatin1("Contacts") ){
671 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 674 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
672 // element->tagName().latin1()); 675 // element->tagName().latin1());
673 element = element->nextChild(); 676 element = element->nextChild();
674 } else { 677 } else {
675 element = element->firstChild(); 678 element = element->firstChild();
676 break; 679 break;
677 } 680 }
678 } 681 }
679 /* Parse all Contacts and ignore unknown tags */ 682 /* Parse all Contacts and ignore unknown tags */
680 while( element ){ 683 while( element ){
681 if( element->tagName() != QString::fromLatin1("Contact") ){ 684 if( element->tagName() != QString::fromLatin1("Contact") ){
682 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 685 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
683 // element->tagName().latin1()); 686 // element->tagName().latin1());
684 element = element->nextChild(); 687 element = element->nextChild();
685 continue; 688 continue;
686 } 689 }
687 /* Found alement with tagname "contact", now parse and store all 690 /* Found alement with tagname "contact", now parse and store all
688 * attributes contained 691 * attributes contained
689 */ 692 */
690 //qWarning("OContactDefBack::load element tagName() : %s", 693 //qWarning("OContactDefBack::load element tagName() : %s",
691 // element->tagName().latin1() ); 694 // element->tagName().latin1() );
692 QString dummy; 695 QString dummy;
693 foundAction = false; 696 foundAction = false;
694 697
695 XMLElement::AttributeMap aMap = element->attributes(); 698 XMLElement::AttributeMap aMap = element->attributes();
696 XMLElement::AttributeMap::Iterator it; 699 XMLElement::AttributeMap::Iterator it;
697 contactMap.clear(); 700 contactMap.clear();
698 customMap.clear(); 701 customMap.clear();
699 for( it = aMap.begin(); it != aMap.end(); ++it ){ 702 for( it = aMap.begin(); it != aMap.end(); ++it ){
700 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 703 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
701 704
702 int *find = dict[ it.key() ]; 705 int *find = dict[ it.key() ];
703 /* Unknown attributes will be stored as "Custom" elements */ 706 /* Unknown attributes will be stored as "Custom" elements */
704 if ( !find ) { 707 if ( !find ) {
705 qWarning("Attribute %s not known.", it.key().latin1()); 708 // qWarning("Attribute %s not known.", it.key().latin1());
706 //contact.setCustomField(it.key(), it.data()); 709 //contact.setCustomField(it.key(), it.data());
707 customMap.insert( it.key(), it.data() ); 710 customMap.insert( it.key(), it.data() );
708 continue; 711 continue;
709 } 712 }
710 713
711 /* Check if special conversion is needed and add attribute 714 /* Check if special conversion is needed and add attribute
712 * into Contact class 715 * into Contact class
713 */ 716 */
714 switch( *find ) { 717 switch( *find ) {
715 /* 718 /*
716 case Qtopia::AddressUid: 719 case Qtopia::AddressUid:
717 contact.setUid( it.data().toInt() ); 720 contact.setUid( it.data().toInt() );
718 break; 721 break;
719 case Qtopia::AddressCategory: 722 case Qtopia::AddressCategory:
720 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 723 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
721 break; 724 break;
722 */ 725 */
723 case JOURNALACTION: 726 case JOURNALACTION:
724 action = journal_action(it.data().toInt()); 727 action = journal_action(it.data().toInt());
725 foundAction = true; 728 foundAction = true;
726 qWarning ("ODefBack(journal)::ACTION found: %d", action); 729 qWarning ("ODefBack(journal)::ACTION found: %d", action);
727 break; 730 break;
728 case JOURNALROW: 731 case JOURNALROW:
729 journalKey = it.data().toInt(); 732 journalKey = it.data().toInt();
730 break; 733 break;
731 default: // no conversion needed add them to the map 734 default: // no conversion needed add them to the map
732 contactMap.insert( *find, it.data() ); 735 contactMap.insert( *find, it.data() );
733 break; 736 break;
734 } 737 }
735 } 738 }
736 /* now generate the Contact contact */ 739 /* now generate the Contact contact */
737 OContact contact( contactMap ); 740 OContact contact( contactMap );
738 741
739 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 742 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
740 contact.setCustomField( customIt.key(), customIt.data() ); 743 contact.setCustomField( customIt.key(), customIt.data() );
741 } 744 }
742 745
743 if (foundAction){ 746 if (foundAction){
744 foundAction = false; 747 foundAction = false;
745 switch ( action ) { 748 switch ( action ) {
746 case ACTION_ADD: 749 case ACTION_ADD:
747 addContact_p (contact); 750 addContact_p (contact);
748 break; 751 break;
749 case ACTION_REMOVE: 752 case ACTION_REMOVE:
750 if ( !remove (contact.uid()) ) 753 if ( !remove (contact.uid()) )
751 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 754 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
752 contact.uid() ); 755 contact.uid() );
753 break; 756 break;
754 case ACTION_REPLACE: 757 case ACTION_REPLACE:
755 if ( !replace ( contact ) ) 758 if ( !replace ( contact ) )
756 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 759 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
757 contact.uid() ); 760 contact.uid() );
758 break; 761 break;
759 default: 762 default:
760 qWarning ("Unknown action: ignored !"); 763 qWarning ("Unknown action: ignored !");
761 break; 764 break;
762 } 765 }
763 }else{ 766 }else{
764 /* Add contact to list */ 767 /* Add contact to list */
765 addContact_p (contact); 768 addContact_p (contact);
766 } 769 }
767 770
768 /* Move to next element */ 771 /* Move to next element */
769 element = element->nextChild(); 772 element = element->nextChild();
770 } 773 }
771 }else { 774 }else {
772 qWarning("ODefBack::could not load"); 775 qWarning("ODefBack::could not load");
773 } 776 }
774 delete root; 777 delete root;
775 qWarning("returning from loading" ); 778 qWarning("returning from loading" );
776 return true; 779 return true;
777} 780}
778 781
779 782
780void OContactAccessBackend_XML::updateJournal( const OContact& cnt, 783void OContactAccessBackend_XML::updateJournal( const OContact& cnt,
781 journal_action action ) 784 journal_action action )
782{ 785{
783 QFile f( m_journalName ); 786 QFile f( m_journalName );
784 bool created = !f.exists(); 787 bool created = !f.exists();
785 if ( !f.open(IO_WriteOnly|IO_Append) ) 788 if ( !f.open(IO_WriteOnly|IO_Append) )
786 return; 789 return;
787 790
788 QString buf; 791 QString buf;
789 QCString str; 792 QCString str;
790 793
791 // if the file was created, we have to set the Tag "<CONTACTS>" to 794 // if the file was created, we have to set the Tag "<CONTACTS>" to
792 // get a XML-File which is readable by our parser. 795 // get a XML-File which is readable by our parser.
793 // This is just a cheat, but better than rewrite the parser. 796 // This is just a cheat, but better than rewrite the parser.
794 if ( created ){ 797 if ( created ){
795 buf = "<Contacts>"; 798 buf = "<Contacts>";
796 QCString cstr = buf.utf8(); 799 QCString cstr = buf.utf8();
797 f.writeBlock( cstr.data(), cstr.length() ); 800 f.writeBlock( cstr.data(), cstr.length() );
798 } 801 }
799 802
800 buf = "<Contact "; 803 buf = "<Contact ";
801 cnt.save( buf ); 804 cnt.save( buf );
802 buf += " action=\"" + QString::number( (int)action ) + "\" "; 805 buf += " action=\"" + QString::number( (int)action ) + "\" ";
803 buf += "/>\n"; 806 buf += "/>\n";
804 QCString cstr = buf.utf8(); 807 QCString cstr = buf.utf8();
805 f.writeBlock( cstr.data(), cstr.length() ); 808 f.writeBlock( cstr.data(), cstr.length() );
806} 809}
807 810
808void OContactAccessBackend_XML::removeJournal() 811void OContactAccessBackend_XML::removeJournal()
809{ 812{
810 QFile f ( m_journalName ); 813 QFile f ( m_journalName );
811 if ( f.exists() ) 814 if ( f.exists() )
812 f.remove(); 815 f.remove();
813} 816}
814 817
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
index 1c21619..1b5af2f 100644
--- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp
@@ -1,814 +1,817 @@
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.8 2003/08/30 15:28:26 eilers
21 * Removed some unimportant debug output which causes slow down..
22 *
20 * Revision 1.7 2003/08/01 12:30:16 eilers 23 * Revision 1.7 2003/08/01 12:30:16 eilers
21 * Merging changes from BRANCH_1_0 to HEAD 24 * Merging changes from BRANCH_1_0 to HEAD
22 * 25 *
23 * Revision 1.6 2003/07/07 16:19:47 eilers 26 * Revision 1.6 2003/07/07 16:19:47 eilers
24 * Fixing serious bug in hasQuerySettings() 27 * Fixing serious bug in hasQuerySettings()
25 * 28 *
26 * Revision 1.5 2003/04/13 18:07:10 zecke 29 * Revision 1.5 2003/04/13 18:07:10 zecke
27 * More API doc 30 * More API doc
28 * QString -> const QString& 31 * QString -> const QString&
29 * QString = 0l -> QString::null 32 * QString = 0l -> QString::null
30 * 33 *
31 * Revision 1.4 2003/03/21 14:32:54 mickeyl 34 * Revision 1.4 2003/03/21 14:32:54 mickeyl
32 * g++ compliance fix: default arguments belong into the declaration, but not the definition 35 * g++ compliance fix: default arguments belong into the declaration, but not the definition
33 * 36 *
34 * Revision 1.3 2003/03/21 12:26:28 eilers 37 * Revision 1.3 2003/03/21 12:26:28 eilers
35 * Fixing small bug: If we search a birthday from today to today, it returned 38 * Fixing small bug: If we search a birthday from today to today, it returned
36 * every contact .. 39 * every contact ..
37 * 40 *
38 * Revision 1.2 2003/03/21 10:33:09 eilers 41 * Revision 1.2 2003/03/21 10:33:09 eilers
39 * Merged speed optimized xml backend for contacts to main. 42 * Merged speed optimized xml backend for contacts to main.
40 * Added QDateTime to querybyexample. For instance, it is now possible to get 43 * Added QDateTime to querybyexample. For instance, it is now possible to get
41 * all Birthdays/Anniversaries between two dates. This should be used 44 * all Birthdays/Anniversaries between two dates. This should be used
42 * to show all birthdays in the datebook.. 45 * to show all birthdays in the datebook..
43 * This change is sourcecode backward compatible but you have to upgrade 46 * This change is sourcecode backward compatible but you have to upgrade
44 * the binaries for today-addressbook. 47 * the binaries for today-addressbook.
45 * 48 *
46 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers 49 * Revision 1.1.2.2 2003/02/11 12:17:28 eilers
47 * Speed optimization. Removed the sequential search loops. 50 * Speed optimization. Removed the sequential search loops.
48 * 51 *
49 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers 52 * Revision 1.1.2.1 2003/02/10 15:31:38 eilers
50 * Writing offsets to debug output.. 53 * Writing offsets to debug output..
51 * 54 *
52 * Revision 1.1 2003/02/09 15:05:01 eilers 55 * Revision 1.1 2003/02/09 15:05:01 eilers
53 * Nothing happened.. Just some cleanup before I will start.. 56 * Nothing happened.. Just some cleanup before I will start..
54 * 57 *
55 * Revision 1.12 2003/01/03 16:58:03 eilers 58 * Revision 1.12 2003/01/03 16:58:03 eilers
56 * Reenable debug output 59 * Reenable debug output
57 * 60 *
58 * Revision 1.11 2003/01/03 12:31:28 eilers 61 * Revision 1.11 2003/01/03 12:31:28 eilers
59 * Bugfix for calculating data diffs.. 62 * Bugfix for calculating data diffs..
60 * 63 *
61 * Revision 1.10 2003/01/02 14:27:12 eilers 64 * Revision 1.10 2003/01/02 14:27:12 eilers
62 * Improved query by example: Search by date is possible.. First step 65 * Improved query by example: Search by date is possible.. First step
63 * for a today plugin for birthdays.. 66 * for a today plugin for birthdays..
64 * 67 *
65 * Revision 1.9 2002/12/08 12:48:57 eilers 68 * Revision 1.9 2002/12/08 12:48:57 eilers
66 * Moved journal-enum from ocontact into i the xml-backend.. 69 * Moved journal-enum from ocontact into i the xml-backend..
67 * 70 *
68 * Revision 1.8 2002/11/14 17:04:24 eilers 71 * Revision 1.8 2002/11/14 17:04:24 eilers
69 * Sorting will now work if fullname is identical on some entries 72 * Sorting will now work if fullname is identical on some entries
70 * 73 *
71 * Revision 1.7 2002/11/13 15:02:46 eilers 74 * Revision 1.7 2002/11/13 15:02:46 eilers
72 * Small Bug in sorted fixed 75 * Small Bug in sorted fixed
73 * 76 *
74 * Revision 1.6 2002/11/13 14:14:51 eilers 77 * Revision 1.6 2002/11/13 14:14:51 eilers
75 * Added sorted for Contacts.. 78 * Added sorted for Contacts..
76 * 79 *
77 * Revision 1.5 2002/11/01 15:10:42 eilers 80 * Revision 1.5 2002/11/01 15:10:42 eilers
78 * Added regExp-search in database for all fields in a contact. 81 * Added regExp-search in database for all fields in a contact.
79 * 82 *
80 * Revision 1.4 2002/10/16 10:52:40 eilers 83 * Revision 1.4 2002/10/16 10:52:40 eilers
81 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 84 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
82 * 85 *
83 * Revision 1.3 2002/10/14 16:21:54 eilers 86 * Revision 1.3 2002/10/14 16:21:54 eilers
84 * Some minor interface updates 87 * Some minor interface updates
85 * 88 *
86 * Revision 1.2 2002/10/07 17:34:24 eilers 89 * Revision 1.2 2002/10/07 17:34:24 eilers
87 * added OBackendFactory for advanced backend access 90 * added OBackendFactory for advanced backend access
88 * 91 *
89 * Revision 1.1 2002/09/27 17:11:44 eilers 92 * Revision 1.1 2002/09/27 17:11:44 eilers
90 * Added API for accessing the Contact-Database ! It is compiling, but 93 * Added API for accessing the Contact-Database ! It is compiling, but
91 * please do not expect that anything is working ! 94 * please do not expect that anything is working !
92 * I will debug that stuff in the next time .. 95 * I will debug that stuff in the next time ..
93 * Please read README_COMPILE for compiling ! 96 * Please read README_COMPILE for compiling !
94 * 97 *
95 * 98 *
96 */ 99 */
97 100
98#include "ocontactaccessbackend_xml.h" 101#include "ocontactaccessbackend_xml.h"
99 102
100#include <qasciidict.h> 103#include <qasciidict.h>
101#include <qdatetime.h> 104#include <qdatetime.h>
102#include <qfile.h> 105#include <qfile.h>
103#include <qfileinfo.h> 106#include <qfileinfo.h>
104#include <qregexp.h> 107#include <qregexp.h>
105#include <qarray.h> 108#include <qarray.h>
106#include <qmap.h> 109#include <qmap.h>
107#include <qdatetime.h> 110#include <qdatetime.h>
108 111
109#include <qpe/global.h> 112#include <qpe/global.h>
110 113
111#include <opie/xmltree.h> 114#include <opie/xmltree.h>
112#include "ocontactaccessbackend.h" 115#include "ocontactaccessbackend.h"
113#include "ocontactaccess.h" 116#include "ocontactaccess.h"
114 117
115#include <stdlib.h> 118#include <stdlib.h>
116#include <errno.h> 119#include <errno.h>
117 120
118using namespace Opie; 121using namespace Opie;
119 122
120 123
121OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ): 124OContactAccessBackend_XML::OContactAccessBackend_XML ( const QString& appname, const QString& filename ):
122 m_changed( false ) 125 m_changed( false )
123{ 126{
124 // Just m_contactlist should call delete if an entry 127 // Just m_contactlist should call delete if an entry
125 // is removed. 128 // is removed.
126 m_contactList.setAutoDelete( true ); 129 m_contactList.setAutoDelete( true );
127 m_uidToContact.setAutoDelete( false ); 130 m_uidToContact.setAutoDelete( false );
128 131
129 m_appName = appname; 132 m_appName = appname;
130 133
131 /* Set journalfile name ... */ 134 /* Set journalfile name ... */
132 m_journalName = getenv("HOME"); 135 m_journalName = getenv("HOME");
133 m_journalName +="/.abjournal" + appname; 136 m_journalName +="/.abjournal" + appname;
134 137
135 /* Expecting to access the default filename if nothing else is set */ 138 /* Expecting to access the default filename if nothing else is set */
136 if ( filename.isEmpty() ){ 139 if ( filename.isEmpty() ){
137 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); 140 m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" );
138 } else 141 } else
139 m_fileName = filename; 142 m_fileName = filename;
140 143
141 /* Load Database now */ 144 /* Load Database now */
142 load (); 145 load ();
143} 146}
144 147
145bool OContactAccessBackend_XML::save() 148bool OContactAccessBackend_XML::save()
146{ 149{
147 150
148 if ( !m_changed ) 151 if ( !m_changed )
149 return true; 152 return true;
150 153
151 QString strNewFile = m_fileName + ".new"; 154 QString strNewFile = m_fileName + ".new";
152 QFile f( strNewFile ); 155 QFile f( strNewFile );
153 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 156 if ( !f.open( IO_WriteOnly|IO_Raw ) )
154 return false; 157 return false;
155 158
156 int total_written; 159 int total_written;
157 int idx_offset = 0; 160 int idx_offset = 0;
158 QString out; 161 QString out;
159 162
160 // Write Header 163 // Write Header
161 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" 164 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
162 " <Groups>\n" 165 " <Groups>\n"
163 " </Groups>\n" 166 " </Groups>\n"
164 " <Contacts>\n"; 167 " <Contacts>\n";
165 QCString cstr = out.utf8(); 168 QCString cstr = out.utf8();
166 f.writeBlock( cstr.data(), cstr.length() ); 169 f.writeBlock( cstr.data(), cstr.length() );
167 idx_offset += cstr.length(); 170 idx_offset += cstr.length();
168 out = ""; 171 out = "";
169 172
170 // Write all contacts 173 // Write all contacts
171 QListIterator<OContact> it( m_contactList ); 174 QListIterator<OContact> it( m_contactList );
172 for ( ; it.current(); ++it ) { 175 for ( ; it.current(); ++it ) {
173 qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset ); 176 // qWarning(" Uid %d at Offset: %x", (*it)->uid(), idx_offset );
174 out += "<Contact "; 177 out += "<Contact ";
175 (*it)->save( out ); 178 (*it)->save( out );
176 out += "/>\n"; 179 out += "/>\n";
177 cstr = out.utf8(); 180 cstr = out.utf8();
178 total_written = f.writeBlock( cstr.data(), cstr.length() ); 181 total_written = f.writeBlock( cstr.data(), cstr.length() );
179 idx_offset += cstr.length(); 182 idx_offset += cstr.length();
180 if ( total_written != int(cstr.length()) ) { 183 if ( total_written != int(cstr.length()) ) {
181 f.close(); 184 f.close();
182 QFile::remove( strNewFile ); 185 QFile::remove( strNewFile );
183 return false; 186 return false;
184 } 187 }
185 out = ""; 188 out = "";
186 } 189 }
187 out += " </Contacts>\n</AddressBook>\n"; 190 out += " </Contacts>\n</AddressBook>\n";
188 191
189 // Write Footer 192 // Write Footer
190 cstr = out.utf8(); 193 cstr = out.utf8();
191 total_written = f.writeBlock( cstr.data(), cstr.length() ); 194 total_written = f.writeBlock( cstr.data(), cstr.length() );
192 if ( total_written != int( cstr.length() ) ) { 195 if ( total_written != int( cstr.length() ) ) {
193 f.close(); 196 f.close();
194 QFile::remove( strNewFile ); 197 QFile::remove( strNewFile );
195 return false; 198 return false;
196 } 199 }
197 f.close(); 200 f.close();
198 201
199 // move the file over, I'm just going to use the system call 202 // move the file over, I'm just going to use the system call
200 // because, I don't feel like using QDir. 203 // because, I don't feel like using QDir.
201 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { 204 if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) {
202 qWarning( "problem renaming file %s to %s, errno: %d", 205 qWarning( "problem renaming file %s to %s, errno: %d",
203 strNewFile.latin1(), m_journalName.latin1(), errno ); 206 strNewFile.latin1(), m_journalName.latin1(), errno );
204 // remove the tmp file... 207 // remove the tmp file...
205 QFile::remove( strNewFile ); 208 QFile::remove( strNewFile );
206 } 209 }
207 210
208 /* The journalfile should be removed now... */ 211 /* The journalfile should be removed now... */
209 removeJournal(); 212 removeJournal();
210 213
211 m_changed = false; 214 m_changed = false;
212 return true; 215 return true;
213} 216}
214 217
215bool OContactAccessBackend_XML::load () 218bool OContactAccessBackend_XML::load ()
216{ 219{
217 m_contactList.clear(); 220 m_contactList.clear();
218 m_uidToContact.clear(); 221 m_uidToContact.clear();
219 222
220 /* Load XML-File and journal if it exists */ 223 /* Load XML-File and journal if it exists */
221 if ( !load ( m_fileName, false ) ) 224 if ( !load ( m_fileName, false ) )
222 return false; 225 return false;
223 /* The returncode of the journalfile is ignored due to the 226 /* The returncode of the journalfile is ignored due to the
224 * fact that it does not exist when this class is instantiated ! 227 * fact that it does not exist when this class is instantiated !
225 * But there may such a file exist, if the application crashed. 228 * But there may such a file exist, if the application crashed.
226 * Therefore we try to load it to get the changes before the # 229 * Therefore we try to load it to get the changes before the #
227 * crash happened... 230 * crash happened...
228 */ 231 */
229 load (m_journalName, true); 232 load (m_journalName, true);
230 233
231 return true; 234 return true;
232} 235}
233 236
234void OContactAccessBackend_XML::clear () 237void OContactAccessBackend_XML::clear ()
235{ 238{
236 m_contactList.clear(); 239 m_contactList.clear();
237 m_uidToContact.clear(); 240 m_uidToContact.clear();
238 241
239 m_changed = false; 242 m_changed = false;
240} 243}
241 244
242bool OContactAccessBackend_XML::wasChangedExternally() 245bool OContactAccessBackend_XML::wasChangedExternally()
243{ 246{
244 QFileInfo fi( m_fileName ); 247 QFileInfo fi( m_fileName );
245 248
246 QDateTime lastmod = fi.lastModified (); 249 QDateTime lastmod = fi.lastModified ();
247 250
248 return (lastmod != m_readtime); 251 return (lastmod != m_readtime);
249} 252}
250 253
251QArray<int> OContactAccessBackend_XML::allRecords() const 254QArray<int> OContactAccessBackend_XML::allRecords() const
252{ 255{
253 QArray<int> uid_list( m_contactList.count() ); 256 QArray<int> uid_list( m_contactList.count() );
254 257
255 uint counter = 0; 258 uint counter = 0;
256 QListIterator<OContact> it( m_contactList ); 259 QListIterator<OContact> it( m_contactList );
257 for( ; it.current(); ++it ){ 260 for( ; it.current(); ++it ){
258 uid_list[counter++] = (*it)->uid(); 261 uid_list[counter++] = (*it)->uid();
259 } 262 }
260 263
261 return ( uid_list ); 264 return ( uid_list );
262} 265}
263 266
264OContact OContactAccessBackend_XML::find ( int uid ) const 267OContact OContactAccessBackend_XML::find ( int uid ) const
265{ 268{
266 OContact foundContact; //Create empty contact 269 OContact foundContact; //Create empty contact
267 270
268 OContact* found = m_uidToContact.find( QString().setNum( uid ) ); 271 OContact* found = m_uidToContact.find( QString().setNum( uid ) );
269 272
270 if ( found ){ 273 if ( found ){
271 foundContact = *found; 274 foundContact = *found;
272 } 275 }
273 276
274 return ( foundContact ); 277 return ( foundContact );
275} 278}
276 279
277QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings, 280QArray<int> OContactAccessBackend_XML::queryByExample ( const OContact &query, int settings,
278 const QDateTime& d ) 281 const QDateTime& d )
279{ 282{
280 283
281 QArray<int> m_currentQuery( m_contactList.count() ); 284 QArray<int> m_currentQuery( m_contactList.count() );
282 QListIterator<OContact> it( m_contactList ); 285 QListIterator<OContact> it( m_contactList );
283 uint arraycounter = 0; 286 uint arraycounter = 0;
284 287
285 for( ; it.current(); ++it ){ 288 for( ; it.current(); ++it ){
286 /* Search all fields and compare them with query object. Store them into list 289 /* Search all fields and compare them with query object. Store them into list
287 * if all fields matches. 290 * if all fields matches.
288 */ 291 */
289 QDate* queryDate = 0l; 292 QDate* queryDate = 0l;
290 QDate* checkDate = 0l; 293 QDate* checkDate = 0l;
291 bool allcorrect = true; 294 bool allcorrect = true;
292 for ( int i = 0; i < Qtopia::Groups; i++ ) { 295 for ( int i = 0; i < Qtopia::Groups; i++ ) {
293 // Birthday and anniversary are special nonstring fields and should 296 // Birthday and anniversary are special nonstring fields and should
294 // be handled specially 297 // be handled specially
295 switch ( i ){ 298 switch ( i ){
296 case Qtopia::Birthday: 299 case Qtopia::Birthday:
297 queryDate = new QDate( query.birthday() ); 300 queryDate = new QDate( query.birthday() );
298 checkDate = new QDate( (*it)->birthday() ); 301 checkDate = new QDate( (*it)->birthday() );
299 case Qtopia::Anniversary: 302 case Qtopia::Anniversary:
300 if ( queryDate == 0l ){ 303 if ( queryDate == 0l ){
301 queryDate = new QDate( query.anniversary() ); 304 queryDate = new QDate( query.anniversary() );
302 checkDate = new QDate( (*it)->anniversary() ); 305 checkDate = new QDate( (*it)->anniversary() );
303 } 306 }
304 307
305 if ( queryDate->isValid() ){ 308 if ( queryDate->isValid() ){
306 if( checkDate->isValid() ){ 309 if( checkDate->isValid() ){
307 if ( settings & OContactAccess::DateYear ){ 310 if ( settings & OContactAccess::DateYear ){
308 if ( queryDate->year() != checkDate->year() ) 311 if ( queryDate->year() != checkDate->year() )
309 allcorrect = false; 312 allcorrect = false;
310 } 313 }
311 if ( settings & OContactAccess::DateMonth ){ 314 if ( settings & OContactAccess::DateMonth ){
312 if ( queryDate->month() != checkDate->month() ) 315 if ( queryDate->month() != checkDate->month() )
313 allcorrect = false; 316 allcorrect = false;
314 } 317 }
315 if ( settings & OContactAccess::DateDay ){ 318 if ( settings & OContactAccess::DateDay ){
316 if ( queryDate->day() != checkDate->day() ) 319 if ( queryDate->day() != checkDate->day() )
317 allcorrect = false; 320 allcorrect = false;
318 } 321 }
319 if ( settings & OContactAccess::DateDiff ) { 322 if ( settings & OContactAccess::DateDiff ) {
320 QDate current; 323 QDate current;
321 // If we get an additional date, we 324 // If we get an additional date, we
322 // will take this date instead of 325 // will take this date instead of
323 // the current one.. 326 // the current one..
324 if ( !d.date().isValid() ) 327 if ( !d.date().isValid() )
325 current = QDate::currentDate(); 328 current = QDate::currentDate();
326 else 329 else
327 current = d.date(); 330 current = d.date();
328 331
329 // We have to equalize the year, otherwise 332 // We have to equalize the year, otherwise
330 // the search will fail.. 333 // the search will fail..
331 checkDate->setYMD( current.year(), 334 checkDate->setYMD( current.year(),
332 checkDate->month(), 335 checkDate->month(),
333 checkDate->day() ); 336 checkDate->day() );
334 if ( *checkDate < current ) 337 if ( *checkDate < current )
335 checkDate->setYMD( current.year()+1, 338 checkDate->setYMD( current.year()+1,
336 checkDate->month(), 339 checkDate->month(),
337 checkDate->day() ); 340 checkDate->day() );
338 341
339 // Check whether the birthday/anniversary date is between 342 // Check whether the birthday/anniversary date is between
340 // the current/given date and the maximum date 343 // the current/given date and the maximum date
341 // ( maximum time range ) ! 344 // ( maximum time range ) !
342 qWarning("Checking if %s is between %s and %s ! ", 345 qWarning("Checking if %s is between %s and %s ! ",
343 checkDate->toString().latin1(), 346 checkDate->toString().latin1(),
344 current.toString().latin1(), 347 current.toString().latin1(),
345 queryDate->toString().latin1() ); 348 queryDate->toString().latin1() );
346 if ( current.daysTo( *queryDate ) >= 0 ){ 349 if ( current.daysTo( *queryDate ) >= 0 ){
347 if ( !( ( *checkDate >= current ) && 350 if ( !( ( *checkDate >= current ) &&
348 ( *checkDate <= *queryDate ) ) ){ 351 ( *checkDate <= *queryDate ) ) ){
349 allcorrect = false; 352 allcorrect = false;
350 qWarning (" Nope!.."); 353 qWarning (" Nope!..");
351 } 354 }
352 } 355 }
353 } 356 }
354 } else{ 357 } else{
355 // checkDate is invalid. Therefore this entry is always rejected 358 // checkDate is invalid. Therefore this entry is always rejected
356 allcorrect = false; 359 allcorrect = false;
357 } 360 }
358 } 361 }
359 362
360 delete queryDate; 363 delete queryDate;
361 queryDate = 0l; 364 queryDate = 0l;
362 delete checkDate; 365 delete checkDate;
363 checkDate = 0l; 366 checkDate = 0l;
364 break; 367 break;
365 default: 368 default:
366 /* Just compare fields which are not empty in the query object */ 369 /* Just compare fields which are not empty in the query object */
367 if ( !query.field(i).isEmpty() ){ 370 if ( !query.field(i).isEmpty() ){
368 switch ( settings & ~( OContactAccess::IgnoreCase 371 switch ( settings & ~( OContactAccess::IgnoreCase
369 | OContactAccess::DateDiff 372 | OContactAccess::DateDiff
370 | OContactAccess::DateYear 373 | OContactAccess::DateYear
371 | OContactAccess::DateMonth 374 | OContactAccess::DateMonth
372 | OContactAccess::DateDay 375 | OContactAccess::DateDay
373 | OContactAccess::MatchOne 376 | OContactAccess::MatchOne
374 ) ){ 377 ) ){
375 378
376 case OContactAccess::RegExp:{ 379 case OContactAccess::RegExp:{
377 QRegExp expr ( query.field(i), 380 QRegExp expr ( query.field(i),
378 !(settings & OContactAccess::IgnoreCase), 381 !(settings & OContactAccess::IgnoreCase),
379 false ); 382 false );
380 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 383 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
381 allcorrect = false; 384 allcorrect = false;
382 } 385 }
383 break; 386 break;
384 case OContactAccess::WildCards:{ 387 case OContactAccess::WildCards:{
385 QRegExp expr ( query.field(i), 388 QRegExp expr ( query.field(i),
386 !(settings & OContactAccess::IgnoreCase), 389 !(settings & OContactAccess::IgnoreCase),
387 true ); 390 true );
388 if ( expr.find ( (*it)->field(i), 0 ) == -1 ) 391 if ( expr.find ( (*it)->field(i), 0 ) == -1 )
389 allcorrect = false; 392 allcorrect = false;
390 } 393 }
391 break; 394 break;
392 case OContactAccess::ExactMatch:{ 395 case OContactAccess::ExactMatch:{
393 if (settings & OContactAccess::IgnoreCase){ 396 if (settings & OContactAccess::IgnoreCase){
394 if ( query.field(i).upper() != 397 if ( query.field(i).upper() !=
395 (*it)->field(i).upper() ) 398 (*it)->field(i).upper() )
396 allcorrect = false; 399 allcorrect = false;
397 }else{ 400 }else{
398 if ( query.field(i) != (*it)->field(i) ) 401 if ( query.field(i) != (*it)->field(i) )
399 allcorrect = false; 402 allcorrect = false;
400 } 403 }
401 } 404 }
402 break; 405 break;
403 } 406 }
404 } 407 }
405 } 408 }
406 } 409 }
407 if ( allcorrect ){ 410 if ( allcorrect ){
408 m_currentQuery[arraycounter++] = (*it)->uid(); 411 m_currentQuery[arraycounter++] = (*it)->uid();
409 } 412 }
410 } 413 }
411 414
412 // Shrink to fit.. 415 // Shrink to fit..
413 m_currentQuery.resize(arraycounter); 416 m_currentQuery.resize(arraycounter);
414 417
415 return m_currentQuery; 418 return m_currentQuery;
416} 419}
417 420
418QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const 421QArray<int> OContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const
419{ 422{
420 QArray<int> m_currentQuery( m_contactList.count() ); 423 QArray<int> m_currentQuery( m_contactList.count() );
421 QListIterator<OContact> it( m_contactList ); 424 QListIterator<OContact> it( m_contactList );
422 uint arraycounter = 0; 425 uint arraycounter = 0;
423 426
424 for( ; it.current(); ++it ){ 427 for( ; it.current(); ++it ){
425 if ( (*it)->match( r ) ){ 428 if ( (*it)->match( r ) ){
426 m_currentQuery[arraycounter++] = (*it)->uid(); 429 m_currentQuery[arraycounter++] = (*it)->uid();
427 } 430 }
428 431
429 } 432 }
430 // Shrink to fit.. 433 // Shrink to fit..
431 m_currentQuery.resize(arraycounter); 434 m_currentQuery.resize(arraycounter);
432 435
433 return m_currentQuery; 436 return m_currentQuery;
434} 437}
435 438
436const uint OContactAccessBackend_XML::querySettings() 439const uint OContactAccessBackend_XML::querySettings()
437{ 440{
438 return ( OContactAccess::WildCards 441 return ( OContactAccess::WildCards
439 | OContactAccess::IgnoreCase 442 | OContactAccess::IgnoreCase
440 | OContactAccess::RegExp 443 | OContactAccess::RegExp
441 | OContactAccess::ExactMatch 444 | OContactAccess::ExactMatch
442 | OContactAccess::DateDiff 445 | OContactAccess::DateDiff
443 | OContactAccess::DateYear 446 | OContactAccess::DateYear
444 | OContactAccess::DateMonth 447 | OContactAccess::DateMonth
445 | OContactAccess::DateDay 448 | OContactAccess::DateDay
446 ); 449 );
447} 450}
448 451
449bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const 452bool OContactAccessBackend_XML::hasQuerySettings (uint querySettings) const
450{ 453{
451 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay 454 /* OContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay
452 * may be added with any of the other settings. IgnoreCase should never used alone. 455 * may be added with any of the other settings. IgnoreCase should never used alone.
453 * Wildcards, RegExp, ExactMatch should never used at the same time... 456 * Wildcards, RegExp, ExactMatch should never used at the same time...
454 */ 457 */
455 458
456 // Step 1: Check whether the given settings are supported by this backend 459 // Step 1: Check whether the given settings are supported by this backend
457 if ( ( querySettings & ( 460 if ( ( querySettings & (
458 OContactAccess::IgnoreCase 461 OContactAccess::IgnoreCase
459 | OContactAccess::WildCards 462 | OContactAccess::WildCards
460 | OContactAccess::DateDiff 463 | OContactAccess::DateDiff
461 | OContactAccess::DateYear 464 | OContactAccess::DateYear
462 | OContactAccess::DateMonth 465 | OContactAccess::DateMonth
463 | OContactAccess::DateDay 466 | OContactAccess::DateDay
464 | OContactAccess::RegExp 467 | OContactAccess::RegExp
465 | OContactAccess::ExactMatch 468 | OContactAccess::ExactMatch
466 ) ) != querySettings ) 469 ) ) != querySettings )
467 return false; 470 return false;
468 471
469 // Step 2: Check whether the given combinations are ok.. 472 // Step 2: Check whether the given combinations are ok..
470 473
471 // IngoreCase alone is invalid 474 // IngoreCase alone is invalid
472 if ( querySettings == OContactAccess::IgnoreCase ) 475 if ( querySettings == OContactAccess::IgnoreCase )
473 return false; 476 return false;
474 477
475 // WildCards, RegExp and ExactMatch should never used at the same time 478 // WildCards, RegExp and ExactMatch should never used at the same time
476 switch ( querySettings & ~( OContactAccess::IgnoreCase 479 switch ( querySettings & ~( OContactAccess::IgnoreCase
477 | OContactAccess::DateDiff 480 | OContactAccess::DateDiff
478 | OContactAccess::DateYear 481 | OContactAccess::DateYear
479 | OContactAccess::DateMonth 482 | OContactAccess::DateMonth
480 | OContactAccess::DateDay 483 | OContactAccess::DateDay
481 ) 484 )
482 ){ 485 ){
483 case OContactAccess::RegExp: 486 case OContactAccess::RegExp:
484 return ( true ); 487 return ( true );
485 case OContactAccess::WildCards: 488 case OContactAccess::WildCards:
486 return ( true ); 489 return ( true );
487 case OContactAccess::ExactMatch: 490 case OContactAccess::ExactMatch:
488 return ( true ); 491 return ( true );
489 case 0: // one of the upper removed bits were set.. 492 case 0: // one of the upper removed bits were set..
490 return ( true ); 493 return ( true );
491 default: 494 default:
492 return ( false ); 495 return ( false );
493 } 496 }
494} 497}
495 498
496// Currently only asc implemented.. 499// Currently only asc implemented..
497QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int ) 500QArray<int> OContactAccessBackend_XML::sorted( bool asc, int , int , int )
498{ 501{
499 QMap<QString, int> nameToUid; 502 QMap<QString, int> nameToUid;
500 QStringList names; 503 QStringList names;
501 QArray<int> m_currentQuery( m_contactList.count() ); 504 QArray<int> m_currentQuery( m_contactList.count() );
502 505
503 // First fill map and StringList with all Names 506 // First fill map and StringList with all Names
504 // Afterwards sort namelist and use map to fill array to return.. 507 // Afterwards sort namelist and use map to fill array to return..
505 QListIterator<OContact> it( m_contactList ); 508 QListIterator<OContact> it( m_contactList );
506 for( ; it.current(); ++it ){ 509 for( ; it.current(); ++it ){
507 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); 510 names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) );
508 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); 511 nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() );
509 } 512 }
510 names.sort(); 513 names.sort();
511 514
512 int i = 0; 515 int i = 0;
513 if ( asc ){ 516 if ( asc ){
514 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) 517 for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it )
515 m_currentQuery[i++] = nameToUid[ (*it) ]; 518 m_currentQuery[i++] = nameToUid[ (*it) ];
516 }else{ 519 }else{
517 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) 520 for ( QStringList::Iterator it = names.end(); it != names.begin(); --it )
518 m_currentQuery[i++] = nameToUid[ (*it) ]; 521 m_currentQuery[i++] = nameToUid[ (*it) ];
519 } 522 }
520 523
521 return m_currentQuery; 524 return m_currentQuery;
522 525
523} 526}
524 527
525bool OContactAccessBackend_XML::add ( const OContact &newcontact ) 528bool OContactAccessBackend_XML::add ( const OContact &newcontact )
526{ 529{
527 //qWarning("odefaultbackend: ACTION::ADD"); 530 //qWarning("odefaultbackend: ACTION::ADD");
528 updateJournal (newcontact, ACTION_ADD); 531 updateJournal (newcontact, ACTION_ADD);
529 addContact_p( newcontact ); 532 addContact_p( newcontact );
530 533
531 m_changed = true; 534 m_changed = true;
532 535
533 return true; 536 return true;
534} 537}
535 538
536bool OContactAccessBackend_XML::replace ( const OContact &contact ) 539bool OContactAccessBackend_XML::replace ( const OContact &contact )
537{ 540{
538 m_changed = true; 541 m_changed = true;
539 542
540 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); 543 OContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) );
541 544
542 if ( found ) { 545 if ( found ) {
543 OContact* newCont = new OContact( contact ); 546 OContact* newCont = new OContact( contact );
544 547
545 updateJournal ( *newCont, ACTION_REPLACE); 548 updateJournal ( *newCont, ACTION_REPLACE);
546 m_contactList.removeRef ( found ); 549 m_contactList.removeRef ( found );
547 m_contactList.append ( newCont ); 550 m_contactList.append ( newCont );
548 m_uidToContact.remove( QString().setNum( contact.uid() ) ); 551 m_uidToContact.remove( QString().setNum( contact.uid() ) );
549 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); 552 m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont );
550 553
551 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid()); 554 qWarning("Nur zur Sicherheit: %d == %d ?",contact.uid(), newCont->uid());
552 555
553 return true; 556 return true;
554 } else 557 } else
555 return false; 558 return false;
556} 559}
557 560
558bool OContactAccessBackend_XML::remove ( int uid ) 561bool OContactAccessBackend_XML::remove ( int uid )
559{ 562{
560 m_changed = true; 563 m_changed = true;
561 564
562 OContact* found = m_uidToContact.find ( QString().setNum( uid ) ); 565 OContact* found = m_uidToContact.find ( QString().setNum( uid ) );
563 566
564 if ( found ) { 567 if ( found ) {
565 updateJournal ( *found, ACTION_REMOVE); 568 updateJournal ( *found, ACTION_REMOVE);
566 m_contactList.removeRef ( found ); 569 m_contactList.removeRef ( found );
567 m_uidToContact.remove( QString().setNum( uid ) ); 570 m_uidToContact.remove( QString().setNum( uid ) );
568 571
569 return true; 572 return true;
570 } else 573 } else
571 return false; 574 return false;
572} 575}
573 576
574bool OContactAccessBackend_XML::reload(){ 577bool OContactAccessBackend_XML::reload(){
575 /* Reload is the same as load in this implementation */ 578 /* Reload is the same as load in this implementation */
576 return ( load() ); 579 return ( load() );
577} 580}
578 581
579void OContactAccessBackend_XML::addContact_p( const OContact &newcontact ) 582void OContactAccessBackend_XML::addContact_p( const OContact &newcontact )
580{ 583{
581 OContact* contRef = new OContact( newcontact ); 584 OContact* contRef = new OContact( newcontact );
582 585
583 m_contactList.append ( contRef ); 586 m_contactList.append ( contRef );
584 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); 587 m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef );
585} 588}
586 589
587/* This function loads the xml-database and the journalfile */ 590/* This function loads the xml-database and the journalfile */
588bool OContactAccessBackend_XML::load( const QString filename, bool isJournal ) 591bool OContactAccessBackend_XML::load( const QString filename, bool isJournal )
589{ 592{
590 593
591 /* We use the time of the last read to check if the file was 594 /* We use the time of the last read to check if the file was
592 * changed externally. 595 * changed externally.
593 */ 596 */
594 if ( !isJournal ){ 597 if ( !isJournal ){
595 QFileInfo fi( filename ); 598 QFileInfo fi( filename );
596 m_readtime = fi.lastModified (); 599 m_readtime = fi.lastModified ();
597 } 600 }
598 601
599 const int JOURNALACTION = Qtopia::Notes + 1; 602 const int JOURNALACTION = Qtopia::Notes + 1;
600 const int JOURNALROW = JOURNALACTION + 1; 603 const int JOURNALROW = JOURNALACTION + 1;
601 604
602 bool foundAction = false; 605 bool foundAction = false;
603 journal_action action = ACTION_ADD; 606 journal_action action = ACTION_ADD;
604 int journalKey = 0; 607 int journalKey = 0;
605 QMap<int, QString> contactMap; 608 QMap<int, QString> contactMap;
606 QMap<QString, QString> customMap; 609 QMap<QString, QString> customMap;
607 QMap<QString, QString>::Iterator customIt; 610 QMap<QString, QString>::Iterator customIt;
608 QAsciiDict<int> dict( 47 ); 611 QAsciiDict<int> dict( 47 );
609 612
610 dict.setAutoDelete( TRUE ); 613 dict.setAutoDelete( TRUE );
611 dict.insert( "Uid", new int(Qtopia::AddressUid) ); 614 dict.insert( "Uid", new int(Qtopia::AddressUid) );
612 dict.insert( "Title", new int(Qtopia::Title) ); 615 dict.insert( "Title", new int(Qtopia::Title) );
613 dict.insert( "FirstName", new int(Qtopia::FirstName) ); 616 dict.insert( "FirstName", new int(Qtopia::FirstName) );
614 dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); 617 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
615 dict.insert( "LastName", new int(Qtopia::LastName) ); 618 dict.insert( "LastName", new int(Qtopia::LastName) );
616 dict.insert( "Suffix", new int(Qtopia::Suffix) ); 619 dict.insert( "Suffix", new int(Qtopia::Suffix) );
617 dict.insert( "FileAs", new int(Qtopia::FileAs) ); 620 dict.insert( "FileAs", new int(Qtopia::FileAs) );
618 dict.insert( "Categories", new int(Qtopia::AddressCategory) ); 621 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
619 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); 622 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
620 dict.insert( "Emails", new int(Qtopia::Emails) ); 623 dict.insert( "Emails", new int(Qtopia::Emails) );
621 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); 624 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
622 dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); 625 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
623 dict.insert( "HomeState", new int(Qtopia::HomeState) ); 626 dict.insert( "HomeState", new int(Qtopia::HomeState) );
624 dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); 627 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
625 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); 628 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
626 dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); 629 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
627 dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); 630 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
628 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); 631 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
629 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); 632 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
630 dict.insert( "Company", new int(Qtopia::Company) ); 633 dict.insert( "Company", new int(Qtopia::Company) );
631 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); 634 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
632 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); 635 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
633 dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); 636 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
634 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); 637 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
635 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); 638 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
636 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); 639 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
637 dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); 640 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
638 dict.insert( "Department", new int(Qtopia::Department) ); 641 dict.insert( "Department", new int(Qtopia::Department) );
639 dict.insert( "Office", new int(Qtopia::Office) ); 642 dict.insert( "Office", new int(Qtopia::Office) );
640 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); 643 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
641 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); 644 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
642 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); 645 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
643 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); 646 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
644 dict.insert( "Profession", new int(Qtopia::Profession) ); 647 dict.insert( "Profession", new int(Qtopia::Profession) );
645 dict.insert( "Assistant", new int(Qtopia::Assistant) ); 648 dict.insert( "Assistant", new int(Qtopia::Assistant) );
646 dict.insert( "Manager", new int(Qtopia::Manager) ); 649 dict.insert( "Manager", new int(Qtopia::Manager) );
647 dict.insert( "Spouse", new int(Qtopia::Spouse) ); 650 dict.insert( "Spouse", new int(Qtopia::Spouse) );
648 dict.insert( "Children", new int(Qtopia::Children) ); 651 dict.insert( "Children", new int(Qtopia::Children) );
649 dict.insert( "Gender", new int(Qtopia::Gender) ); 652 dict.insert( "Gender", new int(Qtopia::Gender) );
650 dict.insert( "Birthday", new int(Qtopia::Birthday) ); 653 dict.insert( "Birthday", new int(Qtopia::Birthday) );
651 dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); 654 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
652 dict.insert( "Nickname", new int(Qtopia::Nickname) ); 655 dict.insert( "Nickname", new int(Qtopia::Nickname) );
653 dict.insert( "Notes", new int(Qtopia::Notes) ); 656 dict.insert( "Notes", new int(Qtopia::Notes) );
654 dict.insert( "action", new int(JOURNALACTION) ); 657 dict.insert( "action", new int(JOURNALACTION) );
655 dict.insert( "actionrow", new int(JOURNALROW) ); 658 dict.insert( "actionrow", new int(JOURNALROW) );
656 659
657 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); 660 //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() );
658 661
659 XMLElement *root = XMLElement::load( filename ); 662 XMLElement *root = XMLElement::load( filename );
660 if(root != 0l ){ // start parsing 663 if(root != 0l ){ // start parsing
661 /* Parse all XML-Elements and put the data into the 664 /* Parse all XML-Elements and put the data into the
662 * Contact-Class 665 * Contact-Class
663 */ 666 */
664 XMLElement *element = root->firstChild(); 667 XMLElement *element = root->firstChild();
665 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); 668 //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() );
666 element = element->firstChild(); 669 element = element->firstChild();
667 670
668 /* Search Tag "Contacts" which is the parent of all Contacts */ 671 /* Search Tag "Contacts" which is the parent of all Contacts */
669 while( element && !isJournal ){ 672 while( element && !isJournal ){
670 if( element->tagName() != QString::fromLatin1("Contacts") ){ 673 if( element->tagName() != QString::fromLatin1("Contacts") ){
671 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", 674 //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s",
672 // element->tagName().latin1()); 675 // element->tagName().latin1());
673 element = element->nextChild(); 676 element = element->nextChild();
674 } else { 677 } else {
675 element = element->firstChild(); 678 element = element->firstChild();
676 break; 679 break;
677 } 680 }
678 } 681 }
679 /* Parse all Contacts and ignore unknown tags */ 682 /* Parse all Contacts and ignore unknown tags */
680 while( element ){ 683 while( element ){
681 if( element->tagName() != QString::fromLatin1("Contact") ){ 684 if( element->tagName() != QString::fromLatin1("Contact") ){
682 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", 685 //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s",
683 // element->tagName().latin1()); 686 // element->tagName().latin1());
684 element = element->nextChild(); 687 element = element->nextChild();
685 continue; 688 continue;
686 } 689 }
687 /* Found alement with tagname "contact", now parse and store all 690 /* Found alement with tagname "contact", now parse and store all
688 * attributes contained 691 * attributes contained
689 */ 692 */
690 //qWarning("OContactDefBack::load element tagName() : %s", 693 //qWarning("OContactDefBack::load element tagName() : %s",
691 // element->tagName().latin1() ); 694 // element->tagName().latin1() );
692 QString dummy; 695 QString dummy;
693 foundAction = false; 696 foundAction = false;
694 697
695 XMLElement::AttributeMap aMap = element->attributes(); 698 XMLElement::AttributeMap aMap = element->attributes();
696 XMLElement::AttributeMap::Iterator it; 699 XMLElement::AttributeMap::Iterator it;
697 contactMap.clear(); 700 contactMap.clear();
698 customMap.clear(); 701 customMap.clear();
699 for( it = aMap.begin(); it != aMap.end(); ++it ){ 702 for( it = aMap.begin(); it != aMap.end(); ++it ){
700 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); 703 // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1());
701 704
702 int *find = dict[ it.key() ]; 705 int *find = dict[ it.key() ];
703 /* Unknown attributes will be stored as "Custom" elements */ 706 /* Unknown attributes will be stored as "Custom" elements */
704 if ( !find ) { 707 if ( !find ) {
705 qWarning("Attribute %s not known.", it.key().latin1()); 708 // qWarning("Attribute %s not known.", it.key().latin1());
706 //contact.setCustomField(it.key(), it.data()); 709 //contact.setCustomField(it.key(), it.data());
707 customMap.insert( it.key(), it.data() ); 710 customMap.insert( it.key(), it.data() );
708 continue; 711 continue;
709 } 712 }
710 713
711 /* Check if special conversion is needed and add attribute 714 /* Check if special conversion is needed and add attribute
712 * into Contact class 715 * into Contact class
713 */ 716 */
714 switch( *find ) { 717 switch( *find ) {
715 /* 718 /*
716 case Qtopia::AddressUid: 719 case Qtopia::AddressUid:
717 contact.setUid( it.data().toInt() ); 720 contact.setUid( it.data().toInt() );
718 break; 721 break;
719 case Qtopia::AddressCategory: 722 case Qtopia::AddressCategory:
720 contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); 723 contact.setCategories( Qtopia::Record::idsFromString( it.data( )));
721 break; 724 break;
722 */ 725 */
723 case JOURNALACTION: 726 case JOURNALACTION:
724 action = journal_action(it.data().toInt()); 727 action = journal_action(it.data().toInt());
725 foundAction = true; 728 foundAction = true;
726 qWarning ("ODefBack(journal)::ACTION found: %d", action); 729 qWarning ("ODefBack(journal)::ACTION found: %d", action);
727 break; 730 break;
728 case JOURNALROW: 731 case JOURNALROW:
729 journalKey = it.data().toInt(); 732 journalKey = it.data().toInt();
730 break; 733 break;
731 default: // no conversion needed add them to the map 734 default: // no conversion needed add them to the map
732 contactMap.insert( *find, it.data() ); 735 contactMap.insert( *find, it.data() );
733 break; 736 break;
734 } 737 }
735 } 738 }
736 /* now generate the Contact contact */ 739 /* now generate the Contact contact */
737 OContact contact( contactMap ); 740 OContact contact( contactMap );
738 741
739 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { 742 for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) {
740 contact.setCustomField( customIt.key(), customIt.data() ); 743 contact.setCustomField( customIt.key(), customIt.data() );
741 } 744 }
742 745
743 if (foundAction){ 746 if (foundAction){
744 foundAction = false; 747 foundAction = false;
745 switch ( action ) { 748 switch ( action ) {
746 case ACTION_ADD: 749 case ACTION_ADD:
747 addContact_p (contact); 750 addContact_p (contact);
748 break; 751 break;
749 case ACTION_REMOVE: 752 case ACTION_REMOVE:
750 if ( !remove (contact.uid()) ) 753 if ( !remove (contact.uid()) )
751 qWarning ("ODefBack(journal)::Unable to remove uid: %d", 754 qWarning ("ODefBack(journal)::Unable to remove uid: %d",
752 contact.uid() ); 755 contact.uid() );
753 break; 756 break;
754 case ACTION_REPLACE: 757 case ACTION_REPLACE:
755 if ( !replace ( contact ) ) 758 if ( !replace ( contact ) )
756 qWarning ("ODefBack(journal)::Unable to replace uid: %d", 759 qWarning ("ODefBack(journal)::Unable to replace uid: %d",
757 contact.uid() ); 760 contact.uid() );
758 break; 761 break;
759 default: 762 default:
760 qWarning ("Unknown action: ignored !"); 763 qWarning ("Unknown action: ignored !");
761 break; 764 break;
762 } 765 }
763 }else{ 766 }else{
764 /* Add contact to list */ 767 /* Add contact to list */
765 addContact_p (contact); 768 addContact_p (contact);
766 } 769 }
767 770
768 /* Move to next element */ 771 /* Move to next element */
769 element = element->nextChild(); 772 element = element->nextChild();
770 } 773 }
771 }else { 774 }else {
772 qWarning("ODefBack::could not load"); 775 qWarning("ODefBack::could not load");
773 } 776 }
774 delete root; 777 delete root;
775 qWarning("returning from loading" ); 778 qWarning("returning from loading" );
776 return true; 779 return true;
777} 780}
778 781
779 782
780void OContactAccessBackend_XML::updateJournal( const OContact& cnt, 783void OContactAccessBackend_XML::updateJournal( const OContact& cnt,
781 journal_action action ) 784 journal_action action )
782{ 785{
783 QFile f( m_journalName ); 786 QFile f( m_journalName );
784 bool created = !f.exists(); 787 bool created = !f.exists();
785 if ( !f.open(IO_WriteOnly|IO_Append) ) 788 if ( !f.open(IO_WriteOnly|IO_Append) )
786 return; 789 return;
787 790
788 QString buf; 791 QString buf;
789 QCString str; 792 QCString str;
790 793
791 // if the file was created, we have to set the Tag "<CONTACTS>" to 794 // if the file was created, we have to set the Tag "<CONTACTS>" to
792 // get a XML-File which is readable by our parser. 795 // get a XML-File which is readable by our parser.
793 // This is just a cheat, but better than rewrite the parser. 796 // This is just a cheat, but better than rewrite the parser.
794 if ( created ){ 797 if ( created ){
795 buf = "<Contacts>"; 798 buf = "<Contacts>";
796 QCString cstr = buf.utf8(); 799 QCString cstr = buf.utf8();
797 f.writeBlock( cstr.data(), cstr.length() ); 800 f.writeBlock( cstr.data(), cstr.length() );
798 } 801 }
799 802
800 buf = "<Contact "; 803 buf = "<Contact ";
801 cnt.save( buf ); 804 cnt.save( buf );
802 buf += " action=\"" + QString::number( (int)action ) + "\" "; 805 buf += " action=\"" + QString::number( (int)action ) + "\" ";
803 buf += "/>\n"; 806 buf += "/>\n";
804 QCString cstr = buf.utf8(); 807 QCString cstr = buf.utf8();
805 f.writeBlock( cstr.data(), cstr.length() ); 808 f.writeBlock( cstr.data(), cstr.length() );
806} 809}
807 810
808void OContactAccessBackend_XML::removeJournal() 811void OContactAccessBackend_XML::removeJournal()
809{ 812{
810 QFile f ( m_journalName ); 813 QFile f ( m_journalName );
811 if ( f.exists() ) 814 if ( f.exists() )
812 f.remove(); 815 f.remove();
813} 816}
814 817
diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp
index e34feeb..0f05b65 100644
--- a/libopie2/opiepim/ocontact.cpp
+++ b/libopie2/opiepim/ocontact.cpp
@@ -598,614 +598,614 @@ QString OContact::toRichText() const
598 text += "<br>" + Qtopia::escapeString(state); 598 text += "<br>" + Qtopia::escapeString(state);
599 marker = true; 599 marker = true;
600 } 600 }
601 break; 601 break;
602 } 602 }
603 case City_State_Zip:{ // City, State Zip_Code 603 case City_State_Zip:{ // City, State Zip_Code
604 state = homeState(); 604 state = homeState();
605 if ( !(value = homeCity()).isEmpty() ) { 605 if ( !(value = homeCity()).isEmpty() ) {
606 marker = true; 606 marker = true;
607 text += "<br>" + Qtopia::escapeString(value); 607 text += "<br>" + Qtopia::escapeString(value);
608 if ( state ) 608 if ( state )
609 text += ", " + Qtopia::escapeString(state); 609 text += ", " + Qtopia::escapeString(state);
610 } else if ( !state.isEmpty() ){ 610 } else if ( !state.isEmpty() ){
611 text += "<br>" + Qtopia::escapeString(state); 611 text += "<br>" + Qtopia::escapeString(state);
612 marker = true; 612 marker = true;
613 } 613 }
614 if ( !(value = homeZip()).isEmpty() ){ 614 if ( !(value = homeZip()).isEmpty() ){
615 text += " " + Qtopia::escapeString(value); 615 text += " " + Qtopia::escapeString(value);
616 marker = true; 616 marker = true;
617 } 617 }
618 break; 618 break;
619 } 619 }
620 } 620 }
621 621
622 if ( !(value = homeCountry()).isEmpty() ){ 622 if ( !(value = homeCountry()).isEmpty() ){
623 text += "<br>" + Qtopia::escapeString(value); 623 text += "<br>" + Qtopia::escapeString(value);
624 marker = true; 624 marker = true;
625 } 625 }
626 626
627 // rest of Home data 627 // rest of Home data
628 str = homeWebpage(); 628 str = homeWebpage();
629 if ( !str.isEmpty() ){ 629 if ( !str.isEmpty() ){
630 text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr("Home Web Page: ") + "</b>" 630 text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr("Home Web Page: ") + "</b>"
631 + Qtopia::escapeString(str); 631 + Qtopia::escapeString(str);
632 marker = true; 632 marker = true;
633 } 633 }
634 str = homePhone(); 634 str = homePhone();
635 if ( !str.isEmpty() ){ 635 if ( !str.isEmpty() ){
636 text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr("Home Phone: ") + "</b>" 636 text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr("Home Phone: ") + "</b>"
637 + Qtopia::escapeString(str); 637 + Qtopia::escapeString(str);
638 marker = true; 638 marker = true;
639 } 639 }
640 str = homeFax(); 640 str = homeFax();
641 if ( !str.isEmpty() ){ 641 if ( !str.isEmpty() ){
642 text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr("Home Fax: ") + "</b>" 642 text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr("Home Fax: ") + "</b>"
643 + Qtopia::escapeString(str); 643 + Qtopia::escapeString(str);
644 marker = true; 644 marker = true;
645 } 645 }
646 str = homeMobile(); 646 str = homeMobile();
647 if ( !str.isEmpty() ){ 647 if ( !str.isEmpty() ){
648 text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr("Home Mobile: ") + "</b>" 648 text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr("Home Mobile: ") + "</b>"
649 + Qtopia::escapeString(str); 649 + Qtopia::escapeString(str);
650 marker = true; 650 marker = true;
651 } 651 }
652 652
653 if ( marker ) 653 if ( marker )
654 text += "<br><hr>"; 654 text += "<br><hr>";
655 655
656 // the rest... 656 // the rest...
657 str = emails(); 657 str = emails();
658 if ( !str.isEmpty() && ( str != defEmail ) ) 658 if ( !str.isEmpty() && ( str != defEmail ) )
659 text += "<br><b>" + QObject::tr("All Emails: ") + "</b>" 659 text += "<br><b>" + QObject::tr("All Emails: ") + "</b>"
660 + Qtopia::escapeString(str); 660 + Qtopia::escapeString(str);
661 str = profession(); 661 str = profession();
662 if ( !str.isEmpty() ) 662 if ( !str.isEmpty() )
663 text += "<br><b>" + QObject::tr("Profession: ") + "</b>" 663 text += "<br><b>" + QObject::tr("Profession: ") + "</b>"
664 + Qtopia::escapeString(str); 664 + Qtopia::escapeString(str);
665 str = assistant(); 665 str = assistant();
666 if ( !str.isEmpty() ) 666 if ( !str.isEmpty() )
667 text += "<br><b>" + QObject::tr("Assistant: ") + "</b>" 667 text += "<br><b>" + QObject::tr("Assistant: ") + "</b>"
668 + Qtopia::escapeString(str); 668 + Qtopia::escapeString(str);
669 str = manager(); 669 str = manager();
670 if ( !str.isEmpty() ) 670 if ( !str.isEmpty() )
671 text += "<br><b>" + QObject::tr("Manager: ") + "</b>" 671 text += "<br><b>" + QObject::tr("Manager: ") + "</b>"
672 + Qtopia::escapeString(str); 672 + Qtopia::escapeString(str);
673 str = gender(); 673 str = gender();
674 if ( !str.isEmpty() && str.toInt() != 0 ) { 674 if ( !str.isEmpty() && str.toInt() != 0 ) {
675 text += "<br>"; 675 text += "<br>";
676 if ( str.toInt() == 1 ) 676 if ( str.toInt() == 1 )
677 str = QObject::tr( "Male" ); 677 str = QObject::tr( "Male" );
678 else if ( str.toInt() == 2 ) 678 else if ( str.toInt() == 2 )
679 str = QObject::tr( "Female" ); 679 str = QObject::tr( "Female" );
680 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str; 680 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str;
681 } 681 }
682 str = spouse(); 682 str = spouse();
683 if ( !str.isEmpty() ) 683 if ( !str.isEmpty() )
684 text += "<br><b>" + QObject::tr("Spouse: ") + "</b>" 684 text += "<br><b>" + QObject::tr("Spouse: ") + "</b>"
685 + Qtopia::escapeString(str); 685 + Qtopia::escapeString(str);
686 if ( birthday().isValid() ){ 686 if ( birthday().isValid() ){
687 str = TimeString::numberDateString( birthday() ); 687 str = TimeString::numberDateString( birthday() );
688 text += "<br><b>" + QObject::tr("Birthday: ") + "</b>" 688 text += "<br><b>" + QObject::tr("Birthday: ") + "</b>"
689 + Qtopia::escapeString(str); 689 + Qtopia::escapeString(str);
690 } 690 }
691 if ( anniversary().isValid() ){ 691 if ( anniversary().isValid() ){
692 str = TimeString::numberDateString( anniversary() ); 692 str = TimeString::numberDateString( anniversary() );
693 text += "<br><b>" + QObject::tr("Anniversary: ") + "</b>" 693 text += "<br><b>" + QObject::tr("Anniversary: ") + "</b>"
694 + Qtopia::escapeString(str); 694 + Qtopia::escapeString(str);
695 } 695 }
696 str = children(); 696 str = children();
697 if ( !str.isEmpty() ) 697 if ( !str.isEmpty() )
698 text += "<br><b>" + QObject::tr("Children: ") + "</b>" 698 text += "<br><b>" + QObject::tr("Children: ") + "</b>"
699 + Qtopia::escapeString(str); 699 + Qtopia::escapeString(str);
700 700
701 str = nickname(); 701 str = nickname();
702 if ( !str.isEmpty() ) 702 if ( !str.isEmpty() )
703 text += "<br><b>" + QObject::tr("Nickname: ") + "</b>" 703 text += "<br><b>" + QObject::tr("Nickname: ") + "</b>"
704 + Qtopia::escapeString(str); 704 + Qtopia::escapeString(str);
705 705
706 // categories 706 // categories
707 if ( categoryNames("Contacts").count() ){ 707 if ( categoryNames("Contacts").count() ){
708 text += "<br><b>" + QObject::tr( "Category:") + "</b> "; 708 text += "<br><b>" + QObject::tr( "Category:") + "</b> ";
709 text += categoryNames("Contacts").join(", "); 709 text += categoryNames("Contacts").join(", ");
710 } 710 }
711 711
712 // notes last 712 // notes last
713 if ( !(value = notes()).isEmpty() ) { 713 if ( !(value = notes()).isEmpty() ) {
714 text += "<br><hr><b>" + QObject::tr( "Notes:") + "</b> "; 714 text += "<br><hr><b>" + QObject::tr( "Notes:") + "</b> ";
715 QRegExp reg("\n"); 715 QRegExp reg("\n");
716 716
717 //QString tmp = Qtopia::escapeString(value); 717 //QString tmp = Qtopia::escapeString(value);
718 QString tmp = QStyleSheet::convertFromPlainText(value); 718 QString tmp = QStyleSheet::convertFromPlainText(value);
719 //tmp.replace( reg, "<br>" ); 719 //tmp.replace( reg, "<br>" );
720 text += "<br>" + tmp + "<br>"; 720 text += "<br>" + tmp + "<br>";
721 } 721 }
722 return text; 722 return text;
723} 723}
724 724
725/*! 725/*!
726 \internal 726 \internal
727*/ 727*/
728void OContact::insert( int key, const QString &v ) 728void OContact::insert( int key, const QString &v )
729{ 729{
730 QString value = v.stripWhiteSpace(); 730 QString value = v.stripWhiteSpace();
731 if ( value.isEmpty() ) 731 if ( value.isEmpty() )
732 mMap.remove( key ); 732 mMap.remove( key );
733 else 733 else
734 mMap.insert( key, value ); 734 mMap.insert( key, value );
735} 735}
736 736
737/*! 737/*!
738 \internal 738 \internal
739*/ 739*/
740void OContact::replace( int key, const QString & v ) 740void OContact::replace( int key, const QString & v )
741{ 741{
742 QString value = v.stripWhiteSpace(); 742 QString value = v.stripWhiteSpace();
743 if ( value.isEmpty() ) 743 if ( value.isEmpty() )
744 mMap.remove( key ); 744 mMap.remove( key );
745 else 745 else
746 mMap.replace( key, value ); 746 mMap.replace( key, value );
747} 747}
748 748
749/*! 749/*!
750 \internal 750 \internal
751*/ 751*/
752QString OContact::find( int key ) const 752QString OContact::find( int key ) const
753{ 753{
754 return mMap[key]; 754 return mMap[key];
755} 755}
756 756
757/*! 757/*!
758 \internal 758 \internal
759*/ 759*/
760QString OContact::displayAddress( const QString &street, 760QString OContact::displayAddress( const QString &street,
761 const QString &city, 761 const QString &city,
762 const QString &state, 762 const QString &state,
763 const QString &zip, 763 const QString &zip,
764 const QString &country ) const 764 const QString &country ) const
765{ 765{
766 QString s = street; 766 QString s = street;
767 if ( !street.isEmpty() ) 767 if ( !street.isEmpty() )
768 s+= "\n"; 768 s+= "\n";
769 s += city; 769 s += city;
770 if ( !city.isEmpty() && !state.isEmpty() ) 770 if ( !city.isEmpty() && !state.isEmpty() )
771 s += ", "; 771 s += ", ";
772 s += state; 772 s += state;
773 if ( !state.isEmpty() && !zip.isEmpty() ) 773 if ( !state.isEmpty() && !zip.isEmpty() )
774 s += " "; 774 s += " ";
775 s += zip; 775 s += zip;
776 if ( !country.isEmpty() && !s.isEmpty() ) 776 if ( !country.isEmpty() && !s.isEmpty() )
777 s += "\n"; 777 s += "\n";
778 s += country; 778 s += country;
779 return s; 779 return s;
780} 780}
781 781
782/*! 782/*!
783 \internal 783 \internal
784*/ 784*/
785QString OContact::displayBusinessAddress() const 785QString OContact::displayBusinessAddress() const
786{ 786{
787 return displayAddress( businessStreet(), businessCity(), 787 return displayAddress( businessStreet(), businessCity(),
788 businessState(), businessZip(), 788 businessState(), businessZip(),
789 businessCountry() ); 789 businessCountry() );
790} 790}
791 791
792/*! 792/*!
793 \internal 793 \internal
794*/ 794*/
795QString OContact::displayHomeAddress() const 795QString OContact::displayHomeAddress() const
796{ 796{
797 return displayAddress( homeStreet(), homeCity(), 797 return displayAddress( homeStreet(), homeCity(),
798 homeState(), homeZip(), 798 homeState(), homeZip(),
799 homeCountry() ); 799 homeCountry() );
800} 800}
801 801
802/*! 802/*!
803 Returns the full name of the contact 803 Returns the full name of the contact
804*/ 804*/
805QString OContact::fullName() const 805QString OContact::fullName() const
806{ 806{
807 QString title = find( Qtopia::Title ); 807 QString title = find( Qtopia::Title );
808 QString firstName = find( Qtopia::FirstName ); 808 QString firstName = find( Qtopia::FirstName );
809 QString middleName = find( Qtopia::MiddleName ); 809 QString middleName = find( Qtopia::MiddleName );
810 QString lastName = find( Qtopia::LastName ); 810 QString lastName = find( Qtopia::LastName );
811 QString suffix = find( Qtopia::Suffix ); 811 QString suffix = find( Qtopia::Suffix );
812 812
813 QString name = title; 813 QString name = title;
814 if ( !firstName.isEmpty() ) { 814 if ( !firstName.isEmpty() ) {
815 if ( !name.isEmpty() ) 815 if ( !name.isEmpty() )
816 name += " "; 816 name += " ";
817 name += firstName; 817 name += firstName;
818 } 818 }
819 if ( !middleName.isEmpty() ) { 819 if ( !middleName.isEmpty() ) {
820 if ( !name.isEmpty() ) 820 if ( !name.isEmpty() )
821 name += " "; 821 name += " ";
822 name += middleName; 822 name += middleName;
823 } 823 }
824 if ( !lastName.isEmpty() ) { 824 if ( !lastName.isEmpty() ) {
825 if ( !name.isEmpty() ) 825 if ( !name.isEmpty() )
826 name += " "; 826 name += " ";
827 name += lastName; 827 name += lastName;
828 } 828 }
829 if ( !suffix.isEmpty() ) { 829 if ( !suffix.isEmpty() ) {
830 if ( !name.isEmpty() ) 830 if ( !name.isEmpty() )
831 name += " "; 831 name += " ";
832 name += suffix; 832 name += suffix;
833 } 833 }
834 return name.simplifyWhiteSpace(); 834 return name.simplifyWhiteSpace();
835} 835}
836 836
837/*! 837/*!
838 Returns a list of the names of the children of the contact. 838 Returns a list of the names of the children of the contact.
839*/ 839*/
840QStringList OContact::childrenList() const 840QStringList OContact::childrenList() const
841{ 841{
842 return QStringList::split( " ", find( Qtopia::Children ) ); 842 return QStringList::split( " ", find( Qtopia::Children ) );
843} 843}
844 844
845/*! \fn void OContact::insertEmail( const QString &email ) 845/*! \fn void OContact::insertEmail( const QString &email )
846 846
847 Insert \a email into the email list. Ensures \a email can only be added 847 Insert \a email into the email list. Ensures \a email can only be added
848 once. If there is no default email address set, it sets it to the \a email. 848 once. If there is no default email address set, it sets it to the \a email.
849*/ 849*/
850 850
851/*! \fn void OContact::removeEmail( const QString &email ) 851/*! \fn void OContact::removeEmail( const QString &email )
852 852
853 Removes the \a email from the email list. If the default email was \a email, 853 Removes the \a email from the email list. If the default email was \a email,
854 then the default email address is assigned to the first email in the 854 then the default email address is assigned to the first email in the
855 email list 855 email list
856*/ 856*/
857 857
858/*! \fn void OContact::clearEmails() 858/*! \fn void OContact::clearEmails()
859 859
860 Clears the email list. 860 Clears the email list.
861 */ 861 */
862 862
863/*! \fn void OContact::insertEmails( const QStringList &emailList ) 863/*! \fn void OContact::insertEmails( const QStringList &emailList )
864 864
865 Appends the \a emailList to the exiting email list 865 Appends the \a emailList to the exiting email list
866 */ 866 */
867 867
868/*! 868/*!
869 Returns a list of email addresses belonging to the contact, including 869 Returns a list of email addresses belonging to the contact, including
870 the default email address. 870 the default email address.
871*/ 871*/
872QStringList OContact::emailList() const 872QStringList OContact::emailList() const
873{ 873{
874 QString emailStr = emails(); 874 QString emailStr = emails();
875 875
876 QStringList r; 876 QStringList r;
877 if ( !emailStr.isEmpty() ) { 877 if ( !emailStr.isEmpty() ) {
878 qDebug(" emailstr "); 878 qDebug(" emailstr ");
879 QStringList l = QStringList::split( emailSeparator(), emailStr ); 879 QStringList l = QStringList::split( emailSeparator(), emailStr );
880 for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) 880 for ( QStringList::ConstIterator it = l.begin();it != l.end();++it )
881 r += (*it).simplifyWhiteSpace(); 881 r += (*it).simplifyWhiteSpace();
882 } 882 }
883 883
884 return r; 884 return r;
885} 885}
886 886
887/*! 887/*!
888 \overload 888 \overload
889 889
890 Generates the string for the contact to be filed as from the first, 890 Generates the string for the contact to be filed as from the first,
891 middle and last name of the contact. 891 middle and last name of the contact.
892*/ 892*/
893void OContact::setFileAs() 893void OContact::setFileAs()
894{ 894{
895 QString lastName, firstName, middleName, fileas; 895 QString lastName, firstName, middleName, fileas;
896 896
897 lastName = find( Qtopia::LastName ); 897 lastName = find( Qtopia::LastName );
898 firstName = find( Qtopia::FirstName ); 898 firstName = find( Qtopia::FirstName );
899 middleName = find( Qtopia::MiddleName ); 899 middleName = find( Qtopia::MiddleName );
900 if ( !lastName.isEmpty() && !firstName.isEmpty() 900 if ( !lastName.isEmpty() && !firstName.isEmpty()
901 && !middleName.isEmpty() ) 901 && !middleName.isEmpty() )
902 fileas = lastName + ", " + firstName + " " + middleName; 902 fileas = lastName + ", " + firstName + " " + middleName;
903 else if ( !lastName.isEmpty() && !firstName.isEmpty() ) 903 else if ( !lastName.isEmpty() && !firstName.isEmpty() )
904 fileas = lastName + ", " + firstName; 904 fileas = lastName + ", " + firstName;
905 else if ( !lastName.isEmpty() || !firstName.isEmpty() || 905 else if ( !lastName.isEmpty() || !firstName.isEmpty() ||
906 !middleName.isEmpty() ) 906 !middleName.isEmpty() )
907 fileas = firstName + ( firstName.isEmpty() ? "" : " " ) 907 fileas = firstName + ( firstName.isEmpty() ? "" : " " )
908 + middleName + ( middleName.isEmpty() ? "" : " " ) 908 + middleName + ( middleName.isEmpty() ? "" : " " )
909 + lastName; 909 + lastName;
910 910
911 replace( Qtopia::FileAs, fileas ); 911 replace( Qtopia::FileAs, fileas );
912} 912}
913 913
914/*! 914/*!
915 \internal 915 \internal
916 Appends the contact information to \a buf. 916 Appends the contact information to \a buf.
917*/ 917*/
918void OContact::save( QString &buf ) const 918void OContact::save( QString &buf ) const
919{ 919{
920 static const QStringList SLFIELDS = fields(); 920 static const QStringList SLFIELDS = fields();
921 // I'm expecting "<Contact " in front of this... 921 // I'm expecting "<Contact " in front of this...
922 for ( QMap<int, QString>::ConstIterator it = mMap.begin(); 922 for ( QMap<int, QString>::ConstIterator it = mMap.begin();
923 it != mMap.end(); ++it ) { 923 it != mMap.end(); ++it ) {
924 const QString &value = it.data(); 924 const QString &value = it.data();
925 int key = it.key(); 925 int key = it.key();
926 if ( !value.isEmpty() ) { 926 if ( !value.isEmpty() ) {
927 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) 927 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid)
928 continue; 928 continue;
929 929
930 key -= Qtopia::AddressCategory+1; 930 key -= Qtopia::AddressCategory+1;
931 buf += SLFIELDS[key]; 931 buf += SLFIELDS[key];
932 buf += "=\"" + Qtopia::escapeString(value) + "\" "; 932 buf += "=\"" + Qtopia::escapeString(value) + "\" ";
933 } 933 }
934 } 934 }
935 buf += customToXml(); 935 buf += customToXml();
936 if ( categories().count() > 0 ) 936 if ( categories().count() > 0 )
937 buf += "Categories=\"" + idsToString( categories() ) + "\" "; 937 buf += "Categories=\"" + idsToString( categories() ) + "\" ";
938 buf += "Uid=\"" + QString::number( uid() ) + "\" "; 938 buf += "Uid=\"" + QString::number( uid() ) + "\" ";
939 // You need to close this yourself 939 // You need to close this yourself
940} 940}
941 941
942 942
943/*! 943/*!
944 \internal 944 \internal
945 Returns the list of fields belonging to a contact 945 Returns the list of fields belonging to a contact
946 Never change order of this list ! It has to be regarding 946 Never change order of this list ! It has to be regarding
947 enum AddressBookFields !! 947 enum AddressBookFields !!
948*/ 948*/
949QStringList OContact::fields() 949QStringList OContact::fields()
950{ 950{
951 QStringList list; 951 QStringList list;
952 952
953 list.append( "Title" ); // Not Used! 953 list.append( "Title" ); // Not Used!
954 list.append( "FirstName" ); 954 list.append( "FirstName" );
955 list.append( "MiddleName" ); 955 list.append( "MiddleName" );
956 list.append( "LastName" ); 956 list.append( "LastName" );
957 list.append( "Suffix" ); 957 list.append( "Suffix" );
958 list.append( "FileAs" ); 958 list.append( "FileAs" );
959 959
960 list.append( "JobTitle" ); 960 list.append( "JobTitle" );
961 list.append( "Department" ); 961 list.append( "Department" );
962 list.append( "Company" ); 962 list.append( "Company" );
963 list.append( "BusinessPhone" ); 963 list.append( "BusinessPhone" );
964 list.append( "BusinessFax" ); 964 list.append( "BusinessFax" );
965 list.append( "BusinessMobile" ); 965 list.append( "BusinessMobile" );
966 966
967 list.append( "DefaultEmail" ); 967 list.append( "DefaultEmail" );
968 list.append( "Emails" ); 968 list.append( "Emails" );
969 969
970 list.append( "HomePhone" ); 970 list.append( "HomePhone" );
971 list.append( "HomeFax" ); 971 list.append( "HomeFax" );
972 list.append( "HomeMobile" ); 972 list.append( "HomeMobile" );
973 973
974 list.append( "BusinessStreet" ); 974 list.append( "BusinessStreet" );
975 list.append( "BusinessCity" ); 975 list.append( "BusinessCity" );
976 list.append( "BusinessState" ); 976 list.append( "BusinessState" );
977 list.append( "BusinessZip" ); 977 list.append( "BusinessZip" );
978 list.append( "BusinessCountry" ); 978 list.append( "BusinessCountry" );
979 list.append( "BusinessPager" ); 979 list.append( "BusinessPager" );
980 list.append( "BusinessWebPage" ); 980 list.append( "BusinessWebPage" );
981 981
982 list.append( "Office" ); 982 list.append( "Office" );
983 list.append( "Profession" ); 983 list.append( "Profession" );
984 list.append( "Assistant" ); 984 list.append( "Assistant" );
985 list.append( "Manager" ); 985 list.append( "Manager" );
986 986
987 list.append( "HomeStreet" ); 987 list.append( "HomeStreet" );
988 list.append( "HomeCity" ); 988 list.append( "HomeCity" );
989 list.append( "HomeState" ); 989 list.append( "HomeState" );
990 list.append( "HomeZip" ); 990 list.append( "HomeZip" );
991 list.append( "HomeCountry" ); 991 list.append( "HomeCountry" );
992 list.append( "HomeWebPage" ); 992 list.append( "HomeWebPage" );
993 993
994 list.append( "Spouse" ); 994 list.append( "Spouse" );
995 list.append( "Gender" ); 995 list.append( "Gender" );
996 list.append( "Birthday" ); 996 list.append( "Birthday" );
997 list.append( "Anniversary" ); 997 list.append( "Anniversary" );
998 list.append( "Nickname" ); 998 list.append( "Nickname" );
999 list.append( "Children" ); 999 list.append( "Children" );
1000 1000
1001 list.append( "Notes" ); 1001 list.append( "Notes" );
1002 list.append( "Groups" ); 1002 list.append( "Groups" );
1003 1003
1004 return list; 1004 return list;
1005} 1005}
1006 1006
1007 1007
1008/*! 1008/*!
1009 Sets the list of email address for contact to those contained in \a str. 1009 Sets the list of email address for contact to those contained in \a str.
1010 Email address should be separated by ';'s. 1010 Email address should be separated by ';'s.
1011*/ 1011*/
1012void OContact::setEmails( const QString &str ) 1012void OContact::setEmails( const QString &str )
1013{ 1013{
1014 replace( Qtopia::Emails, str ); 1014 replace( Qtopia::Emails, str );
1015 if ( str.isEmpty() ) 1015 if ( str.isEmpty() )
1016 setDefaultEmail( QString::null ); 1016 setDefaultEmail( QString::null );
1017} 1017}
1018 1018
1019/*! 1019/*!
1020 Sets the list of children for the contact to those contained in \a str. 1020 Sets the list of children for the contact to those contained in \a str.
1021*/ 1021*/
1022void OContact::setChildren( const QString &str ) 1022void OContact::setChildren( const QString &str )
1023{ 1023{
1024 replace( Qtopia::Children, str ); 1024 replace( Qtopia::Children, str );
1025} 1025}
1026 1026
1027/*! 1027/*!
1028 \overload 1028 \overload
1029 Returns TRUE if the contact matches the regular expression \a regexp. 1029 Returns TRUE if the contact matches the regular expression \a regexp.
1030 Otherwise returns FALSE. 1030 Otherwise returns FALSE.
1031*/ 1031*/
1032bool OContact::match( const QRegExp &r ) const 1032bool OContact::match( const QRegExp &r ) const
1033{ 1033{
1034 setLastHitField( -1 ); 1034 setLastHitField( -1 );
1035 bool match; 1035 bool match;
1036 match = false; 1036 match = false;
1037 QMap<int, QString>::ConstIterator it; 1037 QMap<int, QString>::ConstIterator it;
1038 for ( it = mMap.begin(); it != mMap.end(); ++it ) { 1038 for ( it = mMap.begin(); it != mMap.end(); ++it ) {
1039 if ( (*it).find( r ) > -1 ) { 1039 if ( (*it).find( r ) > -1 ) {
1040 setLastHitField( it.key() ); 1040 setLastHitField( it.key() );
1041 match = true; 1041 match = true;
1042 break; 1042 break;
1043 } 1043 }
1044 } 1044 }
1045 return match; 1045 return match;
1046} 1046}
1047 1047
1048 1048
1049QString OContact::toShortText() const 1049QString OContact::toShortText() const
1050{ 1050{
1051 return ( fullName() ); 1051 return ( fullName() );
1052} 1052}
1053QString OContact::type() const 1053QString OContact::type() const
1054{ 1054{
1055 return QString::fromLatin1( "OContact" ); 1055 return QString::fromLatin1( "OContact" );
1056} 1056}
1057 1057
1058 1058
1059 1059
1060class QString OContact::recordField( int pos ) const 1060class QString OContact::recordField( int pos ) const
1061{ 1061{
1062 QStringList SLFIELDS = fields(); // ?? why this ? (se) 1062 QStringList SLFIELDS = fields(); // ?? why this ? (se)
1063 return SLFIELDS[pos]; 1063 return SLFIELDS[pos];
1064} 1064}
1065 1065
1066// In future releases, we should store birthday and anniversary 1066// In future releases, we should store birthday and anniversary
1067// internally as QDate instead of QString ! 1067// internally as QDate instead of QString !
1068// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) 1068// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se)
1069 1069
1070/*! \fn void OContact::setBirthday( const QDate& date ) 1070/*! \fn void OContact::setBirthday( const QDate& date )
1071 Sets the birthday for the contact to \a date. If date is null 1071 Sets the birthday for the contact to \a date. If date is null
1072 the current stored date will be removed. 1072 the current stored date will be removed.
1073*/ 1073*/
1074void OContact::setBirthday( const QDate &v ) 1074void OContact::setBirthday( const QDate &v )
1075{ 1075{
1076 if ( v.isNull() ){ 1076 if ( v.isNull() ){
1077 qWarning( "Remove Birthday"); 1077 qWarning( "Remove Birthday");
1078 replace( Qtopia::Birthday, QString::null ); 1078 replace( Qtopia::Birthday, QString::null );
1079 return; 1079 return;
1080 } 1080 }
1081 1081
1082 if ( v.isValid() ) 1082 if ( v.isValid() )
1083 replace( Qtopia::Birthday, OConversion::dateToString( v ) ); 1083 replace( Qtopia::Birthday, OConversion::dateToString( v ) );
1084 1084
1085} 1085}
1086 1086
1087 1087
1088/*! \fn void OContact::setAnniversary( const QDate &date ) 1088/*! \fn void OContact::setAnniversary( const QDate &date )
1089 Sets the anniversary of the contact to \a date. If date is 1089 Sets the anniversary of the contact to \a date. If date is
1090 null, the current stored date will be removed. 1090 null, the current stored date will be removed.
1091*/ 1091*/
1092void OContact::setAnniversary( const QDate &v ) 1092void OContact::setAnniversary( const QDate &v )
1093{ 1093{
1094 if ( v.isNull() ){ 1094 if ( v.isNull() ){
1095 qWarning( "Remove Anniversary"); 1095 qWarning( "Remove Anniversary");
1096 replace( Qtopia::Anniversary, QString::null ); 1096 replace( Qtopia::Anniversary, QString::null );
1097 return; 1097 return;
1098 } 1098 }
1099 1099
1100 if ( v.isValid() ) 1100 if ( v.isValid() )
1101 replace( Qtopia::Anniversary, OConversion::dateToString( v ) ); 1101 replace( Qtopia::Anniversary, OConversion::dateToString( v ) );
1102} 1102}
1103 1103
1104/*! \fn QDate OContact::birthday() const 1104/*! \fn QDate OContact::birthday() const
1105 Returns the birthday of the contact. 1105 Returns the birthday of the contact.
1106*/ 1106*/
1107QDate OContact::birthday() const 1107QDate OContact::birthday() const
1108{ 1108{
1109 QString str = find( Qtopia::Birthday ); 1109 QString str = find( Qtopia::Birthday );
1110 qWarning ("Birthday %s", str.latin1() ); 1110 // qWarning ("Birthday %s", str.latin1() );
1111 if ( !str.isEmpty() ) 1111 if ( !str.isEmpty() )
1112 return OConversion::dateFromString ( str ); 1112 return OConversion::dateFromString ( str );
1113 else 1113 else
1114 return QDate(); 1114 return QDate();
1115} 1115}
1116 1116
1117 1117
1118/*! \fn QDate OContact::anniversary() const 1118/*! \fn QDate OContact::anniversary() const
1119 Returns the anniversary of the contact. 1119 Returns the anniversary of the contact.
1120*/ 1120*/
1121QDate OContact::anniversary() const 1121QDate OContact::anniversary() const
1122{ 1122{
1123 QDate empty; 1123 QDate empty;
1124 QString str = find( Qtopia::Anniversary ); 1124 QString str = find( Qtopia::Anniversary );
1125 qWarning ("Anniversary %s", str.latin1() ); 1125 // qWarning ("Anniversary %s", str.latin1() );
1126 if ( !str.isEmpty() ) 1126 if ( !str.isEmpty() )
1127 return OConversion::dateFromString ( str ); 1127 return OConversion::dateFromString ( str );
1128 else 1128 else
1129 return empty; 1129 return empty;
1130} 1130}
1131 1131
1132 1132
1133void OContact::insertEmail( const QString &v ) 1133void OContact::insertEmail( const QString &v )
1134{ 1134{
1135 //qDebug("insertEmail %s", v.latin1()); 1135 //qDebug("insertEmail %s", v.latin1());
1136 QString e = v.simplifyWhiteSpace(); 1136 QString e = v.simplifyWhiteSpace();
1137 QString def = defaultEmail(); 1137 QString def = defaultEmail();
1138 1138
1139 // if no default, set it as the default email and don't insert 1139 // if no default, set it as the default email and don't insert
1140 if ( def.isEmpty() ) { 1140 if ( def.isEmpty() ) {
1141 setDefaultEmail( e ); // will insert into the list for us 1141 setDefaultEmail( e ); // will insert into the list for us
1142 return; 1142 return;
1143 } 1143 }
1144 1144
1145 // otherwise, insert assuming doesn't already exist 1145 // otherwise, insert assuming doesn't already exist
1146 QString emailsStr = find( Qtopia::Emails ); 1146 QString emailsStr = find( Qtopia::Emails );
1147 if ( emailsStr.contains( e )) 1147 if ( emailsStr.contains( e ))
1148 return; 1148 return;
1149 if ( !emailsStr.isEmpty() ) 1149 if ( !emailsStr.isEmpty() )
1150 emailsStr += emailSeparator(); 1150 emailsStr += emailSeparator();
1151 emailsStr += e; 1151 emailsStr += e;
1152 replace( Qtopia::Emails, emailsStr ); 1152 replace( Qtopia::Emails, emailsStr );
1153} 1153}
1154 1154
1155void OContact::removeEmail( const QString &v ) 1155void OContact::removeEmail( const QString &v )
1156{ 1156{
1157 QString e = v.simplifyWhiteSpace(); 1157 QString e = v.simplifyWhiteSpace();
1158 QString def = defaultEmail(); 1158 QString def = defaultEmail();
1159 QString emailsStr = find( Qtopia::Emails ); 1159 QString emailsStr = find( Qtopia::Emails );
1160 QStringList emails = emailList(); 1160 QStringList emails = emailList();
1161 1161
1162 // otherwise, must first contain it 1162 // otherwise, must first contain it
1163 if ( !emailsStr.contains( e ) ) 1163 if ( !emailsStr.contains( e ) )
1164 return; 1164 return;
1165 1165
1166 // remove it 1166 // remove it
1167 //qDebug(" removing email from list %s", e.latin1()); 1167 //qDebug(" removing email from list %s", e.latin1());
1168 emails.remove( e ); 1168 emails.remove( e );
1169 // reset the string 1169 // reset the string
1170 emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator 1170 emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator
1171 replace( Qtopia::Emails, emailsStr ); 1171 replace( Qtopia::Emails, emailsStr );
1172 1172
1173 // if default, then replace the default email with the first one 1173 // if default, then replace the default email with the first one
1174 if ( def == e ) { 1174 if ( def == e ) {
1175 //qDebug("removeEmail is default; setting new default"); 1175 //qDebug("removeEmail is default; setting new default");
1176 if ( !emails.count() ) 1176 if ( !emails.count() )
1177 clearEmails(); 1177 clearEmails();
1178 else // setDefaultEmail will remove e from the list 1178 else // setDefaultEmail will remove e from the list
1179 setDefaultEmail( emails.first() ); 1179 setDefaultEmail( emails.first() );
1180 } 1180 }
1181} 1181}
1182void OContact::clearEmails() 1182void OContact::clearEmails()
1183{ 1183{
1184 mMap.remove( Qtopia::DefaultEmail ); 1184 mMap.remove( Qtopia::DefaultEmail );
1185 mMap.remove( Qtopia::Emails ); 1185 mMap.remove( Qtopia::Emails );
1186} 1186}
1187void OContact::setDefaultEmail( const QString &v ) 1187void OContact::setDefaultEmail( const QString &v )
1188{ 1188{
1189 QString e = v.simplifyWhiteSpace(); 1189 QString e = v.simplifyWhiteSpace();
1190 1190
1191 //qDebug("OContact::setDefaultEmail %s", e.latin1()); 1191 //qDebug("OContact::setDefaultEmail %s", e.latin1());
1192 replace( Qtopia::DefaultEmail, e ); 1192 replace( Qtopia::DefaultEmail, e );
1193 1193
1194 if ( !e.isEmpty() ) 1194 if ( !e.isEmpty() )
1195 insertEmail( e ); 1195 insertEmail( e );
1196 1196
1197} 1197}
1198 1198
1199void OContact::insertEmails( const QStringList &v ) 1199void OContact::insertEmails( const QStringList &v )
1200{ 1200{
1201 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) 1201 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it )
1202 insertEmail( *it ); 1202 insertEmail( *it );
1203} 1203}
1204int OContact::rtti() { 1204int OContact::rtti() {
1205 return OPimResolver::AddressBook; 1205 return OPimResolver::AddressBook;
1206} 1206}
1207void OContact::setUid( int i ) 1207void OContact::setUid( int i )
1208{ 1208{
1209 OPimRecord::setUid(i); 1209 OPimRecord::setUid(i);
1210 replace( Qtopia::AddressUid , QString::number(i)); 1210 replace( Qtopia::AddressUid , QString::number(i));
1211} 1211}