summaryrefslogtreecommitdiff
authoreilers <eilers>2002-11-18 09:36:41 (UTC)
committer eilers <eilers>2002-11-18 09:36:41 (UTC)
commit4d0773414a0fb59e53f30d4d2363f73304f474dc (patch) (unidiff)
treee1d972774367a7d24239c8a00a5a3e47d9bd309c
parentbbe119475b8cb5c03ffb10e4dd328ee281970608 (diff)
downloadopie-4d0773414a0fb59e53f30d4d2363f73304f474dc.zip
opie-4d0773414a0fb59e53f30d4d2363f73304f474dc.tar.gz
opie-4d0773414a0fb59e53f30d4d2363f73304f474dc.tar.bz2
Back to main tree.. Waiting for feature freeze
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/ocontact.cpp625
-rw-r--r--libopie/pim/ocontact.h42
-rw-r--r--libopie2/opiepim/ocontact.cpp625
-rw-r--r--libopie2/opiepim/ocontact.h42
4 files changed, 80 insertions, 1254 deletions
diff --git a/libopie/pim/ocontact.cpp b/libopie/pim/ocontact.cpp
index b0f0d7f..917eb0a 100644
--- a/libopie/pim/ocontact.cpp
+++ b/libopie/pim/ocontact.cpp
@@ -1,58 +1,56 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** Copyright (C) 2002 by Stefan Eilers (eilers.stefan@epost.de) 3** Copyright (C) 2002 by Stefan Eilers (eilers.stefan@epost.de)
4** 4**
5** This file is part of the Qtopia Environment. 5** This file is part of the Qtopia Environment.
6** 6**
7** This file may be distributed and/or modified under the terms of the 7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software 8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the 9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file. 10** packaging of this file.
11** 11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16** 16**
17** Contact info@trolltech.com if any conditions of this licensing are 17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you. 18** not clear to you.
19** 19**
20**********************************************************************/ 20**********************************************************************/
21 21
22#define QTOPIA_INTERNAL_CONTACT_MRE 22#define QTOPIA_INTERNAL_CONTACT_MRE
23 23
24#include "ocontact.h" 24#include "ocontact.h"
25#include "../../library/backend/vobject_p.h"
26#include "../../library/backend/qfiledirect_p.h"
27 25
28#include <qpe/stringutil.h> 26#include <qpe/stringutil.h>
29#include <qpe/timeconversion.h> 27#include <qpe/timeconversion.h>
30#include <qpe/timestring.h> 28#include <qpe/timestring.h>
31 29
32#include <qobject.h> 30#include <qobject.h>
33#include <qregexp.h> 31#include <qregexp.h>
34#include <qstylesheet.h> 32#include <qstylesheet.h>
35#include <qfileinfo.h> 33#include <qfileinfo.h>
36#include <qmap.h> 34#include <qmap.h>
37 35
38#include <stdio.h> 36#include <stdio.h>
39 37
40/*! 38/*!
41 \class Contact contact.h 39 \class Contact contact.h
42 \brief The Contact class holds the data of an address book entry. 40 \brief The Contact class holds the data of an address book entry.
43 41
44 This data includes information the name of the person, contact 42 This data includes information the name of the person, contact
45 information, and business information such as deparment and job title. 43 information, and business information such as deparment and job title.
46 44
47 \ingroup qtopiaemb 45 \ingroup qtopiaemb
48 \ingroup qtopiadesktop 46 \ingroup qtopiadesktop
49*/ 47*/
50 48
51 49
52/*! 50/*!
53 Creates a new, empty contact. 51 Creates a new, empty contact.
54*/ 52*/
55OContact::OContact() 53OContact::OContact()
56 : OPimRecord(), mMap(), d( 0 ) 54 : OPimRecord(), mMap(), d( 0 )
57{ 55{
58} 56}
@@ -558,64 +556,70 @@ QString OContact::toRichText() const
558 + Qtopia::escapeString(str) + "<br>"; 556 + Qtopia::escapeString(str) + "<br>";
559 str = manager(); 557 str = manager();
560 if ( !str.isEmpty() ) 558 if ( !str.isEmpty() )
561 text += "<b>" + QObject::tr("Manager: ") + "</b>" 559 text += "<b>" + QObject::tr("Manager: ") + "</b>"
562 + Qtopia::escapeString(str) + "<br>"; 560 + Qtopia::escapeString(str) + "<br>";
563 str = gender(); 561 str = gender();
564 if ( !str.isEmpty() && str.toInt() != 0 ) { 562 if ( !str.isEmpty() && str.toInt() != 0 ) {
565 if ( str.toInt() == 1 ) 563 if ( str.toInt() == 1 )
566 str = QObject::tr( "Male" ); 564 str = QObject::tr( "Male" );
567 else if ( str.toInt() == 2 ) 565 else if ( str.toInt() == 2 )
568 str = QObject::tr( "Female" ); 566 str = QObject::tr( "Female" );
569 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; 567 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>";
570 } 568 }
571 str = spouse(); 569 str = spouse();
572 if ( !str.isEmpty() ) 570 if ( !str.isEmpty() )
573 text += "<b>" + QObject::tr("Spouse: ") + "</b>" 571 text += "<b>" + QObject::tr("Spouse: ") + "</b>"
574 + Qtopia::escapeString(str) + "<br>"; 572 + Qtopia::escapeString(str) + "<br>";
575 if ( birthday().isValid() ){ 573 if ( birthday().isValid() ){
576 str = TimeString::numberDateString( birthday() ); 574 str = TimeString::numberDateString( birthday() );
577 text += "<b>" + QObject::tr("Birthday: ") + "</b>" 575 text += "<b>" + QObject::tr("Birthday: ") + "</b>"
578 + Qtopia::escapeString(str) + "<br>"; 576 + Qtopia::escapeString(str) + "<br>";
579 } 577 }
580 if ( anniversary().isValid() ){ 578 if ( anniversary().isValid() ){
581 str = TimeString::numberDateString( anniversary() ); 579 str = TimeString::numberDateString( anniversary() );
582 text += "<b>" + QObject::tr("Anniversary: ") + "</b>" 580 text += "<b>" + QObject::tr("Anniversary: ") + "</b>"
583 + Qtopia::escapeString(str) + "<br>"; 581 + Qtopia::escapeString(str) + "<br>";
584 } 582 }
585 str = nickname(); 583 str = nickname();
586 if ( !str.isEmpty() ) 584 if ( !str.isEmpty() )
587 text += "<b>" + QObject::tr("Nickname: ") + "</b>" 585 text += "<b>" + QObject::tr("Nickname: ") + "</b>"
588 + Qtopia::escapeString(str) + "<br>"; 586 + Qtopia::escapeString(str) + "<br>";
589 587
588 if ( categoryNames().count() ){
589 text += "<b>" + QObject::tr( "Category:") + "</b> ";
590 text += categoryNames().join(", ");
591 text += "<br>";
592 }
593
590 // notes last 594 // notes last
591 if ( (value = notes()) ) { 595 if ( (value = notes()) ) {
592 QRegExp reg("\n"); 596 QRegExp reg("\n");
593 597
594 //QString tmp = Qtopia::escapeString(value); 598 //QString tmp = Qtopia::escapeString(value);
595 QString tmp = QStyleSheet::convertFromPlainText(value); 599 QString tmp = QStyleSheet::convertFromPlainText(value);
596 //tmp.replace( reg, "<br>" ); 600 //tmp.replace( reg, "<br>" );
597 text += "<br>" + tmp + "<br>"; 601 text += "<br>" + tmp + "<br>";
598 } 602 }
599 return text; 603 return text;
600} 604}
601 605
602/*! 606/*!
603 \internal 607 \internal
604*/ 608*/
605void OContact::insert( int key, const QString &v ) 609void OContact::insert( int key, const QString &v )
606{ 610{
607 QString value = v.stripWhiteSpace(); 611 QString value = v.stripWhiteSpace();
608 if ( value.isEmpty() ) 612 if ( value.isEmpty() )
609 mMap.remove( key ); 613 mMap.remove( key );
610 else 614 else
611 mMap.insert( key, value ); 615 mMap.insert( key, value );
612} 616}
613 617
614/*! 618/*!
615 \internal 619 \internal
616*/ 620*/
617void OContact::replace( int key, const QString & v ) 621void OContact::replace( int key, const QString & v )
618{ 622{
619 QString value = v.stripWhiteSpace(); 623 QString value = v.stripWhiteSpace();
620 if ( value.isEmpty() ) 624 if ( value.isEmpty() )
621 mMap.remove( key ); 625 mMap.remove( key );
@@ -787,806 +791,236 @@ void OContact::setFileAs()
787 791
788 replace( Qtopia::FileAs, fileas ); 792 replace( Qtopia::FileAs, fileas );
789} 793}
790 794
791/*! 795/*!
792 \internal 796 \internal
793 Appends the contact information to \a buf. 797 Appends the contact information to \a buf.
794*/ 798*/
795void OContact::save( QString &buf ) const 799void OContact::save( QString &buf ) const
796{ 800{
797 static const QStringList SLFIELDS = fields(); 801 static const QStringList SLFIELDS = fields();
798 // I'm expecting "<Contact " in front of this... 802 // I'm expecting "<Contact " in front of this...
799 for ( QMap<int, QString>::ConstIterator it = mMap.begin(); 803 for ( QMap<int, QString>::ConstIterator it = mMap.begin();
800 it != mMap.end(); ++it ) { 804 it != mMap.end(); ++it ) {
801 const QString &value = it.data(); 805 const QString &value = it.data();
802 int key = it.key(); 806 int key = it.key();
803 if ( !value.isEmpty() ) { 807 if ( !value.isEmpty() ) {
804 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) 808 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid)
805 continue; 809 continue;
806 810
807 key -= Qtopia::AddressCategory+1; 811 key -= Qtopia::AddressCategory+1;
808 buf += SLFIELDS[key]; 812 buf += SLFIELDS[key];
809 buf += "=\"" + Qtopia::escapeString(value) + "\" "; 813 buf += "=\"" + Qtopia::escapeString(value) + "\" ";
810 } 814 }
811 } 815 }
812 buf += customToXml(); 816 buf += customToXml();
813 if ( categories().count() > 0 ) 817 if ( categories().count() > 0 )
814 buf += "Categories=\"" + idsToString( categories() ) + "\" "; 818 buf += "Categories=\"" + idsToString( categories() ) + "\" ";
815 buf += "Uid=\"" + QString::number( uid() ) + "\" "; 819 buf += "Uid=\"" + QString::number( uid() ) + "\" ";
816 // You need to close this yourself 820 // You need to close this yourself
817} 821}
818 822
823
819/*! 824/*!
820 \internal 825 \internal
821 Returns the list of fields belonging to a contact 826 Returns the list of fields belonging to a contact
827 Never change order of this list ! It has to be regarding
828 enum AddressBookFields !!
822*/ 829*/
823QStringList OContact::fields() 830QStringList OContact::fields()
824{ 831{
825 QStringList list; 832 QStringList list;
826 833
827 list.append( "Title" ); // Not Used! 834 list.append( "Title" ); // Not Used!
828 list.append( "FirstName" ); 835 list.append( "FirstName" );
829 list.append( "MiddleName" ); 836 list.append( "MiddleName" );
830 list.append( "LastName" ); 837 list.append( "LastName" );
831 list.append( "Suffix" ); 838 list.append( "Suffix" );
832 list.append( "FileAs" ); 839 list.append( "FileAs" );
833 840
834 list.append( "JobTitle" ); 841 list.append( "JobTitle" );
835 list.append( "Department" ); 842 list.append( "Department" );
836 list.append( "Company" ); 843 list.append( "Company" );
837 list.append( "BusinessPhone" ); 844 list.append( "BusinessPhone" );
838 list.append( "BusinessFax" ); 845 list.append( "BusinessFax" );
839 list.append( "BusinessMobile" ); 846 list.append( "BusinessMobile" );
840 847
841 list.append( "DefaultEmail" ); 848 list.append( "DefaultEmail" );
842 list.append( "Emails" ); 849 list.append( "Emails" );
843 850
844 list.append( "HomePhone" ); 851 list.append( "HomePhone" );
845 list.append( "HomeFax" ); 852 list.append( "HomeFax" );
846 list.append( "HomeMobile" ); 853 list.append( "HomeMobile" );
847 854
848 list.append( "BusinessStreet" ); 855 list.append( "BusinessStreet" );
849 list.append( "BusinessCity" ); 856 list.append( "BusinessCity" );
850 list.append( "BusinessState" ); 857 list.append( "BusinessState" );
851 list.append( "BusinessZip" ); 858 list.append( "BusinessZip" );
852 list.append( "BusinessCountry" ); 859 list.append( "BusinessCountry" );
853 list.append( "BusinessPager" ); 860 list.append( "BusinessPager" );
854 list.append( "BusinessWebPage" ); 861 list.append( "BusinessWebPage" );
855 862
856 list.append( "Office" ); 863 list.append( "Office" );
857 list.append( "Profession" ); 864 list.append( "Profession" );
858 list.append( "Assistant" ); 865 list.append( "Assistant" );
859 list.append( "Manager" ); 866 list.append( "Manager" );
860 867
861 list.append( "HomeStreet" ); 868 list.append( "HomeStreet" );
862 list.append( "HomeCity" ); 869 list.append( "HomeCity" );
863 list.append( "HomeState" ); 870 list.append( "HomeState" );
864 list.append( "HomeZip" ); 871 list.append( "HomeZip" );
865 list.append( "HomeCountry" ); 872 list.append( "HomeCountry" );
866 list.append( "HomeWebPage" ); 873 list.append( "HomeWebPage" );
867 874
868 list.append( "Spouse" ); 875 list.append( "Spouse" );
869 list.append( "Gender" ); 876 list.append( "Gender" );
870 list.append( "Birthday" ); 877 list.append( "Birthday" );
871 list.append( "Anniversary" ); 878 list.append( "Anniversary" );
872 list.append( "Nickname" ); 879 list.append( "Nickname" );
873 list.append( "Children" ); 880 list.append( "Children" );
874 881
875 list.append( "Notes" ); 882 list.append( "Notes" );
876 list.append( "Groups" ); 883 list.append( "Groups" );
877 884
878 return list; 885 return list;
879} 886}
880 887
881/*!
882 \internal
883 Returns a translated list of field names for a contact.
884*/
885QStringList OContact::trfields()
886{
887 QStringList list;
888
889 list.append( QObject::tr( "Name Title") );
890 list.append( QObject::tr( "First Name" ) );
891 list.append( QObject::tr( "Middle Name" ) );
892 list.append( QObject::tr( "Last Name" ) );
893 list.append( QObject::tr( "Suffix" ) );
894 list.append( QObject::tr( "File As" ) );
895
896 list.append( QObject::tr( "Job Title" ) );
897 list.append( QObject::tr( "Department" ) );
898 list.append( QObject::tr( "Company" ) );
899 list.append( QObject::tr( "Business Phone" ) );
900 list.append( QObject::tr( "Business Fax" ) );
901 list.append( QObject::tr( "Business Mobile" ) );
902
903 list.append( QObject::tr( "Default Email" ) );
904 list.append( QObject::tr( "Emails" ) );
905
906 list.append( QObject::tr( "Home Phone" ) );
907 list.append( QObject::tr( "Home Fax" ) );
908 list.append( QObject::tr( "Home Mobile" ) );
909
910 list.append( QObject::tr( "Business Street" ) );
911 list.append( QObject::tr( "Business City" ) );
912 list.append( QObject::tr( "Business State" ) );
913 list.append( QObject::tr( "Business Zip" ) );
914 list.append( QObject::tr( "Business Country" ) );
915 list.append( QObject::tr( "Business Pager" ) );
916 list.append( QObject::tr( "Business WebPage" ) );
917
918 list.append( QObject::tr( "Office" ) );
919 list.append( QObject::tr( "Profession" ) );
920 list.append( QObject::tr( "Assistant" ) );
921 list.append( QObject::tr( "Manager" ) );
922
923 list.append( QObject::tr( "Home Street" ) );
924 list.append( QObject::tr( "Home City" ) );
925 list.append( QObject::tr( "Home State" ) );
926 list.append( QObject::tr( "Home Zip" ) );
927 list.append( QObject::tr( "Home Country" ) );
928 list.append( QObject::tr( "Home Web Page" ) );
929
930 list.append( QObject::tr( "Spouse" ) );
931 list.append( QObject::tr( "Gender" ) );
932 list.append( QObject::tr( "Birthday" ) );
933 list.append( QObject::tr( "Anniversary" ) );
934 list.append( QObject::tr( "Nickname" ) );
935 list.append( QObject::tr( "Children" ) );
936
937 list.append( QObject::tr( "Notes" ) );
938 list.append( QObject::tr( "Groups" ) );
939
940 return list;
941}
942
943/*!
944 \internal
945 Returns an untranslated list of field names for a contact.
946*/
947QStringList OContact::untrfields()
948{
949 QStringList list;
950
951 list.append( "Name Title" );
952 list.append( "First Name" );
953 list.append( "Middle Name" );
954 list.append( "Last Name" );
955 list.append( "Suffix" );
956 list.append( "File As" );
957
958 list.append( "Job Title" );
959 list.append( "Department" );
960 list.append( "Company" );
961 list.append( "Business Phone" );
962 list.append( "Business Fax" );
963 list.append( "Business Mobile" );
964
965 list.append( "Default Email" );
966 list.append( "Emails" );
967
968 list.append( "Home Phone" );
969 list.append( "Home Fax" );
970 list.append( "Home Mobile" );
971
972 list.append( "Business Street" );
973 list.append( "Business City" );
974 list.append( "Business State" );
975 list.append( "Business Zip" );
976 list.append( "Business Country" );
977 list.append( "Business Pager" );
978 list.append( "Business WebPage" );
979
980 list.append( "Office" );
981 list.append( "Profession" );
982 list.append( "Assistant" );
983 list.append( "Manager" );
984
985 list.append( "Home Street" );
986 list.append( "Home City" );
987 list.append( "Home State" );
988 list.append( "Home Zip" );
989 list.append( "Home Country" );
990 list.append( "Home Web Page" );
991
992 list.append( "Spouse" );
993 list.append( "Gender" );
994 list.append( "Birthday" );
995 list.append( "Anniversary" );
996 list.append( "Nickname" );
997 list.append( "Children" );
998
999 list.append( "Notes" );
1000 list.append( "Groups" );
1001
1002 return list;
1003}
1004 888
1005/*! 889/*!
1006 Sets the list of email address for contact to those contained in \a str. 890 Sets the list of email address for contact to those contained in \a str.
1007 Email address should be separated by ';'s. 891 Email address should be separated by ';'s.
1008*/ 892*/
1009void OContact::setEmails( const QString &str ) 893void OContact::setEmails( const QString &str )
1010{ 894{
1011 replace( Qtopia::Emails, str ); 895 replace( Qtopia::Emails, str );
1012 if ( str.isEmpty() ) 896 if ( str.isEmpty() )
1013 setDefaultEmail( QString::null ); 897 setDefaultEmail( QString::null );
1014} 898}
1015 899
1016/*! 900/*!
1017 Sets the list of children for the contact to those contained in \a str. 901 Sets the list of children for the contact to those contained in \a str.
1018*/ 902*/
1019void OContact::setChildren( const QString &str ) 903void OContact::setChildren( const QString &str )
1020{ 904{
1021 replace( Qtopia::Children, str ); 905 replace( Qtopia::Children, str );
1022} 906}
1023 907
1024// vcard conversion code
1025/*!
1026 \internal
1027*/
1028static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value )
1029{
1030 VObject *ret = 0;
1031 if ( o && !value.isEmpty() )
1032 ret = addPropValue( o, prop, value.latin1() );
1033 return ret;
1034}
1035
1036/*!
1037 \internal
1038*/
1039static inline VObject *safeAddProp( VObject *o, const char *prop)
1040{
1041 VObject *ret = 0;
1042 if ( o )
1043 ret = addProp( o, prop );
1044 return ret;
1045}
1046
1047/*!
1048 \internal
1049*/
1050static VObject *createVObject( const OContact &c )
1051{
1052 VObject *vcard = newVObject( VCCardProp );
1053 safeAddPropValue( vcard, VCVersionProp, "2.1" );
1054 safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
1055 safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
1056
1057 // full name
1058 safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
1059
1060 // name properties
1061 VObject *name = safeAddProp( vcard, VCNameProp );
1062 safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
1063 safeAddPropValue( name, VCGivenNameProp, c.firstName() );
1064 safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
1065 safeAddPropValue( name, VCNamePrefixesProp, c.title() );
1066 safeAddPropValue( name, VCNameSuffixesProp, c.suffix() );
1067
1068 // home properties
1069 VObject *home_adr= safeAddProp( vcard, VCAdrProp );
1070 safeAddProp( home_adr, VCHomeProp );
1071 safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() );
1072 safeAddPropValue( home_adr, VCCityProp, c.homeCity() );
1073 safeAddPropValue( home_adr, VCRegionProp, c.homeState() );
1074 safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() );
1075 safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() );
1076
1077 VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() );
1078 safeAddProp( home_phone, VCHomeProp );
1079 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() );
1080 safeAddProp( home_phone, VCHomeProp );
1081 safeAddProp( home_phone, VCCellularProp );
1082 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() );
1083 safeAddProp( home_phone, VCHomeProp );
1084 safeAddProp( home_phone, VCFaxProp );
1085
1086 VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() );
1087 safeAddProp( url, VCHomeProp );
1088
1089 // work properties
1090 VObject *work_adr= safeAddProp( vcard, VCAdrProp );
1091 safeAddProp( work_adr, VCWorkProp );
1092 safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() );
1093 safeAddPropValue( work_adr, VCCityProp, c.businessCity() );
1094 safeAddPropValue( work_adr, VCRegionProp, c.businessState() );
1095 safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() );
1096 safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() );
1097
1098 VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() );
1099 safeAddProp( work_phone, VCWorkProp );
1100 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() );
1101 safeAddProp( work_phone, VCWorkProp );
1102 safeAddProp( work_phone, VCCellularProp );
1103 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() );
1104 safeAddProp( work_phone, VCWorkProp );
1105 safeAddProp( work_phone, VCFaxProp );
1106 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() );
1107 safeAddProp( work_phone, VCWorkProp );
1108 safeAddProp( work_phone, VCPagerProp );
1109
1110 url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() );
1111 safeAddProp( url, VCWorkProp );
1112
1113 VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() );
1114 safeAddProp( title, VCWorkProp );
1115
1116
1117 QStringList emails = c.emailList();
1118 emails.prepend( c.defaultEmail() );
1119 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
1120 VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it );
1121 safeAddProp( email, VCInternetProp );
1122 }
1123
1124 safeAddPropValue( vcard, VCNoteProp, c.notes() );
1125
1126 // Exporting Birthday regarding RFC 2425 (5.8.4)
1127 if ( c.birthday().isValid() ){
1128 QString birthd_rfc2425 = QString("%1-%2-%3")
1129 .arg( c.birthday().year() )
1130 .arg( c.birthday().month(), 2 )
1131 .arg( c.birthday().day(), 2 );
1132 // Now replace spaces with "0"...
1133 int pos = 0;
1134 while ( ( pos = birthd_rfc2425.find (' ') ) > 0 )
1135 birthd_rfc2425.replace( pos, 1, "0" );
1136
1137 qWarning("Exporting birthday as: %s", birthd_rfc2425.latin1());
1138 safeAddPropValue( vcard, VCBirthDateProp, birthd_rfc2425.latin1() );
1139 }
1140
1141 if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) {
1142 VObject *org = safeAddProp( vcard, VCOrgProp );
1143 safeAddPropValue( org, VCOrgNameProp, c.company() );
1144 safeAddPropValue( org, VCOrgUnitProp, c.department() );
1145 safeAddPropValue( org, VCOrgUnit2Prop, c.office() );
1146 }
1147
1148 // some values we have to export as custom fields
1149 safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() );
1150 safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() );
1151 safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() );
1152
1153 safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() );
1154 safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() );
1155 // safeAddPropValue( vcard, "X-Qtopia-Anniversary", TimeConversion::toString( c.anniversary() ) ); :SX
1156 safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() );
1157 safeAddPropValue( vcard, "X-Qtopia-Children", c.children() );
1158
1159 return vcard;
1160}
1161
1162
1163/*!
1164 \internal
1165*/
1166static QDate convVCardDateToDate( const QString& datestr )
1167{
1168 int monthPos = datestr.find('-');
1169 int dayPos = datestr.find('-', monthPos+1 );
1170 int sep_ignore = 1;
1171 if ( monthPos == -1 || dayPos == -1 ) {
1172 qDebug("fromString didn't find - in str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
1173 // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD )
1174 if ( datestr.length() == 8 ){
1175 monthPos = 4;
1176 dayPos = 6;
1177 sep_ignore = 0;
1178 qDebug("Try with follwing positions str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
1179 } else {
1180 return QDate();
1181 }
1182 }
1183 int y = datestr.left( monthPos ).toInt();
1184 int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt();
1185 int d = datestr.mid( dayPos + sep_ignore ).toInt();
1186 qDebug("TimeConversion::fromString ymd = %s => %d %d %d; mpos = %d ypos = %d", datestr.latin1(), y, m, d, monthPos, dayPos);
1187 QDate date ( y,m,d );
1188 return date;
1189}
1190
1191static OContact parseVObject( VObject *obj )
1192{
1193 OContact c;
1194
1195 VObjectIterator it;
1196 initPropIterator( &it, obj );
1197 while( moreIteration( &it ) ) {
1198 VObject *o = nextVObject( &it );
1199 QCString name = vObjectName( o );
1200 QCString value = vObjectStringZValue( o );
1201 if ( name == VCNameProp ) {
1202 VObjectIterator nit;
1203 initPropIterator( &nit, o );
1204 while( moreIteration( &nit ) ) {
1205 VObject *o = nextVObject( &nit );
1206 QCString name = vObjectTypeInfo( o );
1207 QString value = vObjectStringZValue( o );
1208 if ( name == VCNamePrefixesProp )
1209 c.setTitle( value );
1210 else if ( name == VCNameSuffixesProp )
1211 c.setSuffix( value );
1212 else if ( name == VCFamilyNameProp )
1213 c.setLastName( value );
1214 else if ( name == VCGivenNameProp )
1215 c.setFirstName( value );
1216 else if ( name == VCAdditionalNamesProp )
1217 c.setMiddleName( value );
1218 }
1219 }
1220 else if ( name == VCAdrProp ) {
1221 bool work = TRUE; // default address is work address
1222 QString street;
1223 QString city;
1224 QString region;
1225 QString postal;
1226 QString country;
1227
1228 VObjectIterator nit;
1229 initPropIterator( &nit, o );
1230 while( moreIteration( &nit ) ) {
1231 VObject *o = nextVObject( &nit );
1232 QCString name = vObjectName( o );
1233 QString value = vObjectStringZValue( o );
1234
1235 if ( name == VCHomeProp )
1236 work = FALSE;
1237 else if ( name == VCWorkProp )
1238 work = TRUE;
1239 else if ( name == VCStreetAddressProp )
1240 street = value;
1241 else if ( name == VCCityProp )
1242 city = value;
1243 else if ( name == VCRegionProp )
1244 region = value;
1245 else if ( name == VCPostalCodeProp )
1246 postal = value;
1247 else if ( name == VCCountryNameProp )
1248 country = value;
1249 }
1250 if ( work ) {
1251 c.setBusinessStreet( street );
1252 c.setBusinessCity( city );
1253 c.setBusinessCountry( country );
1254 c.setBusinessZip( postal );
1255 c.setBusinessState( region );
1256 } else {
1257 c.setHomeStreet( street );
1258 c.setHomeCity( city );
1259 c.setHomeCountry( country );
1260 c.setHomeZip( postal );
1261 c.setHomeState( region );
1262 }
1263 }
1264 else if ( name == VCTelephoneProp ) {
1265 enum {
1266 HOME = 0x01,
1267 WORK = 0x02,
1268 VOICE = 0x04,
1269 CELL = 0x08,
1270 FAX = 0x10,
1271 PAGER = 0x20,
1272 UNKNOWN = 0x80
1273 };
1274 int type = 0;
1275
1276 VObjectIterator nit;
1277 initPropIterator( &nit, o );
1278 while( moreIteration( &nit ) ) {
1279 VObject *o = nextVObject( &nit );
1280 QCString name = vObjectTypeInfo( o );
1281 if ( name == VCHomeProp )
1282 type |= HOME;
1283 else if ( name == VCWorkProp )
1284 type |= WORK;
1285 else if ( name == VCVoiceProp )
1286 type |= VOICE;
1287 else if ( name == VCCellularProp )
1288 type |= CELL;
1289 else if ( name == VCFaxProp )
1290 type |= FAX;
1291 else if ( name == VCPagerProp )
1292 type |= PAGER;
1293 else if ( name == VCPreferredProp )
1294 ;
1295 else
1296 type |= UNKNOWN;
1297 }
1298 if ( (type & UNKNOWN) != UNKNOWN ) {
1299 if ( ( type & (HOME|WORK) ) == 0 ) // default
1300 type |= HOME;
1301 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
1302 type |= VOICE;
1303
1304 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) )
1305 c.setHomePhone( value );
1306 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
1307 c.setHomeFax( value );
1308 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
1309 c.setHomeMobile( value );
1310 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) )
1311 c.setBusinessPhone( value );
1312 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
1313 c.setBusinessFax( value );
1314 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
1315 c.setBusinessMobile( value );
1316 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
1317 c.setBusinessPager( value );
1318 }
1319 }
1320 else if ( name == VCEmailAddressProp ) {
1321 QString email = vObjectStringZValue( o );
1322 bool valid = TRUE;
1323 VObjectIterator nit;
1324 initPropIterator( &nit, o );
1325 while( moreIteration( &nit ) ) {
1326 VObject *o = nextVObject( &nit );
1327 QCString name = vObjectTypeInfo( o );
1328 if ( name != VCInternetProp && name != VCHomeProp &&
1329 name != VCWorkProp &&
1330 name != VCPreferredProp )
1331 // ### preffered should map to default email
1332 valid = FALSE;
1333 }
1334 if ( valid ) {
1335 c.insertEmail( email );
1336 }
1337 }
1338 else if ( name == VCURLProp ) {
1339 VObjectIterator nit;
1340 initPropIterator( &nit, o );
1341 while( moreIteration( &nit ) ) {
1342 VObject *o = nextVObject( &nit );
1343 QCString name = vObjectTypeInfo( o );
1344 if ( name == VCHomeProp )
1345 c.setHomeWebpage( value );
1346 else if ( name == VCWorkProp )
1347 c.setBusinessWebpage( value );
1348 }
1349 }
1350 else if ( name == VCOrgProp ) {
1351 VObjectIterator nit;
1352 initPropIterator( &nit, o );
1353 while( moreIteration( &nit ) ) {
1354 VObject *o = nextVObject( &nit );
1355 QCString name = vObjectName( o );
1356 QString value = vObjectStringZValue( o );
1357 if ( name == VCOrgNameProp )
1358 c.setCompany( value );
1359 else if ( name == VCOrgUnitProp )
1360 c.setDepartment( value );
1361 else if ( name == VCOrgUnit2Prop )
1362 c.setOffice( value );
1363 }
1364 }
1365 else if ( name == VCTitleProp ) {
1366 c.setJobTitle( value );
1367 }
1368 else if ( name == "X-Qtopia-Profession" ) {
1369 c.setProfession( value );
1370 }
1371 else if ( name == "X-Qtopia-Manager" ) {
1372 c.setManager( value );
1373 }
1374 else if ( name == "X-Qtopia-Assistant" ) {
1375 c.setAssistant( value );
1376 }
1377 else if ( name == "X-Qtopia-Spouse" ) {
1378 c.setSpouse( value );
1379 }
1380 else if ( name == "X-Qtopia-Gender" ) {
1381 c.setGender( value );
1382 }
1383 else if ( name == "X-Qtopia-Anniversary" ) {
1384 // c.setAnniversary( TimeConversion::fromString( value ) ); :SX
1385 }
1386 else if ( name == "X-Qtopia-Nickname" ) {
1387 c.setNickname( value );
1388 }
1389 else if ( name == "X-Qtopia-Children" ) {
1390 c.setChildren( value );
1391 }
1392 else if ( name == VCBirthDateProp ) {
1393 // Reading Birthdate regarding RFC 2425 (5.8.4)
1394 c.setBirthday( convVCardDateToDate( value ) );
1395
1396 }
1397
1398#if 0
1399 else {
1400 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
1401 VObjectIterator nit;
1402 initPropIterator( &nit, o );
1403 while( moreIteration( &nit ) ) {
1404 VObject *o = nextVObject( &nit );
1405 QCString name = vObjectName( o );
1406 QString value = vObjectStringZValue( o );
1407 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
1408 }
1409 }
1410#endif
1411 }
1412 c.setFileAs();
1413 return c;
1414}
1415
1416/*!
1417 Writes the list of \a contacts as a set of VCards to the file \a filename.
1418*/
1419void OContact::writeVCard( const QString &filename, const QValueList<OContact> &contacts)
1420{
1421 QFileDirect f( filename.utf8().data() );
1422 if ( !f.open( IO_WriteOnly ) ) {
1423 qWarning("Unable to open vcard write");
1424 return;
1425 }
1426
1427 QValueList<OContact>::ConstIterator it;
1428 for( it = contacts.begin(); it != contacts.end(); ++it ) {
1429 VObject *obj = createVObject( *it );
1430 writeVObject(f.directHandle() , obj );
1431 cleanVObject( obj );
1432 }
1433 cleanStrTbl();
1434}
1435
1436/*!
1437 writes \a contact as a VCard to the file \a filename.
1438*/
1439void OContact::writeVCard( const QString &filename, const OContact &contact)
1440{
1441 QFileDirect f( filename.utf8().data() );
1442 if ( !f.open( IO_WriteOnly ) ) {
1443 qWarning("Unable to open vcard write");
1444 return;
1445 }
1446
1447 VObject *obj = createVObject( contact );
1448 writeVObject( f.directHandle() , obj );
1449 cleanVObject( obj );
1450
1451 cleanStrTbl();
1452}
1453
1454/*!
1455 Returns the set of contacts read as VCards from the file \a filename.
1456*/
1457QValueList<OContact> OContact::readVCard( const QString &filename )
1458{
1459 qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() );
1460 VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() );
1461
1462 qDebug("vobject = %p", obj );
1463
1464 QValueList<OContact> contacts;
1465
1466 while ( obj ) {
1467 OContact con = parseVObject( obj );
1468 /*
1469 * if uid is 0 assign a new one
1470 * this at least happens on
1471 * Nokia6210
1472 */
1473 if ( con.uid() == 0 ){
1474 con.setUid( 1 );
1475 qWarning("assigned new uid %d",con.uid() );
1476 }
1477
1478 contacts.append(con );
1479
1480 VObject *t = obj;
1481 obj = nextVObjectInList(obj);
1482 cleanVObject( t );
1483 }
1484
1485 return contacts;
1486}
1487
1488/*! 908/*!
1489 Returns TRUE if the contact matches the regular expression \a regexp. 909 Returns TRUE if the contact matches the regular expression \a regexp.
1490 Otherwise returns FALSE. 910 Otherwise returns FALSE.
1491*/ 911*/
1492bool OContact::match( const QString &regexp ) const 912bool OContact::match( const QString &regexp ) const
1493{ 913{
1494 return match(QRegExp(regexp)); 914 return match(QRegExp(regexp));
1495} 915}
1496 916
1497/*! 917/*!
1498 \overload 918 \overload
1499 Returns TRUE if the contact matches the regular expression \a regexp. 919 Returns TRUE if the contact matches the regular expression \a regexp.
1500 Otherwise returns FALSE. 920 Otherwise returns FALSE.
1501*/ 921*/
1502bool OContact::match( const QRegExp &r ) const 922bool OContact::match( const QRegExp &r ) const
1503{ 923{
1504 bool match; 924 bool match;
1505 match = false; 925 match = false;
1506 QMap<int, QString>::ConstIterator it; 926 QMap<int, QString>::ConstIterator it;
1507 for ( it = mMap.begin(); it != mMap.end(); ++it ) { 927 for ( it = mMap.begin(); it != mMap.end(); ++it ) {
1508 if ( (*it).find( r ) > -1 ) { 928 if ( (*it).find( r ) > -1 ) {
1509 match = true; 929 match = true;
1510 break; 930 break;
1511 } 931 }
1512 } 932 }
1513 return match; 933 return match;
1514} 934}
1515 935
1516 936
1517QString OContact::toShortText() const 937QString OContact::toShortText() const
1518{ 938{
1519 return ( fullName() ); 939 return ( fullName() );
1520} 940}
1521QString OContact::type() const 941QString OContact::type() const
1522{ 942{
1523 return QString::fromLatin1( "OContact" ); 943 return QString::fromLatin1( "OContact" );
1524} 944}
1525 945
1526// Definition is missing ! (se) 946// Definition is missing ! (se)
1527QMap<QString,QString> OContact::toExtraMap() const 947QMap<QString,QString> OContact::toExtraMap() const
1528{ 948{
1529 qWarning ("Function not implemented: OContact::toExtraMap()"); 949 qWarning ("Function not implemented: OContact::toExtraMap()");
1530 QMap <QString,QString> useless; 950 QMap <QString,QString> useless;
1531 return useless; 951 return useless;
1532} 952}
1533 953
1534class QString OContact::recordField( int pos ) const 954class QString OContact::recordField( int pos ) const
1535{ 955{
1536 QStringList SLFIELDS = fields(); // ?? why this ? (se) 956 QStringList SLFIELDS = fields(); // ?? why this ? (se)
1537 return SLFIELDS[pos]; 957 return SLFIELDS[pos];
1538} 958}
1539 959
1540// In future releases, we should store birthday and anniversary 960// In future releases, we should store birthday and anniversary
1541// internally as QDate instead of QString ! 961// internally as QDate instead of QString !
1542// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) 962// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se)
1543 963
1544/*! \fn void OContact::setBirthday( const QDate& date ) 964/*! \fn void OContact::setBirthday( const QDate& date )
1545 Sets the birthday for the contact to \a date. 965 Sets the birthday for the contact to \a date. If date is null
966 the current stored date will be removed.
1546*/ 967*/
1547void OContact::setBirthday( const QDate &v ) 968void OContact::setBirthday( const QDate &v )
1548{ 969{
1549 if ( ( !v.isNull() ) && ( v.isValid() ) ) 970 if ( v.isNull() ){
971 qWarning( "Remove Birthday");
972 replace( Qtopia::Birthday, QString::null );
973 return;
974 }
975
976 if ( v.isValid() )
1550 replace( Qtopia::Birthday, TimeConversion::toString( v ) ); 977 replace( Qtopia::Birthday, TimeConversion::toString( v ) );
1551 978
1552} 979}
1553 980
1554 981
1555/*! \fn void OContact::setAnniversary( const QDate &date ) 982/*! \fn void OContact::setAnniversary( const QDate &date )
1556 Sets the anniversary of the contact to \a date. 983 Sets the anniversary of the contact to \a date. If date is
984 null, the current stored date will be removed.
1557*/ 985*/
1558void OContact::setAnniversary( const QDate &v ) 986void OContact::setAnniversary( const QDate &v )
1559{ 987{
1560 if ( ( !v.isNull() ) && ( v.isValid() ) ) 988 if ( v.isNull() ){
989 qWarning( "Remove Anniversary");
990 replace( Qtopia::Anniversary, QString::null );
991 return;
992 }
993
994 if ( v.isValid() )
1561 replace( Qtopia::Anniversary, TimeConversion::toString( v ) ); 995 replace( Qtopia::Anniversary, TimeConversion::toString( v ) );
1562} 996}
1563 997
1564/*! \fn QDate OContact::birthday() const 998/*! \fn QDate OContact::birthday() const
1565 Returns the birthday of the contact. 999 Returns the birthday of the contact.
1566*/ 1000*/
1567QDate OContact::birthday() const 1001QDate OContact::birthday() const
1568{ 1002{
1569 QString str = find( Qtopia::Birthday ); 1003 QString str = find( Qtopia::Birthday );
1570 qWarning ("Birthday %s", str.latin1() ); 1004 qWarning ("Birthday %s", str.latin1() );
1571 if ( !str.isEmpty() ) 1005 if ( !str.isEmpty() )
1572 return TimeConversion::fromString ( str ); 1006 return TimeConversion::fromString ( str );
1573 else 1007 else
1574 return QDate(); 1008 return QDate();
1575} 1009}
1576 1010
1577 1011
1578/*! \fn QDate OContact::anniversary() const 1012/*! \fn QDate OContact::anniversary() const
1579 Returns the anniversary of the contact. 1013 Returns the anniversary of the contact.
1580*/ 1014*/
1581QDate OContact::anniversary() const 1015QDate OContact::anniversary() const
1582{ 1016{
1583 QDate empty; 1017 QDate empty;
1584 QString str = find( Qtopia::Anniversary ); 1018 QString str = find( Qtopia::Anniversary );
1585 qWarning ("Anniversary %s", str.latin1() ); 1019 qWarning ("Anniversary %s", str.latin1() );
1586 if ( !str.isEmpty() ) 1020 if ( !str.isEmpty() )
1587 return TimeConversion::fromString ( str ); 1021 return TimeConversion::fromString ( str );
1588 else 1022 else
1589 return empty; 1023 return empty;
1590} 1024}
1591 1025
1592 1026
@@ -1633,32 +1067,37 @@ void OContact::removeEmail( const QString &v )
1633 // if default, then replace the default email with the first one 1067 // if default, then replace the default email with the first one
1634 if ( def == e ) { 1068 if ( def == e ) {
1635 //qDebug("removeEmail is default; setting new default"); 1069 //qDebug("removeEmail is default; setting new default");
1636 if ( !emails.count() ) 1070 if ( !emails.count() )
1637 clearEmails(); 1071 clearEmails();
1638 else // setDefaultEmail will remove e from the list 1072 else // setDefaultEmail will remove e from the list
1639 setDefaultEmail( emails.first() ); 1073 setDefaultEmail( emails.first() );
1640 } 1074 }
1641} 1075}
1642void OContact::clearEmails() 1076void OContact::clearEmails()
1643{ 1077{
1644 mMap.remove( Qtopia::DefaultEmail ); 1078 mMap.remove( Qtopia::DefaultEmail );
1645 mMap.remove( Qtopia::Emails ); 1079 mMap.remove( Qtopia::Emails );
1646} 1080}
1647void OContact::setDefaultEmail( const QString &v ) 1081void OContact::setDefaultEmail( const QString &v )
1648{ 1082{
1649 QString e = v.simplifyWhiteSpace(); 1083 QString e = v.simplifyWhiteSpace();
1650 1084
1651 //qDebug("OContact::setDefaultEmail %s", e.latin1()); 1085 //qDebug("OContact::setDefaultEmail %s", e.latin1());
1652 replace( Qtopia::DefaultEmail, e ); 1086 replace( Qtopia::DefaultEmail, e );
1653 1087
1654 if ( !e.isEmpty() ) 1088 if ( !e.isEmpty() )
1655 insertEmail( e ); 1089 insertEmail( e );
1656 1090
1657} 1091}
1658 1092
1659void OContact::insertEmails( const QStringList &v ) 1093void OContact::insertEmails( const QStringList &v )
1660{ 1094{
1661 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) 1095 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it )
1662 insertEmail( *it ); 1096 insertEmail( *it );
1663} 1097}
1664 1098
1099void OContact::setUid( int i )
1100{
1101 OPimRecord::setUid(i);
1102 replace( Qtopia::AddressUid , QString::number(i));
1103}
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h
index 9643e8b..d97af1c 100644
--- a/libopie/pim/ocontact.h
+++ b/libopie/pim/ocontact.h
@@ -5,87 +5,74 @@
5** This file is part of the Qtopia Environment. 5** This file is part of the Qtopia Environment.
6** 6**
7** This file may be distributed and/or modified under the terms of the 7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software 8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the 9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file. 10** packaging of this file.
11** 11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16** 16**
17** Contact info@trolltech.com if any conditions of this licensing are 17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you. 18** not clear to you.
19** 19**
20**********************************************************************/ 20**********************************************************************/
21 21
22#ifndef __OCONTACT_H__ 22#ifndef __OCONTACT_H__
23#define __OCONTACT_H__ 23#define __OCONTACT_H__
24 24
25#include <opie/opimrecord.h> 25#include <opie/opimrecord.h>
26#include <qpe/recordfields.h> 26#include <qpe/recordfields.h>
27 27
28#include <qdatetime.h> 28#include <qdatetime.h>
29#include <qstringlist.h> 29#include <qstringlist.h>
30 30
31#if defined(QPC_TEMPLATEDLL) 31#if defined(QPC_TEMPLATEDLL)
32// MOC_SKIP_BEGIN 32// MOC_SKIP_BEGIN
33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; 33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
34// MOC_SKIP_END 34// MOC_SKIP_END
35#endif 35#endif
36 36
37class ContactPrivate; // Wozu ist das gut und wo ist das decrariert ? (se) 37class ContactPrivate;
38 /* Stefan das ist eine forward declaration 38
39 * dann machst du in der private section
40 * ContactPrivate *d;
41 *
42 * und wenn du bei Opie1.1 was hinzufuegen moechtest
43 * packst du es in ContactPrivate damit Opie
44 * binaer kompatibel bleibt
45 * -zecke
46 */
47class QPC_EXPORT OContact : public OPimRecord 39class QPC_EXPORT OContact : public OPimRecord
48{ 40{
49 friend class DataSet; 41 friend class DataSet;
50public: 42public:
51 OContact(); 43 OContact();
52 OContact( const QMap<int, QString> &fromMap ); 44 OContact( const QMap<int, QString> &fromMap );
53 virtual ~OContact(); 45 virtual ~OContact();
54 46
55 /* VCARD stuff should vanish! -zecke */
56 static void writeVCard( const QString &filename, const QValueList<OContact> &contacts);
57 static void writeVCard( const QString &filename, const OContact &c );
58 static QValueList<OContact> readVCard( const QString &filename );
59
60 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 47 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
61 48
62 /* 49 /*
63 * do we need to inline them 50 * do we need to inline them
64 * if yes do we need to inline them this way? 51 * if yes do we need to inline them this way?
65 * -zecke 52 * -zecke
66 */ 53 */
67 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } 54 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
68 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } 55 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
69 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } 56 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
70 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } 57 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
71 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } 58 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
72 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } 59 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
73 void setFileAs(); 60 void setFileAs();
74 61
75 // default email address 62 // default email address
76 void setDefaultEmail( const QString &v ); 63 void setDefaultEmail( const QString &v );
77 // inserts email to list and ensure's doesn't already exist 64 // inserts email to list and ensure's doesn't already exist
78 void insertEmail( const QString &v ); 65 void insertEmail( const QString &v );
79 void removeEmail( const QString &v ); 66 void removeEmail( const QString &v );
80 void clearEmails(); 67 void clearEmails();
81 void insertEmails( const QStringList &v ); 68 void insertEmails( const QStringList &v );
82 69
83 // home 70 // home
84 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } 71 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
85 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } 72 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }
86 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } 73 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); }
87 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } 74 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); }
88 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } 75 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); }
89 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } 76 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); }
90 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } 77 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); }
91 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } 78 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); }
@@ -177,88 +164,75 @@ public:
177 QString businessPhone() const { return find( Qtopia::BusinessPhone ); } 164 QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
178 QString businessFax() const { return find( Qtopia::BusinessFax ); } 165 QString businessFax() const { return find( Qtopia::BusinessFax ); }
179 QString businessMobile() const { return find( Qtopia::BusinessMobile ); } 166 QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
180 QString businessPager() const { return find( Qtopia::BusinessPager ); } 167 QString businessPager() const { return find( Qtopia::BusinessPager ); }
181 QString profession() const { return find( Qtopia::Profession ); } 168 QString profession() const { return find( Qtopia::Profession ); }
182 QString assistant() const { return find( Qtopia::Assistant ); } 169 QString assistant() const { return find( Qtopia::Assistant ); }
183 QString manager() const { return find( Qtopia::Manager ); } 170 QString manager() const { return find( Qtopia::Manager ); }
184 /** Multi line string containing all non-empty address info in the form 171 /** Multi line string containing all non-empty address info in the form
185 * Street 172 * Street
186 * City, State Zip 173 * City, State Zip
187 * Country 174 * Country
188 */ 175 */
189 QString displayBusinessAddress() const; 176 QString displayBusinessAddress() const;
190 177
191 //personal 178 //personal
192 QString spouse() const { return find( Qtopia::Spouse ); } 179 QString spouse() const { return find( Qtopia::Spouse ); }
193 QString gender() const { return find( Qtopia::Gender ); } 180 QString gender() const { return find( Qtopia::Gender ); }
194 QDate birthday() const; 181 QDate birthday() const;
195 QDate anniversary() const; 182 QDate anniversary() const;
196 QString nickname() const { return find( Qtopia::Nickname ); } 183 QString nickname() const { return find( Qtopia::Nickname ); }
197 QString children() const { return find( Qtopia::Children ); } 184 QString children() const { return find( Qtopia::Children ); }
198 QStringList childrenList() const; 185 QStringList childrenList() const;
199 186
200 // other 187 // other
201 QString notes() const { return find( Qtopia::Notes ); } 188 QString notes() const { return find( Qtopia::Notes ); }
202 QString groups() const { return find( Qtopia::Groups ); } 189 QString groups() const { return find( Qtopia::Groups ); }
203 QStringList groupList() const; 190 QStringList groupList() const;
204 191
205// // custom 192// // custom
206// const QString &customField( const QString &key ) 193// const QString &customField( const QString &key )
207// { return find( Custom- + key ); } 194// { return find( Custom- + key ); }
208 195
209 static QStringList fields();
210 static QStringList trfields();
211 static QStringList untrfields();
212 196
213 QString toRichText() const; 197 QString toRichText() const;
214 QMap<int, QString> toMap() const; 198 QMap<int, QString> toMap() const;
215 QString field( int key ) const { return find( key ); } 199 QString field( int key ) const { return find( key ); }
216 200
217 201
218 // journaling... 202 void setUid( int i );
219 /* do we still need them? Stefan your backend takes care of these -zecke */
220 void saveJournal( journal_action action, const QString &key = QString::null );
221 void save( QString &buf ) const;
222
223 /* we shouldn't inline this one -zecke */
224 void setUid( int i )
225{ OPimRecord::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); }
226 203
227 QString toShortText()const; 204 QString toShortText()const;
228 QString OContact::type()const; 205 QString OContact::type()const;
229 QMap<QString,QString> OContact::toExtraMap() const; 206 QMap<QString,QString> OContact::toExtraMap() const;
230 class QString OContact::recordField(int) const; 207 class QString OContact::recordField(int) const;
231 208
232 // Why private ? (eilers,se) 209 // Why private ? (eilers,se)
233 QString emailSeparator() const { return " "; } 210 QString emailSeparator() const { return " "; }
234 // the emails should be seperated by a comma 211 // the emails should be seperated by a comma
235 void setEmails( const QString &v ); 212 void setEmails( const QString &v );
236 QString emails() const { return find( Qtopia::Emails ); } 213 QString emails() const { return find( Qtopia::Emails ); }
237 214
238 215
239private: 216private:
240 /* I do not like friends ;) 217 // The XML-Backend needs some access to the private functions
241 * besides that I think we do not need them 218 friend class OContactAccessBackend_XML;
242 * anymore -zecke
243 */
244 friend class AbEditor;
245 friend class AbTable;
246 friend class AddressBookAccessPrivate;
247 friend class XMLIO;
248 219
249 void insert( int key, const QString &value ); 220 void insert( int key, const QString &value );
250 void replace( int key, const QString &value ); 221 void replace( int key, const QString &value );
251 QString find( int key ) const; 222 QString find( int key ) const;
223 static QStringList fields();
224
225 void save( QString &buf ) const;
252 226
253 QString displayAddress( const QString &street, 227 QString displayAddress( const QString &street,
254 const QString &city, 228 const QString &city,
255 const QString &state, 229 const QString &state,
256 const QString &zip, 230 const QString &zip,
257 const QString &country ) const; 231 const QString &country ) const;
258 232
259 QMap<int, QString> mMap; 233 QMap<int, QString> mMap;
260 ContactPrivate *d; 234 ContactPrivate *d;
261}; 235};
262 236
263 237
264#endif 238#endif
diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp
index b0f0d7f..917eb0a 100644
--- a/libopie2/opiepim/ocontact.cpp
+++ b/libopie2/opiepim/ocontact.cpp
@@ -1,58 +1,56 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** Copyright (C) 2002 by Stefan Eilers (eilers.stefan@epost.de) 3** Copyright (C) 2002 by Stefan Eilers (eilers.stefan@epost.de)
4** 4**
5** This file is part of the Qtopia Environment. 5** This file is part of the Qtopia Environment.
6** 6**
7** This file may be distributed and/or modified under the terms of the 7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software 8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the 9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file. 10** packaging of this file.
11** 11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16** 16**
17** Contact info@trolltech.com if any conditions of this licensing are 17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you. 18** not clear to you.
19** 19**
20**********************************************************************/ 20**********************************************************************/
21 21
22#define QTOPIA_INTERNAL_CONTACT_MRE 22#define QTOPIA_INTERNAL_CONTACT_MRE
23 23
24#include "ocontact.h" 24#include "ocontact.h"
25#include "../../library/backend/vobject_p.h"
26#include "../../library/backend/qfiledirect_p.h"
27 25
28#include <qpe/stringutil.h> 26#include <qpe/stringutil.h>
29#include <qpe/timeconversion.h> 27#include <qpe/timeconversion.h>
30#include <qpe/timestring.h> 28#include <qpe/timestring.h>
31 29
32#include <qobject.h> 30#include <qobject.h>
33#include <qregexp.h> 31#include <qregexp.h>
34#include <qstylesheet.h> 32#include <qstylesheet.h>
35#include <qfileinfo.h> 33#include <qfileinfo.h>
36#include <qmap.h> 34#include <qmap.h>
37 35
38#include <stdio.h> 36#include <stdio.h>
39 37
40/*! 38/*!
41 \class Contact contact.h 39 \class Contact contact.h
42 \brief The Contact class holds the data of an address book entry. 40 \brief The Contact class holds the data of an address book entry.
43 41
44 This data includes information the name of the person, contact 42 This data includes information the name of the person, contact
45 information, and business information such as deparment and job title. 43 information, and business information such as deparment and job title.
46 44
47 \ingroup qtopiaemb 45 \ingroup qtopiaemb
48 \ingroup qtopiadesktop 46 \ingroup qtopiadesktop
49*/ 47*/
50 48
51 49
52/*! 50/*!
53 Creates a new, empty contact. 51 Creates a new, empty contact.
54*/ 52*/
55OContact::OContact() 53OContact::OContact()
56 : OPimRecord(), mMap(), d( 0 ) 54 : OPimRecord(), mMap(), d( 0 )
57{ 55{
58} 56}
@@ -558,64 +556,70 @@ QString OContact::toRichText() const
558 + Qtopia::escapeString(str) + "<br>"; 556 + Qtopia::escapeString(str) + "<br>";
559 str = manager(); 557 str = manager();
560 if ( !str.isEmpty() ) 558 if ( !str.isEmpty() )
561 text += "<b>" + QObject::tr("Manager: ") + "</b>" 559 text += "<b>" + QObject::tr("Manager: ") + "</b>"
562 + Qtopia::escapeString(str) + "<br>"; 560 + Qtopia::escapeString(str) + "<br>";
563 str = gender(); 561 str = gender();
564 if ( !str.isEmpty() && str.toInt() != 0 ) { 562 if ( !str.isEmpty() && str.toInt() != 0 ) {
565 if ( str.toInt() == 1 ) 563 if ( str.toInt() == 1 )
566 str = QObject::tr( "Male" ); 564 str = QObject::tr( "Male" );
567 else if ( str.toInt() == 2 ) 565 else if ( str.toInt() == 2 )
568 str = QObject::tr( "Female" ); 566 str = QObject::tr( "Female" );
569 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; 567 text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>";
570 } 568 }
571 str = spouse(); 569 str = spouse();
572 if ( !str.isEmpty() ) 570 if ( !str.isEmpty() )
573 text += "<b>" + QObject::tr("Spouse: ") + "</b>" 571 text += "<b>" + QObject::tr("Spouse: ") + "</b>"
574 + Qtopia::escapeString(str) + "<br>"; 572 + Qtopia::escapeString(str) + "<br>";
575 if ( birthday().isValid() ){ 573 if ( birthday().isValid() ){
576 str = TimeString::numberDateString( birthday() ); 574 str = TimeString::numberDateString( birthday() );
577 text += "<b>" + QObject::tr("Birthday: ") + "</b>" 575 text += "<b>" + QObject::tr("Birthday: ") + "</b>"
578 + Qtopia::escapeString(str) + "<br>"; 576 + Qtopia::escapeString(str) + "<br>";
579 } 577 }
580 if ( anniversary().isValid() ){ 578 if ( anniversary().isValid() ){
581 str = TimeString::numberDateString( anniversary() ); 579 str = TimeString::numberDateString( anniversary() );
582 text += "<b>" + QObject::tr("Anniversary: ") + "</b>" 580 text += "<b>" + QObject::tr("Anniversary: ") + "</b>"
583 + Qtopia::escapeString(str) + "<br>"; 581 + Qtopia::escapeString(str) + "<br>";
584 } 582 }
585 str = nickname(); 583 str = nickname();
586 if ( !str.isEmpty() ) 584 if ( !str.isEmpty() )
587 text += "<b>" + QObject::tr("Nickname: ") + "</b>" 585 text += "<b>" + QObject::tr("Nickname: ") + "</b>"
588 + Qtopia::escapeString(str) + "<br>"; 586 + Qtopia::escapeString(str) + "<br>";
589 587
588 if ( categoryNames().count() ){
589 text += "<b>" + QObject::tr( "Category:") + "</b> ";
590 text += categoryNames().join(", ");
591 text += "<br>";
592 }
593
590 // notes last 594 // notes last
591 if ( (value = notes()) ) { 595 if ( (value = notes()) ) {
592 QRegExp reg("\n"); 596 QRegExp reg("\n");
593 597
594 //QString tmp = Qtopia::escapeString(value); 598 //QString tmp = Qtopia::escapeString(value);
595 QString tmp = QStyleSheet::convertFromPlainText(value); 599 QString tmp = QStyleSheet::convertFromPlainText(value);
596 //tmp.replace( reg, "<br>" ); 600 //tmp.replace( reg, "<br>" );
597 text += "<br>" + tmp + "<br>"; 601 text += "<br>" + tmp + "<br>";
598 } 602 }
599 return text; 603 return text;
600} 604}
601 605
602/*! 606/*!
603 \internal 607 \internal
604*/ 608*/
605void OContact::insert( int key, const QString &v ) 609void OContact::insert( int key, const QString &v )
606{ 610{
607 QString value = v.stripWhiteSpace(); 611 QString value = v.stripWhiteSpace();
608 if ( value.isEmpty() ) 612 if ( value.isEmpty() )
609 mMap.remove( key ); 613 mMap.remove( key );
610 else 614 else
611 mMap.insert( key, value ); 615 mMap.insert( key, value );
612} 616}
613 617
614/*! 618/*!
615 \internal 619 \internal
616*/ 620*/
617void OContact::replace( int key, const QString & v ) 621void OContact::replace( int key, const QString & v )
618{ 622{
619 QString value = v.stripWhiteSpace(); 623 QString value = v.stripWhiteSpace();
620 if ( value.isEmpty() ) 624 if ( value.isEmpty() )
621 mMap.remove( key ); 625 mMap.remove( key );
@@ -787,806 +791,236 @@ void OContact::setFileAs()
787 791
788 replace( Qtopia::FileAs, fileas ); 792 replace( Qtopia::FileAs, fileas );
789} 793}
790 794
791/*! 795/*!
792 \internal 796 \internal
793 Appends the contact information to \a buf. 797 Appends the contact information to \a buf.
794*/ 798*/
795void OContact::save( QString &buf ) const 799void OContact::save( QString &buf ) const
796{ 800{
797 static const QStringList SLFIELDS = fields(); 801 static const QStringList SLFIELDS = fields();
798 // I'm expecting "<Contact " in front of this... 802 // I'm expecting "<Contact " in front of this...
799 for ( QMap<int, QString>::ConstIterator it = mMap.begin(); 803 for ( QMap<int, QString>::ConstIterator it = mMap.begin();
800 it != mMap.end(); ++it ) { 804 it != mMap.end(); ++it ) {
801 const QString &value = it.data(); 805 const QString &value = it.data();
802 int key = it.key(); 806 int key = it.key();
803 if ( !value.isEmpty() ) { 807 if ( !value.isEmpty() ) {
804 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) 808 if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid)
805 continue; 809 continue;
806 810
807 key -= Qtopia::AddressCategory+1; 811 key -= Qtopia::AddressCategory+1;
808 buf += SLFIELDS[key]; 812 buf += SLFIELDS[key];
809 buf += "=\"" + Qtopia::escapeString(value) + "\" "; 813 buf += "=\"" + Qtopia::escapeString(value) + "\" ";
810 } 814 }
811 } 815 }
812 buf += customToXml(); 816 buf += customToXml();
813 if ( categories().count() > 0 ) 817 if ( categories().count() > 0 )
814 buf += "Categories=\"" + idsToString( categories() ) + "\" "; 818 buf += "Categories=\"" + idsToString( categories() ) + "\" ";
815 buf += "Uid=\"" + QString::number( uid() ) + "\" "; 819 buf += "Uid=\"" + QString::number( uid() ) + "\" ";
816 // You need to close this yourself 820 // You need to close this yourself
817} 821}
818 822
823
819/*! 824/*!
820 \internal 825 \internal
821 Returns the list of fields belonging to a contact 826 Returns the list of fields belonging to a contact
827 Never change order of this list ! It has to be regarding
828 enum AddressBookFields !!
822*/ 829*/
823QStringList OContact::fields() 830QStringList OContact::fields()
824{ 831{
825 QStringList list; 832 QStringList list;
826 833
827 list.append( "Title" ); // Not Used! 834 list.append( "Title" ); // Not Used!
828 list.append( "FirstName" ); 835 list.append( "FirstName" );
829 list.append( "MiddleName" ); 836 list.append( "MiddleName" );
830 list.append( "LastName" ); 837 list.append( "LastName" );
831 list.append( "Suffix" ); 838 list.append( "Suffix" );
832 list.append( "FileAs" ); 839 list.append( "FileAs" );
833 840
834 list.append( "JobTitle" ); 841 list.append( "JobTitle" );
835 list.append( "Department" ); 842 list.append( "Department" );
836 list.append( "Company" ); 843 list.append( "Company" );
837 list.append( "BusinessPhone" ); 844 list.append( "BusinessPhone" );
838 list.append( "BusinessFax" ); 845 list.append( "BusinessFax" );
839 list.append( "BusinessMobile" ); 846 list.append( "BusinessMobile" );
840 847
841 list.append( "DefaultEmail" ); 848 list.append( "DefaultEmail" );
842 list.append( "Emails" ); 849 list.append( "Emails" );
843 850
844 list.append( "HomePhone" ); 851 list.append( "HomePhone" );
845 list.append( "HomeFax" ); 852 list.append( "HomeFax" );
846 list.append( "HomeMobile" ); 853 list.append( "HomeMobile" );
847 854
848 list.append( "BusinessStreet" ); 855 list.append( "BusinessStreet" );
849 list.append( "BusinessCity" ); 856 list.append( "BusinessCity" );
850 list.append( "BusinessState" ); 857 list.append( "BusinessState" );
851 list.append( "BusinessZip" ); 858 list.append( "BusinessZip" );
852 list.append( "BusinessCountry" ); 859 list.append( "BusinessCountry" );
853 list.append( "BusinessPager" ); 860 list.append( "BusinessPager" );
854 list.append( "BusinessWebPage" ); 861 list.append( "BusinessWebPage" );
855 862
856 list.append( "Office" ); 863 list.append( "Office" );
857 list.append( "Profession" ); 864 list.append( "Profession" );
858 list.append( "Assistant" ); 865 list.append( "Assistant" );
859 list.append( "Manager" ); 866 list.append( "Manager" );
860 867
861 list.append( "HomeStreet" ); 868 list.append( "HomeStreet" );
862 list.append( "HomeCity" ); 869 list.append( "HomeCity" );
863 list.append( "HomeState" ); 870 list.append( "HomeState" );
864 list.append( "HomeZip" ); 871 list.append( "HomeZip" );
865 list.append( "HomeCountry" ); 872 list.append( "HomeCountry" );
866 list.append( "HomeWebPage" ); 873 list.append( "HomeWebPage" );
867 874
868 list.append( "Spouse" ); 875 list.append( "Spouse" );
869 list.append( "Gender" ); 876 list.append( "Gender" );
870 list.append( "Birthday" ); 877 list.append( "Birthday" );
871 list.append( "Anniversary" ); 878 list.append( "Anniversary" );
872 list.append( "Nickname" ); 879 list.append( "Nickname" );
873 list.append( "Children" ); 880 list.append( "Children" );
874 881
875 list.append( "Notes" ); 882 list.append( "Notes" );
876 list.append( "Groups" ); 883 list.append( "Groups" );
877 884
878 return list; 885 return list;
879} 886}
880 887
881/*!
882 \internal
883 Returns a translated list of field names for a contact.
884*/
885QStringList OContact::trfields()
886{
887 QStringList list;
888
889 list.append( QObject::tr( "Name Title") );
890 list.append( QObject::tr( "First Name" ) );
891 list.append( QObject::tr( "Middle Name" ) );
892 list.append( QObject::tr( "Last Name" ) );
893 list.append( QObject::tr( "Suffix" ) );
894 list.append( QObject::tr( "File As" ) );
895
896 list.append( QObject::tr( "Job Title" ) );
897 list.append( QObject::tr( "Department" ) );
898 list.append( QObject::tr( "Company" ) );
899 list.append( QObject::tr( "Business Phone" ) );
900 list.append( QObject::tr( "Business Fax" ) );
901 list.append( QObject::tr( "Business Mobile" ) );
902
903 list.append( QObject::tr( "Default Email" ) );
904 list.append( QObject::tr( "Emails" ) );
905
906 list.append( QObject::tr( "Home Phone" ) );
907 list.append( QObject::tr( "Home Fax" ) );
908 list.append( QObject::tr( "Home Mobile" ) );
909
910 list.append( QObject::tr( "Business Street" ) );
911 list.append( QObject::tr( "Business City" ) );
912 list.append( QObject::tr( "Business State" ) );
913 list.append( QObject::tr( "Business Zip" ) );
914 list.append( QObject::tr( "Business Country" ) );
915 list.append( QObject::tr( "Business Pager" ) );
916 list.append( QObject::tr( "Business WebPage" ) );
917
918 list.append( QObject::tr( "Office" ) );
919 list.append( QObject::tr( "Profession" ) );
920 list.append( QObject::tr( "Assistant" ) );
921 list.append( QObject::tr( "Manager" ) );
922
923 list.append( QObject::tr( "Home Street" ) );
924 list.append( QObject::tr( "Home City" ) );
925 list.append( QObject::tr( "Home State" ) );
926 list.append( QObject::tr( "Home Zip" ) );
927 list.append( QObject::tr( "Home Country" ) );
928 list.append( QObject::tr( "Home Web Page" ) );
929
930 list.append( QObject::tr( "Spouse" ) );
931 list.append( QObject::tr( "Gender" ) );
932 list.append( QObject::tr( "Birthday" ) );
933 list.append( QObject::tr( "Anniversary" ) );
934 list.append( QObject::tr( "Nickname" ) );
935 list.append( QObject::tr( "Children" ) );
936
937 list.append( QObject::tr( "Notes" ) );
938 list.append( QObject::tr( "Groups" ) );
939
940 return list;
941}
942
943/*!
944 \internal
945 Returns an untranslated list of field names for a contact.
946*/
947QStringList OContact::untrfields()
948{
949 QStringList list;
950
951 list.append( "Name Title" );
952 list.append( "First Name" );
953 list.append( "Middle Name" );
954 list.append( "Last Name" );
955 list.append( "Suffix" );
956 list.append( "File As" );
957
958 list.append( "Job Title" );
959 list.append( "Department" );
960 list.append( "Company" );
961 list.append( "Business Phone" );
962 list.append( "Business Fax" );
963 list.append( "Business Mobile" );
964
965 list.append( "Default Email" );
966 list.append( "Emails" );
967
968 list.append( "Home Phone" );
969 list.append( "Home Fax" );
970 list.append( "Home Mobile" );
971
972 list.append( "Business Street" );
973 list.append( "Business City" );
974 list.append( "Business State" );
975 list.append( "Business Zip" );
976 list.append( "Business Country" );
977 list.append( "Business Pager" );
978 list.append( "Business WebPage" );
979
980 list.append( "Office" );
981 list.append( "Profession" );
982 list.append( "Assistant" );
983 list.append( "Manager" );
984
985 list.append( "Home Street" );
986 list.append( "Home City" );
987 list.append( "Home State" );
988 list.append( "Home Zip" );
989 list.append( "Home Country" );
990 list.append( "Home Web Page" );
991
992 list.append( "Spouse" );
993 list.append( "Gender" );
994 list.append( "Birthday" );
995 list.append( "Anniversary" );
996 list.append( "Nickname" );
997 list.append( "Children" );
998
999 list.append( "Notes" );
1000 list.append( "Groups" );
1001
1002 return list;
1003}
1004 888
1005/*! 889/*!
1006 Sets the list of email address for contact to those contained in \a str. 890 Sets the list of email address for contact to those contained in \a str.
1007 Email address should be separated by ';'s. 891 Email address should be separated by ';'s.
1008*/ 892*/
1009void OContact::setEmails( const QString &str ) 893void OContact::setEmails( const QString &str )
1010{ 894{
1011 replace( Qtopia::Emails, str ); 895 replace( Qtopia::Emails, str );
1012 if ( str.isEmpty() ) 896 if ( str.isEmpty() )
1013 setDefaultEmail( QString::null ); 897 setDefaultEmail( QString::null );
1014} 898}
1015 899
1016/*! 900/*!
1017 Sets the list of children for the contact to those contained in \a str. 901 Sets the list of children for the contact to those contained in \a str.
1018*/ 902*/
1019void OContact::setChildren( const QString &str ) 903void OContact::setChildren( const QString &str )
1020{ 904{
1021 replace( Qtopia::Children, str ); 905 replace( Qtopia::Children, str );
1022} 906}
1023 907
1024// vcard conversion code
1025/*!
1026 \internal
1027*/
1028static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value )
1029{
1030 VObject *ret = 0;
1031 if ( o && !value.isEmpty() )
1032 ret = addPropValue( o, prop, value.latin1() );
1033 return ret;
1034}
1035
1036/*!
1037 \internal
1038*/
1039static inline VObject *safeAddProp( VObject *o, const char *prop)
1040{
1041 VObject *ret = 0;
1042 if ( o )
1043 ret = addProp( o, prop );
1044 return ret;
1045}
1046
1047/*!
1048 \internal
1049*/
1050static VObject *createVObject( const OContact &c )
1051{
1052 VObject *vcard = newVObject( VCCardProp );
1053 safeAddPropValue( vcard, VCVersionProp, "2.1" );
1054 safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) );
1055 safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) );
1056
1057 // full name
1058 safeAddPropValue( vcard, VCFullNameProp, c.fullName() );
1059
1060 // name properties
1061 VObject *name = safeAddProp( vcard, VCNameProp );
1062 safeAddPropValue( name, VCFamilyNameProp, c.lastName() );
1063 safeAddPropValue( name, VCGivenNameProp, c.firstName() );
1064 safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() );
1065 safeAddPropValue( name, VCNamePrefixesProp, c.title() );
1066 safeAddPropValue( name, VCNameSuffixesProp, c.suffix() );
1067
1068 // home properties
1069 VObject *home_adr= safeAddProp( vcard, VCAdrProp );
1070 safeAddProp( home_adr, VCHomeProp );
1071 safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() );
1072 safeAddPropValue( home_adr, VCCityProp, c.homeCity() );
1073 safeAddPropValue( home_adr, VCRegionProp, c.homeState() );
1074 safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() );
1075 safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() );
1076
1077 VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() );
1078 safeAddProp( home_phone, VCHomeProp );
1079 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() );
1080 safeAddProp( home_phone, VCHomeProp );
1081 safeAddProp( home_phone, VCCellularProp );
1082 home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() );
1083 safeAddProp( home_phone, VCHomeProp );
1084 safeAddProp( home_phone, VCFaxProp );
1085
1086 VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() );
1087 safeAddProp( url, VCHomeProp );
1088
1089 // work properties
1090 VObject *work_adr= safeAddProp( vcard, VCAdrProp );
1091 safeAddProp( work_adr, VCWorkProp );
1092 safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() );
1093 safeAddPropValue( work_adr, VCCityProp, c.businessCity() );
1094 safeAddPropValue( work_adr, VCRegionProp, c.businessState() );
1095 safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() );
1096 safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() );
1097
1098 VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() );
1099 safeAddProp( work_phone, VCWorkProp );
1100 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() );
1101 safeAddProp( work_phone, VCWorkProp );
1102 safeAddProp( work_phone, VCCellularProp );
1103 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() );
1104 safeAddProp( work_phone, VCWorkProp );
1105 safeAddProp( work_phone, VCFaxProp );
1106 work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() );
1107 safeAddProp( work_phone, VCWorkProp );
1108 safeAddProp( work_phone, VCPagerProp );
1109
1110 url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() );
1111 safeAddProp( url, VCWorkProp );
1112
1113 VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() );
1114 safeAddProp( title, VCWorkProp );
1115
1116
1117 QStringList emails = c.emailList();
1118 emails.prepend( c.defaultEmail() );
1119 for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) {
1120 VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it );
1121 safeAddProp( email, VCInternetProp );
1122 }
1123
1124 safeAddPropValue( vcard, VCNoteProp, c.notes() );
1125
1126 // Exporting Birthday regarding RFC 2425 (5.8.4)
1127 if ( c.birthday().isValid() ){
1128 QString birthd_rfc2425 = QString("%1-%2-%3")
1129 .arg( c.birthday().year() )
1130 .arg( c.birthday().month(), 2 )
1131 .arg( c.birthday().day(), 2 );
1132 // Now replace spaces with "0"...
1133 int pos = 0;
1134 while ( ( pos = birthd_rfc2425.find (' ') ) > 0 )
1135 birthd_rfc2425.replace( pos, 1, "0" );
1136
1137 qWarning("Exporting birthday as: %s", birthd_rfc2425.latin1());
1138 safeAddPropValue( vcard, VCBirthDateProp, birthd_rfc2425.latin1() );
1139 }
1140
1141 if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) {
1142 VObject *org = safeAddProp( vcard, VCOrgProp );
1143 safeAddPropValue( org, VCOrgNameProp, c.company() );
1144 safeAddPropValue( org, VCOrgUnitProp, c.department() );
1145 safeAddPropValue( org, VCOrgUnit2Prop, c.office() );
1146 }
1147
1148 // some values we have to export as custom fields
1149 safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() );
1150 safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() );
1151 safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() );
1152
1153 safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() );
1154 safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() );
1155 // safeAddPropValue( vcard, "X-Qtopia-Anniversary", TimeConversion::toString( c.anniversary() ) ); :SX
1156 safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() );
1157 safeAddPropValue( vcard, "X-Qtopia-Children", c.children() );
1158
1159 return vcard;
1160}
1161
1162
1163/*!
1164 \internal
1165*/
1166static QDate convVCardDateToDate( const QString& datestr )
1167{
1168 int monthPos = datestr.find('-');
1169 int dayPos = datestr.find('-', monthPos+1 );
1170 int sep_ignore = 1;
1171 if ( monthPos == -1 || dayPos == -1 ) {
1172 qDebug("fromString didn't find - in str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
1173 // Ok.. No "-" found, therefore we will try to read other format ( YYYYMMDD )
1174 if ( datestr.length() == 8 ){
1175 monthPos = 4;
1176 dayPos = 6;
1177 sep_ignore = 0;
1178 qDebug("Try with follwing positions str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, dayPos );
1179 } else {
1180 return QDate();
1181 }
1182 }
1183 int y = datestr.left( monthPos ).toInt();
1184 int m = datestr.mid( monthPos + sep_ignore, dayPos - monthPos - sep_ignore ).toInt();
1185 int d = datestr.mid( dayPos + sep_ignore ).toInt();
1186 qDebug("TimeConversion::fromString ymd = %s => %d %d %d; mpos = %d ypos = %d", datestr.latin1(), y, m, d, monthPos, dayPos);
1187 QDate date ( y,m,d );
1188 return date;
1189}
1190
1191static OContact parseVObject( VObject *obj )
1192{
1193 OContact c;
1194
1195 VObjectIterator it;
1196 initPropIterator( &it, obj );
1197 while( moreIteration( &it ) ) {
1198 VObject *o = nextVObject( &it );
1199 QCString name = vObjectName( o );
1200 QCString value = vObjectStringZValue( o );
1201 if ( name == VCNameProp ) {
1202 VObjectIterator nit;
1203 initPropIterator( &nit, o );
1204 while( moreIteration( &nit ) ) {
1205 VObject *o = nextVObject( &nit );
1206 QCString name = vObjectTypeInfo( o );
1207 QString value = vObjectStringZValue( o );
1208 if ( name == VCNamePrefixesProp )
1209 c.setTitle( value );
1210 else if ( name == VCNameSuffixesProp )
1211 c.setSuffix( value );
1212 else if ( name == VCFamilyNameProp )
1213 c.setLastName( value );
1214 else if ( name == VCGivenNameProp )
1215 c.setFirstName( value );
1216 else if ( name == VCAdditionalNamesProp )
1217 c.setMiddleName( value );
1218 }
1219 }
1220 else if ( name == VCAdrProp ) {
1221 bool work = TRUE; // default address is work address
1222 QString street;
1223 QString city;
1224 QString region;
1225 QString postal;
1226 QString country;
1227
1228 VObjectIterator nit;
1229 initPropIterator( &nit, o );
1230 while( moreIteration( &nit ) ) {
1231 VObject *o = nextVObject( &nit );
1232 QCString name = vObjectName( o );
1233 QString value = vObjectStringZValue( o );
1234
1235 if ( name == VCHomeProp )
1236 work = FALSE;
1237 else if ( name == VCWorkProp )
1238 work = TRUE;
1239 else if ( name == VCStreetAddressProp )
1240 street = value;
1241 else if ( name == VCCityProp )
1242 city = value;
1243 else if ( name == VCRegionProp )
1244 region = value;
1245 else if ( name == VCPostalCodeProp )
1246 postal = value;
1247 else if ( name == VCCountryNameProp )
1248 country = value;
1249 }
1250 if ( work ) {
1251 c.setBusinessStreet( street );
1252 c.setBusinessCity( city );
1253 c.setBusinessCountry( country );
1254 c.setBusinessZip( postal );
1255 c.setBusinessState( region );
1256 } else {
1257 c.setHomeStreet( street );
1258 c.setHomeCity( city );
1259 c.setHomeCountry( country );
1260 c.setHomeZip( postal );
1261 c.setHomeState( region );
1262 }
1263 }
1264 else if ( name == VCTelephoneProp ) {
1265 enum {
1266 HOME = 0x01,
1267 WORK = 0x02,
1268 VOICE = 0x04,
1269 CELL = 0x08,
1270 FAX = 0x10,
1271 PAGER = 0x20,
1272 UNKNOWN = 0x80
1273 };
1274 int type = 0;
1275
1276 VObjectIterator nit;
1277 initPropIterator( &nit, o );
1278 while( moreIteration( &nit ) ) {
1279 VObject *o = nextVObject( &nit );
1280 QCString name = vObjectTypeInfo( o );
1281 if ( name == VCHomeProp )
1282 type |= HOME;
1283 else if ( name == VCWorkProp )
1284 type |= WORK;
1285 else if ( name == VCVoiceProp )
1286 type |= VOICE;
1287 else if ( name == VCCellularProp )
1288 type |= CELL;
1289 else if ( name == VCFaxProp )
1290 type |= FAX;
1291 else if ( name == VCPagerProp )
1292 type |= PAGER;
1293 else if ( name == VCPreferredProp )
1294 ;
1295 else
1296 type |= UNKNOWN;
1297 }
1298 if ( (type & UNKNOWN) != UNKNOWN ) {
1299 if ( ( type & (HOME|WORK) ) == 0 ) // default
1300 type |= HOME;
1301 if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default
1302 type |= VOICE;
1303
1304 if ( (type & (VOICE|HOME) ) == (VOICE|HOME) )
1305 c.setHomePhone( value );
1306 if ( ( type & (FAX|HOME) ) == (FAX|HOME) )
1307 c.setHomeFax( value );
1308 if ( ( type & (CELL|HOME) ) == (CELL|HOME) )
1309 c.setHomeMobile( value );
1310 if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) )
1311 c.setBusinessPhone( value );
1312 if ( ( type & (FAX|WORK) ) == (FAX|WORK) )
1313 c.setBusinessFax( value );
1314 if ( ( type & (CELL|WORK) ) == (CELL|WORK) )
1315 c.setBusinessMobile( value );
1316 if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) )
1317 c.setBusinessPager( value );
1318 }
1319 }
1320 else if ( name == VCEmailAddressProp ) {
1321 QString email = vObjectStringZValue( o );
1322 bool valid = TRUE;
1323 VObjectIterator nit;
1324 initPropIterator( &nit, o );
1325 while( moreIteration( &nit ) ) {
1326 VObject *o = nextVObject( &nit );
1327 QCString name = vObjectTypeInfo( o );
1328 if ( name != VCInternetProp && name != VCHomeProp &&
1329 name != VCWorkProp &&
1330 name != VCPreferredProp )
1331 // ### preffered should map to default email
1332 valid = FALSE;
1333 }
1334 if ( valid ) {
1335 c.insertEmail( email );
1336 }
1337 }
1338 else if ( name == VCURLProp ) {
1339 VObjectIterator nit;
1340 initPropIterator( &nit, o );
1341 while( moreIteration( &nit ) ) {
1342 VObject *o = nextVObject( &nit );
1343 QCString name = vObjectTypeInfo( o );
1344 if ( name == VCHomeProp )
1345 c.setHomeWebpage( value );
1346 else if ( name == VCWorkProp )
1347 c.setBusinessWebpage( value );
1348 }
1349 }
1350 else if ( name == VCOrgProp ) {
1351 VObjectIterator nit;
1352 initPropIterator( &nit, o );
1353 while( moreIteration( &nit ) ) {
1354 VObject *o = nextVObject( &nit );
1355 QCString name = vObjectName( o );
1356 QString value = vObjectStringZValue( o );
1357 if ( name == VCOrgNameProp )
1358 c.setCompany( value );
1359 else if ( name == VCOrgUnitProp )
1360 c.setDepartment( value );
1361 else if ( name == VCOrgUnit2Prop )
1362 c.setOffice( value );
1363 }
1364 }
1365 else if ( name == VCTitleProp ) {
1366 c.setJobTitle( value );
1367 }
1368 else if ( name == "X-Qtopia-Profession" ) {
1369 c.setProfession( value );
1370 }
1371 else if ( name == "X-Qtopia-Manager" ) {
1372 c.setManager( value );
1373 }
1374 else if ( name == "X-Qtopia-Assistant" ) {
1375 c.setAssistant( value );
1376 }
1377 else if ( name == "X-Qtopia-Spouse" ) {
1378 c.setSpouse( value );
1379 }
1380 else if ( name == "X-Qtopia-Gender" ) {
1381 c.setGender( value );
1382 }
1383 else if ( name == "X-Qtopia-Anniversary" ) {
1384 // c.setAnniversary( TimeConversion::fromString( value ) ); :SX
1385 }
1386 else if ( name == "X-Qtopia-Nickname" ) {
1387 c.setNickname( value );
1388 }
1389 else if ( name == "X-Qtopia-Children" ) {
1390 c.setChildren( value );
1391 }
1392 else if ( name == VCBirthDateProp ) {
1393 // Reading Birthdate regarding RFC 2425 (5.8.4)
1394 c.setBirthday( convVCardDateToDate( value ) );
1395
1396 }
1397
1398#if 0
1399 else {
1400 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
1401 VObjectIterator nit;
1402 initPropIterator( &nit, o );
1403 while( moreIteration( &nit ) ) {
1404 VObject *o = nextVObject( &nit );
1405 QCString name = vObjectName( o );
1406 QString value = vObjectStringZValue( o );
1407 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
1408 }
1409 }
1410#endif
1411 }
1412 c.setFileAs();
1413 return c;
1414}
1415
1416/*!
1417 Writes the list of \a contacts as a set of VCards to the file \a filename.
1418*/
1419void OContact::writeVCard( const QString &filename, const QValueList<OContact> &contacts)
1420{
1421 QFileDirect f( filename.utf8().data() );
1422 if ( !f.open( IO_WriteOnly ) ) {
1423 qWarning("Unable to open vcard write");
1424 return;
1425 }
1426
1427 QValueList<OContact>::ConstIterator it;
1428 for( it = contacts.begin(); it != contacts.end(); ++it ) {
1429 VObject *obj = createVObject( *it );
1430 writeVObject(f.directHandle() , obj );
1431 cleanVObject( obj );
1432 }
1433 cleanStrTbl();
1434}
1435
1436/*!
1437 writes \a contact as a VCard to the file \a filename.
1438*/
1439void OContact::writeVCard( const QString &filename, const OContact &contact)
1440{
1441 QFileDirect f( filename.utf8().data() );
1442 if ( !f.open( IO_WriteOnly ) ) {
1443 qWarning("Unable to open vcard write");
1444 return;
1445 }
1446
1447 VObject *obj = createVObject( contact );
1448 writeVObject( f.directHandle() , obj );
1449 cleanVObject( obj );
1450
1451 cleanStrTbl();
1452}
1453
1454/*!
1455 Returns the set of contacts read as VCards from the file \a filename.
1456*/
1457QValueList<OContact> OContact::readVCard( const QString &filename )
1458{
1459 qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() );
1460 VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() );
1461
1462 qDebug("vobject = %p", obj );
1463
1464 QValueList<OContact> contacts;
1465
1466 while ( obj ) {
1467 OContact con = parseVObject( obj );
1468 /*
1469 * if uid is 0 assign a new one
1470 * this at least happens on
1471 * Nokia6210
1472 */
1473 if ( con.uid() == 0 ){
1474 con.setUid( 1 );
1475 qWarning("assigned new uid %d",con.uid() );
1476 }
1477
1478 contacts.append(con );
1479
1480 VObject *t = obj;
1481 obj = nextVObjectInList(obj);
1482 cleanVObject( t );
1483 }
1484
1485 return contacts;
1486}
1487
1488/*! 908/*!
1489 Returns TRUE if the contact matches the regular expression \a regexp. 909 Returns TRUE if the contact matches the regular expression \a regexp.
1490 Otherwise returns FALSE. 910 Otherwise returns FALSE.
1491*/ 911*/
1492bool OContact::match( const QString &regexp ) const 912bool OContact::match( const QString &regexp ) const
1493{ 913{
1494 return match(QRegExp(regexp)); 914 return match(QRegExp(regexp));
1495} 915}
1496 916
1497/*! 917/*!
1498 \overload 918 \overload
1499 Returns TRUE if the contact matches the regular expression \a regexp. 919 Returns TRUE if the contact matches the regular expression \a regexp.
1500 Otherwise returns FALSE. 920 Otherwise returns FALSE.
1501*/ 921*/
1502bool OContact::match( const QRegExp &r ) const 922bool OContact::match( const QRegExp &r ) const
1503{ 923{
1504 bool match; 924 bool match;
1505 match = false; 925 match = false;
1506 QMap<int, QString>::ConstIterator it; 926 QMap<int, QString>::ConstIterator it;
1507 for ( it = mMap.begin(); it != mMap.end(); ++it ) { 927 for ( it = mMap.begin(); it != mMap.end(); ++it ) {
1508 if ( (*it).find( r ) > -1 ) { 928 if ( (*it).find( r ) > -1 ) {
1509 match = true; 929 match = true;
1510 break; 930 break;
1511 } 931 }
1512 } 932 }
1513 return match; 933 return match;
1514} 934}
1515 935
1516 936
1517QString OContact::toShortText() const 937QString OContact::toShortText() const
1518{ 938{
1519 return ( fullName() ); 939 return ( fullName() );
1520} 940}
1521QString OContact::type() const 941QString OContact::type() const
1522{ 942{
1523 return QString::fromLatin1( "OContact" ); 943 return QString::fromLatin1( "OContact" );
1524} 944}
1525 945
1526// Definition is missing ! (se) 946// Definition is missing ! (se)
1527QMap<QString,QString> OContact::toExtraMap() const 947QMap<QString,QString> OContact::toExtraMap() const
1528{ 948{
1529 qWarning ("Function not implemented: OContact::toExtraMap()"); 949 qWarning ("Function not implemented: OContact::toExtraMap()");
1530 QMap <QString,QString> useless; 950 QMap <QString,QString> useless;
1531 return useless; 951 return useless;
1532} 952}
1533 953
1534class QString OContact::recordField( int pos ) const 954class QString OContact::recordField( int pos ) const
1535{ 955{
1536 QStringList SLFIELDS = fields(); // ?? why this ? (se) 956 QStringList SLFIELDS = fields(); // ?? why this ? (se)
1537 return SLFIELDS[pos]; 957 return SLFIELDS[pos];
1538} 958}
1539 959
1540// In future releases, we should store birthday and anniversary 960// In future releases, we should store birthday and anniversary
1541// internally as QDate instead of QString ! 961// internally as QDate instead of QString !
1542// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) 962// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se)
1543 963
1544/*! \fn void OContact::setBirthday( const QDate& date ) 964/*! \fn void OContact::setBirthday( const QDate& date )
1545 Sets the birthday for the contact to \a date. 965 Sets the birthday for the contact to \a date. If date is null
966 the current stored date will be removed.
1546*/ 967*/
1547void OContact::setBirthday( const QDate &v ) 968void OContact::setBirthday( const QDate &v )
1548{ 969{
1549 if ( ( !v.isNull() ) && ( v.isValid() ) ) 970 if ( v.isNull() ){
971 qWarning( "Remove Birthday");
972 replace( Qtopia::Birthday, QString::null );
973 return;
974 }
975
976 if ( v.isValid() )
1550 replace( Qtopia::Birthday, TimeConversion::toString( v ) ); 977 replace( Qtopia::Birthday, TimeConversion::toString( v ) );
1551 978
1552} 979}
1553 980
1554 981
1555/*! \fn void OContact::setAnniversary( const QDate &date ) 982/*! \fn void OContact::setAnniversary( const QDate &date )
1556 Sets the anniversary of the contact to \a date. 983 Sets the anniversary of the contact to \a date. If date is
984 null, the current stored date will be removed.
1557*/ 985*/
1558void OContact::setAnniversary( const QDate &v ) 986void OContact::setAnniversary( const QDate &v )
1559{ 987{
1560 if ( ( !v.isNull() ) && ( v.isValid() ) ) 988 if ( v.isNull() ){
989 qWarning( "Remove Anniversary");
990 replace( Qtopia::Anniversary, QString::null );
991 return;
992 }
993
994 if ( v.isValid() )
1561 replace( Qtopia::Anniversary, TimeConversion::toString( v ) ); 995 replace( Qtopia::Anniversary, TimeConversion::toString( v ) );
1562} 996}
1563 997
1564/*! \fn QDate OContact::birthday() const 998/*! \fn QDate OContact::birthday() const
1565 Returns the birthday of the contact. 999 Returns the birthday of the contact.
1566*/ 1000*/
1567QDate OContact::birthday() const 1001QDate OContact::birthday() const
1568{ 1002{
1569 QString str = find( Qtopia::Birthday ); 1003 QString str = find( Qtopia::Birthday );
1570 qWarning ("Birthday %s", str.latin1() ); 1004 qWarning ("Birthday %s", str.latin1() );
1571 if ( !str.isEmpty() ) 1005 if ( !str.isEmpty() )
1572 return TimeConversion::fromString ( str ); 1006 return TimeConversion::fromString ( str );
1573 else 1007 else
1574 return QDate(); 1008 return QDate();
1575} 1009}
1576 1010
1577 1011
1578/*! \fn QDate OContact::anniversary() const 1012/*! \fn QDate OContact::anniversary() const
1579 Returns the anniversary of the contact. 1013 Returns the anniversary of the contact.
1580*/ 1014*/
1581QDate OContact::anniversary() const 1015QDate OContact::anniversary() const
1582{ 1016{
1583 QDate empty; 1017 QDate empty;
1584 QString str = find( Qtopia::Anniversary ); 1018 QString str = find( Qtopia::Anniversary );
1585 qWarning ("Anniversary %s", str.latin1() ); 1019 qWarning ("Anniversary %s", str.latin1() );
1586 if ( !str.isEmpty() ) 1020 if ( !str.isEmpty() )
1587 return TimeConversion::fromString ( str ); 1021 return TimeConversion::fromString ( str );
1588 else 1022 else
1589 return empty; 1023 return empty;
1590} 1024}
1591 1025
1592 1026
@@ -1633,32 +1067,37 @@ void OContact::removeEmail( const QString &v )
1633 // if default, then replace the default email with the first one 1067 // if default, then replace the default email with the first one
1634 if ( def == e ) { 1068 if ( def == e ) {
1635 //qDebug("removeEmail is default; setting new default"); 1069 //qDebug("removeEmail is default; setting new default");
1636 if ( !emails.count() ) 1070 if ( !emails.count() )
1637 clearEmails(); 1071 clearEmails();
1638 else // setDefaultEmail will remove e from the list 1072 else // setDefaultEmail will remove e from the list
1639 setDefaultEmail( emails.first() ); 1073 setDefaultEmail( emails.first() );
1640 } 1074 }
1641} 1075}
1642void OContact::clearEmails() 1076void OContact::clearEmails()
1643{ 1077{
1644 mMap.remove( Qtopia::DefaultEmail ); 1078 mMap.remove( Qtopia::DefaultEmail );
1645 mMap.remove( Qtopia::Emails ); 1079 mMap.remove( Qtopia::Emails );
1646} 1080}
1647void OContact::setDefaultEmail( const QString &v ) 1081void OContact::setDefaultEmail( const QString &v )
1648{ 1082{
1649 QString e = v.simplifyWhiteSpace(); 1083 QString e = v.simplifyWhiteSpace();
1650 1084
1651 //qDebug("OContact::setDefaultEmail %s", e.latin1()); 1085 //qDebug("OContact::setDefaultEmail %s", e.latin1());
1652 replace( Qtopia::DefaultEmail, e ); 1086 replace( Qtopia::DefaultEmail, e );
1653 1087
1654 if ( !e.isEmpty() ) 1088 if ( !e.isEmpty() )
1655 insertEmail( e ); 1089 insertEmail( e );
1656 1090
1657} 1091}
1658 1092
1659void OContact::insertEmails( const QStringList &v ) 1093void OContact::insertEmails( const QStringList &v )
1660{ 1094{
1661 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) 1095 for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it )
1662 insertEmail( *it ); 1096 insertEmail( *it );
1663} 1097}
1664 1098
1099void OContact::setUid( int i )
1100{
1101 OPimRecord::setUid(i);
1102 replace( Qtopia::AddressUid , QString::number(i));
1103}
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h
index 9643e8b..d97af1c 100644
--- a/libopie2/opiepim/ocontact.h
+++ b/libopie2/opiepim/ocontact.h
@@ -5,87 +5,74 @@
5** This file is part of the Qtopia Environment. 5** This file is part of the Qtopia Environment.
6** 6**
7** This file may be distributed and/or modified under the terms of the 7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software 8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the 9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file. 10** packaging of this file.
11** 11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16** 16**
17** Contact info@trolltech.com if any conditions of this licensing are 17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you. 18** not clear to you.
19** 19**
20**********************************************************************/ 20**********************************************************************/
21 21
22#ifndef __OCONTACT_H__ 22#ifndef __OCONTACT_H__
23#define __OCONTACT_H__ 23#define __OCONTACT_H__
24 24
25#include <opie/opimrecord.h> 25#include <opie/opimrecord.h>
26#include <qpe/recordfields.h> 26#include <qpe/recordfields.h>
27 27
28#include <qdatetime.h> 28#include <qdatetime.h>
29#include <qstringlist.h> 29#include <qstringlist.h>
30 30
31#if defined(QPC_TEMPLATEDLL) 31#if defined(QPC_TEMPLATEDLL)
32// MOC_SKIP_BEGIN 32// MOC_SKIP_BEGIN
33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; 33QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
34// MOC_SKIP_END 34// MOC_SKIP_END
35#endif 35#endif
36 36
37class ContactPrivate; // Wozu ist das gut und wo ist das decrariert ? (se) 37class ContactPrivate;
38 /* Stefan das ist eine forward declaration 38
39 * dann machst du in der private section
40 * ContactPrivate *d;
41 *
42 * und wenn du bei Opie1.1 was hinzufuegen moechtest
43 * packst du es in ContactPrivate damit Opie
44 * binaer kompatibel bleibt
45 * -zecke
46 */
47class QPC_EXPORT OContact : public OPimRecord 39class QPC_EXPORT OContact : public OPimRecord
48{ 40{
49 friend class DataSet; 41 friend class DataSet;
50public: 42public:
51 OContact(); 43 OContact();
52 OContact( const QMap<int, QString> &fromMap ); 44 OContact( const QMap<int, QString> &fromMap );
53 virtual ~OContact(); 45 virtual ~OContact();
54 46
55 /* VCARD stuff should vanish! -zecke */
56 static void writeVCard( const QString &filename, const QValueList<OContact> &contacts);
57 static void writeVCard( const QString &filename, const OContact &c );
58 static QValueList<OContact> readVCard( const QString &filename );
59
60 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 47 enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
61 48
62 /* 49 /*
63 * do we need to inline them 50 * do we need to inline them
64 * if yes do we need to inline them this way? 51 * if yes do we need to inline them this way?
65 * -zecke 52 * -zecke
66 */ 53 */
67 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } 54 void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
68 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } 55 void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
69 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } 56 void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
70 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } 57 void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
71 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } 58 void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
72 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } 59 void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
73 void setFileAs(); 60 void setFileAs();
74 61
75 // default email address 62 // default email address
76 void setDefaultEmail( const QString &v ); 63 void setDefaultEmail( const QString &v );
77 // inserts email to list and ensure's doesn't already exist 64 // inserts email to list and ensure's doesn't already exist
78 void insertEmail( const QString &v ); 65 void insertEmail( const QString &v );
79 void removeEmail( const QString &v ); 66 void removeEmail( const QString &v );
80 void clearEmails(); 67 void clearEmails();
81 void insertEmails( const QStringList &v ); 68 void insertEmails( const QStringList &v );
82 69
83 // home 70 // home
84 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } 71 void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
85 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } 72 void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }
86 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } 73 void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); }
87 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } 74 void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); }
88 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } 75 void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); }
89 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } 76 void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); }
90 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } 77 void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); }
91 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } 78 void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); }
@@ -177,88 +164,75 @@ public:
177 QString businessPhone() const { return find( Qtopia::BusinessPhone ); } 164 QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
178 QString businessFax() const { return find( Qtopia::BusinessFax ); } 165 QString businessFax() const { return find( Qtopia::BusinessFax ); }
179 QString businessMobile() const { return find( Qtopia::BusinessMobile ); } 166 QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
180 QString businessPager() const { return find( Qtopia::BusinessPager ); } 167 QString businessPager() const { return find( Qtopia::BusinessPager ); }
181 QString profession() const { return find( Qtopia::Profession ); } 168 QString profession() const { return find( Qtopia::Profession ); }
182 QString assistant() const { return find( Qtopia::Assistant ); } 169 QString assistant() const { return find( Qtopia::Assistant ); }
183 QString manager() const { return find( Qtopia::Manager ); } 170 QString manager() const { return find( Qtopia::Manager ); }
184 /** Multi line string containing all non-empty address info in the form 171 /** Multi line string containing all non-empty address info in the form
185 * Street 172 * Street
186 * City, State Zip 173 * City, State Zip
187 * Country 174 * Country
188 */ 175 */
189 QString displayBusinessAddress() const; 176 QString displayBusinessAddress() const;
190 177
191 //personal 178 //personal
192 QString spouse() const { return find( Qtopia::Spouse ); } 179 QString spouse() const { return find( Qtopia::Spouse ); }
193 QString gender() const { return find( Qtopia::Gender ); } 180 QString gender() const { return find( Qtopia::Gender ); }
194 QDate birthday() const; 181 QDate birthday() const;
195 QDate anniversary() const; 182 QDate anniversary() const;
196 QString nickname() const { return find( Qtopia::Nickname ); } 183 QString nickname() const { return find( Qtopia::Nickname ); }
197 QString children() const { return find( Qtopia::Children ); } 184 QString children() const { return find( Qtopia::Children ); }
198 QStringList childrenList() const; 185 QStringList childrenList() const;
199 186
200 // other 187 // other
201 QString notes() const { return find( Qtopia::Notes ); } 188 QString notes() const { return find( Qtopia::Notes ); }
202 QString groups() const { return find( Qtopia::Groups ); } 189 QString groups() const { return find( Qtopia::Groups ); }
203 QStringList groupList() const; 190 QStringList groupList() const;
204 191
205// // custom 192// // custom
206// const QString &customField( const QString &key ) 193// const QString &customField( const QString &key )
207// { return find( Custom- + key ); } 194// { return find( Custom- + key ); }
208 195
209 static QStringList fields();
210 static QStringList trfields();
211 static QStringList untrfields();
212 196
213 QString toRichText() const; 197 QString toRichText() const;
214 QMap<int, QString> toMap() const; 198 QMap<int, QString> toMap() const;
215 QString field( int key ) const { return find( key ); } 199 QString field( int key ) const { return find( key ); }
216 200
217 201
218 // journaling... 202 void setUid( int i );
219 /* do we still need them? Stefan your backend takes care of these -zecke */
220 void saveJournal( journal_action action, const QString &key = QString::null );
221 void save( QString &buf ) const;
222
223 /* we shouldn't inline this one -zecke */
224 void setUid( int i )
225{ OPimRecord::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); }
226 203
227 QString toShortText()const; 204 QString toShortText()const;
228 QString OContact::type()const; 205 QString OContact::type()const;
229 QMap<QString,QString> OContact::toExtraMap() const; 206 QMap<QString,QString> OContact::toExtraMap() const;
230 class QString OContact::recordField(int) const; 207 class QString OContact::recordField(int) const;
231 208
232 // Why private ? (eilers,se) 209 // Why private ? (eilers,se)
233 QString emailSeparator() const { return " "; } 210 QString emailSeparator() const { return " "; }
234 // the emails should be seperated by a comma 211 // the emails should be seperated by a comma
235 void setEmails( const QString &v ); 212 void setEmails( const QString &v );
236 QString emails() const { return find( Qtopia::Emails ); } 213 QString emails() const { return find( Qtopia::Emails ); }
237 214
238 215
239private: 216private:
240 /* I do not like friends ;) 217 // The XML-Backend needs some access to the private functions
241 * besides that I think we do not need them 218 friend class OContactAccessBackend_XML;
242 * anymore -zecke
243 */
244 friend class AbEditor;
245 friend class AbTable;
246 friend class AddressBookAccessPrivate;
247 friend class XMLIO;
248 219
249 void insert( int key, const QString &value ); 220 void insert( int key, const QString &value );
250 void replace( int key, const QString &value ); 221 void replace( int key, const QString &value );
251 QString find( int key ) const; 222 QString find( int key ) const;
223 static QStringList fields();
224
225 void save( QString &buf ) const;
252 226
253 QString displayAddress( const QString &street, 227 QString displayAddress( const QString &street,
254 const QString &city, 228 const QString &city,
255 const QString &state, 229 const QString &state,
256 const QString &zip, 230 const QString &zip,
257 const QString &country ) const; 231 const QString &country ) const;
258 232
259 QMap<int, QString> mMap; 233 QMap<int, QString> mMap;
260 ContactPrivate *d; 234 ContactPrivate *d;
261}; 235};
262 236
263 237
264#endif 238#endif