-rw-r--r-- | library/backend/contact.cpp | 909 |
1 files changed, 909 insertions, 0 deletions
diff --git a/library/backend/contact.cpp b/library/backend/contact.cpp new file mode 100644 index 0000000..a5f10ab --- a/dev/null +++ b/library/backend/contact.cpp | |||
@@ -0,0 +1,909 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "contact.h" | ||
22 | #include "vobject_p.h" | ||
23 | #include "qfiledirect_p.h" | ||
24 | |||
25 | #include <qpe/stringutil.h> | ||
26 | #include <qpe/timeconversion.h> | ||
27 | |||
28 | #include <qobject.h> | ||
29 | #include <qregexp.h> | ||
30 | #include <qstylesheet.h> | ||
31 | #include <qfileinfo.h> | ||
32 | |||
33 | #include <stdio.h> | ||
34 | |||
35 | Qtopia::UidGen Contact::sUidGen( Qtopia::UidGen::Qtopia ); | ||
36 | |||
37 | Contact::Contact() | ||
38 | : Record(), mMap(), d( 0 ) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | Contact::Contact( const QMap<int, QString> &fromMap ) : | ||
43 | Record(), mMap( fromMap ), d( 0 ) | ||
44 | { | ||
45 | QString cats = mMap[ Qtopia::AddressCategory ]; | ||
46 | if ( !cats.isEmpty() ) | ||
47 | setCategories( idsFromString( cats ) ); | ||
48 | QString uidStr = find( Qtopia::AddressUid ); | ||
49 | if ( uidStr.isEmpty() ) | ||
50 | setUid( uidGen().generate() ); | ||
51 | else | ||
52 | setUid( uidStr.toInt() ); | ||
53 | } | ||
54 | |||
55 | Contact::~Contact() | ||
56 | { | ||
57 | } | ||
58 | |||
59 | QMap<int, QString> Contact::toMap() const | ||
60 | { | ||
61 | QMap<int, QString> map = mMap; | ||
62 | map.insert( Qtopia::AddressCategory, idsToString( categories() )); | ||
63 | return map; | ||
64 | } | ||
65 | |||
66 | /*! | ||
67 | Returns a rich text formatted QString of the Contact. | ||
68 | */ | ||
69 | QString Contact::toRichText() const | ||
70 | { | ||
71 | QString text; | ||
72 | QString value, comp, state; | ||
73 | |||
74 | // name, jobtitle and company | ||
75 | if ( !(value = fullName()).isEmpty() ) | ||
76 | text += "<b>" + Qtopia::escapeString(value) + "</b><br>"; | ||
77 | if ( !(value = jobTitle()).isEmpty() ) | ||
78 | text += Qtopia::escapeString(value) + "<br>"; | ||
79 | |||
80 | comp = company(); | ||
81 | if ( !(value = department()).isEmpty() ) { | ||
82 | text += Qtopia::escapeString(value); | ||
83 | if ( comp ) | ||
84 | text += ", "; | ||
85 | else | ||
86 | text += "<br>"; | ||
87 | } | ||
88 | if ( !comp.isEmpty() ) | ||
89 | text += Qtopia::escapeString(comp) + "<br>"; | ||
90 | |||
91 | // business address | ||
92 | if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || | ||
93 | !businessZip().isEmpty() || !businessCountry().isEmpty() ) { | ||
94 | text += "<br>"; | ||
95 | text += QObject::tr( "<b>Work Address:</b>" ); | ||
96 | text += "<br>"; | ||
97 | } | ||
98 | |||
99 | if ( !(value = businessStreet()).isEmpty() ) | ||
100 | text += Qtopia::escapeString(value) + "<br>"; | ||
101 | state = businessState(); | ||
102 | if ( !(value = businessCity()).isEmpty() ) { | ||
103 | text += Qtopia::escapeString(value); | ||
104 | if ( state ) | ||
105 | text += ", " + Qtopia::escapeString(state); | ||
106 | text += "<br>"; | ||
107 | } else if ( !state.isEmpty() ) | ||
108 | text += Qtopia::escapeString(state) + "<br>"; | ||
109 | if ( !(value = businessZip()).isEmpty() ) | ||
110 | text += Qtopia::escapeString(value) + "<br>"; | ||
111 | if ( !(value = businessCountry()).isEmpty() ) | ||
112 | text += Qtopia::escapeString(value) + "<br>"; | ||
113 | |||
114 | // home address | ||
115 | if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || | ||
116 | !homeZip().isEmpty() || !homeCountry().isEmpty() ) { | ||
117 | text += "<br>"; | ||
118 | text += QObject::tr( "<b>Home Address:</b>" ); | ||
119 | text += "<br>"; | ||
120 | } | ||
121 | |||
122 | if ( !(value = homeStreet()).isEmpty() ) | ||
123 | text += Qtopia::escapeString(value) + "<br>"; | ||
124 | state = homeState(); | ||
125 | if ( !(value = homeCity()).isEmpty() ) { | ||
126 | text += Qtopia::escapeString(value); | ||
127 | if ( !state.isEmpty() ) | ||
128 | text += ", " + Qtopia::escapeString(state); | ||
129 | text += "<br>"; | ||
130 | } else if (!state.isEmpty()) | ||
131 | text += Qtopia::escapeString(state) + "<br>"; | ||
132 | if ( !(value = homeZip()).isEmpty() ) | ||
133 | text += Qtopia::escapeString(value) + "<br>"; | ||
134 | if ( !(value = homeCountry()).isEmpty() ) | ||
135 | text += Qtopia::escapeString(value) + "<br>"; | ||
136 | |||
137 | // the others... | ||
138 | QString str; | ||
139 | str = emails(); | ||
140 | if ( !str.isEmpty() ) | ||
141 | text += "<b>" + QObject::tr("Email Addresses: ") + "</b>" | ||
142 | + Qtopia::escapeString(str) + "<br>"; | ||
143 | str = homePhone(); | ||
144 | if ( !str.isEmpty() ) | ||
145 | text += "<b>" + QObject::tr("Home Phone: ") + "</b>" | ||
146 | + Qtopia::escapeString(str) + "<br>"; | ||
147 | str = homeFax(); | ||
148 | if ( !str.isEmpty() ) | ||
149 | text += "<b>" + QObject::tr("Home Fax: ") + "</b>" | ||
150 | + Qtopia::escapeString(str) + "<br>"; | ||
151 | str = homeMobile(); | ||
152 | if ( !str.isEmpty() ) | ||
153 | text += "<b>" + QObject::tr("Home Mobile: ") + "</b>" | ||
154 | + Qtopia::escapeString(str) + "<br>"; | ||
155 | str = homeWebpage(); | ||
156 | if ( !str.isEmpty() ) | ||
157 | text += "<b>" + QObject::tr("Home Web Page: ") + "</b>" | ||
158 | + Qtopia::escapeString(str) + "<br>"; | ||
159 | str = businessWebpage(); | ||
160 | if ( !str.isEmpty() ) | ||
161 | text += "<b>" + QObject::tr("Business Web Page: ") + "</b>" | ||
162 | + Qtopia::escapeString(str) + "<br>"; | ||
163 | str = office(); | ||
164 | if ( !str.isEmpty() ) | ||
165 | text += "<b>" + QObject::tr("Office: ") + "</b>" | ||
166 | + Qtopia::escapeString(str) + "<br>"; | ||
167 | str = businessPhone(); | ||
168 | if ( !str.isEmpty() ) | ||
169 | text += "<b>" + QObject::tr("Business Phone: ") + "</b>" | ||
170 | + Qtopia::escapeString(str) + "<br>"; | ||
171 | str = businessFax(); | ||
172 | if ( !str.isEmpty() ) | ||
173 | text += "<b>" + QObject::tr("Business Fax: ") + "</b>" | ||
174 | + Qtopia::escapeString(str) + "<br>"; | ||
175 | str = businessMobile(); | ||
176 | if ( !str.isEmpty() ) | ||
177 | text += "<b>" + QObject::tr("Business Mobile: ") + "</b>" | ||
178 | + Qtopia::escapeString(str) + "<br>"; | ||
179 | str = businessPager(); | ||
180 | if ( !str.isEmpty() ) | ||
181 | text += "<b>" + QObject::tr("Business Pager: ") + "</b>" | ||
182 | + Qtopia::escapeString(str) + "<br>"; | ||
183 | str = profession(); | ||
184 | if ( !str.isEmpty() ) | ||
185 | text += "<b>" + QObject::tr("Profession: ") + "</b>" | ||
186 | + Qtopia::escapeString(str) + "<br>"; | ||
187 | str = assistant(); | ||
188 | if ( !str.isEmpty() ) | ||
189 | text += "<b>" + QObject::tr("Assistant: ") + "</b>" | ||
190 | + Qtopia::escapeString(str) + "<br>"; | ||
191 | str = manager(); | ||
192 | if ( !str.isEmpty() ) | ||
193 | text += "<b>" + QObject::tr("Manager: ") + "</b>" | ||
194 | + Qtopia::escapeString(str) + "<br>"; | ||
195 | str = gender(); | ||
196 | if ( !str.isEmpty() && str.toInt() != 0 ) { | ||
197 | if ( str.toInt() == 1 ) | ||
198 | str = QObject::tr( "Male" ); | ||
199 | else if ( str.toInt() == 2 ) | ||
200 | str = QObject::tr( "Female" ); | ||
201 | text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; | ||
202 | } | ||
203 | str = spouse(); | ||
204 | if ( !str.isEmpty() ) | ||
205 | text += "<b>" + QObject::tr("Spouse: ") + "</b>" | ||
206 | + Qtopia::escapeString(str) + "<br>"; | ||
207 | str = birthday(); | ||
208 | if ( !str.isEmpty() ) | ||
209 | text += "<b>" + QObject::tr("Birthday: ") + "</b>" | ||
210 | + Qtopia::escapeString(str) + "<br>"; | ||
211 | str = anniversary(); | ||
212 | if ( !str.isEmpty() ) | ||
213 | text += "<b>" + QObject::tr("Anniversary: ") + "</b>" | ||
214 | + Qtopia::escapeString(str) + "<br>"; | ||
215 | str = nickname(); | ||
216 | if ( !str.isEmpty() ) | ||
217 | text += "<b>" + QObject::tr("Nickname: ") + "</b>" | ||
218 | + Qtopia::escapeString(str) + "<br>"; | ||
219 | |||
220 | // notes last | ||
221 | if ( (value = notes()) ) { | ||
222 | QRegExp reg("\n"); | ||
223 | |||
224 | //QString tmp = Qtopia::escapeString(value); | ||
225 | QString tmp = QStyleSheet::convertFromPlainText(value); | ||
226 | //tmp.replace( reg, "<br>" ); | ||
227 | text += "<br>" + tmp + "<br>"; | ||
228 | } | ||
229 | return text; | ||
230 | } | ||
231 | |||
232 | void Contact::insert( int key, const QString &v ) | ||
233 | { | ||
234 | QString value = v.stripWhiteSpace(); | ||
235 | if ( value.isEmpty() ) | ||
236 | mMap.remove( key ); | ||
237 | else | ||
238 | mMap.insert( key, value ); | ||
239 | } | ||
240 | |||
241 | void Contact::replace( int key, const QString & v ) | ||
242 | { | ||
243 | QString value = v.stripWhiteSpace(); | ||
244 | if ( value.isEmpty() ) | ||
245 | mMap.remove( key ); | ||
246 | else | ||
247 | mMap.replace( key, value ); | ||
248 | } | ||
249 | |||
250 | QString Contact::find( int key ) const | ||
251 | { | ||
252 | return mMap[key]; | ||
253 | } | ||
254 | |||
255 | QString Contact::displayAddress( const QString &street, | ||
256 | const QString &city, | ||
257 | const QString &state, | ||
258 | const QString &zip, | ||
259 | const QString &country ) const | ||
260 | { | ||
261 | QString s = street; | ||
262 | if ( !street.isEmpty() ) | ||
263 | s+= "\n"; | ||
264 | s += city; | ||
265 | if ( !city.isEmpty() && !state.isEmpty() ) | ||
266 | s += ", "; | ||
267 | s += state; | ||
268 | if ( !state.isEmpty() && !zip.isEmpty() ) | ||
269 | s += " "; | ||
270 | s += zip; | ||
271 | if ( !country.isEmpty() && !s.isEmpty() ) | ||
272 | s += "\n"; | ||
273 | s += country; | ||
274 | return s; | ||
275 | } | ||
276 | |||
277 | QString Contact::displayBusinessAddress() const | ||
278 | { | ||
279 | return displayAddress( businessStreet(), businessCity(), | ||
280 | businessState(), businessZip(), | ||
281 | businessCountry() ); | ||
282 | } | ||
283 | |||
284 | QString Contact::displayHomeAddress() const | ||
285 | { | ||
286 | return displayAddress( homeStreet(), homeCity(), | ||
287 | homeState(), homeZip(), | ||
288 | homeCountry() ); | ||
289 | } | ||
290 | |||
291 | QString Contact::fullName() const | ||
292 | { | ||
293 | QString title = find( Qtopia::Title ); | ||
294 | QString firstName = find( Qtopia::FirstName ); | ||
295 | QString middleName = find( Qtopia::MiddleName ); | ||
296 | QString lastName = find( Qtopia::LastName ); | ||
297 | QString suffix = find( Qtopia::Suffix ); | ||
298 | |||
299 | QString name = title; | ||
300 | if ( !firstName.isEmpty() ) { | ||
301 | if ( !name.isEmpty() ) | ||
302 | name += " "; | ||
303 | name += firstName; | ||
304 | } | ||
305 | if ( !middleName.isEmpty() ) { | ||
306 | if ( !name.isEmpty() ) | ||
307 | name += " "; | ||
308 | name += middleName; | ||
309 | } | ||
310 | if ( !lastName.isEmpty() ) { | ||
311 | if ( !name.isEmpty() ) | ||
312 | name += " "; | ||
313 | name += lastName; | ||
314 | } | ||
315 | if ( !suffix.isEmpty() ) { | ||
316 | if ( !name.isEmpty() ) | ||
317 | name += " "; | ||
318 | name += suffix; | ||
319 | } | ||
320 | return name.simplifyWhiteSpace(); | ||
321 | } | ||
322 | |||
323 | QStringList Contact::childrenList() const | ||
324 | { | ||
325 | return QStringList::split( " ", find( Qtopia::Children ) ); | ||
326 | } | ||
327 | |||
328 | QStringList Contact::emailList() const | ||
329 | { | ||
330 | return QStringList::split( ";", find( Qtopia::Emails ) ); | ||
331 | } | ||
332 | |||
333 | void Contact::setFileAs() | ||
334 | { | ||
335 | QString lastName, firstName, middleName, fileas; | ||
336 | |||
337 | lastName = find( Qtopia::LastName ); | ||
338 | firstName = find( Qtopia::FirstName ); | ||
339 | middleName = find( Qtopia::MiddleName ); | ||
340 | if ( !lastName.isEmpty() && !firstName.isEmpty() | ||
341 | && !middleName.isEmpty() ) | ||
342 | fileas = lastName + ", " + firstName + " " + middleName; | ||
343 | else if ( !lastName.isEmpty() && !firstName.isEmpty() ) | ||
344 | fileas = lastName + ", " + firstName; | ||
345 | else if ( !lastName.isEmpty() || !firstName.isEmpty() || | ||
346 | !middleName.isEmpty() ) | ||
347 | fileas = firstName + ( firstName.isEmpty() ? "" : " " ) | ||
348 | + middleName + ( middleName.isEmpty() ? "" : " " ) | ||
349 | + lastName; | ||
350 | |||
351 | replace( Qtopia::FileAs, fileas ); | ||
352 | } | ||
353 | |||
354 | void Contact::save( QString &buf ) const | ||
355 | { | ||
356 | static const QStringList SLFIELDS = fields(); | ||
357 | // I'm expecting "<Contact " in front of this... | ||
358 | for ( QMap<int, QString>::ConstIterator it = mMap.begin(); | ||
359 | it != mMap.end(); ++it ) { | ||
360 | const QString &value = it.data(); | ||
361 | int key = it.key(); | ||
362 | if ( !value.isEmpty() ) { | ||
363 | if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) | ||
364 | continue; | ||
365 | |||
366 | key -= Qtopia::AddressCategory+1; | ||
367 | buf += SLFIELDS[key]; | ||
368 | buf += "=\"" + Qtopia::escapeString(value) + "\" "; | ||
369 | } | ||
370 | } | ||
371 | buf += customToXml(); | ||
372 | if ( categories().count() > 0 ) | ||
373 | buf += "Categories=\"" + idsToString( categories() ) + "\" "; | ||
374 | buf += "Uid=\"" + QString::number( uid() ) + "\" "; | ||
375 | // You need to close this yourself | ||
376 | } | ||
377 | |||
378 | QStringList Contact::fields() | ||
379 | { | ||
380 | QStringList list; | ||
381 | |||
382 | list.append( "Title" ); // Not Used! | ||
383 | list.append( "FirstName" ); | ||
384 | list.append( "MiddleName" ); | ||
385 | list.append( "LastName" ); | ||
386 | list.append( "Suffix" ); | ||
387 | list.append( "FileAs" ); | ||
388 | |||
389 | list.append( "DefaultEmail" ); | ||
390 | list.append( "Emails" ); | ||
391 | |||
392 | list.append( "HomeStreet" ); | ||
393 | list.append( "HomeCity" ); | ||
394 | list.append( "HomeState" ); | ||
395 | list.append( "HomeZip" ); | ||
396 | list.append( "HomeCountry" ); | ||
397 | list.append( "HomePhone" ); | ||
398 | list.append( "HomeFax" ); | ||
399 | list.append( "HomeMobile" ); | ||
400 | list.append( "HomeWebPage" ); | ||
401 | |||
402 | list.append( "Company" ); | ||
403 | list.append( "BusinessStreet" ); | ||
404 | list.append( "BusinessCity" ); | ||
405 | list.append( "BusinessState" ); | ||
406 | list.append( "BusinessZip" ); | ||
407 | list.append( "BusinessCountry" ); | ||
408 | list.append( "BusinessWebPage" ); | ||
409 | list.append( "JobTitle" ); | ||
410 | list.append( "Department" ); | ||
411 | list.append( "Office" ); | ||
412 | list.append( "BusinessPhone" ); | ||
413 | list.append( "BusinessFax" ); | ||
414 | list.append( "BusinessMobile" ); | ||
415 | list.append( "BusinessPager" ); | ||
416 | list.append( "Profession" ); | ||
417 | list.append( "Assistant" ); | ||
418 | list.append( "Manager" ); | ||
419 | |||
420 | list.append( "Spouse" ); | ||
421 | list.append( "Gender" ); | ||
422 | list.append( "Birthday" ); | ||
423 | list.append( "Anniversary" ); | ||
424 | list.append( "Nickname" ); | ||
425 | |||
426 | list.append( "Children" ); | ||
427 | list.append( "Notes" ); | ||
428 | |||
429 | return list; | ||
430 | } | ||
431 | |||
432 | QStringList Contact::trfields() | ||
433 | { | ||
434 | QStringList list; | ||
435 | |||
436 | list.append( QObject::tr( "Name Title") ); | ||
437 | list.append( QObject::tr( "First Name" ) ); | ||
438 | list.append( QObject::tr( "Middle Name" ) ); | ||
439 | list.append( QObject::tr( "Last Name" ) ); | ||
440 | list.append( QObject::tr( "Suffix" ) ); | ||
441 | list.append( QObject::tr( "File As" ) ); | ||
442 | |||
443 | list.append( QObject::tr( "Default Email" ) ); | ||
444 | list.append( QObject::tr( "Emails" ) ); | ||
445 | |||
446 | list.append( QObject::tr( "Home Street" ) ); | ||
447 | list.append( QObject::tr( "Home City" ) ); | ||
448 | list.append( QObject::tr( "Home State" ) ); | ||
449 | list.append( QObject::tr( "Home Zip" ) ); | ||
450 | list.append( QObject::tr( "Home Country" ) ); | ||
451 | list.append( QObject::tr( "Home Phone" ) ); | ||
452 | list.append( QObject::tr( "Home Fax" ) ); | ||
453 | list.append( QObject::tr( "Home Mobile" ) ); | ||
454 | list.append( QObject::tr( "Home Web Page" ) ); | ||
455 | |||
456 | list.append( QObject::tr( "Company" ) ); | ||
457 | list.append( QObject::tr( "Business Street" ) ); | ||
458 | list.append( QObject::tr( "Business City" ) ); | ||
459 | list.append( QObject::tr( "Business State" ) ); | ||
460 | list.append( QObject::tr( "Business Zip" ) ); | ||
461 | list.append( QObject::tr( "Business Country" ) ); | ||
462 | list.append( QObject::tr( "Business WebPage" ) ); | ||
463 | list.append( QObject::tr( "Job Title" ) ); | ||
464 | list.append( QObject::tr( "Department" ) ); | ||
465 | list.append( QObject::tr( "Office" ) ); | ||
466 | list.append( QObject::tr( "Business Phone" ) ); | ||
467 | list.append( QObject::tr( "Business Fax" ) ); | ||
468 | list.append( QObject::tr( "Business Mobile" ) ); | ||
469 | list.append( QObject::tr( "Business Pager" ) ); | ||
470 | list.append( QObject::tr( "Profession" ) ); | ||
471 | list.append( QObject::tr( "Assistant" ) ); | ||
472 | list.append( QObject::tr( "Manager" ) ); | ||
473 | |||
474 | list.append( QObject::tr( "Spouse" ) ); | ||
475 | list.append( QObject::tr( "Gender" ) ); | ||
476 | list.append( QObject::tr( "Birthday" ) ); | ||
477 | list.append( QObject::tr( "Anniversary" ) ); | ||
478 | list.append( QObject::tr( "Nickname" ) ); | ||
479 | |||
480 | list.append( QObject::tr( "Children" ) ); | ||
481 | list.append( QObject::tr( "Notes" ) ); | ||
482 | |||
483 | return list; | ||
484 | } | ||
485 | |||
486 | void Contact::setEmails( const QString &v ) | ||
487 | { | ||
488 | replace( Qtopia::Emails, v ); | ||
489 | if ( v.isEmpty() ) | ||
490 | setDefaultEmail( QString::null ); | ||
491 | } | ||
492 | |||
493 | void Contact::setChildren( const QString &v ) | ||
494 | { | ||
495 | replace( Qtopia::Children, v ); | ||
496 | } | ||
497 | |||
498 | // vcard conversion code | ||
499 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | ||
500 | { | ||
501 | VObject *ret = 0; | ||
502 | if ( o && !value.isEmpty() ) | ||
503 | ret = addPropValue( o, prop, value.latin1() ); | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | static inline VObject *safeAddProp( VObject *o, const char *prop) | ||
508 | { | ||
509 | VObject *ret = 0; | ||
510 | if ( o ) | ||
511 | ret = addProp( o, prop ); | ||
512 | return ret; | ||
513 | } | ||
514 | |||
515 | static VObject *createVObject( const Contact &c ) | ||
516 | { | ||
517 | VObject *vcard = newVObject( VCCardProp ); | ||
518 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); | ||
519 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); | ||
520 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); | ||
521 | |||
522 | // full name | ||
523 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); | ||
524 | |||
525 | // name properties | ||
526 | VObject *name = safeAddProp( vcard, VCNameProp ); | ||
527 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); | ||
528 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); | ||
529 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); | ||
530 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); | ||
531 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); | ||
532 | |||
533 | // home properties | ||
534 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); | ||
535 | safeAddProp( home_adr, VCHomeProp ); | ||
536 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); | ||
537 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); | ||
538 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); | ||
539 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); | ||
540 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); | ||
541 | |||
542 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); | ||
543 | safeAddProp( home_phone, VCHomeProp ); | ||
544 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); | ||
545 | safeAddProp( home_phone, VCHomeProp ); | ||
546 | safeAddProp( home_phone, VCCellularProp ); | ||
547 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); | ||
548 | safeAddProp( home_phone, VCHomeProp ); | ||
549 | safeAddProp( home_phone, VCFaxProp ); | ||
550 | |||
551 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); | ||
552 | safeAddProp( url, VCHomeProp ); | ||
553 | |||
554 | // work properties | ||
555 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); | ||
556 | safeAddProp( work_adr, VCWorkProp ); | ||
557 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); | ||
558 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); | ||
559 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); | ||
560 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); | ||
561 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); | ||
562 | |||
563 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); | ||
564 | safeAddProp( work_phone, VCWorkProp ); | ||
565 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); | ||
566 | safeAddProp( work_phone, VCWorkProp ); | ||
567 | safeAddProp( work_phone, VCCellularProp ); | ||
568 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); | ||
569 | safeAddProp( work_phone, VCWorkProp ); | ||
570 | safeAddProp( work_phone, VCFaxProp ); | ||
571 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); | ||
572 | safeAddProp( work_phone, VCWorkProp ); | ||
573 | safeAddProp( work_phone, VCPagerProp ); | ||
574 | |||
575 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); | ||
576 | safeAddProp( url, VCWorkProp ); | ||
577 | |||
578 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); | ||
579 | safeAddProp( title, VCWorkProp ); | ||
580 | |||
581 | |||
582 | QStringList emails = c.emailList(); | ||
583 | emails.prepend( c.defaultEmail() ); | ||
584 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { | ||
585 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); | ||
586 | safeAddProp( email, VCInternetProp ); | ||
587 | } | ||
588 | |||
589 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); | ||
590 | |||
591 | safeAddPropValue( vcard, VCBirthDateProp, c.birthday() ); | ||
592 | |||
593 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { | ||
594 | VObject *org = safeAddProp( vcard, VCOrgProp ); | ||
595 | safeAddPropValue( org, VCOrgNameProp, c.company() ); | ||
596 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); | ||
597 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); | ||
598 | } | ||
599 | |||
600 | // some values we have to export as custom fields | ||
601 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); | ||
602 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); | ||
603 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); | ||
604 | |||
605 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); | ||
606 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); | ||
607 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", c.anniversary() ); | ||
608 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); | ||
609 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); | ||
610 | |||
611 | return vcard; | ||
612 | } | ||
613 | |||
614 | |||
615 | static Contact parseVObject( VObject *obj ) | ||
616 | { | ||
617 | Contact c; | ||
618 | |||
619 | bool haveDefaultEmail = FALSE; | ||
620 | |||
621 | VObjectIterator it; | ||
622 | initPropIterator( &it, obj ); | ||
623 | while( moreIteration( &it ) ) { | ||
624 | VObject *o = nextVObject( &it ); | ||
625 | QCString name = vObjectName( o ); | ||
626 | QCString value = vObjectStringZValue( o ); | ||
627 | if ( name == VCNameProp ) { | ||
628 | VObjectIterator nit; | ||
629 | initPropIterator( &nit, o ); | ||
630 | while( moreIteration( &nit ) ) { | ||
631 | VObject *o = nextVObject( &nit ); | ||
632 | QCString name = vObjectName( o ); | ||
633 | QString value = vObjectStringZValue( o ); | ||
634 | if ( name == VCNamePrefixesProp ) | ||
635 | c.setTitle( value ); | ||
636 | else if ( name == VCNameSuffixesProp ) | ||
637 | c.setSuffix( value ); | ||
638 | else if ( name == VCFamilyNameProp ) | ||
639 | c.setLastName( value ); | ||
640 | else if ( name == VCGivenNameProp ) | ||
641 | c.setFirstName( value ); | ||
642 | else if ( name == VCAdditionalNamesProp ) | ||
643 | c.setMiddleName( value ); | ||
644 | } | ||
645 | } | ||
646 | else if ( name == VCAdrProp ) { | ||
647 | bool work = TRUE; // default address is work address | ||
648 | QString street; | ||
649 | QString city; | ||
650 | QString region; | ||
651 | QString postal; | ||
652 | QString country; | ||
653 | |||
654 | VObjectIterator nit; | ||
655 | initPropIterator( &nit, o ); | ||
656 | while( moreIteration( &nit ) ) { | ||
657 | VObject *o = nextVObject( &nit ); | ||
658 | QCString name = vObjectName( o ); | ||
659 | QString value = vObjectStringZValue( o ); | ||
660 | if ( name == VCHomeProp ) | ||
661 | work = FALSE; | ||
662 | else if ( name == VCWorkProp ) | ||
663 | work = TRUE; | ||
664 | else if ( name == VCStreetAddressProp ) | ||
665 | street = value; | ||
666 | else if ( name == VCCityProp ) | ||
667 | city = value; | ||
668 | else if ( name == VCRegionProp ) | ||
669 | region = value; | ||
670 | else if ( name == VCPostalCodeProp ) | ||
671 | postal = value; | ||
672 | else if ( name == VCCountryNameProp ) | ||
673 | country = value; | ||
674 | } | ||
675 | if ( work ) { | ||
676 | c.setBusinessStreet( street ); | ||
677 | c.setBusinessCity( city ); | ||
678 | c.setBusinessCountry( country ); | ||
679 | c.setBusinessZip( postal ); | ||
680 | c.setBusinessState( region ); | ||
681 | } else { | ||
682 | c.setHomeStreet( street ); | ||
683 | c.setHomeCity( city ); | ||
684 | c.setHomeCountry( country ); | ||
685 | c.setHomeZip( postal ); | ||
686 | c.setHomeState( region ); | ||
687 | } | ||
688 | } | ||
689 | else if ( name == VCTelephoneProp ) { | ||
690 | enum { | ||
691 | HOME = 0x01, | ||
692 | WORK = 0x02, | ||
693 | VOICE = 0x04, | ||
694 | CELL = 0x08, | ||
695 | FAX = 0x10, | ||
696 | PAGER = 0x20, | ||
697 | UNKNOWN = 0x80 | ||
698 | }; | ||
699 | int type = 0; | ||
700 | |||
701 | VObjectIterator nit; | ||
702 | initPropIterator( &nit, o ); | ||
703 | while( moreIteration( &nit ) ) { | ||
704 | VObject *o = nextVObject( &nit ); | ||
705 | QCString name = vObjectName( o ); | ||
706 | if ( name == VCHomeProp ) | ||
707 | type |= HOME; | ||
708 | else if ( name == VCWorkProp ) | ||
709 | type |= WORK; | ||
710 | else if ( name == VCVoiceProp ) | ||
711 | type |= VOICE; | ||
712 | else if ( name == VCCellularProp ) | ||
713 | type |= CELL; | ||
714 | else if ( name == VCFaxProp ) | ||
715 | type |= FAX; | ||
716 | else if ( name == VCPagerProp ) | ||
717 | type |= PAGER; | ||
718 | else if ( name == VCPreferredProp ) | ||
719 | ; | ||
720 | else | ||
721 | type |= UNKNOWN; | ||
722 | } | ||
723 | if ( (type & UNKNOWN) != UNKNOWN ) { | ||
724 | if ( ( type & (HOME|WORK) ) == 0 ) // default | ||
725 | type |= HOME; | ||
726 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default | ||
727 | type |= VOICE; | ||
728 | |||
729 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) | ||
730 | c.setHomePhone( value ); | ||
731 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) | ||
732 | c.setHomeFax( value ); | ||
733 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) | ||
734 | c.setHomeMobile( value ); | ||
735 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) | ||
736 | c.setBusinessPhone( value ); | ||
737 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) | ||
738 | c.setBusinessFax( value ); | ||
739 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) | ||
740 | c.setBusinessMobile( value ); | ||
741 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) | ||
742 | c.setBusinessPager( value ); | ||
743 | } | ||
744 | } | ||
745 | else if ( name == VCEmailAddressProp ) { | ||
746 | QString email = vObjectStringZValue( o ); | ||
747 | bool valid = TRUE; | ||
748 | VObjectIterator nit; | ||
749 | initPropIterator( &nit, o ); | ||
750 | while( moreIteration( &nit ) ) { | ||
751 | VObject *o = nextVObject( &nit ); | ||
752 | QCString name = vObjectName( o ); | ||
753 | if ( name != VCInternetProp && name != VCHomeProp && | ||
754 | name != VCWorkProp && | ||
755 | name != VCPreferredProp ) | ||
756 | // ### preffered should map to default email | ||
757 | valid = FALSE; | ||
758 | } | ||
759 | if ( valid ) { | ||
760 | if ( haveDefaultEmail ) { | ||
761 | QString str = c.emails(); | ||
762 | if ( !str.isEmpty() ) | ||
763 | str += ","+email; | ||
764 | c.setEmails( str ); | ||
765 | } else { | ||
766 | c.setDefaultEmail( email ); | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | else if ( name == VCURLProp ) { | ||
771 | VObjectIterator nit; | ||
772 | initPropIterator( &nit, o ); | ||
773 | while( moreIteration( &nit ) ) { | ||
774 | VObject *o = nextVObject( &nit ); | ||
775 | QCString name = vObjectName( o ); | ||
776 | if ( name == VCHomeProp ) | ||
777 | c.setHomeWebpage( value ); | ||
778 | else if ( name == VCWorkProp ) | ||
779 | c.setBusinessWebpage( value ); | ||
780 | } | ||
781 | } | ||
782 | else if ( name == VCOrgProp ) { | ||
783 | VObjectIterator nit; | ||
784 | initPropIterator( &nit, o ); | ||
785 | while( moreIteration( &nit ) ) { | ||
786 | VObject *o = nextVObject( &nit ); | ||
787 | QCString name = vObjectName( o ); | ||
788 | QString value = vObjectStringZValue( o ); | ||
789 | if ( name == VCOrgNameProp ) | ||
790 | c.setCompany( value ); | ||
791 | else if ( name == VCOrgUnitProp ) | ||
792 | c.setDepartment( value ); | ||
793 | else if ( name == VCOrgUnit2Prop ) | ||
794 | c.setOffice( value ); | ||
795 | } | ||
796 | } | ||
797 | else if ( name == VCTitleProp ) { | ||
798 | c.setJobTitle( value ); | ||
799 | } | ||
800 | else if ( name == "X-Qtopia-Profession" ) { | ||
801 | c.setProfession( value ); | ||
802 | } | ||
803 | else if ( name == "X-Qtopia-Manager" ) { | ||
804 | c.setManager( value ); | ||
805 | } | ||
806 | else if ( name == "X-Qtopia-Assistant" ) { | ||
807 | c.setAssistant( value ); | ||
808 | } | ||
809 | else if ( name == "X-Qtopia-Spouse" ) { | ||
810 | c.setSpouse( value ); | ||
811 | } | ||
812 | else if ( name == "X-Qtopia-Gender" ) { | ||
813 | c.setGender( value ); | ||
814 | } | ||
815 | else if ( name == "X-Qtopia-Anniversary" ) { | ||
816 | c.setAnniversary( value ); | ||
817 | } | ||
818 | else if ( name == "X-Qtopia-Nickname" ) { | ||
819 | c.setNickname( value ); | ||
820 | } | ||
821 | else if ( name == "X-Qtopia-Children" ) { | ||
822 | c.setChildren( value ); | ||
823 | } | ||
824 | |||
825 | |||
826 | #if 0 | ||
827 | else { | ||
828 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | ||
829 | VObjectIterator nit; | ||
830 | initPropIterator( &nit, o ); | ||
831 | while( moreIteration( &nit ) ) { | ||
832 | VObject *o = nextVObject( &nit ); | ||
833 | QCString name = vObjectName( o ); | ||
834 | QString value = vObjectStringZValue( o ); | ||
835 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | ||
836 | } | ||
837 | } | ||
838 | #endif | ||
839 | } | ||
840 | c.setFileAs(); | ||
841 | return c; | ||
842 | } | ||
843 | |||
844 | void Contact::writeVCard( const QString &filename, const QValueList<Contact> &contacts) | ||
845 | { | ||
846 | QFileDirect f( filename.utf8().data() ); | ||
847 | if ( !f.open( IO_WriteOnly ) ) { | ||
848 | qWarning("Unable to open vcard write"); | ||
849 | return; | ||
850 | } | ||
851 | |||
852 | QValueList<Contact>::ConstIterator it; | ||
853 | for( it = contacts.begin(); it != contacts.end(); ++it ) { | ||
854 | VObject *obj = createVObject( *it ); | ||
855 | writeVObject(f.directHandle() , obj ); | ||
856 | cleanVObject( obj ); | ||
857 | } | ||
858 | cleanStrTbl(); | ||
859 | } | ||
860 | |||
861 | void Contact::writeVCard( const QString &filename, const Contact &contact) | ||
862 | { | ||
863 | QFileDirect f( filename.utf8().data() ); | ||
864 | if ( !f.open( IO_WriteOnly ) ) { | ||
865 | qWarning("Unable to open vcard write"); | ||
866 | return; | ||
867 | } | ||
868 | |||
869 | VObject *obj = createVObject( contact ); | ||
870 | writeVObject( f.directHandle() , obj ); | ||
871 | cleanVObject( obj ); | ||
872 | |||
873 | cleanStrTbl(); | ||
874 | } | ||
875 | |||
876 | |||
877 | QValueList<Contact> Contact::readVCard( const QString &filename ) | ||
878 | { | ||
879 | qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() ); | ||
880 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | ||
881 | |||
882 | qDebug("vobject = %p", obj ); | ||
883 | |||
884 | QValueList<Contact> contacts; | ||
885 | |||
886 | while ( obj ) { | ||
887 | contacts.append( parseVObject( obj ) ); | ||
888 | |||
889 | VObject *t = obj; | ||
890 | obj = nextVObjectInList(obj); | ||
891 | cleanVObject( t ); | ||
892 | } | ||
893 | |||
894 | return contacts; | ||
895 | } | ||
896 | |||
897 | bool Contact::match( const QRegExp &r ) const | ||
898 | { | ||
899 | bool match; | ||
900 | match = false; | ||
901 | QMap<int, QString>::ConstIterator it; | ||
902 | for ( it = mMap.begin(); it != mMap.end(); ++it ) { | ||
903 | if ( (*it).find( r ) > -1 ) { | ||
904 | match = true; | ||
905 | break; | ||
906 | } | ||
907 | } | ||
908 | return match; | ||
909 | } | ||