-rw-r--r-- | libopie/pim/README_COMPILE | 11 | ||||
-rw-r--r-- | libopie/pim/libopie.pro | 11 | ||||
-rw-r--r-- | libopie/pim/ocontact.cpp | 1433 | ||||
-rw-r--r-- | libopie/pim/ocontact.h | 311 | ||||
-rw-r--r-- | libopie/pim/ocontactaccess.cpp | 174 | ||||
-rw-r--r-- | libopie/pim/ocontactaccess.h | 197 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend.h | 70 | ||||
-rw-r--r-- | libopie/pim/ocontactaccessbackend_xml.h | 550 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.h | 70 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.h | 550 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.cpp | 174 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.h | 197 | ||||
-rw-r--r-- | libopie2/opiepim/ocontact.cpp | 1433 | ||||
-rw-r--r-- | libopie2/opiepim/ocontact.h | 311 |
14 files changed, 5490 insertions, 2 deletions
diff --git a/libopie/pim/README_COMPILE b/libopie/pim/README_COMPILE new file mode 100644 index 0000000..d9f13ce --- a/dev/null +++ b/libopie/pim/README_COMPILE | |||
@@ -0,0 +1,11 @@ | |||
1 | To compile successfully ocontact there have to be the | ||
2 | following symbolic links created: | ||
3 | |||
4 | ln -s ../../library/backend/qfiledirect_p.h | ||
5 | ln -s ../../library/backend/vobject_p.h | ||
6 | |||
7 | |||
8 | This "dirty" solution will be fixed, soon ! | ||
9 | |||
10 | |||
11 | Bye, Stefan (Eilers.Stefan@epost.de) \ No newline at end of file | ||
diff --git a/libopie/pim/libopie.pro b/libopie/pim/libopie.pro index b17758a..1dacbe7 100644 --- a/libopie/pim/libopie.pro +++ b/libopie/pim/libopie.pro | |||
@@ -25,3 +25,8 @@ HEADERS = ofontmenu.h \ | |||
25 | pim/otodoaccess.h \ | 25 | pim/otodoaccess.h \ |
26 | pim/otodacessbackend.h | 26 | pim/otodacessbackend.h \ |
27 | pim/ocontact.h \ | ||
28 | pim/ocontactaccess.h \ | ||
29 | pim/ocontactaccessbackend.h \ | ||
30 | pim/ocontactaccessbackend_xml.h | ||
31 | |||
27 | SOURCES = ofontmenu.cc \ | 32 | SOURCES = ofontmenu.cc \ |
@@ -45,3 +50,5 @@ SOURCES = ofontmenu.cc \ | |||
45 | pim/otodoaccess.cpp \ | 50 | pim/otodoaccess.cpp \ |
46 | pim/otodoaccessbackend.cpp | 51 | pim/otodoaccessbackend.cpp \ |
52 | pim/ocontact.cpp \ | ||
53 | pim/ocontactaccess.cpp | ||
47 | 54 | ||
diff --git a/libopie/pim/ocontact.cpp b/libopie/pim/ocontact.cpp new file mode 100644 index 0000000..66632f5 --- a/dev/null +++ b/libopie/pim/ocontact.cpp | |||
@@ -0,0 +1,1433 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the 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 | #define QTOPIA_INTERNAL_CONTACT_MRE | ||
22 | |||
23 | #include "ocontact.h" | ||
24 | #include "vobject_p.h" | ||
25 | #include "qfiledirect_p.h" | ||
26 | |||
27 | #include <qpe/stringutil.h> | ||
28 | #include <qpe/timeconversion.h> | ||
29 | |||
30 | #include <qobject.h> | ||
31 | #include <qregexp.h> | ||
32 | #include <qstylesheet.h> | ||
33 | #include <qfileinfo.h> | ||
34 | #include <qmap.h> | ||
35 | |||
36 | #include <stdio.h> | ||
37 | |||
38 | /*! | ||
39 | \class Contact contact.h | ||
40 | \brief The Contact class holds the data of an address book entry. | ||
41 | |||
42 | This data includes information the name of the person, contact | ||
43 | information, and business information such as deparment and job title. | ||
44 | |||
45 | \ingroup qtopiaemb | ||
46 | \ingroup qtopiadesktop | ||
47 | */ | ||
48 | |||
49 | Qtopia::UidGen OContact::sUidGen( Qtopia::UidGen::Qtopia ); | ||
50 | |||
51 | /*! | ||
52 | Creates a new, empty contact. | ||
53 | */ | ||
54 | OContact::OContact() | ||
55 | : OPimRecord(), mMap(), d( 0 ) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | /*! | ||
60 | \internal | ||
61 | Creates a new contact. The properties of the contact are | ||
62 | set from \a fromMap. | ||
63 | */ | ||
64 | OContact::OContact( const QMap<int, QString> &fromMap ) : | ||
65 | OPimRecord(), mMap( fromMap ), d( 0 ) | ||
66 | { | ||
67 | QString cats = mMap[ Qtopia::AddressCategory ]; | ||
68 | if ( !cats.isEmpty() ) | ||
69 | setCategories( idsFromString( cats ) ); | ||
70 | QString uidStr = find( Qtopia::AddressUid ); | ||
71 | |||
72 | if ( uidStr.isEmpty() ) | ||
73 | setUid( uidGen().generate() ); | ||
74 | else | ||
75 | setUid( uidStr.toInt() ); | ||
76 | |||
77 | if ( !uidStr.isEmpty() ) | ||
78 | setUid( uidStr.toInt() ); | ||
79 | } | ||
80 | |||
81 | /*! | ||
82 | Destroys a contact. | ||
83 | */ | ||
84 | OContact::~OContact() | ||
85 | { | ||
86 | } | ||
87 | |||
88 | /*! \fn void OContact::setTitle( const QString &str ) | ||
89 | Sets the title of the contact to \a str. | ||
90 | */ | ||
91 | |||
92 | /*! \fn void OContact::setFirstName( const QString &str ) | ||
93 | Sets the first name of the contact to \a str. | ||
94 | */ | ||
95 | |||
96 | /*! \fn void OContact::setMiddleName( const QString &str ) | ||
97 | Sets the middle name of the contact to \a str. | ||
98 | */ | ||
99 | |||
100 | /*! \fn void OContact::setLastName( const QString &str ) | ||
101 | Sets the last name of the contact to \a str. | ||
102 | */ | ||
103 | |||
104 | /*! \fn void OContact::setSuffix( const QString &str ) | ||
105 | Sets the suffix of the contact to \a str. | ||
106 | */ | ||
107 | |||
108 | /*! \fn void OContact::setFileAs( const QString &str ) | ||
109 | Sets the contact to filed as \a str. | ||
110 | */ | ||
111 | |||
112 | /*! \fn void OContact::setDefaultEmail( const QString &str ) | ||
113 | Sets the default email of the contact to \a str. | ||
114 | */ | ||
115 | |||
116 | /*! \fn void OContact::setHomeStreet( const QString &str ) | ||
117 | Sets the home street address of the contact to \a str. | ||
118 | */ | ||
119 | |||
120 | /*! \fn void OContact::setHomeCity( const QString &str ) | ||
121 | Sets the home city of the contact to \a str. | ||
122 | */ | ||
123 | |||
124 | /*! \fn void OContact::setHomeState( const QString &str ) | ||
125 | Sets the home state of the contact to \a str. | ||
126 | */ | ||
127 | |||
128 | /*! \fn void OContact::setHomeZip( const QString &str ) | ||
129 | Sets the home zip code of the contact to \a str. | ||
130 | */ | ||
131 | |||
132 | /*! \fn void OContact::setHomeCountry( const QString &str ) | ||
133 | Sets the home country of the contact to \a str. | ||
134 | */ | ||
135 | |||
136 | /*! \fn void OContact::setHomePhone( const QString &str ) | ||
137 | Sets the home phone number of the contact to \a str. | ||
138 | */ | ||
139 | |||
140 | /*! \fn void OContact::setHomeFax( const QString &str ) | ||
141 | Sets the home fax number of the contact to \a str. | ||
142 | */ | ||
143 | |||
144 | /*! \fn void OContact::setHomeMobile( const QString &str ) | ||
145 | Sets the home mobile phone number of the contact to \a str. | ||
146 | */ | ||
147 | |||
148 | /*! \fn void OContact::setHomeWebpage( const QString &str ) | ||
149 | Sets the home webpage of the contact to \a str. | ||
150 | */ | ||
151 | |||
152 | /*! \fn void OContact::setCompany( const QString &str ) | ||
153 | Sets the company for contact to \a str. | ||
154 | */ | ||
155 | |||
156 | /*! \fn void OContact::setJobTitle( const QString &str ) | ||
157 | Sets the job title of the contact to \a str. | ||
158 | */ | ||
159 | |||
160 | /*! \fn void OContact::setDepartment( const QString &str ) | ||
161 | Sets the department for contact to \a str. | ||
162 | */ | ||
163 | |||
164 | /*! \fn void OContact::setOffice( const QString &str ) | ||
165 | Sets the office for contact to \a str. | ||
166 | */ | ||
167 | |||
168 | /*! \fn void OContact::setBusinessStreet( const QString &str ) | ||
169 | Sets the business street address of the contact to \a str. | ||
170 | */ | ||
171 | |||
172 | /*! \fn void OContact::setBusinessCity( const QString &str ) | ||
173 | Sets the business city of the contact to \a str. | ||
174 | */ | ||
175 | |||
176 | /*! \fn void OContact::setBusinessState( const QString &str ) | ||
177 | Sets the business state of the contact to \a str. | ||
178 | */ | ||
179 | |||
180 | /*! \fn void OContact::setBusinessZip( const QString &str ) | ||
181 | Sets the business zip code of the contact to \a str. | ||
182 | */ | ||
183 | |||
184 | /*! \fn void OContact::setBusinessCountry( const QString &str ) | ||
185 | Sets the business country of the contact to \a str. | ||
186 | */ | ||
187 | |||
188 | /*! \fn void OContact::setBusinessPhone( const QString &str ) | ||
189 | Sets the business phone number of the contact to \a str. | ||
190 | */ | ||
191 | |||
192 | /*! \fn void OContact::setBusinessFax( const QString &str ) | ||
193 | Sets the business fax number of the contact to \a str. | ||
194 | */ | ||
195 | |||
196 | /*! \fn void OContact::setBusinessMobile( const QString &str ) | ||
197 | Sets the business mobile phone number of the contact to \a str. | ||
198 | */ | ||
199 | |||
200 | /*! \fn void OContact::setBusinessPager( const QString &str ) | ||
201 | Sets the business pager number of the contact to \a str. | ||
202 | */ | ||
203 | |||
204 | /*! \fn void OContact::setBusinessWebpage( const QString &str ) | ||
205 | Sets the business webpage of the contact to \a str. | ||
206 | */ | ||
207 | |||
208 | /*! \fn void OContact::setProfession( const QString &str ) | ||
209 | Sets the profession of the contact to \a str. | ||
210 | */ | ||
211 | |||
212 | /*! \fn void OContact::setAssistant( const QString &str ) | ||
213 | Sets the assistant of the contact to \a str. | ||
214 | */ | ||
215 | |||
216 | /*! \fn void OContact::setManager( const QString &str ) | ||
217 | Sets the manager of the contact to \a str. | ||
218 | */ | ||
219 | |||
220 | /*! \fn void OContact::setSpouse( const QString &str ) | ||
221 | Sets the spouse of the contact to \a str. | ||
222 | */ | ||
223 | |||
224 | /*! \fn void OContact::setGender( const QString &str ) | ||
225 | Sets the gender of the contact to \a str. | ||
226 | */ | ||
227 | |||
228 | /*! \fn void OContact::setBirthday( const QString &str ) | ||
229 | Sets the birthday for the contact to \a str. | ||
230 | */ | ||
231 | |||
232 | /*! \fn void OContact::setAnniversary( const QString &str ) | ||
233 | Sets the anniversary of the contact to \a str. | ||
234 | */ | ||
235 | |||
236 | /*! \fn void OContact::setNickname( const QString &str ) | ||
237 | Sets the nickname of the contact to \a str. | ||
238 | */ | ||
239 | |||
240 | /*! \fn void OContact::setNotes( const QString &str ) | ||
241 | Sets the notes about the contact to \a str. | ||
242 | */ | ||
243 | |||
244 | /*! \fn QString OContact::title() const | ||
245 | Returns the title of the contact. | ||
246 | */ | ||
247 | |||
248 | /*! \fn QString OContact::firstName() const | ||
249 | Returns the first name of the contact. | ||
250 | */ | ||
251 | |||
252 | /*! \fn QString OContact::middleName() const | ||
253 | Returns the middle name of the contact. | ||
254 | */ | ||
255 | |||
256 | /*! \fn QString OContact::lastName() const | ||
257 | Returns the last name of the contact. | ||
258 | */ | ||
259 | |||
260 | /*! \fn QString OContact::suffix() const | ||
261 | Returns the suffix of the contact. | ||
262 | */ | ||
263 | |||
264 | /*! \fn QString OContact::fileAs() const | ||
265 | Returns the string the contact is filed as. | ||
266 | */ | ||
267 | |||
268 | /*! \fn QString OContact::defaultEmail() const | ||
269 | Returns the default email address of the contact. | ||
270 | */ | ||
271 | |||
272 | /*! \fn QString OContact::emails() const | ||
273 | Returns the list of email address for a contact separated by ';'s in a single | ||
274 | string. | ||
275 | */ | ||
276 | |||
277 | /*! \fn QString OContact::homeStreet() const | ||
278 | Returns the home street address of the contact. | ||
279 | */ | ||
280 | |||
281 | /*! \fn QString OContact::homeCity() const | ||
282 | Returns the home city of the contact. | ||
283 | */ | ||
284 | |||
285 | /*! \fn QString OContact::homeState() const | ||
286 | Returns the home state of the contact. | ||
287 | */ | ||
288 | |||
289 | /*! \fn QString OContact::homeZip() const | ||
290 | Returns the home zip of the contact. | ||
291 | */ | ||
292 | |||
293 | /*! \fn QString OContact::homeCountry() const | ||
294 | Returns the home country of the contact. | ||
295 | */ | ||
296 | |||
297 | /*! \fn QString OContact::homePhone() const | ||
298 | Returns the home phone number of the contact. | ||
299 | */ | ||
300 | |||
301 | /*! \fn QString OContact::homeFax() const | ||
302 | Returns the home fax number of the contact. | ||
303 | */ | ||
304 | |||
305 | /*! \fn QString OContact::homeMobile() const | ||
306 | Returns the home mobile number of the contact. | ||
307 | */ | ||
308 | |||
309 | /*! \fn QString OContact::homeWebpage() const | ||
310 | Returns the home webpage of the contact. | ||
311 | */ | ||
312 | |||
313 | /*! \fn QString OContact::company() const | ||
314 | Returns the company for the contact. | ||
315 | */ | ||
316 | |||
317 | /*! \fn QString OContact::department() const | ||
318 | Returns the department for the contact. | ||
319 | */ | ||
320 | |||
321 | /*! \fn QString OContact::office() const | ||
322 | Returns the office for the contact. | ||
323 | */ | ||
324 | |||
325 | /*! \fn QString OContact::jobTitle() const | ||
326 | Returns the job title of the contact. | ||
327 | */ | ||
328 | |||
329 | /*! \fn QString OContact::profession() const | ||
330 | Returns the profession of the contact. | ||
331 | */ | ||
332 | |||
333 | /*! \fn QString OContact::assistant() const | ||
334 | Returns the assistant of the contact. | ||
335 | */ | ||
336 | |||
337 | /*! \fn QString OContact::manager() const | ||
338 | Returns the manager of the contact. | ||
339 | */ | ||
340 | |||
341 | /*! \fn QString OContact::businessStreet() const | ||
342 | Returns the business street address of the contact. | ||
343 | */ | ||
344 | |||
345 | /*! \fn QString OContact::businessCity() const | ||
346 | Returns the business city of the contact. | ||
347 | */ | ||
348 | |||
349 | /*! \fn QString OContact::businessState() const | ||
350 | Returns the business state of the contact. | ||
351 | */ | ||
352 | |||
353 | /*! \fn QString OContact::businessZip() const | ||
354 | Returns the business zip of the contact. | ||
355 | */ | ||
356 | |||
357 | /*! \fn QString OContact::businessCountry() const | ||
358 | Returns the business country of the contact. | ||
359 | */ | ||
360 | |||
361 | /*! \fn QString OContact::businessPhone() const | ||
362 | Returns the business phone number of the contact. | ||
363 | */ | ||
364 | |||
365 | /*! \fn QString OContact::businessFax() const | ||
366 | Returns the business fax number of the contact. | ||
367 | */ | ||
368 | |||
369 | /*! \fn QString OContact::businessMobile() const | ||
370 | Returns the business mobile number of the contact. | ||
371 | */ | ||
372 | |||
373 | /*! \fn QString OContact::businessPager() const | ||
374 | Returns the business pager number of the contact. | ||
375 | */ | ||
376 | |||
377 | /*! \fn QString OContact::businessWebpage() const | ||
378 | Returns the business webpage of the contact. | ||
379 | */ | ||
380 | |||
381 | /*! \fn QString OContact::spouse() const | ||
382 | Returns the spouse of the contact. | ||
383 | */ | ||
384 | |||
385 | /*! \fn QString OContact::gender() const | ||
386 | Returns the gender of the contact. | ||
387 | */ | ||
388 | |||
389 | /*! \fn QString OContact::birthday() const | ||
390 | Returns the birthday of the contact. | ||
391 | */ | ||
392 | |||
393 | /*! \fn QString OContact::anniversary() const | ||
394 | Returns the anniversary of the contact. | ||
395 | */ | ||
396 | |||
397 | /*! \fn QString OContact::nickname() const | ||
398 | Returns the nickname of the contact. | ||
399 | */ | ||
400 | |||
401 | /*! \fn QString OContact::children() const | ||
402 | Returns the children of the contact. | ||
403 | */ | ||
404 | |||
405 | /*! \fn QString OContact::notes() const | ||
406 | Returns the notes relating to the the contact. | ||
407 | */ | ||
408 | |||
409 | /*! \fn QString OContact::groups() const | ||
410 | \internal | ||
411 | Returns the groups for the contact. | ||
412 | */ | ||
413 | |||
414 | /*! \fn QStringList OContact::groupList() const | ||
415 | \internal | ||
416 | */ | ||
417 | |||
418 | /*! \fn QString OContact::field(int) const | ||
419 | \internal | ||
420 | */ | ||
421 | |||
422 | /*! \fn void OContact::saveJournal( journal_action, const QString & = QString::null ) | ||
423 | \internal | ||
424 | */ | ||
425 | |||
426 | /*! \fn void OContact::setUid( int id ) | ||
427 | \internal | ||
428 | Sets the uid for this record to \a id. | ||
429 | */ | ||
430 | |||
431 | /*! \enum OContact::journal_action | ||
432 | \internal | ||
433 | */ | ||
434 | |||
435 | /*! | ||
436 | \internal | ||
437 | */ | ||
438 | QMap<int, QString> OContact::toMap() const | ||
439 | { | ||
440 | QMap<int, QString> map = mMap; | ||
441 | QString cats = idsToString( categories() ); | ||
442 | if ( !cats.isEmpty() ) | ||
443 | map.insert( Qtopia::AddressCategory, cats ); | ||
444 | return map; | ||
445 | } | ||
446 | |||
447 | /*! | ||
448 | Returns a rich text formatted QString representing the contents the contact. | ||
449 | */ | ||
450 | QString OContact::toRichText() const | ||
451 | { | ||
452 | QString text; | ||
453 | QString value, comp, state; | ||
454 | |||
455 | // name, jobtitle and company | ||
456 | if ( !(value = fullName()).isEmpty() ) | ||
457 | text += "<b>" + Qtopia::escapeString(value) + "</b><br>"; | ||
458 | if ( !(value = jobTitle()).isEmpty() ) | ||
459 | text += Qtopia::escapeString(value) + "<br>"; | ||
460 | |||
461 | comp = company(); | ||
462 | if ( !(value = department()).isEmpty() ) { | ||
463 | text += Qtopia::escapeString(value); | ||
464 | if ( comp ) | ||
465 | text += ", "; | ||
466 | else | ||
467 | text += "<br>"; | ||
468 | } | ||
469 | if ( !comp.isEmpty() ) | ||
470 | text += Qtopia::escapeString(comp) + "<br>"; | ||
471 | |||
472 | // business address | ||
473 | if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || | ||
474 | !businessZip().isEmpty() || !businessCountry().isEmpty() ) { | ||
475 | text += "<br>"; | ||
476 | text += QObject::tr( "<b>Work Address:</b>" ); | ||
477 | text += "<br>"; | ||
478 | } | ||
479 | |||
480 | if ( !(value = businessStreet()).isEmpty() ) | ||
481 | text += Qtopia::escapeString(value) + "<br>"; | ||
482 | state = businessState(); | ||
483 | if ( !(value = businessCity()).isEmpty() ) { | ||
484 | text += Qtopia::escapeString(value); | ||
485 | if ( state ) | ||
486 | text += ", " + Qtopia::escapeString(state); | ||
487 | text += "<br>"; | ||
488 | } else if ( !state.isEmpty() ) | ||
489 | text += Qtopia::escapeString(state) + "<br>"; | ||
490 | if ( !(value = businessZip()).isEmpty() ) | ||
491 | text += Qtopia::escapeString(value) + "<br>"; | ||
492 | if ( !(value = businessCountry()).isEmpty() ) | ||
493 | text += Qtopia::escapeString(value) + "<br>"; | ||
494 | |||
495 | // home address | ||
496 | if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || | ||
497 | !homeZip().isEmpty() || !homeCountry().isEmpty() ) { | ||
498 | text += "<br>"; | ||
499 | text += QObject::tr( "<b>Home Address:</b>" ); | ||
500 | text += "<br>"; | ||
501 | } | ||
502 | |||
503 | if ( !(value = homeStreet()).isEmpty() ) | ||
504 | text += Qtopia::escapeString(value) + "<br>"; | ||
505 | state = homeState(); | ||
506 | if ( !(value = homeCity()).isEmpty() ) { | ||
507 | text += Qtopia::escapeString(value); | ||
508 | if ( !state.isEmpty() ) | ||
509 | text += ", " + Qtopia::escapeString(state); | ||
510 | text += "<br>"; | ||
511 | } else if (!state.isEmpty()) | ||
512 | text += Qtopia::escapeString(state) + "<br>"; | ||
513 | if ( !(value = homeZip()).isEmpty() ) | ||
514 | text += Qtopia::escapeString(value) + "<br>"; | ||
515 | if ( !(value = homeCountry()).isEmpty() ) | ||
516 | text += Qtopia::escapeString(value) + "<br>"; | ||
517 | |||
518 | // the others... | ||
519 | QString str; | ||
520 | str = emails(); | ||
521 | if ( !str.isEmpty() ) | ||
522 | text += "<b>" + QObject::tr("Email Addresses: ") + "</b>" | ||
523 | + Qtopia::escapeString(str) + "<br>"; | ||
524 | str = homePhone(); | ||
525 | if ( !str.isEmpty() ) | ||
526 | text += "<b>" + QObject::tr("Home Phone: ") + "</b>" | ||
527 | + Qtopia::escapeString(str) + "<br>"; | ||
528 | str = homeFax(); | ||
529 | if ( !str.isEmpty() ) | ||
530 | text += "<b>" + QObject::tr("Home Fax: ") + "</b>" | ||
531 | + Qtopia::escapeString(str) + "<br>"; | ||
532 | str = homeMobile(); | ||
533 | if ( !str.isEmpty() ) | ||
534 | text += "<b>" + QObject::tr("Home Mobile: ") + "</b>" | ||
535 | + Qtopia::escapeString(str) + "<br>"; | ||
536 | str = homeWebpage(); | ||
537 | if ( !str.isEmpty() ) | ||
538 | text += "<b>" + QObject::tr("Home Web Page: ") + "</b>" | ||
539 | + Qtopia::escapeString(str) + "<br>"; | ||
540 | str = businessWebpage(); | ||
541 | if ( !str.isEmpty() ) | ||
542 | text += "<b>" + QObject::tr("Business Web Page: ") + "</b>" | ||
543 | + Qtopia::escapeString(str) + "<br>"; | ||
544 | str = office(); | ||
545 | if ( !str.isEmpty() ) | ||
546 | text += "<b>" + QObject::tr("Office: ") + "</b>" | ||
547 | + Qtopia::escapeString(str) + "<br>"; | ||
548 | str = businessPhone(); | ||
549 | if ( !str.isEmpty() ) | ||
550 | text += "<b>" + QObject::tr("Business Phone: ") + "</b>" | ||
551 | + Qtopia::escapeString(str) + "<br>"; | ||
552 | str = businessFax(); | ||
553 | if ( !str.isEmpty() ) | ||
554 | text += "<b>" + QObject::tr("Business Fax: ") + "</b>" | ||
555 | + Qtopia::escapeString(str) + "<br>"; | ||
556 | str = businessMobile(); | ||
557 | if ( !str.isEmpty() ) | ||
558 | text += "<b>" + QObject::tr("Business Mobile: ") + "</b>" | ||
559 | + Qtopia::escapeString(str) + "<br>"; | ||
560 | str = businessPager(); | ||
561 | if ( !str.isEmpty() ) | ||
562 | text += "<b>" + QObject::tr("Business Pager: ") + "</b>" | ||
563 | + Qtopia::escapeString(str) + "<br>"; | ||
564 | str = profession(); | ||
565 | if ( !str.isEmpty() ) | ||
566 | text += "<b>" + QObject::tr("Profession: ") + "</b>" | ||
567 | + Qtopia::escapeString(str) + "<br>"; | ||
568 | str = assistant(); | ||
569 | if ( !str.isEmpty() ) | ||
570 | text += "<b>" + QObject::tr("Assistant: ") + "</b>" | ||
571 | + Qtopia::escapeString(str) + "<br>"; | ||
572 | str = manager(); | ||
573 | if ( !str.isEmpty() ) | ||
574 | text += "<b>" + QObject::tr("Manager: ") + "</b>" | ||
575 | + Qtopia::escapeString(str) + "<br>"; | ||
576 | str = gender(); | ||
577 | if ( !str.isEmpty() && str.toInt() != 0 ) { | ||
578 | if ( str.toInt() == 1 ) | ||
579 | str = QObject::tr( "Male" ); | ||
580 | else if ( str.toInt() == 2 ) | ||
581 | str = QObject::tr( "Female" ); | ||
582 | text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; | ||
583 | } | ||
584 | str = spouse(); | ||
585 | if ( !str.isEmpty() ) | ||
586 | text += "<b>" + QObject::tr("Spouse: ") + "</b>" | ||
587 | + Qtopia::escapeString(str) + "<br>"; | ||
588 | str = birthday(); | ||
589 | if ( !str.isEmpty() ) | ||
590 | text += "<b>" + QObject::tr("Birthday: ") + "</b>" | ||
591 | + Qtopia::escapeString(str) + "<br>"; | ||
592 | str = anniversary(); | ||
593 | if ( !str.isEmpty() ) | ||
594 | text += "<b>" + QObject::tr("Anniversary: ") + "</b>" | ||
595 | + Qtopia::escapeString(str) + "<br>"; | ||
596 | str = nickname(); | ||
597 | if ( !str.isEmpty() ) | ||
598 | text += "<b>" + QObject::tr("Nickname: ") + "</b>" | ||
599 | + Qtopia::escapeString(str) + "<br>"; | ||
600 | |||
601 | // notes last | ||
602 | if ( (value = notes()) ) { | ||
603 | QRegExp reg("\n"); | ||
604 | |||
605 | //QString tmp = Qtopia::escapeString(value); | ||
606 | QString tmp = QStyleSheet::convertFromPlainText(value); | ||
607 | //tmp.replace( reg, "<br>" ); | ||
608 | text += "<br>" + tmp + "<br>"; | ||
609 | } | ||
610 | return text; | ||
611 | } | ||
612 | |||
613 | /*! | ||
614 | \internal | ||
615 | */ | ||
616 | void OContact::insert( int key, const QString &v ) | ||
617 | { | ||
618 | QString value = v.stripWhiteSpace(); | ||
619 | if ( value.isEmpty() ) | ||
620 | mMap.remove( key ); | ||
621 | else | ||
622 | mMap.insert( key, value ); | ||
623 | } | ||
624 | |||
625 | /*! | ||
626 | \internal | ||
627 | */ | ||
628 | void OContact::replace( int key, const QString & v ) | ||
629 | { | ||
630 | QString value = v.stripWhiteSpace(); | ||
631 | if ( value.isEmpty() ) | ||
632 | mMap.remove( key ); | ||
633 | else | ||
634 | mMap.replace( key, value ); | ||
635 | } | ||
636 | |||
637 | /*! | ||
638 | \internal | ||
639 | */ | ||
640 | QString OContact::find( int key ) const | ||
641 | { | ||
642 | return mMap[key]; | ||
643 | } | ||
644 | |||
645 | /*! | ||
646 | \internal | ||
647 | */ | ||
648 | QString OContact::displayAddress( const QString &street, | ||
649 | const QString &city, | ||
650 | const QString &state, | ||
651 | const QString &zip, | ||
652 | const QString &country ) const | ||
653 | { | ||
654 | QString s = street; | ||
655 | if ( !street.isEmpty() ) | ||
656 | s+= "\n"; | ||
657 | s += city; | ||
658 | if ( !city.isEmpty() && !state.isEmpty() ) | ||
659 | s += ", "; | ||
660 | s += state; | ||
661 | if ( !state.isEmpty() && !zip.isEmpty() ) | ||
662 | s += " "; | ||
663 | s += zip; | ||
664 | if ( !country.isEmpty() && !s.isEmpty() ) | ||
665 | s += "\n"; | ||
666 | s += country; | ||
667 | return s; | ||
668 | } | ||
669 | |||
670 | /*! | ||
671 | \internal | ||
672 | */ | ||
673 | QString OContact::displayBusinessAddress() const | ||
674 | { | ||
675 | return displayAddress( businessStreet(), businessCity(), | ||
676 | businessState(), businessZip(), | ||
677 | businessCountry() ); | ||
678 | } | ||
679 | |||
680 | /*! | ||
681 | \internal | ||
682 | */ | ||
683 | QString OContact::displayHomeAddress() const | ||
684 | { | ||
685 | return displayAddress( homeStreet(), homeCity(), | ||
686 | homeState(), homeZip(), | ||
687 | homeCountry() ); | ||
688 | } | ||
689 | |||
690 | /*! | ||
691 | Returns the full name of the contact | ||
692 | */ | ||
693 | QString OContact::fullName() const | ||
694 | { | ||
695 | QString title = find( Qtopia::Title ); | ||
696 | QString firstName = find( Qtopia::FirstName ); | ||
697 | QString middleName = find( Qtopia::MiddleName ); | ||
698 | QString lastName = find( Qtopia::LastName ); | ||
699 | QString suffix = find( Qtopia::Suffix ); | ||
700 | |||
701 | QString name = title; | ||
702 | if ( !firstName.isEmpty() ) { | ||
703 | if ( !name.isEmpty() ) | ||
704 | name += " "; | ||
705 | name += firstName; | ||
706 | } | ||
707 | if ( !middleName.isEmpty() ) { | ||
708 | if ( !name.isEmpty() ) | ||
709 | name += " "; | ||
710 | name += middleName; | ||
711 | } | ||
712 | if ( !lastName.isEmpty() ) { | ||
713 | if ( !name.isEmpty() ) | ||
714 | name += " "; | ||
715 | name += lastName; | ||
716 | } | ||
717 | if ( !suffix.isEmpty() ) { | ||
718 | if ( !name.isEmpty() ) | ||
719 | name += " "; | ||
720 | name += suffix; | ||
721 | } | ||
722 | return name.simplifyWhiteSpace(); | ||
723 | } | ||
724 | |||
725 | /*! | ||
726 | Returns a list of the names of the children of the contact. | ||
727 | */ | ||
728 | QStringList OContact::childrenList() const | ||
729 | { | ||
730 | return QStringList::split( " ", find( Qtopia::Children ) ); | ||
731 | } | ||
732 | |||
733 | /*! \fn void OContact::insertEmail( const QString &email ) | ||
734 | |||
735 | Insert \a email into the email list. Ensures \a email can only be added | ||
736 | once. If there is no default email address set, it sets it to the \a email. | ||
737 | */ | ||
738 | |||
739 | /*! \fn void OContact::removeEmail( const QString &email ) | ||
740 | |||
741 | Removes the \a email from the email list. If the default email was \a email, | ||
742 | then the default email address is assigned to the first email in the | ||
743 | email list | ||
744 | */ | ||
745 | |||
746 | /*! \fn void OContact::clearEmails() | ||
747 | |||
748 | Clears the email list. | ||
749 | */ | ||
750 | |||
751 | /*! \fn void OContact::insertEmails( const QStringList &emailList ) | ||
752 | |||
753 | Appends the \a emailList to the exiting email list | ||
754 | */ | ||
755 | |||
756 | /*! | ||
757 | Returns a list of email addresses belonging to the contact, including | ||
758 | the default email address. | ||
759 | */ | ||
760 | QStringList OContact::emailList() const | ||
761 | { | ||
762 | QString emailStr = emails(); | ||
763 | |||
764 | QStringList r; | ||
765 | if ( !emailStr.isEmpty() ) { | ||
766 | qDebug(" emailstr "); | ||
767 | QStringList l = QStringList::split( emailSeparator(), emailStr ); | ||
768 | for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) | ||
769 | r += (*it).simplifyWhiteSpace(); | ||
770 | } | ||
771 | |||
772 | return r; | ||
773 | } | ||
774 | |||
775 | /*! | ||
776 | \overload | ||
777 | |||
778 | Generates the string for the contact to be filed as from the first, | ||
779 | middle and last name of the contact. | ||
780 | */ | ||
781 | void OContact::setFileAs() | ||
782 | { | ||
783 | QString lastName, firstName, middleName, fileas; | ||
784 | |||
785 | lastName = find( Qtopia::LastName ); | ||
786 | firstName = find( Qtopia::FirstName ); | ||
787 | middleName = find( Qtopia::MiddleName ); | ||
788 | if ( !lastName.isEmpty() && !firstName.isEmpty() | ||
789 | && !middleName.isEmpty() ) | ||
790 | fileas = lastName + ", " + firstName + " " + middleName; | ||
791 | else if ( !lastName.isEmpty() && !firstName.isEmpty() ) | ||
792 | fileas = lastName + ", " + firstName; | ||
793 | else if ( !lastName.isEmpty() || !firstName.isEmpty() || | ||
794 | !middleName.isEmpty() ) | ||
795 | fileas = firstName + ( firstName.isEmpty() ? "" : " " ) | ||
796 | + middleName + ( middleName.isEmpty() ? "" : " " ) | ||
797 | + lastName; | ||
798 | |||
799 | replace( Qtopia::FileAs, fileas ); | ||
800 | } | ||
801 | |||
802 | /*! | ||
803 | \internal | ||
804 | Appends the contact information to \a buf. | ||
805 | */ | ||
806 | void OContact::save( QString &buf ) const | ||
807 | { | ||
808 | static const QStringList SLFIELDS = fields(); | ||
809 | // I'm expecting "<Contact " in front of this... | ||
810 | for ( QMap<int, QString>::ConstIterator it = mMap.begin(); | ||
811 | it != mMap.end(); ++it ) { | ||
812 | const QString &value = it.data(); | ||
813 | int key = it.key(); | ||
814 | if ( !value.isEmpty() ) { | ||
815 | if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) | ||
816 | continue; | ||
817 | |||
818 | key -= Qtopia::AddressCategory+1; | ||
819 | buf += SLFIELDS[key]; | ||
820 | buf += "=\"" + Qtopia::escapeString(value) + "\" "; | ||
821 | } | ||
822 | } | ||
823 | buf += customToXml(); | ||
824 | if ( categories().count() > 0 ) | ||
825 | buf += "Categories=\"" + idsToString( categories() ) + "\" "; | ||
826 | buf += "Uid=\"" + QString::number( uid() ) + "\" "; | ||
827 | // You need to close this yourself | ||
828 | } | ||
829 | |||
830 | /*! | ||
831 | \internal | ||
832 | Returns the list of fields belonging to a contact | ||
833 | */ | ||
834 | QStringList OContact::fields() | ||
835 | { | ||
836 | QStringList list; | ||
837 | |||
838 | list.append( "Title" ); // Not Used! | ||
839 | list.append( "FirstName" ); | ||
840 | list.append( "MiddleName" ); | ||
841 | list.append( "LastName" ); | ||
842 | list.append( "Suffix" ); | ||
843 | list.append( "FileAs" ); | ||
844 | |||
845 | list.append( "JobTitle" ); | ||
846 | list.append( "Department" ); | ||
847 | list.append( "Company" ); | ||
848 | list.append( "BusinessPhone" ); | ||
849 | list.append( "BusinessFax" ); | ||
850 | list.append( "BusinessMobile" ); | ||
851 | |||
852 | list.append( "DefaultEmail" ); | ||
853 | list.append( "Emails" ); | ||
854 | |||
855 | list.append( "HomePhone" ); | ||
856 | list.append( "HomeFax" ); | ||
857 | list.append( "HomeMobile" ); | ||
858 | |||
859 | list.append( "BusinessStreet" ); | ||
860 | list.append( "BusinessCity" ); | ||
861 | list.append( "BusinessState" ); | ||
862 | list.append( "BusinessZip" ); | ||
863 | list.append( "BusinessCountry" ); | ||
864 | list.append( "BusinessPager" ); | ||
865 | list.append( "BusinessWebPage" ); | ||
866 | |||
867 | list.append( "Office" ); | ||
868 | list.append( "Profession" ); | ||
869 | list.append( "Assistant" ); | ||
870 | list.append( "Manager" ); | ||
871 | |||
872 | list.append( "HomeStreet" ); | ||
873 | list.append( "HomeCity" ); | ||
874 | list.append( "HomeState" ); | ||
875 | list.append( "HomeZip" ); | ||
876 | list.append( "HomeCountry" ); | ||
877 | list.append( "HomeWebPage" ); | ||
878 | |||
879 | list.append( "Spouse" ); | ||
880 | list.append( "Gender" ); | ||
881 | list.append( "Birthday" ); | ||
882 | list.append( "Anniversary" ); | ||
883 | list.append( "Nickname" ); | ||
884 | list.append( "Children" ); | ||
885 | |||
886 | list.append( "Notes" ); | ||
887 | list.append( "Groups" ); | ||
888 | |||
889 | return list; | ||
890 | } | ||
891 | |||
892 | /*! | ||
893 | \internal | ||
894 | Returns a translated list of field names for a contact. | ||
895 | */ | ||
896 | QStringList OContact::trfields() | ||
897 | { | ||
898 | QStringList list; | ||
899 | |||
900 | list.append( QObject::tr( "Name Title") ); | ||
901 | list.append( QObject::tr( "First Name" ) ); | ||
902 | list.append( QObject::tr( "Middle Name" ) ); | ||
903 | list.append( QObject::tr( "Last Name" ) ); | ||
904 | list.append( QObject::tr( "Suffix" ) ); | ||
905 | list.append( QObject::tr( "File As" ) ); | ||
906 | |||
907 | list.append( QObject::tr( "Job Title" ) ); | ||
908 | list.append( QObject::tr( "Department" ) ); | ||
909 | list.append( QObject::tr( "Company" ) ); | ||
910 | list.append( QObject::tr( "Business Phone" ) ); | ||
911 | list.append( QObject::tr( "Business Fax" ) ); | ||
912 | list.append( QObject::tr( "Business Mobile" ) ); | ||
913 | |||
914 | list.append( QObject::tr( "Default Email" ) ); | ||
915 | list.append( QObject::tr( "Emails" ) ); | ||
916 | |||
917 | list.append( QObject::tr( "Home Phone" ) ); | ||
918 | list.append( QObject::tr( "Home Fax" ) ); | ||
919 | list.append( QObject::tr( "Home Mobile" ) ); | ||
920 | |||
921 | list.append( QObject::tr( "Business Street" ) ); | ||
922 | list.append( QObject::tr( "Business City" ) ); | ||
923 | list.append( QObject::tr( "Business State" ) ); | ||
924 | list.append( QObject::tr( "Business Zip" ) ); | ||
925 | list.append( QObject::tr( "Business Country" ) ); | ||
926 | list.append( QObject::tr( "Business Pager" ) ); | ||
927 | list.append( QObject::tr( "Business WebPage" ) ); | ||
928 | |||
929 | list.append( QObject::tr( "Office" ) ); | ||
930 | list.append( QObject::tr( "Profession" ) ); | ||
931 | list.append( QObject::tr( "Assistant" ) ); | ||
932 | list.append( QObject::tr( "Manager" ) ); | ||
933 | |||
934 | list.append( QObject::tr( "Home Street" ) ); | ||
935 | list.append( QObject::tr( "Home City" ) ); | ||
936 | list.append( QObject::tr( "Home State" ) ); | ||
937 | list.append( QObject::tr( "Home Zip" ) ); | ||
938 | list.append( QObject::tr( "Home Country" ) ); | ||
939 | list.append( QObject::tr( "Home Web Page" ) ); | ||
940 | |||
941 | list.append( QObject::tr( "Spouse" ) ); | ||
942 | list.append( QObject::tr( "Gender" ) ); | ||
943 | list.append( QObject::tr( "Birthday" ) ); | ||
944 | list.append( QObject::tr( "Anniversary" ) ); | ||
945 | list.append( QObject::tr( "Nickname" ) ); | ||
946 | list.append( QObject::tr( "Children" ) ); | ||
947 | |||
948 | list.append( QObject::tr( "Notes" ) ); | ||
949 | list.append( QObject::tr( "Groups" ) ); | ||
950 | |||
951 | return list; | ||
952 | } | ||
953 | |||
954 | /*! | ||
955 | Sets the list of email address for contact to those contained in \a str. | ||
956 | Email address should be separated by ';'s. | ||
957 | */ | ||
958 | void OContact::setEmails( const QString &str ) | ||
959 | { | ||
960 | replace( Qtopia::Emails, str ); | ||
961 | if ( str.isEmpty() ) | ||
962 | setDefaultEmail( QString::null ); | ||
963 | } | ||
964 | |||
965 | /*! | ||
966 | Sets the list of children for the contact to those contained in \a str. | ||
967 | */ | ||
968 | void OContact::setChildren( const QString &str ) | ||
969 | { | ||
970 | replace( Qtopia::Children, str ); | ||
971 | } | ||
972 | |||
973 | // vcard conversion code | ||
974 | /*! | ||
975 | \internal | ||
976 | */ | ||
977 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | ||
978 | { | ||
979 | VObject *ret = 0; | ||
980 | if ( o && !value.isEmpty() ) | ||
981 | ret = addPropValue( o, prop, value.latin1() ); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | /*! | ||
986 | \internal | ||
987 | */ | ||
988 | static inline VObject *safeAddProp( VObject *o, const char *prop) | ||
989 | { | ||
990 | VObject *ret = 0; | ||
991 | if ( o ) | ||
992 | ret = addProp( o, prop ); | ||
993 | return ret; | ||
994 | } | ||
995 | |||
996 | /*! | ||
997 | \internal | ||
998 | */ | ||
999 | static VObject *createVObject( const OContact &c ) | ||
1000 | { | ||
1001 | VObject *vcard = newVObject( VCCardProp ); | ||
1002 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); | ||
1003 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); | ||
1004 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); | ||
1005 | |||
1006 | // full name | ||
1007 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); | ||
1008 | |||
1009 | // name properties | ||
1010 | VObject *name = safeAddProp( vcard, VCNameProp ); | ||
1011 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); | ||
1012 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); | ||
1013 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); | ||
1014 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); | ||
1015 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); | ||
1016 | |||
1017 | // home properties | ||
1018 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); | ||
1019 | safeAddProp( home_adr, VCHomeProp ); | ||
1020 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); | ||
1021 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); | ||
1022 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); | ||
1023 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); | ||
1024 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); | ||
1025 | |||
1026 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); | ||
1027 | safeAddProp( home_phone, VCHomeProp ); | ||
1028 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); | ||
1029 | safeAddProp( home_phone, VCHomeProp ); | ||
1030 | safeAddProp( home_phone, VCCellularProp ); | ||
1031 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); | ||
1032 | safeAddProp( home_phone, VCHomeProp ); | ||
1033 | safeAddProp( home_phone, VCFaxProp ); | ||
1034 | |||
1035 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); | ||
1036 | safeAddProp( url, VCHomeProp ); | ||
1037 | |||
1038 | // work properties | ||
1039 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); | ||
1040 | safeAddProp( work_adr, VCWorkProp ); | ||
1041 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); | ||
1042 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); | ||
1043 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); | ||
1044 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); | ||
1045 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); | ||
1046 | |||
1047 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); | ||
1048 | safeAddProp( work_phone, VCWorkProp ); | ||
1049 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); | ||
1050 | safeAddProp( work_phone, VCWorkProp ); | ||
1051 | safeAddProp( work_phone, VCCellularProp ); | ||
1052 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); | ||
1053 | safeAddProp( work_phone, VCWorkProp ); | ||
1054 | safeAddProp( work_phone, VCFaxProp ); | ||
1055 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); | ||
1056 | safeAddProp( work_phone, VCWorkProp ); | ||
1057 | safeAddProp( work_phone, VCPagerProp ); | ||
1058 | |||
1059 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); | ||
1060 | safeAddProp( url, VCWorkProp ); | ||
1061 | |||
1062 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); | ||
1063 | safeAddProp( title, VCWorkProp ); | ||
1064 | |||
1065 | |||
1066 | QStringList emails = c.emailList(); | ||
1067 | emails.prepend( c.defaultEmail() ); | ||
1068 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { | ||
1069 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); | ||
1070 | safeAddProp( email, VCInternetProp ); | ||
1071 | } | ||
1072 | |||
1073 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); | ||
1074 | |||
1075 | safeAddPropValue( vcard, VCBirthDateProp, c.birthday() ); | ||
1076 | |||
1077 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { | ||
1078 | VObject *org = safeAddProp( vcard, VCOrgProp ); | ||
1079 | safeAddPropValue( org, VCOrgNameProp, c.company() ); | ||
1080 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); | ||
1081 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); | ||
1082 | } | ||
1083 | |||
1084 | // some values we have to export as custom fields | ||
1085 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); | ||
1086 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); | ||
1087 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); | ||
1088 | |||
1089 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); | ||
1090 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); | ||
1091 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", c.anniversary() ); | ||
1092 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); | ||
1093 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); | ||
1094 | |||
1095 | return vcard; | ||
1096 | } | ||
1097 | |||
1098 | |||
1099 | /*! | ||
1100 | \internal | ||
1101 | */ | ||
1102 | static OContact parseVObject( VObject *obj ) | ||
1103 | { | ||
1104 | OContact c; | ||
1105 | |||
1106 | VObjectIterator it; | ||
1107 | initPropIterator( &it, obj ); | ||
1108 | while( moreIteration( &it ) ) { | ||
1109 | VObject *o = nextVObject( &it ); | ||
1110 | QCString name = vObjectName( o ); | ||
1111 | QCString value = vObjectStringZValue( o ); | ||
1112 | if ( name == VCNameProp ) { | ||
1113 | VObjectIterator nit; | ||
1114 | initPropIterator( &nit, o ); | ||
1115 | while( moreIteration( &nit ) ) { | ||
1116 | VObject *o = nextVObject( &nit ); | ||
1117 | QCString name = vObjectTypeInfo( o ); | ||
1118 | QString value = vObjectStringZValue( o ); | ||
1119 | if ( name == VCNamePrefixesProp ) | ||
1120 | c.setTitle( value ); | ||
1121 | else if ( name == VCNameSuffixesProp ) | ||
1122 | c.setSuffix( value ); | ||
1123 | else if ( name == VCFamilyNameProp ) | ||
1124 | c.setLastName( value ); | ||
1125 | else if ( name == VCGivenNameProp ) | ||
1126 | c.setFirstName( value ); | ||
1127 | else if ( name == VCAdditionalNamesProp ) | ||
1128 | c.setMiddleName( value ); | ||
1129 | } | ||
1130 | } | ||
1131 | else if ( name == VCAdrProp ) { | ||
1132 | bool work = TRUE; // default address is work address | ||
1133 | QString street; | ||
1134 | QString city; | ||
1135 | QString region; | ||
1136 | QString postal; | ||
1137 | QString country; | ||
1138 | |||
1139 | VObjectIterator nit; | ||
1140 | initPropIterator( &nit, o ); | ||
1141 | while( moreIteration( &nit ) ) { | ||
1142 | VObject *o = nextVObject( &nit ); | ||
1143 | QCString name = vObjectName( o ); | ||
1144 | QString value = vObjectStringZValue( o ); | ||
1145 | if ( name == VCHomeProp ) | ||
1146 | work = FALSE; | ||
1147 | else if ( name == VCWorkProp ) | ||
1148 | work = TRUE; | ||
1149 | else if ( name == VCStreetAddressProp ) | ||
1150 | street = value; | ||
1151 | else if ( name == VCCityProp ) | ||
1152 | city = value; | ||
1153 | else if ( name == VCRegionProp ) | ||
1154 | region = value; | ||
1155 | else if ( name == VCPostalCodeProp ) | ||
1156 | postal = value; | ||
1157 | else if ( name == VCCountryNameProp ) | ||
1158 | country = value; | ||
1159 | } | ||
1160 | if ( work ) { | ||
1161 | c.setBusinessStreet( street ); | ||
1162 | c.setBusinessCity( city ); | ||
1163 | c.setBusinessCountry( country ); | ||
1164 | c.setBusinessZip( postal ); | ||
1165 | c.setBusinessState( region ); | ||
1166 | } else { | ||
1167 | c.setHomeStreet( street ); | ||
1168 | c.setHomeCity( city ); | ||
1169 | c.setHomeCountry( country ); | ||
1170 | c.setHomeZip( postal ); | ||
1171 | c.setHomeState( region ); | ||
1172 | } | ||
1173 | } | ||
1174 | else if ( name == VCTelephoneProp ) { | ||
1175 | enum { | ||
1176 | HOME = 0x01, | ||
1177 | WORK = 0x02, | ||
1178 | VOICE = 0x04, | ||
1179 | CELL = 0x08, | ||
1180 | FAX = 0x10, | ||
1181 | PAGER = 0x20, | ||
1182 | UNKNOWN = 0x80 | ||
1183 | }; | ||
1184 | int type = 0; | ||
1185 | |||
1186 | VObjectIterator nit; | ||
1187 | initPropIterator( &nit, o ); | ||
1188 | while( moreIteration( &nit ) ) { | ||
1189 | VObject *o = nextVObject( &nit ); | ||
1190 | QCString name = vObjectTypeInfo( o ); | ||
1191 | if ( name == VCHomeProp ) | ||
1192 | type |= HOME; | ||
1193 | else if ( name == VCWorkProp ) | ||
1194 | type |= WORK; | ||
1195 | else if ( name == VCVoiceProp ) | ||
1196 | type |= VOICE; | ||
1197 | else if ( name == VCCellularProp ) | ||
1198 | type |= CELL; | ||
1199 | else if ( name == VCFaxProp ) | ||
1200 | type |= FAX; | ||
1201 | else if ( name == VCPagerProp ) | ||
1202 | type |= PAGER; | ||
1203 | else if ( name == VCPreferredProp ) | ||
1204 | ; | ||
1205 | else | ||
1206 | type |= UNKNOWN; | ||
1207 | } | ||
1208 | if ( (type & UNKNOWN) != UNKNOWN ) { | ||
1209 | if ( ( type & (HOME|WORK) ) == 0 ) // default | ||
1210 | type |= HOME; | ||
1211 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default | ||
1212 | type |= VOICE; | ||
1213 | |||
1214 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) | ||
1215 | c.setHomePhone( value ); | ||
1216 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) | ||
1217 | c.setHomeFax( value ); | ||
1218 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) | ||
1219 | c.setHomeMobile( value ); | ||
1220 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) | ||
1221 | c.setBusinessPhone( value ); | ||
1222 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) | ||
1223 | c.setBusinessFax( value ); | ||
1224 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) | ||
1225 | c.setBusinessMobile( value ); | ||
1226 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) | ||
1227 | c.setBusinessPager( value ); | ||
1228 | } | ||
1229 | } | ||
1230 | else if ( name == VCEmailAddressProp ) { | ||
1231 | QString email = vObjectStringZValue( o ); | ||
1232 | bool valid = TRUE; | ||
1233 | VObjectIterator nit; | ||
1234 | initPropIterator( &nit, o ); | ||
1235 | while( moreIteration( &nit ) ) { | ||
1236 | VObject *o = nextVObject( &nit ); | ||
1237 | QCString name = vObjectTypeInfo( o ); | ||
1238 | if ( name != VCInternetProp && name != VCHomeProp && | ||
1239 | name != VCWorkProp && | ||
1240 | name != VCPreferredProp ) | ||
1241 | // ### preffered should map to default email | ||
1242 | valid = FALSE; | ||
1243 | } | ||
1244 | if ( valid ) { | ||
1245 | c.insertEmail( email ); | ||
1246 | } | ||
1247 | } | ||
1248 | else if ( name == VCURLProp ) { | ||
1249 | VObjectIterator nit; | ||
1250 | initPropIterator( &nit, o ); | ||
1251 | while( moreIteration( &nit ) ) { | ||
1252 | VObject *o = nextVObject( &nit ); | ||
1253 | QCString name = vObjectTypeInfo( o ); | ||
1254 | if ( name == VCHomeProp ) | ||
1255 | c.setHomeWebpage( value ); | ||
1256 | else if ( name == VCWorkProp ) | ||
1257 | c.setBusinessWebpage( value ); | ||
1258 | } | ||
1259 | } | ||
1260 | else if ( name == VCOrgProp ) { | ||
1261 | VObjectIterator nit; | ||
1262 | initPropIterator( &nit, o ); | ||
1263 | while( moreIteration( &nit ) ) { | ||
1264 | VObject *o = nextVObject( &nit ); | ||
1265 | QCString name = vObjectName( o ); | ||
1266 | QString value = vObjectStringZValue( o ); | ||
1267 | if ( name == VCOrgNameProp ) | ||
1268 | c.setCompany( value ); | ||
1269 | else if ( name == VCOrgUnitProp ) | ||
1270 | c.setDepartment( value ); | ||
1271 | else if ( name == VCOrgUnit2Prop ) | ||
1272 | c.setOffice( value ); | ||
1273 | } | ||
1274 | } | ||
1275 | else if ( name == VCTitleProp ) { | ||
1276 | c.setJobTitle( value ); | ||
1277 | } | ||
1278 | else if ( name == "X-Qtopia-Profession" ) { | ||
1279 | c.setProfession( value ); | ||
1280 | } | ||
1281 | else if ( name == "X-Qtopia-Manager" ) { | ||
1282 | c.setManager( value ); | ||
1283 | } | ||
1284 | else if ( name == "X-Qtopia-Assistant" ) { | ||
1285 | c.setAssistant( value ); | ||
1286 | } | ||
1287 | else if ( name == "X-Qtopia-Spouse" ) { | ||
1288 | c.setSpouse( value ); | ||
1289 | } | ||
1290 | else if ( name == "X-Qtopia-Gender" ) { | ||
1291 | c.setGender( value ); | ||
1292 | } | ||
1293 | else if ( name == "X-Qtopia-Anniversary" ) { | ||
1294 | c.setAnniversary( value ); | ||
1295 | } | ||
1296 | else if ( name == "X-Qtopia-Nickname" ) { | ||
1297 | c.setNickname( value ); | ||
1298 | } | ||
1299 | else if ( name == "X-Qtopia-Children" ) { | ||
1300 | c.setChildren( value ); | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | #if 0 | ||
1305 | else { | ||
1306 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | ||
1307 | VObjectIterator nit; | ||
1308 | initPropIterator( &nit, o ); | ||
1309 | while( moreIteration( &nit ) ) { | ||
1310 | VObject *o = nextVObject( &nit ); | ||
1311 | QCString name = vObjectName( o ); | ||
1312 | QString value = vObjectStringZValue( o ); | ||
1313 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | ||
1314 | } | ||
1315 | } | ||
1316 | #endif | ||
1317 | } | ||
1318 | c.setFileAs(); | ||
1319 | return c; | ||
1320 | } | ||
1321 | |||
1322 | /*! | ||
1323 | Writes the list of \a contacts as a set of VCards to the file \a filename. | ||
1324 | */ | ||
1325 | void OContact::writeVCard( const QString &filename, const QValueList<OContact> &contacts) | ||
1326 | { | ||
1327 | QFileDirect f( filename.utf8().data() ); | ||
1328 | if ( !f.open( IO_WriteOnly ) ) { | ||
1329 | qWarning("Unable to open vcard write"); | ||
1330 | return; | ||
1331 | } | ||
1332 | |||
1333 | QValueList<OContact>::ConstIterator it; | ||
1334 | for( it = contacts.begin(); it != contacts.end(); ++it ) { | ||
1335 | VObject *obj = createVObject( *it ); | ||
1336 | writeVObject(f.directHandle() , obj ); | ||
1337 | cleanVObject( obj ); | ||
1338 | } | ||
1339 | cleanStrTbl(); | ||
1340 | } | ||
1341 | |||
1342 | /*! | ||
1343 | writes \a contact as a VCard to the file \a filename. | ||
1344 | */ | ||
1345 | void OContact::writeVCard( const QString &filename, const OContact &contact) | ||
1346 | { | ||
1347 | QFileDirect f( filename.utf8().data() ); | ||
1348 | if ( !f.open( IO_WriteOnly ) ) { | ||
1349 | qWarning("Unable to open vcard write"); | ||
1350 | return; | ||
1351 | } | ||
1352 | |||
1353 | VObject *obj = createVObject( contact ); | ||
1354 | writeVObject( f.directHandle() , obj ); | ||
1355 | cleanVObject( obj ); | ||
1356 | |||
1357 | cleanStrTbl(); | ||
1358 | } | ||
1359 | |||
1360 | /*! | ||
1361 | Returns the set of contacts read as VCards from the file \a filename. | ||
1362 | */ | ||
1363 | QValueList<OContact> OContact::readVCard( const QString &filename ) | ||
1364 | { | ||
1365 | qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() ); | ||
1366 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | ||
1367 | |||
1368 | qDebug("vobject = %p", obj ); | ||
1369 | |||
1370 | QValueList<OContact> contacts; | ||
1371 | |||
1372 | while ( obj ) { | ||
1373 | contacts.append( parseVObject( obj ) ); | ||
1374 | |||
1375 | VObject *t = obj; | ||
1376 | obj = nextVObjectInList(obj); | ||
1377 | cleanVObject( t ); | ||
1378 | } | ||
1379 | |||
1380 | return contacts; | ||
1381 | } | ||
1382 | |||
1383 | /*! | ||
1384 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1385 | Otherwise returns FALSE. | ||
1386 | */ | ||
1387 | bool OContact::match( const QString ®exp ) const | ||
1388 | { | ||
1389 | return match(QRegExp(regexp)); | ||
1390 | } | ||
1391 | |||
1392 | /*! | ||
1393 | \overload | ||
1394 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1395 | Otherwise returns FALSE. | ||
1396 | */ | ||
1397 | bool OContact::match( const QRegExp &r ) const | ||
1398 | { | ||
1399 | bool match; | ||
1400 | match = false; | ||
1401 | QMap<int, QString>::ConstIterator it; | ||
1402 | for ( it = mMap.begin(); it != mMap.end(); ++it ) { | ||
1403 | if ( (*it).find( r ) > -1 ) { | ||
1404 | match = true; | ||
1405 | break; | ||
1406 | } | ||
1407 | } | ||
1408 | return match; | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | // Noch nicht definiert ! :SX | ||
1413 | QString OContact::toShortText() const | ||
1414 | { | ||
1415 | return ( QString::fromLatin1( "Not defined!") ); | ||
1416 | } | ||
1417 | QString OContact::type() const | ||
1418 | { | ||
1419 | return QString::fromLatin1( "OContact" ); | ||
1420 | } | ||
1421 | |||
1422 | // Noch nicht definiert ! :SX | ||
1423 | QMap<QString,QString> OContact::toExtraMap() const | ||
1424 | { | ||
1425 | QMap <QString,QString> useless; | ||
1426 | return useless; | ||
1427 | } | ||
1428 | |||
1429 | // Noch nicht definiert ! :SX | ||
1430 | class QString OContact::recordField(int) const | ||
1431 | { | ||
1432 | return QString::fromLatin1( "Noch nicht implementiert !" ); | ||
1433 | } | ||
diff --git a/libopie/pim/ocontact.h b/libopie/pim/ocontact.h new file mode 100644 index 0000000..e0555c8 --- a/dev/null +++ b/libopie/pim/ocontact.h | |||
@@ -0,0 +1,311 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the 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 | #ifndef __OCONTACT_H__ | ||
22 | #define __OCONTACT_H__ | ||
23 | |||
24 | #include <opie/opimrecord.h> | ||
25 | #include <qpe/recordfields.h> | ||
26 | |||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #if defined(QPC_TEMPLATEDLL) | ||
30 | // MOC_SKIP_BEGIN | ||
31 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; | ||
32 | // MOC_SKIP_END | ||
33 | #endif | ||
34 | |||
35 | class ContactPrivate; // Wozu ist das gut und wo ist das decrariert ? (se) | ||
36 | class QPC_EXPORT OContact : public OPimRecord | ||
37 | { | ||
38 | friend class DataSet; | ||
39 | public: | ||
40 | OContact(); | ||
41 | OContact( const QMap<int, QString> &fromMap ); | ||
42 | virtual ~OContact(); | ||
43 | |||
44 | static void writeVCard( const QString &filename, const QValueList<OContact> &contacts); | ||
45 | static void writeVCard( const QString &filename, const OContact &c ); | ||
46 | static QValueList<OContact> readVCard( const QString &filename ); | ||
47 | |||
48 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | ||
49 | |||
50 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } | ||
51 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } | ||
52 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } | ||
53 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } | ||
54 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } | ||
55 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } | ||
56 | void setFileAs(); | ||
57 | |||
58 | // default email address | ||
59 | void setDefaultEmail( const QString &v ); | ||
60 | // inserts email to list and ensure's doesn't already exist | ||
61 | void insertEmail( const QString &v ); | ||
62 | void removeEmail( const QString &v ); | ||
63 | void clearEmails(); | ||
64 | void insertEmails( const QStringList &v ); | ||
65 | |||
66 | // home | ||
67 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } | ||
68 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } | ||
69 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } | ||
70 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } | ||
71 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } | ||
72 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } | ||
73 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } | ||
74 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } | ||
75 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } | ||
76 | |||
77 | // business | ||
78 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } | ||
79 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } | ||
80 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } | ||
81 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } | ||
82 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } | ||
83 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } | ||
84 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } | ||
85 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } | ||
86 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } | ||
87 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } | ||
88 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } | ||
89 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } | ||
90 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } | ||
91 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } | ||
92 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } | ||
93 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } | ||
94 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } | ||
95 | |||
96 | // personal | ||
97 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } | ||
98 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } | ||
99 | void setBirthday( const QString &v ) { replace( Qtopia::Birthday, v ); } | ||
100 | void setAnniversary( const QString &v ) { replace( Qtopia::Anniversary, v ); } | ||
101 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } | ||
102 | void setChildren( const QString &v ); | ||
103 | |||
104 | // other | ||
105 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } | ||
106 | |||
107 | bool match( const QString ®exp ) const; | ||
108 | |||
109 | // DON'T ATTEMPT TO USE THIS | ||
110 | #ifdef QTOPIA_INTERNAL_CONTACT_MRE | ||
111 | bool match( const QRegExp ®exp ) const; | ||
112 | #endif | ||
113 | |||
114 | // // custom | ||
115 | // void setCustomField( const QString &key, const QString &v ) | ||
116 | // { replace(Custom- + key, v ); } | ||
117 | |||
118 | // name | ||
119 | QString fullName() const; | ||
120 | QString title() const { return find( Qtopia::Title ); } | ||
121 | QString firstName() const { return find( Qtopia::FirstName ); } | ||
122 | QString middleName() const { return find( Qtopia::MiddleName ); } | ||
123 | QString lastName() const { return find( Qtopia::LastName ); } | ||
124 | QString suffix() const { return find( Qtopia::Suffix ); } | ||
125 | QString fileAs() const { return find( Qtopia::FileAs ); } | ||
126 | |||
127 | |||
128 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } | ||
129 | QStringList emailList() const; | ||
130 | |||
131 | // home | ||
132 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } | ||
133 | QString homeCity() const { return find( Qtopia::HomeCity ); } | ||
134 | QString homeState() const { return find( Qtopia::HomeState ); } | ||
135 | QString homeZip() const { return find( Qtopia::HomeZip ); } | ||
136 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } | ||
137 | QString homePhone() const { return find( Qtopia::HomePhone ); } | ||
138 | QString homeFax() const { return find( Qtopia::HomeFax ); } | ||
139 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } | ||
140 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } | ||
141 | /** Multi line string containing all non-empty address info in the form | ||
142 | * Street | ||
143 | * City, State Zip | ||
144 | * Country | ||
145 | */ | ||
146 | QString displayHomeAddress() const; | ||
147 | |||
148 | // business | ||
149 | QString company() const { return find( Qtopia::Company ); } | ||
150 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } | ||
151 | QString businessCity() const { return find( Qtopia::BusinessCity ); } | ||
152 | QString businessState() const { return find( Qtopia::BusinessState ); } | ||
153 | QString businessZip() const { return find( Qtopia::BusinessZip ); } | ||
154 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } | ||
155 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } | ||
156 | QString jobTitle() const { return find( Qtopia::JobTitle ); } | ||
157 | QString department() const { return find( Qtopia::Department ); } | ||
158 | QString office() const { return find( Qtopia::Office ); } | ||
159 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } | ||
160 | QString businessFax() const { return find( Qtopia::BusinessFax ); } | ||
161 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } | ||
162 | QString businessPager() const { return find( Qtopia::BusinessPager ); } | ||
163 | QString profession() const { return find( Qtopia::Profession ); } | ||
164 | QString assistant() const { return find( Qtopia::Assistant ); } | ||
165 | QString manager() const { return find( Qtopia::Manager ); } | ||
166 | /** Multi line string containing all non-empty address info in the form | ||
167 | * Street | ||
168 | * City, State Zip | ||
169 | * Country | ||
170 | */ | ||
171 | QString displayBusinessAddress() const; | ||
172 | |||
173 | //personal | ||
174 | QString spouse() const { return find( Qtopia::Spouse ); } | ||
175 | QString gender() const { return find( Qtopia::Gender ); } | ||
176 | QString birthday() const { return find( Qtopia::Birthday ); } | ||
177 | QString anniversary() const { return find( Qtopia::Anniversary ); } | ||
178 | QString nickname() const { return find( Qtopia::Nickname ); } | ||
179 | QString children() const { return find( Qtopia::Children ); } | ||
180 | QStringList childrenList() const; | ||
181 | |||
182 | // other | ||
183 | QString notes() const { return find( Qtopia::Notes ); } | ||
184 | QString groups() const { return find( Qtopia::Groups ); } | ||
185 | QStringList groupList() const; | ||
186 | |||
187 | // // custom | ||
188 | // const QString &customField( const QString &key ) | ||
189 | // { return find( Custom- + key ); } | ||
190 | |||
191 | static QStringList fields(); | ||
192 | static QStringList trfields(); | ||
193 | |||
194 | QString toRichText() const; | ||
195 | QMap<int, QString> toMap() const; | ||
196 | QString field( int key ) const { return find( key ); } | ||
197 | |||
198 | |||
199 | // journaling... | ||
200 | void saveJournal( journal_action action, const QString &key = QString::null ); | ||
201 | void save( QString &buf ) const; | ||
202 | |||
203 | void setUid( int i ) | ||
204 | { Record::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } | ||
205 | |||
206 | QString toShortText()const; | ||
207 | QString OContact::type()const; | ||
208 | QMap<QString,QString> OContact::toExtraMap() const; | ||
209 | class QString OContact::recordField(int) const; | ||
210 | |||
211 | private: | ||
212 | friend class AbEditor; | ||
213 | friend class AbTable; | ||
214 | friend class AddressBookAccessPrivate; | ||
215 | friend class XMLIO; | ||
216 | |||
217 | QString emailSeparator() const { return " "; } | ||
218 | // the emails should be seperated by a comma | ||
219 | void setEmails( const QString &v ); | ||
220 | QString emails() const { return find( Qtopia::Emails ); } | ||
221 | |||
222 | void insert( int key, const QString &value ); | ||
223 | void replace( int key, const QString &value ); | ||
224 | QString find( int key ) const; | ||
225 | |||
226 | QString displayAddress( const QString &street, | ||
227 | const QString &city, | ||
228 | const QString &state, | ||
229 | const QString &zip, | ||
230 | const QString &country ) const; | ||
231 | |||
232 | Qtopia::UidGen &uidGen() { return sUidGen; } | ||
233 | static Qtopia::UidGen sUidGen; | ||
234 | QMap<int, QString> mMap; | ||
235 | ContactPrivate *d; | ||
236 | }; | ||
237 | |||
238 | // these methods are inlined to keep binary compatability with Qtopia 1.5 | ||
239 | inline void OContact::insertEmail( const QString &v ) | ||
240 | { | ||
241 | //qDebug("insertEmail %s", v.latin1()); | ||
242 | QString e = v.simplifyWhiteSpace(); | ||
243 | QString def = defaultEmail(); | ||
244 | |||
245 | // if no default, set it as the default email and don't insert | ||
246 | if ( def.isEmpty() ) { | ||
247 | setDefaultEmail( e ); // will insert into the list for us | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | // otherwise, insert assuming doesn't already exist | ||
252 | QString emailsStr = find( Qtopia::Emails ); | ||
253 | if ( emailsStr.contains( e )) | ||
254 | return; | ||
255 | if ( !emailsStr.isEmpty() ) | ||
256 | emailsStr += emailSeparator(); | ||
257 | emailsStr += e; | ||
258 | replace( Qtopia::Emails, emailsStr ); | ||
259 | } | ||
260 | |||
261 | inline void OContact::removeEmail( const QString &v ) | ||
262 | { | ||
263 | QString e = v.simplifyWhiteSpace(); | ||
264 | QString def = defaultEmail(); | ||
265 | QString emailsStr = find( Qtopia::Emails ); | ||
266 | QStringList emails = emailList(); | ||
267 | |||
268 | // otherwise, must first contain it | ||
269 | if ( !emailsStr.contains( e ) ) | ||
270 | return; | ||
271 | |||
272 | // remove it | ||
273 | //qDebug(" removing email from list %s", e.latin1()); | ||
274 | emails.remove( e ); | ||
275 | // reset the string | ||
276 | emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator | ||
277 | replace( Qtopia::Emails, emailsStr ); | ||
278 | |||
279 | // if default, then replace the default email with the first one | ||
280 | if ( def == e ) { | ||
281 | //qDebug("removeEmail is default; setting new default"); | ||
282 | if ( !emails.count() ) | ||
283 | clearEmails(); | ||
284 | else // setDefaultEmail will remove e from the list | ||
285 | setDefaultEmail( emails.first() ); | ||
286 | } | ||
287 | } | ||
288 | inline void OContact::clearEmails() | ||
289 | { | ||
290 | mMap.remove( Qtopia::DefaultEmail ); | ||
291 | mMap.remove( Qtopia::Emails ); | ||
292 | } | ||
293 | inline void OContact::setDefaultEmail( const QString &v ) | ||
294 | { | ||
295 | QString e = v.simplifyWhiteSpace(); | ||
296 | |||
297 | //qDebug("OContact::setDefaultEmail %s", e.latin1()); | ||
298 | replace( Qtopia::DefaultEmail, e ); | ||
299 | |||
300 | if ( !e.isEmpty() ) | ||
301 | insertEmail( e ); | ||
302 | |||
303 | } | ||
304 | |||
305 | inline void OContact::insertEmails( const QStringList &v ) | ||
306 | { | ||
307 | for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) | ||
308 | insertEmail( *it ); | ||
309 | } | ||
310 | |||
311 | #endif | ||
diff --git a/libopie/pim/ocontactaccess.cpp b/libopie/pim/ocontactaccess.cpp new file mode 100644 index 0000000..2d808f7 --- a/dev/null +++ b/libopie/pim/ocontactaccess.cpp | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * Class to manage the Contacts. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * Info: This class could just work with a change in the header-file | ||
13 | * of the Contact class ! Therefore our libopie only compiles | ||
14 | * with our version of libqpe | ||
15 | * ===================================================================== | ||
16 | * ToDo: XML-Backend: Automatic reload if something was changed... | ||
17 | * | ||
18 | * | ||
19 | * ===================================================================== | ||
20 | * Version: $Id$ | ||
21 | * ===================================================================== | ||
22 | * History: | ||
23 | * $Log$ | ||
24 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
25 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
26 | * please do not expect that anything is working ! | ||
27 | * I will debug that stuff in the next time .. | ||
28 | * Please read README_COMPILE for compiling ! | ||
29 | * | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include "ocontactaccess.h" | ||
34 | |||
35 | #include <qasciidict.h> | ||
36 | #include <qdatetime.h> | ||
37 | #include <qfile.h> | ||
38 | #include <qregexp.h> | ||
39 | #include <qlist.h> | ||
40 | #include <qcopchannel_qws.h> | ||
41 | |||
42 | //#include <qpe/qcopenvelope_qws.h> | ||
43 | #include <qpe/global.h> | ||
44 | |||
45 | #include <errno.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <unistd.h> | ||
48 | #include <stdlib.h> | ||
49 | |||
50 | #include "ocontactaccessbackend_xml.h" | ||
51 | |||
52 | |||
53 | OContactAccess::OContactAccess ( const QString appname, const QString filename, | ||
54 | OContactAccessBackend* end, bool autosync ): | ||
55 | OPimAccessTemplate<OContact>( end ), | ||
56 | m_changed ( false ) | ||
57 | { | ||
58 | /* take care of the backend. If there is no one defined, we | ||
59 | * will use the XML-Backend as default (until we have a cute SQL-Backend..). | ||
60 | */ | ||
61 | if( end == 0 ) { | ||
62 | end = new OContactAccessBackend_XML( appname, filename ); | ||
63 | } | ||
64 | m_backEnd = end; | ||
65 | |||
66 | /* Connect signal of external db change to function */ | ||
67 | QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); | ||
68 | connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), | ||
69 | this, SLOT(copMessage( const QCString &, const QByteArray &)) ); | ||
70 | if ( autosync ){ | ||
71 | QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); | ||
72 | connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), | ||
73 | this, SLOT(copMessage( const QCString &, const QByteArray &)) ); | ||
74 | } | ||
75 | |||
76 | |||
77 | } | ||
78 | OContactAccess::~OContactAccess () | ||
79 | { | ||
80 | /* The user may forget to save the changed database, therefore try to | ||
81 | * do it for him.. | ||
82 | */ | ||
83 | if ( m_changed ) | ||
84 | save(); | ||
85 | delete m_backEnd; | ||
86 | } | ||
87 | |||
88 | bool OContactAccess::load() | ||
89 | { | ||
90 | return ( m_backEnd->load() ); | ||
91 | } | ||
92 | |||
93 | bool OContactAccess::save () | ||
94 | { | ||
95 | /* If the database was changed externally, we could not save the | ||
96 | * Data. This will remove added items which is unacceptable ! | ||
97 | * Therefore: Reload database and merge the data... | ||
98 | */ | ||
99 | if ( m_backEnd->wasChangedExternally() ) | ||
100 | reload(); | ||
101 | |||
102 | if ( m_changed ){ | ||
103 | bool status = m_backEnd->save(); | ||
104 | if ( !status ) return false; | ||
105 | |||
106 | m_changed = false; | ||
107 | /* Now tell everyone that new data is available. | ||
108 | */ | ||
109 | QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); | ||
110 | |||
111 | } | ||
112 | |||
113 | return true; | ||
114 | } | ||
115 | |||
116 | const uint OContactAccess::querySettings() | ||
117 | { | ||
118 | return ( m_backEnd->querySettings() ); | ||
119 | } | ||
120 | |||
121 | bool OContactAccess::hasQuerySettings ( int querySettings ) const | ||
122 | { | ||
123 | return ( m_backEnd->hasQuerySettings ( querySettings ) ); | ||
124 | } | ||
125 | |||
126 | bool OContactAccess::add ( const OContact& newcontact ) | ||
127 | { | ||
128 | m_changed = true; | ||
129 | return ( m_backEnd->add ( newcontact ) ); | ||
130 | } | ||
131 | |||
132 | bool OContactAccess::replace ( const OContact& contact ) | ||
133 | { | ||
134 | m_changed = true; | ||
135 | return ( m_backEnd->replace ( contact ) ); | ||
136 | } | ||
137 | |||
138 | bool OContactAccess::remove ( const OContact& t ) | ||
139 | { | ||
140 | m_changed = true; | ||
141 | return ( m_backEnd->remove ( t.uid() ) ); | ||
142 | } | ||
143 | |||
144 | bool OContactAccess::remove ( int uid ) | ||
145 | { | ||
146 | m_changed = true; | ||
147 | return ( m_backEnd->remove ( uid ) ); | ||
148 | } | ||
149 | |||
150 | bool OContactAccess::wasChangedExternally()const | ||
151 | { | ||
152 | return ( m_backEnd->wasChangedExternally() ); | ||
153 | } | ||
154 | |||
155 | |||
156 | bool OContactAccess::reload() | ||
157 | { | ||
158 | return ( m_backEnd->reload() ); | ||
159 | } | ||
160 | |||
161 | void OContactAccess::copMessage( const QCString &msg, const QByteArray & ) | ||
162 | { | ||
163 | if ( msg == "addressbookUpdated()" ){ | ||
164 | qWarning ("OContactAccess: Received addressbokUpdated()"); | ||
165 | emit signalChanged ( this ); | ||
166 | } else if ( msg == "flush()" ) { | ||
167 | qWarning ("OContactAccess: Received flush()"); | ||
168 | save (); | ||
169 | } else if ( msg == "reload()" ) { | ||
170 | qWarning ("OContactAccess: Received reload()"); | ||
171 | reload (); | ||
172 | emit signalChanged ( this ); | ||
173 | } | ||
174 | } | ||
diff --git a/libopie/pim/ocontactaccess.h b/libopie/pim/ocontactaccess.h new file mode 100644 index 0000000..54f7f07 --- a/dev/null +++ b/libopie/pim/ocontactaccess.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Class to manage the Contacts. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | ||
6 | * | ||
7 | * ===================================================================== | ||
8 | *This program is free software; you can redistribute it and/or | ||
9 | *modify it under the terms of the GNU Library General Public | ||
10 | * License as published by the Free Software Foundation; | ||
11 | * either version 2 of the License, or (at your option) any later | ||
12 | * version. | ||
13 | * ===================================================================== | ||
14 | * ToDo: Define enum for query settings | ||
15 | * ===================================================================== | ||
16 | * Version: $Id$ | ||
17 | * ===================================================================== | ||
18 | * History: | ||
19 | * $Log$ | ||
20 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
21 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
22 | * please do not expect that anything is working ! | ||
23 | * I will debug that stuff in the next time .. | ||
24 | * Please read README_COMPILE for compiling ! | ||
25 | * | ||
26 | * ===================================================================== | ||
27 | */ | ||
28 | #ifndef _OCONTACTACCESS_H | ||
29 | #define _OCONTACTACCESS_H | ||
30 | |||
31 | #include <qobject.h> | ||
32 | |||
33 | #include <qpe/qcopenvelope_qws.h> | ||
34 | |||
35 | #include <qvaluelist.h> | ||
36 | #include <qfileinfo.h> | ||
37 | |||
38 | #include "ocontact.h" | ||
39 | #include "ocontactaccessbackend.h" | ||
40 | #include "opimaccesstemplate.h" | ||
41 | |||
42 | /** Class to access the contacts database. | ||
43 | * This is just a frontend for the real database handling which is | ||
44 | * done by the backend. | ||
45 | */ | ||
46 | class OContactAccess: public QObject, public OPimAccessTemplate<OContact> | ||
47 | { | ||
48 | Q_OBJECT | ||
49 | |||
50 | |||
51 | /* class Iterator{ | ||
52 | friend OContactAccess; | ||
53 | public: | ||
54 | Iterator(); | ||
55 | Iterator ( const Iterator& copy ); | ||
56 | |||
57 | bool operator== ( const Iterator& it ); | ||
58 | bool operator!= ( const Iterator& it ); | ||
59 | Iterator& operator= ( const Iterator& it ); | ||
60 | Iterator& operator++ (); // prefix | ||
61 | Iterator operator++ ( int ); // postfix | ||
62 | Iterator& operator-- (); // prefix | ||
63 | Iterator operator-- ( int ); // postfix | ||
64 | Contact operator*() const; | ||
65 | Contact operator->() const; | ||
66 | |||
67 | Iterator begin(); | ||
68 | Iterator end(); | ||
69 | |||
70 | uint count() const; | ||
71 | |||
72 | private: | ||
73 | QValueList<int> m_uids; | ||
74 | int m_cur_position; | ||
75 | bool m_end_reached; | ||
76 | OContactAccess *m_db; | ||
77 | |||
78 | }; | ||
79 | |||
80 | */ | ||
81 | |||
82 | public: | ||
83 | /** Create Database with contacts (addressbook). | ||
84 | * @param appname Name of application which wants access to the database | ||
85 | * (i.e. "todolist") | ||
86 | * @param filename The name of the database file. If not set, the default one | ||
87 | * is used. | ||
88 | * @param backend Pointer to an alternative Backend. If not set, we will use | ||
89 | * the default backend. | ||
90 | * @param handlesync If <b>true</b> the database stores the current state | ||
91 | * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> | ||
92 | * which are used before and after synchronisation. If the application wants | ||
93 | * to react itself, it should be disabled by setting it to <b>false</b> | ||
94 | * @see OContactBackend | ||
95 | */ | ||
96 | OContactAccess (const QString appname, const QString filename = 0l, | ||
97 | OContactAccessBackend* backend = 0l, bool handlesync = true); | ||
98 | ~OContactAccess (); | ||
99 | |||
100 | /** Constants for query. | ||
101 | * Use this constants to set the query parameters. | ||
102 | * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! | ||
103 | * @see queryByExample() | ||
104 | * - why not enum - zecke? | ||
105 | * -> Had some implementation problems .. Will use enum soon ! .. (se) | ||
106 | */ | ||
107 | static const int query_WildCards = 0x0001; | ||
108 | static const int query_IgnoreCase = 0x0002; | ||
109 | static const int query_RegExp = 0x0004; | ||
110 | static const int query_ExactMatch = 0x0008; | ||
111 | |||
112 | /** Return all possible settings. | ||
113 | * @return All settings provided by the current backend | ||
114 | * (i.e.: query_WildCards & query_IgnoreCase) | ||
115 | */ | ||
116 | const uint querySettings(); | ||
117 | |||
118 | /** Check whether settings are correct. | ||
119 | * @return <i>true</i> if the given settings are correct and possible. | ||
120 | */ | ||
121 | bool hasQuerySettings ( int querySettings ) const; | ||
122 | |||
123 | /** Add Contact to database. | ||
124 | * @param newcontact The contact to add. | ||
125 | * @return <i>true</i> if added successfully. | ||
126 | */ | ||
127 | bool add (const OContact& newcontact); | ||
128 | |||
129 | /** Replace contact. | ||
130 | * Replaces given contact with contact with the user id <i>uid</i>. | ||
131 | * @param uid The user ID | ||
132 | * @param contact The new contact | ||
133 | * @return <i>true</i> if successful. | ||
134 | */ | ||
135 | bool replace ( const OContact& contact ); | ||
136 | |||
137 | /** Remove contact. | ||
138 | * Removes contact with the user id <i>uid</i>. | ||
139 | * @param The contact to remove | ||
140 | * @return <i>true</i> if successful. | ||
141 | */ | ||
142 | bool remove ( const OContact& t ); | ||
143 | |||
144 | /** Remove contact. | ||
145 | * Removes contact with the user id <i>uid</i>. | ||
146 | * @param The user id of the contact to remove | ||
147 | * @return <i>true</i> if successful. | ||
148 | */ | ||
149 | bool remove ( int uid ); | ||
150 | |||
151 | /** Load Database * | ||
152 | */ | ||
153 | bool load(); | ||
154 | |||
155 | /** | ||
156 | * if the resource was changed externally. | ||
157 | * You should use the signal instead of polling possible changes ! | ||
158 | */ | ||
159 | bool wasChangedExternally()const; | ||
160 | |||
161 | /** Reload database. | ||
162 | * You should execute this function if the external database | ||
163 | * was changed. | ||
164 | * This function will load the external database and afterwards | ||
165 | * rejoin the local changes. Therefore the local database will be set consistent. | ||
166 | */ | ||
167 | bool reload(); | ||
168 | |||
169 | /** Save contacts database. | ||
170 | * Save is more a "commit". After calling this function, all changes are public available. | ||
171 | * @return true if successful | ||
172 | */ | ||
173 | bool save(); | ||
174 | |||
175 | signals: | ||
176 | /* Signal is emitted if the database was changed. Therefore | ||
177 | * we may need to reload to stay consistent. | ||
178 | * @param which Pointer to the database who created this event. This pointer | ||
179 | * is useful if an application has to handle multiple databases at the same time. | ||
180 | * @see reload() | ||
181 | */ | ||
182 | void signalChanged ( const OContactAccess *which ); | ||
183 | |||
184 | |||
185 | private: | ||
186 | // class OContactAccessPrivate; | ||
187 | // OContactAccessPrivate* d; | ||
188 | OContactAccessBackend *m_backEnd; | ||
189 | bool m_loading:1; | ||
190 | bool m_changed; | ||
191 | |||
192 | private slots: | ||
193 | void copMessage( const QCString &msg, const QByteArray &data ); | ||
194 | |||
195 | |||
196 | }; | ||
197 | #endif | ||
diff --git a/libopie/pim/ocontactaccessbackend.h b/libopie/pim/ocontactaccessbackend.h new file mode 100644 index 0000000..9469bbc --- a/dev/null +++ b/libopie/pim/ocontactaccessbackend.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /** | ||
2 | * The class responsible for managing a backend. | ||
3 | * The implementation of this abstract class contains | ||
4 | * the complete database handling. | ||
5 | * | ||
6 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
7 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | ||
8 | * | ||
9 | * ===================================================================== | ||
10 | *This program is free software; you can redistribute it and/or | ||
11 | *modify it under the terms of the GNU Library General Public | ||
12 | * License as published by the Free Software Foundation; | ||
13 | * either version 2 of the License, or (at your option) any later | ||
14 | * version. | ||
15 | * ===================================================================== | ||
16 | * ToDo: Define enum for query settings | ||
17 | * ===================================================================== | ||
18 | * Version: $Id$ | ||
19 | * ===================================================================== | ||
20 | * History: | ||
21 | * $Log$ | ||
22 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
23 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
24 | * please do not expect that anything is working ! | ||
25 | * I will debug that stuff in the next time .. | ||
26 | * Please read README_COMPILE for compiling ! | ||
27 | * | ||
28 | * ===================================================================== | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef _OCONTACTACCESSBACKEND_H_ | ||
33 | #define _OCONTACTACCESSBACKEND_H_ | ||
34 | |||
35 | #include "opimaccessbackend.h" | ||
36 | |||
37 | class OContactAccessBackend: public OPimAccessBackend<OContact> { | ||
38 | public: | ||
39 | OContactAccessBackend() {} | ||
40 | virtual ~OContactAccessBackend() {} | ||
41 | |||
42 | |||
43 | /** Return if database was changed externally. | ||
44 | * This may just make sense on file based databases like a XML-File. | ||
45 | * It is used to prevent to overwrite the current database content | ||
46 | * if the file was already changed by something else ! | ||
47 | * If this happens, we have to reload before save our data. | ||
48 | * If we use real databases, this should be handled by the database | ||
49 | * management system themselve, therefore this function should always return false in | ||
50 | * this case. It is not our problem to handle this conflict ... | ||
51 | * @return <i>true</i> if the database was changed and if save without reload will | ||
52 | * be dangerous. <i>false</i> if the database was not changed or it is save to write | ||
53 | * in this situation. | ||
54 | */ | ||
55 | virtual bool wasChangedExternally() = 0; | ||
56 | |||
57 | /** Return all possible settings. | ||
58 | * @return All settings provided by the current backend | ||
59 | * (i.e.: query_WildCards & query_IgnoreCase) | ||
60 | */ | ||
61 | virtual const uint querySettings() = 0; | ||
62 | |||
63 | /** Check whether settings are correct. | ||
64 | * @return <i>true</i> if the given settings are correct and possible. | ||
65 | */ | ||
66 | virtual bool hasQuerySettings (uint querySettings) const = 0; | ||
67 | |||
68 | |||
69 | }; | ||
70 | #endif | ||
diff --git a/libopie/pim/ocontactaccessbackend_xml.h b/libopie/pim/ocontactaccessbackend_xml.h new file mode 100644 index 0000000..2cdb45b --- a/dev/null +++ b/libopie/pim/ocontactaccessbackend_xml.h | |||
@@ -0,0 +1,550 @@ | |||
1 | /* | ||
2 | * XML Backend for the OPIE-Contact Database. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ToDo: XML-Backend: Automatic reload if something was changed... | ||
13 | * | ||
14 | * | ||
15 | * ===================================================================== | ||
16 | * Version: $Id$ | ||
17 | * ===================================================================== | ||
18 | * History: | ||
19 | * $Log$ | ||
20 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
21 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
22 | * please do not expect that anything is working ! | ||
23 | * I will debug that stuff in the next time .. | ||
24 | * Please read README_COMPILE for compiling ! | ||
25 | * | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef _OContactAccessBackend_XML_ | ||
30 | #define _OContactAccessBackend_XML_ | ||
31 | |||
32 | #include <qasciidict.h> | ||
33 | #include <qdatetime.h> | ||
34 | #include <qfile.h> | ||
35 | #include <qregexp.h> | ||
36 | #include <qarray.h> | ||
37 | |||
38 | #include <opie/xmltree.h> | ||
39 | #include "ocontactaccessbackend.h" | ||
40 | |||
41 | using namespace Opie; | ||
42 | |||
43 | /* the default xml implementation */ | ||
44 | class OContactAccessBackend_XML : public OContactAccessBackend { | ||
45 | public: | ||
46 | OContactAccessBackend_XML ( QString appname, QString filename = 0l ) | ||
47 | { | ||
48 | m_appName = appname; | ||
49 | |||
50 | /* Set journalfile name ... */ | ||
51 | m_journalName = getenv("HOME"); | ||
52 | m_journalName +="/.abjournal" + appname; | ||
53 | |||
54 | /* Expecting to access the default filename if nothing else is set */ | ||
55 | if ( filename.isEmpty() ){ | ||
56 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); | ||
57 | } else | ||
58 | m_fileName = filename; | ||
59 | |||
60 | /* Load Database now */ | ||
61 | load (); | ||
62 | } | ||
63 | |||
64 | bool save() { | ||
65 | QString strNewFile = m_fileName + ".new"; | ||
66 | QFile f( strNewFile ); | ||
67 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) | ||
68 | return false; | ||
69 | |||
70 | int total_written; | ||
71 | QString out; | ||
72 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" | ||
73 | " <Groups>\n" | ||
74 | " </Groups>\n" | ||
75 | " <Contacts>\n"; | ||
76 | //QValueList<Contact>::iterator it; | ||
77 | QValueListConstIterator<OContact> it; | ||
78 | for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { | ||
79 | out += "<Contact "; | ||
80 | (*it).save( out ); | ||
81 | out += "/>\n"; | ||
82 | QCString cstr = out.utf8(); | ||
83 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | ||
84 | if ( total_written != int(cstr.length()) ) { | ||
85 | f.close(); | ||
86 | QFile::remove( strNewFile ); | ||
87 | return false; | ||
88 | } | ||
89 | out = ""; | ||
90 | } | ||
91 | out += " </Contacts>\n</AddressBook>\n"; | ||
92 | |||
93 | QCString cstr = out.utf8(); | ||
94 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | ||
95 | if ( total_written != int( cstr.length() ) ) { | ||
96 | f.close(); | ||
97 | QFile::remove( strNewFile ); | ||
98 | return false; | ||
99 | } | ||
100 | f.close(); | ||
101 | |||
102 | // move the file over, I'm just going to use the system call | ||
103 | // because, I don't feel like using QDir. | ||
104 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { | ||
105 | qWarning( "problem renaming file %s to %s, errno: %d", | ||
106 | strNewFile.latin1(), m_journalName.latin1(), errno ); | ||
107 | // remove the tmp file... | ||
108 | QFile::remove( strNewFile ); | ||
109 | } | ||
110 | |||
111 | /* The journalfile should be removed now... */ | ||
112 | removeJournal(); | ||
113 | return true; | ||
114 | } | ||
115 | |||
116 | bool load () { | ||
117 | m_contactList.clear(); | ||
118 | |||
119 | /* Load XML-File and journal if it exists */ | ||
120 | if ( !load ( m_fileName, false ) ) | ||
121 | return false; | ||
122 | /* The returncode of the journalfile is ignored due to the | ||
123 | * fact that it does not exist when this class is instantiated ! | ||
124 | * But there may such a file exist, if the application crashed. | ||
125 | * Therefore we try to load it to get the changes before the # | ||
126 | * crash happened... | ||
127 | */ | ||
128 | load (m_journalName, true); | ||
129 | |||
130 | return true; | ||
131 | } | ||
132 | |||
133 | void clear () { | ||
134 | m_contactList.clear(); | ||
135 | |||
136 | } | ||
137 | |||
138 | bool wasChangedExternally() | ||
139 | { | ||
140 | QFileInfo fi( m_fileName ); | ||
141 | |||
142 | QDateTime lastmod = fi.lastModified (); | ||
143 | |||
144 | return (lastmod != m_readtime); | ||
145 | } | ||
146 | |||
147 | QArray<int> allRecords() const { | ||
148 | QArray<int> uid_list( m_contactList.count() ); | ||
149 | |||
150 | uint counter = 0; | ||
151 | QValueListConstIterator<OContact> it; | ||
152 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
153 | uid_list[counter++] = (*it).uid(); | ||
154 | } | ||
155 | |||
156 | return ( uid_list ); | ||
157 | } | ||
158 | |||
159 | OContact find ( int uid ) const | ||
160 | { | ||
161 | bool found = false; | ||
162 | OContact foundContact; //Create empty contact | ||
163 | |||
164 | QValueListConstIterator<OContact> it; | ||
165 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
166 | if ((*it).uid() == uid){ | ||
167 | found = true; | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | if ( found ){ | ||
172 | foundContact = *it; | ||
173 | } | ||
174 | |||
175 | return ( foundContact ); | ||
176 | } | ||
177 | |||
178 | QArray<int> queryByExample ( const OContact &query, int settings ){ | ||
179 | |||
180 | QArray<int> m_currentQuery( m_contactList.count() ); | ||
181 | QValueListConstIterator<OContact> it; | ||
182 | uint arraycounter = 0; | ||
183 | |||
184 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
185 | /* Search all fields and compare them with query object. Store them into list | ||
186 | * if all fields matches. | ||
187 | */ | ||
188 | bool allcorrect = true; | ||
189 | for ( int i = 0; i < Qtopia::rid; i++ ) { | ||
190 | /* Just compare fields which are not empty in the query object */ | ||
191 | if ( !query.field(i).isEmpty() ){ | ||
192 | switch ( settings & ~OContactAccess::query_IgnoreCase ){ | ||
193 | case OContactAccess::query_RegExp:{ | ||
194 | QRegExp expr ( query.field(i), | ||
195 | !(settings & OContactAccess::query_IgnoreCase), | ||
196 | false ); | ||
197 | if ( expr.find ( (*it).field(i), 0 ) == -1 ) | ||
198 | allcorrect = false; | ||
199 | } | ||
200 | break; | ||
201 | case OContactAccess::query_WildCards:{ | ||
202 | QRegExp expr ( query.field(i), | ||
203 | !(settings & OContactAccess::query_IgnoreCase), | ||
204 | true ); | ||
205 | if ( expr.find ( (*it).field(i), 0 ) == -1 ) | ||
206 | allcorrect = false; | ||
207 | } | ||
208 | break; | ||
209 | case OContactAccess::query_ExactMatch:{ | ||
210 | if (settings & OContactAccess::query_IgnoreCase){ | ||
211 | if ( query.field(i).upper() != | ||
212 | (*it).field(i).upper() ) | ||
213 | allcorrect = false; | ||
214 | }else{ | ||
215 | if ( query.field(i) != (*it).field(i) ) | ||
216 | allcorrect = false; | ||
217 | } | ||
218 | } | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | if ( allcorrect ){ | ||
224 | m_currentQuery[arraycounter++] = (*it).uid(); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | // Shrink to fit.. | ||
229 | m_currentQuery.resize(arraycounter); | ||
230 | |||
231 | return m_currentQuery; | ||
232 | } | ||
233 | |||
234 | const uint querySettings() | ||
235 | { | ||
236 | return ( OContactAccess::query_WildCards | ||
237 | & OContactAccess::query_IgnoreCase | ||
238 | & OContactAccess::query_RegExp | ||
239 | & OContactAccess::query_ExactMatch ); | ||
240 | } | ||
241 | |||
242 | bool hasQuerySettings (uint querySettings) const | ||
243 | { | ||
244 | /* OContactAccess::query_IgnoreCase may be added with one | ||
245 | * of the other settings, but never used alone. | ||
246 | * The other settings are just valid alone... | ||
247 | */ | ||
248 | switch ( querySettings & ~OContactAccess::query_IgnoreCase ){ | ||
249 | case OContactAccess::query_RegExp: | ||
250 | return ( true ); | ||
251 | case OContactAccess::query_WildCards: | ||
252 | return ( true ); | ||
253 | case OContactAccess::query_ExactMatch: | ||
254 | return ( true ); | ||
255 | default: | ||
256 | return ( false ); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | bool add ( const OContact &newcontact ) | ||
261 | { | ||
262 | //qWarning("odefaultbackend: ACTION::ADD"); | ||
263 | updateJournal (newcontact, OContact::ACTION_ADD); | ||
264 | addContact_p( newcontact ); | ||
265 | return true; | ||
266 | } | ||
267 | |||
268 | bool replace ( const OContact &contact ) | ||
269 | { | ||
270 | bool found = false; | ||
271 | |||
272 | QValueListIterator<OContact> it; | ||
273 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
274 | if ( (*it).uid() == contact.uid() ){ | ||
275 | found = true; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if (found) { | ||
280 | updateJournal (contact, OContact::ACTION_REPLACE); | ||
281 | m_contactList.remove (it); | ||
282 | m_contactList.append (contact); | ||
283 | return true; | ||
284 | } else | ||
285 | return false; | ||
286 | } | ||
287 | |||
288 | bool remove ( int uid ) | ||
289 | { | ||
290 | bool found = false; | ||
291 | QValueListIterator<OContact> it; | ||
292 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
293 | if ((*it).uid() == uid){ | ||
294 | found = true; | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | if (found) { | ||
299 | updateJournal ( *it, OContact::ACTION_REMOVE); | ||
300 | m_contactList.remove (it); | ||
301 | return true; | ||
302 | } else | ||
303 | return false; | ||
304 | } | ||
305 | |||
306 | bool reload(){ | ||
307 | /* Reload is the same as load in this implementation */ | ||
308 | return ( load() ); | ||
309 | } | ||
310 | |||
311 | private: | ||
312 | void addContact_p( const OContact &newcontact ){ | ||
313 | m_contactList.append (newcontact); | ||
314 | } | ||
315 | |||
316 | /* This function loads the xml-database and the journalfile */ | ||
317 | bool load( const QString filename, bool isJournal ) { | ||
318 | |||
319 | /* We use the time of the last read to check if the file was | ||
320 | * changed externally. | ||
321 | */ | ||
322 | if ( !isJournal ){ | ||
323 | QFileInfo fi( filename ); | ||
324 | m_readtime = fi.lastModified (); | ||
325 | } | ||
326 | |||
327 | const int JOURNALACTION = Qtopia::Notes + 1; | ||
328 | const int JOURNALROW = JOURNALACTION + 1; | ||
329 | |||
330 | bool foundAction = false; | ||
331 | OContact::journal_action action = OContact::ACTION_ADD; | ||
332 | int journalKey = 0; | ||
333 | QMap<int, QString> contactMap; | ||
334 | QMap<QString, QString> customMap; | ||
335 | QMap<QString, QString>::Iterator customIt; | ||
336 | QAsciiDict<int> dict( 47 ); | ||
337 | |||
338 | dict.setAutoDelete( TRUE ); | ||
339 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); | ||
340 | dict.insert( "Title", new int(Qtopia::Title) ); | ||
341 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); | ||
342 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); | ||
343 | dict.insert( "LastName", new int(Qtopia::LastName) ); | ||
344 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); | ||
345 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); | ||
346 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); | ||
347 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); | ||
348 | dict.insert( "Emails", new int(Qtopia::Emails) ); | ||
349 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); | ||
350 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); | ||
351 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); | ||
352 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); | ||
353 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); | ||
354 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); | ||
355 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); | ||
356 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); | ||
357 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); | ||
358 | dict.insert( "Company", new int(Qtopia::Company) ); | ||
359 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); | ||
360 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); | ||
361 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); | ||
362 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); | ||
363 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); | ||
364 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); | ||
365 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); | ||
366 | dict.insert( "Department", new int(Qtopia::Department) ); | ||
367 | dict.insert( "Office", new int(Qtopia::Office) ); | ||
368 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); | ||
369 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); | ||
370 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); | ||
371 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); | ||
372 | dict.insert( "Profession", new int(Qtopia::Profession) ); | ||
373 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); | ||
374 | dict.insert( "Manager", new int(Qtopia::Manager) ); | ||
375 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); | ||
376 | dict.insert( "Children", new int(Qtopia::Children) ); | ||
377 | dict.insert( "Gender", new int(Qtopia::Gender) ); | ||
378 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); | ||
379 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); | ||
380 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); | ||
381 | dict.insert( "Notes", new int(Qtopia::Notes) ); | ||
382 | dict.insert( "action", new int(JOURNALACTION) ); | ||
383 | dict.insert( "actionrow", new int(JOURNALROW) ); | ||
384 | |||
385 | //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); | ||
386 | |||
387 | XMLElement *root = XMLElement::load( filename ); | ||
388 | if(root != 0l ){ // start parsing | ||
389 | /* Parse all XML-Elements and put the data into the | ||
390 | * Contact-Class | ||
391 | */ | ||
392 | XMLElement *element = root->firstChild(); | ||
393 | //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); | ||
394 | element = element->firstChild(); | ||
395 | |||
396 | /* Search Tag "Contacts" which is the parent of all Contacts */ | ||
397 | while( element && !isJournal ){ | ||
398 | if( element->tagName() != QString::fromLatin1("Contacts") ){ | ||
399 | //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", | ||
400 | // element->tagName().latin1()); | ||
401 | element = element->nextChild(); | ||
402 | } else { | ||
403 | element = element->firstChild(); | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | /* Parse all Contacts and ignore unknown tags */ | ||
408 | while( element ){ | ||
409 | if( element->tagName() != QString::fromLatin1("Contact") ){ | ||
410 | //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", | ||
411 | // element->tagName().latin1()); | ||
412 | element = element->nextChild(); | ||
413 | continue; | ||
414 | } | ||
415 | /* Found alement with tagname "contact", now parse and store all | ||
416 | * attributes contained | ||
417 | */ | ||
418 | //qWarning("OContactDefBack::load element tagName() : %s", | ||
419 | // element->tagName().latin1() ); | ||
420 | QString dummy; | ||
421 | foundAction = false; | ||
422 | |||
423 | XMLElement::AttributeMap aMap = element->attributes(); | ||
424 | XMLElement::AttributeMap::Iterator it; | ||
425 | contactMap.clear(); | ||
426 | customMap.clear(); | ||
427 | for( it = aMap.begin(); it != aMap.end(); ++it ){ | ||
428 | // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); | ||
429 | |||
430 | int *find = dict[ it.key() ]; | ||
431 | /* Unknown attributes will be stored as "Custom" elements */ | ||
432 | if ( !find ) { | ||
433 | qWarning("Attribute %s not known.", it.key().latin1()); | ||
434 | //contact.setCustomField(it.key(), it.data()); | ||
435 | customMap.insert( it.key(), it.data() ); | ||
436 | continue; | ||
437 | } | ||
438 | |||
439 | /* Check if special conversion is needed and add attribute | ||
440 | * into Contact class | ||
441 | */ | ||
442 | switch( *find ) { | ||
443 | /* | ||
444 | case Qtopia::AddressUid: | ||
445 | contact.setUid( it.data().toInt() ); | ||
446 | break; | ||
447 | case Qtopia::AddressCategory: | ||
448 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); | ||
449 | break; | ||
450 | */ | ||
451 | case JOURNALACTION: | ||
452 | action = OContact::journal_action(it.data().toInt()); | ||
453 | foundAction = true; | ||
454 | qWarning ("ODefBack(journal)::ACTION found: %d", action); | ||
455 | break; | ||
456 | case JOURNALROW: | ||
457 | journalKey = it.data().toInt(); | ||
458 | break; | ||
459 | default: // no conversion needed add them to the map | ||
460 | contactMap.insert( *find, it.data() ); | ||
461 | break; | ||
462 | } | ||
463 | } | ||
464 | /* now generate the Contact contact */ | ||
465 | OContact contact( contactMap ); | ||
466 | |||
467 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { | ||
468 | contact.setCustomField( customIt.key(), customIt.data() ); | ||
469 | } | ||
470 | |||
471 | if (foundAction){ | ||
472 | foundAction = false; | ||
473 | switch ( action ) { | ||
474 | case OContact::ACTION_ADD: | ||
475 | addContact_p (contact); | ||
476 | break; | ||
477 | case OContact::ACTION_REMOVE: | ||
478 | if ( !remove (contact.uid()) ) | ||
479 | qWarning ("ODefBack(journal)::Unable to remove uid: %d", | ||
480 | contact.uid() ); | ||
481 | break; | ||
482 | case OContact::ACTION_REPLACE: | ||
483 | if ( !replace ( contact ) ) | ||
484 | qWarning ("ODefBack(journal)::Unable to replace uid: %d", | ||
485 | contact.uid() ); | ||
486 | break; | ||
487 | default: | ||
488 | qWarning ("Unknown action: ignored !"); | ||
489 | break; | ||
490 | } | ||
491 | }else{ | ||
492 | /* Add contact to list */ | ||
493 | addContact_p (contact); | ||
494 | } | ||
495 | |||
496 | /* Move to next element */ | ||
497 | element = element->nextChild(); | ||
498 | } | ||
499 | }else { | ||
500 | qWarning("ODefBack::could not load"); | ||
501 | } | ||
502 | delete root; | ||
503 | qWarning("returning from loading" ); | ||
504 | return true; | ||
505 | } | ||
506 | |||
507 | |||
508 | void updateJournal( const OContact& cnt, | ||
509 | OContact::journal_action action ) { | ||
510 | QFile f( m_journalName ); | ||
511 | bool created = !f.exists(); | ||
512 | if ( !f.open(IO_WriteOnly|IO_Append) ) | ||
513 | return; | ||
514 | |||
515 | QString buf; | ||
516 | QCString str; | ||
517 | |||
518 | // if the file was created, we have to set the Tag "<CONTACTS>" to | ||
519 | // get a XML-File which is readable by our parser. | ||
520 | // This is just a cheat, but better than rewrite the parser. | ||
521 | if ( created ){ | ||
522 | buf = "<Contacts>"; | ||
523 | QCString cstr = buf.utf8(); | ||
524 | f.writeBlock( cstr.data(), cstr.length() ); | ||
525 | } | ||
526 | |||
527 | buf = "<Contact "; | ||
528 | cnt.save( buf ); | ||
529 | buf += " action=\"" + QString::number( (int)action ) + "\" "; | ||
530 | buf += "/>\n"; | ||
531 | QCString cstr = buf.utf8(); | ||
532 | f.writeBlock( cstr.data(), cstr.length() ); | ||
533 | } | ||
534 | |||
535 | void removeJournal() | ||
536 | { | ||
537 | QFile f ( m_journalName ); | ||
538 | if ( f.exists() ) | ||
539 | f.remove(); | ||
540 | } | ||
541 | |||
542 | protected: | ||
543 | QString m_journalName; | ||
544 | QString m_fileName; | ||
545 | QString m_appName; | ||
546 | QValueList<OContact> m_contactList; | ||
547 | QDateTime m_readtime; | ||
548 | }; | ||
549 | |||
550 | #endif | ||
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h new file mode 100644 index 0000000..9469bbc --- a/dev/null +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /** | ||
2 | * The class responsible for managing a backend. | ||
3 | * The implementation of this abstract class contains | ||
4 | * the complete database handling. | ||
5 | * | ||
6 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
7 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | ||
8 | * | ||
9 | * ===================================================================== | ||
10 | *This program is free software; you can redistribute it and/or | ||
11 | *modify it under the terms of the GNU Library General Public | ||
12 | * License as published by the Free Software Foundation; | ||
13 | * either version 2 of the License, or (at your option) any later | ||
14 | * version. | ||
15 | * ===================================================================== | ||
16 | * ToDo: Define enum for query settings | ||
17 | * ===================================================================== | ||
18 | * Version: $Id$ | ||
19 | * ===================================================================== | ||
20 | * History: | ||
21 | * $Log$ | ||
22 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
23 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
24 | * please do not expect that anything is working ! | ||
25 | * I will debug that stuff in the next time .. | ||
26 | * Please read README_COMPILE for compiling ! | ||
27 | * | ||
28 | * ===================================================================== | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef _OCONTACTACCESSBACKEND_H_ | ||
33 | #define _OCONTACTACCESSBACKEND_H_ | ||
34 | |||
35 | #include "opimaccessbackend.h" | ||
36 | |||
37 | class OContactAccessBackend: public OPimAccessBackend<OContact> { | ||
38 | public: | ||
39 | OContactAccessBackend() {} | ||
40 | virtual ~OContactAccessBackend() {} | ||
41 | |||
42 | |||
43 | /** Return if database was changed externally. | ||
44 | * This may just make sense on file based databases like a XML-File. | ||
45 | * It is used to prevent to overwrite the current database content | ||
46 | * if the file was already changed by something else ! | ||
47 | * If this happens, we have to reload before save our data. | ||
48 | * If we use real databases, this should be handled by the database | ||
49 | * management system themselve, therefore this function should always return false in | ||
50 | * this case. It is not our problem to handle this conflict ... | ||
51 | * @return <i>true</i> if the database was changed and if save without reload will | ||
52 | * be dangerous. <i>false</i> if the database was not changed or it is save to write | ||
53 | * in this situation. | ||
54 | */ | ||
55 | virtual bool wasChangedExternally() = 0; | ||
56 | |||
57 | /** Return all possible settings. | ||
58 | * @return All settings provided by the current backend | ||
59 | * (i.e.: query_WildCards & query_IgnoreCase) | ||
60 | */ | ||
61 | virtual const uint querySettings() = 0; | ||
62 | |||
63 | /** Check whether settings are correct. | ||
64 | * @return <i>true</i> if the given settings are correct and possible. | ||
65 | */ | ||
66 | virtual bool hasQuerySettings (uint querySettings) const = 0; | ||
67 | |||
68 | |||
69 | }; | ||
70 | #endif | ||
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h new file mode 100644 index 0000000..2cdb45b --- a/dev/null +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h | |||
@@ -0,0 +1,550 @@ | |||
1 | /* | ||
2 | * XML Backend for the OPIE-Contact Database. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * ToDo: XML-Backend: Automatic reload if something was changed... | ||
13 | * | ||
14 | * | ||
15 | * ===================================================================== | ||
16 | * Version: $Id$ | ||
17 | * ===================================================================== | ||
18 | * History: | ||
19 | * $Log$ | ||
20 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
21 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
22 | * please do not expect that anything is working ! | ||
23 | * I will debug that stuff in the next time .. | ||
24 | * Please read README_COMPILE for compiling ! | ||
25 | * | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #ifndef _OContactAccessBackend_XML_ | ||
30 | #define _OContactAccessBackend_XML_ | ||
31 | |||
32 | #include <qasciidict.h> | ||
33 | #include <qdatetime.h> | ||
34 | #include <qfile.h> | ||
35 | #include <qregexp.h> | ||
36 | #include <qarray.h> | ||
37 | |||
38 | #include <opie/xmltree.h> | ||
39 | #include "ocontactaccessbackend.h" | ||
40 | |||
41 | using namespace Opie; | ||
42 | |||
43 | /* the default xml implementation */ | ||
44 | class OContactAccessBackend_XML : public OContactAccessBackend { | ||
45 | public: | ||
46 | OContactAccessBackend_XML ( QString appname, QString filename = 0l ) | ||
47 | { | ||
48 | m_appName = appname; | ||
49 | |||
50 | /* Set journalfile name ... */ | ||
51 | m_journalName = getenv("HOME"); | ||
52 | m_journalName +="/.abjournal" + appname; | ||
53 | |||
54 | /* Expecting to access the default filename if nothing else is set */ | ||
55 | if ( filename.isEmpty() ){ | ||
56 | m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); | ||
57 | } else | ||
58 | m_fileName = filename; | ||
59 | |||
60 | /* Load Database now */ | ||
61 | load (); | ||
62 | } | ||
63 | |||
64 | bool save() { | ||
65 | QString strNewFile = m_fileName + ".new"; | ||
66 | QFile f( strNewFile ); | ||
67 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) | ||
68 | return false; | ||
69 | |||
70 | int total_written; | ||
71 | QString out; | ||
72 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" | ||
73 | " <Groups>\n" | ||
74 | " </Groups>\n" | ||
75 | " <Contacts>\n"; | ||
76 | //QValueList<Contact>::iterator it; | ||
77 | QValueListConstIterator<OContact> it; | ||
78 | for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { | ||
79 | out += "<Contact "; | ||
80 | (*it).save( out ); | ||
81 | out += "/>\n"; | ||
82 | QCString cstr = out.utf8(); | ||
83 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | ||
84 | if ( total_written != int(cstr.length()) ) { | ||
85 | f.close(); | ||
86 | QFile::remove( strNewFile ); | ||
87 | return false; | ||
88 | } | ||
89 | out = ""; | ||
90 | } | ||
91 | out += " </Contacts>\n</AddressBook>\n"; | ||
92 | |||
93 | QCString cstr = out.utf8(); | ||
94 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | ||
95 | if ( total_written != int( cstr.length() ) ) { | ||
96 | f.close(); | ||
97 | QFile::remove( strNewFile ); | ||
98 | return false; | ||
99 | } | ||
100 | f.close(); | ||
101 | |||
102 | // move the file over, I'm just going to use the system call | ||
103 | // because, I don't feel like using QDir. | ||
104 | if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { | ||
105 | qWarning( "problem renaming file %s to %s, errno: %d", | ||
106 | strNewFile.latin1(), m_journalName.latin1(), errno ); | ||
107 | // remove the tmp file... | ||
108 | QFile::remove( strNewFile ); | ||
109 | } | ||
110 | |||
111 | /* The journalfile should be removed now... */ | ||
112 | removeJournal(); | ||
113 | return true; | ||
114 | } | ||
115 | |||
116 | bool load () { | ||
117 | m_contactList.clear(); | ||
118 | |||
119 | /* Load XML-File and journal if it exists */ | ||
120 | if ( !load ( m_fileName, false ) ) | ||
121 | return false; | ||
122 | /* The returncode of the journalfile is ignored due to the | ||
123 | * fact that it does not exist when this class is instantiated ! | ||
124 | * But there may such a file exist, if the application crashed. | ||
125 | * Therefore we try to load it to get the changes before the # | ||
126 | * crash happened... | ||
127 | */ | ||
128 | load (m_journalName, true); | ||
129 | |||
130 | return true; | ||
131 | } | ||
132 | |||
133 | void clear () { | ||
134 | m_contactList.clear(); | ||
135 | |||
136 | } | ||
137 | |||
138 | bool wasChangedExternally() | ||
139 | { | ||
140 | QFileInfo fi( m_fileName ); | ||
141 | |||
142 | QDateTime lastmod = fi.lastModified (); | ||
143 | |||
144 | return (lastmod != m_readtime); | ||
145 | } | ||
146 | |||
147 | QArray<int> allRecords() const { | ||
148 | QArray<int> uid_list( m_contactList.count() ); | ||
149 | |||
150 | uint counter = 0; | ||
151 | QValueListConstIterator<OContact> it; | ||
152 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
153 | uid_list[counter++] = (*it).uid(); | ||
154 | } | ||
155 | |||
156 | return ( uid_list ); | ||
157 | } | ||
158 | |||
159 | OContact find ( int uid ) const | ||
160 | { | ||
161 | bool found = false; | ||
162 | OContact foundContact; //Create empty contact | ||
163 | |||
164 | QValueListConstIterator<OContact> it; | ||
165 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
166 | if ((*it).uid() == uid){ | ||
167 | found = true; | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | if ( found ){ | ||
172 | foundContact = *it; | ||
173 | } | ||
174 | |||
175 | return ( foundContact ); | ||
176 | } | ||
177 | |||
178 | QArray<int> queryByExample ( const OContact &query, int settings ){ | ||
179 | |||
180 | QArray<int> m_currentQuery( m_contactList.count() ); | ||
181 | QValueListConstIterator<OContact> it; | ||
182 | uint arraycounter = 0; | ||
183 | |||
184 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
185 | /* Search all fields and compare them with query object. Store them into list | ||
186 | * if all fields matches. | ||
187 | */ | ||
188 | bool allcorrect = true; | ||
189 | for ( int i = 0; i < Qtopia::rid; i++ ) { | ||
190 | /* Just compare fields which are not empty in the query object */ | ||
191 | if ( !query.field(i).isEmpty() ){ | ||
192 | switch ( settings & ~OContactAccess::query_IgnoreCase ){ | ||
193 | case OContactAccess::query_RegExp:{ | ||
194 | QRegExp expr ( query.field(i), | ||
195 | !(settings & OContactAccess::query_IgnoreCase), | ||
196 | false ); | ||
197 | if ( expr.find ( (*it).field(i), 0 ) == -1 ) | ||
198 | allcorrect = false; | ||
199 | } | ||
200 | break; | ||
201 | case OContactAccess::query_WildCards:{ | ||
202 | QRegExp expr ( query.field(i), | ||
203 | !(settings & OContactAccess::query_IgnoreCase), | ||
204 | true ); | ||
205 | if ( expr.find ( (*it).field(i), 0 ) == -1 ) | ||
206 | allcorrect = false; | ||
207 | } | ||
208 | break; | ||
209 | case OContactAccess::query_ExactMatch:{ | ||
210 | if (settings & OContactAccess::query_IgnoreCase){ | ||
211 | if ( query.field(i).upper() != | ||
212 | (*it).field(i).upper() ) | ||
213 | allcorrect = false; | ||
214 | }else{ | ||
215 | if ( query.field(i) != (*it).field(i) ) | ||
216 | allcorrect = false; | ||
217 | } | ||
218 | } | ||
219 | break; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | if ( allcorrect ){ | ||
224 | m_currentQuery[arraycounter++] = (*it).uid(); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | // Shrink to fit.. | ||
229 | m_currentQuery.resize(arraycounter); | ||
230 | |||
231 | return m_currentQuery; | ||
232 | } | ||
233 | |||
234 | const uint querySettings() | ||
235 | { | ||
236 | return ( OContactAccess::query_WildCards | ||
237 | & OContactAccess::query_IgnoreCase | ||
238 | & OContactAccess::query_RegExp | ||
239 | & OContactAccess::query_ExactMatch ); | ||
240 | } | ||
241 | |||
242 | bool hasQuerySettings (uint querySettings) const | ||
243 | { | ||
244 | /* OContactAccess::query_IgnoreCase may be added with one | ||
245 | * of the other settings, but never used alone. | ||
246 | * The other settings are just valid alone... | ||
247 | */ | ||
248 | switch ( querySettings & ~OContactAccess::query_IgnoreCase ){ | ||
249 | case OContactAccess::query_RegExp: | ||
250 | return ( true ); | ||
251 | case OContactAccess::query_WildCards: | ||
252 | return ( true ); | ||
253 | case OContactAccess::query_ExactMatch: | ||
254 | return ( true ); | ||
255 | default: | ||
256 | return ( false ); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | bool add ( const OContact &newcontact ) | ||
261 | { | ||
262 | //qWarning("odefaultbackend: ACTION::ADD"); | ||
263 | updateJournal (newcontact, OContact::ACTION_ADD); | ||
264 | addContact_p( newcontact ); | ||
265 | return true; | ||
266 | } | ||
267 | |||
268 | bool replace ( const OContact &contact ) | ||
269 | { | ||
270 | bool found = false; | ||
271 | |||
272 | QValueListIterator<OContact> it; | ||
273 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
274 | if ( (*it).uid() == contact.uid() ){ | ||
275 | found = true; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if (found) { | ||
280 | updateJournal (contact, OContact::ACTION_REPLACE); | ||
281 | m_contactList.remove (it); | ||
282 | m_contactList.append (contact); | ||
283 | return true; | ||
284 | } else | ||
285 | return false; | ||
286 | } | ||
287 | |||
288 | bool remove ( int uid ) | ||
289 | { | ||
290 | bool found = false; | ||
291 | QValueListIterator<OContact> it; | ||
292 | for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ | ||
293 | if ((*it).uid() == uid){ | ||
294 | found = true; | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | if (found) { | ||
299 | updateJournal ( *it, OContact::ACTION_REMOVE); | ||
300 | m_contactList.remove (it); | ||
301 | return true; | ||
302 | } else | ||
303 | return false; | ||
304 | } | ||
305 | |||
306 | bool reload(){ | ||
307 | /* Reload is the same as load in this implementation */ | ||
308 | return ( load() ); | ||
309 | } | ||
310 | |||
311 | private: | ||
312 | void addContact_p( const OContact &newcontact ){ | ||
313 | m_contactList.append (newcontact); | ||
314 | } | ||
315 | |||
316 | /* This function loads the xml-database and the journalfile */ | ||
317 | bool load( const QString filename, bool isJournal ) { | ||
318 | |||
319 | /* We use the time of the last read to check if the file was | ||
320 | * changed externally. | ||
321 | */ | ||
322 | if ( !isJournal ){ | ||
323 | QFileInfo fi( filename ); | ||
324 | m_readtime = fi.lastModified (); | ||
325 | } | ||
326 | |||
327 | const int JOURNALACTION = Qtopia::Notes + 1; | ||
328 | const int JOURNALROW = JOURNALACTION + 1; | ||
329 | |||
330 | bool foundAction = false; | ||
331 | OContact::journal_action action = OContact::ACTION_ADD; | ||
332 | int journalKey = 0; | ||
333 | QMap<int, QString> contactMap; | ||
334 | QMap<QString, QString> customMap; | ||
335 | QMap<QString, QString>::Iterator customIt; | ||
336 | QAsciiDict<int> dict( 47 ); | ||
337 | |||
338 | dict.setAutoDelete( TRUE ); | ||
339 | dict.insert( "Uid", new int(Qtopia::AddressUid) ); | ||
340 | dict.insert( "Title", new int(Qtopia::Title) ); | ||
341 | dict.insert( "FirstName", new int(Qtopia::FirstName) ); | ||
342 | dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); | ||
343 | dict.insert( "LastName", new int(Qtopia::LastName) ); | ||
344 | dict.insert( "Suffix", new int(Qtopia::Suffix) ); | ||
345 | dict.insert( "FileAs", new int(Qtopia::FileAs) ); | ||
346 | dict.insert( "Categories", new int(Qtopia::AddressCategory) ); | ||
347 | dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); | ||
348 | dict.insert( "Emails", new int(Qtopia::Emails) ); | ||
349 | dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); | ||
350 | dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); | ||
351 | dict.insert( "HomeState", new int(Qtopia::HomeState) ); | ||
352 | dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); | ||
353 | dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); | ||
354 | dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); | ||
355 | dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); | ||
356 | dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); | ||
357 | dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); | ||
358 | dict.insert( "Company", new int(Qtopia::Company) ); | ||
359 | dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); | ||
360 | dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); | ||
361 | dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); | ||
362 | dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); | ||
363 | dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); | ||
364 | dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); | ||
365 | dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); | ||
366 | dict.insert( "Department", new int(Qtopia::Department) ); | ||
367 | dict.insert( "Office", new int(Qtopia::Office) ); | ||
368 | dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); | ||
369 | dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); | ||
370 | dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); | ||
371 | dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); | ||
372 | dict.insert( "Profession", new int(Qtopia::Profession) ); | ||
373 | dict.insert( "Assistant", new int(Qtopia::Assistant) ); | ||
374 | dict.insert( "Manager", new int(Qtopia::Manager) ); | ||
375 | dict.insert( "Spouse", new int(Qtopia::Spouse) ); | ||
376 | dict.insert( "Children", new int(Qtopia::Children) ); | ||
377 | dict.insert( "Gender", new int(Qtopia::Gender) ); | ||
378 | dict.insert( "Birthday", new int(Qtopia::Birthday) ); | ||
379 | dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); | ||
380 | dict.insert( "Nickname", new int(Qtopia::Nickname) ); | ||
381 | dict.insert( "Notes", new int(Qtopia::Notes) ); | ||
382 | dict.insert( "action", new int(JOURNALACTION) ); | ||
383 | dict.insert( "actionrow", new int(JOURNALROW) ); | ||
384 | |||
385 | //qWarning( "OContactDefaultBackEnd::loading %s", filename.latin1() ); | ||
386 | |||
387 | XMLElement *root = XMLElement::load( filename ); | ||
388 | if(root != 0l ){ // start parsing | ||
389 | /* Parse all XML-Elements and put the data into the | ||
390 | * Contact-Class | ||
391 | */ | ||
392 | XMLElement *element = root->firstChild(); | ||
393 | //qWarning("OContactAccess::load tagName(): %s", root->tagName().latin1() ); | ||
394 | element = element->firstChild(); | ||
395 | |||
396 | /* Search Tag "Contacts" which is the parent of all Contacts */ | ||
397 | while( element && !isJournal ){ | ||
398 | if( element->tagName() != QString::fromLatin1("Contacts") ){ | ||
399 | //qWarning ("OContactDefBack::Searching for Tag \"Contacts\"! Found: %s", | ||
400 | // element->tagName().latin1()); | ||
401 | element = element->nextChild(); | ||
402 | } else { | ||
403 | element = element->firstChild(); | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | /* Parse all Contacts and ignore unknown tags */ | ||
408 | while( element ){ | ||
409 | if( element->tagName() != QString::fromLatin1("Contact") ){ | ||
410 | //qWarning ("OContactDefBack::Searching for Tag \"Contact\"! Found: %s", | ||
411 | // element->tagName().latin1()); | ||
412 | element = element->nextChild(); | ||
413 | continue; | ||
414 | } | ||
415 | /* Found alement with tagname "contact", now parse and store all | ||
416 | * attributes contained | ||
417 | */ | ||
418 | //qWarning("OContactDefBack::load element tagName() : %s", | ||
419 | // element->tagName().latin1() ); | ||
420 | QString dummy; | ||
421 | foundAction = false; | ||
422 | |||
423 | XMLElement::AttributeMap aMap = element->attributes(); | ||
424 | XMLElement::AttributeMap::Iterator it; | ||
425 | contactMap.clear(); | ||
426 | customMap.clear(); | ||
427 | for( it = aMap.begin(); it != aMap.end(); ++it ){ | ||
428 | // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); | ||
429 | |||
430 | int *find = dict[ it.key() ]; | ||
431 | /* Unknown attributes will be stored as "Custom" elements */ | ||
432 | if ( !find ) { | ||
433 | qWarning("Attribute %s not known.", it.key().latin1()); | ||
434 | //contact.setCustomField(it.key(), it.data()); | ||
435 | customMap.insert( it.key(), it.data() ); | ||
436 | continue; | ||
437 | } | ||
438 | |||
439 | /* Check if special conversion is needed and add attribute | ||
440 | * into Contact class | ||
441 | */ | ||
442 | switch( *find ) { | ||
443 | /* | ||
444 | case Qtopia::AddressUid: | ||
445 | contact.setUid( it.data().toInt() ); | ||
446 | break; | ||
447 | case Qtopia::AddressCategory: | ||
448 | contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); | ||
449 | break; | ||
450 | */ | ||
451 | case JOURNALACTION: | ||
452 | action = OContact::journal_action(it.data().toInt()); | ||
453 | foundAction = true; | ||
454 | qWarning ("ODefBack(journal)::ACTION found: %d", action); | ||
455 | break; | ||
456 | case JOURNALROW: | ||
457 | journalKey = it.data().toInt(); | ||
458 | break; | ||
459 | default: // no conversion needed add them to the map | ||
460 | contactMap.insert( *find, it.data() ); | ||
461 | break; | ||
462 | } | ||
463 | } | ||
464 | /* now generate the Contact contact */ | ||
465 | OContact contact( contactMap ); | ||
466 | |||
467 | for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { | ||
468 | contact.setCustomField( customIt.key(), customIt.data() ); | ||
469 | } | ||
470 | |||
471 | if (foundAction){ | ||
472 | foundAction = false; | ||
473 | switch ( action ) { | ||
474 | case OContact::ACTION_ADD: | ||
475 | addContact_p (contact); | ||
476 | break; | ||
477 | case OContact::ACTION_REMOVE: | ||
478 | if ( !remove (contact.uid()) ) | ||
479 | qWarning ("ODefBack(journal)::Unable to remove uid: %d", | ||
480 | contact.uid() ); | ||
481 | break; | ||
482 | case OContact::ACTION_REPLACE: | ||
483 | if ( !replace ( contact ) ) | ||
484 | qWarning ("ODefBack(journal)::Unable to replace uid: %d", | ||
485 | contact.uid() ); | ||
486 | break; | ||
487 | default: | ||
488 | qWarning ("Unknown action: ignored !"); | ||
489 | break; | ||
490 | } | ||
491 | }else{ | ||
492 | /* Add contact to list */ | ||
493 | addContact_p (contact); | ||
494 | } | ||
495 | |||
496 | /* Move to next element */ | ||
497 | element = element->nextChild(); | ||
498 | } | ||
499 | }else { | ||
500 | qWarning("ODefBack::could not load"); | ||
501 | } | ||
502 | delete root; | ||
503 | qWarning("returning from loading" ); | ||
504 | return true; | ||
505 | } | ||
506 | |||
507 | |||
508 | void updateJournal( const OContact& cnt, | ||
509 | OContact::journal_action action ) { | ||
510 | QFile f( m_journalName ); | ||
511 | bool created = !f.exists(); | ||
512 | if ( !f.open(IO_WriteOnly|IO_Append) ) | ||
513 | return; | ||
514 | |||
515 | QString buf; | ||
516 | QCString str; | ||
517 | |||
518 | // if the file was created, we have to set the Tag "<CONTACTS>" to | ||
519 | // get a XML-File which is readable by our parser. | ||
520 | // This is just a cheat, but better than rewrite the parser. | ||
521 | if ( created ){ | ||
522 | buf = "<Contacts>"; | ||
523 | QCString cstr = buf.utf8(); | ||
524 | f.writeBlock( cstr.data(), cstr.length() ); | ||
525 | } | ||
526 | |||
527 | buf = "<Contact "; | ||
528 | cnt.save( buf ); | ||
529 | buf += " action=\"" + QString::number( (int)action ) + "\" "; | ||
530 | buf += "/>\n"; | ||
531 | QCString cstr = buf.utf8(); | ||
532 | f.writeBlock( cstr.data(), cstr.length() ); | ||
533 | } | ||
534 | |||
535 | void removeJournal() | ||
536 | { | ||
537 | QFile f ( m_journalName ); | ||
538 | if ( f.exists() ) | ||
539 | f.remove(); | ||
540 | } | ||
541 | |||
542 | protected: | ||
543 | QString m_journalName; | ||
544 | QString m_fileName; | ||
545 | QString m_appName; | ||
546 | QValueList<OContact> m_contactList; | ||
547 | QDateTime m_readtime; | ||
548 | }; | ||
549 | |||
550 | #endif | ||
diff --git a/libopie2/opiepim/core/ocontactaccess.cpp b/libopie2/opiepim/core/ocontactaccess.cpp new file mode 100644 index 0000000..2d808f7 --- a/dev/null +++ b/libopie2/opiepim/core/ocontactaccess.cpp | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * Class to manage the Contacts. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * | ||
6 | * ===================================================================== | ||
7 | *This program is free software; you can redistribute it and/or | ||
8 | *modify it under the terms of the GNU Library General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2 of the License, or (at your option) any later version. | ||
11 | * ===================================================================== | ||
12 | * Info: This class could just work with a change in the header-file | ||
13 | * of the Contact class ! Therefore our libopie only compiles | ||
14 | * with our version of libqpe | ||
15 | * ===================================================================== | ||
16 | * ToDo: XML-Backend: Automatic reload if something was changed... | ||
17 | * | ||
18 | * | ||
19 | * ===================================================================== | ||
20 | * Version: $Id$ | ||
21 | * ===================================================================== | ||
22 | * History: | ||
23 | * $Log$ | ||
24 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
25 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
26 | * please do not expect that anything is working ! | ||
27 | * I will debug that stuff in the next time .. | ||
28 | * Please read README_COMPILE for compiling ! | ||
29 | * | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include "ocontactaccess.h" | ||
34 | |||
35 | #include <qasciidict.h> | ||
36 | #include <qdatetime.h> | ||
37 | #include <qfile.h> | ||
38 | #include <qregexp.h> | ||
39 | #include <qlist.h> | ||
40 | #include <qcopchannel_qws.h> | ||
41 | |||
42 | //#include <qpe/qcopenvelope_qws.h> | ||
43 | #include <qpe/global.h> | ||
44 | |||
45 | #include <errno.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <unistd.h> | ||
48 | #include <stdlib.h> | ||
49 | |||
50 | #include "ocontactaccessbackend_xml.h" | ||
51 | |||
52 | |||
53 | OContactAccess::OContactAccess ( const QString appname, const QString filename, | ||
54 | OContactAccessBackend* end, bool autosync ): | ||
55 | OPimAccessTemplate<OContact>( end ), | ||
56 | m_changed ( false ) | ||
57 | { | ||
58 | /* take care of the backend. If there is no one defined, we | ||
59 | * will use the XML-Backend as default (until we have a cute SQL-Backend..). | ||
60 | */ | ||
61 | if( end == 0 ) { | ||
62 | end = new OContactAccessBackend_XML( appname, filename ); | ||
63 | } | ||
64 | m_backEnd = end; | ||
65 | |||
66 | /* Connect signal of external db change to function */ | ||
67 | QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); | ||
68 | connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), | ||
69 | this, SLOT(copMessage( const QCString &, const QByteArray &)) ); | ||
70 | if ( autosync ){ | ||
71 | QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); | ||
72 | connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), | ||
73 | this, SLOT(copMessage( const QCString &, const QByteArray &)) ); | ||
74 | } | ||
75 | |||
76 | |||
77 | } | ||
78 | OContactAccess::~OContactAccess () | ||
79 | { | ||
80 | /* The user may forget to save the changed database, therefore try to | ||
81 | * do it for him.. | ||
82 | */ | ||
83 | if ( m_changed ) | ||
84 | save(); | ||
85 | delete m_backEnd; | ||
86 | } | ||
87 | |||
88 | bool OContactAccess::load() | ||
89 | { | ||
90 | return ( m_backEnd->load() ); | ||
91 | } | ||
92 | |||
93 | bool OContactAccess::save () | ||
94 | { | ||
95 | /* If the database was changed externally, we could not save the | ||
96 | * Data. This will remove added items which is unacceptable ! | ||
97 | * Therefore: Reload database and merge the data... | ||
98 | */ | ||
99 | if ( m_backEnd->wasChangedExternally() ) | ||
100 | reload(); | ||
101 | |||
102 | if ( m_changed ){ | ||
103 | bool status = m_backEnd->save(); | ||
104 | if ( !status ) return false; | ||
105 | |||
106 | m_changed = false; | ||
107 | /* Now tell everyone that new data is available. | ||
108 | */ | ||
109 | QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); | ||
110 | |||
111 | } | ||
112 | |||
113 | return true; | ||
114 | } | ||
115 | |||
116 | const uint OContactAccess::querySettings() | ||
117 | { | ||
118 | return ( m_backEnd->querySettings() ); | ||
119 | } | ||
120 | |||
121 | bool OContactAccess::hasQuerySettings ( int querySettings ) const | ||
122 | { | ||
123 | return ( m_backEnd->hasQuerySettings ( querySettings ) ); | ||
124 | } | ||
125 | |||
126 | bool OContactAccess::add ( const OContact& newcontact ) | ||
127 | { | ||
128 | m_changed = true; | ||
129 | return ( m_backEnd->add ( newcontact ) ); | ||
130 | } | ||
131 | |||
132 | bool OContactAccess::replace ( const OContact& contact ) | ||
133 | { | ||
134 | m_changed = true; | ||
135 | return ( m_backEnd->replace ( contact ) ); | ||
136 | } | ||
137 | |||
138 | bool OContactAccess::remove ( const OContact& t ) | ||
139 | { | ||
140 | m_changed = true; | ||
141 | return ( m_backEnd->remove ( t.uid() ) ); | ||
142 | } | ||
143 | |||
144 | bool OContactAccess::remove ( int uid ) | ||
145 | { | ||
146 | m_changed = true; | ||
147 | return ( m_backEnd->remove ( uid ) ); | ||
148 | } | ||
149 | |||
150 | bool OContactAccess::wasChangedExternally()const | ||
151 | { | ||
152 | return ( m_backEnd->wasChangedExternally() ); | ||
153 | } | ||
154 | |||
155 | |||
156 | bool OContactAccess::reload() | ||
157 | { | ||
158 | return ( m_backEnd->reload() ); | ||
159 | } | ||
160 | |||
161 | void OContactAccess::copMessage( const QCString &msg, const QByteArray & ) | ||
162 | { | ||
163 | if ( msg == "addressbookUpdated()" ){ | ||
164 | qWarning ("OContactAccess: Received addressbokUpdated()"); | ||
165 | emit signalChanged ( this ); | ||
166 | } else if ( msg == "flush()" ) { | ||
167 | qWarning ("OContactAccess: Received flush()"); | ||
168 | save (); | ||
169 | } else if ( msg == "reload()" ) { | ||
170 | qWarning ("OContactAccess: Received reload()"); | ||
171 | reload (); | ||
172 | emit signalChanged ( this ); | ||
173 | } | ||
174 | } | ||
diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h new file mode 100644 index 0000000..54f7f07 --- a/dev/null +++ b/libopie2/opiepim/core/ocontactaccess.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Class to manage the Contacts. | ||
3 | * | ||
4 | * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) | ||
5 | * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) | ||
6 | * | ||
7 | * ===================================================================== | ||
8 | *This program is free software; you can redistribute it and/or | ||
9 | *modify it under the terms of the GNU Library General Public | ||
10 | * License as published by the Free Software Foundation; | ||
11 | * either version 2 of the License, or (at your option) any later | ||
12 | * version. | ||
13 | * ===================================================================== | ||
14 | * ToDo: Define enum for query settings | ||
15 | * ===================================================================== | ||
16 | * Version: $Id$ | ||
17 | * ===================================================================== | ||
18 | * History: | ||
19 | * $Log$ | ||
20 | * Revision 1.1 2002/09/27 17:11:44 eilers | ||
21 | * Added API for accessing the Contact-Database ! It is compiling, but | ||
22 | * please do not expect that anything is working ! | ||
23 | * I will debug that stuff in the next time .. | ||
24 | * Please read README_COMPILE for compiling ! | ||
25 | * | ||
26 | * ===================================================================== | ||
27 | */ | ||
28 | #ifndef _OCONTACTACCESS_H | ||
29 | #define _OCONTACTACCESS_H | ||
30 | |||
31 | #include <qobject.h> | ||
32 | |||
33 | #include <qpe/qcopenvelope_qws.h> | ||
34 | |||
35 | #include <qvaluelist.h> | ||
36 | #include <qfileinfo.h> | ||
37 | |||
38 | #include "ocontact.h" | ||
39 | #include "ocontactaccessbackend.h" | ||
40 | #include "opimaccesstemplate.h" | ||
41 | |||
42 | /** Class to access the contacts database. | ||
43 | * This is just a frontend for the real database handling which is | ||
44 | * done by the backend. | ||
45 | */ | ||
46 | class OContactAccess: public QObject, public OPimAccessTemplate<OContact> | ||
47 | { | ||
48 | Q_OBJECT | ||
49 | |||
50 | |||
51 | /* class Iterator{ | ||
52 | friend OContactAccess; | ||
53 | public: | ||
54 | Iterator(); | ||
55 | Iterator ( const Iterator& copy ); | ||
56 | |||
57 | bool operator== ( const Iterator& it ); | ||
58 | bool operator!= ( const Iterator& it ); | ||
59 | Iterator& operator= ( const Iterator& it ); | ||
60 | Iterator& operator++ (); // prefix | ||
61 | Iterator operator++ ( int ); // postfix | ||
62 | Iterator& operator-- (); // prefix | ||
63 | Iterator operator-- ( int ); // postfix | ||
64 | Contact operator*() const; | ||
65 | Contact operator->() const; | ||
66 | |||
67 | Iterator begin(); | ||
68 | Iterator end(); | ||
69 | |||
70 | uint count() const; | ||
71 | |||
72 | private: | ||
73 | QValueList<int> m_uids; | ||
74 | int m_cur_position; | ||
75 | bool m_end_reached; | ||
76 | OContactAccess *m_db; | ||
77 | |||
78 | }; | ||
79 | |||
80 | */ | ||
81 | |||
82 | public: | ||
83 | /** Create Database with contacts (addressbook). | ||
84 | * @param appname Name of application which wants access to the database | ||
85 | * (i.e. "todolist") | ||
86 | * @param filename The name of the database file. If not set, the default one | ||
87 | * is used. | ||
88 | * @param backend Pointer to an alternative Backend. If not set, we will use | ||
89 | * the default backend. | ||
90 | * @param handlesync If <b>true</b> the database stores the current state | ||
91 | * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> | ||
92 | * which are used before and after synchronisation. If the application wants | ||
93 | * to react itself, it should be disabled by setting it to <b>false</b> | ||
94 | * @see OContactBackend | ||
95 | */ | ||
96 | OContactAccess (const QString appname, const QString filename = 0l, | ||
97 | OContactAccessBackend* backend = 0l, bool handlesync = true); | ||
98 | ~OContactAccess (); | ||
99 | |||
100 | /** Constants for query. | ||
101 | * Use this constants to set the query parameters. | ||
102 | * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! | ||
103 | * @see queryByExample() | ||
104 | * - why not enum - zecke? | ||
105 | * -> Had some implementation problems .. Will use enum soon ! .. (se) | ||
106 | */ | ||
107 | static const int query_WildCards = 0x0001; | ||
108 | static const int query_IgnoreCase = 0x0002; | ||
109 | static const int query_RegExp = 0x0004; | ||
110 | static const int query_ExactMatch = 0x0008; | ||
111 | |||
112 | /** Return all possible settings. | ||
113 | * @return All settings provided by the current backend | ||
114 | * (i.e.: query_WildCards & query_IgnoreCase) | ||
115 | */ | ||
116 | const uint querySettings(); | ||
117 | |||
118 | /** Check whether settings are correct. | ||
119 | * @return <i>true</i> if the given settings are correct and possible. | ||
120 | */ | ||
121 | bool hasQuerySettings ( int querySettings ) const; | ||
122 | |||
123 | /** Add Contact to database. | ||
124 | * @param newcontact The contact to add. | ||
125 | * @return <i>true</i> if added successfully. | ||
126 | */ | ||
127 | bool add (const OContact& newcontact); | ||
128 | |||
129 | /** Replace contact. | ||
130 | * Replaces given contact with contact with the user id <i>uid</i>. | ||
131 | * @param uid The user ID | ||
132 | * @param contact The new contact | ||
133 | * @return <i>true</i> if successful. | ||
134 | */ | ||
135 | bool replace ( const OContact& contact ); | ||
136 | |||
137 | /** Remove contact. | ||
138 | * Removes contact with the user id <i>uid</i>. | ||
139 | * @param The contact to remove | ||
140 | * @return <i>true</i> if successful. | ||
141 | */ | ||
142 | bool remove ( const OContact& t ); | ||
143 | |||
144 | /** Remove contact. | ||
145 | * Removes contact with the user id <i>uid</i>. | ||
146 | * @param The user id of the contact to remove | ||
147 | * @return <i>true</i> if successful. | ||
148 | */ | ||
149 | bool remove ( int uid ); | ||
150 | |||
151 | /** Load Database * | ||
152 | */ | ||
153 | bool load(); | ||
154 | |||
155 | /** | ||
156 | * if the resource was changed externally. | ||
157 | * You should use the signal instead of polling possible changes ! | ||
158 | */ | ||
159 | bool wasChangedExternally()const; | ||
160 | |||
161 | /** Reload database. | ||
162 | * You should execute this function if the external database | ||
163 | * was changed. | ||
164 | * This function will load the external database and afterwards | ||
165 | * rejoin the local changes. Therefore the local database will be set consistent. | ||
166 | */ | ||
167 | bool reload(); | ||
168 | |||
169 | /** Save contacts database. | ||
170 | * Save is more a "commit". After calling this function, all changes are public available. | ||
171 | * @return true if successful | ||
172 | */ | ||
173 | bool save(); | ||
174 | |||
175 | signals: | ||
176 | /* Signal is emitted if the database was changed. Therefore | ||
177 | * we may need to reload to stay consistent. | ||
178 | * @param which Pointer to the database who created this event. This pointer | ||
179 | * is useful if an application has to handle multiple databases at the same time. | ||
180 | * @see reload() | ||
181 | */ | ||
182 | void signalChanged ( const OContactAccess *which ); | ||
183 | |||
184 | |||
185 | private: | ||
186 | // class OContactAccessPrivate; | ||
187 | // OContactAccessPrivate* d; | ||
188 | OContactAccessBackend *m_backEnd; | ||
189 | bool m_loading:1; | ||
190 | bool m_changed; | ||
191 | |||
192 | private slots: | ||
193 | void copMessage( const QCString &msg, const QByteArray &data ); | ||
194 | |||
195 | |||
196 | }; | ||
197 | #endif | ||
diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp new file mode 100644 index 0000000..66632f5 --- a/dev/null +++ b/libopie2/opiepim/ocontact.cpp | |||
@@ -0,0 +1,1433 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the 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 | #define QTOPIA_INTERNAL_CONTACT_MRE | ||
22 | |||
23 | #include "ocontact.h" | ||
24 | #include "vobject_p.h" | ||
25 | #include "qfiledirect_p.h" | ||
26 | |||
27 | #include <qpe/stringutil.h> | ||
28 | #include <qpe/timeconversion.h> | ||
29 | |||
30 | #include <qobject.h> | ||
31 | #include <qregexp.h> | ||
32 | #include <qstylesheet.h> | ||
33 | #include <qfileinfo.h> | ||
34 | #include <qmap.h> | ||
35 | |||
36 | #include <stdio.h> | ||
37 | |||
38 | /*! | ||
39 | \class Contact contact.h | ||
40 | \brief The Contact class holds the data of an address book entry. | ||
41 | |||
42 | This data includes information the name of the person, contact | ||
43 | information, and business information such as deparment and job title. | ||
44 | |||
45 | \ingroup qtopiaemb | ||
46 | \ingroup qtopiadesktop | ||
47 | */ | ||
48 | |||
49 | Qtopia::UidGen OContact::sUidGen( Qtopia::UidGen::Qtopia ); | ||
50 | |||
51 | /*! | ||
52 | Creates a new, empty contact. | ||
53 | */ | ||
54 | OContact::OContact() | ||
55 | : OPimRecord(), mMap(), d( 0 ) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | /*! | ||
60 | \internal | ||
61 | Creates a new contact. The properties of the contact are | ||
62 | set from \a fromMap. | ||
63 | */ | ||
64 | OContact::OContact( const QMap<int, QString> &fromMap ) : | ||
65 | OPimRecord(), mMap( fromMap ), d( 0 ) | ||
66 | { | ||
67 | QString cats = mMap[ Qtopia::AddressCategory ]; | ||
68 | if ( !cats.isEmpty() ) | ||
69 | setCategories( idsFromString( cats ) ); | ||
70 | QString uidStr = find( Qtopia::AddressUid ); | ||
71 | |||
72 | if ( uidStr.isEmpty() ) | ||
73 | setUid( uidGen().generate() ); | ||
74 | else | ||
75 | setUid( uidStr.toInt() ); | ||
76 | |||
77 | if ( !uidStr.isEmpty() ) | ||
78 | setUid( uidStr.toInt() ); | ||
79 | } | ||
80 | |||
81 | /*! | ||
82 | Destroys a contact. | ||
83 | */ | ||
84 | OContact::~OContact() | ||
85 | { | ||
86 | } | ||
87 | |||
88 | /*! \fn void OContact::setTitle( const QString &str ) | ||
89 | Sets the title of the contact to \a str. | ||
90 | */ | ||
91 | |||
92 | /*! \fn void OContact::setFirstName( const QString &str ) | ||
93 | Sets the first name of the contact to \a str. | ||
94 | */ | ||
95 | |||
96 | /*! \fn void OContact::setMiddleName( const QString &str ) | ||
97 | Sets the middle name of the contact to \a str. | ||
98 | */ | ||
99 | |||
100 | /*! \fn void OContact::setLastName( const QString &str ) | ||
101 | Sets the last name of the contact to \a str. | ||
102 | */ | ||
103 | |||
104 | /*! \fn void OContact::setSuffix( const QString &str ) | ||
105 | Sets the suffix of the contact to \a str. | ||
106 | */ | ||
107 | |||
108 | /*! \fn void OContact::setFileAs( const QString &str ) | ||
109 | Sets the contact to filed as \a str. | ||
110 | */ | ||
111 | |||
112 | /*! \fn void OContact::setDefaultEmail( const QString &str ) | ||
113 | Sets the default email of the contact to \a str. | ||
114 | */ | ||
115 | |||
116 | /*! \fn void OContact::setHomeStreet( const QString &str ) | ||
117 | Sets the home street address of the contact to \a str. | ||
118 | */ | ||
119 | |||
120 | /*! \fn void OContact::setHomeCity( const QString &str ) | ||
121 | Sets the home city of the contact to \a str. | ||
122 | */ | ||
123 | |||
124 | /*! \fn void OContact::setHomeState( const QString &str ) | ||
125 | Sets the home state of the contact to \a str. | ||
126 | */ | ||
127 | |||
128 | /*! \fn void OContact::setHomeZip( const QString &str ) | ||
129 | Sets the home zip code of the contact to \a str. | ||
130 | */ | ||
131 | |||
132 | /*! \fn void OContact::setHomeCountry( const QString &str ) | ||
133 | Sets the home country of the contact to \a str. | ||
134 | */ | ||
135 | |||
136 | /*! \fn void OContact::setHomePhone( const QString &str ) | ||
137 | Sets the home phone number of the contact to \a str. | ||
138 | */ | ||
139 | |||
140 | /*! \fn void OContact::setHomeFax( const QString &str ) | ||
141 | Sets the home fax number of the contact to \a str. | ||
142 | */ | ||
143 | |||
144 | /*! \fn void OContact::setHomeMobile( const QString &str ) | ||
145 | Sets the home mobile phone number of the contact to \a str. | ||
146 | */ | ||
147 | |||
148 | /*! \fn void OContact::setHomeWebpage( const QString &str ) | ||
149 | Sets the home webpage of the contact to \a str. | ||
150 | */ | ||
151 | |||
152 | /*! \fn void OContact::setCompany( const QString &str ) | ||
153 | Sets the company for contact to \a str. | ||
154 | */ | ||
155 | |||
156 | /*! \fn void OContact::setJobTitle( const QString &str ) | ||
157 | Sets the job title of the contact to \a str. | ||
158 | */ | ||
159 | |||
160 | /*! \fn void OContact::setDepartment( const QString &str ) | ||
161 | Sets the department for contact to \a str. | ||
162 | */ | ||
163 | |||
164 | /*! \fn void OContact::setOffice( const QString &str ) | ||
165 | Sets the office for contact to \a str. | ||
166 | */ | ||
167 | |||
168 | /*! \fn void OContact::setBusinessStreet( const QString &str ) | ||
169 | Sets the business street address of the contact to \a str. | ||
170 | */ | ||
171 | |||
172 | /*! \fn void OContact::setBusinessCity( const QString &str ) | ||
173 | Sets the business city of the contact to \a str. | ||
174 | */ | ||
175 | |||
176 | /*! \fn void OContact::setBusinessState( const QString &str ) | ||
177 | Sets the business state of the contact to \a str. | ||
178 | */ | ||
179 | |||
180 | /*! \fn void OContact::setBusinessZip( const QString &str ) | ||
181 | Sets the business zip code of the contact to \a str. | ||
182 | */ | ||
183 | |||
184 | /*! \fn void OContact::setBusinessCountry( const QString &str ) | ||
185 | Sets the business country of the contact to \a str. | ||
186 | */ | ||
187 | |||
188 | /*! \fn void OContact::setBusinessPhone( const QString &str ) | ||
189 | Sets the business phone number of the contact to \a str. | ||
190 | */ | ||
191 | |||
192 | /*! \fn void OContact::setBusinessFax( const QString &str ) | ||
193 | Sets the business fax number of the contact to \a str. | ||
194 | */ | ||
195 | |||
196 | /*! \fn void OContact::setBusinessMobile( const QString &str ) | ||
197 | Sets the business mobile phone number of the contact to \a str. | ||
198 | */ | ||
199 | |||
200 | /*! \fn void OContact::setBusinessPager( const QString &str ) | ||
201 | Sets the business pager number of the contact to \a str. | ||
202 | */ | ||
203 | |||
204 | /*! \fn void OContact::setBusinessWebpage( const QString &str ) | ||
205 | Sets the business webpage of the contact to \a str. | ||
206 | */ | ||
207 | |||
208 | /*! \fn void OContact::setProfession( const QString &str ) | ||
209 | Sets the profession of the contact to \a str. | ||
210 | */ | ||
211 | |||
212 | /*! \fn void OContact::setAssistant( const QString &str ) | ||
213 | Sets the assistant of the contact to \a str. | ||
214 | */ | ||
215 | |||
216 | /*! \fn void OContact::setManager( const QString &str ) | ||
217 | Sets the manager of the contact to \a str. | ||
218 | */ | ||
219 | |||
220 | /*! \fn void OContact::setSpouse( const QString &str ) | ||
221 | Sets the spouse of the contact to \a str. | ||
222 | */ | ||
223 | |||
224 | /*! \fn void OContact::setGender( const QString &str ) | ||
225 | Sets the gender of the contact to \a str. | ||
226 | */ | ||
227 | |||
228 | /*! \fn void OContact::setBirthday( const QString &str ) | ||
229 | Sets the birthday for the contact to \a str. | ||
230 | */ | ||
231 | |||
232 | /*! \fn void OContact::setAnniversary( const QString &str ) | ||
233 | Sets the anniversary of the contact to \a str. | ||
234 | */ | ||
235 | |||
236 | /*! \fn void OContact::setNickname( const QString &str ) | ||
237 | Sets the nickname of the contact to \a str. | ||
238 | */ | ||
239 | |||
240 | /*! \fn void OContact::setNotes( const QString &str ) | ||
241 | Sets the notes about the contact to \a str. | ||
242 | */ | ||
243 | |||
244 | /*! \fn QString OContact::title() const | ||
245 | Returns the title of the contact. | ||
246 | */ | ||
247 | |||
248 | /*! \fn QString OContact::firstName() const | ||
249 | Returns the first name of the contact. | ||
250 | */ | ||
251 | |||
252 | /*! \fn QString OContact::middleName() const | ||
253 | Returns the middle name of the contact. | ||
254 | */ | ||
255 | |||
256 | /*! \fn QString OContact::lastName() const | ||
257 | Returns the last name of the contact. | ||
258 | */ | ||
259 | |||
260 | /*! \fn QString OContact::suffix() const | ||
261 | Returns the suffix of the contact. | ||
262 | */ | ||
263 | |||
264 | /*! \fn QString OContact::fileAs() const | ||
265 | Returns the string the contact is filed as. | ||
266 | */ | ||
267 | |||
268 | /*! \fn QString OContact::defaultEmail() const | ||
269 | Returns the default email address of the contact. | ||
270 | */ | ||
271 | |||
272 | /*! \fn QString OContact::emails() const | ||
273 | Returns the list of email address for a contact separated by ';'s in a single | ||
274 | string. | ||
275 | */ | ||
276 | |||
277 | /*! \fn QString OContact::homeStreet() const | ||
278 | Returns the home street address of the contact. | ||
279 | */ | ||
280 | |||
281 | /*! \fn QString OContact::homeCity() const | ||
282 | Returns the home city of the contact. | ||
283 | */ | ||
284 | |||
285 | /*! \fn QString OContact::homeState() const | ||
286 | Returns the home state of the contact. | ||
287 | */ | ||
288 | |||
289 | /*! \fn QString OContact::homeZip() const | ||
290 | Returns the home zip of the contact. | ||
291 | */ | ||
292 | |||
293 | /*! \fn QString OContact::homeCountry() const | ||
294 | Returns the home country of the contact. | ||
295 | */ | ||
296 | |||
297 | /*! \fn QString OContact::homePhone() const | ||
298 | Returns the home phone number of the contact. | ||
299 | */ | ||
300 | |||
301 | /*! \fn QString OContact::homeFax() const | ||
302 | Returns the home fax number of the contact. | ||
303 | */ | ||
304 | |||
305 | /*! \fn QString OContact::homeMobile() const | ||
306 | Returns the home mobile number of the contact. | ||
307 | */ | ||
308 | |||
309 | /*! \fn QString OContact::homeWebpage() const | ||
310 | Returns the home webpage of the contact. | ||
311 | */ | ||
312 | |||
313 | /*! \fn QString OContact::company() const | ||
314 | Returns the company for the contact. | ||
315 | */ | ||
316 | |||
317 | /*! \fn QString OContact::department() const | ||
318 | Returns the department for the contact. | ||
319 | */ | ||
320 | |||
321 | /*! \fn QString OContact::office() const | ||
322 | Returns the office for the contact. | ||
323 | */ | ||
324 | |||
325 | /*! \fn QString OContact::jobTitle() const | ||
326 | Returns the job title of the contact. | ||
327 | */ | ||
328 | |||
329 | /*! \fn QString OContact::profession() const | ||
330 | Returns the profession of the contact. | ||
331 | */ | ||
332 | |||
333 | /*! \fn QString OContact::assistant() const | ||
334 | Returns the assistant of the contact. | ||
335 | */ | ||
336 | |||
337 | /*! \fn QString OContact::manager() const | ||
338 | Returns the manager of the contact. | ||
339 | */ | ||
340 | |||
341 | /*! \fn QString OContact::businessStreet() const | ||
342 | Returns the business street address of the contact. | ||
343 | */ | ||
344 | |||
345 | /*! \fn QString OContact::businessCity() const | ||
346 | Returns the business city of the contact. | ||
347 | */ | ||
348 | |||
349 | /*! \fn QString OContact::businessState() const | ||
350 | Returns the business state of the contact. | ||
351 | */ | ||
352 | |||
353 | /*! \fn QString OContact::businessZip() const | ||
354 | Returns the business zip of the contact. | ||
355 | */ | ||
356 | |||
357 | /*! \fn QString OContact::businessCountry() const | ||
358 | Returns the business country of the contact. | ||
359 | */ | ||
360 | |||
361 | /*! \fn QString OContact::businessPhone() const | ||
362 | Returns the business phone number of the contact. | ||
363 | */ | ||
364 | |||
365 | /*! \fn QString OContact::businessFax() const | ||
366 | Returns the business fax number of the contact. | ||
367 | */ | ||
368 | |||
369 | /*! \fn QString OContact::businessMobile() const | ||
370 | Returns the business mobile number of the contact. | ||
371 | */ | ||
372 | |||
373 | /*! \fn QString OContact::businessPager() const | ||
374 | Returns the business pager number of the contact. | ||
375 | */ | ||
376 | |||
377 | /*! \fn QString OContact::businessWebpage() const | ||
378 | Returns the business webpage of the contact. | ||
379 | */ | ||
380 | |||
381 | /*! \fn QString OContact::spouse() const | ||
382 | Returns the spouse of the contact. | ||
383 | */ | ||
384 | |||
385 | /*! \fn QString OContact::gender() const | ||
386 | Returns the gender of the contact. | ||
387 | */ | ||
388 | |||
389 | /*! \fn QString OContact::birthday() const | ||
390 | Returns the birthday of the contact. | ||
391 | */ | ||
392 | |||
393 | /*! \fn QString OContact::anniversary() const | ||
394 | Returns the anniversary of the contact. | ||
395 | */ | ||
396 | |||
397 | /*! \fn QString OContact::nickname() const | ||
398 | Returns the nickname of the contact. | ||
399 | */ | ||
400 | |||
401 | /*! \fn QString OContact::children() const | ||
402 | Returns the children of the contact. | ||
403 | */ | ||
404 | |||
405 | /*! \fn QString OContact::notes() const | ||
406 | Returns the notes relating to the the contact. | ||
407 | */ | ||
408 | |||
409 | /*! \fn QString OContact::groups() const | ||
410 | \internal | ||
411 | Returns the groups for the contact. | ||
412 | */ | ||
413 | |||
414 | /*! \fn QStringList OContact::groupList() const | ||
415 | \internal | ||
416 | */ | ||
417 | |||
418 | /*! \fn QString OContact::field(int) const | ||
419 | \internal | ||
420 | */ | ||
421 | |||
422 | /*! \fn void OContact::saveJournal( journal_action, const QString & = QString::null ) | ||
423 | \internal | ||
424 | */ | ||
425 | |||
426 | /*! \fn void OContact::setUid( int id ) | ||
427 | \internal | ||
428 | Sets the uid for this record to \a id. | ||
429 | */ | ||
430 | |||
431 | /*! \enum OContact::journal_action | ||
432 | \internal | ||
433 | */ | ||
434 | |||
435 | /*! | ||
436 | \internal | ||
437 | */ | ||
438 | QMap<int, QString> OContact::toMap() const | ||
439 | { | ||
440 | QMap<int, QString> map = mMap; | ||
441 | QString cats = idsToString( categories() ); | ||
442 | if ( !cats.isEmpty() ) | ||
443 | map.insert( Qtopia::AddressCategory, cats ); | ||
444 | return map; | ||
445 | } | ||
446 | |||
447 | /*! | ||
448 | Returns a rich text formatted QString representing the contents the contact. | ||
449 | */ | ||
450 | QString OContact::toRichText() const | ||
451 | { | ||
452 | QString text; | ||
453 | QString value, comp, state; | ||
454 | |||
455 | // name, jobtitle and company | ||
456 | if ( !(value = fullName()).isEmpty() ) | ||
457 | text += "<b>" + Qtopia::escapeString(value) + "</b><br>"; | ||
458 | if ( !(value = jobTitle()).isEmpty() ) | ||
459 | text += Qtopia::escapeString(value) + "<br>"; | ||
460 | |||
461 | comp = company(); | ||
462 | if ( !(value = department()).isEmpty() ) { | ||
463 | text += Qtopia::escapeString(value); | ||
464 | if ( comp ) | ||
465 | text += ", "; | ||
466 | else | ||
467 | text += "<br>"; | ||
468 | } | ||
469 | if ( !comp.isEmpty() ) | ||
470 | text += Qtopia::escapeString(comp) + "<br>"; | ||
471 | |||
472 | // business address | ||
473 | if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || | ||
474 | !businessZip().isEmpty() || !businessCountry().isEmpty() ) { | ||
475 | text += "<br>"; | ||
476 | text += QObject::tr( "<b>Work Address:</b>" ); | ||
477 | text += "<br>"; | ||
478 | } | ||
479 | |||
480 | if ( !(value = businessStreet()).isEmpty() ) | ||
481 | text += Qtopia::escapeString(value) + "<br>"; | ||
482 | state = businessState(); | ||
483 | if ( !(value = businessCity()).isEmpty() ) { | ||
484 | text += Qtopia::escapeString(value); | ||
485 | if ( state ) | ||
486 | text += ", " + Qtopia::escapeString(state); | ||
487 | text += "<br>"; | ||
488 | } else if ( !state.isEmpty() ) | ||
489 | text += Qtopia::escapeString(state) + "<br>"; | ||
490 | if ( !(value = businessZip()).isEmpty() ) | ||
491 | text += Qtopia::escapeString(value) + "<br>"; | ||
492 | if ( !(value = businessCountry()).isEmpty() ) | ||
493 | text += Qtopia::escapeString(value) + "<br>"; | ||
494 | |||
495 | // home address | ||
496 | if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || | ||
497 | !homeZip().isEmpty() || !homeCountry().isEmpty() ) { | ||
498 | text += "<br>"; | ||
499 | text += QObject::tr( "<b>Home Address:</b>" ); | ||
500 | text += "<br>"; | ||
501 | } | ||
502 | |||
503 | if ( !(value = homeStreet()).isEmpty() ) | ||
504 | text += Qtopia::escapeString(value) + "<br>"; | ||
505 | state = homeState(); | ||
506 | if ( !(value = homeCity()).isEmpty() ) { | ||
507 | text += Qtopia::escapeString(value); | ||
508 | if ( !state.isEmpty() ) | ||
509 | text += ", " + Qtopia::escapeString(state); | ||
510 | text += "<br>"; | ||
511 | } else if (!state.isEmpty()) | ||
512 | text += Qtopia::escapeString(state) + "<br>"; | ||
513 | if ( !(value = homeZip()).isEmpty() ) | ||
514 | text += Qtopia::escapeString(value) + "<br>"; | ||
515 | if ( !(value = homeCountry()).isEmpty() ) | ||
516 | text += Qtopia::escapeString(value) + "<br>"; | ||
517 | |||
518 | // the others... | ||
519 | QString str; | ||
520 | str = emails(); | ||
521 | if ( !str.isEmpty() ) | ||
522 | text += "<b>" + QObject::tr("Email Addresses: ") + "</b>" | ||
523 | + Qtopia::escapeString(str) + "<br>"; | ||
524 | str = homePhone(); | ||
525 | if ( !str.isEmpty() ) | ||
526 | text += "<b>" + QObject::tr("Home Phone: ") + "</b>" | ||
527 | + Qtopia::escapeString(str) + "<br>"; | ||
528 | str = homeFax(); | ||
529 | if ( !str.isEmpty() ) | ||
530 | text += "<b>" + QObject::tr("Home Fax: ") + "</b>" | ||
531 | + Qtopia::escapeString(str) + "<br>"; | ||
532 | str = homeMobile(); | ||
533 | if ( !str.isEmpty() ) | ||
534 | text += "<b>" + QObject::tr("Home Mobile: ") + "</b>" | ||
535 | + Qtopia::escapeString(str) + "<br>"; | ||
536 | str = homeWebpage(); | ||
537 | if ( !str.isEmpty() ) | ||
538 | text += "<b>" + QObject::tr("Home Web Page: ") + "</b>" | ||
539 | + Qtopia::escapeString(str) + "<br>"; | ||
540 | str = businessWebpage(); | ||
541 | if ( !str.isEmpty() ) | ||
542 | text += "<b>" + QObject::tr("Business Web Page: ") + "</b>" | ||
543 | + Qtopia::escapeString(str) + "<br>"; | ||
544 | str = office(); | ||
545 | if ( !str.isEmpty() ) | ||
546 | text += "<b>" + QObject::tr("Office: ") + "</b>" | ||
547 | + Qtopia::escapeString(str) + "<br>"; | ||
548 | str = businessPhone(); | ||
549 | if ( !str.isEmpty() ) | ||
550 | text += "<b>" + QObject::tr("Business Phone: ") + "</b>" | ||
551 | + Qtopia::escapeString(str) + "<br>"; | ||
552 | str = businessFax(); | ||
553 | if ( !str.isEmpty() ) | ||
554 | text += "<b>" + QObject::tr("Business Fax: ") + "</b>" | ||
555 | + Qtopia::escapeString(str) + "<br>"; | ||
556 | str = businessMobile(); | ||
557 | if ( !str.isEmpty() ) | ||
558 | text += "<b>" + QObject::tr("Business Mobile: ") + "</b>" | ||
559 | + Qtopia::escapeString(str) + "<br>"; | ||
560 | str = businessPager(); | ||
561 | if ( !str.isEmpty() ) | ||
562 | text += "<b>" + QObject::tr("Business Pager: ") + "</b>" | ||
563 | + Qtopia::escapeString(str) + "<br>"; | ||
564 | str = profession(); | ||
565 | if ( !str.isEmpty() ) | ||
566 | text += "<b>" + QObject::tr("Profession: ") + "</b>" | ||
567 | + Qtopia::escapeString(str) + "<br>"; | ||
568 | str = assistant(); | ||
569 | if ( !str.isEmpty() ) | ||
570 | text += "<b>" + QObject::tr("Assistant: ") + "</b>" | ||
571 | + Qtopia::escapeString(str) + "<br>"; | ||
572 | str = manager(); | ||
573 | if ( !str.isEmpty() ) | ||
574 | text += "<b>" + QObject::tr("Manager: ") + "</b>" | ||
575 | + Qtopia::escapeString(str) + "<br>"; | ||
576 | str = gender(); | ||
577 | if ( !str.isEmpty() && str.toInt() != 0 ) { | ||
578 | if ( str.toInt() == 1 ) | ||
579 | str = QObject::tr( "Male" ); | ||
580 | else if ( str.toInt() == 2 ) | ||
581 | str = QObject::tr( "Female" ); | ||
582 | text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; | ||
583 | } | ||
584 | str = spouse(); | ||
585 | if ( !str.isEmpty() ) | ||
586 | text += "<b>" + QObject::tr("Spouse: ") + "</b>" | ||
587 | + Qtopia::escapeString(str) + "<br>"; | ||
588 | str = birthday(); | ||
589 | if ( !str.isEmpty() ) | ||
590 | text += "<b>" + QObject::tr("Birthday: ") + "</b>" | ||
591 | + Qtopia::escapeString(str) + "<br>"; | ||
592 | str = anniversary(); | ||
593 | if ( !str.isEmpty() ) | ||
594 | text += "<b>" + QObject::tr("Anniversary: ") + "</b>" | ||
595 | + Qtopia::escapeString(str) + "<br>"; | ||
596 | str = nickname(); | ||
597 | if ( !str.isEmpty() ) | ||
598 | text += "<b>" + QObject::tr("Nickname: ") + "</b>" | ||
599 | + Qtopia::escapeString(str) + "<br>"; | ||
600 | |||
601 | // notes last | ||
602 | if ( (value = notes()) ) { | ||
603 | QRegExp reg("\n"); | ||
604 | |||
605 | //QString tmp = Qtopia::escapeString(value); | ||
606 | QString tmp = QStyleSheet::convertFromPlainText(value); | ||
607 | //tmp.replace( reg, "<br>" ); | ||
608 | text += "<br>" + tmp + "<br>"; | ||
609 | } | ||
610 | return text; | ||
611 | } | ||
612 | |||
613 | /*! | ||
614 | \internal | ||
615 | */ | ||
616 | void OContact::insert( int key, const QString &v ) | ||
617 | { | ||
618 | QString value = v.stripWhiteSpace(); | ||
619 | if ( value.isEmpty() ) | ||
620 | mMap.remove( key ); | ||
621 | else | ||
622 | mMap.insert( key, value ); | ||
623 | } | ||
624 | |||
625 | /*! | ||
626 | \internal | ||
627 | */ | ||
628 | void OContact::replace( int key, const QString & v ) | ||
629 | { | ||
630 | QString value = v.stripWhiteSpace(); | ||
631 | if ( value.isEmpty() ) | ||
632 | mMap.remove( key ); | ||
633 | else | ||
634 | mMap.replace( key, value ); | ||
635 | } | ||
636 | |||
637 | /*! | ||
638 | \internal | ||
639 | */ | ||
640 | QString OContact::find( int key ) const | ||
641 | { | ||
642 | return mMap[key]; | ||
643 | } | ||
644 | |||
645 | /*! | ||
646 | \internal | ||
647 | */ | ||
648 | QString OContact::displayAddress( const QString &street, | ||
649 | const QString &city, | ||
650 | const QString &state, | ||
651 | const QString &zip, | ||
652 | const QString &country ) const | ||
653 | { | ||
654 | QString s = street; | ||
655 | if ( !street.isEmpty() ) | ||
656 | s+= "\n"; | ||
657 | s += city; | ||
658 | if ( !city.isEmpty() && !state.isEmpty() ) | ||
659 | s += ", "; | ||
660 | s += state; | ||
661 | if ( !state.isEmpty() && !zip.isEmpty() ) | ||
662 | s += " "; | ||
663 | s += zip; | ||
664 | if ( !country.isEmpty() && !s.isEmpty() ) | ||
665 | s += "\n"; | ||
666 | s += country; | ||
667 | return s; | ||
668 | } | ||
669 | |||
670 | /*! | ||
671 | \internal | ||
672 | */ | ||
673 | QString OContact::displayBusinessAddress() const | ||
674 | { | ||
675 | return displayAddress( businessStreet(), businessCity(), | ||
676 | businessState(), businessZip(), | ||
677 | businessCountry() ); | ||
678 | } | ||
679 | |||
680 | /*! | ||
681 | \internal | ||
682 | */ | ||
683 | QString OContact::displayHomeAddress() const | ||
684 | { | ||
685 | return displayAddress( homeStreet(), homeCity(), | ||
686 | homeState(), homeZip(), | ||
687 | homeCountry() ); | ||
688 | } | ||
689 | |||
690 | /*! | ||
691 | Returns the full name of the contact | ||
692 | */ | ||
693 | QString OContact::fullName() const | ||
694 | { | ||
695 | QString title = find( Qtopia::Title ); | ||
696 | QString firstName = find( Qtopia::FirstName ); | ||
697 | QString middleName = find( Qtopia::MiddleName ); | ||
698 | QString lastName = find( Qtopia::LastName ); | ||
699 | QString suffix = find( Qtopia::Suffix ); | ||
700 | |||
701 | QString name = title; | ||
702 | if ( !firstName.isEmpty() ) { | ||
703 | if ( !name.isEmpty() ) | ||
704 | name += " "; | ||
705 | name += firstName; | ||
706 | } | ||
707 | if ( !middleName.isEmpty() ) { | ||
708 | if ( !name.isEmpty() ) | ||
709 | name += " "; | ||
710 | name += middleName; | ||
711 | } | ||
712 | if ( !lastName.isEmpty() ) { | ||
713 | if ( !name.isEmpty() ) | ||
714 | name += " "; | ||
715 | name += lastName; | ||
716 | } | ||
717 | if ( !suffix.isEmpty() ) { | ||
718 | if ( !name.isEmpty() ) | ||
719 | name += " "; | ||
720 | name += suffix; | ||
721 | } | ||
722 | return name.simplifyWhiteSpace(); | ||
723 | } | ||
724 | |||
725 | /*! | ||
726 | Returns a list of the names of the children of the contact. | ||
727 | */ | ||
728 | QStringList OContact::childrenList() const | ||
729 | { | ||
730 | return QStringList::split( " ", find( Qtopia::Children ) ); | ||
731 | } | ||
732 | |||
733 | /*! \fn void OContact::insertEmail( const QString &email ) | ||
734 | |||
735 | Insert \a email into the email list. Ensures \a email can only be added | ||
736 | once. If there is no default email address set, it sets it to the \a email. | ||
737 | */ | ||
738 | |||
739 | /*! \fn void OContact::removeEmail( const QString &email ) | ||
740 | |||
741 | Removes the \a email from the email list. If the default email was \a email, | ||
742 | then the default email address is assigned to the first email in the | ||
743 | email list | ||
744 | */ | ||
745 | |||
746 | /*! \fn void OContact::clearEmails() | ||
747 | |||
748 | Clears the email list. | ||
749 | */ | ||
750 | |||
751 | /*! \fn void OContact::insertEmails( const QStringList &emailList ) | ||
752 | |||
753 | Appends the \a emailList to the exiting email list | ||
754 | */ | ||
755 | |||
756 | /*! | ||
757 | Returns a list of email addresses belonging to the contact, including | ||
758 | the default email address. | ||
759 | */ | ||
760 | QStringList OContact::emailList() const | ||
761 | { | ||
762 | QString emailStr = emails(); | ||
763 | |||
764 | QStringList r; | ||
765 | if ( !emailStr.isEmpty() ) { | ||
766 | qDebug(" emailstr "); | ||
767 | QStringList l = QStringList::split( emailSeparator(), emailStr ); | ||
768 | for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) | ||
769 | r += (*it).simplifyWhiteSpace(); | ||
770 | } | ||
771 | |||
772 | return r; | ||
773 | } | ||
774 | |||
775 | /*! | ||
776 | \overload | ||
777 | |||
778 | Generates the string for the contact to be filed as from the first, | ||
779 | middle and last name of the contact. | ||
780 | */ | ||
781 | void OContact::setFileAs() | ||
782 | { | ||
783 | QString lastName, firstName, middleName, fileas; | ||
784 | |||
785 | lastName = find( Qtopia::LastName ); | ||
786 | firstName = find( Qtopia::FirstName ); | ||
787 | middleName = find( Qtopia::MiddleName ); | ||
788 | if ( !lastName.isEmpty() && !firstName.isEmpty() | ||
789 | && !middleName.isEmpty() ) | ||
790 | fileas = lastName + ", " + firstName + " " + middleName; | ||
791 | else if ( !lastName.isEmpty() && !firstName.isEmpty() ) | ||
792 | fileas = lastName + ", " + firstName; | ||
793 | else if ( !lastName.isEmpty() || !firstName.isEmpty() || | ||
794 | !middleName.isEmpty() ) | ||
795 | fileas = firstName + ( firstName.isEmpty() ? "" : " " ) | ||
796 | + middleName + ( middleName.isEmpty() ? "" : " " ) | ||
797 | + lastName; | ||
798 | |||
799 | replace( Qtopia::FileAs, fileas ); | ||
800 | } | ||
801 | |||
802 | /*! | ||
803 | \internal | ||
804 | Appends the contact information to \a buf. | ||
805 | */ | ||
806 | void OContact::save( QString &buf ) const | ||
807 | { | ||
808 | static const QStringList SLFIELDS = fields(); | ||
809 | // I'm expecting "<Contact " in front of this... | ||
810 | for ( QMap<int, QString>::ConstIterator it = mMap.begin(); | ||
811 | it != mMap.end(); ++it ) { | ||
812 | const QString &value = it.data(); | ||
813 | int key = it.key(); | ||
814 | if ( !value.isEmpty() ) { | ||
815 | if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) | ||
816 | continue; | ||
817 | |||
818 | key -= Qtopia::AddressCategory+1; | ||
819 | buf += SLFIELDS[key]; | ||
820 | buf += "=\"" + Qtopia::escapeString(value) + "\" "; | ||
821 | } | ||
822 | } | ||
823 | buf += customToXml(); | ||
824 | if ( categories().count() > 0 ) | ||
825 | buf += "Categories=\"" + idsToString( categories() ) + "\" "; | ||
826 | buf += "Uid=\"" + QString::number( uid() ) + "\" "; | ||
827 | // You need to close this yourself | ||
828 | } | ||
829 | |||
830 | /*! | ||
831 | \internal | ||
832 | Returns the list of fields belonging to a contact | ||
833 | */ | ||
834 | QStringList OContact::fields() | ||
835 | { | ||
836 | QStringList list; | ||
837 | |||
838 | list.append( "Title" ); // Not Used! | ||
839 | list.append( "FirstName" ); | ||
840 | list.append( "MiddleName" ); | ||
841 | list.append( "LastName" ); | ||
842 | list.append( "Suffix" ); | ||
843 | list.append( "FileAs" ); | ||
844 | |||
845 | list.append( "JobTitle" ); | ||
846 | list.append( "Department" ); | ||
847 | list.append( "Company" ); | ||
848 | list.append( "BusinessPhone" ); | ||
849 | list.append( "BusinessFax" ); | ||
850 | list.append( "BusinessMobile" ); | ||
851 | |||
852 | list.append( "DefaultEmail" ); | ||
853 | list.append( "Emails" ); | ||
854 | |||
855 | list.append( "HomePhone" ); | ||
856 | list.append( "HomeFax" ); | ||
857 | list.append( "HomeMobile" ); | ||
858 | |||
859 | list.append( "BusinessStreet" ); | ||
860 | list.append( "BusinessCity" ); | ||
861 | list.append( "BusinessState" ); | ||
862 | list.append( "BusinessZip" ); | ||
863 | list.append( "BusinessCountry" ); | ||
864 | list.append( "BusinessPager" ); | ||
865 | list.append( "BusinessWebPage" ); | ||
866 | |||
867 | list.append( "Office" ); | ||
868 | list.append( "Profession" ); | ||
869 | list.append( "Assistant" ); | ||
870 | list.append( "Manager" ); | ||
871 | |||
872 | list.append( "HomeStreet" ); | ||
873 | list.append( "HomeCity" ); | ||
874 | list.append( "HomeState" ); | ||
875 | list.append( "HomeZip" ); | ||
876 | list.append( "HomeCountry" ); | ||
877 | list.append( "HomeWebPage" ); | ||
878 | |||
879 | list.append( "Spouse" ); | ||
880 | list.append( "Gender" ); | ||
881 | list.append( "Birthday" ); | ||
882 | list.append( "Anniversary" ); | ||
883 | list.append( "Nickname" ); | ||
884 | list.append( "Children" ); | ||
885 | |||
886 | list.append( "Notes" ); | ||
887 | list.append( "Groups" ); | ||
888 | |||
889 | return list; | ||
890 | } | ||
891 | |||
892 | /*! | ||
893 | \internal | ||
894 | Returns a translated list of field names for a contact. | ||
895 | */ | ||
896 | QStringList OContact::trfields() | ||
897 | { | ||
898 | QStringList list; | ||
899 | |||
900 | list.append( QObject::tr( "Name Title") ); | ||
901 | list.append( QObject::tr( "First Name" ) ); | ||
902 | list.append( QObject::tr( "Middle Name" ) ); | ||
903 | list.append( QObject::tr( "Last Name" ) ); | ||
904 | list.append( QObject::tr( "Suffix" ) ); | ||
905 | list.append( QObject::tr( "File As" ) ); | ||
906 | |||
907 | list.append( QObject::tr( "Job Title" ) ); | ||
908 | list.append( QObject::tr( "Department" ) ); | ||
909 | list.append( QObject::tr( "Company" ) ); | ||
910 | list.append( QObject::tr( "Business Phone" ) ); | ||
911 | list.append( QObject::tr( "Business Fax" ) ); | ||
912 | list.append( QObject::tr( "Business Mobile" ) ); | ||
913 | |||
914 | list.append( QObject::tr( "Default Email" ) ); | ||
915 | list.append( QObject::tr( "Emails" ) ); | ||
916 | |||
917 | list.append( QObject::tr( "Home Phone" ) ); | ||
918 | list.append( QObject::tr( "Home Fax" ) ); | ||
919 | list.append( QObject::tr( "Home Mobile" ) ); | ||
920 | |||
921 | list.append( QObject::tr( "Business Street" ) ); | ||
922 | list.append( QObject::tr( "Business City" ) ); | ||
923 | list.append( QObject::tr( "Business State" ) ); | ||
924 | list.append( QObject::tr( "Business Zip" ) ); | ||
925 | list.append( QObject::tr( "Business Country" ) ); | ||
926 | list.append( QObject::tr( "Business Pager" ) ); | ||
927 | list.append( QObject::tr( "Business WebPage" ) ); | ||
928 | |||
929 | list.append( QObject::tr( "Office" ) ); | ||
930 | list.append( QObject::tr( "Profession" ) ); | ||
931 | list.append( QObject::tr( "Assistant" ) ); | ||
932 | list.append( QObject::tr( "Manager" ) ); | ||
933 | |||
934 | list.append( QObject::tr( "Home Street" ) ); | ||
935 | list.append( QObject::tr( "Home City" ) ); | ||
936 | list.append( QObject::tr( "Home State" ) ); | ||
937 | list.append( QObject::tr( "Home Zip" ) ); | ||
938 | list.append( QObject::tr( "Home Country" ) ); | ||
939 | list.append( QObject::tr( "Home Web Page" ) ); | ||
940 | |||
941 | list.append( QObject::tr( "Spouse" ) ); | ||
942 | list.append( QObject::tr( "Gender" ) ); | ||
943 | list.append( QObject::tr( "Birthday" ) ); | ||
944 | list.append( QObject::tr( "Anniversary" ) ); | ||
945 | list.append( QObject::tr( "Nickname" ) ); | ||
946 | list.append( QObject::tr( "Children" ) ); | ||
947 | |||
948 | list.append( QObject::tr( "Notes" ) ); | ||
949 | list.append( QObject::tr( "Groups" ) ); | ||
950 | |||
951 | return list; | ||
952 | } | ||
953 | |||
954 | /*! | ||
955 | Sets the list of email address for contact to those contained in \a str. | ||
956 | Email address should be separated by ';'s. | ||
957 | */ | ||
958 | void OContact::setEmails( const QString &str ) | ||
959 | { | ||
960 | replace( Qtopia::Emails, str ); | ||
961 | if ( str.isEmpty() ) | ||
962 | setDefaultEmail( QString::null ); | ||
963 | } | ||
964 | |||
965 | /*! | ||
966 | Sets the list of children for the contact to those contained in \a str. | ||
967 | */ | ||
968 | void OContact::setChildren( const QString &str ) | ||
969 | { | ||
970 | replace( Qtopia::Children, str ); | ||
971 | } | ||
972 | |||
973 | // vcard conversion code | ||
974 | /*! | ||
975 | \internal | ||
976 | */ | ||
977 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | ||
978 | { | ||
979 | VObject *ret = 0; | ||
980 | if ( o && !value.isEmpty() ) | ||
981 | ret = addPropValue( o, prop, value.latin1() ); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | /*! | ||
986 | \internal | ||
987 | */ | ||
988 | static inline VObject *safeAddProp( VObject *o, const char *prop) | ||
989 | { | ||
990 | VObject *ret = 0; | ||
991 | if ( o ) | ||
992 | ret = addProp( o, prop ); | ||
993 | return ret; | ||
994 | } | ||
995 | |||
996 | /*! | ||
997 | \internal | ||
998 | */ | ||
999 | static VObject *createVObject( const OContact &c ) | ||
1000 | { | ||
1001 | VObject *vcard = newVObject( VCCardProp ); | ||
1002 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); | ||
1003 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); | ||
1004 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); | ||
1005 | |||
1006 | // full name | ||
1007 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); | ||
1008 | |||
1009 | // name properties | ||
1010 | VObject *name = safeAddProp( vcard, VCNameProp ); | ||
1011 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); | ||
1012 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); | ||
1013 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); | ||
1014 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); | ||
1015 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); | ||
1016 | |||
1017 | // home properties | ||
1018 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); | ||
1019 | safeAddProp( home_adr, VCHomeProp ); | ||
1020 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); | ||
1021 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); | ||
1022 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); | ||
1023 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); | ||
1024 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); | ||
1025 | |||
1026 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); | ||
1027 | safeAddProp( home_phone, VCHomeProp ); | ||
1028 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); | ||
1029 | safeAddProp( home_phone, VCHomeProp ); | ||
1030 | safeAddProp( home_phone, VCCellularProp ); | ||
1031 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); | ||
1032 | safeAddProp( home_phone, VCHomeProp ); | ||
1033 | safeAddProp( home_phone, VCFaxProp ); | ||
1034 | |||
1035 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); | ||
1036 | safeAddProp( url, VCHomeProp ); | ||
1037 | |||
1038 | // work properties | ||
1039 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); | ||
1040 | safeAddProp( work_adr, VCWorkProp ); | ||
1041 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); | ||
1042 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); | ||
1043 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); | ||
1044 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); | ||
1045 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); | ||
1046 | |||
1047 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); | ||
1048 | safeAddProp( work_phone, VCWorkProp ); | ||
1049 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); | ||
1050 | safeAddProp( work_phone, VCWorkProp ); | ||
1051 | safeAddProp( work_phone, VCCellularProp ); | ||
1052 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); | ||
1053 | safeAddProp( work_phone, VCWorkProp ); | ||
1054 | safeAddProp( work_phone, VCFaxProp ); | ||
1055 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); | ||
1056 | safeAddProp( work_phone, VCWorkProp ); | ||
1057 | safeAddProp( work_phone, VCPagerProp ); | ||
1058 | |||
1059 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); | ||
1060 | safeAddProp( url, VCWorkProp ); | ||
1061 | |||
1062 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); | ||
1063 | safeAddProp( title, VCWorkProp ); | ||
1064 | |||
1065 | |||
1066 | QStringList emails = c.emailList(); | ||
1067 | emails.prepend( c.defaultEmail() ); | ||
1068 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { | ||
1069 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); | ||
1070 | safeAddProp( email, VCInternetProp ); | ||
1071 | } | ||
1072 | |||
1073 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); | ||
1074 | |||
1075 | safeAddPropValue( vcard, VCBirthDateProp, c.birthday() ); | ||
1076 | |||
1077 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { | ||
1078 | VObject *org = safeAddProp( vcard, VCOrgProp ); | ||
1079 | safeAddPropValue( org, VCOrgNameProp, c.company() ); | ||
1080 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); | ||
1081 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); | ||
1082 | } | ||
1083 | |||
1084 | // some values we have to export as custom fields | ||
1085 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); | ||
1086 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); | ||
1087 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); | ||
1088 | |||
1089 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); | ||
1090 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); | ||
1091 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", c.anniversary() ); | ||
1092 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); | ||
1093 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); | ||
1094 | |||
1095 | return vcard; | ||
1096 | } | ||
1097 | |||
1098 | |||
1099 | /*! | ||
1100 | \internal | ||
1101 | */ | ||
1102 | static OContact parseVObject( VObject *obj ) | ||
1103 | { | ||
1104 | OContact c; | ||
1105 | |||
1106 | VObjectIterator it; | ||
1107 | initPropIterator( &it, obj ); | ||
1108 | while( moreIteration( &it ) ) { | ||
1109 | VObject *o = nextVObject( &it ); | ||
1110 | QCString name = vObjectName( o ); | ||
1111 | QCString value = vObjectStringZValue( o ); | ||
1112 | if ( name == VCNameProp ) { | ||
1113 | VObjectIterator nit; | ||
1114 | initPropIterator( &nit, o ); | ||
1115 | while( moreIteration( &nit ) ) { | ||
1116 | VObject *o = nextVObject( &nit ); | ||
1117 | QCString name = vObjectTypeInfo( o ); | ||
1118 | QString value = vObjectStringZValue( o ); | ||
1119 | if ( name == VCNamePrefixesProp ) | ||
1120 | c.setTitle( value ); | ||
1121 | else if ( name == VCNameSuffixesProp ) | ||
1122 | c.setSuffix( value ); | ||
1123 | else if ( name == VCFamilyNameProp ) | ||
1124 | c.setLastName( value ); | ||
1125 | else if ( name == VCGivenNameProp ) | ||
1126 | c.setFirstName( value ); | ||
1127 | else if ( name == VCAdditionalNamesProp ) | ||
1128 | c.setMiddleName( value ); | ||
1129 | } | ||
1130 | } | ||
1131 | else if ( name == VCAdrProp ) { | ||
1132 | bool work = TRUE; // default address is work address | ||
1133 | QString street; | ||
1134 | QString city; | ||
1135 | QString region; | ||
1136 | QString postal; | ||
1137 | QString country; | ||
1138 | |||
1139 | VObjectIterator nit; | ||
1140 | initPropIterator( &nit, o ); | ||
1141 | while( moreIteration( &nit ) ) { | ||
1142 | VObject *o = nextVObject( &nit ); | ||
1143 | QCString name = vObjectName( o ); | ||
1144 | QString value = vObjectStringZValue( o ); | ||
1145 | if ( name == VCHomeProp ) | ||
1146 | work = FALSE; | ||
1147 | else if ( name == VCWorkProp ) | ||
1148 | work = TRUE; | ||
1149 | else if ( name == VCStreetAddressProp ) | ||
1150 | street = value; | ||
1151 | else if ( name == VCCityProp ) | ||
1152 | city = value; | ||
1153 | else if ( name == VCRegionProp ) | ||
1154 | region = value; | ||
1155 | else if ( name == VCPostalCodeProp ) | ||
1156 | postal = value; | ||
1157 | else if ( name == VCCountryNameProp ) | ||
1158 | country = value; | ||
1159 | } | ||
1160 | if ( work ) { | ||
1161 | c.setBusinessStreet( street ); | ||
1162 | c.setBusinessCity( city ); | ||
1163 | c.setBusinessCountry( country ); | ||
1164 | c.setBusinessZip( postal ); | ||
1165 | c.setBusinessState( region ); | ||
1166 | } else { | ||
1167 | c.setHomeStreet( street ); | ||
1168 | c.setHomeCity( city ); | ||
1169 | c.setHomeCountry( country ); | ||
1170 | c.setHomeZip( postal ); | ||
1171 | c.setHomeState( region ); | ||
1172 | } | ||
1173 | } | ||
1174 | else if ( name == VCTelephoneProp ) { | ||
1175 | enum { | ||
1176 | HOME = 0x01, | ||
1177 | WORK = 0x02, | ||
1178 | VOICE = 0x04, | ||
1179 | CELL = 0x08, | ||
1180 | FAX = 0x10, | ||
1181 | PAGER = 0x20, | ||
1182 | UNKNOWN = 0x80 | ||
1183 | }; | ||
1184 | int type = 0; | ||
1185 | |||
1186 | VObjectIterator nit; | ||
1187 | initPropIterator( &nit, o ); | ||
1188 | while( moreIteration( &nit ) ) { | ||
1189 | VObject *o = nextVObject( &nit ); | ||
1190 | QCString name = vObjectTypeInfo( o ); | ||
1191 | if ( name == VCHomeProp ) | ||
1192 | type |= HOME; | ||
1193 | else if ( name == VCWorkProp ) | ||
1194 | type |= WORK; | ||
1195 | else if ( name == VCVoiceProp ) | ||
1196 | type |= VOICE; | ||
1197 | else if ( name == VCCellularProp ) | ||
1198 | type |= CELL; | ||
1199 | else if ( name == VCFaxProp ) | ||
1200 | type |= FAX; | ||
1201 | else if ( name == VCPagerProp ) | ||
1202 | type |= PAGER; | ||
1203 | else if ( name == VCPreferredProp ) | ||
1204 | ; | ||
1205 | else | ||
1206 | type |= UNKNOWN; | ||
1207 | } | ||
1208 | if ( (type & UNKNOWN) != UNKNOWN ) { | ||
1209 | if ( ( type & (HOME|WORK) ) == 0 ) // default | ||
1210 | type |= HOME; | ||
1211 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default | ||
1212 | type |= VOICE; | ||
1213 | |||
1214 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) | ||
1215 | c.setHomePhone( value ); | ||
1216 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) | ||
1217 | c.setHomeFax( value ); | ||
1218 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) | ||
1219 | c.setHomeMobile( value ); | ||
1220 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) | ||
1221 | c.setBusinessPhone( value ); | ||
1222 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) | ||
1223 | c.setBusinessFax( value ); | ||
1224 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) | ||
1225 | c.setBusinessMobile( value ); | ||
1226 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) | ||
1227 | c.setBusinessPager( value ); | ||
1228 | } | ||
1229 | } | ||
1230 | else if ( name == VCEmailAddressProp ) { | ||
1231 | QString email = vObjectStringZValue( o ); | ||
1232 | bool valid = TRUE; | ||
1233 | VObjectIterator nit; | ||
1234 | initPropIterator( &nit, o ); | ||
1235 | while( moreIteration( &nit ) ) { | ||
1236 | VObject *o = nextVObject( &nit ); | ||
1237 | QCString name = vObjectTypeInfo( o ); | ||
1238 | if ( name != VCInternetProp && name != VCHomeProp && | ||
1239 | name != VCWorkProp && | ||
1240 | name != VCPreferredProp ) | ||
1241 | // ### preffered should map to default email | ||
1242 | valid = FALSE; | ||
1243 | } | ||
1244 | if ( valid ) { | ||
1245 | c.insertEmail( email ); | ||
1246 | } | ||
1247 | } | ||
1248 | else if ( name == VCURLProp ) { | ||
1249 | VObjectIterator nit; | ||
1250 | initPropIterator( &nit, o ); | ||
1251 | while( moreIteration( &nit ) ) { | ||
1252 | VObject *o = nextVObject( &nit ); | ||
1253 | QCString name = vObjectTypeInfo( o ); | ||
1254 | if ( name == VCHomeProp ) | ||
1255 | c.setHomeWebpage( value ); | ||
1256 | else if ( name == VCWorkProp ) | ||
1257 | c.setBusinessWebpage( value ); | ||
1258 | } | ||
1259 | } | ||
1260 | else if ( name == VCOrgProp ) { | ||
1261 | VObjectIterator nit; | ||
1262 | initPropIterator( &nit, o ); | ||
1263 | while( moreIteration( &nit ) ) { | ||
1264 | VObject *o = nextVObject( &nit ); | ||
1265 | QCString name = vObjectName( o ); | ||
1266 | QString value = vObjectStringZValue( o ); | ||
1267 | if ( name == VCOrgNameProp ) | ||
1268 | c.setCompany( value ); | ||
1269 | else if ( name == VCOrgUnitProp ) | ||
1270 | c.setDepartment( value ); | ||
1271 | else if ( name == VCOrgUnit2Prop ) | ||
1272 | c.setOffice( value ); | ||
1273 | } | ||
1274 | } | ||
1275 | else if ( name == VCTitleProp ) { | ||
1276 | c.setJobTitle( value ); | ||
1277 | } | ||
1278 | else if ( name == "X-Qtopia-Profession" ) { | ||
1279 | c.setProfession( value ); | ||
1280 | } | ||
1281 | else if ( name == "X-Qtopia-Manager" ) { | ||
1282 | c.setManager( value ); | ||
1283 | } | ||
1284 | else if ( name == "X-Qtopia-Assistant" ) { | ||
1285 | c.setAssistant( value ); | ||
1286 | } | ||
1287 | else if ( name == "X-Qtopia-Spouse" ) { | ||
1288 | c.setSpouse( value ); | ||
1289 | } | ||
1290 | else if ( name == "X-Qtopia-Gender" ) { | ||
1291 | c.setGender( value ); | ||
1292 | } | ||
1293 | else if ( name == "X-Qtopia-Anniversary" ) { | ||
1294 | c.setAnniversary( value ); | ||
1295 | } | ||
1296 | else if ( name == "X-Qtopia-Nickname" ) { | ||
1297 | c.setNickname( value ); | ||
1298 | } | ||
1299 | else if ( name == "X-Qtopia-Children" ) { | ||
1300 | c.setChildren( value ); | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | #if 0 | ||
1305 | else { | ||
1306 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | ||
1307 | VObjectIterator nit; | ||
1308 | initPropIterator( &nit, o ); | ||
1309 | while( moreIteration( &nit ) ) { | ||
1310 | VObject *o = nextVObject( &nit ); | ||
1311 | QCString name = vObjectName( o ); | ||
1312 | QString value = vObjectStringZValue( o ); | ||
1313 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | ||
1314 | } | ||
1315 | } | ||
1316 | #endif | ||
1317 | } | ||
1318 | c.setFileAs(); | ||
1319 | return c; | ||
1320 | } | ||
1321 | |||
1322 | /*! | ||
1323 | Writes the list of \a contacts as a set of VCards to the file \a filename. | ||
1324 | */ | ||
1325 | void OContact::writeVCard( const QString &filename, const QValueList<OContact> &contacts) | ||
1326 | { | ||
1327 | QFileDirect f( filename.utf8().data() ); | ||
1328 | if ( !f.open( IO_WriteOnly ) ) { | ||
1329 | qWarning("Unable to open vcard write"); | ||
1330 | return; | ||
1331 | } | ||
1332 | |||
1333 | QValueList<OContact>::ConstIterator it; | ||
1334 | for( it = contacts.begin(); it != contacts.end(); ++it ) { | ||
1335 | VObject *obj = createVObject( *it ); | ||
1336 | writeVObject(f.directHandle() , obj ); | ||
1337 | cleanVObject( obj ); | ||
1338 | } | ||
1339 | cleanStrTbl(); | ||
1340 | } | ||
1341 | |||
1342 | /*! | ||
1343 | writes \a contact as a VCard to the file \a filename. | ||
1344 | */ | ||
1345 | void OContact::writeVCard( const QString &filename, const OContact &contact) | ||
1346 | { | ||
1347 | QFileDirect f( filename.utf8().data() ); | ||
1348 | if ( !f.open( IO_WriteOnly ) ) { | ||
1349 | qWarning("Unable to open vcard write"); | ||
1350 | return; | ||
1351 | } | ||
1352 | |||
1353 | VObject *obj = createVObject( contact ); | ||
1354 | writeVObject( f.directHandle() , obj ); | ||
1355 | cleanVObject( obj ); | ||
1356 | |||
1357 | cleanStrTbl(); | ||
1358 | } | ||
1359 | |||
1360 | /*! | ||
1361 | Returns the set of contacts read as VCards from the file \a filename. | ||
1362 | */ | ||
1363 | QValueList<OContact> OContact::readVCard( const QString &filename ) | ||
1364 | { | ||
1365 | qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() ); | ||
1366 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | ||
1367 | |||
1368 | qDebug("vobject = %p", obj ); | ||
1369 | |||
1370 | QValueList<OContact> contacts; | ||
1371 | |||
1372 | while ( obj ) { | ||
1373 | contacts.append( parseVObject( obj ) ); | ||
1374 | |||
1375 | VObject *t = obj; | ||
1376 | obj = nextVObjectInList(obj); | ||
1377 | cleanVObject( t ); | ||
1378 | } | ||
1379 | |||
1380 | return contacts; | ||
1381 | } | ||
1382 | |||
1383 | /*! | ||
1384 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1385 | Otherwise returns FALSE. | ||
1386 | */ | ||
1387 | bool OContact::match( const QString ®exp ) const | ||
1388 | { | ||
1389 | return match(QRegExp(regexp)); | ||
1390 | } | ||
1391 | |||
1392 | /*! | ||
1393 | \overload | ||
1394 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1395 | Otherwise returns FALSE. | ||
1396 | */ | ||
1397 | bool OContact::match( const QRegExp &r ) const | ||
1398 | { | ||
1399 | bool match; | ||
1400 | match = false; | ||
1401 | QMap<int, QString>::ConstIterator it; | ||
1402 | for ( it = mMap.begin(); it != mMap.end(); ++it ) { | ||
1403 | if ( (*it).find( r ) > -1 ) { | ||
1404 | match = true; | ||
1405 | break; | ||
1406 | } | ||
1407 | } | ||
1408 | return match; | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | // Noch nicht definiert ! :SX | ||
1413 | QString OContact::toShortText() const | ||
1414 | { | ||
1415 | return ( QString::fromLatin1( "Not defined!") ); | ||
1416 | } | ||
1417 | QString OContact::type() const | ||
1418 | { | ||
1419 | return QString::fromLatin1( "OContact" ); | ||
1420 | } | ||
1421 | |||
1422 | // Noch nicht definiert ! :SX | ||
1423 | QMap<QString,QString> OContact::toExtraMap() const | ||
1424 | { | ||
1425 | QMap <QString,QString> useless; | ||
1426 | return useless; | ||
1427 | } | ||
1428 | |||
1429 | // Noch nicht definiert ! :SX | ||
1430 | class QString OContact::recordField(int) const | ||
1431 | { | ||
1432 | return QString::fromLatin1( "Noch nicht implementiert !" ); | ||
1433 | } | ||
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h new file mode 100644 index 0000000..e0555c8 --- a/dev/null +++ b/libopie2/opiepim/ocontact.h | |||
@@ -0,0 +1,311 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the 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 | #ifndef __OCONTACT_H__ | ||
22 | #define __OCONTACT_H__ | ||
23 | |||
24 | #include <opie/opimrecord.h> | ||
25 | #include <qpe/recordfields.h> | ||
26 | |||
27 | #include <qstringlist.h> | ||
28 | |||
29 | #if defined(QPC_TEMPLATEDLL) | ||
30 | // MOC_SKIP_BEGIN | ||
31 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; | ||
32 | // MOC_SKIP_END | ||
33 | #endif | ||
34 | |||
35 | class ContactPrivate; // Wozu ist das gut und wo ist das decrariert ? (se) | ||
36 | class QPC_EXPORT OContact : public OPimRecord | ||
37 | { | ||
38 | friend class DataSet; | ||
39 | public: | ||
40 | OContact(); | ||
41 | OContact( const QMap<int, QString> &fromMap ); | ||
42 | virtual ~OContact(); | ||
43 | |||
44 | static void writeVCard( const QString &filename, const QValueList<OContact> &contacts); | ||
45 | static void writeVCard( const QString &filename, const OContact &c ); | ||
46 | static QValueList<OContact> readVCard( const QString &filename ); | ||
47 | |||
48 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | ||
49 | |||
50 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } | ||
51 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } | ||
52 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } | ||
53 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } | ||
54 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } | ||
55 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } | ||
56 | void setFileAs(); | ||
57 | |||
58 | // default email address | ||
59 | void setDefaultEmail( const QString &v ); | ||
60 | // inserts email to list and ensure's doesn't already exist | ||
61 | void insertEmail( const QString &v ); | ||
62 | void removeEmail( const QString &v ); | ||
63 | void clearEmails(); | ||
64 | void insertEmails( const QStringList &v ); | ||
65 | |||
66 | // home | ||
67 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } | ||
68 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } | ||
69 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } | ||
70 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } | ||
71 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } | ||
72 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } | ||
73 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } | ||
74 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } | ||
75 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } | ||
76 | |||
77 | // business | ||
78 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } | ||
79 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } | ||
80 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } | ||
81 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } | ||
82 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } | ||
83 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } | ||
84 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } | ||
85 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } | ||
86 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } | ||
87 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } | ||
88 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } | ||
89 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } | ||
90 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } | ||
91 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } | ||
92 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } | ||
93 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } | ||
94 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } | ||
95 | |||
96 | // personal | ||
97 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } | ||
98 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } | ||
99 | void setBirthday( const QString &v ) { replace( Qtopia::Birthday, v ); } | ||
100 | void setAnniversary( const QString &v ) { replace( Qtopia::Anniversary, v ); } | ||
101 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } | ||
102 | void setChildren( const QString &v ); | ||
103 | |||
104 | // other | ||
105 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } | ||
106 | |||
107 | bool match( const QString ®exp ) const; | ||
108 | |||
109 | // DON'T ATTEMPT TO USE THIS | ||
110 | #ifdef QTOPIA_INTERNAL_CONTACT_MRE | ||
111 | bool match( const QRegExp ®exp ) const; | ||
112 | #endif | ||
113 | |||
114 | // // custom | ||
115 | // void setCustomField( const QString &key, const QString &v ) | ||
116 | // { replace(Custom- + key, v ); } | ||
117 | |||
118 | // name | ||
119 | QString fullName() const; | ||
120 | QString title() const { return find( Qtopia::Title ); } | ||
121 | QString firstName() const { return find( Qtopia::FirstName ); } | ||
122 | QString middleName() const { return find( Qtopia::MiddleName ); } | ||
123 | QString lastName() const { return find( Qtopia::LastName ); } | ||
124 | QString suffix() const { return find( Qtopia::Suffix ); } | ||
125 | QString fileAs() const { return find( Qtopia::FileAs ); } | ||
126 | |||
127 | |||
128 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } | ||
129 | QStringList emailList() const; | ||
130 | |||
131 | // home | ||
132 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } | ||
133 | QString homeCity() const { return find( Qtopia::HomeCity ); } | ||
134 | QString homeState() const { return find( Qtopia::HomeState ); } | ||
135 | QString homeZip() const { return find( Qtopia::HomeZip ); } | ||
136 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } | ||
137 | QString homePhone() const { return find( Qtopia::HomePhone ); } | ||
138 | QString homeFax() const { return find( Qtopia::HomeFax ); } | ||
139 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } | ||
140 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } | ||
141 | /** Multi line string containing all non-empty address info in the form | ||
142 | * Street | ||
143 | * City, State Zip | ||
144 | * Country | ||
145 | */ | ||
146 | QString displayHomeAddress() const; | ||
147 | |||
148 | // business | ||
149 | QString company() const { return find( Qtopia::Company ); } | ||
150 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } | ||
151 | QString businessCity() const { return find( Qtopia::BusinessCity ); } | ||
152 | QString businessState() const { return find( Qtopia::BusinessState ); } | ||
153 | QString businessZip() const { return find( Qtopia::BusinessZip ); } | ||
154 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } | ||
155 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } | ||
156 | QString jobTitle() const { return find( Qtopia::JobTitle ); } | ||
157 | QString department() const { return find( Qtopia::Department ); } | ||
158 | QString office() const { return find( Qtopia::Office ); } | ||
159 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } | ||
160 | QString businessFax() const { return find( Qtopia::BusinessFax ); } | ||
161 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } | ||
162 | QString businessPager() const { return find( Qtopia::BusinessPager ); } | ||
163 | QString profession() const { return find( Qtopia::Profession ); } | ||
164 | QString assistant() const { return find( Qtopia::Assistant ); } | ||
165 | QString manager() const { return find( Qtopia::Manager ); } | ||
166 | /** Multi line string containing all non-empty address info in the form | ||
167 | * Street | ||
168 | * City, State Zip | ||
169 | * Country | ||
170 | */ | ||
171 | QString displayBusinessAddress() const; | ||
172 | |||
173 | //personal | ||
174 | QString spouse() const { return find( Qtopia::Spouse ); } | ||
175 | QString gender() const { return find( Qtopia::Gender ); } | ||
176 | QString birthday() const { return find( Qtopia::Birthday ); } | ||
177 | QString anniversary() const { return find( Qtopia::Anniversary ); } | ||
178 | QString nickname() const { return find( Qtopia::Nickname ); } | ||
179 | QString children() const { return find( Qtopia::Children ); } | ||
180 | QStringList childrenList() const; | ||
181 | |||
182 | // other | ||
183 | QString notes() const { return find( Qtopia::Notes ); } | ||
184 | QString groups() const { return find( Qtopia::Groups ); } | ||
185 | QStringList groupList() const; | ||
186 | |||
187 | // // custom | ||
188 | // const QString &customField( const QString &key ) | ||
189 | // { return find( Custom- + key ); } | ||
190 | |||
191 | static QStringList fields(); | ||
192 | static QStringList trfields(); | ||
193 | |||
194 | QString toRichText() const; | ||
195 | QMap<int, QString> toMap() const; | ||
196 | QString field( int key ) const { return find( key ); } | ||
197 | |||
198 | |||
199 | // journaling... | ||
200 | void saveJournal( journal_action action, const QString &key = QString::null ); | ||
201 | void save( QString &buf ) const; | ||
202 | |||
203 | void setUid( int i ) | ||
204 | { Record::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } | ||
205 | |||
206 | QString toShortText()const; | ||
207 | QString OContact::type()const; | ||
208 | QMap<QString,QString> OContact::toExtraMap() const; | ||
209 | class QString OContact::recordField(int) const; | ||
210 | |||
211 | private: | ||
212 | friend class AbEditor; | ||
213 | friend class AbTable; | ||
214 | friend class AddressBookAccessPrivate; | ||
215 | friend class XMLIO; | ||
216 | |||
217 | QString emailSeparator() const { return " "; } | ||
218 | // the emails should be seperated by a comma | ||
219 | void setEmails( const QString &v ); | ||
220 | QString emails() const { return find( Qtopia::Emails ); } | ||
221 | |||
222 | void insert( int key, const QString &value ); | ||
223 | void replace( int key, const QString &value ); | ||
224 | QString find( int key ) const; | ||
225 | |||
226 | QString displayAddress( const QString &street, | ||
227 | const QString &city, | ||
228 | const QString &state, | ||
229 | const QString &zip, | ||
230 | const QString &country ) const; | ||
231 | |||
232 | Qtopia::UidGen &uidGen() { return sUidGen; } | ||
233 | static Qtopia::UidGen sUidGen; | ||
234 | QMap<int, QString> mMap; | ||
235 | ContactPrivate *d; | ||
236 | }; | ||
237 | |||
238 | // these methods are inlined to keep binary compatability with Qtopia 1.5 | ||
239 | inline void OContact::insertEmail( const QString &v ) | ||
240 | { | ||
241 | //qDebug("insertEmail %s", v.latin1()); | ||
242 | QString e = v.simplifyWhiteSpace(); | ||
243 | QString def = defaultEmail(); | ||
244 | |||
245 | // if no default, set it as the default email and don't insert | ||
246 | if ( def.isEmpty() ) { | ||
247 | setDefaultEmail( e ); // will insert into the list for us | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | // otherwise, insert assuming doesn't already exist | ||
252 | QString emailsStr = find( Qtopia::Emails ); | ||
253 | if ( emailsStr.contains( e )) | ||
254 | return; | ||
255 | if ( !emailsStr.isEmpty() ) | ||
256 | emailsStr += emailSeparator(); | ||
257 | emailsStr += e; | ||
258 | replace( Qtopia::Emails, emailsStr ); | ||
259 | } | ||
260 | |||
261 | inline void OContact::removeEmail( const QString &v ) | ||
262 | { | ||
263 | QString e = v.simplifyWhiteSpace(); | ||
264 | QString def = defaultEmail(); | ||
265 | QString emailsStr = find( Qtopia::Emails ); | ||
266 | QStringList emails = emailList(); | ||
267 | |||
268 | // otherwise, must first contain it | ||
269 | if ( !emailsStr.contains( e ) ) | ||
270 | return; | ||
271 | |||
272 | // remove it | ||
273 | //qDebug(" removing email from list %s", e.latin1()); | ||
274 | emails.remove( e ); | ||
275 | // reset the string | ||
276 | emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator | ||
277 | replace( Qtopia::Emails, emailsStr ); | ||
278 | |||
279 | // if default, then replace the default email with the first one | ||
280 | if ( def == e ) { | ||
281 | //qDebug("removeEmail is default; setting new default"); | ||
282 | if ( !emails.count() ) | ||
283 | clearEmails(); | ||
284 | else // setDefaultEmail will remove e from the list | ||
285 | setDefaultEmail( emails.first() ); | ||
286 | } | ||
287 | } | ||
288 | inline void OContact::clearEmails() | ||
289 | { | ||
290 | mMap.remove( Qtopia::DefaultEmail ); | ||
291 | mMap.remove( Qtopia::Emails ); | ||
292 | } | ||
293 | inline void OContact::setDefaultEmail( const QString &v ) | ||
294 | { | ||
295 | QString e = v.simplifyWhiteSpace(); | ||
296 | |||
297 | //qDebug("OContact::setDefaultEmail %s", e.latin1()); | ||
298 | replace( Qtopia::DefaultEmail, e ); | ||
299 | |||
300 | if ( !e.isEmpty() ) | ||
301 | insertEmail( e ); | ||
302 | |||
303 | } | ||
304 | |||
305 | inline void OContact::insertEmails( const QStringList &v ) | ||
306 | { | ||
307 | for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) | ||
308 | insertEmail( *it ); | ||
309 | } | ||
310 | |||
311 | #endif | ||