1/*
2 This file is part of libkabc.
3 Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <klocale.h>
22#include <klocalizedstring.h>
23#include <kconfig.h>
24#include <kglobal.h>
25#include <kconfiggroup.h>
26
27#include "field.h"
28
29using namespace KABC;
30
31class Field::Private
32{
33 public:
34 Private( int fieldId, int category = 0,
35 const QString &label = QString(),
36 const QString &key = QString(),
37 const QString &app = QString() )
38 : mFieldId( fieldId ), mCategory( category ), mLabel( label ),
39 mKey( key ), mApp( app ) {}
40
41 enum FieldId
42 {
43 CustomField,
44 FormattedName,
45 FamilyName,
46 GivenName,
47 AdditionalName,
48 Prefix,
49 Suffix,
50 NickName,
51 Birthday,
52 HomeAddressStreet,
53 HomeAddressPostOfficeBox,
54 HomeAddressLocality,
55 HomeAddressRegion,
56 HomeAddressPostalCode,
57 HomeAddressCountry,
58 HomeAddressLabel,
59 BusinessAddressStreet,
60 BusinessAddressPostOfficeBox,
61 BusinessAddressLocality,
62 BusinessAddressRegion,
63 BusinessAddressPostalCode,
64 BusinessAddressCountry,
65 BusinessAddressLabel,
66 HomePhone,
67 BusinessPhone,
68 MobilePhone,
69 HomeFax,
70 BusinessFax,
71 CarPhone,
72 Isdn,
73 Pager,
74 Email,
75 Mailer,
76 Title,
77 Role,
78 Organization,
79 Department,
80 Note,
81 Url
82 };
83
84 int fieldId() { return mFieldId; }
85 int category() { return mCategory; }
86
87 QString label() { return mLabel; }
88 QString key() { return mKey; }
89 QString app() { return mApp; }
90
91 static Field::List mAllFields;
92 static Field::List mDefaultFields;
93 static Field::List mCustomFields;
94
95 private:
96 int mFieldId;
97 int mCategory;
98
99 QString mLabel;
100 QString mKey;
101 QString mApp;
102};
103
104Field::List Field::Private::mAllFields;
105Field::List Field::Private::mDefaultFields;
106Field::List Field::Private::mCustomFields;
107
108Field::Field( Private *p )
109 : d( p )
110{
111}
112
113Field::~Field()
114{
115 delete d;
116}
117
118QString Field::label()
119{
120 switch ( d->fieldId() ) {
121 case Private::FormattedName:
122 return Addressee::formattedNameLabel();
123 case Private::FamilyName:
124 return Addressee::familyNameLabel();
125 case Private::GivenName:
126 return Addressee::givenNameLabel();
127 case Private::AdditionalName:
128 return Addressee::additionalNameLabel();
129 case Private::Prefix:
130 return Addressee::prefixLabel();
131 case Private::Suffix:
132 return Addressee::suffixLabel();
133 case Private::NickName:
134 return Addressee::nickNameLabel();
135 case Private::Birthday:
136 return Addressee::birthdayLabel();
137 case Private::HomeAddressStreet:
138 return Addressee::homeAddressStreetLabel();
139 case Private::HomeAddressPostOfficeBox:
140 return Addressee::homeAddressPostOfficeBoxLabel();
141 case Private::HomeAddressLocality:
142 return Addressee::homeAddressLocalityLabel();
143 case Private::HomeAddressRegion:
144 return Addressee::homeAddressRegionLabel();
145 case Private::HomeAddressPostalCode:
146 return Addressee::homeAddressPostalCodeLabel();
147 case Private::HomeAddressCountry:
148 return Addressee::homeAddressCountryLabel();
149 case Private::HomeAddressLabel:
150 return Addressee::homeAddressLabelLabel();
151 case Private::BusinessAddressStreet:
152 return Addressee::businessAddressStreetLabel();
153 case Private::BusinessAddressPostOfficeBox:
154 return Addressee::businessAddressPostOfficeBoxLabel();
155 case Private::BusinessAddressLocality:
156 return Addressee::businessAddressLocalityLabel();
157 case Private::BusinessAddressRegion:
158 return Addressee::businessAddressRegionLabel();
159 case Private::BusinessAddressPostalCode:
160 return Addressee::businessAddressPostalCodeLabel();
161 case Private::BusinessAddressCountry:
162 return Addressee::businessAddressCountryLabel();
163 case Private::BusinessAddressLabel:
164 return Addressee::businessAddressLabelLabel();
165 case Private::HomePhone:
166 return Addressee::homePhoneLabel();
167 case Private::BusinessPhone:
168 return Addressee::businessPhoneLabel();
169 case Private::MobilePhone:
170 return Addressee::mobilePhoneLabel();
171 case Private::HomeFax:
172 return Addressee::homeFaxLabel();
173 case Private::BusinessFax:
174 return Addressee::businessFaxLabel();
175 case Private::CarPhone:
176 return Addressee::carPhoneLabel();
177 case Private::Isdn:
178 return Addressee::isdnLabel();
179 case Private::Pager:
180 return Addressee::pagerLabel();
181 case Private::Email:
182 return Addressee::emailLabel();
183 case Private::Mailer:
184 return Addressee::mailerLabel();
185 case Private::Title:
186 return Addressee::titleLabel();
187 case Private::Role:
188 return Addressee::roleLabel();
189 case Private::Organization:
190 return Addressee::organizationLabel();
191 case Private::Department:
192 return Addressee::departmentLabel();
193 case Private::Note:
194 return Addressee::noteLabel();
195 case Private::Url:
196 return Addressee::urlLabel();
197 case Private::CustomField:
198 return d->label();
199 default:
200 return i18n( "Unknown Field" );
201 }
202}
203
204int Field::category()
205{
206 return d->category();
207}
208
209QString Field::categoryLabel( int category )
210{
211 switch ( category ) {
212 case All:
213 return i18n( "All" );
214 case Frequent:
215 return i18n( "Frequent" );
216 case Address:
217 return i18nc( "street/postal","Address" );
218 case Email:
219 return i18n( "Email" );
220 case Personal:
221 return i18n( "Personal" );
222 case Organization:
223 return i18n( "Organization" );
224 case CustomCategory:
225 return i18n( "Custom" );
226 default:
227 return i18n( "Undefined" );
228 }
229}
230
231QString Field::value( const KABC::Addressee &a )
232{
233 switch ( d->fieldId() ) {
234 case Private::FormattedName:
235 return a.formattedName();
236 case Private::FamilyName:
237 return a.familyName();
238 case Private::GivenName:
239 return a.givenName();
240 case Private::AdditionalName:
241 return a.additionalName();
242 case Private::Prefix:
243 return a.prefix();
244 case Private::Suffix:
245 return a.suffix();
246 case Private::NickName:
247 return a.nickName();
248 case Private::Mailer:
249 return a.mailer();
250 case Private::Title:
251 return a.title();
252 case Private::Role:
253 return a.role();
254 case Private::Organization:
255 return a.organization();
256 case Private::Department:
257 return a.department();
258 case Private::Note:
259 return a.note();
260 case Private::Email:
261 return a.preferredEmail();
262 case Private::Birthday:
263 if ( a.birthday().isValid() )
264 return a.birthday().date().toString( Qt::ISODate );
265 else
266 return QString();
267 case Private::Url:
268 return a.url().prettyUrl();
269 case Private::HomePhone:
270 {
271 PhoneNumber::List::ConstIterator it;
272
273 {
274 // check for preferred number
275 const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home | PhoneNumber::Pref );
276 for ( it = list.begin(); it != list.end(); ++it ) {
277 if ( ( ( *it ).type() & ~( PhoneNumber::Pref ) ) == PhoneNumber::Home ) {
278 return ( *it ).number();
279 }
280 }
281 }
282
283 {
284 // check for normal home number
285 const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home );
286 for ( it = list.begin(); it != list.end(); ++it ) {
287 if ( ( ( *it ).type() & ~(PhoneNumber::Pref) ) == PhoneNumber::Home ) {
288 return ( *it ).number();
289 }
290 }
291 }
292
293 return QString();
294 }
295 case Private::BusinessPhone:
296 {
297 PhoneNumber::List::ConstIterator it;
298
299 {
300 // check for preferred number
301 const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work | PhoneNumber::Pref );
302 for ( it = list.begin(); it != list.end(); ++it ) {
303 if ( ( ( *it ).type() & ~(PhoneNumber::Pref) ) == PhoneNumber::Work ) {
304 return ( *it ).number();
305 }
306 }
307 }
308
309 {
310 // check for normal work number
311 const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work );
312 for ( it = list.begin(); it != list.end(); ++it ) {
313 if ( ( ( *it ).type() & ~(PhoneNumber::Pref) ) == PhoneNumber::Work ) {
314 return ( *it ).number();
315 }
316 }
317 }
318
319 return QString();
320 }
321 case Private::MobilePhone:
322 return a.phoneNumber( PhoneNumber::Cell ).number();
323 case Private::HomeFax:
324 return a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ).number();
325 case Private::BusinessFax:
326 return a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ).number();
327 case Private::CarPhone:
328 return a.phoneNumber( PhoneNumber::Car ).number();
329 case Private::Isdn:
330 return a.phoneNumber( PhoneNumber::Isdn ).number();
331 case Private::Pager:
332 return a.phoneNumber( PhoneNumber::Pager ).number();
333 case Private::HomeAddressStreet:
334 return a.address( Address::Home ).street();
335 case Private::HomeAddressPostOfficeBox:
336 return a.address( Address::Home ).postOfficeBox();
337 case Private::HomeAddressLocality:
338 return a.address( Address::Home ).locality();
339 case Private::HomeAddressRegion:
340 return a.address( Address::Home ).region();
341 case Private::HomeAddressPostalCode:
342 return a.address( Address::Home ).postalCode();
343 case Private::HomeAddressCountry:
344 return a.address( Address::Home ).country();
345 case Private::BusinessAddressStreet:
346 return a.address( Address::Work ).street();
347 case Private::BusinessAddressPostOfficeBox:
348 return a.address( Address::Work ).postOfficeBox();
349 case Private::BusinessAddressLocality:
350 return a.address( Address::Work ).locality();
351 case Private::BusinessAddressRegion:
352 return a.address( Address::Work ).region();
353 case Private::BusinessAddressPostalCode:
354 return a.address( Address::Work ).postalCode();
355 case Private::BusinessAddressCountry:
356 return a.address( Address::Work ).country();
357 case Private::CustomField:
358 return a.custom( d->app(), d->key() );
359 default:
360 return QString();
361 }
362}
363
364bool Field::setValue( KABC::Addressee &a, const QString &value )
365{
366 switch ( d->fieldId() ) {
367 case Private::FormattedName:
368 a.setFormattedName( value );
369 return true;
370 case Private::FamilyName:
371 a.setFamilyName( value );
372 return true;
373 case Private::GivenName:
374 a.setGivenName( value );
375 return true;
376 case Private::AdditionalName:
377 a.setAdditionalName( value );
378 return true;
379 case Private::Prefix:
380 a.setPrefix( value );
381 return true;
382 case Private::Suffix:
383 a.setSuffix( value );
384 return true;
385 case Private::NickName:
386 a.setNickName( value );
387 return true;
388 case Private::Mailer:
389 a.setMailer( value );
390 return true;
391 case Private::Title:
392 a.setTitle( value );
393 return true;
394 case Private::Role:
395 a.setRole( value );
396 return true;
397 case Private::Organization:
398 a.setOrganization( value );
399 return true;
400 case Private::Department:
401 a.setDepartment( value );
402 return true;
403 case Private::Note:
404 a.setNote( value );
405 return true;
406 case Private::Birthday:
407 a.setBirthday( QDateTime::fromString( value, Qt::ISODate ) );
408 return true;
409 case Private::CustomField:
410 a.insertCustom( d->app(), d->key(), value );
411 return true;
412 default:
413 return false;
414 }
415}
416
417QString Field::sortKey( const KABC::Addressee &a )
418{
419 switch ( d->fieldId() ) {
420 case Private::FormattedName:
421 return a.formattedName();
422 case Private::FamilyName:
423 return a.familyName();
424 case Private::GivenName:
425 return a.givenName();
426 case Private::AdditionalName:
427 return a.additionalName();
428 case Private::Prefix:
429 return a.prefix();
430 case Private::Suffix:
431 return a.suffix();
432 case Private::NickName:
433 return a.nickName();
434 case Private::Mailer:
435 return a.mailer();
436 case Private::Title:
437 return a.title();
438 case Private::Role:
439 return a.role();
440 case Private::Organization:
441 return a.organization();
442 case Private::Department:
443 return a.department();
444 case Private::Note:
445 return a.note();
446 case Private::Birthday:
447 if ( a.birthday().isValid() ) {
448 QDate date = a.birthday().date();
449 QString key;
450 key.sprintf( "%02d-%02d", date.month(), date.day() );
451 return key;
452 } else
453 return QLatin1String( "00-00" );
454 default:
455 return value( a ).toLower();
456 }
457}
458
459bool Field::isCustom()
460{
461 return d->fieldId() == Private::CustomField;
462}
463
464Field::List Field::allFields()
465{
466 if ( Private::mAllFields.isEmpty() ) {
467 createField( Private::FormattedName, Frequent );
468 createField( Private::FamilyName, Frequent );
469 createField( Private::GivenName, Frequent );
470 createField( Private::AdditionalName );
471 createField( Private::Prefix );
472 createField( Private::Suffix );
473 createField( Private::NickName, Personal );
474 createField( Private::Birthday, Personal );
475 createField( Private::HomeAddressStreet, Address|Personal );
476 createField( Private::HomeAddressPostOfficeBox, Address|Personal );
477 createField( Private::HomeAddressLocality, Address|Personal );
478 createField( Private::HomeAddressRegion, Address|Personal );
479 createField( Private::HomeAddressPostalCode, Address|Personal );
480 createField( Private::HomeAddressCountry, Address|Personal );
481 createField( Private::HomeAddressLabel, Address|Personal );
482 createField( Private::BusinessAddressStreet, Address|Organization );
483 createField( Private::BusinessAddressPostOfficeBox, Address|Organization );
484 createField( Private::BusinessAddressLocality, Address|Organization );
485 createField( Private::BusinessAddressRegion, Address|Organization );
486 createField( Private::BusinessAddressPostalCode, Address|Organization );
487 createField( Private::BusinessAddressCountry, Address|Organization );
488 createField( Private::BusinessAddressLabel, Address|Organization );
489 createField( Private::HomePhone, Personal|Frequent );
490 createField( Private::BusinessPhone, Organization|Frequent );
491 createField( Private::MobilePhone, Frequent );
492 createField( Private::HomeFax );
493 createField( Private::BusinessFax );
494 createField( Private::CarPhone );
495 createField( Private::Isdn );
496 createField( Private::Pager );
497 createField( Private::Email, Email|Frequent );
498 createField( Private::Mailer, Email );
499 createField( Private::Title, Organization );
500 createField( Private::Role, Organization );
501 createField( Private::Organization, Organization );
502 createField( Private::Department, Organization );
503 createField( Private::Note );
504 createField( Private::Url );
505 }
506
507 return Private::mAllFields;
508}
509
510Field::List Field::defaultFields()
511{
512 if ( Private::mDefaultFields.isEmpty() ) {
513 createDefaultField( Private::FormattedName );
514 createDefaultField( Private::Email );
515 }
516
517 return Private::mDefaultFields;
518}
519
520void Field::createField( int id, int category )
521{
522 Private::mAllFields.append( new Field( new Private( id, category ) ) );
523}
524
525void Field::createDefaultField( int id, int category )
526{
527 Private::mDefaultFields.append( new Field( new Private( id, category ) ) );
528}
529
530void Field::deleteFields()
531{
532 Field::List::ConstIterator it;
533
534 for ( it = Private::mAllFields.constBegin(); it != Private::mAllFields.constEnd(); ++it ) {
535 delete ( *it );
536 }
537 Private::mAllFields.clear();
538
539 for ( it = Private::mDefaultFields.constBegin(); it != Private::mDefaultFields.constEnd(); ++it ) {
540 delete ( *it );
541 }
542 Private::mDefaultFields.clear();
543
544 for ( it = Private::mCustomFields.constBegin(); it != Private::mCustomFields.constEnd(); ++it ) {
545 delete ( *it );
546 }
547 Private::mCustomFields.clear();
548}
549
550void Field::saveFields( const QString &identifier,
551 const Field::List &fields )
552{
553 KConfigGroup cg( KGlobal::config(), "KABCFields" );
554
555 saveFields( cg, identifier, fields );
556}
557
558void Field::saveFields( KConfigGroup &cfg, const QString &identifier,
559 const Field::List &fields )
560{
561 QList<int> fieldIds;
562
563 int custom = 0;
564 Field::List::ConstIterator it;
565 for ( it = fields.begin(); it != fields.end(); ++it ) {
566 fieldIds.append( ( *it )->d->fieldId() );
567 if ( ( *it )->isCustom() ) {
568 QStringList customEntry;
569 customEntry << ( *it )->d->label();
570 customEntry << ( *it )->d->key();
571 customEntry << ( *it )->d->app();
572 cfg.writeEntry( QLatin1String( "KABC_CustomEntry_" ) + identifier + QLatin1Char( '_' ) +
573 QString::number( custom++ ), customEntry );
574 }
575 }
576
577 cfg.writeEntry( identifier, fieldIds );
578}
579
580Field::List Field::restoreFields( const QString &identifier )
581{
582 KConfigGroup cg( KGlobal::config(), "KABCFields" );
583
584 return restoreFields( cg, identifier );
585}
586
587Field::List Field::restoreFields( const KConfigGroup &cfg, const QString &identifier )
588{
589 const QList<int> fieldIds = cfg.readEntry( identifier,QList<int>() );
590
591 Field::List fields;
592
593 int custom = 0;
594 QList<int>::ConstIterator it;
595 for ( it = fieldIds.begin(); it != fieldIds.end(); ++it ) {
596 Private *f = 0;
597 if ( ( *it ) == Private::CustomField ) {
598 QStringList customEntry = cfg.readEntry( QLatin1String( "KABC_CustomEntry_" ) +
599 identifier + QLatin1Char( '_' ) +
600 QString::number( custom++ ),QStringList() );
601 f = new Private( *it, CustomCategory, customEntry[ 0 ],
602 customEntry[ 1 ], customEntry[ 2 ] );
603 } else {
604 f = new Private( *it );
605 }
606 fields.append( new Field( f ) );
607 }
608
609 return fields;
610}
611
612bool Field::equals( Field *field )
613{
614 bool sameId = ( d->fieldId() == field->d->fieldId() );
615
616 if ( !sameId ) return false;
617
618 if ( d->fieldId() != Private::CustomField ) return true;
619
620 return d->key() == field->d->key();
621}
622
623Field *Field::createCustomField( const QString &label, int category,
624 const QString &key, const QString &app )
625{
626 Field *field = new Field( new Private( Private::CustomField,
627 category | CustomCategory,
628 label, key, app ) );
629 Private::mCustomFields.append( field );
630
631 return field;
632}
633