summaryrefslogtreecommitdiff
Unidiff
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
@@ -22,8 +22,6 @@
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>
@@ -587,6 +585,12 @@ QString OContact::toRichText() const
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");
@@ -816,9 +820,12 @@ void OContact::save( QString &buf ) const
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{
@@ -878,129 +885,6 @@ QStringList OContact::fields()
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.
@@ -1021,470 +905,6 @@ void OContact::setChildren( const QString &str )
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.
@@ -1542,22 +962,36 @@ class QString OContact::recordField( int pos ) const
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
@@ -1662,3 +1096,8 @@ void OContact::insertEmails( const QStringList &v )
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
@@ -34,16 +34,8 @@ QPC_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;
@@ -52,11 +44,6 @@ public:
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 /*
@@ -206,23 +193,13 @@ public:
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;
@@ -237,18 +214,15 @@ public:
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,
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
@@ -22,8 +22,6 @@
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>
@@ -587,6 +585,12 @@ QString OContact::toRichText() const
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");
@@ -816,9 +820,12 @@ void OContact::save( QString &buf ) const
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{
@@ -878,129 +885,6 @@ QStringList OContact::fields()
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.
@@ -1021,470 +905,6 @@ void OContact::setChildren( const QString &str )
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.
@@ -1542,22 +962,36 @@ class QString OContact::recordField( int pos ) const
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
@@ -1662,3 +1096,8 @@ void OContact::insertEmails( const QStringList &v )
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
@@ -34,16 +34,8 @@ QPC_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;
@@ -52,11 +44,6 @@ public:
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 /*
@@ -206,23 +193,13 @@ public:
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;
@@ -237,18 +214,15 @@ public:
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,