27#include <klocalizedstring.h>
29#include <kstandarddirs.h>
30#include <kconfiggroup.h>
32#include <QtCore/QFile>
34#include <QtCore/QTextStream>
35#include <QtCore/QSharedData>
40#define KABC_FMTTAG_realname QString::fromLatin1("%n")
41#define KABC_FMTTAG_REALNAME QString::fromLatin1("%N")
42#define KABC_FMTTAG_company QString::fromLatin1("%cm")
43#define KABC_FMTTAG_COMPANY QString::fromLatin1("%CM")
44#define KABC_FMTTAG_pobox QString::fromLatin1("%p")
45#define KABC_FMTTAG_street QString::fromLatin1("%s")
46#define KABC_FMTTAG_STREET QString::fromLatin1("%S")
47#define KABC_FMTTAG_zipcode QString::fromLatin1("%z")
48#define KABC_FMTTAG_location QString::fromLatin1("%l")
49#define KABC_FMTTAG_LOCATION QString::fromLatin1("%L")
50#define KABC_FMTTAG_region QString::fromLatin1("%r")
51#define KABC_FMTTAG_REGION QString::fromLatin1("%R")
52#define KABC_FMTTAG_newline QString::fromLatin1("\\n")
53#define KABC_FMTTAG_condcomma QString::fromLatin1("%,")
54#define KABC_FMTTAG_condwhite QString::fromLatin1("%w")
55#define KABC_FMTTAG_purgeempty QString::fromLatin1("%0")
62static int findBalancedBracket(
const QString &tsection,
int pos )
64 int balancecounter = 0;
65 for (
int i = pos + 1; i < tsection.length(); ++i ) {
66 if ( QLatin1Char(
')' ) == tsection[i] && 0 == balancecounter ) {
70 if ( QLatin1Char(
'(' ) == tsection[i] ) {
85static bool parseAddressTemplateSection(
const QString &tsection, QString &result,
86 const QString &realName,
const QString &orgaName,
99 int fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos );
100 while ( -1 != fpos ) {
101 int bpos1 = fpos + KABC_FMTTAG_purgeempty.length();
105 if ( QLatin1Char(
'(' ) == result[bpos1] ) {
106 bpos2 = findBalancedBracket( result, bpos1 );
110 bool purge = !parseAddressTemplateSection( result.mid( bpos1+1,
111 bpos2-bpos1-1 ), rplstr,
112 realName, orgaName, address );
116 result.replace( fpos, bpos2 - fpos + 1, QLatin1String(
"!_P_!" ) );
120 result.replace( fpos, bpos2 - fpos + 1, rplstr );
122 stpos = fpos + rplstr.length();
130 fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos );
137#define REPLTAG(R_TAG,R_FIELD) \
138 if ( result.indexOf( R_TAG, false ) != -1 ) { \
139 QString rpl = R_FIELD.isEmpty() ? QLatin1String( "!_P_!" ) : R_FIELD; \
140 result.replace( R_TAG, rpl ); \
141 if ( !R_FIELD.isEmpty() ) { \
145 REPLTAG( KABC_FMTTAG_realname, realName );
146 REPLTAG( KABC_FMTTAG_REALNAME, realName.toUpper() );
147 REPLTAG( KABC_FMTTAG_company, orgaName );
148 REPLTAG( KABC_FMTTAG_COMPANY, orgaName.toUpper() );
150 REPLTAG( KABC_FMTTAG_street, address.
street() );
151 REPLTAG( KABC_FMTTAG_STREET, address.
street().toUpper() );
152 REPLTAG( KABC_FMTTAG_zipcode, address.
postalCode() );
153 REPLTAG( KABC_FMTTAG_location, address.
locality() );
154 REPLTAG( KABC_FMTTAG_LOCATION, address.
locality().toUpper() );
155 REPLTAG( KABC_FMTTAG_region, address.
region() );
156 REPLTAG( KABC_FMTTAG_REGION, address.
region().toUpper() );
157 result.replace( KABC_FMTTAG_newline, QLatin1String(
"\n" ) );
161 fpos = result.indexOf( KABC_FMTTAG_condcomma, 0 );
162 while ( -1 != fpos ) {
163 const QString str1 = result.mid( fpos - 5, 5 );
164 const QString str2 = result.mid( fpos + 2, 5 );
165 if ( str1 != QLatin1String(
"!_P_!" ) && str2 != QLatin1String(
"!_P_!" ) ) {
166 result.replace( fpos, 2, QLatin1String(
", " ) );
168 result.remove( fpos, 2 );
170 fpos = result.indexOf( KABC_FMTTAG_condcomma, fpos );
173 fpos = result.indexOf( KABC_FMTTAG_condwhite, 0 );
174 while ( -1 != fpos ) {
175 const QString str1 = result.mid( fpos - 5, 5 );
176 const QString str2 = result.mid( fpos + 2, 5 );
177 if ( str1 != QLatin1String(
"!_P_!" ) && str2 != QLatin1String(
"!_P_!" ) ) {
178 result.replace( fpos, 2, QLatin1String(
" " ) );
180 result.remove( fpos, 2 );
182 fpos = result.indexOf( KABC_FMTTAG_condwhite, fpos );
186 result.remove( QLatin1String(
"!_P_!" ) );
191class Address::Private :
public QSharedData
195 : mEmpty( true ), mType( 0 )
197 mId = KRandom::randomString( 10 );
200 Private(
const Private &other )
201 : QSharedData( other )
203 mEmpty = other.mEmpty;
207 mPostOfficeBox = other.mPostOfficeBox;
208 mExtended = other.mExtended;
209 mStreet = other.mStreet;
210 mLocality = other.mLocality;
211 mRegion = other.mRegion;
212 mPostalCode = other.mPostalCode;
213 mCountry = other.mCountry;
214 mLabel = other.mLabel;
221 QString mPostOfficeBox;
253 if (
this != &other ) {
262 if ( d->mId != other.d->mId ) {
265 if ( d->mType != other.d->mType ) {
268 if ( d->mPostOfficeBox != other.d->mPostOfficeBox ) {
271 if ( d->mExtended != other.d->mExtended ) {
274 if ( d->mStreet != other.d->mStreet ) {
277 if ( d->mLocality != other.d->mLocality ) {
280 if ( d->mRegion != other.d->mRegion ) {
283 if ( d->mPostalCode != other.d->mPostalCode ) {
286 if ( d->mCountry != other.d->mCountry ) {
289 if ( d->mLabel != other.d->mLabel ) {
298 return !( a == *this );
340 TypeList::ConstIterator it;
341 for ( it = list.begin(); it != list.end(); ++it ) {
342 if ( (
type() & ( *it ) ) && ( ( *it ) !=
Pref ) ) {
344 label.append( QLatin1Char(
'/' ) );
364 return d->mPostOfficeBox;
369 return i18n(
"Post Office Box" );
385 return i18n(
"Extended Address Information" );
401 return i18n(
"Street" );
417 return i18n(
"Locality" );
433 return i18n(
"Region" );
444 return d->mPostalCode;
449 return i18n(
"Postal Code" );
465 return i18n(
"Country" );
481 return i18n(
"Delivery Label" );
488 if ( list.isEmpty() ) {
498 return i18nc(
"Preferred address",
"Preferred" );
503 return i18nc(
"Address is in home country",
"Domestic" );
506 return i18nc(
"Address is not in home country",
"International" );
509 return i18nc(
"Address for delivering letters",
"Postal" );
512 return i18nc(
"Address for delivering packages",
"Parcel" );
515 return i18nc(
"Home Address",
"Home" );
518 return i18nc(
"Work Address",
"Work" );
521 return i18n(
"Preferred Address" );
524 return i18nc(
"another type of address",
"Other" );
533 str += QLatin1String(
"Address {\n" );
534 str += QString::fromLatin1(
" IsEmpty: %1\n" ).
535 arg( d->mEmpty ? QLatin1String(
"true" ) : QLatin1String(
"false" ) );
536 str += QString::fromLatin1(
" Id: %1\n" ).arg( d->mId );
537 str += QString::fromLatin1(
" Type: %1\n" ).arg(
typeLabel( d->mType ) );
538 str += QString::fromLatin1(
" Post office box: %1\n" ).arg( d->mPostOfficeBox );
539 str += QString::fromLatin1(
" Extended: %1\n" ).arg( d->mExtended );
540 str += QString::fromLatin1(
" Street: %1\n" ).arg( d->mStreet );
541 str += QString::fromLatin1(
" Locality: %1\n" ).arg( d->mLocality );
542 str += QString::fromLatin1(
" Region: %1\n" ).arg( d->mRegion );
543 str += QString::fromLatin1(
" Postal code: %1\n" ).arg( d->mPostalCode );
544 str += QString::fromLatin1(
" Country: %1\n" ).arg( d->mCountry );
545 str += QString::fromLatin1(
" Label: %1\n" ).arg( d->mLabel );
546 str += QLatin1String(
"}\n" );
552 const QString &orgaName )
const
555 QString addrTemplate;
563 ciso = KGlobal::locale()->country();
565 KConfig entry( KStandardDirs::locate(
"locale",
566 QLatin1String(
"l10n/" ) + ciso + QLatin1String(
"/entry.desktop" ) ) );
568 KConfigGroup group = entry.group(
"KCM Locale" );
570 if ( orgaName.isEmpty() ) {
571 addrTemplate = group.readEntry(
"AddressFormat" );
573 addrTemplate = group.readEntry(
"BusinessAddressFormat" );
574 if ( addrTemplate.isEmpty() ) {
575 addrTemplate = group.readEntry(
"AddressFormat" );
581 if ( addrTemplate.isEmpty() ) {
582 kWarning( 5700 ) <<
"address format database incomplete"
583 <<
"(no format for locale" << ciso
584 <<
"found). Using default address formatting.";
585 addrTemplate = QLatin1String(
"%0(%n\\n)%0(%cm\\n)%0(%s\\n)%0(PO BOX %p\\n)%0(%l%w%r)%,%z" );
589 parseAddressTemplateSection( addrTemplate, ret, realName, orgaName, *
this );
594 KConfig entry( KStandardDirs::locate(
"locale", QLatin1String(
"l10n/" ) +
596 QLatin1String(
"/entry.desktop" ) ) );
597 KConfigGroup group = entry.group(
"KCM Locale" );
598 QString cpos = group.readEntry(
"AddressCountryPosition" );
599 if ( QLatin1String(
"BELOW" ) == cpos || cpos.isEmpty() ) {
600 ret = ret + QLatin1String(
"\n\n" ) +
country().toUpper();
601 }
else if ( QLatin1String(
"below" ) == cpos ) {
602 ret = ret + QLatin1String(
"\n\n" ) +
country();
603 }
else if ( QLatin1String(
"ABOVE" ) == cpos ) {
604 ret =
country().toUpper() + QLatin1String(
"\n\n" ) + ret;
605 }
else if ( QLatin1String(
"above" ) == cpos ) {
606 ret =
country() + QLatin1String(
"\n\n" ) + ret;
618 typedef QMap<QString, QString> stringMap;
619 K_GLOBAL_STATIC( stringMap, sISOMap )
621 QMap<QString, QString>::ConstIterator it;
622 it = sISOMap->constFind( cname );
623 if ( it != sISOMap->constEnd() ) {
627 QString mapfile = KGlobal::dirs()->findResource(
"data",
628 QLatin1String(
"kabc/countrytransl.map" ) );
630 QFile file( mapfile );
631 if ( file.open( QIODevice::ReadOnly ) ) {
632 QTextStream s( &file );
633 QString strbuf = s.readLine();
634 while ( !strbuf.isEmpty() ) {
635 QStringList countryInfo = strbuf.split( QLatin1Char(
'\t' ), QString::KeepEmptyParts );
636 if ( countryInfo[ 0 ] == cname ) {
638 sISOMap->insert( cname, countryInfo[ 1 ] );
639 return countryInfo[ 1 ];
641 strbuf = s.readLine();
647 sISOMap->insert( cname, KGlobal::locale()->
country() );
648 return KGlobal::locale()->country();
654 if ( ISOname.simplified().isEmpty() ) {
658 QString mapfile = KGlobal::dirs()->findResource(
"data",
659 QLatin1String(
"kabc/countrytransl.map" ) );
661 QFile file( mapfile );
662 if ( file.open( QIODevice::ReadOnly ) ) {
663 QTextStream s( &file );
664 QString searchStr = QLatin1Char(
'\t' ) + ISOname.simplified().toLower();
665 QString strbuf = s.readLine();
667 while ( !strbuf.isEmpty() ) {
668 if ( ( pos = strbuf.indexOf( searchStr ) ) != -1 ) {
670 return i18n( strbuf.left( pos ).toUtf8() );
672 strbuf = s.readLine();
682 return s << addr.d->mId << (uint)addr.d->mType << addr.d->mPostOfficeBox
683 << addr.d->mExtended << addr.d->mStreet << addr.d->mLocality
684 << addr.d->mRegion << addr.d->mPostalCode << addr.d->mCountry
685 << addr.d->mLabel << addr.d->mEmpty;
691 s >> addr.d->mId >> type >> addr.d->mPostOfficeBox >> addr.d->mExtended
692 >> addr.d->mStreet >> addr.d->mLocality >> addr.d->mRegion
693 >> addr.d->mPostalCode >> addr.d->mCountry >> addr.d->mLabel
696 addr.d->mType = Address::Type( type );
Postal address information.
static QString labelLabel()
Returns the translated label for delivery label field.
static TypeList typeList()
Returns the list of available types.
QString street() const
Returns the street.
static QString streetLabel()
Returns the translated label for street field.
QString postOfficeBox() const
Returns the post office box.
bool isEmpty() const
Returns true, if the address is empty.
QString label() const
Returns the delivery label.
QList< TypeFlag > TypeList
List of address types.
static QString ISOtoCountry(const QString &ISOname)
Returns a localized country name for a ISO code.
Address & operator=(const Address &addr)
Assignment operator.
static QString countryLabel()
Returns the translated label for country field.
QString extended() const
Returns the extended address information.
QString country() const
Returns the country.
void setType(Type type)
Sets the type of address.
void setStreet(const QString &street)
Sets the street (including house number).
Type type() const
Returns the type of address.
bool operator!=(const Address &addr) const
Not-equal operator.
Address()
Creates an empty address.
void setCountry(const QString &country)
Sets the country.
QString region() const
Returns the region.
static QString regionLabel()
Returns the translated label for region field.
void setPostOfficeBox(const QString &postOfficeBox)
Sets the post office box.
void setRegion(const QString ®ion)
Sets the region, e.g.
QString toString() const
Returns a string representation of the address.
void setId(const QString &identifier)
Sets the unique identifier.
void clear()
Clears all entries of the address.
QString locality() const
Returns the locality.
void setExtended(const QString &extended)
Sets the extended address information.
QString typeLabel() const
Returns a translated string of all types the address has.
static QString postalCodeLabel()
Returns the translated label for postal code field.
QString postalCode() const
Returns the postal code.
QString id() const
Returns the unique identifier.
bool operator==(const Address &addr) const
Equality operator.
static QString postOfficeBoxLabel()
Returns the translated label for post office box field.
~Address()
Destroys the address.
QString formattedAddress(const QString &realName=QString(), const QString &orgaName=QString()) const
Returns this address formatted according to the country-specific address formatting rules.
static QString countryToISO(const QString &cname)
Returns ISO code for a localized country name.
static QString extendedLabel()
Returns the translated label for extended field.
void setPostalCode(const QString &code)
Sets the postal code.
static QString localityLabel()
Returns the translated label for locality field.
void setLocality(const QString &locality)
Sets the locality, e.g.
void setLabel(const QString &label)
Sets the delivery label.
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)
QDataStream & operator<<(QDataStream &stream, const Address &address)
Serializes the address object into the stream.
QDataStream & operator>>(QDataStream &stream, Address &address)
Initializes the address object from the stream.