summaryrefslogtreecommitdiff
path: root/kabc
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2012-06-26 13:24:30 (GMT)
committerChristian Mollekopf <chrigi_1@fastmail.fm>2012-06-26 13:24:30 (GMT)
commita79b766c00ffd198cde3601011503c4bf203efbf (patch)
tree6dd92d5a79b6bd9e97d549dd201067a16a8c261b /kabc
parentdb6eb28e9626dd78156b9c6fc17bc0c65ff2f6ca (diff)
downloadlibcalendaring-a79b766c00ffd198cde3601011503c4bf203efbf.tar.gz
imported kabc from
commit b54a325116b194da090f900c9a538710759eb303 Author: Stephen Kelly <steveire@gmail.com> Date: Sun May 6 20:44:53 2012 +0200 Revert "Port to const QRegExp API." This reverts commit 0ca0dfc7e0ca8095efd0b060d1d5e26ac9ceb379. The qtbase commit requiring this was reverted.
Diffstat (limited to 'kabc')
-rw-r--r--kabc/.krazy2
-rw-r--r--kabc/CMakeLists.txt121
-rw-r--r--kabc/HACKING100
-rw-r--r--kabc/HOWTO372
-rw-r--r--kabc/Mainpage.dox35
-rw-r--r--kabc/Messages.sh4
-rw-r--r--kabc/README28
-rw-r--r--kabc/README.AddressFormat66
-rw-r--r--kabc/TODO1
-rw-r--r--kabc/address.cpp697
-rw-r--r--kabc/address.h340
-rw-r--r--kabc/addresseehelper.cpp116
-rw-r--r--kabc/addresseehelper.h122
-rw-r--r--kabc/addresseelist.cpp352
-rw-r--r--kabc/addresseelist.h420
-rw-r--r--kabc/contactgroup.cpp496
-rw-r--r--kabc/contactgroup.h474
-rw-r--r--kabc/contactgroup.xsd76
-rw-r--r--kabc/contactgrouptool.cpp367
-rw-r--r--kabc/contactgrouptool.h76
-rw-r--r--kabc/countrytransl.map5685
-rw-r--r--kabc/emailselectdialog.cpp135
-rw-r--r--kabc/emailselectdialog.h48
-rw-r--r--kabc/errorhandler.cpp78
-rw-r--r--kabc/errorhandler.h114
-rw-r--r--kabc/field.h239
-rw-r--r--kabc/format.h73
-rw-r--r--kabc/geo.cpp170
-rw-r--r--kabc/geo.h134
-rw-r--r--kabc/kabc_export.h127
-rw-r--r--kabc/key.cpp245
-rw-r--r--kabc/key.h185
-rw-r--r--kabc/ldapdn.cpp209
-rw-r--r--kabc/ldapdn_p.h84
-rw-r--r--kabc/ldif.cpp451
-rw-r--r--kabc/ldif_p.h197
-rw-r--r--kabc/ldifconverter.cpp561
-rw-r--r--kabc/ldifconverter.h88
-rw-r--r--kabc/lock.cpp182
-rw-r--r--kabc/lock.h119
-rw-r--r--kabc/locknull.cpp78
-rw-r--r--kabc/locknull.h57
-rw-r--r--kabc/phonenumber.cpp283
-rw-r--r--kabc/phonenumber.h229
-rw-r--r--kabc/picture.cpp187
-rw-r--r--kabc/picture.h168
-rw-r--r--kabc/plugin.cpp71
-rw-r--r--kabc/plugin.h92
-rw-r--r--kabc/resourceabc.h118
-rw-r--r--kabc/scripts/addressee.src.cpp1091
-rw-r--r--kabc/scripts/addressee.src.h483
-rwxr-xr-xkabc/scripts/createisomap.pl32
-rwxr-xr-xkabc/scripts/doxygen-preprocess-addressee.sh5
-rw-r--r--kabc/scripts/entrylist83
-rw-r--r--kabc/scripts/field.src.cpp386
-rwxr-xr-xkabc/scripts/makeaddressee224
-rw-r--r--kabc/secrecy.cpp162
-rw-r--r--kabc/secrecy.h125
-rw-r--r--kabc/sortmode.cpp114
-rw-r--r--kabc/sortmode.h136
-rw-r--r--kabc/sound.cpp171
-rw-r--r--kabc/sound.h182
-rw-r--r--kabc/tests/CMakeLists.txt109
-rw-r--r--kabc/tests/addresseetest.cpp352
-rw-r--r--kabc/tests/addresseetest.h41
-rw-r--r--kabc/tests/addresstest.cpp223
-rw-r--r--kabc/tests/addresstest.h40
-rw-r--r--kabc/tests/bigread.cpp80
-rw-r--r--kabc/tests/bigwrite.cpp90
-rw-r--r--kabc/tests/contactgrouptest.cpp380
-rw-r--r--kabc/tests/geotest.cpp91
-rw-r--r--kabc/tests/geotest.h39
-rw-r--r--kabc/tests/kabcargl.cpp70
-rw-r--r--kabc/tests/keytest.cpp100
-rw-r--r--kabc/tests/keytest.h38
-rw-r--r--kabc/tests/phonenumbertest.cpp173
-rw-r--r--kabc/tests/phonenumbertest.h40
-rw-r--r--kabc/tests/picturetest.cpp152
-rw-r--r--kabc/tests/picturetest.h42
-rw-r--r--kabc/tests/secrecytest.cpp86
-rw-r--r--kabc/tests/secrecytest.h39
-rw-r--r--kabc/tests/soundtest.cpp135
-rw-r--r--kabc/tests/soundtest.h42
-rw-r--r--kabc/tests/testaddresseelist.cpp202
-rw-r--r--kabc/tests/testaddresslineedit.cpp48
-rw-r--r--kabc/tests/testkabc.cpp79
-rw-r--r--kabc/tests/testkabcdlg.cpp62
-rw-r--r--kabc/tests/testlock.cpp207
-rw-r--r--kabc/tests/testlock.h52
-rw-r--r--kabc/tests/timezonetest.cpp87
-rw-r--r--kabc/tests/timezonetest.h39
-rw-r--r--kabc/tests/vcarddragtest.cpp182
-rw-r--r--kabc/timezone.cpp134
-rw-r--r--kabc/timezone.h106
-rw-r--r--kabc/vcardconverter.cpp93
-rw-r--r--kabc/vcardconverter.h140
-rw-r--r--kabc/vcarddrag.cpp94
-rw-r--r--kabc/vcarddrag.h99
-rw-r--r--kabc/vcardparser/CMakeLists.txt38
-rw-r--r--kabc/vcardparser/README.testing15
-rwxr-xr-xkabc/vcardparser/checkvcard.pl79
-rw-r--r--kabc/vcardparser/testread.cpp80
-rw-r--r--kabc/vcardparser/testread2.cpp61
-rw-r--r--kabc/vcardparser/tests/vcard1.vcf13
-rw-r--r--kabc/vcardparser/tests/vcard1.vcf.ref15
-rw-r--r--kabc/vcardparser/tests/vcard2.vcf11
-rw-r--r--kabc/vcardparser/tests/vcard2.vcf.ref12
-rw-r--r--kabc/vcardparser/tests/vcard3.vcf11
-rw-r--r--kabc/vcardparser/tests/vcard3.vcf.ref12
-rw-r--r--kabc/vcardparser/tests/vcard4.vcf14
-rw-r--r--kabc/vcardparser/tests/vcard4.vcf.ref14
-rw-r--r--kabc/vcardparser/tests/vcard5.vcf313
-rw-r--r--kabc/vcardparser/tests/vcard5.vcf.ref313
-rw-r--r--kabc/vcardparser/tests/vcard6.vcf10
-rw-r--r--kabc/vcardparser/tests/vcard6.vcf.ref10
-rw-r--r--kabc/vcardparser/tests/vcard7.vcf7
-rw-r--r--kabc/vcardparser/tests/vcard7.vcf.ref8
-rw-r--r--kabc/vcardparser/testutils.cpp115
-rw-r--r--kabc/vcardparser/testutils.h36
-rw-r--r--kabc/vcardparser/testwrite.cpp120
-rw-r--r--kabc/vcardparser/vcard.cpp116
-rw-r--r--kabc/vcardparser/vcard.h93
-rw-r--r--kabc/vcardparser/vcardline.cpp134
-rw-r--r--kabc/vcardparser/vcardline.h124
-rw-r--r--kabc/vcardparser/vcardparser.cpp312
-rw-r--r--kabc/vcardparser/vcardparser.h45
-rw-r--r--kabc/vcardtool.cpp929
-rw-r--r--kabc/vcardtool.h86
128 files changed, 24998 insertions, 0 deletions
diff --git a/kabc/.krazy b/kabc/.krazy
new file mode 100644
index 0000000..94be3e2
--- /dev/null
+++ b/kabc/.krazy
@@ -0,0 +1,2 @@
+SKIP /scripts/\|/tests/
+EXTRA style
diff --git a/kabc/CMakeLists.txt b/kabc/CMakeLists.txt
new file mode 100644
index 0000000..387bdb1
--- /dev/null
+++ b/kabc/CMakeLists.txt
@@ -0,0 +1,121 @@
+
+project(kabc)
+
+include_directories( ${KDE4_KIO_INCLUDES} )
+
+add_definitions(${QDBUS_DEFINITIONS} -DKDE_DEFAULT_DEBUG_AREA=5700)
+add_definitions( -DQT_NO_CAST_FROM_ASCII )
+add_definitions( -DQT_NO_CAST_TO_ASCII )
+add_definitions( -DWANT_DEPRECATED_KABC_API )
+
+# these apply also for all subdirs
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/vcardparser
+)
+
+# kabc/vcardparser/Makefile.am: vcards
+
+set(vcards_STAT_SRCS
+ vcardparser/vcard.cpp
+ vcardparser/vcardline.cpp
+ vcardparser/vcardparser.cpp
+)
+
+add_subdirectory( vcardparser )
+add_subdirectory( tests )
+#add_subdirectory( scripts )
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripts)
+
+
+
+add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/field.cpp ${CMAKE_CURRENT_BINARY_DIR}/addressee.h ${CMAKE_CURRENT_BINARY_DIR}/addressee.cpp
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/scripts
+ COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/makeaddressee
+ DEPENDS
+ scripts/makeaddressee
+ scripts/addressee.src.cpp
+ scripts/addressee.src.h
+ scripts/entrylist
+ scripts/field.src.cpp
+ )
+
+
+########### next target ###############
+
+set(kabc_LIB_SRCS
+ address.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/addressee.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/addressee.h
+ ${CMAKE_CURRENT_BINARY_DIR}/field.cpp
+ contactgroup.cpp
+ contactgrouptool.cpp
+ errorhandler.cpp
+ geo.cpp
+ key.cpp
+ ldapdn.cpp
+ ldif.cpp
+ phonenumber.cpp
+ picture.cpp
+ plugin.cpp
+ secrecy.cpp
+ sound.cpp
+ timezone.cpp
+ ldifconverter.cpp
+ addresseelist.cpp
+ vcardconverter.cpp
+ vcardtool.cpp
+ addresseehelper.cpp
+ lock.cpp
+ locknull.cpp
+ sortmode.cpp
+ vcarddrag.cpp
+ ${vcards_STAT_SRCS}
+)
+
+if (NOT WINCE)
+ set(kabc_LIB_SRCS
+ ${kabc_LIB_SRCS}
+ #disabled due to no QTreeWidget
+ emailselectdialog.cpp
+ )
+endif()
+
+kde4_add_library(kabc ${LIBRARY_TYPE} ${kabc_LIB_SRCS})
+
+target_link_libraries(kabc ${KDE4_KDEUI_LIBS} ${KDE4_KDECORE_LIBS})
+target_link_libraries(kabc LINK_INTERFACE_LIBRARIES ${KDE4_KDEUI_LIBS})
+
+set_target_properties(kabc PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
+install(TARGETS kabc EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
+
+########### install files ###############
+
+install( FILES countrytransl.map DESTINATION ${DATA_INSTALL_DIR}/kabc )
+install( FILES
+ kabc_export.h
+ address.h
+ ${CMAKE_CURRENT_BINARY_DIR}/addressee.h
+ addresseelist.h
+ contactgroup.h
+ contactgrouptool.h
+ emailselectdialog.h
+ errorhandler.h
+ field.h
+ geo.h
+ key.h
+ ldifconverter.h
+ lock.h
+ locknull.h
+ phonenumber.h
+ picture.h
+ plugin.h
+ secrecy.h
+ sortmode.h
+ sound.h
+ timezone.h
+ vcardconverter.h
+ vcarddrag.h
+ DESTINATION ${INCLUDE_INSTALL_DIR}/kabc COMPONENT Devel
+)
diff --git a/kabc/HACKING b/kabc/HACKING
new file mode 100644
index 0000000..429ae08
--- /dev/null
+++ b/kabc/HACKING
@@ -0,0 +1,100 @@
+Coding Style
+============
+
+See http://korganizer.kde.org/hacking.html for an HTML version.
+
+Formatting
+----------
+
+- No Tabs.
+- Indent with 2 spaces.
+- A line must not have more than 80 chars.
+- Put Spaces between brackets and arguments of functions.
+- For if, else, while and similar statements put the brackets on the same line
+ as the statement.
+- Function and class definitions have their brackets on separate lines.
+
+Example:
+
+void MyClass::myFunction()
+{
+ if ( blah == fasel ) {
+ blubbVariable = arglValue;
+ } else {
+ blubbVariable = oerxValue;
+ }
+}
+
+
+Header Formatting
+-----------------
+
+- General formatting rules apply.
+- Access modifiers are indented.
+- Put curly brackets of class definition on its own line.
+- Double inclusion protection defines are all upper case letters and are
+ composed of the namespace (if available), the classname and a H suffix
+ separated by underscores.
+- Inside a namespace there is no indentation.
+
+Example:
+
+#ifndef XKJ_MYCLASS_H
+#define XKJ_MYCLASS_H
+
+namespace XKJ {
+
+class MyClass
+{
+ public:
+ MyClass();
+
+ private:
+ int mMyInt;
+};
+
+}
+
+#endif
+
+
+API docs
+--------
+
+- Each public function must have a Doxygen compatible comment in the header
+- Use C-style comments without additional asterisks
+- Indent correctly.
+- Comments should be grammatically correct, e.g. sentences start with uppercase
+ letters and end with a full stop.
+- Be concise.
+
+Example:
+
+ /**
+ This function makes tea.
+
+ @param cups number of cups.
+ @result tea
+ */
+ Tea makeTea( int cups );
+
+
+Class and File Names
+--------------------
+
+- Put classes in files, which have the same name as the class, but only
+ lower-case letters.
+- Designer-generated files should have a name classname_base.ui and shoul
+ contain a class called ClassnameBase.
+- Classes inheriting from designer-generated classes have the same name as the
+ generated class, but without the Base suffix.
+
+Class and Variable Names
+------------------------
+
+- For class, variable, function names seperate multiple words by upper-casing
+ the words precedeed by other words.
+- Class names start with an upper-case letter.
+- Function names start with a lower-case letter.
+- Variable names start with a lower-case letter.
+- Member variables of a class start with "m" followed by an upper-case letter.
diff --git a/kabc/HOWTO b/kabc/HOWTO
new file mode 100644
index 0000000..a1e3bbb
--- /dev/null
+++ b/kabc/HOWTO
@@ -0,0 +1,372 @@
+The KDE Address Book Framework
+===============================
+
+The KDE address book framework tries to provide an easy to use and powerful
+mechanism to handle contacts in all KDE applications.
+
+If you want to make use of it, this small introduction to programming
+with libkabc may be helpful.
+
+
+General Concepts
+=================
+
+In libkabc the storage and management of contacts is devided in 2 layers.
+
+******************
+Management Layer *
+******************
+
+ .-------------------.
+ | KABC::AddressBook |
+ .--------------------------------.
+ | KABC::Addressee | => Iterators
+ | KABC::Addressee |
+ | KABC::Addressee | => Search functions
+ | ... |
+ `--------------------------------'
+ |
+ - - - - - - - - - - - | - - - - - - - - - - - - -
+ |
+*************** |
+Storage Layer * |
+*************** | .......................
+ | . . - Network
+ .---------------. | . .---------------. .
+ | ResourceFile |----+-----| ResourceLDAP | .
+ `---------------' | . `---------------' .
+ .---------------. | . .---------------. .
+ | ResourceDir |----+-----| ResourceNet | .
+ `---------------' . `---------------' .
+ . .
+ .......................
+
+
+The Management Layer
+---------------------
+The Management Layer consists of the two classes KABC::AddressBook and
+KABC::Addressee. KABC::AddressBook is a container for KABC::Addressee objects
+and provides 2 kinds of access methods.
+1) Iterators
+ With iterators you can iterate over each of the contacts of the
+ address book and perform an action on it
+
+2) Search functions
+ With search functions you can search for contacts with special attributes
+ such as "all contacts with the name 'Harald'"
+
+The class KABC::Addressee represents a single contact and contains all data
+a vCard could store (as specified in RFC 2426).
+
+The Storage Layer
+------------------
+The Storage Layer consists of the class KABC::Resource and its derived classes.
+These classes are used by KABC::AddressBook to load and store the contacts to
+the single backends.
+At the moment libkabc provides 4 types of resources:
+1) ResourceFile
+ - stores all contacts in a single file
+
+2) ResourceDir
+ - stores each contact in its own file with the unique identifier of the
+ contact as a filename, will all of the files together in one directory
+
+3) ResourceLDAP
+ - stores all of the contacts on a LDAP server
+
+4) ResourceNet
+ - stores all contacts in a single file, which can be accessable via HTTP,
+ FTP, Fish, WebDAV, POP3, IMAP or whatever the KIO frame work supports
+
+In general the developer does not have to take how to save the single contacts.
+He just has to plug one of the above mentioned resources into KABC::AddressBook
+and perform a save action.
+
+Examples
+=========
+Like a picture, C/C++ code is worth a 1000 words I'd like to give you a
+lot of examples now, how to use libkabc for several tasks:
+
+
+Using KABC::StdAddressBook and Iterators
+-----------------------------------------
+Normally you have to plugin the resources manually into the addressbook object
+and call the load() function before you can access the contacts, but there is
+a special class KABC::StdAddressBook, which loads all resources of the standard
+address book of the user automatically. You can use it the following way:
+
+
+ #include <kabc/stdaddressbook.h>
+
+ 1: KABC::AddressBook *ab = KABC::StdAddressBook::self();
+ 2: KABC::AddressBook::Iterator it;
+ 3: for ( it = ab->begin(); it != ab->end(); ++it ) {
+ 4: KABC::Addressee addr = (*it);
+ 5:
+ 6: kDebug() << "Name=" << addr.formattedName();
+ 7: }
+
+The above example prints out the names of all the contacts in the user's address
+book. In line 1 you retrieve a pointer to the user's standard address book
+(provided by KABC::StdAddressBook via a singleton design pattern).
+In line 2 an iterator is defined, which is used in line 3 to iterate over the
+whole address book. The assignment in line 4 is intended only to show more
+clearly how iterators function.
+You could also use (*it).formattedName() directly. In line 6 the formatted name
+of the current contact is printed out to stderr.
+As you can see that's all magic, and it's quite easy ;)
+
+
+Using KABC::AddressBook manually
+---------------------------------
+In some cases you don't want to load the user's standard address book, but,
+for example, just a single vCard. For this purpose you have to use the
+class KABC::AddressBook and handle the resource stuff manually.
+The following code will create a file resource and save a contact into it:
+
+
+ #include <kabc/addressbook.h>
+ #include <kabc/resourcefile.h>
+
+ 1: KABC::AddressBook ab;
+ 2:
+ 3: // create a file resource
+ 4: KABC::Resource *res = new KABC::ResourceFile( "/home/user/myvcard.vcf", "vcard" );
+ 5:
+ 6: if ( !ab.addResource( res ) ) {
+ 7: kDebug() << "Unable to open resource";
+ 8: return 1;
+ 9: }
+10:
+11: if ( !ab.load() ) {
+12: kDebug() << "Unable to load address book!";
+13: return 2;
+14: }
+15:
+16: KABC::Addressee addr;
+17: addr.setNameFromString( "Otto Harald Meyer" );
+18: addr.setBirthday( QDate( 1982, 07, 19 ) );
+19: addr.setNickName( "otto" );
+20: addr.setMailer( "kmail" );
+21:
+22: // TZ
+23: KABC::TimeZone tz( 60 ); // takes time shift in minutes as argument
+24: addr.setTimeZone( tz );
+25:
+26: // GEO
+27: KABC::Geo geo( 52.5, 13.36 ); // takes latitude and longitude as argument
+28: addr.setGeo( geo );
+29:
+30: addr.setTitle( "dude, the" );
+31: addr.setRole( "developer" );
+32: addr.setOrganization( "KDE e.V." );
+33: addr.setNote( "Yet another senseless note..." );
+34: addr.setUrl( KUrl( "http://kaddressbook.org" ) );
+35:
+36: // CLASS
+37: KABC::Secrecy secrecy( KABC::Secrecy::Confidential );
+38: addr.setSecrecy( secrecy );
+39:
+40: // PHOTO or LOGO
+41: KABC::Picture photo;
+42: QImage img;
+43: if ( img.load( "face.png", "PNG" ) ) {
+44: photo.setData( img );
+45: photo.setType( "image/png" );
+46: addr.setPhoto( photo );
+47: }
+48:
+49: addr.insertEmail( "otto@kde.se", true ); // preferred email
+50: addr.insertEmail( "otti@yahoo.com", false );
+51:
+52: // TEL
+53: KABC::PhoneNumber phoneHome( "0351 5466738", KABC::PhoneNumber::Home );
+54: KABC::PhoneNumber phoneWork( "0351 2335411", KABC::PhoneNumber::Work );
+55: addr.insertPhoneNumber( phoneHome );
+56: addr.insertPhoneNumber( phoneWork );
+57:
+58: // ADR
+59: KABC::Address homeAddr( KABC::Address::Home );
+60: homeAddr.setStreet( "Milliwaystreet 42" );
+61: homeAddr.setLocality( "London" );
+62: homeAddr.setRegion( "Saxony" );
+63: homeAddr.setPostalCode( "43435" );
+64: homeAddr.setCountry( "Germany" );
+65: addr.insertAddress( homeAddr );
+66:
+67: addr.insertCategory( "LUG-Dresden-Members" );
+68:
+69: addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", "21.04.2009" );
+70:
+71: ab.insertAddressee( addr ); // will be assigned to the standard resource
+72: // automatically
+73:
+74: KABC::Ticket *ticket = ab.requestSaveTicket( res );
+75: if ( !ticket ) {
+76: kError() << "Resource is locked by other application!";
+77: } else {
+78: if ( !ab.save( ticket ) ) {
+79: kError() << "Saving failed!";
+80: ab.releaseSaveTicket( ticket );
+81: }
+82:
+83: }
+84:
+85: return 0;
+
+In line 1 the KABC::AddressBook is created. In line 4 you creat the
+KABC::ResourceFile (which will handle the loading/saving).
+The resource takes 2 arguments, the first is the file name and the
+second one the file format. At the moment libkabc supports two file formats:
+1) vCard, as specified in RFC 2426
+2) Binary, which increases performance during loading and saving
+
+In line 6 we try to plug the resource into the addressbook. The addressbook
+class tries to open the resource immediately and returns whether opening was
+successful. We add here only one resource, but you can add as many resources
+as you want.
+
+In line 11 we try to load all contacts from the backends into the address book.
+As before, it returns whether opening was successful.
+
+In line 16 a KABC::Addressee is created, which we will fill now with data,
+before inserting it into the KABC::AddressBook.
+The setNameFromString() function in the following line takes a string as
+argument and tries to parse it into the single name components such as: given
+name, family name, additional names, honoric prefix and honoric suffix.
+You can set these values manually as well by calling
+ addr.setGivenName( "Otto" );
+and
+ addr.setFamilyName( "Meyer" );
+etc. etc.
+
+In line 23 we use the class KABC::TimeZone to store the timezone. This class
+takes the time shift in minutes.
+
+In line 27 the KABC::Geo class is used for storing the geographical
+information. The arguments are the latitude and longitude as float values.
+
+KABC::Secrecy in line 37 represents the CLASS entity of a vCard and can take
+KABC::Secrecy::Public, KABC::Secrecy::Private or KABC::Secrecy::Confidential
+as argument.
+
+In line 41 we make use of KABC::Picture class to store the photo of the
+contact. This class can contain either an URL or the raw image data in form
+of a QImage, in this example we use the latter.
+
+In line 43 we try to load the image "face.png" from the local directory and
+assign this QImage to the KABC::Picture class via the setData() function.
+Additionally we set the type of the picture to "image/png".
+
+From 49 - 50 we insert 2 email addresses with the first one as preferred
+(second argument is true).
+
+In 53 and the following 3 lines we add two telephone numbers. For this purpose
+libkabc provides the KABC::PhoneNumber class, which takes the phone number in
+string representation as first argument and the type as second. The types can
+be combined, so 'KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax' would be
+the Home Fax.
+
+In line 59 we create a KABC::Address object and set the single parts in the
+following lines.
+
+In line 67 we assign the contact to a special category.
+
+A contact can also contain custom entries, which are not specified in the API,
+so you can add custom values with insertCustom() as shown in line 69.
+The first argument of this function should be the name of the application, so
+2 applications which use the same custom entry accidentally, do not overwrite
+the data for each other. The second argument contains the name of the
+custom entry and the third argument the value in string representation.
+
+In line 71 we finally insert the KABC::Addressee object into the
+KABC::AddressBook. Since we have only one resource loaded, the contact is
+automatically assigned to this resource. If you have several writeable
+resources loaded, you should ask the user which resource the contact shall
+belong to and assign the selected resource to the contact with
+ KABC::Addressee.setResource( KABC::Resource *resource );
+before inserting it into the address book.
+
+To prevent multiple access to one resource and possible resulting data loss
+we have to lock the resource before saving our changes.
+For this purpose KABC::AddressBook provides the function
+ requestSaveTicket( KABC::Resource* )
+which takes a pointer to the resource which shall be saved as argument and
+returns a so called 'Save Ticket' if locking succeeded or a null pointer
+if the resource is already locked by another application.
+
+So when we retrieved a valid ticket in line 74, we try to save our changes in
+line 78.
+The KABC::AddressBook::save() function takes the save ticket as argument and
+returns whether saving succeeded. It also releases the save ticket when successful.
+
+Important!
+If the save() call fails, you have to release the save ticket manually, as is
+done in line 80, otherwise possible locks, created by the resources, won't be
+removed.
+
+You can see also, that manual use is quite easy for the KABC::AddressBook class
+and for the ResourceFile. For more information about the API of KABC::Addressee
+please take a look at the official API documentation or the header files.
+
+
+Distribution Lists
+-------------------
+libkabc provides so called distribution lists to group contacts. These lists
+just store the uid of contacts, so they can be used for every kind of contact
+grouping. There are 2 classes which handle the whole distribution list tasks,
+KABC::DistributionListManager and KABC::DistributionList. The first one keeps
+track of all available distribution lists and the latter one is the
+representation of one list.
+
+
+ #include <kabc/distributionlist.h>
+ #include <kabc/stdaddressbook.h>
+
+ 1: KABC::DistributionListManager manager( KABC::StdAddressBook::self() );
+ 2:
+ 3: // load the lists
+ 4: manager.load();
+ 5:
+ 6: QStringList listNames = manager.listNames();
+ 7: QStringList::Iterator it;
+ 8: for ( it = listNames.begin(); it != listNames.end(); ++it ) {
+ 9: KABC::DistributionList *list = manager.list( *it );
+10: kDebug() << list->name();
+11:
+12: QStringList emails = list->emails();
+13: QStringList::Iterator eit;
+14: for ( eit = emails.begin(); eit != emails.end(); ++eit )
+15: kDebug() << QString( "\t%1" ).arg( (*eit).toLatin1() );
+16: }
+
+In the first line a KABC::DistributionListManager is created. The manager takes
+a pointer to a KABC::AddressBook, because he has to resolve the stored uids to
+currently available email addresses.
+In line 4 the manager loads all distribution lists from the central config file
+$HOME/.kde/share/apps/kabc/distlists.
+The next line queries the names of all available distribution lists, which are
+used in line 9 to retrieve a pointer to the specific list.
+Now that you have a KABC::DistributionList object, you can performe the
+following actions on it:
+ - set / get the name
+ - insert an entry
+ - remove an entry
+ - get a list of all email addresses
+ - get a list of all entries (which includes the uids)
+
+In line 12 we query all email addresses of every resource and print them out.
+
+<kabc/distributionlist.h> contains also the declaration for the class
+KABC::DistributionListWatcher. This class exists only once per application and
+its only job is to emit a signal as soon as the distribution list file has
+changed. So to make your application aware of changes use the following code:
+
+
+ #include <kabc/distributionlist.h>
+
+ 1: connect( KABC::DistributionListWatcher::self(), SIGNAL( changed() ),
+ 2: this, SLOT( slotDistributionListChanged() ) );
+
+You see, as usual, easy ;)
+
diff --git a/kabc/Mainpage.dox b/kabc/Mainpage.dox
new file mode 100644
index 0000000..6ee8d00
--- /dev/null
+++ b/kabc/Mainpage.dox
@@ -0,0 +1,35 @@
+/*
+ Mainpage.dox -- for now, copied from README
+ */
+
+/**
+@mainpage LIBKABC - new address book API for KDE
+
+@section purpose Purpose
+
+libkabc provides an API for address book data. This can be used by all KDE
+application using data of this type, e.g. KAddressBook, KMail, KOrganizer,
+KPilot etc. It is meant as replacement for libkab (in kdebase/kab).
+
+@section features Features
+
+- Value based interface, addressbook entry data is implicitly shared.
+- Address book entries are identified by a unique id.
+- vCard backend (RFC 2425 / RFC 2426).
+- Locking mechanism to support concurrent access to the address book by
+ multiple processes.
+- Notification on change of addressbook by other process.
+- Dialog for selecting address book entries, supports mouse and keyboard
+ selection, supports automatic name completion.
+- GUI client for viewing, modifying address book data. This is aimed at
+ developers not end users.
+- Tool for converting data, written with libkab, to libkabc format.
+- Multiple backends (resources) for storing entries e.g. LDAP
+
+@authors Cornelius Schumacher \<schumacher@kde.org\>
+
+<b>LICENCE: LGPL</b>
+*/
+// DOXYGEN_REFERENCES = kdecore kdeui kresources
+// DOXYGEN_EXCLUDE = scripts
+// DOXYGEN_TOOLTIP = "An API for the KDE Addressbook."
diff --git a/kabc/Messages.sh b/kabc/Messages.sh
new file mode 100644
index 0000000..b09261a
--- /dev/null
+++ b/kabc/Messages.sh
@@ -0,0 +1,4 @@
+#! /usr/bin/env bash
+cd scripts && perl ./makeaddressee && cd ..
+$XGETTEXT *.cpp -o $podir/kabc.pot
+rm -f addressee.cpp addressee.h field.cpp
diff --git a/kabc/README b/kabc/README
new file mode 100644
index 0000000..632fcab
--- /dev/null
+++ b/kabc/README
@@ -0,0 +1,28 @@
+LIBKABC - new address book API for KDE
+
+PURPOSE:
+
+libkabc provides an API for address book data. This can be used by all KDE
+application using data of this type, e.g. KAddressBook, KMail, KOrganizer,
+KPilot etc. It is meant as replacement for libkab (in kdebase/kab).
+
+FEATURES:
+
+- Value based interface, addressbook entry data is implicitly shared.
+- Address book entries are identified by a unique id.
+- vCard backend (RFC 2425 / RFC 2426).
+- Locking mechanism to support concurrent access to the address book by
+ multiple processes.
+- Notification on change of addressbook by other process.
+- Dialog for selecting address book entries, supports mouse and keyboard
+ selection, supports automatic name completion.
+- GUI client for viewing, modifying address book data. This is aimed at
+ developers not end users.
+- Tool for converting data, written with libkab, to libkabc format.
+- Multiple backends (resources) for storing entries e.g. LDAP
+
+AUTHOR: Cornelius Schumacher <schumacher@kde.org>
+
+LICENCE: LGPL
+
+DATE: 13 Oct 2001
diff --git a/kabc/README.AddressFormat b/kabc/README.AddressFormat
new file mode 100644
index 0000000..8079e49
--- /dev/null
+++ b/kabc/README.AddressFormat
@@ -0,0 +1,66 @@
+Address formats can be a tricky thing. libkabc tries very hard to perfectly fit
+the needs of ~95% of users and to be at least sufficient for the other 5%.
+
+The formatting of an address depends on the destination country as well as on
+the origin country of a letter. Basically, the part indicating the destination
+country follows the rules of the country of origin, all the rest follows the
+rules of the destination country. So we need to store for every country a) the
+country positioning and b) the address formatting.
+
+Address formats should usually be stored in a country's entry.desktop. There we
+store the country position in field "AddressCountryPosition" and the address
+format in a field "AddressFormat". Note that for most countries one field
+"AddressFormat" is sufficient for personal as well as company addresses
+(because personal addresses look just like business addresses without company);
+however, in some countries (eg. Hungary) business addresses differ in their
+structure. In this case you have the possibility of adding another field
+"BusinessAddressFormat" which will be preferred for formatting of business
+addresses; if libkabc can't find such a field, it will fall back to
+"AddressFormat". (Please use BusinessAddressFormat ONLY if you really need to)
+
+The format consists mainly of tags that will be replaced by address fields.
+The list of tags may grow in the future, the format *might* change in the near
+future, but I hope not.
+
+Any comments very very welcome to kde-pim@kde.org or to jost@schenck.de.
+
+-Jost.
+
+Fields AddressFormat and BusinessAddressFormat
+------------------------------------------------
+%n = real name
+%N = REAL NAME
+%cm = company
+%CM = COMPANY
+%s = street
+%S = STREET
+%z = zip code
+%l = location
+%L = LOCATION
+%r = region
+%R = REGION
+%p = post office box
+%, = conditional comma+whitespace,
+ will be left out if the value left or right of it is purged
+%w = conditional whitespace,
+ will be left out if the value left or right of it is purged
+%0(...) = the text inside the brackets will be completely purged if not
+ at least one tag inside it evaluates to something. Example: when the
+ address doesn't have a postbox, the string %0(PO Box %p) will not
+ evaluate to "PO Box " but to an empty string.
+\n = newline
+
+Field AddressCountryPosition
+------------------------------------------------
+below = country name below rest of address
+BELOW = country name below in capital letters
+above = country name above rest of address
+ABOVE = country name above in capital letters
+
+Some Tips
+------------------------------------------------
+- You sometimes have three fields in a line which can all be empty. If you eg.
+separate them all with conditional whitespace (same goes for cond. comma) like
+in "%z%w%r%w%l" and only the middle value (here: region) is empty, there will
+be no whitespace at all between the outer values (here: zipcode and location).
+To avoid this, combine two of these values with purge brackets: %0(%z%w%r)%w%l.
diff --git a/kabc/TODO b/kabc/TODO
new file mode 100644
index 0000000..41644b8
--- /dev/null
+++ b/kabc/TODO
@@ -0,0 +1 @@
+Factor out KLockFile.
diff --git a/kabc/address.cpp b/kabc/address.cpp
new file mode 100644
index 0000000..112c59e
--- /dev/null
+++ b/kabc/address.cpp
@@ -0,0 +1,697 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "address.h"
+
+#include <krandom.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kconfiggroup.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QMap>
+#include <QtCore/QTextStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+// template tags for address formatting localization
+#define KABC_FMTTAG_realname QString::fromLatin1("%n")
+#define KABC_FMTTAG_REALNAME QString::fromLatin1("%N")
+#define KABC_FMTTAG_company QString::fromLatin1("%cm")
+#define KABC_FMTTAG_COMPANY QString::fromLatin1("%CM")
+#define KABC_FMTTAG_pobox QString::fromLatin1("%p")
+#define KABC_FMTTAG_street QString::fromLatin1("%s")
+#define KABC_FMTTAG_STREET QString::fromLatin1("%S")
+#define KABC_FMTTAG_zipcode QString::fromLatin1("%z")
+#define KABC_FMTTAG_location QString::fromLatin1("%l")
+#define KABC_FMTTAG_LOCATION QString::fromLatin1("%L")
+#define KABC_FMTTAG_region QString::fromLatin1("%r")
+#define KABC_FMTTAG_REGION QString::fromLatin1("%R")
+#define KABC_FMTTAG_newline QString::fromLatin1("\\n")
+#define KABC_FMTTAG_condcomma QString::fromLatin1("%,")
+#define KABC_FMTTAG_condwhite QString::fromLatin1("%w")
+#define KABC_FMTTAG_purgeempty QString::fromLatin1("%0")
+
+/**
+ Finds the balanced closing bracket starting from the opening bracket at
+ pos in tsection.
+ @return position of closing bracket, -1 for unbalanced brackets
+*/
+static int findBalancedBracket( const QString &tsection, int pos )
+{
+ int balancecounter = 0;
+ for ( int i = pos + 1; i < tsection.length(); ++i ) {
+ if ( QLatin1Char( ')' ) == tsection[i] && 0 == balancecounter ) {
+ // found end of brackets
+ return i;
+ } else {
+ if ( QLatin1Char( '(' ) == tsection[i] ) {
+ // nested brackets
+ balancecounter++;
+ }
+ }
+ }
+ return -1;
+}
+
+/**
+ Parses a snippet of an address template
+ @param tsection the template string to be parsed
+ @param result QString reference in which the result will be stored
+ @return true if at least one tag evaluated positively, else false
+*/
+static bool parseAddressTemplateSection( const QString &tsection, QString &result,
+ const QString &realName, const QString &orgaName,
+ const KABC::Address &address )
+{
+ // This method first parses and substitutes any bracketed sections and
+ // after that replaces any tags with their values. If a bracketed section
+ // or a tag evaluate to zero, they are not just removed but replaced
+ // with a placeholder. This is because in the last step conditionals are
+ // resolved which depend on information about zero-evaluations.
+ result = tsection;
+ int stpos = 0;
+ bool ret = false;
+
+ // first check for brackets that have to be evaluated first
+ int fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos );
+ while ( -1 != fpos ) {
+ int bpos1 = fpos + KABC_FMTTAG_purgeempty.length();
+ int bpos2;
+ // expect opening bracket and find next balanced closing bracket. If
+ // next char is no opening bracket, continue parsing (no valid tag)
+ if ( QLatin1Char( '(' ) == result[bpos1] ) {
+ bpos2 = findBalancedBracket( result, bpos1 );
+ if ( -1 != bpos2 ) {
+ // we have balanced brackets, recursively parse:
+ QString rplstr;
+ bool purge = !parseAddressTemplateSection( result.mid( bpos1+1,
+ bpos2-bpos1-1 ), rplstr,
+ realName, orgaName, address );
+ if ( purge ) {
+ // purge -> remove all
+ // replace with !_P_!, so conditional tags work later
+ result.replace( fpos, bpos2 - fpos + 1, QLatin1String( "!_P_!" ) );
+ // leave stpos as it is
+ } else {
+ // no purge -> replace with recursively parsed string
+ result.replace( fpos, bpos2 - fpos + 1, rplstr );
+ ret = true;
+ stpos = fpos + rplstr.length();
+ }
+ } else {
+ // unbalanced brackets: keep on parsing (should not happen
+ // and will result in bad formatting)
+ stpos = bpos1;
+ }
+ }
+ fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos );
+ }
+
+ // after sorting out all purge tags, we just search'n'replace the rest,
+ // keeping track of whether at least one tag evaluates to something.
+ // The following macro needs QString for R_FIELD
+ // It substitutes !_P_! for empty fields so conditional tags work later
+#define REPLTAG(R_TAG,R_FIELD) \
+ if ( result.indexOf( R_TAG, false ) != -1 ) { \
+ QString rpl = R_FIELD.isEmpty() ? QLatin1String( "!_P_!" ) : R_FIELD; \
+ result.replace( R_TAG, rpl ); \
+ if ( !R_FIELD.isEmpty() ) { \
+ ret = true; \
+ } \
+ }
+ REPLTAG( KABC_FMTTAG_realname, realName );
+ REPLTAG( KABC_FMTTAG_REALNAME, realName.toUpper() );
+ REPLTAG( KABC_FMTTAG_company, orgaName );
+ REPLTAG( KABC_FMTTAG_COMPANY, orgaName.toUpper() );
+ REPLTAG( KABC_FMTTAG_pobox, address.postOfficeBox() );
+ REPLTAG( KABC_FMTTAG_street, address.street() );
+ REPLTAG( KABC_FMTTAG_STREET, address.street().toUpper() );
+ REPLTAG( KABC_FMTTAG_zipcode, address.postalCode() );
+ REPLTAG( KABC_FMTTAG_location, address.locality() );
+ REPLTAG( KABC_FMTTAG_LOCATION, address.locality().toUpper() );
+ REPLTAG( KABC_FMTTAG_region, address.region() );
+ REPLTAG( KABC_FMTTAG_REGION, address.region().toUpper() );
+ result.replace( KABC_FMTTAG_newline, QLatin1String( "\n" ) );
+#undef REPLTAG
+
+ // conditional comma
+ fpos = result.indexOf( KABC_FMTTAG_condcomma, 0 );
+ while ( -1 != fpos ) {
+ const QString str1 = result.mid( fpos - 5, 5 );
+ const QString str2 = result.mid( fpos + 2, 5 );
+ if ( str1 != QLatin1String( "!_P_!" ) && str2 != QLatin1String( "!_P_!" ) ) {
+ result.replace( fpos, 2, QLatin1String( ", " ) );
+ } else {
+ result.remove( fpos, 2 );
+ }
+ fpos = result.indexOf( KABC_FMTTAG_condcomma, fpos );
+ }
+ // conditional whitespace
+ fpos = result.indexOf( KABC_FMTTAG_condwhite, 0 );
+ while ( -1 != fpos ) {
+ const QString str1 = result.mid( fpos - 5, 5 );
+ const QString str2 = result.mid( fpos + 2, 5 );
+ if ( str1 != QLatin1String( "!_P_!" ) && str2 != QLatin1String( "!_P_!" ) ) {
+ result.replace( fpos, 2, QLatin1String( " " ) );
+ } else {
+ result.remove( fpos, 2 );
+ }
+ fpos = result.indexOf( KABC_FMTTAG_condwhite, fpos );
+ }
+
+ // remove purged:
+ result.remove( QLatin1String( "!_P_!" ) );
+
+ return ret;
+}
+
+class Address::Private : public QSharedData
+{
+ public:
+ Private()
+ : mEmpty( true ), mType( 0 )
+ {
+ mId = KRandom::randomString( 10 );
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mEmpty = other.mEmpty;
+ mId = other.mId;
+ mType = other.mType;
+
+ mPostOfficeBox = other.mPostOfficeBox;
+ mExtended = other.mExtended;
+ mStreet = other.mStreet;
+ mLocality = other.mLocality;
+ mRegion = other.mRegion;
+ mPostalCode = other.mPostalCode;
+ mCountry = other.mCountry;
+ mLabel = other.mLabel;
+ }
+
+ bool mEmpty;
+ QString mId;
+ Type mType;
+
+ QString mPostOfficeBox;
+ QString mExtended;
+ QString mStreet;
+ QString mLocality;
+ QString mRegion;
+ QString mPostalCode;
+ QString mCountry;
+ QString mLabel;
+};
+
+Address::Address()
+ : d( new Private )
+{
+}
+
+Address::Address( Type type )
+ : d( new Private )
+{
+ d->mType = type;
+}
+
+Address::Address( const Address &other )
+ : d( other.d )
+{
+}
+
+Address::~Address()
+{
+}
+
+Address &Address::operator=( const Address &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool Address::operator==( const Address &other ) const
+{
+ if ( d->mId != other.d->mId ) {
+ return false;
+ }
+ if ( d->mType != other.d->mType ) {
+ return false;
+ }
+ if ( d->mPostOfficeBox != other.d->mPostOfficeBox ) {
+ return false;
+ }
+ if ( d->mExtended != other.d->mExtended ) {
+ return false;
+ }
+ if ( d->mStreet != other.d->mStreet ) {
+ return false;
+ }
+ if ( d->mLocality != other.d->mLocality ) {
+ return false;
+ }
+ if ( d->mRegion != other.d->mRegion ) {
+ return false;
+ }
+ if ( d->mPostalCode != other.d->mPostalCode ) {
+ return false;
+ }
+ if ( d->mCountry != other.d->mCountry ) {
+ return false;
+ }
+ if ( d->mLabel != other.d->mLabel ) {
+ return false;
+ }
+
+ return true;
+}
+
+bool Address::operator!=( const Address &a ) const
+{
+ return !( a == *this );
+}
+
+bool Address::isEmpty() const
+{
+ return d->mEmpty;
+}
+
+void Address::clear()
+{
+ *this = Address();
+}
+
+void Address::setId( const QString &id )
+{
+ d->mEmpty = false;
+ d->mId = id;
+}
+
+QString Address::id() const
+{
+ return d->mId;
+}
+
+void Address::setType( Type type )
+{
+ d->mEmpty = false;
+ d->mType = type;
+}
+
+Address::Type Address::type() const
+{
+ return d->mType;
+}
+
+QString Address::typeLabel() const
+{
+ QString label;
+ bool first = true;
+
+ const TypeList list = typeList();
+
+ TypeList::ConstIterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ if ( ( type() & (*it) ) && ( (*it) != Pref ) ) {
+ if ( !first ) {
+ label.append( QLatin1Char( '/' ) );
+ }
+ label.append( typeLabel( *it ) );
+ if ( first ) {
+ first = false;
+ }
+ }
+ }
+
+ return label;
+}
+
+void Address::setPostOfficeBox( const QString &postOfficeBox )
+{
+ d->mEmpty = false;
+ d->mPostOfficeBox = postOfficeBox;
+}
+
+QString Address::postOfficeBox() const
+{
+ return d->mPostOfficeBox;
+}
+
+QString Address::postOfficeBoxLabel()
+{
+ return i18n( "Post Office Box" );
+}
+
+void Address::setExtended( const QString &extended )
+{
+ d->mEmpty = false;
+ d->mExtended = extended;
+}
+
+QString Address::extended() const
+{
+ return d->mExtended;
+}
+
+QString Address::extendedLabel()
+{
+ return i18n( "Extended Address Information" );
+}
+
+void Address::setStreet( const QString &street )
+{
+ d->mEmpty = false;
+ d->mStreet = street;
+}
+
+QString Address::street() const
+{
+ return d->mStreet;
+}
+
+QString Address::streetLabel()
+{
+ return i18n( "Street" );
+}
+
+void Address::setLocality( const QString &locality )
+{
+ d->mEmpty = false;
+ d->mLocality = locality;
+}
+
+QString Address::locality() const
+{
+ return d->mLocality;
+}
+
+QString Address::localityLabel()
+{
+ return i18n( "Locality" );
+}
+
+void Address::setRegion( const QString &region )
+{
+ d->mEmpty = false;
+ d->mRegion = region;
+}
+
+QString Address::region() const
+{
+ return d->mRegion;
+}
+
+QString Address::regionLabel()
+{
+ return i18n( "Region" );
+}
+
+void Address::setPostalCode( const QString &postalCode )
+{
+ d->mEmpty = false;
+ d->mPostalCode = postalCode;
+}
+
+QString Address::postalCode() const
+{
+ return d->mPostalCode;
+}
+
+QString Address::postalCodeLabel()
+{
+ return i18n( "Postal Code" );
+}
+
+void Address::setCountry( const QString &country )
+{
+ d->mEmpty = false;
+ d->mCountry = country;
+}
+
+QString Address::country() const
+{
+ return d->mCountry;
+}
+
+QString Address::countryLabel()
+{
+ return i18n( "Country" );
+}
+
+void Address::setLabel( const QString &label )
+{
+ d->mEmpty = false;
+ d->mLabel = label;
+}
+
+QString Address::label() const
+{
+ return d->mLabel;
+}
+
+QString Address::labelLabel()
+{
+ return i18n( "Delivery Label" );
+}
+
+Address::TypeList Address::typeList()
+{
+ static TypeList list;
+
+ if ( list.isEmpty() ) {
+ list << Dom << Intl << Postal << Parcel << Home << Work << Pref;
+ }
+
+ return list;
+}
+
+QString Address::typeLabel( Type type )
+{
+ if ( type & Pref ) {
+ return i18nc( "Preferred address", "Preferred" );
+ }
+
+ switch ( type ) {
+ case Dom:
+ return i18nc( "Address is in home country", "Domestic" );
+ break;
+ case Intl:
+ return i18nc( "Address is not in home country", "International" );
+ break;
+ case Postal:
+ return i18nc( "Address for delivering letters", "Postal" );
+ break;
+ case Parcel:
+ return i18nc( "Address for delivering packages", "Parcel" );
+ break;
+ case Home:
+ return i18nc( "Home Address", "Home" );
+ break;
+ case Work:
+ return i18nc( "Work Address", "Work" );
+ break;
+ case Pref:
+ return i18n( "Preferred Address" );
+ break;
+ default:
+ return i18nc( "another type of address", "Other" );
+ break;
+ }
+}
+
+QString Address::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Address {\n" );
+ str += QString::fromLatin1( " IsEmpty: %1\n" ).
+ arg( d->mEmpty ? QLatin1String( "true" ) : QLatin1String( "false" ) );
+ str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId );
+ str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) );
+ str += QString::fromLatin1( " Post office box: %1\n" ).arg( d->mPostOfficeBox );
+ str += QString::fromLatin1( " Extended: %1\n" ).arg( d->mExtended );
+ str += QString::fromLatin1( " Street: %1\n" ).arg( d->mStreet );
+ str += QString::fromLatin1( " Locality: %1\n" ).arg( d->mLocality );
+ str += QString::fromLatin1( " Region: %1\n" ).arg( d->mRegion );
+ str += QString::fromLatin1( " Postal code: %1\n" ).arg( d->mPostalCode );
+ str += QString::fromLatin1( " Country: %1\n" ).arg( d->mCountry );
+ str += QString::fromLatin1( " Label: %1\n" ).arg( d->mLabel );
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+QString Address::formattedAddress( const QString &realName,
+ const QString &orgaName ) const
+{
+ QString ciso;
+ QString addrTemplate;
+ QString ret;
+
+ // FIXME: first check for iso-country-field and prefer that one
+ if ( !country().isEmpty() ) {
+ ciso = countryToISO( country() );
+ } else {
+ // fall back to our own country
+ ciso = KGlobal::locale()->country();
+ }
+ KConfig entry( KStandardDirs::locate( "locale",
+ QLatin1String( "l10n/" ) + ciso + QLatin1String( "/entry.desktop" ) ) );
+
+ KConfigGroup group = entry.group( "KCM Locale" );
+ // decide whether this needs special business address formatting
+ if ( orgaName.isEmpty() ) {
+ addrTemplate = group.readEntry( "AddressFormat" );
+ } else {
+ addrTemplate = group.readEntry( "BusinessAddressFormat" );
+ if ( addrTemplate.isEmpty() ) {
+ addrTemplate = group.readEntry( "AddressFormat" );
+ }
+ }
+
+ // in the case there's no format found at all, default to what we've always
+ // used:
+ if ( addrTemplate.isEmpty() ) {
+ kWarning(5700) << "address format database incomplete"
+ << "(no format for locale" << ciso
+ << "found). Using default address formatting.";
+ addrTemplate = QLatin1String( "%0(%n\\n)%0(%cm\\n)%0(%s\\n)%0(PO BOX %p\\n)%0(%l%w%r)%,%z" );
+ }
+
+ // scan
+ parseAddressTemplateSection( addrTemplate, ret, realName, orgaName, *this );
+
+ // now add the country line if needed (formatting this time according to
+ // the rules of our own system country )
+ if ( !country().isEmpty() ) {
+ KConfig entry( KStandardDirs::locate( "locale", QLatin1String( "l10n/" ) +
+ KGlobal::locale()->country() +
+ QLatin1String( "/entry.desktop" ) ) );
+ KConfigGroup group = entry.group( "KCM Locale" );
+ QString cpos = group.readEntry( "AddressCountryPosition" );
+ if ( QLatin1String( "BELOW" ) == cpos || cpos.isEmpty() ) {
+ ret = ret + QLatin1String( "\n\n" ) + country().toUpper();
+ } else if ( QLatin1String( "below" ) == cpos ) {
+ ret = ret + QLatin1String( "\n\n" ) + country();
+ } else if ( QLatin1String( "ABOVE" ) == cpos ) {
+ ret = country().toUpper() + QLatin1String( "\n\n" ) + ret;
+ } else if ( QLatin1String( "above" ) == cpos ) {
+ ret = country() + QLatin1String( "\n\n" ) + ret;
+ }
+ }
+
+ return ret;
+}
+
+QString Address::countryToISO( const QString &cname )
+{
+ // we search a map file for translations from country names to
+ // iso codes, storing caching things in a QMap for faster future
+ // access.
+ typedef QMap<QString, QString> stringMap;
+ K_GLOBAL_STATIC( stringMap, sISOMap )
+
+ QMap<QString, QString>::ConstIterator it;
+ it = sISOMap->constFind( cname );
+ if ( it != sISOMap->constEnd() ) {
+ return it.value();
+ }
+
+ QString mapfile = KGlobal::dirs()->findResource( "data",
+ QLatin1String( "kabc/countrytransl.map" ) );
+
+ QFile file( mapfile );
+ if ( file.open( QIODevice::ReadOnly ) ) {
+ QTextStream s( &file );
+ QString strbuf = s.readLine();
+ while ( !strbuf.isEmpty() ) {
+ QStringList countryInfo = strbuf.split( QLatin1Char( '\t' ), QString::KeepEmptyParts );
+ if ( countryInfo[ 0 ] == cname ) {
+ file.close();
+ sISOMap->insert( cname, countryInfo[ 1 ] );
+ return countryInfo[ 1 ];
+ }
+ strbuf = s.readLine();
+ }
+ file.close();
+ }
+
+ // fall back to system country
+ sISOMap->insert( cname, KGlobal::locale()->country() );
+ return KGlobal::locale()->country();
+}
+
+QString Address::ISOtoCountry( const QString &ISOname )
+{
+ // get country name from ISO country code (e.g. "no" -> i18n("Norway"))
+ if ( ISOname.simplified().isEmpty() ) {
+ return QString();
+ }
+
+ QString mapfile = KGlobal::dirs()->findResource( "data",
+ QLatin1String( "kabc/countrytransl.map" ) );
+
+ QFile file( mapfile );
+ if ( file.open( QIODevice::ReadOnly ) ) {
+ QTextStream s( &file );
+ QString searchStr = QLatin1Char( '\t' ) + ISOname.simplified().toLower();
+ QString strbuf = s.readLine();
+ int pos;
+ while ( !strbuf.isEmpty() ) {
+ if ( ( pos = strbuf.indexOf( searchStr ) ) != -1 ) {
+ file.close();
+ return i18n( strbuf.left( pos ).toUtf8() );
+ }
+ strbuf = s.readLine();
+ }
+ file.close();
+ }
+
+ return ISOname;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Address &addr )
+{
+ return s << addr.d->mId << (uint)addr.d->mType << addr.d->mPostOfficeBox
+ << addr.d->mExtended << addr.d->mStreet << addr.d->mLocality
+ << addr.d->mRegion << addr.d->mPostalCode << addr.d->mCountry
+ << addr.d->mLabel << addr.d->mEmpty;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Address &addr )
+{
+ uint type;
+ s >> addr.d->mId >> type >> addr.d->mPostOfficeBox >> addr.d->mExtended
+ >> addr.d->mStreet >> addr.d->mLocality >> addr.d->mRegion
+ >> addr.d->mPostalCode >> addr.d->mCountry >> addr.d->mLabel
+ >> addr.d->mEmpty;
+
+ addr.d->mType = Address::Type( type );
+
+ return s;
+}
diff --git a/kabc/address.h b/kabc/address.h
new file mode 100644
index 0000000..25a4e9c
--- /dev/null
+++ b/kabc/address.h
@@ -0,0 +1,340 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_ADDRESS_H
+#define KABC_ADDRESS_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QString>
+
+#include "kabc_export.h"
+
+namespace KABC {
+
+/**
+ @brief
+ Postal address information.
+
+ This class represents information about a postal address.
+*/
+class KABC_EXPORT Address
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &s, const Address &addr );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &s, Address &addr );
+
+ public:
+ /**
+ List of addresses.
+ */
+ typedef QList<Address> List;
+
+ /**
+ Address types:
+ */
+ enum TypeFlag {
+ Dom = 1, /**< domestic */
+ Intl = 2, /**< international */
+ Postal = 4, /**< postal */
+ Parcel = 8, /**< parcel */
+ Home = 16, /**< home address */
+ Work = 32, /**< address at work */
+ Pref = 64 /**< preferred address */
+ };
+
+ Q_DECLARE_FLAGS( Type, TypeFlag )
+
+ /**
+ List of address types.
+ */
+ typedef QList<TypeFlag> TypeList;
+
+ /**
+ Creates an empty address.
+ */
+ Address();
+
+ /**
+ Creates an address of the given @p type.
+ */
+ Address( Type type );
+
+ /**
+ Copy constructor.
+ */
+ Address( const Address &address );
+
+ /**
+ Destroys the address.
+ */
+ ~Address();
+
+ /**
+ Equality operator.
+
+ @param addr the address to compare to
+ @return @c true if @c this and @p addr are equal, otherwise @c false
+ */
+ bool operator==( const Address &addr ) const;
+
+ /**
+ Not-equal operator.
+
+ @param addr the address to compare to
+ @return @c true if @c this and @p addr are not equal, otherwise @c false
+ */
+ bool operator!=( const Address &addr ) const;
+
+ /**
+ Assignment operator.
+
+ @param addr the address data to assign to @c this
+ @return a reference to @c this
+ */
+ Address &operator=( const Address &addr );
+
+ /**
+ Returns true, if the address is empty.
+ */
+ bool isEmpty() const;
+
+ /**
+ Clears all entries of the address.
+ */
+ void clear();
+
+ /**
+ Sets the unique @p identifier.
+ */
+ void setId( const QString &identifier );
+
+ /**
+ Returns the unique identifier.
+ */
+ QString id() const;
+
+ /**
+ Sets the type of address. See enum for definiton of types.
+
+ @param type type, can be a bitwise or of multiple types.
+ */
+ void setType( Type type );
+
+ /**
+ Returns the type of address. Can be a bitwise or of multiple types.
+ */
+ Type type() const;
+
+ /**
+ Returns a translated string of all types the address has.
+ */
+ QString typeLabel() const;
+
+ /**
+ Sets the post office box.
+ */
+ void setPostOfficeBox( const QString &postOfficeBox );
+
+ /**
+ Returns the post office box.
+ */
+ QString postOfficeBox() const;
+
+ /**
+ Returns the translated label for post office box field.
+ */
+ static QString postOfficeBoxLabel();
+
+ /**
+ Sets the @p extended address information.
+ */
+ void setExtended( const QString &extended );
+
+ /**
+ Returns the extended address information.
+ */
+ QString extended() const;
+
+ /**
+ Returns the translated label for extended field.
+ */
+ static QString extendedLabel();
+
+ /**
+ Sets the @p street (including house number).
+ */
+ void setStreet( const QString &street );
+
+ /**
+ Returns the street.
+ */
+ QString street() const;
+
+ /**
+ Returns the translated label for street field.
+ */
+ static QString streetLabel();
+
+ /**
+ Sets the @p locality, e.g. city.
+
+ @param locality the locality of the address, e.g. city
+ */
+ void setLocality( const QString &locality );
+
+ /**
+ Returns the locality.
+ */
+ QString locality() const;
+
+ /**
+ Returns the translated label for locality field.
+ */
+ static QString localityLabel();
+
+ /**
+ Sets the @p region, e.g. state.
+
+ @param region the region the address falls into, e.g. state
+ */
+ void setRegion( const QString &region );
+
+ /**
+ Returns the region.
+ */
+ QString region() const;
+
+ /**
+ Returns the translated label for region field.
+ */
+ static QString regionLabel();
+
+ /**
+ Sets the postal @p code.
+ */
+ void setPostalCode( const QString &code );
+
+ /**
+ Returns the postal code.
+ */
+ QString postalCode() const;
+
+ /**
+ Returns the translated label for postal code field.
+ */
+ static QString postalCodeLabel();
+
+ /**
+ Sets the @p country.
+ */
+ void setCountry( const QString &country );
+
+ /**
+ Returns the country.
+ */
+ QString country() const;
+
+ /**
+ Returns the translated label for country field.
+ */
+ static QString countryLabel();
+
+ /**
+ Sets the delivery @p label. This is the literal text to be used as label.
+
+ @param label the string to use for delivery labels
+ */
+ void setLabel( const QString &label );
+
+ /**
+ Returns the delivery label.
+ */
+ QString label() const;
+
+ /**
+ Returns the translated label for delivery label field.
+ */
+ static QString labelLabel();
+
+ /**
+ Returns the list of available types.
+ */
+ static TypeList typeList();
+
+ /**
+ Returns the translated label for the given @p type.
+ */
+ static QString typeLabel( Type type );
+
+ /**
+ Returns a string representation of the address.
+ */
+ QString toString() const;
+
+ /**
+ Returns this address formatted according to the country-specific
+ address formatting rules. The formatting rules applied depend on
+ either the addresses {@link #country country} field, or (if the
+ latter is empty) on the system country setting. If companyName is
+ provided, an available business address format will be preferred.
+
+ @param realName the formatted name of the contact
+ @param orgaName the name of the organization or company
+ @return the formatted address (containing newline characters)
+ */
+ QString formattedAddress( const QString &realName = QString(),
+ const QString &orgaName = QString() ) const;
+
+ /**
+ Returns ISO code for a localized country name. Only localized country
+ names will be understood. This might be replaced by a KLocale method in
+ the future.
+ @param cname name of the country
+ @return two digit ISO code
+ */
+ static QString countryToISO( const QString &cname );
+
+ /**
+ Returns a localized country name for a ISO code.
+ This might be replaced by a KLocale method in the future.
+ @param ISOname two digit ISO code
+ @return localized name of the country
+ */
+ static QString ISOtoCountry( const QString &ISOname );
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( Address::Type )
+
+/**
+ Serializes the @p address object into the @p stream.
+*/
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Address &address );
+
+/**
+ Initializes the @p address object from the @p stream.
+*/
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Address &address );
+
+}
+
+#endif
diff --git a/kabc/addresseehelper.cpp b/kabc/addresseehelper.cpp
new file mode 100644
index 0000000..d6e1468
--- /dev/null
+++ b/kabc/addresseehelper.cpp
@@ -0,0 +1,116 @@
+/*
+ This file is part of the KDE libraries
+ Copyright (C) 2003 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "addresseehelper.h"
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kconfiggroup.h>
+
+#include <QApplication>
+#include <QtDBus/QtDBus>
+
+using namespace KABC;
+
+AddresseeHelper *AddresseeHelper::s_self;
+
+// static
+AddresseeHelper *AddresseeHelper::self()
+{
+ if ( !s_self ) {
+ s_self = new AddresseeHelper();
+ }
+
+ return s_self;
+}
+
+AddresseeHelper::AddresseeHelper()
+ : QObject( qApp )
+{
+ initSettings();
+
+ QDBusConnection::sessionBus().connect( QString(), QLatin1String( "/KABC" ),
+ QLatin1String( "org.kde.kabc.AddressBookConfig" ),
+ QLatin1String( "changed" ),
+ this, SLOT(initSettings()));
+}
+
+// static
+void AddresseeHelper::addToSet( const QStringList &list, QSet<QString> &container )
+{
+ QStringList::ConstIterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ if ( !(*it).isEmpty() ) {
+ container.insert( *it );
+ }
+ }
+}
+
+void AddresseeHelper::initSettings()
+{
+ mTitles.clear();
+ mSuffixes.clear();
+ mPrefixes.clear();
+
+ mTitles.insert( i18n( "Dr." ) );
+ mTitles.insert( i18n( "Miss" ) );
+ mTitles.insert( i18n( "Mr." ) );
+ mTitles.insert( i18n( "Mrs." ) );
+ mTitles.insert( i18n( "Ms." ) );
+ mTitles.insert( i18n( "Prof." ) );
+
+ mSuffixes.insert( i18n( "I" ) );
+ mSuffixes.insert( i18n( "II" ) );
+ mSuffixes.insert( i18n( "III" ) );
+ mSuffixes.insert( i18n( "Jr." ) );
+ mSuffixes.insert( i18n( "Sr." ) );
+
+ mPrefixes.insert( QLatin1String( "van" ) );
+ mPrefixes.insert( QLatin1String( "von" ) );
+ mPrefixes.insert( QLatin1String( "de" ) );
+
+ KConfig _config( QLatin1String( "kabcrc" ), KConfig::NoGlobals );
+ KConfigGroup config(&_config, "General" );
+
+ addToSet( config.readEntry( "Prefixes", QStringList() ), mTitles );
+ addToSet( config.readEntry( "Inclusions", QStringList() ), mPrefixes );
+ addToSet( config.readEntry( "Suffixes", QStringList() ), mSuffixes );
+ mTradeAsFamilyName = config.readEntry( "TradeAsFamilyName", true );
+}
+
+bool AddresseeHelper::containsTitle( const QString &title ) const
+{
+ return mTitles.contains( title );
+}
+
+bool AddresseeHelper::containsPrefix( const QString &prefix ) const
+{
+ return mPrefixes.contains( prefix );
+}
+
+bool AddresseeHelper::containsSuffix( const QString &suffix ) const
+{
+ return mSuffixes.contains( suffix );
+}
+
+bool AddresseeHelper::tradeAsFamilyName() const
+{
+ return mTradeAsFamilyName;
+}
+
diff --git a/kabc/addresseehelper.h b/kabc/addresseehelper.h
new file mode 100644
index 0000000..bfbb32c
--- /dev/null
+++ b/kabc/addresseehelper.h
@@ -0,0 +1,122 @@
+/*
+ This file is part of the KDE libraries
+ Copyright (C) 2003 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation, version 2.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_ADDRESSEEHELPER_H
+#define KABC_ADDRESSEEHELPER_H
+
+#include "kabc_export.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QSet>
+
+namespace KABC {
+
+/**
+ * This singleton class stores static data, which is shared
+ * by all Addressee objects. It maintains three lists of
+ * strings, which can be queried using this class:
+ *
+ * - a list of honoric prefixes, like "Mrs.", "Prof." etc,
+ * see containsTitle()
+ * - a list of inclusions, such as "van" or "de", see
+ * containsPrefix()
+ * - a list of honoric suffixes, such as "I" or "Jr.", see
+ * containsSuffix()
+ *
+ * All of these lists have a hardcoded and a configurable
+ * part. The configurable part is found in @c kabcrc, group
+ * @c General, fields @c Prefixes, @c Inclusions, and
+ * @c Suffixes.
+ *
+ * In addition to the above, this class stores one conveniece
+ * setting: it stores whether or not a single name component
+ * should be interpreted as a family name (see
+ * tradeAsFamilyName()). The corresponding configuration
+ * field is @c TradeAsFamilyName.
+ */
+class KABC_EXPORT AddresseeHelper : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Singleton interface to this class
+ *
+ * @return a pointer to the unique instance of this class.
+ */
+ static AddresseeHelper *self();
+
+ /**
+ * Queries the list of honoric prefixes.
+ *
+ * @param title the honoric prefix to search for
+ * @return @c true, if @p title was found in the list,
+ * @c false otherwise
+ */
+ bool containsTitle( const QString &title ) const;
+
+ /**
+ * Queries the list of inclusions.
+ *
+ * @param prefix the inclusion to search for
+ * @return @c true, if @p prefix was found in the list,
+ * @c false otherwise
+ */
+ bool containsPrefix( const QString &prefix ) const;
+
+ /**
+ * Queries the list of honoric suffixes.
+ *
+ * @param suffix the honoric suffix to search for
+ * @return @c true, if @p suffix was found in the list,
+ * @c false otherwise
+ */
+ bool containsSuffix( const QString &suffix ) const;
+
+ /**
+ * Returns whether or not a single name component should
+ * be interpreted as a family name.
+ *
+ * @return @c true if single name component is a family name,
+ * @c false otherwise.
+ */
+ bool tradeAsFamilyName() const;
+
+ public Q_SLOTS:
+ /**
+ * Recreates the static data and reparses the configuration.
+ */
+ void initSettings();
+
+ private:
+ AddresseeHelper();
+
+ static void addToSet( const QStringList &list, QSet<QString> &container );
+ QSet<QString> mTitles;
+ QSet<QString> mPrefixes;
+ QSet<QString> mSuffixes;
+ bool mTradeAsFamilyName;
+
+ static AddresseeHelper *s_self;
+};
+
+}
+
+#endif
diff --git a/kabc/addresseelist.cpp b/kabc/addresseelist.cpp
new file mode 100644
index 0000000..ad2fc4f
--- /dev/null
+++ b/kabc/addresseelist.cpp
@@ -0,0 +1,352 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Jost Schenck <jost@schenck.de>
+ 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "addresseelist.h"
+#include "field.h"
+#include "sortmode.h"
+
+#include <kdebug.h>
+
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+//
+//
+// Traits
+//
+//
+
+SortingTraits::Uid::Uid()
+ : d( 0 )
+{
+}
+
+SortingTraits::Uid::~Uid()
+{
+}
+
+bool SortingTraits::Uid::eq( const Addressee &a1, const Addressee &a2 )
+{
+ // locale awareness doesn't make sense sorting ids
+ return QString::compare( a1.uid(), a2.uid() ) == 0;
+}
+
+bool SortingTraits::Uid::lt( const Addressee &a1, const Addressee &a2 )
+{
+ // locale awareness doesn't make sense sorting ids
+ return QString::compare( a1.uid(), a2.uid() ) < 0;
+}
+
+SortingTraits::Name::Name()
+ : d( 0 )
+{
+}
+
+SortingTraits::Name::~Name()
+{
+}
+
+bool SortingTraits::Name::eq( const Addressee &a1, const Addressee &a2 )
+{
+ return QString::localeAwareCompare( a1.name(), a2.name() ) == 0;
+}
+
+bool SortingTraits::Name::lt( const Addressee &a1, const Addressee &a2 )
+{
+ return QString::localeAwareCompare( a1.name(), a2.name() ) < 0;
+}
+
+SortingTraits::FormattedName::FormattedName()
+ : d( 0 )
+{
+}
+
+SortingTraits::FormattedName::~FormattedName()
+{
+}
+
+bool SortingTraits::FormattedName::eq( const Addressee &a1, const Addressee &a2 )
+{
+ return QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) == 0;
+}
+
+bool SortingTraits::FormattedName::lt( const Addressee &a1, const Addressee &a2 )
+{
+ return QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) < 0;
+}
+
+SortingTraits::FamilyName::FamilyName()
+ : d( 0 )
+{
+}
+
+SortingTraits::FamilyName::~FamilyName()
+{
+}
+
+bool SortingTraits::FamilyName::eq( const Addressee &a1, const Addressee &a2 )
+{
+ return
+ QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0 &&
+ QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0;
+}
+
+bool SortingTraits::FamilyName::lt( const Addressee &a1, const Addressee &a2 )
+{
+ int family = QString::localeAwareCompare( a1.familyName(), a2.familyName() );
+ if ( 0 == family ) {
+ return QString::localeAwareCompare( a1.givenName(), a2.givenName() ) < 0;
+ } else {
+ return family < 0;
+ }
+}
+
+SortingTraits::GivenName::GivenName()
+ : d( 0 )
+{
+}
+
+SortingTraits::GivenName::~GivenName()
+{
+}
+
+bool SortingTraits::GivenName::eq( const Addressee &a1, const Addressee &a2 )
+{
+ return
+ QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0 &&
+ QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0;
+}
+
+bool SortingTraits::GivenName::lt( const Addressee &a1, const Addressee &a2 )
+{
+ int given = QString::localeAwareCompare( a1.givenName(), a2.givenName() );
+ if ( 0 == given ) {
+ return QString::localeAwareCompare( a1.familyName(), a2.familyName() ) < 0;
+ } else {
+ return given < 0;
+ }
+}
+
+//
+//
+// AddresseeList
+//
+//
+
+static Field *sActiveField=0;
+
+class AddresseeList::Private : public QSharedData
+{
+ public:
+ Private()
+ : mReverseSorting( false ), mActiveSortingCriterion( FormattedName )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mReverseSorting = other.mReverseSorting;
+ mActiveSortingCriterion = other.mActiveSortingCriterion;
+ }
+
+ bool mReverseSorting;
+ SortingCriterion mActiveSortingCriterion;
+};
+
+AddresseeList::AddresseeList()
+ : QList<Addressee>(), d( new Private )
+{
+}
+
+AddresseeList::~AddresseeList()
+{
+}
+
+AddresseeList::AddresseeList( const AddresseeList &other )
+ : QList<Addressee>( other ), d( other.d )
+{
+}
+
+AddresseeList::AddresseeList( const QList<Addressee> &l )
+ : QList<Addressee>( l ), d( new Private )
+{
+}
+
+AddresseeList &AddresseeList::operator=( const AddresseeList &other )
+{
+ if ( this != &other ) {
+ QList<Addressee>::operator=( other );
+ d = other.d;
+ }
+
+ return *this;
+}
+
+QString AddresseeList::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "AddresseeList {\n" );
+ str += QString::fromLatin1( " Reverse Order: %1\n" ).arg( d->mReverseSorting ?
+ QLatin1String( "true" ) :
+ QLatin1String( "false" ) );
+
+ QString crit;
+ if ( Uid == d->mActiveSortingCriterion ) {
+ crit = QLatin1String( "Uid" );
+ } else if ( Name == d->mActiveSortingCriterion ) {
+ crit = QLatin1String( "Name" );
+ } else if ( FormattedName == d->mActiveSortingCriterion ) {
+ crit = QLatin1String( "FormattedName" );
+ } else if ( FamilyName == d->mActiveSortingCriterion ) {
+ crit = QLatin1String( "FamilyName" );
+ } else if ( GivenName == d->mActiveSortingCriterion ) {
+ crit = QLatin1String( "GivenName" );
+ } else {
+ crit = QLatin1String( "unknown -- update dump method" );
+ }
+
+ str += QString::fromLatin1( " Sorting criterion: %1\n" ).arg( crit );
+
+ for ( const_iterator it = begin(); it != end(); ++it ) {
+// str += (*it).toString();
+ }
+
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+void AddresseeList::setReverseSorting( bool reverseSorting )
+{
+ d->mReverseSorting = reverseSorting;
+}
+
+bool AddresseeList::reverseSorting() const
+{
+ return d->mReverseSorting;
+}
+
+void AddresseeList::sortBy( SortingCriterion c )
+{
+ d->mActiveSortingCriterion = c;
+ if ( Uid == c ) {
+ sortByTrait<SortingTraits::Uid>();
+ } else if ( Name == c ) {
+ sortByTrait<SortingTraits::Name>();
+ } else if ( FormattedName == c ) {
+ sortByTrait<SortingTraits::FormattedName>();
+ } else if ( FamilyName == c ) {
+ sortByTrait<SortingTraits::FamilyName>();
+ } else if ( GivenName == c ) {
+ sortByTrait<SortingTraits::GivenName>();
+ } else {
+ kError(5700) << "AddresseeList sorting criterion passed for which a trait is not known."
+ << "No sorting done.";
+ }
+}
+
+void AddresseeList::sort()
+{
+ sortBy( d->mActiveSortingCriterion );
+}
+
+template<class Trait>
+void AddresseeList::sortByTrait()
+{
+ // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists.
+ //
+ // for i := 1 to n - 1
+ // do for j := 1 to n - i
+ // do if A[j] > A[j+1]
+ // then temp := A[j]
+ // A[j] := A[j + 1]
+ // A[j + 1 ] := temp
+
+ iterator i1 = begin();
+ iterator endIt = end();
+ --endIt;
+ if ( i1 == endIt ) { // don't need sorting
+ return;
+ }
+
+ iterator i2 = endIt;
+ while ( i1 != endIt ) {
+ iterator j1 = begin();
+ iterator j2 = j1;
+ ++j2;
+ while ( j1 != i2 ) {
+ if ( ( !d->mReverseSorting && Trait::lt( *j2, *j1 ) ) ||
+ ( d->mReverseSorting && Trait::lt( *j1, *j2 ) ) ) {
+ qSwap( *j1, *j2 );
+ }
+ ++j1;
+ ++j2;
+ }
+ ++i1;
+ --i2;
+ }
+}
+
+void AddresseeList::sortByField( Field *field )
+{
+ if ( !field ) {
+ kWarning(5700) << "sortByField called with no active sort field";
+ return;
+ }
+
+ sActiveField = field;
+
+ if ( count() == 0 ) {
+ return;
+ }
+
+ KABC::FieldSortMode *mode = new KABC::FieldSortMode( sActiveField, !d->mReverseSorting );
+
+ KABC::Addressee::setSortMode( mode );
+ qSort( *this );
+ KABC::Addressee::setSortMode( 0 );
+
+ delete mode;
+}
+
+void AddresseeList::sortByMode( SortMode *mode )
+{
+ if ( count() == 0 ) {
+ return;
+ }
+
+ KABC::Addressee::setSortMode( mode );
+ qSort( *this );
+ KABC::Addressee::setSortMode( 0 );
+}
+
+SortingCriterion AddresseeList::sortingCriterion() const
+{
+ return d->mActiveSortingCriterion;
+}
+
+Field *AddresseeList::sortingField() const
+{
+ return sActiveField;
+}
diff --git a/kabc/addresseelist.h b/kabc/addresseelist.h
new file mode 100644
index 0000000..e842c9b
--- /dev/null
+++ b/kabc/addresseelist.h
@@ -0,0 +1,420 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Jost Schenck <jost@schenck.de>
+ 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_ADDRESSEELIST_H
+#define KABC_ADDRESSEELIST_H
+
+#include "kabc_export.h"
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QList>
+
+namespace KABC {
+
+class Field;
+class SortMode;
+class Addressee;
+
+/**
+ * Each trait must implement one static function for equality, one for "less
+ * than". Class name should be the field name. A trait does not necessarily
+ * have to stick to just one field: a trait sorting by family name can e.g.
+ * sort addressees with equal family name by given name.
+ *
+ * If you want to implement reverse sorting, you do not have to write another
+ * trait, as AddresseeList takes care of that.
+ */
+namespace SortingTraits
+{
+
+class KABC_EXPORT Uid
+{
+ public:
+ /**
+ * Creates an instance.
+ */
+ Uid();
+
+ /**
+ * Destroys the instance.
+ */
+ ~Uid();
+
+ /**
+ * "Equal" compare method
+ *
+ * @return @c true if the first parameter is equal to the second
+ * when comparing the uid attribute.
+ *
+ * @see Addressee::uid()
+ * @see QString::compare()
+ */
+ static bool eq( const Addressee &, const Addressee & );
+
+ /**
+ * "Less-Than" compare method
+ *
+ * @return @c true if the first parameter is "less-than" the second
+ * when comparing the uid attribute.
+ *
+ * @see Addressee::uid()
+ * @see QString::compare()
+ */
+ static bool lt( const Addressee &, const Addressee & );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+class KABC_EXPORT Name
+{
+ public:
+ /**
+ * Creates an instance.
+ */
+ Name();
+
+ /**
+ * Destroys the instance.
+ */
+ ~Name();
+
+ /**
+ * "Equal" compare method
+ *
+ * @return @c true if the first parameter is equal to the second
+ * when comparing the name attribute.
+ *
+ * @see Addressee::name()
+ * @see QString::localeAwareCompare()
+ */
+ static bool eq( const Addressee &, const Addressee & );
+
+ /**
+ * "Less-Than" compare method
+ *
+ * @return @c true if the first parameter is "less-than" the second
+ * when comparing the name attribute.
+ *
+ * @see Addressee::name()
+ * @see QString::localeAwareCompare()
+ */
+ static bool lt( const Addressee &, const Addressee & );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+class KABC_EXPORT FormattedName
+{
+ public:
+ /**
+ * Creates an instance.
+ */
+ FormattedName();
+
+ /**
+ * Destroys the instance.
+ */
+ ~FormattedName();
+
+ /**
+ * "Equal" compare method
+ *
+ * @return @c true if the first parameter is equal to the second
+ * when comparing the formatted name attribute.
+ *
+ * @see Addressee::formattedName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool eq( const Addressee &, const Addressee & );
+
+ /**
+ * "Less-Than" compare method
+ *
+ * @return @c true if the first parameter is "less-than" the second
+ * when comparing the formatted name attribute.
+ *
+ * @see Addressee::formattedName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool lt( const Addressee &, const Addressee & );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+class KABC_EXPORT FamilyName // fallback to given name
+{
+ public:
+ /**
+ * Creates an instance.
+ */
+ FamilyName();
+
+ /**
+ * Destroys the instance.
+ */
+ ~FamilyName();
+
+ /**
+ * "Equal" compare method
+ *
+ * @return @c true if the first parameter is equal to the second
+ * when comparing the family name and given name attributes.
+ *
+ * @see Addressee::familyName()
+ * @see Addressee::givenName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool eq( const Addressee &, const Addressee & );
+
+ /**
+ * "Less-Than" compare method
+ *
+ * Falls back to comparing given name if equal
+ *
+ * @return @c true if the first parameter is "less-than" the second
+ * when comparing the family name attribute.
+ *
+ * @see Addressee::familyName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool lt( const Addressee &, const Addressee & );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+class KABC_EXPORT GivenName // fallback to family name
+{
+ public:
+ /**
+ * Creates an instance.
+ */
+ GivenName();
+
+ /**
+ * Destroys the instance.
+ */
+ ~GivenName();
+
+ /**
+ * "Equal" compare method
+ *
+ * @return @c true if the first parameter is equal to the second
+ * when comparing the given name and family name attributes.
+ *
+ * @see Addressee::givenName()
+ * @see Addressee::familyName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool eq( const Addressee &, const Addressee & );
+
+ /**
+ * "Less-Than" compare method
+ *
+ * Falls back to comparing family name if equal
+ *
+ * @return @c true if the first parameter is "less-than" the second
+ * when comparing the given name attribute.
+ *
+ * @see Addressee::givenName()
+ * @see QString::localeAwareCompare()
+ */
+ static bool lt( const Addressee &, const Addressee & );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+}
+
+/**
+ * Addressee attribute used for sorting.
+ */
+typedef enum {
+ Uid,
+ Name,
+ FormattedName,
+ FamilyName,
+ GivenName
+} SortingCriterion;
+
+/**
+ * @short a QValueList of Addressee, with sorting functionality
+ *
+ * This class extends the functionality of QValueList with
+ * sorting methods specific to the Addressee class. It can be used
+ * just like any other QValueList but is no template class.
+ *
+ * An AddresseeList does not automatically keep sorted when addressees
+ * are added or removed or the sorting order is changed, as this would
+ * slow down larger operations by sorting after every step. So after
+ * such operations you have to call {@link #sort} or {@link #sortBy} to
+ * create a defined order again.
+ *
+ * Iterator usage is inherited from QList and extensively documented
+ * there. Please remember that the state of an iterator is undefined
+ * after any sorting operation.
+ *
+ * For the enumeration Type SortingCriterion, which specifies the
+ * field by the collection will be sorted, the following values exist:
+ * Uid, Name, FormattedName, FamilyName, GivenName.
+ *
+ * @author Jost Schenck jost@schenck.de
+ */
+class KABC_EXPORT AddresseeList : public QList<Addressee>
+{
+ public:
+ /**
+ * Creates a new addressee list.
+ */
+ AddresseeList();
+
+ /**
+ * Creates a new addressee list.
+ */
+ AddresseeList( const AddresseeList & );
+
+ /**
+ * Creates a new addressee list.
+ */
+ AddresseeList( const QList<Addressee> & );
+
+ /**
+ * Destroys the addressee list.
+ */
+ ~AddresseeList();
+
+ /**
+ * Assignment operator.
+ *
+ * @param other the list to assign from
+ * @return a reference to @c this
+ */
+ AddresseeList &operator=( const AddresseeList &other );
+
+ /**
+ * Determines the direction of sorting. On change, the list
+ * will <em>not</em> automatically be resorted.
+ * @param reverseSorting <tt>true</tt> if sorting should be done reverse,
+ * <tt>false</tt> otherwise
+ */
+ void setReverseSorting( bool reverseSorting = true );
+
+ /**
+ * Returns the direction of sorting.
+ * @return <tt>true</tt> if sorting is done reverse, <tt>false</tt> otherwise
+ */
+ bool reverseSorting() const;
+
+ /**
+ * Sorts this list by a specific criterion.
+ * @param c the criterion by which should be sorted
+ */
+ void sortBy( SortingCriterion c );
+
+ /**
+ * Sorts this list by a specific field. If no parameter is given, the
+ * last used Field object will be used.
+ * @param field pointer to the Field object to be sorted by
+ */
+ void sortByField( Field *field = 0 );
+
+ /**
+ * Sorts this list by a specific sorting mode.
+ * @param mode pointer to the sorting mode object to be sorted by
+ */
+ void sortByMode( SortMode *mode = 0 );
+
+ /**
+ * Sorts this list by its active sorting criterion. This normally is the
+ * criterion of the last sortBy operation or <tt>FormattedName</tt> if up
+ * to now there has been no sortBy operation.
+ *
+ * Please note that the sorting trait of the last {@link #sortByTrait}
+ * method call is not remembered and thus the action can not be repeated
+ * by this method.
+ */
+ void sort();
+
+ /**
+ * Templated sort function. You normally will not want to use this but
+ * {@link #sortBy} and {@link #sort} instead as the existing sorting
+ * criteria completely suffice for most cases.
+ *
+ * However, if you do want to use some special sorting criterion, you can
+ * write a trait class that will be provided to this templated method.
+ * This trait class has to have a class declaration like the following:
+ * \code
+ * class MySortingTrait {
+ * public:
+ * // eq returns true if a1 and a2 are equal
+ * static bool eq(KABC::Addressee a1, KABC::Addressee a2);
+ * // lt returns true is a1 is "less than" a2
+ * static bool lt(KABC::Addressee a1, KABC::Addressee a2);
+ * };
+ * \endcode
+ * You can then pass this class to the sortByTrait method like this:
+ * \code
+ * myAddresseelist.sortByTrait&lt;MySortingTrait&gt;();
+ * \endcode
+ * Please note that the {@link #sort} method can not be used to repeat the
+ * sorting of the last <tt>sortByTrait</tt> action.
+ *
+ * Right now this method uses the bubble sort algorithm. This should be
+ * replaced for a better one when I have time.
+ */
+ template<class Trait> void sortByTrait();
+
+ /**
+ * Returns the active sorting criterion, ie the sorting criterion that
+ * will be used by a {@link #sort} call.
+ */
+ SortingCriterion sortingCriterion() const;
+
+ /**
+ * Returns the active sorting field, ie a pointer to the Field object
+ * which was used for the last {@link #sortByField} operation.
+ * This function returns the last GLOBAL sorting field, not
+ * the class specific one.
+ * You're a lot better off by keeping track of this locally.
+ */
+ Field *sortingField() const;
+
+ /**
+ * Returns a string representation of the addressee list.
+ */
+ QString toString() const;
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+}
+
+#endif
diff --git a/kabc/contactgroup.cpp b/kabc/contactgroup.cpp
new file mode 100644
index 0000000..ad6b35f
--- /dev/null
+++ b/kabc/contactgroup.cpp
@@ -0,0 +1,496 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "contactgroup.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QSharedData>
+#include <QtCore/QString>
+#include <QtCore/QUuid>
+
+using namespace KABC;
+
+class ContactGroup::ContactReference::ContactReferencePrivate : public QSharedData
+{
+ public:
+ ContactReferencePrivate()
+ : QSharedData()
+ {
+ }
+
+ ContactReferencePrivate( const ContactReferencePrivate &other )
+ : QSharedData( other )
+ {
+ mUid = other.mUid;
+ mPreferredEmail = other.mPreferredEmail;
+ mCustoms = other.mCustoms;
+ }
+
+ QString mUid;
+ QString mPreferredEmail;
+ QMap<QString, QString> mCustoms;
+};
+
+ContactGroup::ContactReference::ContactReference()
+ : d( new ContactReferencePrivate )
+{
+}
+
+ContactGroup::ContactReference::ContactReference( const ContactReference &other )
+ : d( other.d )
+{
+}
+
+ContactGroup::ContactReference::ContactReference( const QString &uid )
+ : d( new ContactReferencePrivate )
+{
+ d->mUid = uid;
+}
+
+ContactGroup::ContactReference::~ContactReference()
+{
+}
+
+void ContactGroup::ContactReference::setUid( const QString &uid )
+{
+ d->mUid = uid;
+}
+
+QString ContactGroup::ContactReference::uid() const
+{
+ return d->mUid;
+}
+
+void ContactGroup::ContactReference::setPreferredEmail( const QString &email )
+{
+ d->mPreferredEmail = email;
+}
+
+QString ContactGroup::ContactReference::preferredEmail() const
+{
+ return d->mPreferredEmail;
+}
+
+void ContactGroup::ContactReference::insertCustom( const QString &key, const QString &value )
+{
+ d->mCustoms.insert( key, value );
+}
+
+void ContactGroup::ContactReference::removeCustom( const QString &key )
+{
+ d->mCustoms.remove( key );
+}
+
+QString ContactGroup::ContactReference::custom( const QString &key ) const
+{
+ return d->mCustoms.value( key );
+}
+
+ContactGroup::ContactReference &ContactGroup::ContactReference::operator=(
+ const ContactGroup::ContactReference &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool ContactGroup::ContactReference::operator==( const ContactReference &other ) const
+{
+ return d->mUid == other.d->mUid &&
+ d->mPreferredEmail == other.d->mPreferredEmail &&
+ d->mCustoms == other.d->mCustoms;
+}
+
+class ContactGroup::ContactGroupReference::ContactGroupReferencePrivate : public QSharedData
+{
+ public:
+ ContactGroupReferencePrivate()
+ : QSharedData()
+ {
+ }
+
+ ContactGroupReferencePrivate( const ContactGroupReferencePrivate &other )
+ : QSharedData( other )
+ {
+ mUid = other.mUid;
+ mCustoms = other.mCustoms;
+ }
+
+ QString mUid;
+ QMap<QString, QString> mCustoms;
+};
+
+ContactGroup::ContactGroupReference::ContactGroupReference()
+ : d( new ContactGroupReferencePrivate )
+{
+}
+
+ContactGroup::ContactGroupReference::ContactGroupReference( const ContactGroupReference &other )
+ : d( other.d )
+{
+}
+
+ContactGroup::ContactGroupReference::ContactGroupReference( const QString &uid )
+ : d( new ContactGroupReferencePrivate )
+{
+ d->mUid = uid;
+}
+
+ContactGroup::ContactGroupReference::~ContactGroupReference()
+{
+}
+
+void ContactGroup::ContactGroupReference::setUid( const QString &uid )
+{
+ d->mUid = uid;
+}
+
+QString ContactGroup::ContactGroupReference::uid() const
+{
+ return d->mUid;
+}
+
+void ContactGroup::ContactGroupReference::insertCustom( const QString &key, const QString &value )
+{
+ d->mCustoms.insert( key, value );
+}
+
+void ContactGroup::ContactGroupReference::removeCustom( const QString &key )
+{
+ d->mCustoms.remove( key );
+}
+
+QString ContactGroup::ContactGroupReference::custom( const QString &key ) const
+{
+ return d->mCustoms.value( key );
+}
+
+ContactGroup::ContactGroupReference &ContactGroup::ContactGroupReference::operator=(
+ const ContactGroup::ContactGroupReference &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool ContactGroup::ContactGroupReference::operator==( const ContactGroupReference &other ) const
+{
+ return d->mUid == other.d->mUid &&
+ d->mCustoms == other.d->mCustoms;
+}
+
+class ContactGroup::Data::DataPrivate : public QSharedData
+{
+ public:
+ DataPrivate()
+ : QSharedData()
+ {
+ }
+
+ DataPrivate( const DataPrivate &other )
+ : QSharedData( other )
+ {
+ mName = other.mName;
+ mEmail = other.mEmail;
+ mCustoms = other.mCustoms;
+ }
+
+ QString mName;
+ QString mEmail;
+ QMap<QString, QString> mCustoms;
+};
+
+ContactGroup::Data::Data()
+ : d( new DataPrivate )
+{
+}
+
+ContactGroup::Data::Data( const Data &other )
+ : d( other.d )
+{
+}
+
+ContactGroup::Data::Data( const QString &name, const QString &email )
+ : d( new DataPrivate )
+{
+ d->mName = name;
+ d->mEmail = email;
+}
+
+ContactGroup::Data::~Data()
+{
+}
+
+void ContactGroup::Data::setName( const QString &name )
+{
+ d->mName = name;
+}
+
+QString ContactGroup::Data::name() const
+{
+ return d->mName;
+}
+
+void ContactGroup::Data::setEmail( const QString &email )
+{
+ d->mEmail = email;
+}
+
+QString ContactGroup::Data::email() const
+{
+ return d->mEmail;
+}
+
+void ContactGroup::Data::insertCustom( const QString &key, const QString &value )
+{
+ d->mCustoms.insert( key, value );
+}
+
+void ContactGroup::Data::removeCustom( const QString &key )
+{
+ d->mCustoms.remove( key );
+}
+
+QString ContactGroup::Data::custom( const QString &key ) const
+{
+ return d->mCustoms.value( key );
+}
+
+ContactGroup::Data &ContactGroup::Data::operator=( const ContactGroup::Data &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool ContactGroup::Data::operator==( const Data &other ) const
+{
+ return d->mName == other.d->mName &&
+ d->mEmail == other.d->mEmail &&
+ d->mCustoms == other.d->mCustoms;
+}
+
+class ContactGroup::Private : public QSharedData
+{
+ public:
+ Private()
+ : QSharedData(),
+ mIdentifier( QUuid::createUuid().toString() )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mIdentifier = other.mIdentifier;
+ mName = other.mName;
+ mContactReferences = other.mContactReferences;
+ mContactGroupReferences = other.mContactGroupReferences;
+ mDataObjects = other.mDataObjects;
+ }
+
+ QString mIdentifier;
+ QString mName;
+ ContactGroup::ContactReference::List mContactReferences;
+ ContactGroup::ContactGroupReference::List mContactGroupReferences;
+ ContactGroup::Data::List mDataObjects;
+};
+
+ContactGroup::ContactGroup()
+ : d( new Private )
+{
+}
+
+ContactGroup::ContactGroup( const ContactGroup &other )
+ : d( other.d )
+{
+}
+
+ContactGroup::ContactGroup( const QString &name )
+ : d( new Private )
+{
+ d->mName = name;
+}
+
+ContactGroup::~ContactGroup()
+{
+}
+
+void ContactGroup::setName( const QString &name )
+{
+ d->mName = name;
+}
+
+QString ContactGroup::name() const
+{
+ return d->mName;
+}
+
+void ContactGroup::setId( const QString &id )
+{
+ d->mIdentifier = id;
+}
+
+QString ContactGroup::id() const
+{
+ return d->mIdentifier;
+}
+
+unsigned int ContactGroup::count() const
+{
+ return d->mContactReferences.count() + d->mDataObjects.count();
+}
+
+unsigned int ContactGroup::contactReferenceCount() const
+{
+ return d->mContactReferences.count();
+}
+
+unsigned int ContactGroup::contactGroupReferenceCount() const
+{
+ return d->mContactGroupReferences.count();
+}
+
+unsigned int ContactGroup::dataCount() const
+{
+ return d->mDataObjects.count();
+}
+
+ContactGroup::ContactReference &ContactGroup::contactReference( unsigned int index )
+{
+ Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(),
+ "contactReference()", "index out of range" );
+
+ return d->mContactReferences[ index ];
+}
+
+const ContactGroup::ContactReference &ContactGroup::contactReference( unsigned int index ) const
+{
+ Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(),
+ "contactReference()", "index out of range" );
+
+ return d->mContactReferences[ index ];
+}
+
+ContactGroup::ContactGroupReference &ContactGroup::contactGroupReference( unsigned int index )
+{
+ Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(),
+ "contactGroupReference()", "index out of range" );
+
+ return d->mContactGroupReferences[ index ];
+}
+
+const ContactGroup::ContactGroupReference &ContactGroup::contactGroupReference(
+ unsigned int index ) const
+{
+ Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(),
+ "contactGroupReference()", "index out of range" );
+
+ return d->mContactGroupReferences[ index ];
+}
+
+ContactGroup::Data &ContactGroup::data( unsigned int index )
+{
+ Q_ASSERT_X( index < (unsigned int)d->mDataObjects.count(), "data()", "index out of range" );
+
+ return d->mDataObjects[ index ];
+}
+
+const ContactGroup::Data &ContactGroup::data( unsigned int index ) const
+{
+ Q_ASSERT_X( index < (unsigned int)d->mDataObjects.count(), "data()", "index out of range" );
+
+ return d->mDataObjects[ index ];
+}
+
+void ContactGroup::append( const ContactReference &reference )
+{
+ d->mContactReferences.append( reference );
+}
+
+void ContactGroup::append( const ContactGroupReference &reference )
+{
+ d->mContactGroupReferences.append( reference );
+}
+
+void ContactGroup::append( const Data &data )
+{
+ d->mDataObjects.append( data );
+}
+
+void ContactGroup::remove( const ContactReference &reference )
+{
+ d->mContactReferences.removeOne( reference );
+}
+
+void ContactGroup::remove( const ContactGroupReference &reference )
+{
+ d->mContactGroupReferences.removeOne( reference );
+}
+
+void ContactGroup::remove( const Data &data )
+{
+ d->mDataObjects.removeOne( data );
+}
+
+void ContactGroup::removeAllContactReferences()
+{
+ d->mContactReferences.clear();
+}
+
+void ContactGroup::removeAllContactGroupReferences()
+{
+ d->mContactGroupReferences.clear();
+}
+
+void ContactGroup::removeAllContactData()
+{
+ d->mDataObjects.clear();
+}
+
+ContactGroup &ContactGroup::operator=( const ContactGroup &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool ContactGroup::operator==( const ContactGroup &other ) const
+{
+ return d->mIdentifier == other.d->mIdentifier &&
+ d->mName == other.d->mName &&
+ d->mContactReferences == other.d->mContactReferences &&
+ d->mContactGroupReferences == other.d->mContactGroupReferences &&
+ d->mDataObjects == other.d->mDataObjects;
+}
+
+QString ContactGroup::mimeType()
+{
+ return QLatin1String( "application/x-vnd.kde.contactgroup" );
+}
diff --git a/kabc/contactgroup.h b/kabc/contactgroup.h
new file mode 100644
index 0000000..bfdb193
--- /dev/null
+++ b/kabc/contactgroup.h
@@ -0,0 +1,474 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_CONTACTGROUP_H
+#define KABC_CONTACTGROUP_H
+
+#include <QtCore/QList>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QMetaType>
+
+#include "kabc_export.h"
+
+class QString;
+
+namespace KABC {
+
+/**
+ * @short This class represents a group of contacts.
+ *
+ * It can contain two types of contacts, either a reference
+ * or data.
+ * The reference entry is just an unique identifier which
+ * identifies the real contact in the system.
+ * The data entry contains a name and an email address.
+ *
+ * @author Tobias Koenig <tokoe@kde.org>
+ * @since 4.3
+ */
+class KABC_EXPORT ContactGroup
+{
+ public:
+
+ /**
+ * This class represents a contact reference
+ */
+ class KABC_EXPORT ContactReference
+ {
+ public:
+ /**
+ * A list of contact references.
+ */
+ typedef QList<ContactReference> List;
+
+ /**
+ * Creates an empty contact reference.
+ */
+ ContactReference();
+
+ /**
+ * Creates a contact reference from an @p other reference.
+ */
+ ContactReference( const ContactReference &other );
+
+ /**
+ * Creates a contact reference for the given contact @p uid.
+ */
+ ContactReference( const QString &uid );
+
+ /**
+ * Destroys the contact reference.
+ */
+ ~ContactReference();
+
+ /**
+ * Sets the contact uid of the contact reference.
+ *
+ * @note That is the Akonadi Item ID of the contact that
+ * is referenced here.
+ */
+ void setUid( const QString &uid );
+
+ /**
+ * Returns the contact uid of the contact reference.
+ *
+ * @note That is the Akonadi Item ID of the contact that
+ * is referenced here.
+ */
+ QString uid() const;
+
+ /**
+ * Sets the preferred email address.
+ */
+ void setPreferredEmail( const QString &email );
+
+ /**
+ * Returns the preferred email address, or an empty string
+ * if no preferred email address is set.
+ */
+ QString preferredEmail() const;
+
+ /**
+ * Inserts a custom entry.
+ * If an entry with the same @p key already exists, it is
+ * overwritten.
+ *
+ * @param key The unique key.
+ * @param value The value.
+ */
+ void insertCustom( const QString &key, const QString &value );
+
+ /**
+ * Removes the custom entry with the given @p key.
+ */
+ void removeCustom( const QString &key );
+
+ /**
+ * Returns the value for the given @p key, or an empty string
+ * if the entry for that key does not exists.
+ */
+ QString custom( const QString &key ) const;
+
+ /**
+ * @internal
+ */
+ ContactReference &operator=( const ContactReference & );
+
+ /**
+ * @internal
+ */
+ bool operator==( const ContactReference & ) const;
+
+ private:
+ class ContactReferencePrivate;
+ QSharedDataPointer<ContactReferencePrivate> d;
+ };
+
+ /**
+ * This class represents a contact group reference
+ */
+ class KABC_EXPORT ContactGroupReference
+ {
+ public:
+ /**
+ * A list of contact group references.
+ */
+ typedef QList<ContactGroupReference> List;
+
+ /**
+ * Creates an empty contact group reference.
+ */
+ ContactGroupReference();
+
+ /**
+ * Creates a contact group reference from an @p other reference.
+ */
+ ContactGroupReference( const ContactGroupReference &other );
+
+ /**
+ * Creates a contact group reference for the given contact group @p uid.
+ */
+ ContactGroupReference( const QString &uid );
+
+ /**
+ * Destroys the contact group reference.
+ */
+ ~ContactGroupReference();
+
+ /**
+ * Sets the contact group uid of the contact group reference.
+ */
+ void setUid( const QString &uid );
+
+ /**
+ * Returns the contact group uid of the contact group reference.
+ */
+ QString uid() const;
+
+ /**
+ * Inserts a custom entry.
+ * If an entry with the same @p key already exists, it is
+ * overwritten.
+ *
+ * @param key The unique key.
+ * @param value The value.
+ */
+ void insertCustom( const QString &key, const QString &value );
+
+ /**
+ * Removes the custom entry with the given @p key.
+ */
+ void removeCustom( const QString &key );
+
+ /**
+ * Returns the value for the given @p key, or an empty string
+ * if the entry for that key does not exists.
+ */
+ QString custom( const QString &key ) const;
+
+ /**
+ * @internal
+ */
+ ContactGroupReference &operator=( const ContactGroupReference & );
+
+ /**
+ * @internal
+ */
+ bool operator==( const ContactGroupReference & ) const;
+
+ private:
+ class ContactGroupReferencePrivate;
+ QSharedDataPointer<ContactGroupReferencePrivate> d;
+ };
+
+ /**
+ * This class represents a contact data object
+ */
+ class KABC_EXPORT Data
+ {
+ public:
+ /**
+ * A list of contact data.
+ */
+ typedef QList<Data> List;
+
+ /**
+ * Creates an empty contact data object.
+ */
+ Data();
+
+ /**
+ * Creates a contact data object from an @p other data object.
+ */
+ Data( const Data &other );
+
+ /**
+ * Creates a contact data object with the given @p name and @p email address.
+ */
+ Data( const QString &name, const QString &email );
+
+ /**
+ * Destroys the contact data object.
+ */
+ ~Data();
+
+ /**
+ * Sets the @p name of the contact data object.
+ */
+ void setName( const QString &name );
+
+ /**
+ * Returns the name of the contact data object.
+ */
+ QString name() const;
+
+ /**
+ * Sets the @p email address of the contact data object.
+ */
+ void setEmail( const QString &email );
+
+ /**
+ * Returns the email address of the contact data object.
+ */
+ QString email() const;
+
+ /**
+ * Inserts a custom entry.
+ * If an entry with the same @p key already exists, it is
+ * overwritten.
+ *
+ * @param key The unique key.
+ * @param value The value.
+ */
+ void insertCustom( const QString &key, const QString &value );
+
+ /**
+ * Removes the custom entry with the given @p key.
+ */
+ void removeCustom( const QString &key );
+
+ /**
+ * Returns the value for the given @p key, or an empty string
+ * if the entry for that key does not exists.
+ */
+ QString custom( const QString &key ) const;
+
+ /**
+ * @internal
+ */
+ Data &operator=( const Data & );
+
+ /**
+ * @internal
+ */
+ bool operator==( const Data & ) const;
+
+ private:
+ class DataPrivate;
+ QSharedDataPointer<DataPrivate> d;
+ };
+
+ /**
+ * A list of contact groups.
+ */
+ typedef QList<ContactGroup> List;
+
+ /**
+ * Creates an empty contact group.
+ */
+ ContactGroup();
+
+ /**
+ * Creates a contact group from an @p other group.
+ */
+ ContactGroup( const ContactGroup &other );
+
+ /**
+ * Creates a contact group with the given name.
+ */
+ ContactGroup( const QString &name );
+
+ /**
+ * Destroys the contact group.
+ */
+ ~ContactGroup();
+
+ /**
+ * Sets the unique @p id of the contact group.
+ */
+ void setId( const QString &id );
+
+ /**
+ * Returns the unique id of the contact group.
+ */
+ QString id() const;
+
+ /**
+ * Sets the i18n'd @p name of the contact group.
+ */
+ void setName( const QString &name );
+
+ /**
+ * Returns the i18n'd name of the contact group.
+ */
+ QString name() const;
+
+ /**
+ * Returns the number of contacts in this group.
+ * That includes the contact references and contact data.
+ */
+ unsigned int count() const;
+
+ /**
+ * Returns the number of contact references in this group.
+ */
+ unsigned int contactReferenceCount() const;
+
+ /**
+ * Returns the number of group references in this group.
+ */
+ unsigned int contactGroupReferenceCount() const;
+
+ /**
+ * Returns the number of contact data objects in this group.
+ */
+ unsigned int dataCount() const;
+
+ /**
+ * Returns the contact reference at the given @p index.
+ */
+ ContactReference &contactReference( unsigned int index );
+
+ /**
+ * Returns the contact reference at the given @p index.
+ */
+ const ContactReference &contactReference( unsigned int index ) const;
+
+ /**
+ * Returns the contact group reference at the given @p index.
+ */
+ ContactGroupReference &contactGroupReference( unsigned int index );
+
+ /**
+ * Returns the contact group reference at the given @p index.
+ */
+ const ContactGroupReference &contactGroupReference( unsigned int index ) const;
+
+ /**
+ * Returns the contact data object at the given @p index.
+ */
+ Data &data( unsigned int index );
+
+ /**
+ * Returns the contact data object at the given @p index.
+ */
+ const Data &data( unsigned int index ) const;
+
+ /**
+ * Appends a new contact @p reference to the contact group.
+ */
+ void append( const ContactReference &reference );
+
+ /**
+ * Appends a new contact group @p reference to the contact group.
+ */
+ void append( const ContactGroupReference &reference );
+
+ /**
+ * Appends a new contact @p data object to the contact group.
+ */
+ void append( const Data &data );
+
+ /**
+ * Removes the given contact @p reference from the contact group.
+ */
+ void remove( const ContactReference &reference );
+
+ /**
+ * Removes the given contact group @p reference from the contact group.
+ */
+ void remove( const ContactGroupReference &reference );
+
+ /**
+ * Removes the given contact @p data object from the contact group.
+ */
+ void remove( const Data &data );
+
+ /**
+ * Removes all contact references from the contact group.
+ */
+ void removeAllContactReferences();
+
+ /**
+ * Removes all contact group references from the contact group.
+ */
+ void removeAllContactGroupReferences();
+
+ /**
+ * Removes all contact data from the contact group.
+ */
+ void removeAllContactData();
+
+ /**
+ * @internal
+ */
+ ContactGroup &operator=( const ContactGroup & );
+
+ /**
+ * @internal
+ */
+ bool operator==( const ContactGroup & ) const;
+
+ /**
+ * Returns the MIME type used for Contact Groups
+ */
+ static QString mimeType();
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+}
+
+#define KABC_CONTACTGROUP_METATYPE_DEFINED
+Q_DECLARE_METATYPE( KABC::ContactGroup )
+
+#endif
diff --git a/kabc/contactgroup.xsd b/kabc/contactgroup.xsd
new file mode 100644
index 0000000..ba486b6
--- /dev/null
+++ b/kabc/contactgroup.xsd
@@ -0,0 +1,76 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<!--
+ Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+-->
+
+ <!-- The root element of every ContactGroup document -->
+ <xsd:element name="contactGroup">
+ <xsd:complexType>
+ <!-- A list of contacts or contact references -->
+ <xsd:choice minOccurs="0" maxOccurs="unbound">
+ <xsd:element name="contactData" type="contactDataType"/>
+ <xsd:element name="contactReference" type="contactReferenceType"/>
+ </xsd:choice>
+
+ <!-- The unique identifier of this contact group -->
+ <xsd:attribute name="uid" type="xsd:string" use="required" />
+
+ <!-- The i18n'ed name of this contact group -->
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- The type for inline contacts. -->
+ <xsd:complexType name="contactDataType">
+ <xsd:sequence>
+ <!-- The i18n'ed name of this contact -->
+ <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+
+ <!-- The plain email address (without the name) of this contact -->
+ <xsd:element name="email" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+
+ <!-- A list of custom fields for this contact -->
+ <xsd:element name="custom" minOccurs="0" maxOccurs="unbound">
+ <xsd:complexType>
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ <xsd:attribute name="value" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="contactReferenceType">
+ <xsd:sequence>
+ <!-- The uid of the contact this entry references -->
+ <xsd:element name="uid" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+
+ <!-- The preferred email address which shall be used for the contact -->
+ <xsd:element name="preferredEmail" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+
+ <!-- A list of custom fields for this contact -->
+ <xsd:element name="custom" minOccurs="0" maxOccurs="unbound">
+ <xsd:complexType>
+ <xsd:attribute name="key" type="xsd:string" use="required" />
+ <xsd:attribute name="value" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/kabc/contactgrouptool.cpp b/kabc/contactgrouptool.cpp
new file mode 100644
index 0000000..e63dfd0
--- /dev/null
+++ b/kabc/contactgrouptool.cpp
@@ -0,0 +1,367 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "contactgrouptool.h"
+#include "contactgroup.h"
+
+#include <QtCore/QIODevice>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamWriter>
+
+using namespace KABC;
+
+class XmlContactGroupWriter : public QXmlStreamWriter
+{
+ public:
+ XmlContactGroupWriter();
+
+ void write( const ContactGroup &group, QIODevice *device );
+ void write( const QList<ContactGroup> &groupLis, QIODevice *device );
+
+ private:
+ void writeGroup( const ContactGroup &group );
+ void writeContactReference( const ContactGroup::ContactReference & );
+ void writeContactGroupReference( const ContactGroup::ContactGroupReference & );
+ void writeData( const ContactGroup::Data & );
+};
+
+XmlContactGroupWriter::XmlContactGroupWriter()
+{
+ setAutoFormatting( true );
+}
+
+void XmlContactGroupWriter::write( const ContactGroup &group, QIODevice *device )
+{
+ setDevice( device );
+
+ writeStartDocument();
+
+ writeGroup( group );
+
+ writeEndDocument();
+}
+
+void XmlContactGroupWriter::write( const QList<ContactGroup> &groupList, QIODevice *device )
+{
+ setDevice( device );
+
+ writeStartDocument();
+
+ writeStartElement( QLatin1String( "contactGroupList" ) );
+
+ foreach ( const ContactGroup & group, groupList ) {
+ writeGroup( group );
+ }
+
+ writeEndElement();
+
+ writeEndDocument();
+}
+
+void XmlContactGroupWriter::writeGroup( const ContactGroup &group )
+{
+ writeStartElement( QLatin1String( "contactGroup" ) );
+ writeAttribute( QLatin1String( "uid" ), group.id() );
+ writeAttribute( QLatin1String( "name" ), group.name() );
+
+ for ( uint i = 0; i < group.contactReferenceCount(); ++i ) {
+ writeContactReference( group.contactReference( i ) );
+ }
+
+ for ( uint i = 0; i < group.contactGroupReferenceCount(); ++i ) {
+ writeContactGroupReference( group.contactGroupReference( i ) );
+ }
+
+ for ( uint i = 0; i < group.dataCount(); ++i ) {
+ writeData( group.data( i ) );
+ }
+
+ writeEndElement();
+}
+
+void XmlContactGroupWriter::writeContactReference( const ContactGroup::ContactReference &reference )
+{
+ writeStartElement( QLatin1String( "contactReference" ) );
+ writeAttribute( QLatin1String( "uid" ), reference.uid() );
+ if ( !reference.preferredEmail().isEmpty() ) {
+ writeAttribute( QLatin1String( "preferredEmail" ), reference.preferredEmail() );
+ }
+
+ // TODO: customs
+
+ writeEndElement();
+}
+
+void XmlContactGroupWriter::writeContactGroupReference(
+ const ContactGroup::ContactGroupReference &reference )
+{
+ writeStartElement( QLatin1String( "contactGroupReference" ) );
+ writeAttribute( QLatin1String( "uid" ), reference.uid() );
+
+ // TODO: customs
+
+ writeEndElement();
+}
+
+void XmlContactGroupWriter::writeData( const ContactGroup::Data &data )
+{
+ writeStartElement( QLatin1String( "contactData" ) );
+ writeAttribute( QLatin1String( "name" ), data.name() );
+ writeAttribute( QLatin1String( "email" ), data.email() );
+
+ // TODO: customs
+
+ writeEndElement();
+}
+
+class XmlContactGroupReader : public QXmlStreamReader
+{
+ public:
+ XmlContactGroupReader();
+
+ bool read( QIODevice *device, ContactGroup &group );
+ bool read( QIODevice *device, QList<ContactGroup> &groupList );
+
+ private:
+ bool readGroup( ContactGroup &group );
+ bool readContactReference( ContactGroup::ContactReference &reference );
+ bool readContactGroupReference( ContactGroup::ContactGroupReference &reference );
+ bool readData( ContactGroup::Data &data );
+};
+
+XmlContactGroupReader::XmlContactGroupReader()
+{
+}
+
+bool XmlContactGroupReader::read( QIODevice *device, ContactGroup &group )
+{
+ setDevice( device );
+
+ while ( !atEnd() ) {
+ readNext();
+ if ( isStartElement() ) {
+ if ( name() == QLatin1String( "contactGroup" ) ) {
+ return readGroup( group );
+ } else {
+ raiseError( QLatin1String( "The document does not describe a ContactGroup" ) );
+ }
+ }
+ }
+
+ return error() == NoError;
+}
+
+bool XmlContactGroupReader::read( QIODevice *device, QList<ContactGroup> &groupList )
+{
+ setDevice( device );
+
+ int depth = 0;
+
+ while ( !atEnd() ) {
+ readNext();
+ if ( isStartElement() ) {
+ ++depth;
+ if ( depth == 1 ) {
+ if ( name() == QLatin1String( "contactGroupList" ) ) {
+ continue;
+ } else {
+ raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) );
+ }
+ } else if ( depth == 2 ) {
+ if ( name() == QLatin1String( "contactGroup" ) ) {
+ ContactGroup group;
+ if ( !readGroup( group ) ) {
+ return false;
+ }
+
+ groupList.append( group );
+ } else {
+ raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) );
+ }
+ }
+ }
+
+ if ( isEndElement() ) {
+ --depth;
+ }
+ }
+
+ return error() == NoError;
+}
+
+bool XmlContactGroupReader::readGroup( ContactGroup &group )
+{
+ const QXmlStreamAttributes elementAttributes = attributes();
+ const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
+ if ( uid.isEmpty() ) {
+ raiseError( QLatin1String( "ContactGroup is missing a uid" ) );
+ return false;
+ }
+
+ const QStringRef groupName = elementAttributes.value( QLatin1String( "name" ) );
+ if ( groupName.isEmpty() ) {
+ raiseError( QLatin1String( "ContactGroup is missing a name" ) );
+ return false;
+ }
+
+ group.setId( uid.toString() );
+ group.setName( groupName.toString() );
+
+ while ( !atEnd() ) {
+ readNext();
+ if ( isStartElement() ) {
+ if ( name() == QLatin1String( "contactData" ) ) {
+ ContactGroup::Data data;
+ if ( !readData( data ) ) {
+ return false;
+ }
+ group.append( data );
+ } else if ( name() == QLatin1String( "contactReference" ) ) {
+ ContactGroup::ContactReference reference;
+ if ( !readContactReference( reference ) ) {
+ return false;
+ }
+ group.append( reference );
+ } else if ( name() == QLatin1String( "contactGroupReference" ) ) {
+ ContactGroup::ContactGroupReference reference;
+ if ( !readContactGroupReference( reference ) ) {
+ return false;
+ }
+ group.append( reference );
+ } else {
+ raiseError( QLatin1String( "The document does not describe a ContactGroup" ) );
+ }
+ }
+
+ if ( isEndElement() ) {
+ if ( name() == QLatin1String( "contactGroup" ) ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool XmlContactGroupReader::readData( ContactGroup::Data &data )
+{
+ const QXmlStreamAttributes elementAttributes = attributes();
+ const QStringRef email = elementAttributes.value( QLatin1String( "email" ) );
+ if ( email.isEmpty() ) {
+ raiseError( QLatin1String( "ContactData is missing an email address" ) );
+ return false;
+ }
+
+ const QStringRef name = elementAttributes.value( QLatin1String( "name" ) );
+
+ data.setName( name.toString() );
+ data.setEmail( email.toString() );
+
+ return true;
+}
+
+bool XmlContactGroupReader::readContactReference( ContactGroup::ContactReference &reference )
+{
+ const QXmlStreamAttributes elementAttributes = attributes();
+ const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
+ if ( uid.isEmpty() ) {
+ raiseError( QLatin1String( "ContactReference is missing a uid" ) );
+ return false;
+ }
+ const QStringRef preferredEmail = elementAttributes.value( QLatin1String( "preferredEmail" ) );
+
+ reference.setUid( uid.toString() );
+ reference.setPreferredEmail( preferredEmail.toString() );
+
+ return true;
+}
+
+bool XmlContactGroupReader::readContactGroupReference(
+ ContactGroup::ContactGroupReference &reference )
+{
+ const QXmlStreamAttributes elementAttributes = attributes();
+ const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
+ if ( uid.isEmpty() ) {
+ raiseError( QLatin1String( "ContactGroupReference is missing a uid" ) );
+ return false;
+ }
+
+ reference.setUid( uid.toString() );
+
+ return true;
+}
+
+bool ContactGroupTool::convertFromXml( QIODevice *device, ContactGroup &group,
+ QString *errorMessage )
+{
+ Q_UNUSED( errorMessage );
+
+ XmlContactGroupReader reader;
+
+ bool ok = reader.read( device, group );
+
+ if ( !ok && errorMessage != 0 ) {
+ *errorMessage = reader.errorString();
+ }
+
+ return ok;
+}
+
+bool ContactGroupTool::convertToXml( const ContactGroup &group, QIODevice *device,
+ QString *errorMessage )
+{
+ Q_UNUSED( errorMessage );
+
+ XmlContactGroupWriter writer;
+ writer.write( group, device );
+
+ return true;
+}
+
+bool ContactGroupTool::convertFromXml( QIODevice *device, QList<ContactGroup> &groupList,
+ QString *errorMessage )
+{
+ Q_UNUSED( errorMessage );
+
+ XmlContactGroupReader reader;
+
+ bool ok = reader.read( device, groupList );
+
+ if ( !ok && errorMessage != 0 ) {
+ *errorMessage = reader.errorString();
+ }
+
+ return ok;
+}
+
+bool ContactGroupTool::convertToXml( const QList<ContactGroup> &groupList,
+ QIODevice *device, QString *errorMessage )
+{
+ Q_UNUSED( errorMessage );
+
+ XmlContactGroupWriter writer;
+ writer.write( groupList, device );
+
+ return true;
+}
diff --git a/kabc/contactgrouptool.h b/kabc/contactgrouptool.h
new file mode 100644
index 0000000..9768393
--- /dev/null
+++ b/kabc/contactgrouptool.h
@@ -0,0 +1,76 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_CONTACTGROUPTOOL_H
+#define KABC_CONTACTGROUPTOOL_H
+
+#include "kabc_export.h"
+
+class QIODevice;
+class QString;
+
+template <class T> class QList;
+
+namespace KABC {
+
+class ContactGroup;
+
+/**
+ * Static methods for converting ContactGroup to XML format and vice versa.
+ *
+ * @author Kevin Krammer <kevin.krammer@gmx.at>
+ * @since 4.3
+ */
+namespace ContactGroupTool {
+
+ /**
+ * Converts XML data coming from a @p device into a contact @p group.
+ * If an error occurs, @c false is returned and @p errorMessage is set.
+ */
+ KABC_EXPORT bool convertFromXml( QIODevice *device, ContactGroup &group,
+ QString *errorMessage = 0 );
+
+ /**
+ * Converts a contact @p group into XML data and writes them to a @p device.
+ * If an error occurs, @c false is returned and @p errorMessage is set.
+ */
+ KABC_EXPORT bool convertToXml( const ContactGroup &group, QIODevice *device,
+ QString *errorMessage = 0 );
+
+ /**
+ * Converts XML data coming from a @p device into a @p list of contact groups.
+ * If an error occurs, @c false is returned and @p errorMessage is set.
+ */
+ KABC_EXPORT bool convertFromXml( QIODevice *device,
+ QList<ContactGroup> &list,
+ QString *errorMessage = 0 );
+
+ /**
+ * Converts a @p list of contact groups into XML data and writes them to a @p device.
+ * If an error occurs, @c false is returned and @p errorMessage is set.
+ */
+ KABC_EXPORT bool convertToXml( const QList<ContactGroup> &list,
+ QIODevice *device, QString *errorMessage = 0 );
+}
+
+}
+
+#endif
diff --git a/kabc/countrytransl.map b/kabc/countrytransl.map
new file mode 100644
index 0000000..2810d36
--- /dev/null
+++ b/kabc/countrytransl.map
@@ -0,0 +1,5685 @@
+Andorra ad
+Андора ad
+Андора ad
+Andora ad
+ອີນເດີຍ ad
+Andora ad
+Андорра ad
+安道尔 ad
+United Arab Emirates ae
+Vereenigde Arabiese Emirate ae
+الإمارات العربية المتحدة ae
+Злучаныя Арабскія Эміраты ae
+Обединени Арабски Емирства ae
+Ujedinjeni arapski emirati ae
+Emirats Àrabs Units ae
+Spojené arabské emiráty ae
+Forenende Arabiske Emirater ae
+Vereinigte Arabische Emirate ae
+Ενωμένα Αραβικά Εμιράτα ae
+Emiratos árabes unidos ae
+Araabia Ühendemiraadid ae
+Arabiar Emirato Batuak ae
+امارات متحده عربی ae
+Yhdistyneet Arabiemiraatit ae
+Émirats Arabes Unis ae
+איחוד האמירויות הערביות ae
+Ujedinjeni arapski emirati ae
+Egyesült Arab Emirátusok ae
+Emirati arabi uniti ae
+アラブ首長国連邦 ae
+아랍 에미레이트 연합 ae
+ສະຫະລັດ ae
+Jungtiniai Arabų Emiratai ae
+Emirati Għarab Magħquda ae
+De forente arabiske emirater ae
+Verenigde Arabische Emiraten ae
+Dei sameinte arabiske emirata ae
+Di-Emirate tseo di Kopanego tsa Arab ae
+Zjednoczone Emiraty Arabskie ae
+Emiratos Árabes Unidos ae
+Emirados Árabes ae
+Emiratele Arabe Unite ae
+Объединенные Арабские Эмираты ae
+Spojené arabské emiráty ae
+Združeni arabski Emirati ae
+Förenade arabemiraten ae
+³ì¸¢Â «ÃÒ ¿¡Î¸û ae
+Birleşik Arap Emirlikleri ae
+Об'єднані Арабські Емірати ae
+Mashango o tangananaho a Emirates ae
+阿拉伯联合酋长国 ae
+阿拉伯聯合大公國 ae
+Izindawo zezinduna zase-United Arab ae
+Afghanistan af
+Афганістан af
+Афганистан af
+Afganistan af
+Afghanistán af
+Afganisztán af
+ລີທົ່ວເນີຍ af
+Afeganistão af
+Afganistan af
+Afganistan af
+Afganistan af
+Афганістан af
+阿富汗 af
+Antigua and Barbuda ag
+Antigue en Barbuda ag
+أنتيغوا و باربودا ag
+Antigua və Barbuda ag
+Антыгуа і Барбуда ag
+Антигуа и Барбадос ag
+Antigua ha Barbuda ag
+Antigua i Barbuda ag
+Antigua i Barbuda ag
+Antigua a Barbuda ag
+Antigua og Barbuda ag
+Antigua und Barbuda ag
+Antigua και Barbuda ag
+Antigvo kaj Barbudo ag
+Antigua y Barbuda ag
+Antigua ja Barbuda ag
+Antigua eta Barbuda ag
+آنتیگوا و باربودا ag
+Antigua ja Barbados ag
+Antigua og Barbuda ag
+Antigua et Barbuda ag
+Antiga e Barbuda ag
+אנטיגואה וברבודה ag
+Antigua i Barbuda ag
+Antigua és Barbuda ag
+Antigua dan Barbuda ag
+Antigúa og Barbúda ag
+Antigua e Barbuda ag
+アンティグアバーブーダ ag
+앤티가 바부다 ag
+Antikva ir Barbuda ag
+Antigva un Barbudas ag
+Antigwa u Barbuda ag
+Antigua og Barbuda ag
+Antigua en Barbuda ag
+Antigua og Barbuda ag
+Antigua le Barbuda ag
+Antigua e Barbuda ag
+Antigua i Barbuda ag
+Antigua e Barbuda ag
+Antigua e Barbuda ag
+Antigua şi Barbuda ag
+Антигуа и Барбадос ag
+Antigua a Barbuda ag
+Antigva in Barbuda ag
+Antigua i Barbuda ag
+I-Antigua kanye ne Barbuda ag
+Antigua och Barbuda ag
+¬ýÊÌÅ¡ & À¡÷Ò¼¡ ag
+Antigua ve Barbuda ag
+Трінідад та Тобаго ag
+Antigua và Barbuda ag
+Antigua eyet Barbuda ag
+Antigua ne Barbuda ag
+安地瓜岛和巴布达岛 ag
+安地瓜島和巴布達島 ag
+Antigua kanye ne-Barbuda ag
+Anguilla ai
+Ангуила ai
+ແພນວິນ ai
+Angvila ai
+Ангілья ai
+安圭拉 ai
+Albania al
+Альбанія al
+Албания al
+Albanija al
+Albanien al
+Albánia al
+ແອດແລນຕິກ al
+Albânia al
+Albánsko al
+Albanija al
+Albanien al
+Албанія al
+阿尔巴尼亚 al
+Armenia am
+Армэнія am
+Армения am
+Armenija am
+Armenien am
+Örményország am
+ອາເຈນຕິນາ am
+Armênia am
+Arménsko am
+Armenija am
+Armenien am
+Арменія am
+亚美尼亚 am
+Netherlands Antilles an
+Холандски Антили an
+Nizozemski Antili an
+Nederlandske antiller an
+Antillas holandesas an
+Antilla Holandarrak an
+Holland-Antillák an
+ເນເທີແລນ an
+Antilhas an
+Holandské Antily an
+Nizozemski Antili an
+Nederländska Antillerna an
+Голландські Антилли an
+荷属安的列斯群岛 an
+Angola ao
+Ангола ao
+Ангола ao
+ບັນແກເລີຍ ao
+Ангола ao
+安哥拉 ao
+Argentina ar
+Argentinië ar
+الأرجنتين ar
+Аргентына ar
+Аржентина ar
+Arc'hantina ar
+Argentinien ar
+Αργεντινή ar
+Argentino ar
+Argentiina ar
+آرژانتین ar
+Agentiina ar
+Argentine ar
+Arxentina ar
+ארגנטינה ar
+Argentína ar
+Argentína ar
+アルゼンチン ar
+아르헨티나 ar
+ອາເຈນຕິນາ ar
+Argentīna ar
+Arġentina ar
+Argentinië ar
+Argentyna ar
+Аргентина ar
+Argentína ar
+I-Argentina ar
+¬÷¦ºƒýÊÉ¡ ar
+อาร์เจนตินา ar
+Arjantin ar
+Аргентина ar
+Agenthina ar
+Årdjintene ar
+阿根廷 ar
+阿根廷 ar
+American Samoa as
+Амэрыканскае Самоа as
+Американска Самоа as
+Američka Samoa as
+Samoa (USA) as
+Samoa americana as
+Amerikako Samoa as
+Amerikai Szamoa as
+ອາເມລິກາເຫນືອ as
+Samoa Americana as
+Americká Samoa as
+Ameriška Samoa as
+Amerikanska Samoa as
+Американське Самоа as
+美属萨摩亚群岛 as
+Austria at
+Oostenryk at
+النمسا at
+Avstriya at
+Аўстрыя at
+Австрия at
+Aostria at
+Austrija at
+Àustria at
+Rakousko at
+Østrig at
+Österreich at
+Αυστρία at
+Aŭstrio at
+اتریش at
+Itävalta at
+Eysturríki at
+Autriche at
+אוסטריה at
+Austrija at
+Ausztria at
+Austurríki at
+オーストリア at
+오스트리아 at
+ອອດສະເຕເລີຍ at
+Austrija at
+Austrija at
+Awtrija at
+Østerrike at
+Oostenrijk at
+Austerrike at
+Áustria at
+Áustria at
+Австрия at
+Rakúsko at
+Avstrija at
+Austrija at
+I-Austria at
+Österrike at
+¬Íò¾¢Ã¢Â¡ at
+ออสเตรีย at
+Avusturya at
+Австрія at
+Ositiria at
+A'o at
+Ôtriche at
+奥地利 at
+奧地利 at
+Australia au
+Australië au
+أستراليا au
+Avustralya au
+Аўстралія au
+Австралия au
+Aostralia au
+Australija au
+Austràlia au
+Austrálie au
+Australien au
+Australien au
+Αυστραλία au
+Aŭstralio au
+Austraalia au
+استرالیا au
+Australie au
+אוסטרליה au
+Australija au
+Ausztrália au
+Ástralía au
+オーストラリア au
+오스트레일리아 au
+ອອດສະເຕເລີຍ au
+Australija au
+Austrālija au
+Awstralja au
+Australië au
+Austrália au
+Austrália au
+Австралия au
+Austrália au
+Avstralija au
+Australija au
+I-Australia au
+Australien au
+¬ŠÍò¾¢§ÃĢ¡ au
+ออสเตรเลีย au
+Avusturalya au
+Австралія au
+Ositiralia au
+U'c au
+Ôstraleye au
+澳大利亚 au
+澳大利亞 au
+Aruba aw
+Аруба aw
+ເກມໄັພ່ aw
+Аруба aw
+阿鲁巴岛 aw
+Azerbaijan az
+أذربيجان az
+Azərbaycan az
+Азэрбайджан az
+Азарбайджан az
+Azerbejdžan az
+Azerbaitjan az
+Ázerbajdžánský az
+Azerbajdjan az
+Aserbaidschan az
+Αζερμπαϊτζάν az
+Azerbajĝana az
+Azerbaiján az
+Aserbaidžaan az
+آذربایجان az
+Azerbaidzan az
+Aserbadsjan az
+אזרביג'ן az
+Azerbejdžan az
+Azerbajdzsán az
+Azerbaigian az
+アゼルバイジャン az
+아제르바이잔 az
+ອາເຊີໄບຈັນ az
+Azerbaidžanas az
+Azerbaidžāņu az
+Ażerbajġan az
+Aserbajdsjan az
+Azerbeidjan az
+Aserbajdsjan az
+Azerbejdżan az
+Azerbaijão az
+Turco az
+Azerbadjan az
+Азербайджан az
+Ázerbajdžánsky az
+Azerbajdžan az
+Azerbejdžan az
+I-Azerbaijan az
+«º÷¨Àº¡ý az
+อาร์เซอร์ไบจัน az
+Azerice az
+Азербайджан az
+Azerbaydjan az
+阿塞拜疆 az
+亞塞拜然 az
+Bosnia and Herzegovina ba
+Bosnië en Herzegovina ba
+البوسنا و الهرسك ba
+Босьнія і Герцагавіна ba
+Боснена и Херцеговина ba
+Bosna i Hercegovina ba
+Bòsnia i Hercegovina ba
+Bosna a Herzegovina ba
+Bosnien-Herzegovina ba
+Bosnien und Herzegowina ba
+Βοσνία και Ερζεγοβίνη ba
+Bosnio kaj Hercegovino ba
+Bosnia y Herzegovina ba
+Bosnia ja Hertsegovina ba
+Bosnia eta Herzegovina ba
+بوسنی و هرزگوین ba
+Bosnia ja Herzegovina ba
+Bosnia-Herzegovina ba
+Bosnie herzégovine ba
+בוסניה הרצגובינה ba
+Bosna i Hercegovina ba
+Bosznia-Hercegovina ba
+Bosnia e Erzegovina ba
+ボスニアヘルツェゴビナ ba
+보스니아어와 헤르체고비나 ba
+ບອສເນີຍ ແລະ ເຫີເຊີໂກວິນາ ba
+Bosnija ir Hercegovina ba
+Bosnija un Hercogovina ba
+Bożnia u Ħerżegovina ba
+Bosnia-Hercegovina ba
+Bosnië en Herzegovina ba
+Bosnia-Hercegovina ba
+Bosnia le Herzegovina ba
+Bośnia i Hercegowina ba
+Bósnia e Herzegovina ba
+Bósnia Herzegóvina ba
+Bosnia şi Herţegovina ba
+Босния и Герцеговина ba
+Bosna a Hercegovina ba
+Bosna in Hercegovina ba
+I-Bosnia kanye ne Herzegovina ba
+Bosnien och Herzegovina ba
+¦À¡Íɢ¡ ba
+บอสเนีย และ เฮอร์เซโกวินา ba
+Bosna Hersek ba
+Боснія та Герцеговина ba
+Mubosinia na Muhezegovina ba
+Bosneye ba
+Bosnia ne Herzegovina ba
+波斯尼亚和黑塞哥维那 ba
+波士尼亞與赫塞哥維納 ba
+Bosnia kanye ne-Herzegovina ba
+Barbados bb
+بربادوس bb
+Барбадос bb
+Барбадос bb
+Μπαρμπάντος bb
+Babadoso bb
+باربادوس bb
+Barbade bb
+ברבדוס bb
+バルバドス bb
+바르바도스 bb
+ບາລບາດອດສ bb
+Barbadosas bb
+Barbadosa bb
+Барбадос bb
+I-Barbados bb
+À¡÷§À¼¡Í bb
+บาร์บาดอส bb
+Барбадос bb
+Barbades bb
+巴巴多斯 bb
+巴貝多 bb
+Bangladesh bd
+بنغلاديش bd
+Banqladeş bd
+Банглядэш bd
+Бангладеш bd
+Bangladeš bd
+Bangladéš bd
+Bangladesch bd
+Μπαγκλαντές bd
+Bangladeŝo bd
+بنگلادش bd
+בנגלדש bd
+Bangladeš bd
+Banglades bd
+バングラデシュ bd
+방글라데시 bd
+ບັງຄະລາເທດ bd
+Bangladešas bd
+Bangladeša bd
+Bangladexx bd
+Bangladesz bd
+Banglade bd
+Бангладеш bd
+Bangladéš bd
+Bangladeš bd
+I-Bangladesh bd
+Àí¸Ç¡§¾Í bd
+บังคลาเทศ bd
+Bangladeş bd
+Бангладеш bd
+孟加拉 bd
+孟加拉 bd
+Belgium be
+België be
+بلجيكا be
+Belçika be
+Бэльгія be
+Белгия be
+Belgia be
+Belgija be
+Bèlgica be
+Belgie be
+Belgien be
+Belgien be
+Βέλγιο be
+Belgio be
+Bélgica be
+Belgia be
+Belgika be
+بلژیک be
+Belgia be
+Belgia be
+Belgique be
+Bélxica be
+בלגיה be
+Belgija be
+Belgia be
+Belgía be
+Belgio be
+ベルギー be
+벨기에 be
+ເບລຢ່ງມ be
+Belgija be
+Beļģija be
+Belġju be
+Belgia be
+België be
+Belgia be
+Bèlgica be
+Belgia be
+Bélgica be
+Bélgica be
+Belgia be
+Бельгия be
+Belgicko be
+Belgija be
+Belgija be
+I-Belgium be
+Belgien be
+¦Àøº¢Âõ be
+เบลเยียม be
+Belçika be
+Бельгія be
+Beljike be
+比利时 be
+比利時 be
+Burkina Faso bf
+Буркіна Фасо bf
+Буркина Фаско bf
+ຕຸລະກີ bf
+Буркіна Фасо bf
+布基纳法索 bf
+Bulgaria bg
+Bulgarye bg
+بلغاريا bg
+Bolgarıstan bg
+Баўгарыя bg
+България bg
+Bugarska bg
+Bulgària bg
+Bulharsko bg
+Bulgarien bg
+Bulgarien bg
+Βουλγαρία bg
+Bulgario bg
+Bulgaaria bg
+بلغارستان bg
+Bulgarie bg
+בולגריה bg
+Bugarska bg
+Bulgária bg
+Búlgaría bg
+ブルガリア bg
+불가리아 bg
+ບັນແກເລີຍ bg
+Bulgarija bg
+Bulgārija bg
+Bulgarija bg
+Bulgarije bg
+Bułgaria bg
+Bulgária bg
+Bulgária bg
+Болгария bg
+Bulharsko bg
+Bolgarija bg
+Bugarska bg
+I-Bulgaria bg
+Bulgarien bg
+Àø§¸Ã¢Â¡ bg
+บัลแกเรีย bg
+Bulgaristan bg
+Болгарія bg
+Baligaria bg
+Bulgåreye bg
+保加利亚 bg
+保加利亞 bg
+Bahrain bh
+البحرين bh
+Бахрэйн bh
+Бахрейн bh
+Bahrein bh
+Bahrajn bh
+Μπαχρέιν bh
+Bahrein bh
+Bahrein bh
+بحرین bh
+בחריין bh
+バーレーン bh
+바레인 bh
+ຖັກກ່ງວ bh
+Bahreinas bh
+Baħrain bh
+Baghrein bh
+Bahrajn bh
+Bahamas bh
+Bahrein bh
+Бахрейн bh
+Bahrajn bh
+Bahrajn bh
+I-Bahrain bh
+Bahrein bh
+À‹¨Ãý bh
+Bahreyn bh
+Бахрейн bh
+巴林 bh
+巴林 bh
+Burundi bi
+Бурундзі bi
+Бурунди bi
+ເຄອຣດ bi
+Бурунді bi
+布隆迪 bi
+Benin bj
+Бэнін bj
+Бенин bj
+ບອສເນີຍ bj
+Бенін bj
+贝宁 bj
+Bermuda bm
+Бэрмуды bm
+Бермуда bm
+ເຍລລະມັນ bm
+Bermudy bm
+Bermudi bm
+Бермуди bm
+百慕大 bm
+Brunei Darussalam bn
+Брунэй bn
+Бруней bn
+Brunei bn
+Brunei Szultánság bn
+ເບລາລັສເຊີຍ bn
+Brunei bn
+Brunei Darusalam bn
+Бруней Даруссалам bn
+Bolivia bo
+Bolivië bo
+بوليفيا bo
+Boliviya bo
+Балівія bo
+Боливия bo
+Bolivija bo
+Bolívia bo
+Bolívie bo
+Bolivien bo
+Βολιβία bo
+Bolivio bo
+Boliivia bo
+بولیوی bo
+Bolivie bo
+בוליביה bo
+Bolivija bo
+Bolívia bo
+Bólivía bo
+ボリビア bo
+볼리비아 bo
+ໂບລີເວີຍ bo
+Bolivija bo
+Bolīvija bo
+Bolivja bo
+Boliwia bo
+Bolívia bo
+Bolívia bo
+Боливия bo
+Bolívia bo
+Bolivija bo
+Bolivija bo
+I-Bolivia bo
+¦À¡Ä¢Å¢Â¡ bo
+โบลิเวีย bo
+Bolivya bo
+Болівія bo
+Boliveye bo
+波利维亚 bo
+玻利維亞 bo
+Brazil br
+Brazilië br
+البرازيل br
+Braziliya br
+Бразылія br
+Бразилия br
+Brasil br
+Brazílie br
+Brasilien br
+Brasilien br
+Βραζιλία br
+Brazilo br
+Brasil br
+Brasiilia br
+Brasil br
+برزیل br
+Brasilia br
+Brésil br
+Brasil br
+ברזיל br
+Brazília br
+Brasilía br
+Brasile br
+ブラジル br
+브라질 br
+ບາຊີລ br
+Brazilija br
+Brazīlija br
+Brażil br
+Brasil br
+Brazilië br
+Brasil br
+Brasil br
+Brazylia br
+Brasil br
+Brasil br
+Brazilia br
+Бразилия br
+Brazília br
+Brazilija br
+I-Brazil br
+Brasilien br
+À¢§Ãº¢ø br
+บราซิล br
+Brezilya br
+Бразилія br
+Burazili br
+Braezi br
+巴西 br
+巴西 br
+Bahamas bs
+Багамы bs
+Бахами bs
+Bahami bs
+Bahamák bs
+ປານາມາ bs
+Bahamy bs
+Bahami bs
+Багами bs
+巴哈马 bs
+Bhutan bt
+Бутан bt
+Бутан bt
+Butan bt
+Bhután bt
+Bhután bt
+ຖັກກ່ງວ bt
+Butan bt
+Бутан bt
+不丹 bt
+Botswana bw
+Батсвана bw
+Боцвана bw
+Bocvana bw
+ບອດສເນີຍ bw
+Botsvana bw
+Ботсвана bw
+博茨瓦纳 bw
+Belarus by
+روسيا البيضاء by
+Беларусь by
+Беларус by
+Bjelorusija by
+Bělorusko by
+Hviderusland by
+Weißrussland by
+Bjelorusio by
+Valgevene by
+بلاروس by
+Valkovenäjä by
+Hvítarusland by
+Bélarus by
+בלרוס by
+Bjelorusija by
+Fehéroroszország by
+Hvíta-Rússland by
+Bielorussia by
+ベラルーシ by
+벨라루스 by
+ເບລາລັສ by
+Baltarusija by
+Baltkrievu by
+Hviterussland by
+Wit-Rusland by
+Kviterussland by
+Białoruś by
+Bielorússia by
+Bielorusso by
+Беларусь by
+Bielorusko by
+Belorusija by
+I-Belarus by
+Vitryssland by
+¦ÀÄ¡åÍ by
+เบลารัส by
+Білорусія by
+Belaruss by
+白俄罗斯 by
+白俄羅斯 by
+Belize bz
+Бэлізе bz
+Белиз bz
+ເບລຍ່ງມ bz
+Беліз bz
+伯利兹 bz
+Default C
+Verstek C
+افتراضي C
+Əsas C
+Па ўмаўчаньні C
+По подразбиране C
+Dre ziouer C
+Omissió C
+Výchozí C
+Standard C
+Standard C
+Προκαθορισμένο C
+Apriora C
+Predeterminado C
+Vaikimisi C
+Aurremugatua C
+پیش‌فرض C
+Oletus C
+Forsettur C
+Par défaut C
+Por Omisión C
+ברירת מחדל C
+Uobičajeno C
+Alapértelmezett C
+Standar C
+Sjálfgefið C
+Predefinito C
+標準 C
+기본 C
+ຄ່າປະລິຍາຍ C
+Nutylima C
+Noklusētais C
+Normali C
+Standard C
+Standaard C
+Standard C
+Thuso ya Tshoganetso C
+Omission C
+Domyślnie C
+Por Omissão C
+Padrão C
+Implicit C
+По умолчанию C
+Štandardný C
+Privzeto C
+Predefinisano C
+Förval C
+¦¸¡¼¡¿¢¨Ä C
+ค่าปริยาย C
+Öntanımlı C
+Типовий C
+Mặc định C
+Prémetou C
+Okwendalo C
+默认 C
+預設 C
+Okwendalo C
+Canada ca
+Kanada ca
+كندا ca
+Kanada ca
+Канада ca
+Канада ca
+Kanada ca
+Kanada ca
+Canadà ca
+Kanada ca
+Kanada ca
+Καναδάς ca
+Kanado ca
+Canadá ca
+Kanada ca
+Kanada ca
+کانادا ca
+Kanada ca
+Kanada ca
+Canadá ca
+קנדה ca
+Kanada ca
+Kanada ca
+Kanada ca
+Kanada ca
+カナダ ca
+캐나다 ca
+ແຄນາດາ ca
+Kanada ca
+Kanāda ca
+Kanada ca
+Kanada ca
+Canadá ca
+Canadá ca
+Канада ca
+Kanada ca
+Kanada ca
+Kanada ca
+I-Canada ca
+Kanada ca
+¸É¼¡ ca
+แคนาดา ca
+Kanada ca
+Канада ca
+加拿大 ca
+加拿大 ca
+Cocos (Keeling) Islands cc
+Кокосови Острови cc
+Kokosovo (Keeling) ostrvo cc
+Islas Cocos (Keeling) cc
+Koko Irlak cc
+Kókusz-szigetek (Keeling) cc
+Ilhas Cocos cc
+Kokosove Ostrovy cc
+Kokosovi (Keelingovi) otoki cc
+Kokosöarna cc
+Кокосові острови cc
+Congo, the democratic republic of the cd
+Дэмакратычная Рэспубліка Конга cd
+Конго cd
+Kongo, demokratska republika cd
+Congo, den demokratiske republik cd
+Congo, república democrática del cd
+Kongo, errepublika demokratikoa cd
+Kongói Demokratikus Köztársaság cd
+República Democrática do Congo cd
+Demokratická Republika Kongo cd
+Kongo, demokratična republika cd
+Demokratiska republiken Kongo cd
+刚果民主共和国 cd
+Central African Republic cf
+ЦАР cf
+Centralnoafrička Republika cf
+Central-afrikanske Republik cf
+República Centroafricana cf
+Afrika Erdiko Errepublika cf
+Közép-Afrikai Köztársaság cf
+ໂດມິນິກັນ cf
+República da África Central cf
+Stredoafrická Republika cf
+Centralnoafriška republika cf
+Centralafrikanska Republiken cf
+Центральноафриканська республіка cf
+中非共和国 cf
+Congo cg
+Конга cg
+Конго cg
+Kongo cg
+Kongo cg
+Kongó cg
+ຄອນໂໍຊລ cg
+Kongo cg
+Kongo cg
+Kongo cg
+Конго cg
+刚果 cg
+Switzerland ch
+Switserland ch
+سويسرا ch
+İsveçrə ch
+Швэйцарыя ch
+Швейцария ch
+Suis ch
+Švicarska ch
+Suïssa ch
+Švýcarsko ch
+Schweiz ch
+Schweiz ch
+Ελβετία ch
+Svislando ch
+Suiza ch
+Šveits ch
+Suitza ch
+سوییس ch
+Sveitsi ch
+Suisse ch
+Suíza ch
+שוייץ ch
+Švicarska ch
+Svájc ch
+Swiss ch
+Sviss ch
+Svizzera ch
+スイス ch
+스위스 ch
+ສະວິສເຊີແລນ ch
+Šveicarija ch
+Šveice ch
+Svizzera ch
+Sveits ch
+Zwitserland ch
+Sveits ch
+Suissa ch
+Szwajcaria ch
+Suíça ch
+Suíça ch
+Elveţia ch
+Швейцария ch
+Švajčiarsko ch
+Švica ch
+Švajcarska ch
+I-Switzerland ch
+Schweiz ch
+ÍÅ¢ðº÷Ä¡óÐ ch
+สวิสเซอร์แลนด์ ch
+İsviçre ch
+Швейцарія ch
+Thuỵ Sĩ ch
+Swisse ch
+瑞士 ch
+瑞士 ch
+Cote d'ivoire ci
+Бераг Слановай Косьці ci
+Кот'Дивоар ci
+Obala Slonovače ci
+Elfenbenskysten ci
+Costa de Marfil ci
+Elefántcsontpart ci
+ປ່ອຍຫມາກກະລອກ ci
+Slonokoščena obala ci
+Elfenbenskusten ci
+Кот д'Івуар ci
+Cook islands ck
+Kukova ostrva ck
+Cook-øerne ck
+Islas Cook ck
+Cook Irlak ck
+Cook-szigetek ck
+ຄຸກກີ້ ck
+Ilhas Cook ck
+Cookove ostrovy ck
+Cookovi otoki ck
+Cooköarna ck
+Острови Кука ck
+库克群岛 ck
+Chile cl
+Chilië cl
+تشيلي cl
+Şili cl
+Чылі cl
+Чили cl
+Čile cl
+Xile cl
+Χιλή cl
+Ĉilio cl
+Tšiili cl
+Txile cl
+شیلی cl
+Chili cl
+צ'ילה cl
+Čile cl
+Chili cl
+Cile cl
+チリ cl
+칠레 cl
+ຊີລີ cl
+Čilė cl
+Čīle cl
+Ċile cl
+Chili cl
+Cile cl
+Чили cl
+Čile cl
+Čile cl
+Čile cl
+I-Chile cl
+º¢Ä¢ cl
+ชิลี cl
+Şili cl
+Чилі cl
+Chi lê cl
+Tchili cl
+智利 cl
+智利 cl
+Cameroon cm
+Камэрун cm
+Камерун cm
+Kamerun cm
+Cameroun cm
+Camerún cm
+Kamerun cm
+Kamerun cm
+ຕາລາງງານ - K cm
+Camarões cm
+Komerun cm
+Kamerun cm
+Kamerun cm
+Камерун cm
+喀麦隆 cm
+China cn
+Sjina cn
+الصين cn
+Çin cn
+Кітай cn
+Китай cn
+Sina cn
+Kina cn
+Xina cn
+Čína cn
+Kina cn
+Κίνα cn
+Ĉinujo cn
+Hiina cn
+Txina cn
+چین cn
+Kiina cn
+Kina cn
+Chine cn
+סין cn
+Kina cn
+Kína cn
+Cina cn
+Kína cn
+Cina cn
+中国 cn
+중국 cn
+ຈີນ cn
+Kinija cn
+Ķīna cn
+Ċina cn
+Kina cn
+Kina cn
+Xina cn
+Chiny cn
+Китай cn
+Čína cn
+Kitajska cn
+Kina cn
+I-China cn
+Kina cn
+º£É¡ cn
+จีน cn
+Çin cn
+Китай cn
+Trung Quốc cn
+Chine cn
+中国 cn
+中國 cn
+Colombia co
+Colombië co
+كولمبيا co
+Калюмбія co
+Колумбия co
+Kolumbija co
+Colòmbia co
+Kolumbie co
+Kolumbien co
+Κολομβία co
+Kolumbio co
+Kolumbia co
+Kolonbia co
+کلمبیا co
+Kolumbia co
+Colombie co
+קולומביה co
+Kolumbija co
+Kolumbia co
+コロンビア co
+콜롬비아 co
+ໂຄລຳເບີຍ co
+Kolumbija co
+Kolumbija co
+Kolumbja co
+Columbia co
+Kolumbia co
+Colômbia co
+Colômbia co
+Columbia co
+Колумбия co
+Kolumbia co
+Kolumbija co
+I-Colombia co
+¦¸¡ÄõÀ¢Â¡ co
+โคลัมเบีย co
+Kolombiya co
+Колумбія co
+Colombeye co
+Columbia co
+哥伦比亚 co
+哥倫比亞 co
+Costa Rica cr
+كوستاريكا cr
+Коста Рыка cr
+Коста Рика cr
+Kostarika cr
+Kostarika cr
+Κόστα Ρίκα cr
+کاستاریکا cr
+Kosta Rika cr
+קוסטה ריקה cr
+Costa rica cr
+コスタリカ cr
+코스타 리카 cr
+ໂຄເອເທີຍ cr
+Kosta Rika cr
+Kostaryka cr
+Коста-Рика cr
+Kostarika cr
+Kostarika cr
+I-Costa Rica cr
+§¸¡Š¼¡ ⸡ cr
+Kosta Rika cr
+Коста-Ріка cr
+哥斯达黎加 cr
+哥斯大黎加 cr
+Cuba cu
+Kuba cu
+كوبا cu
+Куба cu
+Куба cu
+Kuba cu
+Kuba cu
+Kuba cu
+Κούβα cu
+Kuuba cu
+Kuba cu
+کوبا cu
+Kuuba cu
+Kuba cu
+קובה cu
+Kuba cu
+キューバ cu
+쿠바 cu
+ເກມໄພ່ cu
+Kuba cu
+Kuba cu
+Kuba cu
+Куба cu
+Kuba cu
+Kuba cu
+I-Cuba cu
+Kuba cu
+¸¢ÔÀ¡ cu
+Küba cu
+Куба cu
+古巴 cu
+古巴 cu
+Cape Verde cv
+Капе Верде cv
+Zelenortska ostrva cv
+Kapverdiske øer cv
+Cabo Verde cv
+Cabo Verde cv
+Zöldfoki-szigetek cv
+ເກມໄພ່ cv
+Cabo Verde cv
+Kap Verde cv
+佛得角 cv
+Christmas Island cx
+Božično ostrvo cx
+Juleøen cx
+Islas Christmas cx
+Eguberri Irla cx
+Karácsony-szigetek cx
+ຄິດສະຕອລ cx
+Ilhas do Natal cx
+Vianočné Ostrovy cx
+Božični otok cx
+Julön cx
+Острів Різдва cx
+圣诞岛 cx
+Cyprus cy
+Кіпр cy
+Кипър cy
+Kipar cy
+Cypern cy
+Chipre cy
+Txipre cy
+Ciprus cy
+ບີບອັດ cy
+Chipre cy
+Ciper cy
+Cypern cy
+Кипр cy
+塞浦路斯 cy
+Czechia cz
+Czechië cz
+التشيك cz
+Çex Respublikası cz
+Чэхія cz
+Чехия cz
+Tchekia cz
+Češka cz
+Txèquia cz
+Česko cz
+Tjekkiet cz
+Tschechien cz
+Τσεχία cz
+Ĉeĥio cz
+República Checa cz
+Tšehhi cz
+Txekia cz
+چک cz
+Tsekki cz
+République tchèque cz
+Chequia cz
+צ'כיה cz
+Češka cz
+Csehország cz
+Tékkland cz
+Repubblica Ceca cz
+チェコ cz
+체코 cz
+Čekija cz
+Čehija cz
+Cżekia cz
+Tsjekkia cz
+Tsjechië cz
+Tsjekkia cz
+Chèquia cz
+Czechy cz
+República Checa cz
+República Tcheca cz
+Cehia cz
+Чехия cz
+Česko cz
+Češka cz
+Češka cz
+I-Czechia cz
+Tjeckien cz
+¦ºì¡ cz
+Çek Cumhuriyeti cz
+Чехія cz
+Séc cz
+Tchekeye cz
+捷克 cz
+捷克 cz
+Germany de
+Duitsland de
+ألمانيا de
+Almaniya de
+Нямеччына de
+Германия de
+Alamagn de
+Njemačka de
+Alemanya de
+Německo de
+Tyskland de
+Deutschland de
+Γερμανία de
+Germanio de
+Alemania de
+Saksamaa de
+Alemania de
+ آلمان de
+Saksa de
+Týskland de
+Allemagne de
+Alemaña de
+גרמניה de
+Njemačka de
+Németország de
+Jerman de
+Þýskaland de
+Germania de
+ドイツ de
+독일 de
+ເຍລລະມັນນີ de
+Vokietija de
+Vācija de
+Ġermanja de
+Tyskland de
+Duitsland de
+Tyskland de
+Alemanya de
+Niemcy de
+Alemanha de
+Alemanha de
+Germania de
+Германия de
+Nemecko de
+Nemčija de
+Nemačka de
+I-Germany de
+Tyskland de
+§º÷ÁÉ¢ de
+เยอรมันนี de
+Almanya de
+Німеччина de
+Đức de
+Almagne de
+德国 de
+德國 de
+IJalimani de
+Djibouti dj
+جيبوتي dj
+Джыбуці dj
+Джибути dj
+Đibuti dj
+Džibuti dj
+Dschibuti dj
+Τζιμπουτί dj
+جیبوتی dj
+ג'יבוטי dj
+Džibuti dj
+Dzsibuti dj
+ジブティ dj
+지부티 dj
+ພັດພາ dj
+Džibuti dj
+Dġibuti dj
+Dżibuti dj
+Djibuti dj
+Djibuti dj
+Джибути dj
+Džibuty dj
+Džibuti dj
+I-Djibouti dj
+Ê¢ƒ¢¦À¡Ê dj
+Cibuti dj
+Джібуті dj
+吉布提 dj
+吉布地 dj
+Denmark dk
+Denemarke dk
+الدنمارك dk
+Danimarka dk
+Данія dk
+Дания dk
+Danmark dk
+Danska dk
+Dinamarca dk
+Dánsko dk
+Danmark dk
+Dänemark dk
+Δανία dk
+Danlando dk
+Dinamarca dk
+Taani dk
+Danimarka dk
+دانمارک dk
+Tanska dk
+Danmark dk
+Danemark dk
+Dinamarca dk
+דנמרק dk
+Danska dk
+Dánia dk
+Danmörk dk
+Danimarca dk
+デンマーク dk
+덴마크 dk
+ເດນມາກ dk
+Danija dk
+Dānija dk
+Danimarka dk
+Danmark dk
+Denemarken dk
+Danmark dk
+Dinamarca dk
+Dania dk
+Dinamarca dk
+Dinamarca dk
+Danemarca dk
+Дания dk
+Dánsko dk
+Danska dk
+Danska dk
+I-Denmark dk
+Danmark dk
+¦¼ýÁ¡÷ì dk
+เดนมาร์ก dk
+Danimarka dk
+Данія dk
+Đan Mạch dk
+Daenmåtche dk
+丹麦 dk
+丹麥 dk
+Dominica dm
+Дамініка dm
+Доминика dm
+Dominika dm
+Dominika dm
+ໂລມາເນີຍ dm
+Dominicana dm
+Dominikánsko dm
+Dominikanska republika dm
+Домініка dm
+多米尼加 dm
+Dominican Republic do
+Dominikiese Republiek do
+جمهورية الدومينيكان do
+Dominik Respublikası do
+Дамініканская Рэспубліка do
+Доминиканска република do
+Republik Dominikan do
+Dominikanska Republika do
+República Dominicana do
+Dominikánská republika do
+Dominikanske Republik do
+Dominikanische Republik do
+Δομινικανή Δημοκρατία do
+Dominika Respubliko do
+República Dominicana do
+Dominikaani Vabariik do
+Dominikar Errepublika do
+جمهوری دامینیکن do
+Dominikaaninen tasavalta do
+République dominicaine do
+República Dominicana do
+הרפובליקה הדומיניקנית do
+Dominikanska Republika do
+Dominikai Köztársaság do
+Republik Dominika do
+Dóminíska Lýðveldið do
+Repubblica Dominicana do
+ドミニカ共和国 do
+도미니카 공화국 do
+ໂດມິນີກັນ do
+Dominikos Respublika do
+Dominikas Republika do
+Repubblika Dominikana do
+Den dominikanske republikk do
+Dominicaanse Republiek do
+Den dominikanske republikken do
+Republica Dominicana do
+Dominikana do
+República Dominicana do
+República Dominicana do
+Republica Dominicană do
+Доминиканская республика do
+Dominikánska republika do
+Dominikanska republika do
+Dominikanska republika do
+I-Dominican Republic do
+Dominikanska republiken do
+¦¼¡Á¢É¢ì¸ý ÌÊÂÃÍ do
+โดมินิกัน do
+Dominik Cumhuriyeti do
+Домініканська республіка do
+Muvhuso wa Dominican do
+Cộng hoà Dominican do
+Republike Dominikinne do
+IRepublic yeDominican do
+多米尼加共和国 do
+多明尼加共和國 do
+Algeria dz
+Algerië dz
+الجزائر dz
+Альжыр dz
+Алжир dz
+Alžir dz
+Algèria dz
+Alžírsko dz
+Algeriet dz
+Algerien dz
+Αλγερία dz
+Algerio dz
+Argelia dz
+Alžeeria dz
+ الجزیره dz
+Algérie dz
+אלג'יריה dz
+Alžir dz
+Algéria dz
+アルジェリア dz
+알제리 dz
+ບັນກາເລີຍ dz
+Alžyras dz
+Alġerija dz
+Algerie dz
+Algerije dz
+Algerie dz
+Algieria dz
+Argélia dz
+Argélia dz
+Алжир dz
+Alžírsko dz
+Alžirija dz
+I-Algeria dz
+Algeriet dz
+«øƒ¢Ã¢Â¡ dz
+Алжир dz
+Aldjereye dz
+阿尔及利亚 dz
+阿爾及利亞 dz
+Equador ec
+Ewenaar ec
+الإكوادور ec
+Ekvator ec
+Эквадор ec
+Еквадор ec
+Ecuador ec
+Ekvador ec
+Ekvádor ec
+Ecuador ec
+Ισημερινός ec
+Ekvadoro ec
+Ecuador ec
+Ekvador ec
+Ekuador ec
+اکوادور ec
+Équateur ec
+Ecuador ec
+אקוודור ec
+Ekvador ec
+Ecuador ec
+Ekvador ec
+Ecuador ec
+エクアドル ec
+에콰도르 ec
+ເອກໍດໍ ec
+Ekvadoras ec
+Ekvadora ec
+Ekwador ec
+Ecuador ec
+Ecuador ec
+Ekwador ec
+Ecuador ec
+Эквадор ec
+Ekvádor ec
+Ekvador ec
+Ekvador ec
+I-Equador ec
+®ì¦Å§¼¡÷ ec
+เอกวาดอร์ ec
+Ekvator ec
+Еквадор ec
+Ecwåteur ec
+厄瓜多尔 ec
+厄瓜多 ec
+Estonia ee
+Estlandies ee
+استونيا ee
+Estoniya ee
+Эстонія ee
+Естония ee
+Estonija ee
+Estònia ee
+Estonsko ee
+Estland ee
+Estland ee
+Εσθονία ee
+Estlando ee
+Eesti ee
+استونی ee
+Eesti ee
+Estonie ee
+אסטוניה ee
+Estonija ee
+Észtország ee
+Eistland ee
+エストニア ee
+에스토니아 ee
+ເອໂທເນີຍ ee
+Estija ee
+Igaunija ee
+Estonja ee
+Estland ee
+Estland ee
+Estland ee
+Estònia ee
+Estónia ee
+Estônia ee
+Эстония ee
+Estónsko ee
+Estonija ee
+Estonija ee
+I-Estonia ee
+Estland ee
+±Í§¼¡É¢Â¡ ee
+เอสโธเนีย ee
+Estonya ee
+Естонія ee
+Estoneye ee
+爱沙尼亚 ee
+愛沙尼亞 ee
+Egypt eg
+Egipte eg
+مصر eg
+Misir eg
+Эгіпэт eg
+Египет eg
+Egipat eg
+Egipte eg
+Egypten eg
+Ägypten eg
+Αίγυπτος eg
+Egiptujo eg
+Egipto eg
+Egiptus eg
+Egypto eg
+مصر eg
+Egypti eg
+Egyptaland eg
+Égypte eg
+מצרים eg
+Egipat eg
+Egyiptom eg
+Egyptaland eg
+Egitto eg
+エジプト eg
+이집트 eg
+ອີຢີບ eg
+Egiptas eg
+Ēģipte eg
+Eġittu eg
+Egypte eg
+Egepeta eg
+Egipt eg
+Egipto eg
+Egito eg
+Egipt eg
+Египет eg
+Egipt eg
+I-Egypt eg
+Egypten eg
+±¸¢ôÐ eg
+อียิปต์ eg
+Mısır eg
+Єгипет eg
+Edjipe eg
+埃及 eg
+埃及 eg
+Igibhithe eg
+Western Sahara eh
+Западна Сахара eh
+Zapadna Sahara eh
+Vestsahara eh
+Sahara occidental eh
+Mendebaldeko Sahara eh
+Nyugat-Szahara eh
+ພື້ນທີ່ທຳງານ eh
+Sahara eh
+Západna Sahara eh
+Zahodna Sahara eh
+Västsahara eh
+Західна Сахара eh
+西撒哈拉 eh
+Eritrea er
+Эрытрэя er
+Еритрея er
+Eritreja er
+ແກ້ໄຂແຟ້ມທຳງານ er
+Eritreja er
+Еритрея er
+厄立特里亚 er
+Spain es
+Spanje es
+أسبانيا es
+İspaniya es
+Гішпанія es
+Испания es
+Spagn es
+Španija es
+Espanya es
+Španělsko es
+Spanien es
+Spanien es
+Ισπανία es
+Hispanio es
+España es
+Hispaania es
+Espainia es
+اسپانیا es
+Espanja es
+Spania es
+Espagne es
+España es
+ספרד es
+Španjolska es
+Spanyolország es
+Spanyol es
+Spánn es
+Spagna es
+スペイン es
+스페인 es
+ສະເປັນ es
+Ispanija es
+Spānija es
+Spanja es
+Spania es
+Spanje es
+Spania es
+Espanha es
+Hiszpania es
+Espanha es
+Espanha es
+Spania es
+Испания es
+Španielsko es
+Španija es
+Španija es
+I-Spain es
+Spanien es
+ͦÀ¢ý es
+สเปน es
+İspanya es
+Іспанія es
+Tây Ban Nha es
+Sipagne es
+西班牙 es
+西班牙 es
+Ethiopia et
+Этыёпія et
+Етиопия et
+Etiopija et
+Ethiopien et
+Etiopía et
+Etiopia et
+Etiópia et
+ເອໂທເນີຍ et
+Etiópia et
+Etiópia et
+Etiopija et
+Etiopien et
+Ефіопія et
+埃塞俄比亚 et
+Finland fi
+فنلندا fi
+Finlandiya fi
+Фінляндыя fi
+Финландия fi
+Finska fi
+Finlàndia fi
+Finsko fi
+Finnland fi
+Φινλανδία fi
+Finlando fi
+Finlandia fi
+Soome fi
+Finlandia fi
+فنلاند fi
+Suomi fi
+Finnland fi
+Finlande fi
+Finlandia fi
+פינלנד fi
+Finska fi
+Finnország fi
+Finlandia fi
+Finnland fi
+Finlandia fi
+フィンランド fi
+핀란드 fi
+ຟີນແລນ fi
+Suomija fi
+Somija fi
+Finlandja fi
+Finlandia fi
+Finlandia fi
+Finlândia fi
+Finlândia fi
+Finlanda fi
+Финляндия fi
+Fínsko fi
+Finska fi
+Finska fi
+I-Finland fi
+À¢ýÄ¡óÐ fi
+ฟินแลนด์ fi
+Finlandiya fi
+Фінляндія fi
+Phần Lan fi
+Finlande fi
+芬兰 fi
+芬蘭 fi
+Fiji fj
+Фіджы fj
+Фиджи fj
+Fidži fj
+Fidzsi fj
+ມີດີ fj
+Ilhas Fiji fj
+Fidži fj
+Fidži fj
+Фіджі fj
+斐济 fj
+Falkland Islands (Malvinas) fk
+Фолклендски Острови fk
+Foklandska ostrva (Malvini) fk
+Falkland-øerne fk
+Islas Falkland (Malvinas) fk
+Falkland Irlak (Malvinak) fk
+Falkland-szigetek fk
+Ilhas Malvinas fk
+Falklandské Ostrovy (Malviny) fk
+Falklandski otoki (Malvini) fk
+Falklandsöarna fk
+福克兰岛 (马尔维纳斯) fk
+Micronesia, Federated states of fm
+Федэрацыя Мiкранэзіі fm
+Микронезия fm
+Mikronezija, Federalne države fm
+Mikronesien, de forenede stater af fm
+Micronesia, Estados federados de fm
+Mikronesia, Estatu Federatuak fm
+Mikronézia fm
+Estados Federados da Micronésia fm
+Spjoené štáty Mikronézie fm
+Mikronezija, Združene države fm
+Mikronesiska federationen fm
+密克罗尼西亚联邦 fm
+Faroe Islands fo
+Фареорски Острови fo
+Farska ostrva fo
+Færøerne fo
+islas Faroe fo
+Faroe Irlak fo
+Faroe-szigetek fo
+ໄອແລນ fo
+Ilhas Faroe fo
+Ostrovy Faroe fo
+Otoki Faroe fo
+Färöarna fo
+Фарерські острови fo
+France fr
+Frankryk fr
+فرنسا fr
+Fransa fr
+Францыя fr
+Франция fr
+Frañs fr
+Francuska fr
+França fr
+Francie fr
+Frankrig fr
+Frankreich fr
+Γαλλία fr
+Francio fr
+Francia fr
+Prantsusmaa fr
+Frantzia fr
+فرانسه fr
+Ranska fr
+Frakland fr
+Francia fr
+צרפת fr
+Francuska fr
+Franciaország fr
+Prancis fr
+Frakkland fr
+Francia fr
+フランス fr
+프랑스 fr
+ຝຣັ່ງ fr
+Prancūzija fr
+Francija fr
+Franza fr
+Frankrike fr
+Frankrijk fr
+Frankrike fr
+Fora fr
+França fr
+Francja fr
+França fr
+França fr
+Franţa fr
+Франция fr
+Francúzsko fr
+Francija fr
+Francuska fr
+I-France fr
+Frankrike fr
+À¢Ã¡ýÍ fr
+ฝรั่งเศส fr
+Fransa fr
+Франція fr
+Fura fr
+Pháp fr
+Fransi fr
+法国 fr
+法國 fr
+Gabon ga
+Габон ga
+Габон ga
+Gabón ga
+ແກລ່ງນ ga
+Gabão ga
+Габон ga
+加蓬 ga
+United Kingdom gb
+Vereenigde Koninkryk gb
+المملكة المتحدة gb
+Birləşmiş Krallıq gb
+Злучанае Каралеўства gb
+Великобритания gb
+Rouantelezh Unanet gb
+Velika Britanija gb
+Regne Unit gb
+Spojené království gb
+Storbritannien gb
+Großbritannien gb
+Ηνωμένο Βασίλειο gb
+Britio gb
+Reino Unido gb
+Ühendatud Kuningriigid gb
+Erreinu Batua gb
+بریتانیا gb
+Iso-Britannia gb
+Stórabretland gb
+Royaume Uni gb
+Reino Unido gb
+בריטניה gb
+Ujedinjeno Kraljevstvo gb
+Egyesült Királyság gb
+Inggris gb
+Stóra Bretland gb
+Regno Unito gb
+イギリス gb
+영국 gb
+ສະຫະລາດສະອານາຈັກ gb
+Jungtinė Karalystė gb
+Apvienotā Karaliste gb
+Renju Unit gb
+Storbritannia gb
+Verenigd Koninkrijk gb
+Storbritannia gb
+Regne Unit gb
+Wielka Brytania gb
+Reino Unido gb
+Reino Unido gb
+Anglia gb
+Великобритания gb
+Anglicko gb
+Združeno kraljestvo gb
+Velika Britanija gb
+I-United Kingdom gb
+Storbritannien gb
+³ì¸¢Â ­Ã¡îº¢Âõ gb
+สหราชอาณาจักร gb
+Birleşik Krallık gb
+Великобританія gb
+Anh gb
+United Kingdom gb
+联合王国 gb
+聯合王國 gb
+United Kingdom gb
+Grenada gd
+غرينادا gd
+Qrenada gd
+Грэнада gd
+Гренада gd
+Granada gd
+Γρενάδα gd
+Grenado gd
+Granada gd
+گرانادا gd
+Grenade gd
+Granada gd
+גרנדה gd
+Grænhöfðaeyjar gd
+Granada gd
+グラナダ gd
+그러네이다 gd
+ເກນາດາ gd
+Grenāda gd
+Granada gd
+Granada gd
+Granada gd
+Гренада gd
+I-Grenada gd
+¸¢¦Ãɼ¡ gd
+เกรนาดา gd
+Гренада gd
+格林纳达 gd
+格瑞那達 gd
+Georgia ge
+Грузія ge
+Грузия ge
+Gruzija ge
+Georgien ge
+Grúzia ge
+ເຊີເບີຍ ge
+Geórgia ge
+Gruzija ge
+Georgien ge
+Грузія ge
+格鲁吉亚 ge
+Ghana gh
+غانا gh
+Гана gh
+Гана gh
+Gana gh
+Γκάνα gh
+غنا gh
+גאנה gh
+ガーナ gh
+ຈີນ gh
+Gana gh
+Gana gh
+Gana gh
+Гана gh
+Gana gh
+I-Ghana gh
+¸¡É¡ gh
+Гана gh
+加纳 gh
+迦納 gh
+Gibraltar gi
+Гибралтар gi
+Gibraltár gi
+ມອລຕາ gi
+Гібралтар gi
+直布罗陀 gi
+Gambia gm
+Гамбія gm
+Гамбия gm
+Gambija gm
+ແກມມາ gm
+Gâmbia gm
+Gambija gm
+Гамбія gm
+冈比亚 gm
+Guinea gn
+Гвінэя gn
+Гвинея gn
+Gvineja gn
+ເຖາວັນ gn
+Guiné gn
+Gvineja gn
+Гвінея gn
+几内亚 gn
+Guadeloupe gp
+Гвадалупа gp
+Gvadalupe gp
+Guadalupe gp
+ເດີລຸກ gp
+Guadalupe gp
+Гваделупа gp
+瓜德罗普岛 gp
+Equatorial Guinea gq
+Экватарыяльная Гвінэя gq
+Екваториялна Гвинея gq
+Ekvatorijalna Gvineja gq
+Ækvatorial Guinea gq
+Guinea equatorial gq
+Ginea Ekuatoriala gq
+Egyenlítői Guinea gq
+ການສອນ gq
+Guiné Equatorial gq
+Rovníkova Guinea gq
+Ekvatorialna Gvineja gq
+Ekvatorialguinea gq
+Екваторіальна Гвінея gq
+赤道几内亚 gq
+Greece gr
+Griekeland gr
+اليونان gr
+Yunanıstan gr
+Грэцыя gr
+Гърция gr
+Gres gr
+Grčka gr
+Grècia gr
+Řecko gr
+Grækenland gr
+Griechenland gr
+Ελλάδα gr
+Grekujo gr
+Grecia gr
+Kreeka gr
+Grezia gr
+یونان gr
+Kreikka gr
+Grikkaland gr
+Grèce gr
+Grecia gr
+יוון gr
+Grčka gr
+Görögország gr
+Grikkland gr
+Grecia gr
+ギリシャ gr
+그리스 gr
+ກີຊ gr
+Graikija gr
+Grieķija gr
+Greċja gr
+Hellas gr
+Griekenland gr
+Hellas gr
+Grèça gr
+Grecja gr
+Grécia gr
+Grécia gr
+Grecia gr
+Греция gr
+Grécko gr
+Grčija gr
+Grčka gr
+I-Greece gr
+Grekland gr
+¸¢Ã£Í gr
+กรีซ gr
+Yunanistan gr
+Греція gr
+Hy Lạp gr
+Grece gr
+希腊 gr
+希臘 gr
+Guatemala gt
+Gautemala gt
+غواتيمالا gt
+Quatemala gt
+Гватэмала gt
+Гватемала gt
+Gvatemala gt
+Γουατεμάλα gt
+Gvatemalo gt
+Guatemaala gt
+گواتمالا gt
+גואטמלה gt
+Gvatemala gt
+カタロニア gt
+과테말라 gt
+ກັວເຕມາລາ gt
+Gvatemala gt
+Gvatemala gt
+Gwatemala gt
+Gwatemala gt
+Гватемала gt
+Gvatemala gt
+Gvatemala gt
+I-Guatemala gt
+ÌÅ¡ò¾Á¡Ä¡ gt
+กัวเตมาลา gt
+Гватемала gt
+Gwatemala gt
+瓜地马拉 gt
+瓜地馬拉 gt
+Guam gu
+Гуам gu
+ແກມມາ gu
+Гуам gu
+关岛 gu
+Guinea-Bissau gw
+Гвінэя-Бісаў gw
+Гвинея-Бисау gw
+Gvineja-Bisau gw
+Ginea-Bissau gw
+Bissau-Guinea gw
+ລັດເຊີຍ gw
+Guiné-Bissau gw
+Гвінея-Біссау gw
+几内亚比绍 gw
+Guyana gy
+Гвіяна gy
+Гуана gy
+Gvajana gy
+ຈີນ gy
+Guiana gy
+Gvajana gy
+Гаяна gy
+圭亚那 gy
+Hong Kong hk
+Ганконг hk
+Хонг Конг hk
+Hongkong hk
+ບໍ່ຮູ້ຈັກ hk
+Гонконг hk
+香港 hk
+Honduras hn
+هندوراس hn
+Гандурас hn
+Хондурас hn
+Hondures hn
+Ονδούρα hn
+Honduraso hn
+Honduuras hn
+هندوراس hn
+הונדורס hn
+ホンデュラス hn
+온두라스 hn
+ຫອນດູລັດ hn
+Hondūras hn
+Hondurasa hn
+Ħonduras hn
+Hondures hn
+Гондурас hn
+I-Honduras hn
+¬ñÎáŠÍ hn
+ฮอนดูรัส hn
+Гондурас hn
+洪都拉斯 hn
+宏都拉斯 hn
+Croatia hr
+Kroatië hr
+كرواتيا hr
+Xırvatıstan hr
+Харватыя hr
+Хърватска hr
+Kroatia hr
+Hrvatska hr
+Croàcia hr
+Chorvatsko hr
+Kroatien hr
+Kroatien hr
+Κροατία hr
+Kroatio hr
+Croacia hr
+Horvaatia hr
+Kroazia hr
+کرواسی hr
+Kroatia hr
+Kroatia hr
+Croatie hr
+Croacia hr
+קרואטיה hr
+Hrvatska hr
+Horvátország hr
+Kroasia hr
+Króatía hr
+Croazia hr
+クロアチア hr
+크로아티아 hr
+ໂຄເອເທີຍ hr
+Kroatija hr
+Horvātija hr
+Kroazja hr
+Kroatia hr
+Kroatië hr
+Kroatia hr
+Croacia hr
+Chorwacja hr
+Croácia hr
+Croácia hr
+Croaţia hr
+Хорватия hr
+Chorvátsko hr
+Hrvaška hr
+Hrvatska hr
+I-Croatia hr
+Kroatien hr
+̦á§Åº¢Â¡ hr
+โครเอเธีย hr
+Hırvatistan hr
+Хорватія hr
+Crowåceye hr
+克罗地亚 hr
+克羅埃西亞 hr
+Haiti ht
+Гаіці ht
+Хаити ht
+Haití ht
+ວາດຮູບ - K ht
+Гаїті ht
+海地岛 ht
+Hungary hu
+Hongarye hu
+هنغاريا hu
+Macarıstan hu
+Вугоршчына hu
+Унгария hu
+Hungaria hu
+Mađarska hu
+Hongria hu
+Maďarsko hu
+Ungarn hu
+Ungarn hu
+Ουγγαρία hu
+Hungario hu
+Hungría hu
+Ungari hu
+Hungaria hu
+مجارستان hu
+Unkari hu
+Ungarn hu
+Hongrie hu
+Hungría hu
+הונגריה hu
+Mađjarska hu
+Magyarország hu
+Hungaria hu
+Ungverjaland hu
+Ungheria hu
+ハンガリー hu
+헝가리 hu
+ຫັງກາລີ hu
+Vengrija hu
+Ungārija hu
+Ungerija hu
+Ungarn hu
+Hongarije hu
+Ungarn hu
+Hongria hu
+Węgry hu
+Hungria hu
+Hungria hu
+Ungaria hu
+Венгрия hu
+Maďarsko hu
+Madžarska hu
+Mađarska hu
+I-Hungary hu
+Ungern hu
+¬í§¸Ã¢ hu
+ฮังการี hu
+Macaristan hu
+Угорщина hu
+Hongreye hu
+匈牙利 hu
+匈牙利 hu
+Indonesia id
+Indonesië id
+إندونيسيا id
+İndoneziya id
+Інданэзія id
+Индонезия id
+Indonezija id
+Indonèsia id
+Indonésie id
+Indonesien id
+Indonesien id
+Ινδονησία id
+Indonezio id
+Indoneesia id
+اندونزی id
+Indonésie id
+אינדונזיה id
+Indonezija id
+Indonézia id
+Indónesía id
+インドネシア id
+인도네시아 id
+ອີຍໂດນີເຊີຍ id
+Indonezija id
+Indonēzija id
+Indoneżja id
+Indonesië id
+Indonezja id
+Indonésia id
+Indonésia id
+Indonezia id
+Индонезия id
+Indonézia id
+Indonezija id
+I-Indonesia id
+Indonesien id
+­ó§¾¡É£º¢Â¡ id
+อินโดนีเซีย id
+İndonezya id
+Індонезія id
+Indoneseye id
+印度尼西亚 id
+印尼 id
+Ireland ie
+Ierland ie
+أيرلندا ie
+İrlandiya ie
+Ірляндыя ie
+Ирландия ie
+Iwerzhon ie
+Irska ie
+Irlanda ie
+Irsko ie
+Irland ie
+Irland ie
+Ιρλανδία ie
+Islando ie
+Irlanda ie
+Island ie
+Irlanda ie
+ایرلند ie
+Irlanti ie
+Írland ie
+Irlande ie
+Irlanda ie
+אירלנד ie
+Irska ie
+Írország ie
+Irlandia ie
+Írland ie
+Irlanda ie
+アイスランド ie
+아일랜드 ie
+ໄອແລນ ie
+Airija ie
+Īrija ie
+Irlanda ie
+Irland ie
+Ierland ie
+Irland ie
+Irlanda ie
+Irlandia ie
+Irlanda ie
+Irlanda ie
+Irlanda ie
+Ирландия ie
+Írsko ie
+Irska ie
+Irska ie
+I-Ireland ie
+Irland ie
+«Â÷Ä¡óÐ ie
+ไอร์แลนด์ ie
+İrlanda ie
+Ірландія ie
+Irlande ie
+爱尔兰 ie
+愛爾蘭 ie
+Israel il
+اسرائيل il
+İzrail il
+Ізраіль il
+Израел il
+Izrael il
+Izrael il
+Ισραήλ il
+Israelo il
+Iisrael il
+اسراییل il
+Ísrael il
+Israël il
+ישראל il
+Izrael il
+Izrael il
+Ísrael il
+Israele il
+イスラエル il
+이스라엘 il
+ອິດສະລະເອລ il
+Izraelis il
+Izraēla il
+Iżrael il
+Izrael il
+Израиль il
+Izrael il
+Izrael il
+Izrael il
+I-Israel il
+­Í§Ãø il
+อิสราเอล il
+İsrail il
+Ізраїль il
+Israyel il
+USirayeli il
+以色列 il
+以色列 il
+India in
+Indië in
+الهند in
+Hindistan in
+Індыя in
+Индия in
+Indija in
+Índia in
+Indie in
+Indien in
+Indien in
+Ινδία in
+Hindujo in
+هندوستان in
+Intia in
+Inde in
+הודו in
+Indija in
+Indland in
+インド in
+인도 in
+ອິນເດີຍ in
+Indija in
+Indija in
+Indja in
+Indie in
+Índia in
+Índia in
+Индия in
+Indija in
+I-India in
+Indien in
+­ó¾¢Â¡ in
+อินเดีย in
+Hindistan in
+Індія in
+Inde in
+印度 in
+印度 in
+Endiya in
+Iraq iq
+Irak iq
+العراق iq
+İraq iq
+Ірак iq
+Ирак iq
+Irak iq
+Irák iq
+Irak iq
+Irak iq
+Ιράκ iq
+Irako iq
+Irak iq
+Iraak iq
+عراق iq
+Irak iq
+Irak iq
+Irak iq
+עירק iq
+Irak iq
+Irak iq
+Írak iq
+Irak iq
+イラク iq
+이라크 iq
+ອີລັກ iq
+Irakas iq
+Irāka iq
+Irak iq
+Irak iq
+Irak iq
+Irak iq
+Iraque iq
+Iraque iq
+Irak iq
+Ирак iq
+Irák iq
+Irak iq
+I-Iraq iq
+Irak iq
+®Ã¡ì iq
+อิรัค iq
+Irak iq
+Ірак iq
+Irak iq
+伊拉克 iq
+伊拉克 iq
+Iran ir
+أيران ir
+Іран ir
+Иран ir
+Írán ir
+Ιράν ir
+Iraan ir
+ایران ir
+אירן ir
+Irán ir
+イラン ir
+이란 ir
+ອີລັກ ir
+Iranas ir
+Irão ir
+Irã ir
+Иран ir
+Irán ir
+I-Iran ir
+®Ã¡ý ir
+İran ir
+Іран ir
+伊朗 ir
+伊朗 ir
+Iceland is
+Ysland is
+أيسلندا is
+İslandiya is
+Ісьляндыя is
+Исландия is
+Island is
+Island is
+Islàndia is
+Island is
+Island is
+Island is
+Ισλανδία is
+Islando is
+Islandia is
+Island is
+Islandia is
+ایسلند is
+Islanti is
+Ísland is
+Islande is
+Islandia is
+איסלנד is
+Island is
+Izland is
+Islandia is
+Ísland is
+Islanda is
+アイスランド is
+아이슬란드 is
+ໄອຊແລນ is
+Islandija is
+Islande is
+Islandja is
+Island is
+IJsland is
+Island is
+Islandia is
+Islandia is
+Islândia is
+Islândia is
+Islanda is
+Исландия is
+Island is
+Islandija is
+Island is
+I-Iceland is
+Island is
+³ÍÄ¡óÐ is
+ไอซ์แลนด์ is
+İzlanda is
+Ісландія is
+Izlande is
+冰岛 is
+冰島 is
+Icelandi is
+Italy it
+Italië it
+ايطاليا it
+İtalyia it
+Італія it
+Италия it
+Italia it
+Italija it
+Itàlia it
+Itálie it
+Italien it
+Italien it
+Ιταλία it
+Italio it
+Italia it
+Itaalia it
+Italia it
+ایتالیا it
+Italia it
+Italia it
+Italie it
+Italia it
+איטליה it
+Italija it
+Olaszország it
+Italia it
+Ítalía it
+Italia it
+イタリア it
+이탈리아 it
+ອີຕາລີ it
+Italija it
+Itālija it
+Italja it
+Italia it
+Italië it
+Italia it
+Italia it
+Włochy it
+Itália it
+Itália it
+Italia it
+Италия it
+Taliansko it
+Italija it
+Italija it
+I-Italy it
+Italien it
+­ò¾¡Ä¢ it
+อิตาลี it
+İtalya it
+Італія it
+Itåleye it
+Ithali it
+意大利 it
+義大利 it
+Jamaica jm
+Jamaika jm
+جامايكا jm
+Yamayka jm
+Ямайка jm
+Ямайка jm
+Jamaika jm
+Jamajka jm
+Jamajka jm
+Jamaika jm
+Τζαμάικα jm
+Ĵamaiko jm
+Jamaika jm
+Jamaika jm
+جاماییکا jm
+Jamaika jm
+Jamaïque jm
+Xamaica jm
+ג'מייקה jm
+Jamajka jm
+Jamaika jm
+Jamaika jm
+Giamaica jm
+ジャマイカ jm
+자메이카 jm
+ຈາໄມກາ jm
+Jamaika jm
+Jamaika jm
+Ġamajka jm
+Jamajka jm
+Ямайка jm
+Jamajka jm
+Jamajka jm
+Jamajka jm
+I-Jamaica jm
+ƒº¦Áö측 jm
+จาไมกา jm
+Jamaika jm
+Ямайка jm
+Djamayike jm
+牙买加 jm
+牙買加 jm
+Jordan jo
+Jordaan jo
+الأردن jo
+İordaniya jo
+Ярданія jo
+Йордания jo
+Jordania jo
+Jordán jo
+Jordanien jo
+Ιορδανία jo
+Jordanio jo
+Jordania jo
+اردن jo
+Jordania jo
+Jordanie jo
+ירדן jo
+Jordánia jo
+Jórdanía jo
+Giordania jo
+ヨルダン jo
+요르단 jo
+ຈໍແດນ jo
+Jordanija jo
+Jordāna jo
+Ġordan jo
+Jordanië jo
+Jordania jo
+Jordânia jo
+Jordânia jo
+Iordania jo
+Иордания jo
+Jordánsko jo
+Jordanija jo
+I-Jordan jo
+Jordanien jo
+§Â¡÷¾¡ý jo
+จอร์แดน jo
+Ürdün jo
+Йорданія jo
+Djordaneye jo
+约旦 jo
+約旦 jo
+Ijolidani jo
+Japan jp
+اليابان jp
+Yaponiya jp
+Японія jp
+Япония jp
+Japó jp
+Japonsko jp
+Ιαπωνία jp
+Japanio jp
+Japón jp
+Jaapan jp
+Japonia jp
+ژاپن jp
+Japani jp
+Japon jp
+Xapón jp
+יפן jp
+Japán jp
+Jepang jp
+Giappone jp
+日本 jp
+일본 jp
+ຍີ່ປຸ່ນ jp
+Japonija jp
+Japāna jp
+Ġappun jp
+Japon jp
+Japonia jp
+Japão jp
+Japão jp
+Japonia jp
+Япония jp
+Japonsko jp
+Japonska jp
+I-Japan jp
+ºôÀ¡ý jp
+ญี่ปุ่น jp
+Japonya jp
+Японія jp
+Nhật bản jp
+Djapon jp
+日本 jp
+日本 jp
+Kenya ke
+Кенія ke
+Кения ke
+Kenija ke
+Kenia ke
+ເວນດາ ke
+Quênia ke
+Keňa ke
+Kenija ke
+Кенія ke
+肯尼亚 ke
+Kyrgyzstan kg
+Кыргызстан kg
+Киргистан kg
+Kirgistan kg
+Kirgizistan kg
+Kyrgyzstán kg
+Kirgizisztán kg
+ຄສິຕັລ kg
+Kirgizstan kg
+Kirgizistan kg
+Киргизстан kg
+吉尔吉斯坦 kg
+Cambodia kh
+Камбоджа kh
+Камбоджа kh
+Kambođa kh
+Kambodzsa kh
+ໂຄລຳເບີຍ kh
+Cambodja kh
+Kambodža kh
+Kambodža kh
+Kambodja kh
+Камбоджа kh
+柬埔寨 kh
+Kiribati ki
+Кiрыбацi ki
+Кирибати ki
+ແຟຄທັລ - K ki
+Кірібаті ki
+基里巴斯 ki
+Comoros km
+Каморы km
+Коморски km
+Komori km
+Comorerne km
+ສີ km
+Komori km
+Komorerna km
+Комори km
+科摩罗群岛 km
+St. Kitts and Nevis kn
+St. Kitts en Nevis kn
+سانت كيتس و نيفيس kn
+St. Kitts və Nevis kn
+Св. Кристоф и Невис kn
+S. Kitts ha Nevis kn
+St. Kitts i Nevis kn
+Sv. Kitts a Nevis kn
+St. Kitts-Nevis kn
+St. Kitts und Nevis kn
+St. Kitts και Nevis kn
+St. Kitts kaj Nevis kn
+St. Kitts y Nevis kn
+St. Kitts ja Nevis kn
+St. Kitts eta Nevis kn
+سن کیتس و نویس kn
+St. Kitts ja Nevis kn
+St Kitts et Nevis kn
+Saint Kitts e Nevis kn
+סנט קיטס ונביס kn
+St. Kitts és Nevis kn
+St. Kitts dan Nevis kn
+Ss. Kitts e Nevis kn
+セントキッツネヴィス kn
+세인트 키츠 네비스 kn
+Šv. Kitts ir Nevis kn
+St. Kitts un Nevis kn
+St. Kitts u Nevis kn
+St. Kitts og Nevis kn
+St. Kitts en Nevis kn
+St. Kitts og Nevis kn
+St. Kitts le Nevis kn
+St. Kitts e Nevis kn
+St. Kitts e Nevis kn
+St Kitts e Nevis kn
+Sf. Kitts şi Nevis kn
+о. Св. Кристофа и Невиса kn
+St. Kitts a Nevis kn
+St. Kitts in Nevis kn
+St. Kitts i Nevis kn
+I-St. Kitts and Nevis kn
+St. Kitts och Nevis kn
+¦ºÂ¢ý𠸢ðÍ & ¦¿Å¢Í kn
+St. Kitts ve Nevis kn
+Федерація Сент-Кітс і Невіс kn
+St. Kitts na Nevis kn
+St. Kitts neNevis kn
+圣基特和里维斯 kn
+聖克理斯多福及尼維斯 kn
+St. Kitts kanye no-Nevis kn
+North Korea kp
+Noord Korea kp
+كوريا الشمالية kp
+Şimali Koreya kp
+Паўночная Карэя kp
+Северна Корея kp
+Norzh-Korea kp
+Sjeverna Koreja kp
+Corea del Nord kp
+Severní Korea kp
+Nordkorea kp
+Nord-Korea kp
+Βόρεια Κορέα kp
+Nordkoreo kp
+Corea del Norte kp
+Põhja-Korea kp
+Ipar Korea kp
+کره شمالی kp
+Pohjois-Korea kp
+Norðurkorea kp
+Corée du nord kp
+Corea do Norte kp
+צפון קוריאה kp
+Sjeverna Koreja kp
+Észak-Korea kp
+Korea Utara kp
+Kórea - Norðurkórea kp
+Corea del Nord kp
+北朝鮮 kp
+조선민주주의 인민공화국 kp
+ເກົາລີເຫນືອ kp
+Šiaurės Korėja kp
+ZiemeļKoreja kp
+Korea ta' Fuq kp
+Nord-Korea kp
+Noord-Korea kp
+Nord-Korea kp
+Lebowa la Korea kp
+Corea dèu Nord kp
+Korea Północna kp
+Coreia do Norte kp
+Coréia do Norte kp
+Coreea de Nord kp
+Северная Корея kp
+severná Kórea kp
+Severna Koreja kp
+Severna Koreja kp
+I-North Korea kp
+Nordkorea kp
+ż ¦¸¡Ã¢Â¡ kp
+เกาหลีเหนือ kp
+Kuzey Kore kp
+Північна Корея kp
+Devhula ha Korea kp
+Bắc Triều Tiên kp
+Bijhe Coreye kp
+Umntla Korea kp
+朝鲜 kp
+北韓 kp
+Enyakatho ne-Korea kp
+South Korea kr
+Suid Korea kr
+كوريا الجنوبية kr
+Cənubi Koreya kr
+Паўднёвая Карэя kr
+Южна Корея kr
+Su-Korea kr
+Južna Koreja kr
+Corea del Sud kr
+Jižní Korea kr
+Sydkorea kr
+Süd-Korea kr
+Νότια Κορέα kr
+Sudkoreo kr
+Corea del Sur kr
+Lõuna-Korea kr
+Hego Korea kr
+کره جنوبی kr
+Etelä-Korea kr
+Suðurkorea kr
+Corée du sud kr
+Corea do Sur kr
+דרום קוריאה kr
+Južna Koreja kr
+Dél-Korea kr
+Korea Selatan kr
+Kórea - Suðurkórea kr
+Corea del Sud kr
+韓国 kr
+대한민국 kr
+ເກົາລີໃຕ້ kr
+Pietų Korėja kr
+DievidKoreja kr
+Korea t'Isfel kr
+Sør-Korea kr
+Zuid-Korea kr
+Sør-Korea kr
+Borwa bja Korea kr
+Corea dèu Sud kr
+Korea Południowa kr
+Coreia do Sul kr
+Coréia do Sul kr
+Coreea de Sud kr
+Южная Корея kr
+Južná Kórea kr
+Južna Koreja kr
+Južna Koreja kr
+I-South Korea kr
+Sydkorea kr
+¦¾ý ¦¸¡Ã¢Â¡ kr
+เกาหลีใต้ kr
+Güney Kore kr
+Південна Корея kr
+Korea tshipembe kr
+Hàn Quốc kr
+Nonne Coreye kr
+Umzantsi Korea kr
+韩国 kr
+南韓 kr
+Emzansi Korea kr
+Kuwait kw
+Kuwaït kw
+الكويت kw
+Кувэйт kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+Κουβέιτ kw
+Kuveit kw
+کویت kw
+Kuvait kw
+Kowait kw
+כווית kw
+Kuvajt kw
+Kuvait kw
+クェート kw
+쿠웨이트 kw
+ແຕ້ມຮູບ- K kw
+Kuveitas kw
+Koeweit kw
+Koweit kw
+Kuveit kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+I-Kuwait kw
+̨Åò kw
+KКувейт kw
+科威特 kw
+科威特 kw
+Cayman Islands ky
+Кайманови Острови ky
+Kajmanska ostrva ky
+Cayman-øerne ky
+Islas Caimán ky
+Kaiman Irlak ky
+Kajmán-szigetek ky
+ຄາຕາລັນ ky
+Ilhas Cayman ky
+Kajmanske Ostrovy ky
+Kajmanski otoki ky
+Caymanöarna ky
+Кайманські острови ky
+开曼群岛 ky
+Kazakhstan kz
+Казахстан kz
+Казахстан kz
+Kazahstan kz
+Kazakhstán kz
+Kazahsztán kz
+ແກແລກຕິກ - K kz
+Kazaquistão kz
+Kazachstan kz
+Kazahstan kz
+Kazakstan kz
+Казахстан kz
+哈萨克斯坦 kz
+Laos la
+Лаос la
+Лаос la
+Laosz la
+ລາວ la
+老挝 la
+Lebanon lb
+Libanon lb
+لبنان lb
+Ліван lb
+Ливан lb
+Liban lb
+Libanon lb
+Libanon lb
+Libanon lb
+Λίβανος lb
+Lebanono lb
+Líbano lb
+Liibanon lb
+لبنان lb
+Libanon lb
+Libanon lb
+Liban lb
+לבנון lb
+Libanon lb
+Libanon lb
+Libano lb
+レバノン lb
+레바논 lb
+ເດນ່ງນ lb
+Libanas lb
+Libanu lb
+Libanon lb
+Libanon lb
+Libanon lb
+Liban lb
+Líbano lb
+Líbano lb
+Liban lb
+Ливан lb
+Libanon lb
+Libanon lb
+I-Lebanon lb
+Libanon lb
+¦ÄÀÉ¡ý lb
+Ліван lb
+Liban lb
+黎巴嫩 lb
+黎巴嫩 lb
+St. Lucia lc
+سانت لوسيا lc
+Св. Люсиа lc
+S. Lucia lc
+Svatá Lucie lc
+Σάντα Λουτσία lc
+St. Lucio lc
+Santa Lucía lc
+سن لوسیا lc
+Sankta Lusia lc
+Sainte Lucie lc
+Santa Lucía lc
+סנטה לוסיה lc
+Santa Lucia lc
+セントルキア lc
+세인트 루시아 lc
+ເຊັນລູເຊີຍ lc
+Šv Liucija lc
+Sv. Lūcija lc
+St. Luċija lc
+Santa Lúcia lc
+Santa Lúcia lc
+Sf. Lucia lc
+о. Св. Люсии lc
+Sv. Júlia lc
+Sv. Lucija lc
+I-St. Lucia lc
+¦ºýð 溢¡ lc
+เซนต์ลูเซีย lc
+Санта Лучія lc
+圣路西亚 lc
+聖露西亞 lc
+Liechtenstein li
+Ліхтэнштэйн li
+Лихтенщайн li
+Lihtenštajn li
+Liechtestein li
+ຟ້າແມບ li
+列支敦士登 li
+Sri Lanka lk
+Шры-Ланка lk
+Шри Ланка lk
+Šri Lanka lk
+ເຊີເບີຍ lk
+Šri Lanka lk
+斯里兰卡 lk
+Liberia lr
+Лібэрыя lr
+Либеря lr
+Liberija lr
+Libéria lr
+ລິຊາ lr
+Libéria lr
+Lýbia lr
+Liberija lr
+利比里亚 lr
+Lesotho ls
+Лесота ls
+Лесото ls
+Lesoto ls
+Lesoto ls
+ທົດສອບ ls
+Lesoto ls
+莱索托 ls
+Lithuania lt
+Lithuanië lt
+ليتوانيا lt
+Litvaniya lt
+Літва lt
+Литва lt
+Litvanija lt
+Lituània lt
+Litva lt
+Litauen lt
+Litauen lt
+Λιθουανία lt
+Litovio lt
+Lituania lt
+Leedu lt
+Lituania lt
+لیتوانی lt
+Liettua lt
+Lituanie lt
+ליטא lt
+Litva lt
+Litvánia lt
+Litháenska lt
+Lituania lt
+リトアニア lt
+리 투아니아 lt
+ລິທົ່ວເນີຍ lt
+Lietuva lt
+Lietuva lt
+Litwanja lt
+Litauen lt
+Litouwen lt
+Litauen lt
+Litwa lt
+Lituânia lt
+Lituânia lt
+Lituania lt
+Литва lt
+Litva lt
+Litva lt
+Litvanija lt
+I-Lithuania lt
+Litauen lt
+Ä¢òЧÅɢ¡ lt
+ลิธัวเนีย lt
+Litvanya lt
+Литва lt
+立陶宛 lt
+立陶宛 lt
+Luxembourg lu
+Luxenburg lu
+لوكسمبورغ lu
+Lüksemburq lu
+Люксэмбург lu
+Люксембург lu
+Luksemburg lu
+Luxemburg lu
+Lucembursko lu
+Luxemburg lu
+Λουξεμβούργο lu
+Luksemburgo lu
+Luxemburgo lu
+Luksemburg lu
+Luxemburg lu
+لوگزامبورگ lu
+Luxemburg lu
+Luksemborg lu
+לוקסמבורג lu
+Luksemburg lu
+Luxemburg lu
+Lúxemborg lu
+Lussemburgo lu
+ルクセンブルグ lu
+룩셈부르크 lu
+ລັກແຊມເບີກ lu
+Liuksemburgas lu
+Luksemburga lu
+Lussemburgu lu
+Luxemburg lu
+Luksemburg lu
+Luxemburgo lu
+Luxemburgo lu
+Luxemburg lu
+Люксембург lu
+Luxemburg lu
+Luksemburg lu
+Luksemburg lu
+I-Luxembourg lu
+Luxemburg lu
+Äìºõ§À¡÷ì lu
+ลักเซมเบอร์ก lu
+Lüksemburg lu
+Люксембург lu
+Lucsimbork lu
+卢森堡 lu
+盧森堡 lu
+Latvia lv
+لاتفيا lv
+Latviya lv
+Латвія lv
+Латвия lv
+Latvija lv
+Lotyšsko lv
+Letland lv
+Lettland lv
+Λιθουανία lv
+Latvio lv
+Letonia lv
+Läti lv
+لاتویا lv
+Lettonie lv
+לטביה lv
+Latvija lv
+Lettország lv
+Léttland lv
+Lettonia lv
+ラトビア lv
+라트비아 lv
+ລັດເວີຍ lv
+Latvija lv
+Latvija lv
+Latvja lv
+Letland lv
+Łotwa lv
+Letónia lv
+Латвия lv
+Lotyšsko lv
+Latvija lv
+Latvija lv
+I-Latvia lv
+Lettland lv
+ÄðŢ¡ lv
+ลัธเวีย lv
+Litvanya lv
+Латвія lv
+Lativia lv
+拉脱维亚 lv
+拉脫維亞 lv
+Libya ly
+Libië ly
+ليبيا ly
+Лівія ly
+Либия ly
+Libija ly
+Líbia ly
+Lýbie ly
+Libyen ly
+Libyen ly
+Λιβύη ly
+Libia ly
+Liibüa ly
+Libia ly
+لیبی ly
+Lybie ly
+לוב ly
+Líbia ly
+Libia ly
+リビア ly
+ລິຊາ ly
+Libija ly
+Libië ly
+Libia ly
+Líbia ly
+Líbia ly
+Ливия ly
+Lýbia ly
+Libija ly
+I-Libya ly
+Libyen ly
+Ä¢À¢Â¡ ly
+Лівія ly
+利比亚 ly
+利比亞 ly
+Morocco ma
+Morokko ma
+المغرب ma
+Марока ma
+Мароко ma
+Maroko ma
+Marroc ma
+Maroko ma
+Marokko ma
+Marokko ma
+Μαρόκο ma
+Moroko ma
+Marruecos ma
+Maroko ma
+Maroko ma
+مراکش ma
+Marokko ma
+Marokko ma
+Maroc ma
+מרוקו ma
+Maroko ma
+Marokkó ma
+Marocco ma
+モロッコ ma
+모로코 ma
+ເມົາລິ ma
+Marokas ma
+Marokk ma
+Marokko ma
+Marokko ma
+Marokko ma
+Maroko ma
+Marrocos ma
+Marrocos ma
+Maroc ma
+Марокко ma
+Maroko ma
+Maroko ma
+I-Morocco ma
+Marocko ma
+§Á¡Ã¡§¸¡ ma
+Марокко ma
+Marok ma
+摩洛哥 ma
+摩洛哥 ma
+Monaco mc
+Манака mc
+Монако mc
+Monako mc
+Mónaco mc
+ເມົາລິ mc
+Mônaco mc
+Monako mc
+Monako mc
+摩纳哥 mc
+Moldova md
+Малдова md
+Молдова md
+Moldavia md
+Moldavia md
+ສະໂລວັກ md
+Moldávsko md
+Moldavien md
+摩尔多瓦 md
+Madagascar mg
+Мадагаскар mg
+Мадагаскар mg
+Madagaskar mg
+Madagaszkár mg
+ຄາສະບາລ - K mg
+Madagaskar mg
+Madagaskar mg
+Madagaskar mg
+马达加斯加 mg
+Marshall Islands mh
+Маршаллавы астравы mh
+Маршалови Острови mh
+Maršalova ostrva mh
+Marshall-øerne mh
+Islas Marshall mh
+Marshall Irlak mh
+Marshall-szigetek mh
+ລາດສະອານາຈັກໄທຍ mh
+Ilhas Marshall mh
+Maršálove ostrovy mh
+Marshallovi otoki mh
+Marshallöarna mh
+马绍尔群岛 mh
+Macedonia mk
+Makedoniese mk
+مقدونيا mk
+Makedonya mk
+Македонія mk
+Македония mk
+Makedonia mk
+Makedonija mk
+Macedònia mk
+Makedonie mk
+Makedonien mk
+Makedonien mk
+Μακεδονία mk
+Macedonio mk
+Makedoonia mk
+Mazedonia mk
+مقدونیه mk
+Makedonia mk
+Macédoine mk
+מקדוניה mk
+Makedonija mk
+Macedónia mk
+Masedonia mk
+Makedónía mk
+マケドニア語 mk
+마케도니아 mk
+ມາເຊໂດເນີຍ mk
+Makedonija mk
+Maķedonija mk
+Maċedonja mk
+Makedonia mk
+Macedonië mk
+Makedonia mk
+Macedònian mk
+Macedónia mk
+Macedônia mk
+Македония mk
+Macedónsky mk
+Makedonija mk
+Makedonija mk
+I-Macedonia mk
+Makedonien mk
+Á¡º¢§¼¡É¢Â¡ mk
+มาเซโดเนีย mk
+Makedonya mk
+Македонія mk
+Masedonia mk
+马其顿 mk
+馬其頓 mk
+Mali ml
+Малі ml
+Мали ml
+ຈົດຫມາຍ ml
+马里 ml
+Myanmar mm
+М'янма mm
+Майнмар mm
+Mjanmar mm
+Burma mm
+Birmania mm
+ຕົວຮງກພີື້ນທີ່ທຳງານ - K mm
+Mjanmar mm
+缅甸 mm
+Mongolia mn
+Манголія mn
+Монголия mn
+Mongolija mn
+Mongoliet mn
+Mongólia mn
+ລອກອິນ mn
+Mongólia mn
+Mongolsko mn
+Mongolija mn
+Mongoliet mn
+蒙古 mn
+Macau mo
+Макао mo
+Makau mo
+Macao mo
+Makaó mo
+ມອລຕາ mo
+Makao mo
+Macao mo
+澳门 mo
+Martinique mq
+Мартиника mq
+Martinik mq
+Martinica mq
+ເມົາລິ mq
+Martinik mq
+马提尼克岛 mq
+Mauritania mr
+Маўрытанія mr
+Мавритания mr
+Mauritanija mr
+Mauretanien mr
+Mauritánia mr
+ລິທົວເນີຍ mr
+Mauritânia mr
+Mavretanija mr
+Mauretanien mr
+毛里塔尼亚 mr
+Montserrat ms
+Монсерат ms
+Monsera ms
+ຈໍພາບ ms
+蒙特塞拉特岛 ms
+Malta mt
+مالطة mt
+Мальта mt
+Малта mt
+Μάλτα mt
+Malto mt
+مالت mt
+Malte mt
+מלטה mt
+Málta mt
+マルタ mt
+왈타 mt
+ມອລຕາ mt
+Мальта mt
+I-Malta mt
+Á¡ø¼¡ mt
+มอลตา mt
+Мальта mt
+Male mt
+马耳他 mt
+馬爾他 mt
+Mauritius mu
+Маўрыцы mu
+Маурици mu
+Mauricijus mu
+Mauricio mu
+ພາທິຊັ້ນ mu
+Maurícius mu
+Mavricij mu
+毛里求斯 mu
+Maldives mv
+Мальдывы mv
+Малдиви mv
+Maldivi mv
+Maldiverne mv
+Maldivas mv
+Maldív-szigetek mv
+ມັລດິສ mv
+Maldivas mv
+Maldiv mv
+Maldiverna mv
+马尔代夫 mv
+Malawi mw
+Малаві mw
+Малави mw
+Malavi mw
+ມອລຕາ mw
+马拉维 mw
+Mexico mx
+Meksiko mx
+المكسيك mx
+Meksika mx
+Мэксыка mx
+Мексико mx
+Mec'hiko mx
+Meksiko mx
+Mèxic mx
+Mexiko mx
+Mexiko mx
+Μεξικό mx
+Meksikujo mx
+México mx
+Mehhiko mx
+Mexiko mx
+مکزیک mx
+Meksiko mx
+Meksiko mx
+Mexique mx
+México mx
+מקסיקו mx
+Meksiko mx
+Mexikó mx
+Meksiko mx
+Mexíkó mx
+Messico mx
+メキシコ mx
+멕시코 mx
+ເມັກຊີໂກ mx
+Meksika mx
+Meksika mx
+Messiku mx
+Mèxic mx
+Meksyk mx
+México mx
+México mx
+Mexic mx
+Мексика mx
+Mexiko mx
+Mehika mx
+Meksiko mx
+I-Mexico mx
+¦Á캢§¸¡ mx
+เม็กซิโก mx
+Meksika mx
+Мексика mx
+Mê hi cô mx
+Mecsike mx
+墨西哥 mx
+墨西哥 mx
+Malaysia my
+Малайзыя my
+Малайзия my
+Malezija my
+Malasia my
+Malasia my
+Malajzia my
+ມອລຕາ my
+Malásia my
+Malajzia my
+Malezija my
+马来西亚 my
+Mozambique mz
+Мазамбік mz
+Мозамбик mz
+Mozambik mz
+Mozambik mz
+ຫນ່ວຍຄວາມຈຳ mz
+Moçambique mz
+Mozambik mz
+Mozambik mz
+Moçambique mz
+莫桑比克 mz
+Namibia na
+Намібія na
+Намибия na
+Namibija na
+Namíbia na
+ຈາໄມກາ na
+Namíbia na
+Namíbia na
+Namibija na
+纳米比亚 na
+New Caledonia nc
+Нова Каледония nc
+Nova Kaledonija nc
+Ny Caledonien nc
+Nueva Caledonia nc
+Kaledonia Berria nc
+Új-Kaledónia nc
+ມາເຊໂດເນີຍ nc
+Nova Caledônia nc
+Nová Kaledónia nc
+Nova Kaledonija nc
+Nya Caledonien nc
+新喀里多尼亚 nc
+Niger ne
+Нігер ne
+Нигер ne
+ຕົວຮງກພື້ນທີ່ທຳງານ ne
+Nigéria ne
+Nigéria ne
+尼日尔 ne
+Norfolk Island nf
+Остров Норфолк nf
+Norfolk ostrvo nf
+Norfolk-øerne (Australien) nf
+Isla Norfolk nf
+Norfok Irla nf
+Norfolk-szigetek nf
+ໂປແລນ nf
+Ilhas Norfolk nf
+Ostrov Norfolk nf
+Otok Norfolk nf
+Norfolkön nf
+诺福克岛 nf
+Nigeria ng
+Нігерыя ng
+Нигерия ng
+Nigerija ng
+Nigéria ng
+ບັນແກເລີຍ ng
+Nigéria ng
+Nigéria ng
+Nigerija ng
+尼日利亚 ng
+Nicaragua ni
+Nikaragua ni
+نيكاراغوا ni
+Нікарагуа ni
+Никарагуа ni
+Nikaragva ni
+Nikaragua ni
+Νικαράγουα ni
+Nikaraagua ni
+نیکاراگویه ni
+Nikaragua ni
+Nikaragua ni
+ניקרגווה ni
+ニカラグア ni
+니카라과 ni
+ປາລາກກວຍ ni
+Nikaragua ni
+Nikaragwa ni
+Nikaragua ni
+Nicarágua ni
+Nicarágua ni
+Никарагуа ni
+Nikaragua ni
+Nikaragva ni
+I-Nicaragua ni
+¿¢¸Ã¡Ì§Å ni
+Nikaragua ni
+Нікарагуа ni
+尼加拉瓜 ni
+尼加拉瓜 ni
+Netherlands nl
+Nederland nl
+هولندا nl
+Hollandiya nl
+Галяндыя nl
+Холандия nl
+Izelvroioù nl
+Nizozemska nl
+Holanda nl
+Nizozemí nl
+Holland nl
+Niederlande nl
+Κάτω Χώρες nl
+Nederlando nl
+Países Bajos nl
+Holland nl
+Holanda nl
+هلند nl
+Alankomaat nl
+Háland nl
+Pays bas nl
+Países Baixos nl
+הולנד nl
+Nizozemska nl
+Hollandia nl
+Belanda nl
+Holland nl
+Paesi Bassi nl
+オランダ nl
+네덜란드 nl
+ເນເທີແລນ์ nl
+Olandija nl
+Nīderlande nl
+Nederland nl
+Nederland nl
+Nederland nl
+Holanda nl
+Holandia nl
+Países Baixos nl
+Holanda nl
+Olanda nl
+Нидерланды nl
+Holandsko nl
+Nizozemska nl
+Holandija nl
+I-Netherlands nl
+Nederländerna nl
+¦¿¾÷Ä¡óÐ nl
+เนเธอร์แลนด์ nl
+Hollanda nl
+Голландія nl
+Hà Lan nl
+荷兰 nl
+荷蘭 nl
+Norway no
+Noorweë no
+النرويج no
+Norveç no
+Нарвэгія no
+Норвегия no
+Norvegia no
+Norveška no
+Noruega no
+Norsko no
+Norge no
+Norwegen no
+Νορβηγία no
+Norvegio no
+Noruega no
+Norra no
+Norvegia no
+نروژ no
+Norja no
+Norra no
+Norvège no
+Noruega no
+נורבגיה no
+Norveška no
+Norvégia no
+Norwegia no
+Noregur no
+Norvegia no
+ノルウェー no
+노르웨이 no
+ນໍເວ no
+Norvegija no
+Norvēģija no
+Norveġja no
+Norge no
+Noorwegen no
+Noreg no
+Noruega no
+Norwegia no
+Noruega no
+Noruega no
+Norvegia no
+Норвегия no
+Nórsko no
+Norveška no
+Norveška no
+I-Norway no
+Norge no
+¿¡÷§Å no
+นอร์เวย์ no
+Norveç no
+Норвегія no
+Na uy no
+挪威 no
+挪威 no
+Nepal np
+Нэпал np
+Непал np
+Nepál np
+ເວນດາ np
+尼泊尔 np
+Nauru nr
+Науру nr
+Науру nr
+Naurú nr
+ປາລາກກວຍ nr
+瑙鲁 nr
+Niue nu
+Ниуе nu
+ເນ໊ຕ nu
+纽埃岛 nu
+New Zealand nz
+Nuwe Seeland nz
+نيوزيلاندا nz
+Yeni Zellandiya nz
+Новая Зэляндыя nz
+Нова Зеландия nz
+Zeland nevez nz
+Novi Zeland nz
+Nova Zelanda nz
+Nový Zéland nz
+Neuseeland nz
+Νέα Ζηλανδία nz
+Novzelando nz
+Nueva Zelanda nz
+Uus-Meremaa nz
+Zelanda Berria nz
+زلاندنو nz
+Uusi-Seelanti nz
+Nýsæland nz
+Nouvelle Zélande nz
+Nova Celandia nz
+ניו זילנד nz
+Novi Zeland nz
+Új-Zéland nz
+Selandia Baru nz
+Nýja Sjáland nz
+Nuova Zelanda nz
+ニュージーランド nz
+뉴질랜드 nz
+ນີວຊີແລນ nz
+Naujoji Zelandija nz
+JaunZēlande nz
+Nieuw Zeeland nz
+Navera Zelanda nz
+Nowa Zelandia nz
+Nova Zelândia nz
+Nova Zelândia nz
+Noua Zeelandă nz
+Новая Зеландия nz
+Nový Zéland nz
+Nova Zelandija nz
+Novi Zeland nz
+I-New Zealand nz
+Nya Zeeland nz
+¿¢äº¢Ä¡óÐ nz
+นิวซีแลนด์ nz
+Yeni Zelanda nz
+Нова Зеландія nz
+Nouve Zelande nz
+新西兰 nz
+紐西蘭 nz
+Oman om
+عُمان om
+Аман om
+Оман om
+Omán om
+Ομάν om
+Omano om
+Omán om
+Omaan om
+عمان om
+עומן om
+Omán om
+オマーン om
+오만 om
+ເຍີຍລະມັນ om
+Omanas om
+Omã om
+Оман om
+Omán om
+I-Oman om
+µÁý om
+Umman om
+Оман om
+ Oman om
+阿曼 om
+阿曼 om
+Panama pa
+بنما pa
+Панама pa
+Панама pa
+Panamà pa
+Παναμάς pa
+Panamo pa
+Panamá pa
+پاناما pa
+Panamá pa
+פנמה pa
+パナマ pa
+파나마 pa
+ປານາມາ pa
+Panamá pa
+Panamá pa
+Панама pa
+I-Panama pa
+ÀÉ¡Á¡ pa
+ปานามา pa
+Панама pa
+巴拿马 pa
+巴拿馬 pa
+Peru pe
+البيرو pe
+Пэру pe
+Перу pe
+Perou pe
+Perú pe
+Περού pe
+Peruo pe
+Perú pe
+Peruu pe
+پرو pe
+Pérou pe
+Perú pe
+פרו pe
+Perú pe
+Perù pe
+ペルー pe
+페루 pe
+ເປລູ pe
+Perū pe
+Pero pe
+Perú pe
+Перу pe
+I-Peru pe
+¦ÀÕ pe
+เปรู pe
+Перу pe
+Perou pe
+秘鲁 pe
+秘魯 pe
+French Polynesia pf
+Француская Палінэзія pf
+Френска Полинезия pf
+Francuska Polinezija pf
+Fransk Polynesien pf
+Polinesia francesa pf
+Polinesia Frantziarra pf
+Francia-Polinézia pf
+ຝຣັ່ງເສດ pf
+Polinésia Francesa pf
+Francúzska Polynézia pf
+Francoska Polinezija pf
+Franska Polynesien pf
+法属波利尼西亚 pf
+Papua New Guinea pg
+Папуа–Новая Гвінэя pg
+Папуа и Нова Гвинея pg
+Papua Nova Gvineja pg
+Papua Nueva Guinea pg
+Papua Ginea Berria pg
+Pápua Új-Guinea pg
+ເທົາອ່ອນ pg
+Nova Guiné Papua pg
+Papua Nová Guinea pg
+Papua Nova Gvineja pg
+Papua Nya Guinea pg
+巴布亚新几内亚 pg
+Philippines ph
+Філіпіны ph
+Филипини ph
+Filipini ph
+Filippinerne ph
+Filipinas ph
+Filipinak ph
+Fülöp-szigetek ph
+ອາລະປະໂຫຍດ ph
+Filipinas ph
+Filipíny ph
+Filipini ph
+Filippinerna ph
+菲律宾 ph
+Pakistan pk
+Пакістан pk
+Пакистан pk
+Pakisztán pk
+ລງບ pk
+Paquistão pk
+巴基斯坦 pk
+Poland pl
+Poolland pl
+بولندا pl
+Polşa pl
+Польшча pl
+Полша pl
+Polonia pl
+Poljska pl
+Polònia pl
+Polsko pl
+Polen pl
+Polen pl
+Πολωνία pl
+Pollando pl
+Polonia pl
+Poola pl
+Polonia pl
+لهستان pl
+Puola pl
+Pólland pl
+Pologne pl
+Polonia pl
+פולין pl
+Poljska pl
+Lengyelország pl
+Polandia pl
+Pólland pl
+Polonia pl
+ポーランド pl
+폴란드 pl
+ໂປແລນ pl
+Lenkija pl
+Polija pl
+Polonja pl
+Polen pl
+Polen pl
+Polen pl
+Polònia pl
+Polska pl
+Polónia pl
+Polônia pl
+Polonia pl
+Польша pl
+Poľsko pl
+Poljska pl
+Poljska pl
+I-Poland pl
+Polen pl
+§À¡Ä¡óÐ pl
+โปแลนด์ pl
+Polonya pl
+Польща pl
+Pholandi pl
+Ba Lan pl
+Pologne pl
+波兰 pl
+波蘭 pl
+Saint Pierre and Miquelon pm
+Sveti Pjer i Migelon pm
+Saint Pierre og Miquelon pm
+Saint Pierre y Miquelon pm
+Saint Pierre eta Miquelon pm
+Saint Pierre és Miquelon pm
+Saint Pierre e Miquelon pm
+Saint Pierre a Miquelon pm
+Sveti Pierre in Miquelon pm
+Saint Pierre och Miquelon pm
+圣皮埃尔和密克隆岛 pm
+Pitcairn pn
+Pitkern pn
+ລງບ pn
+Puerto Rico pr
+Пуерто Рико pr
+Portoriko pr
+ໂປຣໂຕຄອນ pr
+Porto Rico pr
+Portoriko pr
+波多尼各 pr
+Palestinian Territory ps
+Palesteinse Gebied ps
+السلطة الفلسطينية ps
+Палестынская тэрыторыя ps
+Палестина ps
+Palestinska teritorija ps
+Territori Palestí ps
+Palestinské území ps
+Palæstinensiske selvstyreområder ps
+Palästinensisches Gebiet ps
+Παλαιστίνη ps
+Palestinaj teritorioj ps
+Territorio palestino ps
+Palestiina territoorium ps
+Palestina ps
+فلسطین ps
+Palestiinalaisalue ps
+Palestinensiska økið ps
+Territoire palestinien ps
+השטחים הפלסטיניים ps
+Palestinski teritorij ps
+Palesztin területek ps
+Territori palestinesi ps
+パレスチナ自治区 ps
+팔레스타인 자치구 ps
+ການພິມຜິດພາດ ps
+Palestinos teritorija ps
+Palestina ps
+Palestinske territorier ps
+Palestijns territorium ps
+Palestinske territorium ps
+Bohwa bja Palestina ps
+Palestyna ps
+Território Palestiniano ps
+Território Palestino ps
+Teritoriul Palestinian ps
+Палестинские территории ps
+Palestínske územia ps
+Palestinski teritorij ps
+I-Palestinian Territory ps
+Palestina ps
+À¡ÄŠ¾£É ¬¨½Âõ ps
+Filistin Bölgesi ps
+Палестинська територія ps
+Mukano wa maphalesitina ps
+Palestene ps
+Umhlaba wePalestina ps
+巴勒斯坦地区 ps
+巴勒斯坦領地 ps
+Indawo yama-Phalesitina ps
+Portugal pt
+البرتغال pt
+Portuqaliya pt
+Партугалія pt
+Португалия pt
+Portugalsko pt
+Πορτογαλία pt
+Portugalo pt
+پرتغال pt
+Portugali pt
+פורטוגל pt
+Portugália pt
+Portúgal pt
+Portogallo pt
+ポルトガル pt
+포르투갈 pt
+ໂປຣຕຸເກສ pt
+Portugalija pt
+Portugāle pt
+Portugall pt
+Portugalia pt
+Portugalia pt
+Португалия pt
+Portugalsko pt
+Portugalska pt
+I-Portugal pt
+§À¡÷òиø pt
+โปรตุเกส pt
+Portekiz pt
+Португалія pt
+BềEĐào Nha pt
+葡萄牙 pt
+葡萄牙 pt
+Palau pw
+Палау pw
+Палау pw
+ມອລຕາ pw
+帕劳群岛 pw
+Paraguay py
+Paraguaai py
+باراغواي py
+Paraqvay py
+Парагвай py
+Парагвай py
+Paragvaj py
+Paraguai py
+Παραγουάη py
+Paragvajo py
+Paraguai py
+پاراگویه py
+Paraguai py
+פרגואי py
+Paragvaj py
+パラグアイ py
+파라과이 py
+ປາລາກກວຍ py
+Paragvajus py
+Paragvaja py
+Paragwaj py
+Paraguai py
+Paragwaj py
+Paraguai py
+Paraguai py
+Paraguai py
+Парагвай py
+Portugalsko py
+Paragvaj py
+Paragvaj py
+I-Paraguay py
+Àá̧Špy
+ปารากวัย py
+Парагвай py
+Paragway py
+巴拉圭 py
+巴拉圭 py
+Qatar qa
+قطر qa
+Катар qa
+Катар qa
+Katar qa
+Katar qa
+Katar qa
+Κατάρ qa
+Kataro qa
+Katar qa
+قطر qa
+Katar qa
+קטר qa
+Katar qa
+Katar qa
+カタール qa
+카타르 qa
+ມອລຕາ qa
+Katar qa
+Катар qa
+Katar qa
+Katar qa
+I-Qatar qa
+¸¾¡÷ qa
+Katar qa
+Катар qa
+卡塔尔 qa
+卡達 qa
+Romania ro
+Romenië ro
+رومانيا ro
+Rumıniya ro
+Румынія ro
+Румъния ro
+Roumania ro
+Rumunija ro
+Rumunsko ro
+Rumænien ro
+Rumänien ro
+Ρουμανία ro
+Rumanio ro
+Rumanía ro
+Rumeenia ro
+Errumania ro
+رومانی ro
+Rumenia ro
+Roumanie ro
+Romanía ro
+רומניה ro
+Rumunjska ro
+Románia ro
+Rumania ro
+Rúmenía ro
+ルーマニア ro
+루마니아 ro
+ໂລມາເນີຍ ro
+Rumunija ro
+Rumānija ro
+Rumanija ro
+Roemenië ro
+Rumunia ro
+Roménia ro
+Romênia ro
+Румыния ro
+Rumunsko ro
+Romunija ro
+Rumunija ro
+I-Romania ro
+Rumänien ro
+Õ§Áɢ¡ ro
+โรมาเนีย ro
+Romanya ro
+Румунія ro
+Ru ma ni ro
+Roumaneye ro
+罗马尼亚 ro
+羅馬尼亞 ro
+Russia ru
+Rusland ru
+روسيا ru
+Rusiya ru
+Расея ru
+Русия ru
+Rusia ru
+Rusija ru
+Rússia ru
+Rusko ru
+Rusland ru
+Russland ru
+Ρωσία ru
+Ruslando ru
+Rusia ru
+Venemaa ru
+Errusia ru
+روسیه ru
+Venäjä ru
+Russland ru
+Russie ru
+Rusia ru
+רוסיה ru
+Rusija ru
+Oroszország ru
+Rusia ru
+Rússland ru
+ロシア ru
+러시아 ru
+ລັດເຊີຍ ru
+Rusija ru
+Krievija ru
+Russja ru
+Russland ru
+Rusland ru
+Russland ru
+Rosja ru
+Rússia ru
+Rússia ru
+Rusia ru
+Россия ru
+Rusko ru
+Rusija ru
+Rusija ru
+I-Russia ru
+Ryssland ru
+ú¢Â¡ ru
+รัสเซีย ru
+Rusya ru
+Росія ru
+Rashia ru
+Nga ru
+Russeye ru
+Rashiya ru
+俄罗斯 ru
+俄羅斯 ru
+Rwanda rw
+Руанда rw
+Руанда rw
+Ruanda rw
+Ruanda rw
+Ruanda rw
+ແພນດ້າ rw
+Ruanda rw
+Ruanda rw
+卢旺达 rw
+Saudi Arabia sa
+Saudi Arabië sa
+السعودية sa
+Саудаўская Арабія sa
+Саудитска Арабия sa
+Saudijska Arabija sa
+Aràbia Saudí sa
+Saúdská Arábie sa
+Saudi Arabien sa
+Saudi-Arabien sa
+Σαουδική Αραβία sa
+Saŭdi-Arabio sa
+Arabia Saudí sa
+Saudi Araabia sa
+عربستان سعودی sa
+Saudi-Arabia sa
+Arabie Saoudite sa
+ערב הסעודית sa
+Saudijska Arabija sa
+Szaúd-Arábia sa
+Arabia saudita sa
+サウジアラビア sa
+사우디 아라비아 sa
+ອາລະບິກ sa
+Saudi Arabija sa
+Għarabja Sawdita sa
+Saudi-Arabia sa
+Saudi-Arabië sa
+Saudi-Arabia sa
+Arabia Saudyjska sa
+Arábia Saudita sa
+Arábia Saudita sa
+Arabia Saudită sa
+Саудовская Аравия sa
+Saudská arábia sa
+Saudova Arabija sa
+I-Saudi Arabia sa
+Saudiarabien sa
+º×¾¢ «§ÃÀ¢Â¡ sa
+Suudi Arabistan sa
+Саудівська Аравія sa
+沙特阿拉伯 sa
+沙烏地阿拉伯 sa
+Solomon Islands sb
+Саламонавы астравы sb
+Соломонови Острови sb
+Solomonska ostrva sb
+Salomon-øerne sb
+Islas Salomón sb
+Solomon Irlak sb
+Salamon-szigetek sb
+ສະໂລວະເນີຍ sb
+Ilhas Salomão sb
+Šalamúnove ostrovy sb
+Solomonovi otoki sb
+Salomonöarna sb
+所罗门群岛 sb
+Seychelles sc
+Сэйшэлы sc
+Сейшелски острови sc
+Sejšeli sc
+Seychellerne sc
+ເຊລ sc
+Sejšeli sc
+Seychellerna sc
+塞舌尔 sc
+Sudan sd
+السودان sd
+Судан sd
+Судан sd
+Sudán sd
+Σουδάν sd
+Sudano sd
+Sudán sd
+Sudaan sd
+سودان sd
+Sudania sd
+Soudan sd
+סודן sd
+Szudán sd
+Súdan sd
+スーダン sd
+수단 sd
+ຊູດານ sd
+Sudanas sd
+Sudāna sd
+Sudão sd
+Sudão sd
+Судан sd
+Sudán sd
+I-Sudan sd
+ݼ¡ý sd
+ซูดาน sd
+Судан sd
+Sudani sd
+Soudan sd
+苏丹 sd
+蘇丹 sd
+Sweden se
+Swede se
+السويد se
+İsveç se
+Швэцыя se
+Швеция se
+Sveden se
+Švedska se
+Suècia se
+Švédsko se
+Sverige se
+Schweden se
+Σουηδία se
+Svedio se
+Suecia se
+Rootsi se
+Suedia se
+سوید se
+Ruotsi se
+Svøriki se
+Suède se
+Suecia se
+שבדיה se
+Švedska se
+Svédország se
+Swedia se
+Svíþjóð se
+Svezia se
+スウェーデン se
+스웨덴 se
+ສະວີເດນ se
+Švedija se
+Zviedrija se
+Svezja se
+Sverige se
+Zweden se
+Sverige se
+Suècia se
+Szwecja se
+Suécia se
+Suécia se
+Suedia se
+Швеция se
+Švédsko se
+Švedska se
+Švedska se
+I-Sweden se
+Sverige se
+ÍÅ£¼ý se
+สวีเดน se
+İsveç se
+Швеція se
+Swidene se
+Thuỵ Điển se
+瑞典 se
+瑞典 se
+Singapore sg
+Сынгапур sg
+Сингапур sg
+Singapur sg
+Singapur sg
+Szingapúr sg
+ໂຊນາ sg
+Singapura sg
+Singapur sg
+Singapur sg
+新加坡 sg
+Saint Helena sh
+Свети Елена sh
+Sveta Helena sh
+St. Helena sh
+Santa Helena sh
+Szent Heléna sh
+ຫົວເລື່ອງ sh
+Santa Helena sh
+Svätá Helena sh
+Sveta Helena sh
+圣赫勒拿岛 sh
+Slovenia si
+Slovenië si
+سلوفينيا si
+Sloveniya si
+Славенія si
+Словения si
+Slovenija si
+Eslovenia si
+Slovinsko si
+Slovenien si
+Slowenien si
+Σλοβενία si
+Slovenio si
+Eslovenia si
+Sloveenia si
+Eslovenia si
+اسلوانی si
+Slovénie si
+Eslovenia si
+סלובניה si
+Slovenija si
+Szlovénia si
+Slóvenía si
+スロベニア si
+슬로베니아 si
+ສະໂລວະເນີຍ si
+Slovėnija si
+Slovēnija si
+Slovenja si
+Slovenië si
+Eslovenia si
+Słowenia si
+Eslovénia si
+Eslovênia si
+Словения si
+Slovinsko si
+Slovenija si
+Slovenija si
+I-Slovenia si
+Slovenien si
+ͧġŢɢ¡ si
+สโลเวเนีย si
+Slovenya si
+Словенія si
+斯洛文尼亚 si
+斯洛維尼亞 si
+Slovakia sk
+Slovakië sk
+سلوفاكيا sk
+Slovakiya sk
+Славакія sk
+Словакия sk
+Slovačka sk
+Eslovaquia sk
+Slovensko sk
+Slovakiet sk
+Slowakien sk
+Σλοβακία sk
+Slovakujo sk
+Eslovaquia sk
+Slovakkia sk
+Eslovakia sk
+اسلواکی sk
+Slovaquie sk
+סלובקיה sk
+Slovačka sk
+Szlovákia sk
+Slóvakía sk
+Slovacchia sk
+スロバキア sk
+슬로바키아 sk
+ສະໂລວັກ sk
+Slovakija sk
+Slovākija sk
+Slovakja sk
+Slovakije sk
+Słowacja sk
+Eslováquia sk
+Eslováquia sk
+Slovacia sk
+Словакия sk
+Slovensko sk
+Slovaška sk
+I-Slovakia sk
+Slovakien sk
+ͧġš츢 sk
+สโลวัค sk
+Slovakya sk
+Словакія sk
+斯洛伐克 sk
+斯洛伐克 sk
+San Marino sm
+Сан-Марына sm
+Сан Марино sm
+ໂຊນາ sm
+圣马力诺 sm
+Senegal sn
+Сэнэгал sn
+Сенегал sn
+Szenegál sn
+ທົ່ວໄປ sn
+塞内加尔 sn
+Somalia so
+Somalië so
+صومال so
+Самалі so
+Сомалия so
+Somalija so
+Somàlia so
+Somálsko so
+Σομαλία so
+Somalio so
+Somaalia so
+سومالی so
+Somalie so
+סומליה so
+Somalija so
+Szomália so
+ソマリア so
+소말리아 so
+ໂລມາເນີຍ so
+Somalis so
+Somalija so
+Somalie so
+Somália so
+Somália so
+Сомали so
+Somálsko so
+Somalija so
+I-Somalia so
+§º¡Á¡Ä¢Â¡ so
+Somali so
+Сомалі so
+Somaleye so
+索马里 so
+索馬利亞 so
+Suriname sr
+Сурынам sr
+Суринам sr
+Surinam sr
+ເຊີເບີຍ sr
+Surinam sr
+Surinam sr
+Surinam sr
+Sao Tome and Principe st
+Сан Томе и Приницпе st
+Sao Tome i Principe st
+Sao Tomé og Principe st
+Sao Tome y Príncipe st
+Sao Tome eta Principe st
+Sao Tome és Principe st
+ບໍລິການ st
+São Tome e Príncipe st
+Sao Tome a Principe st
+Sao Tome in Principe st
+São Tomé och Príncipe st
+El Salvador sv
+السلفادور sv
+Сальвадор sv
+Ел Салвадор sv
+Salvador sv
+Salvador sv
+Ελ Σαλβαντόρ sv
+Elsalvadoro sv
+Salvador sv
+السالوادور sv
+Salvador sv
+O Salvador sv
+אל סלבדור sv
+Salvador sv
+エルサルバドル sv
+엘살바도르 sv
+ເອລຊັນວາດດໍ sv
+Salvadoras sv
+Salvadora sv
+Salwador sv
+Salvador sv
+Сальвадор sv
+Salvádor sv
+Salvador sv
+I-El Salvador sv
+±ø º¡øŧ¼¡÷ sv
+เอลซัลวาดอร์ sv
+Ель-Сальвадор sv
+萨尔瓦多 sv
+薩爾瓦多 sv
+Syria sy
+Sirië sy
+سوريا sy
+Сырыя sy
+Сирия sy
+Sirija sy
+Síria sy
+Sýrie sy
+Syrien sy
+Syrien sy
+Συρία sy
+Sirio sy
+Siria sy
+Süüria sy
+Siria sy
+سوریه sy
+Syyria sy
+Syrie sy
+סוריה sy
+Sirija sy
+Szíria sy
+Siria sy
+シリア sy
+시리아 sy
+ເຊີເບີຍ sy
+Sirija sy
+Siria sy
+Syrië sy
+Síria sy
+Síria sy
+Siria sy
+Сирия sy
+Sýria sy
+Sirija sy
+I-Syria sy
+Syrien sy
+º¢Ã¢Â¡ sy
+Suriye sy
+Сирія sy
+叙利亚 sy
+敘利亞 sy
+Swaziland sz
+Свазылэнд sz
+Свазиленд sz
+Svazilend sz
+Swazilandia sz
+Swazilandia sz
+Szváziföld sz
+ລາດສະນາຈັກໄທຍ sz
+Suécia sz
+Swazijsko sz
+Svazi sz
+斯威士兰 sz
+Turks and Caicos Islands tc
+Turks i Kaikos ostrva tc
+Turks- og Caicosøerne tc
+Islas Turcos y Caicos tc
+Turks eta Caicos Irlak tc
+Turks- és Caicos-szigetek tc
+Ilhas Caicos e Turca tc
+Turks a Caicos ostrovy tc
+Otoka Turks in Caicos tc
+Turks- och Caicosöarna tc
+特克斯和凯科斯群岛 tc
+Chad td
+Чад td
+Чад td
+Čad td
+Tchad td
+Txad td
+Csád td
+ເກມໄພ່ td
+Čad td
+Čad td
+Tchad td
+乍得 td
+Togo tg
+Тога tg
+Того tg
+ຂອງເລ່ນສະນຸກ tg
+多哥 tg
+Thailand th
+تايلاند th
+Tayland th
+Тайлянд th
+Тайланд th
+Tajland th
+Tailàndia th
+Thajsko th
+Ταϊλάνδη th
+Tajlando th
+Tailandia th
+Tai th
+Thailandia th
+تایلند th
+Thaimaa th
+Tailand th
+Thaïlande th
+Tailandia th
+תאילנד th
+Tajland th
+Thaiföld th
+Tæland th
+Tailandia th
+タイ th
+태국 (타이) th
+ລາດສະນາຈັກໄທຍ th
+Tailandas th
+Taivāna th
+Tajlandja th
+Tailandia th
+Tajlandia th
+Tailândia th
+Tailândia th
+Tailanda th
+Таиланд th
+Thajsko th
+Tajska th
+Tajland th
+I-Thailand th
+¾¡öÄ¡óÐ th
+ราชอาณาจักรไทย th
+Tayland th
+Таїланд th
+Thái Lan th
+Taylande th
+泰国 th
+泰國 th
+Tajikistan tj
+Таджыкістан tj
+Таджикистан tj
+Tadžikistan tj
+Tajikistán tj
+Tadzsikisztán tj
+ໃຕ້ຫວັນ tj
+Tajiquistão tj
+Tadžikistan tj
+Tadžikistan tj
+Tadzjikistan tj
+塔吉克斯坦 tj
+Tokelau tk
+Токелао tk
+ເບລາລັສ tk
+Turkmenistan tm
+Туркмэністан tm
+Туркменистан tm
+Turkmenistán tm
+Türkmenisztán tm
+ຕຸລະກີ tm
+Turquia tm
+土库曼斯坦 tm
+Tunisia tn
+Tunisië tn
+تونس tn
+Туніс tn
+Тунис tn
+Tunis tn
+Tuníssia tn
+Tunisko tn
+Tunesien tn
+Tunesien tn
+Τυνησία tn
+Tunisio tn
+Túnez tn
+Tuneesia tn
+تونس tn
+Tunesia tn
+Tunisie tn
+תוניסיה tn
+Tunis tn
+Tunézia tn
+チュニジア tn
+튀니지 tn
+ລັດເຊີຍ tn
+Tunisas tn
+Tuneżija tn
+Tunisie tn
+Tunezja tn
+Tunísia tn
+Tunísia tn
+Тунис tn
+Tunisko tn
+Tunizija tn
+I-Tunisia tn
+Tunisien tn
+ÐÉ¢º¢Â¡ tn
+Tunus tn
+Туніс tn
+突尼斯 tn
+突尼西亞 tn
+Tonga to
+Тонга to
+Тонга to
+ໂຊນາ to
+汤加 to
+East Timor tp
+Источен Тимур tp
+Istočni Timor tp
+Østtimor tp
+Timor oriental tp
+Ekialdeko Timor tp
+Kelet-Timor tp
+ວັນແລະເວລາ tp
+Timor Leste tp
+Východný Timor tp
+Vzhodni Timor tp
+Östtimor tp
+东帝汶 tp
+Turkey tr
+Turkeye tr
+تركيا tr
+Türkiyə tr
+Турцыя tr
+Турция tr
+Turkia tr
+Turska tr
+Turquia tr
+Turecko tr
+Tyrkiet tr
+Türkei tr
+Τουρκία tr
+Turkujo tr
+Turquía tr
+Türgi tr
+Turkia tr
+ترکیه tr
+Turkki tr
+Turkaland tr
+Turquie tr
+Turquía tr
+טורקיה tr
+Turska tr
+Törökország tr
+Turki tr
+Tyrkland tr
+Turchia tr
+トルコ tr
+터키 tr
+ຕຸລະກີ tr
+Turkija tr
+Turcija tr
+Turkija tr
+Tyrkia tr
+Turkije tr
+Tyrkia tr
+Turquia tr
+Turcja tr
+Turquia tr
+Turquia tr
+Turcia tr
+Турция tr
+Turecko tr
+Turčija tr
+Turska tr
+I-Turkey tr
+Turkiet tr
+ÐÕ츢 tr
+ตุรกี tr
+Türkiye tr
+Туреччина tr
+ThềENhĩ Kì tr
+土耳其 tr
+土耳其 tr
+Trinidad and Tobago tt
+Trinidad en Tobago tt
+ترينيداد و توباغو tt
+Trinidad və Tabaqo tt
+Трынідад і Табага tt
+Тринидад и Тобаго tt
+Trinidad ha Tobago tt
+Trinidad i Tobago tt
+Trinidad i Tobago tt
+Trinidad a Tobago tt
+Trinidad og Tobago tt
+Trinidad und Tobago tt
+Τρίνινταντ και Τομπάγκο tt
+Trinidado kaj Tobago tt
+Trinidad y Tobago tt
+Trinidad ja Tobago tt
+Trinidad eta Tobago tt
+ترینیداد و تُباگو tt
+Trinidad ja Tobago tt
+Trinidad og Tobago tt
+Trinidad et Tobago tt
+Trindade e Tobago tt
+טרינידד וטובגו tt
+Trinidad i Tobago tt
+Trinidad és Tobago tt
+Trinidad dan Tobago tt
+Trinidad og Tobago tt
+Trinidad e Tobago tt
+トリニダードトバコ tt
+트리니다드토바고 tt
+ຕີນິແດດແລະໂທບາໂກ tt
+Trinidadas ir Tobagas tt
+Trinidada un Tobago tt
+Trinidad u Tobago tt
+Trinidad og Tobago tt
+Trinidad en Tobago tt
+Trinidad og Tobago tt
+Trinidad le Tobago tt
+Trinidad e Tobago tt
+Trinidad i Tobago tt
+Trinidade e Tobago tt
+Trinidad e Tobago tt
+Trinidad şi Tobago tt
+Тринидад и Тобаго tt
+Trinidad a Tobago tt
+Trinidad in Tabago tt
+Trinidad i Tobago tt
+I-Trinidad kanye neTobago tt
+Trinidad och Tobago tt
+ðâɢ¼¡ð & ¦¼¡À¡§¸¡ tt
+ตรีนิแดดและโทบาโก tt
+Trinidad veTabago tt
+Республіка Трінідад та Тобаго tt
+Trinidad na Tobago tt
+Trinidad và Tobago tt
+Trinidad ne Tobago tt
+特里尼达和多巴哥 tt
+千里達及托貝哥 tt
+Trinidad knaye ne-Tobago tt
+Tuvalu tv
+Тувалу tv
+Тували tv
+ຊູລູ tv
+图瓦卢 tv
+Taiwan tw
+تايوان tw
+Tayvan tw
+Тайвань tw
+Тайван tw
+Tajvan tw
+Ταϊβάν tw
+Tajvano tw
+Taiwán tw
+Taivan tw
+تایوان tw
+Taivan tw
+Taïwan tw
+Taiwán tw
+טיוואן tw
+Tajvan tw
+Tajvan tw
+台湾 tw
+대만 tw
+ໃຕ້ຫວັນ tw
+Taivanis tw
+Taivāna tw
+Tajwan tw
+Tajwan tw
+Formosa tw
+Тайвань tw
+Tajvan tw
+Tajvan tw
+I-Taiwan tw
+¾¡öÅ¡ý tw
+ได้หวัน tw
+Tayvan tw
+Тайвань tw
+Đài Loan tw
+中国台湾 tw
+台灣 tw
+Tanzania, United Republic of tz
+Злучаная Рэспубліка Танзанія tz
+Танзания tz
+Tanzanija, Ujedinjena Republika tz
+Tanzania tz
+Tanzania, Republica de tz
+Tanazia, Errepublika Batua tz
+Tanzánia tz
+ໂດມິນິກັນ tz
+República da Tanzânia tz
+Tanzánia, Spojená republika tz
+Tanzanija, Združena republika tz
+Förenade republiken Tanzania tz
+坦桑尼亚 tz
+Ukraine ua
+Ukraïne ua
+أوكرانيا ua
+Ukrayna ua
+Украіна ua
+Украйна ua
+Ukraina ua
+Ukrajina ua
+Ucraïna ua
+Ukrajina ua
+Ουκρανία ua
+Ukrainio ua
+Ucrania ua
+Ukraina ua
+Ukrania ua
+اکراین ua
+Ukraina ua
+Ukraina ua
+Ucraína ua
+אוקראינה ua
+Ukrajina ua
+Ukrajna ua
+Ukraina ua
+Úkraína ua
+Ucraina ua
+ウクライナ ua
+우크라이나 ua
+ຍູເຄຣນ ua
+Ukraina ua
+Ukraina ua
+Ukranja ua
+Ukraina ua
+Oekraïne ua
+Ukraina ua
+Ucraina ua
+Ukraina ua
+Ucrânia ua
+Ucrânia ua
+Ucraina ua
+Украина ua
+Ukrajina ua
+Ukrajina ua
+Ukrajna ua
+I-Ukraine ua
+Ukraina ua
+¯ì¦Ãöý ua
+ยูเครน ua
+Ukrayna ua
+Україна ua
+Ukraina ua
+Ucrinne ua
+乌克兰 ua
+烏克蘭 ua
+Uganda ug
+Уганда ug
+Уганда ug
+ແພນດ້າ ug
+乌干达 ug
+United States of America us
+Vereenigde State van Amerika us
+الولايات المتحدة الأمريكية us
+Amerika Birləşmiş Ştatları us
+Злучаныя Штаты Амэрыкі us
+САЩ us
+Stadoù-Unanet Amerika us
+Sjedinjene Američke Države us
+Estats Units d'Amèrica us
+Spojené státy americké us
+USA us
+USA us
+Ην. Πολιτείες της Αμερικής us
+Usono us
+Estados Unidos de América us
+Ameerika Ühendriigid us
+Amerikako Estatu Batuak us
+ایالات متحده‌ی آمریکا us
+Yhdysvallat us
+Sambandsríki Amerika (USA) us
+États Unis d'Amérique us
+Estados Unidos de América us
+ארצות הברית us
+Sjedinjene Američke Države us
+Amerikai Egyesült Államok us
+Amerika Serikat us
+Bandaríki Norður Ameríku us
+Stati Uniti d'America us
+アメリカ us
+미 합중국 us
+ສະຫະລັດອາເມລິກາ us
+Jungtinės Amerikos Valstijos us
+Amerikas Savienotās Valstis us
+Stati Uniti us
+USA us
+Verenigde Staten van Amerika us
+USA us
+Estats Units d'Amèrica us
+Stany Zjednoczone Ameryki us
+Estados Unidos da América us
+Estados Unidos us
+Statele Unite ale Americii us
+Соединенные Штаты Америки us
+USA us
+Združene države Amerike us
+Sjedinjene američke države us
+I-United States of America us
+Amerikas förenta stater us
+³ì¸¢Â «¦ÁÃ¢ì¸ ¿¡Î¸û us
+สหรัฐอเมริกา us
+Amerika Birleşik Devletleri us
+США us
+mashango o tangananaho a America us
+Mĩ us
+United States ye Melika us
+美利坚合众国 us
+美利堅合眾國 us
+Uruguay uy
+الأوروغواي uy
+Uruqvay uy
+Уругвай uy
+Уругвай uy
+Urugvaj uy
+Uruguai uy
+Ουρουγουάη uy
+Urugvajo uy
+Uruguai uy
+اروگویه uy
+Uruguai uy
+אורוגואי uy
+Urugvaj uy
+ウルグアイ uy
+우루과이 uy
+ອຸລຸກກວຍ uy
+Urugvajus uy
+Urugvaja uy
+Urugwaj uy
+Uruguai uy
+Urugwaj uy
+Uruguai uy
+Uruguai uy
+Uruguai uy
+Уругвай uy
+Uruguaj uy
+Urugvaj uy
+Urugvaj uy
+I-Uruguay uy
+¯Õ̧Šuy
+อุรุกวัย uy
+Уругвай uy
+Ourougway uy
+乌拉圭 uy
+烏拉圭 uy
+Uzbekistan uz
+Узбэкістан uz
+Узбекистан uz
+Uzbekistán uz
+Üzbegisztán uz
+ເດນ່ງນ uz
+Uzbequistão uz
+乌兹别克斯坦 uz
+Vatican City va
+Ватыкан va
+Ватикана va
+Vatikan va
+Vatikanstaten va
+Vaticano va
+Batikano Hiria va
+Vatikán va
+ລັດເວີຍ va
+Cidade do Vaticano va
+Vatikán va
+Vatikan va
+Vatikanstaten va
+梵蒂冈 va
+St. Vincent and the Grenadines vc
+St. Vincent en die Grenadene vc
+سانت فينسنت و الغرينادين vc
+St. Vincent və Grenadines vc
+Сент-Винсент и Гренадине vc
+S. Visant hag ar Grenadinez vc
+Sveti Vincent i Grenadini vc
+St. Vincent i les Granadines vc
+St. Vincent a Grenadiny vc
+St. Vincent og Grenadinerne vc
+St. Vincent und Grenadinen vc
+St. Vincent kaj la Grenadinoj vc
+San Vicente y las Granadinas vc
+St. Vincent ja Grenadines vc
+St. Vincent eta Grenadines vc
+سن وینسن و گرادینس vc
+St. Vincent ja Grenadiinit vc
+Sankta Vinsent og Grenadinoyggjar vc
+St Vincent et les Grenadines vc
+San Vicente e as Granadinas vc
+סנט וינסנט והגרנדינים vc
+St. Vincent és Grenadines vc
+St. Vincent dan the Grenadines vc
+St. Vincent og Grenadines vc
+S. Vincent e the Grenadines vc
+セントヴィンセントグレナディン vc
+세인트 빈센트 그레나딘 vc
+ເຊີນວິນແຊນ ແລະເກນາດີນ vc
+Šv. Vincentas ir Grenadinai vc
+Sv. Vincents un Grenadīnes vc
+St. Vinċenz u l-Grenadini vc
+St. Vincent og Grenadinene vc
+St. Vincent en de Grenadines vc
+St. Vincent og Grenadinane vc
+St. Vincent le Grenadines vc
+St. Vincent e les Granadines vc
+St. Vincent i Grenadyny vc
+São Vicente e Grenadinas vc
+São Vicente e Grenadines vc
+Sf. Vincent şi Grenadines vc
+Сент-Винсент и Гренадины vc
+St. Vincent a Grenadines vc
+Sv. Vincent in Grenadini vc
+St. Vincent i Grenadine vc
+I-St. Vincent and the Grenadines vc
+St. Vincent och Grenadinerna vc
+¦ºÂ¢ýð Å¢ý¦ºýð & ¸¢¦ÃÉËý¸û vc
+เซนต์วินเซนต์ และ เกรนาดีน vc
+St. Vincent ve Grenadines vc
+Сент-Вінсент і Гренадіни vc
+St. Vincent na Grenadines vc
+St. Vincent và Grenadines vc
+St. Vincent ne Grenadines vc
+圣文森特和格林那达 vc
+聖文森及格納那丁 vc
+I-St. Vincent kanye ne-Grenadines vc
+Venezuela ve
+فنزويلا ve
+Вэнэсуэла ve
+Венецуела ve
+Venecuela ve
+Βενεζουέλα ve
+Venezuelo ve
+Venetsueela ve
+ونزویلا ve
+Venesuela ve
+Vénézuela ve
+ונצואלה ve
+Venecuela ve
+ベネズェラ ve
+베네수엘라 ve
+ເວເນຊຸເອລາ ve
+Venesuela ve
+Venecuēla ve
+Veneżwela ve
+Wenezuela ve
+Венесуэла ve
+Venecuela ve
+I-Venezuela ve
+¦ÅÉ¢ÍÅÄ¡ ve
+เวเนซูเอลา ve
+Венесуела ve
+委内瑞拉 ve
+委內瑞拉 ve
+Virgin Islands, British vg
+Вирджински Острови, Британски vg
+Djevičanska ostrva, Britanska vg
+Britiske jomfruøer vg
+Islas Vírgenes Británicas vg
+Irla Birjinak, Britaniar vg
+Virgin-szigetek (brit) vg
+Ilhas Virgens, Inglaterra vg
+Panenské Ostrovy, Britské vg
+Deviški otoki, Britanski vg
+Brittiska Jungfruöarna vg
+维尔京群岛,英国 vg
+Virgin Islands, U.S. vi
+Вирджински Острови, Американски vi
+Djevičanska ostrva, Američka vi
+Jomfruøerne vi
+Islas Vírgenes Americanas vi
+Irla Birjinak, EE.BB. vi
+Virgin-szigetek (USA) vi
+Ilhas Virgens, EUA vi
+Panenské Ostrovy, Americké vi
+Deviški otoki, ZDA vi
+Amerikanska Jungfruöarna vi
+维尔京群岛,美国 vi
+Vietnam vn
+Viëtnam vn
+فييتنام vn
+Vyetnam vn
+Віетнам vn
+Виетнам vn
+Vijetnam vn
+Βιετνάμ vn
+Vjetnamo vn
+ویتنام vn
+וייטנאם vn
+Vijetnam vn
+Víetnam vn
+ベトナム vn
+베트남 vn
+ຫວງດນາມ vn
+Vietnamas vn
+Vjetnama vn
+Vjetnam vn
+Viëtnam vn
+Wietnam vn
+Vietname vn
+Vietnã vn
+Вьетнам vn
+I-Vietnam vn
+เวียตนาม vn
+В'єтнам vn
+越南 vn
+越南 vn
+Vanuatu vu
+Вануату vu
+Ванути vu
+ຈີນ vu
+瓦努阿图 vu
+Wallis and Futuna wf
+Valis i Futuna wf
+Wallis- og Futuna-øerne wf
+Wallis y Futuna wf
+Wallis eta Futuna wf
+Wallis és Futuna wf
+ປັກອິນພາບ wf
+Wallis e Futuna wf
+Wallis a Futuna wf
+Wallis in Futuna wf
+Wallis och Futuna wf
+Samoa ws
+Самоа ws
+Самоя ws
+Szamoa ws
+ໂຊນາ ws
+萨摩亚群岛 ws
+Yemen ye
+اليمن ye
+Емен ye
+Йемен ye
+Jemen ye
+Iemen ye
+Jemen ye
+Jemen ye
+Υεμένη ye
+Jemeno ye
+Jeemen ye
+یمن ye
+Jemen ye
+Jemen ye
+תימן ye
+Jemen ye
+Jemen ye
+イエメン ye
+예멘 ye
+ເດມອນ ye
+Jemenas ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Iémen ye
+Йемен ye
+Jemen ye
+Jemen ye
+I-Yemen ye
+Jemen ye
+§ÂÁý ye
+Ємен ye
+也门 ye
+葉門 ye
+Yugoslavia yu
+Югаславія yu
+Югославия yu
+Jugoslavija yu
+Jugoslavien (Serbien/Montenegro) yu
+Jugoszlávia yu
+ໂບລິເວີຍ yu
+Iugoslávia yu
+Juhoslávia yu
+Jugoslavija yu
+Jugoslavien yu
+南斯拉夫 yu
+South Africa za
+Suid Afrika za
+جنوب أفريقيا za
+Cənubi Afrika za
+Паўднёвая Афрыка za
+Южна Африка za
+Suafrika za
+Južna Afrika za
+Sudàfrica za
+Jižní Afrika za
+Sydafrikanske republik za
+Südafrika za
+Νότια Αφρική za
+Sudafriko za
+Sudáfrica za
+Lõuna Aafrika za
+Hego Afrika za
+آفریقای جنوبی za
+Etelä-Afrikka za
+Suðurafrika za
+Afrique du sud za
+África do Sur za
+דרום אפריקה za
+Južna Afrika za
+Dél-Afrika za
+Afrika Selatan za
+Suður Afríka za
+Sud Africa za
+南アフリカ za
+남 아프리카 공화국 za
+ແອບພິກາໃຕ້ za
+Pietų Afrika za
+Dienvid Āfrika za
+Afrika t'Isfel za
+Sør-Afrika za
+Zuid-Afrika za
+Sør-Afrika za
+Afrika Borwa za
+Sudafrica za
+Afryka Południowa za
+Africa do Sul za
+África do Sul za
+Africa de Sud za
+Южная Африка za
+Južná Afrika za
+Južna Afrika za
+Južna Afrika za
+I-South Africa za
+Sydafrika za
+¦¾ý ¬ôâ측 za
+แอฟริกาใต้ za
+Güney Afrika za
+Південна Африка za
+Afurika tshipembe za
+Nam Phi za
+Mzantsi Afrika za
+南非 za
+南非 za
+Emzantsi Afrika za
+Zambia zm
+Замбія zm
+Замбия zm
+ຈາໄມກາ້ zm
+Zâmbia zm
+Zambija zm
+赞比亚 zm
+Zimbabwe zw
+Зымбабвэ zw
+Зимбабве zw
+Zimbabve zw
+ລິຊາ zw
+Zimbabve zw
+津巴布韦 zw
diff --git a/kabc/emailselectdialog.cpp b/kabc/emailselectdialog.cpp
new file mode 100644
index 0000000..77c31f6
--- /dev/null
+++ b/kabc/emailselectdialog.cpp
@@ -0,0 +1,135 @@
+/*
+ This file is part of the kabc library.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "emailselectdialog.h"
+#include "addressee.h"
+
+#include <klocale.h>
+
+#include <QtCore/QPointer>
+#include <QButtonGroup>
+#include <QTreeWidget>
+#include <QGroupBox>
+#include <QLayout>
+#include <QRadioButton>
+
+
+using namespace KABC;
+
+class EmailSelectDialog::Private
+{
+ public:
+ QButtonGroup *mButtonGroup;
+};
+
+EmailSelectDialog::EmailSelectDialog( const QStringList &emails,
+ const QString &current,
+ QWidget *parent )
+ : KDialog( parent ), d( new Private )
+{
+ setCaption( i18n( "Select Email Address" ) );
+ setButtons( Ok );
+ setDefaultButton( Ok );
+
+ QFrame *topFrame = new QFrame( this );
+ setMainWidget( topFrame );
+
+ QBoxLayout *topLayout = new QVBoxLayout( topFrame );
+ QGroupBox *box = new QGroupBox( i18n( "Email Addresses" ) );
+ d->mButtonGroup = new QButtonGroup( box );
+ d->mButtonGroup->setExclusive( true );
+ topLayout->addWidget( box );
+ QVBoxLayout *layout = new QVBoxLayout;
+
+ QStringList::ConstIterator it;
+ for ( it = emails.begin(); it != emails.end(); ++it ) {
+ QRadioButton *button = new QRadioButton( *it, box );
+ d->mButtonGroup->addButton( button );
+ layout->addWidget( button );
+ if ( (*it) == current ) {
+ button->setChecked( true );
+ }
+ }
+ layout->addStretch( 1 );
+ box->setLayout( layout );
+}
+
+EmailSelectDialog::~EmailSelectDialog()
+{
+ delete d;
+}
+
+QString EmailSelectDialog::selected()
+{
+ QAbstractButton *button = d->mButtonGroup->checkedButton();
+ if ( button ) {
+ return button->text();
+ }
+ return QString();
+}
+
+QString EmailSelectDialog::getEmail( const QStringList &emails, const QString &current,
+ QWidget *parent )
+{
+ QPointer<EmailSelectDialog> dlg = new EmailSelectDialog( emails, current, parent );
+
+ QString result;
+ if ( dlg->exec() && dlg ) {
+ result = dlg->selected();
+ }
+
+ delete dlg;
+
+ return result;
+}
+
+class EditEntryItem : public QTreeWidgetItem
+{
+ public:
+ EditEntryItem( QTreeWidget *parent, const Addressee &addressee,
+ const QString &email=QString() ) :
+ QTreeWidgetItem( parent ),
+ mAddressee( addressee ),
+ mEmail( email )
+ {
+ setText( 0, addressee.realName() );
+ if ( email.isEmpty() ) {
+ setText( 1, addressee.preferredEmail() );
+ setText( 2, i18nc( "this the preferred email address", "Yes" ) );
+ } else {
+ setText( 1, email );
+ setText( 2, i18nc( "this is not preferred email address", "No" ) );
+ }
+ }
+
+ Addressee addressee() const
+ {
+ return mAddressee;
+ }
+
+ QString email() const
+ {
+ return mEmail;
+ }
+
+ private:
+ Addressee mAddressee;
+ QString mEmail;
+};
diff --git a/kabc/emailselectdialog.h b/kabc/emailselectdialog.h
new file mode 100644
index 0000000..79cadc2
--- /dev/null
+++ b/kabc/emailselectdialog.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of the kabc library.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KABC_EMAILSELECTDIALOG_H
+#define KABC_EMAILSELECTDIALOG_H
+
+#include <kabc/kabc_export.h>
+#include <kdialog.h>
+
+namespace KABC {
+
+class KABC_EXPORT EmailSelectDialog : public KDialog
+{
+ Q_OBJECT
+
+ public:
+ EmailSelectDialog( const QStringList &emails, const QString &current, QWidget *parent );
+ ~EmailSelectDialog();
+
+ QString selected();
+
+ static QString getEmail( const QStringList &emails, const QString &current,
+ QWidget *parent );
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+}
+
+#endif
diff --git a/kabc/errorhandler.cpp b/kabc/errorhandler.cpp
new file mode 100644
index 0000000..e9019fa
--- /dev/null
+++ b/kabc/errorhandler.cpp
@@ -0,0 +1,78 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "errorhandler.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <QApplication>
+
+using namespace KABC;
+
+ErrorHandler::~ErrorHandler()
+{
+}
+
+ConsoleErrorHandler::ConsoleErrorHandler()
+ : d( 0 )
+{
+}
+
+ConsoleErrorHandler::~ConsoleErrorHandler()
+{
+}
+
+void ConsoleErrorHandler::error( const QString &msg )
+{
+ // no debug area is ok here
+ kError(5700) << msg;
+}
+
+class GuiErrorHandler::Private
+{
+ public:
+ Private( QWidget *widget )
+ : mWidget( widget )
+ {
+ }
+
+ QWidget *mWidget;
+};
+
+GuiErrorHandler::GuiErrorHandler( QWidget *widget )
+ : d( new Private( widget ) )
+{
+}
+
+GuiErrorHandler::~GuiErrorHandler()
+{
+ delete d;
+}
+
+void GuiErrorHandler::error( const QString &msg )
+{
+ if ( qApp ) {
+ KMessageBox::error( d->mWidget, msg );
+ }
+}
diff --git a/kabc/errorhandler.h b/kabc/errorhandler.h
new file mode 100644
index 0000000..00cb965
--- /dev/null
+++ b/kabc/errorhandler.h
@@ -0,0 +1,114 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KABC_ERRORHANDLER_H
+#define KABC_ERRORHANDLER_H
+
+#include "kabc_export.h"
+#include <QtCore/QString>
+
+class QWidget;
+
+namespace KABC {
+
+/**
+ Abstract class that provides displaying of error messages.
+ We need this to make libkabc gui independent on the one side
+ and provide user friendly error messages on the other side.
+ Use @p ConsoleErrorHandler or @p GuiErrorHandler in your
+ application or provide your own ErrorHandler.
+*/
+class KABC_EXPORT ErrorHandler
+{
+ public:
+ /**
+ Destroys the handler instance.
+ */
+ virtual ~ErrorHandler();
+
+ /**
+ Show error message.
+
+ @param msg The error message to show
+ */
+ virtual void error( const QString &msg ) = 0;
+};
+
+/**
+ This class prints the error messages to stderr via kError().
+*/
+class KABC_EXPORT ConsoleErrorHandler : public ErrorHandler
+{
+ public:
+ /**
+ Create an error handler for console output.
+
+ Uses kError() to write the error messages.
+ */
+ ConsoleErrorHandler();
+
+ /**
+ Destroys the handler instance.
+ */
+ virtual ~ConsoleErrorHandler();
+
+ virtual void error( const QString &msg );
+
+ private:
+ class Private;
+ Private *const d;
+
+ Q_DISABLE_COPY( ConsoleErrorHandler )
+};
+
+/**
+ This class shows messages boxes for every
+ error message.
+*/
+class KABC_EXPORT GuiErrorHandler : public ErrorHandler
+{
+ public:
+ /**
+ Create error handler.
+
+ Uses KMessageBox::error() to display the error messages.
+
+ @param parent Widget which is used as parent for the error dialogs.
+ */
+ GuiErrorHandler( QWidget *parent = 0 );
+
+ /**
+ Destroys the handler instance.
+ */
+ virtual ~GuiErrorHandler();
+
+ virtual void error( const QString &msg );
+
+ private:
+ class Private;
+ Private *const d;
+
+ Q_DISABLE_COPY( GuiErrorHandler )
+};
+
+}
+
+#endif
diff --git a/kabc/field.h b/kabc/field.h
new file mode 100644
index 0000000..b24cc5a
--- /dev/null
+++ b/kabc/field.h
@@ -0,0 +1,239 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_FIELD_H
+#define KABC_FIELD_H
+
+#include "addressee.h"
+#include <QtCore/QString>
+
+class KConfigGroup;
+
+namespace KABC {
+
+/**
+ * @short Represents a field in the Addressbook
+ *
+ * This class represents a field in the Addressbook database.
+ * It provides methods for accessing meta-information about
+ * the field (such as label() or category()) as well as
+ * getting or setting the field's value in an instance of
+ * Addressee (value(), setValue()).
+ *
+ * Furthermore, some static methods are provided for getting
+ * a list of all fields (allFields(), defaultFields()), for
+ * creating new fields (createCustomField()) and for saving
+ * or loading fields to/from a config file (saveFields(),
+ * restoreFields()).
+ */
+class KABC_EXPORT Field
+{
+ public:
+ /**
+ * This type is used for a list of fields.
+ */
+ typedef QList<Field *> List;
+
+ /**
+ * Represents the category a field belongs to.
+ */
+ enum FieldCategory {
+ /**
+ * All fields
+ */
+ All = 0x0,
+ /**
+ * Frequently used fields
+ */
+ Frequent = 0x01,
+ /**
+ * Fields which belong to the address, such as Street, City, Zip, etc.
+ */
+ Address = 0x02,
+ /**
+ * Fields which store information about the e-mail contact, such as
+ * e-mail address or mail client
+ */
+ Email = 0x04,
+ /**
+ * Personal fields, such as Birthday, Home Address fields, IM Address, etc.
+ */
+ Personal = 0x08,
+ /**
+ * Fields about the organization, such as Business Address fields, Department,
+ * Profession, etc.
+ */
+ Organization = 0x10,
+ /**
+ * Custom (user-defined) fields
+ */
+ CustomCategory = 0x20
+ };
+
+ /**
+ * Returns the translated label for this field.
+ */
+ virtual QString label();
+
+ /**
+ * Returns the ored categories the field belongs to.
+ */
+ virtual int category();
+
+ /**
+ * Returns the translated label for @p category.
+ *
+ * @param category the category of type FieldCategory
+ * @return the translated label
+ */
+ static QString categoryLabel( int category );
+
+ /**
+ * Returns a string representation of the value the field has in the given
+ * Addressee.
+ *
+ * @return the string representation of the value or QString(), if it
+ * is not possible to convert the value to a string.
+ */
+ virtual QString value( const KABC::Addressee & );
+
+ /**
+ * Sets the value of the field in the given Addressee.
+ *
+ * @return @c true on success or @c false, if the given string couldn't
+ * be converted to a valid value.
+ */
+ virtual bool setValue( KABC::Addressee &, const QString & );
+
+ /**
+ * Returns a string, that can be used for sorting.
+ */
+ QString sortKey( const KABC::Addressee & );
+
+ /**
+ * Returns, if the field is a user-defined field.
+ *
+ * @return @c true if this is a custom field, @c false otherwise
+ */
+ virtual bool isCustom();
+
+ /**
+ * Returns, if the field is equal with @p field.
+ *
+ * @param field the field to compare this field to
+ * @return @c true if the fields are equal, @c false otherwise
+ */
+ virtual bool equals( Field *field );
+
+ /**
+ * Returns a list of all fields.
+ */
+ static Field::List allFields();
+
+ /**
+ * Returns a list of the default fields.
+ */
+ static Field::List defaultFields();
+
+ /**
+ * Creates a custom field.
+ *
+ * @param label The label for this field
+ * @param category The category of this field
+ * @param key Unique key for this field
+ * @param app Unique app name for this field
+ */
+ static Field *createCustomField( const QString &label, int category,
+ const QString &key, const QString &app );
+
+ /**
+ * Delete all fields from list.
+ */
+ static void deleteFields();
+
+ /**
+ * Save the field settings to a config file.
+ *
+ * @param cfg The config file object
+ * @param identifier The unique identifier
+ * @param fields The list of the fields
+ */
+ static void saveFields( KConfigGroup &cfg, const QString &identifier,
+ const Field::List &fields );
+ /**
+ * @overload
+ *
+ * Here, the list is stored in KGlobal::config() in group "KABCFields".
+ *
+ * @param identifier The unique identifier
+ * @param fields The list of the fields
+ */
+ static void saveFields( const QString &identifier,
+ const Field::List &fields );
+
+ /**
+ * Load the field settings from a config file.
+ *
+ * @param cfg The config file object
+ * @param identifier The unique identifier
+ */
+ static Field::List restoreFields( const KConfigGroup &cfg, const QString &identifier );
+
+ /**
+ * @overload
+ *
+ * Here, the list is loaded from KGlobal::config() from group "KABCFields".
+ *
+ * @param identifier The unique identifier
+ */
+ static Field::List restoreFields( const QString &identifier );
+
+ protected:
+ /**
+ * @internal
+ *
+ * Creates a field and appends it to the general list of fields.
+ *
+ * @param id The identifier for the field
+ * @param category The optional category for the field
+ */
+ static void createField( int id, int category = 0 );
+
+ /**
+ * @internal
+ *
+ * Creates a field and appends it to the list of default fields.
+ *
+ * @param id The identifier for the field
+ * @param category The optional category for the field
+ */
+ static void createDefaultField( int id, int category = 0 );
+
+ private:
+ class Private;
+
+ Field( Private * );
+ virtual ~Field();
+
+ Private *const d;
+};
+
+}
+#endif
diff --git a/kabc/format.h b/kabc/format.h
new file mode 100644
index 0000000..c9a296c
--- /dev/null
+++ b/kabc/format.h
@@ -0,0 +1,73 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_FORMAT_H
+#define KABC_FORMAT_H
+
+#include <QtCore/QFile>
+
+#include "plugin.h"
+#include "resource.h"
+
+namespace KABC {
+
+class AddressBook;
+class Addressee;
+
+/**
+ * @short Base class for address book formats.
+ *
+ * This class provides an abstract interface for ResourceFile and
+ * ResourceDir formats.
+ *
+ * @internal
+ */
+class KABC_EXPORT_DEPRECATED Format : public Plugin
+{
+ public:
+
+ /**
+ * Load single addressee from file.
+ */
+ virtual bool load( Addressee &, QFile *file ) = 0;
+
+ /**
+ * Load whole addressbook from file.
+ */
+ virtual bool loadAll( AddressBook *, Resource *, QFile *file ) = 0;
+
+ /**
+ * Save a single Addressee to file.
+ */
+ virtual void save( const Addressee &, QFile *file ) = 0;
+
+ /**
+ * Save whole addressbook to file.
+ */
+ virtual void saveAll( AddressBook *, Resource *, QFile *file ) = 0;
+
+ /**
+ * Checks if given file contains the right format
+ */
+ virtual bool checkFormat( QFile *file ) const = 0;
+};
+
+}
+#endif
diff --git a/kabc/geo.cpp b/kabc/geo.cpp
new file mode 100644
index 0000000..3b6ae16
--- /dev/null
+++ b/kabc/geo.cpp
@@ -0,0 +1,170 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "geo.h"
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+class Geo::Private : public QSharedData
+{
+ public:
+ Private()
+ : mLatitude( 91 ), mLongitude( 181 ),
+ mValidLatitude( false ), mValidLongitude( false )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mLatitude = other.mLatitude;
+ mLongitude = other.mLongitude;
+ mValid = other.mValid;
+ mValidLatitude = other.mValidLatitude;
+ mValidLongitude = other.mValidLongitude;
+ }
+
+ float mLatitude;
+ float mLongitude;
+
+ bool mValid;
+ bool mValidLatitude;
+ bool mValidLongitude;
+};
+
+Geo::Geo()
+ : d( new Private )
+{
+}
+
+Geo::Geo( float latitude, float longitude )
+ : d( new Private )
+{
+ setLatitude( latitude );
+ setLongitude( longitude );
+}
+
+Geo::Geo( const Geo &other )
+ : d( other.d )
+{
+}
+
+Geo::~Geo()
+{
+}
+
+void Geo::setLatitude( float latitude )
+{
+ if ( latitude >= -90 && latitude <= 90 ) {
+ d->mLatitude = latitude;
+ d->mValidLatitude = true;
+ } else {
+ d->mLatitude = 91;
+ d->mValidLatitude = false;
+ }
+}
+
+float Geo::latitude() const
+{
+ return d->mLatitude;
+}
+
+void Geo::setLongitude( float longitude )
+{
+ if ( longitude >= -180 && longitude <= 180 ) {
+ d->mLongitude = longitude;
+ d->mValidLongitude = true;
+ } else {
+ d->mLongitude = 181;
+ d->mValidLongitude = false;
+ }
+}
+
+float Geo::longitude() const
+{
+ return d->mLongitude;
+}
+
+bool Geo::isValid() const
+{
+ return d->mValidLatitude && d->mValidLongitude;
+}
+
+bool Geo::operator==( const Geo &other ) const
+{
+ if ( !other.isValid() && !isValid() ) {
+ return true;
+ }
+
+ if ( !other.isValid() || !isValid() ) {
+ return false;
+ }
+
+ if ( other.d->mLatitude == d->mLatitude && other.d->mLongitude == d->mLongitude ) {
+ return true;
+ }
+
+ return false;
+}
+
+bool Geo::operator!=( const Geo &other ) const
+{
+ return !( *this == other );
+}
+
+Geo &Geo::operator=( const Geo &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+QString Geo::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Geo {\n" );
+ str += QString::fromLatin1( " Valid: %1\n" ).
+ arg( isValid() ? QLatin1String( "true" ) : QLatin1String( "false" ) );
+ str += QString::fromLatin1( " Latitude: %1\n" ).arg( d->mLatitude );
+ str += QString::fromLatin1( " Longitude: %1\n" ).arg( d->mLongitude );
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Geo &geo )
+{
+ return s << geo.d->mLatitude << geo.d->mValidLatitude
+ << geo.d->mLongitude << geo.d->mValidLongitude;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Geo &geo )
+{
+ s >> geo.d->mLatitude >> geo.d->mValidLatitude
+ >> geo.d->mLongitude >> geo.d->mValidLongitude;
+
+ return s;
+}
diff --git a/kabc/geo.h b/kabc/geo.h
new file mode 100644
index 0000000..633ef47
--- /dev/null
+++ b/kabc/geo.h
@@ -0,0 +1,134 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_GEO_H
+#define KABC_GEO_H
+
+#include "kabc_export.h"
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QString>
+
+namespace KABC {
+
+/**
+ * @short Geographic position
+ *
+ * This class represents a geographic position.
+ */
+class KABC_EXPORT Geo
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Geo & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Geo & );
+
+ public:
+ /**
+ * Creates an invalid geographics position object.
+ */
+ Geo();
+
+ /**
+ * Creates a geographics position object.
+ *
+ * @param latitude Geographical latitude
+ * @param longitude Geographical longitude
+ */
+ Geo( float latitude, float longitude );
+
+ /**
+ * Copy constructor.
+ */
+ Geo( const Geo &other );
+
+ /**
+ * Destroys the geographics position object.
+ */
+ ~Geo();
+
+ /**
+ * Sets the @p latitude.
+ *
+ * @param latitude The location's latitude coordinate
+ */
+ void setLatitude( float latitude );
+
+ /**
+ * Returns the latitude.
+ */
+ float latitude() const;
+
+ /**
+ * Sets the @p longitude.
+ *
+ * @param longitude The location's longitude coordinate
+ */
+ void setLongitude( float longitude );
+
+ /**
+ * Returns the longitude.
+ */
+ float longitude() const;
+
+ /**
+ * Returns, whether this object contains a valid geographical position.
+ */
+ bool isValid() const;
+
+ /**
+ * Equality operator.
+ *
+ * @note Two invalid Geo instance will return @c true
+ */
+ bool operator==( const Geo & ) const;
+
+ /**
+ * Not-Equal operator.
+ */
+ bool operator!=( const Geo & ) const;
+
+ /**
+ * Assignment operator.
+ *
+ * @param other The Geo instance to assign to @c this
+ */
+ Geo &operator=( const Geo &other );
+
+ /**
+ * Returns string representation of geographical position.
+ */
+ QString toString() const;
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+/**
+ * Serializes the geographical position @p object into the @p stream.
+ */
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Geo &object );
+
+/**
+ * Initializes the geographical position @p object from the @p stream.
+ */
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Geo &object );
+
+}
+
+#endif
diff --git a/kabc/kabc_export.h b/kabc/kabc_export.h
new file mode 100644
index 0000000..861a9d4
--- /dev/null
+++ b/kabc/kabc_export.h
@@ -0,0 +1,127 @@
+/*
+ This file is part of the kabc library.
+ Copyright (c) 2006-2007 Allen Winter <winter@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_EXPORT_H
+#define KABC_EXPORT_H
+
+#include <kdemacros.h>
+
+#ifndef KABC_EXPORT
+# if defined(KDEPIM_STATIC_LIBS)
+ /* No export/import for static libraries */
+# define KABC_EXPORT
+# elif defined(MAKE_KABC_LIB)
+ /* We are building this library */
+# define KABC_EXPORT KDE_EXPORT
+# else
+ /* We are using this library */
+# define KABC_EXPORT KDE_IMPORT
+# endif
+#endif
+
+#ifndef KABC_FILE_CORE_EXPORT
+# if defined(KDEPIM_STATIC_LIBS)
+ /* No export/import for static libraries */
+# define KABC_FILE_CORE_EXPORT
+# elif defined(MAKE_KABC_FILE_CORE_LIB)
+ /* We are building this library */
+# define KABC_FILE_CORE_EXPORT KDE_EXPORT
+# else
+ /* We are using this library */
+# define KABC_FILE_CORE_EXPORT KDE_IMPORT
+# endif
+#endif
+
+#ifndef KABC_DIR_EXPORT
+# if defined(KDEPIM_STATIC_LIBS)
+ /* No export/import for static libraries */
+# define KABC_DIR_EXPORT
+# elif defined(MAKE_KABC_DIRECTORY_LIB)
+ /* We are building this library */
+# define KABC_DIR_EXPORT KDE_EXPORT
+# else
+ /* We are using this library */
+# define KABC_DIR_EXPORT KDE_IMPORT
+# endif
+#endif
+
+#ifndef KABC_NET_EXPORT
+# if defined(KDEPIM_STATIC_LIBS)
+ /* No export/import for static libraries */
+# define KABC_NET_EXPORT
+# elif defined(MAKE_KABC_NET_LIB)
+ /* We are building this library */
+# define KABC_NET_EXPORT KDE_EXPORT
+# else
+ /* We are using this library */
+# define KABC_NET_EXPORT KDE_IMPORT
+# endif
+#endif
+
+#ifndef KABC_LDAPKIO_EXPORT
+# if defined(KDEPIM_STATIC_LIBS)
+ /* No export/import for static libraries */
+# define KABC_LDAPKIO_EXPORT
+# elif defined(MAKE_KABC_LDAPKIO_LIB)
+ /* We are building this library */
+# define KABC_LDAPKIO_EXPORT KDE_EXPORT
+# else
+ /* We are using this library */
+# define KABC_LDAPKIO_EXPORT KDE_IMPORT
+# endif
+#endif
+
+# ifndef KABC_EXPORT_DEPRECATED
+# if !defined( WANT_DEPRECATED_KABC_API )
+# define KABC_EXPORT_DEPRECATED KDE_DEPRECATED KABC_EXPORT
+# else
+# define KABC_EXPORT_DEPRECATED KABC_EXPORT
+# endif
+# endif
+# ifndef KABC_FILE_CORE_EXPORT_DEPRECATED
+# if !defined( WANT_DEPRECATED_KABC_API )
+# define KABC_FILE_CORE_EXPORT_DEPRECATED KDE_DEPRECATED KABC_FILE_CORE_EXPORT
+# else
+# define KABC_FILE_CORE_EXPORT_DEPRECATED KABC_FILE_CORE_EXPORT
+# endif
+# endif
+# ifndef KABC_DIRECTORY_EXPORT_DEPRECATED
+# if !defined( WANT_DEPRECATED_KABC_API )
+# define KABC_DIRECTORY_EXPORT_DEPRECATED KDE_DEPRECATED KABC_DIRECTORY_EXPORT
+# else
+# define KABC_DIRECTORY_EXPORT_DEPRECATED KABC_DIRECTORY_EXPORT
+# endif
+# endif
+# ifndef KABC_NET_EXPORT_DEPRECATED
+# if !defined( WANT_DEPRECATED_KABC_API )
+# define KABC_NET_EXPORT_DEPRECATED KDE_DEPRECATED KABC_NET_EXPORT
+# else
+# define KABC_NET_EXPORT_DEPRECATED KABC_NET_EXPORT
+# endif
+# endif
+# ifndef KABC_LDAPKIO_EXPORT_DEPRECATED
+# if !defined( WANT_DEPRECATED_KABC_API )
+# define KABC_LDAPKIO_EXPORT_DEPRECATED KDE_DEPRECATED KABC_LDAPKIO_EXPORT
+# else
+# define KABC_LDAPKIO_EXPORT_DEPRECATED KABC_LDAPKIO_EXPORT
+# endif
+# endif
+
+#endif
diff --git a/kabc/key.cpp b/kabc/key.cpp
new file mode 100644
index 0000000..ad78071
--- /dev/null
+++ b/kabc/key.cpp
@@ -0,0 +1,245 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "key.h"
+
+#include <klocale.h>
+#include <krandom.h>
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+class Key::Private : public QSharedData
+{
+ public:
+ Private()
+ : mId( KRandom::randomString( 8 ) )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mId = other.mId;
+ mBinaryData = other.mBinaryData;
+ mTextData = other.mTextData;
+ mCustomTypeString = other.mCustomTypeString;
+ mIsBinary = other.mIsBinary;
+ mType = other.mType;
+ }
+
+ QString mId;
+ QByteArray mBinaryData;
+ QString mTextData;
+ QString mCustomTypeString;
+
+ bool mIsBinary;
+ Type mType;
+};
+
+Key::Key( const QString &text, Type type )
+ : d( new Private )
+{
+ d->mTextData = text;
+ d->mIsBinary = false;
+ d->mType = type;
+}
+
+Key::Key( const Key &other )
+ : d( other.d )
+{
+}
+
+Key::~Key()
+{
+}
+
+bool Key::operator==( const Key &other ) const
+{
+ if ( d->mId != other.d->mId ) {
+ return false;
+ }
+
+ if ( d->mType != other.d->mType ) {
+ return false;
+ }
+
+ if ( d->mIsBinary != other.d->mIsBinary ) {
+ return false;
+ }
+
+ if ( d->mIsBinary ) {
+ if ( d->mBinaryData != other.d->mBinaryData ) {
+ return false;
+ }
+ } else {
+ if ( d->mTextData != other.d->mTextData ) {
+ return false;
+ }
+ }
+
+ if ( d->mCustomTypeString != other.d->mCustomTypeString ) {
+ return false;
+ }
+
+ return true;
+}
+
+bool Key::operator!=( const Key &other ) const
+{
+ return !( *this == other );
+}
+
+Key &Key::operator=( const Key &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+void Key::setId( const QString &id )
+{
+ d->mId = id;
+}
+
+QString Key::id() const
+{
+ return d->mId;
+}
+
+void Key::setBinaryData( const QByteArray &binary )
+{
+ d->mBinaryData = binary;
+ d->mIsBinary = true;
+}
+
+QByteArray Key::binaryData() const
+{
+ return d->mBinaryData;
+}
+
+void Key::setTextData( const QString &text )
+{
+ d->mTextData = text;
+ d->mIsBinary = false;
+}
+
+QString Key::textData() const
+{
+ return d->mTextData;
+}
+
+bool Key::isBinary() const
+{
+ return d->mIsBinary;
+}
+
+void Key::setType( Type type )
+{
+ d->mType = type;
+}
+
+void Key::setCustomTypeString( const QString &custom )
+{
+ d->mCustomTypeString = custom;
+}
+
+Key::Type Key::type() const
+{
+ return d->mType;
+}
+
+QString Key::customTypeString() const
+{
+ return d->mCustomTypeString;
+}
+
+QString Key::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Key {\n" );
+ str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId );
+ str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) );
+ if ( d->mType == Custom ) {
+ str += QString::fromLatin1( " CustomType: %1\n" ).arg( d->mCustomTypeString );
+ }
+ str += QString::fromLatin1( " IsBinary: %1\n" ).
+ arg( d->mIsBinary ? QLatin1String( "true" ) : QLatin1String( "false" ) );
+ if ( d->mIsBinary ) {
+ str += QString::fromLatin1( " Binary: %1\n" ).
+ arg( QString::fromLatin1( d->mBinaryData.toBase64() ) );
+ } else {
+ str += QString::fromLatin1( " Text: %1\n" ).arg( d->mTextData );
+ }
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+Key::TypeList Key::typeList()
+{
+ static TypeList list;
+
+ if ( list.isEmpty() ) {
+ list << X509 << PGP << Custom;
+ }
+
+ return list;
+}
+
+QString Key::typeLabel( Type type )
+{
+ switch ( type ) {
+ case X509:
+ return i18nc( "X.509 public key", "X509" );
+ break;
+ case PGP:
+ return i18nc( "Pretty Good Privacy key", "PGP" );
+ break;
+ case Custom:
+ return i18nc( "A custom key", "Custom" );
+ break;
+ default:
+ return i18nc( "another type of encryption key", "Unknown type" );
+ break;
+ }
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Key &key )
+{
+ return s << key.d->mId << key.d->mType << key.d->mIsBinary << key.d->mBinaryData
+ << key.d->mTextData << key.d->mCustomTypeString;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Key &key )
+{
+ uint type;
+ s >> key.d->mId >> type >> key.d->mIsBinary >> key.d->mBinaryData >> key.d->mTextData
+ >> key.d->mCustomTypeString;
+
+ key.d->mType = Key::Type( type );
+
+ return s;
+}
diff --git a/kabc/key.h b/kabc/key.h
new file mode 100644
index 0000000..679e7a2
--- /dev/null
+++ b/kabc/key.h
@@ -0,0 +1,185 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_KEY_H
+#define KABC_KEY_H
+
+#include "kabc_export.h"
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedDataPointer>
+
+namespace KABC {
+
+/**
+ * @short A class to store an encryption key.
+ */
+class KABC_EXPORT Key
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Key & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Key & );
+
+ public:
+ /**
+ List of keys.
+ */
+ typedef QList<Key> List;
+
+ /**
+ Key types
+ */
+ enum Type {
+ X509, /**< X509 key */
+ PGP, /**< Pretty Good Privacy key */
+ Custom /**< Custom or IANA conform key */
+ };
+
+ /**
+ List of key types.
+ */
+ typedef QList<Type> TypeList;
+
+ /**
+ Creates a new key.
+
+ @param text The text data.
+ @param type The key type, see Types.
+ */
+ explicit Key( const QString &text = QString(), Type type = PGP );
+
+ /**
+ Copy constructor.
+ */
+ Key( const Key &other );
+
+ /**
+ Destroys the key.
+ */
+ ~Key();
+
+ /**
+ Equality operator.
+ */
+ bool operator==( const Key & ) const;
+
+ /**
+ Not-equal operator.
+ */
+ bool operator!=( const Key & ) const;
+
+ /**
+ Assignment operator.
+
+ @param other The Key instance to assign to @c this
+ */
+ Key &operator=( const Key &other );
+
+ /**
+ Sets the unique @p identifier.
+ */
+ void setId( const QString &identifier );
+
+ /**
+ Returns the unique identifier.
+ */
+ QString id() const;
+
+ /**
+ Sets binary @p data.
+ */
+ void setBinaryData( const QByteArray &data );
+
+ /**
+ Returns the binary data.
+ */
+ QByteArray binaryData() const;
+
+ /**
+ Sets text @p data.
+ */
+ void setTextData( const QString &data );
+
+ /**
+ Returns the text data.
+ */
+ QString textData() const;
+
+ /**
+ Returns whether the key contains binary or text data.
+ */
+ bool isBinary() const;
+
+ /**
+ Sets the @p type.
+
+ @param type The type of the key
+
+ @see Type
+ */
+ void setType( Type type );
+
+ /**
+ Sets custom @p type string.
+ */
+ void setCustomTypeString( const QString &type );
+
+ /**
+ Returns the type, see Type.
+ */
+ Type type() const;
+
+ /**
+ Returns the custom type string.
+ */
+ QString customTypeString() const;
+
+ /**
+ Returns a string representation of the key.
+ */
+ QString toString() const;
+
+ /**
+ Returns a list of all available key types.
+ */
+ static TypeList typeList();
+
+ /**
+ Returns a translated label for a given key @p type.
+ */
+ static QString typeLabel( Type type );
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+/**
+ Serializes the @p key object into the @p stream.
+*/
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Key &key );
+
+/**
+ Initializes the @p key object from the @p stream.
+*/
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Key &key );
+
+}
+
+#endif
diff --git a/kabc/ldapdn.cpp b/kabc/ldapdn.cpp
new file mode 100644
index 0000000..2b2a733
--- /dev/null
+++ b/kabc/ldapdn.cpp
@@ -0,0 +1,209 @@
+/*
+ A temporary copy to break dependency to KLDAP
+
+ This file is part of libkldap.
+ Copyright (c) 2006 Sean Harmer <sh@theharmers.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "ldapdn_p.h"
+
+#include <algorithm>
+
+#include <kdebug.h>
+
+class LdapDN::LdapDNPrivate
+{
+ public:
+ LdapDNPrivate() : m_dn() {}
+ ~LdapDNPrivate() {}
+
+ bool isValidRDNString( const QString &rdn ) const;
+ QStringList splitOnNonEscapedChar( const QString &rdn, const QChar &ch ) const;
+
+ QString m_dn;
+};
+
+bool LdapDN::LdapDNPrivate::isValidRDNString( const QString &rdn ) const
+{
+ kDebug() << "Testing rdn:" << rdn;
+
+ // If it is a muli-valued rdn, split it into its constituent parts
+ QStringList rdnParts = splitOnNonEscapedChar( rdn, QLatin1Char( '+' ) );
+ if ( rdnParts.size() > 1 ) {
+ for ( int i = 0; i < rdnParts.size(); i++ ) {
+ if ( !isValidRDNString( rdnParts.at( i ) ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Split the rdn into the attribute name and value parts
+ QStringList components = rdn.split( QLatin1Char( '=' ) );
+
+ // We should have exactly two parts
+ if ( components.size() != 2 ) {
+ return false;
+ }
+
+ return true;
+}
+
+QStringList LdapDN::LdapDNPrivate::splitOnNonEscapedChar( const QString &str,
+ const QChar &ch ) const
+{
+ QStringList strParts;
+ int index = 0;
+ int searchFrom = 0;
+ int strPartStartIndex = 0;
+ while ( ( index = str.indexOf( ch, searchFrom ) ) != -1 ) {
+ const QChar prev = str[std::max( 0, index - 1 )];
+ if ( prev != QLatin1Char( '\\' ) ) {
+ // Found a component of a multi-valued RDN
+ //kDebug() << "Found" << ch << "at index" << index;
+ QString tmp = str.mid( strPartStartIndex, index - strPartStartIndex );
+ //kDebug() << "Adding part:" << tmp;
+ strParts.append( tmp );
+ strPartStartIndex = index + 1;
+ }
+
+ searchFrom = index + 1;
+ }
+
+ // Add on the part after the last found delimeter
+ QString tmp = str.mid( strPartStartIndex );
+ //kDebug() << "Adding part:" << tmp;
+ strParts.append( tmp );
+
+ return strParts;
+}
+
+LdapDN::LdapDN()
+ : d( new LdapDNPrivate )
+{
+
+}
+
+LdapDN::LdapDN( const QString &dn )
+ : d( new LdapDNPrivate )
+{
+ d->m_dn = dn;
+}
+
+LdapDN::LdapDN( const LdapDN &that )
+ : d( new LdapDNPrivate )
+{
+ *d = *that.d;
+}
+
+LdapDN &LdapDN::operator=( const LdapDN &that )
+{
+ if ( this == &that ) {
+ return *this;
+ }
+
+ *d = *that.d;
+ return *this;
+}
+
+LdapDN::~LdapDN()
+{
+ delete d;
+}
+
+void LdapDN::clear()
+{
+ d->m_dn.clear();
+}
+
+bool LdapDN::isEmpty() const
+{
+ return d->m_dn.isEmpty();
+}
+
+QString LdapDN::toString() const
+{
+ return d->m_dn;
+}
+
+QString LdapDN::toString( int depth ) const
+{
+ QStringList rdns = d->splitOnNonEscapedChar( d->m_dn, QLatin1Char( ',' ) );
+ if ( depth >= rdns.size() ) {
+ return QString();
+ }
+
+ // Construct a DN down to the requested depth
+ QString dn;
+ for ( int i = depth; i >= 0; i-- ) {
+ dn += rdns.at( rdns.size() - 1 - i ) + QLatin1Char( ',' );
+ kDebug() << "dn =" << dn;
+ }
+ dn = dn.left( dn.length() - 1 ); // Strip off the extraneous comma
+
+ return dn;
+}
+
+QString LdapDN::rdnString() const
+{
+ /** \TODO We should move this into the d pointer as we calculate rdns quite a lot */
+ QStringList rdns = d->splitOnNonEscapedChar( d->m_dn, QLatin1Char( ',' ) );
+ return rdns.at( 0 );
+}
+
+QString LdapDN::rdnString( int depth ) const
+{
+ QStringList rdns = d->splitOnNonEscapedChar( d->m_dn, QLatin1Char( ',' ) );
+ if ( depth >= rdns.size() ) {
+ return QString();
+ }
+ return rdns.at( rdns.size() - 1 - depth );
+}
+
+bool LdapDN::isValid() const
+{
+ kDebug() << "Testing dn:" << d->m_dn;
+
+ // Break the string into rdn's
+ QStringList rdns = d->splitOnNonEscapedChar( d->m_dn, QLatin1Char( ',' ) );
+
+ // Test to see if each rdn is valid
+ for ( int i = 0; i < rdns.size(); i++ ) {
+ if ( !d->isValidRDNString( rdns.at( i ) ) ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int LdapDN::depth() const
+{
+ QStringList rdns = d->splitOnNonEscapedChar( d->m_dn, QLatin1Char( ',' ) );
+ return rdns.size();
+}
+
+bool LdapDN::operator == ( const LdapDN &rhs ) const
+{
+ return d->m_dn == rhs.d->m_dn;
+}
+
+bool LdapDN::operator != ( const LdapDN &rhs ) const
+{
+ return d->m_dn != rhs.d->m_dn;
+}
diff --git a/kabc/ldapdn_p.h b/kabc/ldapdn_p.h
new file mode 100644
index 0000000..f765ee1
--- /dev/null
+++ b/kabc/ldapdn_p.h
@@ -0,0 +1,84 @@
+/*
+ A temporary copy to break dependency to KLDAP
+
+ This file is part of libkldap.
+ Copyright (c) 2006 Sean Harmer <sh@theharmers.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef LDAPDN_P_H
+#define LDAPDN_P_H
+
+#include <QtCore/QStringList>
+
+class LdapDN
+{
+ public:
+ explicit LdapDN();
+ explicit LdapDN( const QString &dn );
+
+ LdapDN( const LdapDN &that );
+ LdapDN &operator=( const LdapDN &that );
+
+ ~LdapDN();
+
+ void clear();
+
+ bool isEmpty() const;
+
+ /**
+ * \returns A QString representing the DN.
+ */
+ QString toString() const;
+
+ /**
+ * \param depth The depth of the DN to return using a zero-based index.
+ * \returns A QString representing the DN levels deep in the directory.
+ */
+ QString toString( int depth ) const;
+
+ /**
+ * \returns A QString representing the RDN of this DN.
+ */
+ QString rdnString() const;
+
+ /**
+ * \param depth The depth of the RDN to return using a zero-based index.
+ * \returns A QString representing the RDN levels deep in the directory.
+ */
+ QString rdnString( int depth ) const;
+
+ /**
+ * \returns True if this is a valid DN, false otherwise.
+ */
+ bool isValid() const;
+
+ /**
+ * \returns The depth of this DN in the directory.
+ */
+ int depth() const;
+
+ bool operator == ( const LdapDN &rhs ) const;
+
+ bool operator != ( const LdapDN &rhs ) const;
+
+ private:
+ class LdapDNPrivate;
+ LdapDNPrivate *const d;
+};
+
+#endif
diff --git a/kabc/ldif.cpp b/kabc/ldif.cpp
new file mode 100644
index 0000000..19addd9
--- /dev/null
+++ b/kabc/ldif.cpp
@@ -0,0 +1,451 @@
+/*
+ A temporary copy to break dependency to KLDAP
+
+ This file is part of libkldap.
+ Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "ldif_p.h"
+
+#include <kdebug.h>
+
+class Ldif::LdifPrivate
+{
+ public:
+ int mModType;
+ bool mDelOldRdn, mUrl;
+ LdapDN mDn;
+ QString mAttr, mNewRdn, mNewSuperior, mOid;
+ QByteArray mLdif, mValue;
+ EntryType mEntryType;
+
+ bool mIsNewLine, mIsComment, mCritical;
+ ParseValue mLastParseValue;
+ uint mPos, mLineNumber;
+ QByteArray mLine;
+};
+
+Ldif::Ldif() : d( new LdifPrivate )
+{
+ startParsing();
+}
+
+Ldif::Ldif( const Ldif &that ) : d( new LdifPrivate )
+{
+ *d = *that.d;
+
+ startParsing();
+}
+
+Ldif &Ldif::operator=( const Ldif &that )
+{
+ if ( this == &that ) {
+ return *this;
+ }
+
+ *d = *that.d;
+
+ return *this;
+}
+
+Ldif::~Ldif()
+{
+ delete d;
+}
+
+QByteArray Ldif::assembleLine( const QString &fieldname,
+ const QByteArray &value,
+ uint linelen, bool url )
+{
+ bool safe = false;
+ bool isDn;
+ QByteArray result;
+
+ if ( url ) {
+ result = fieldname.toUtf8() + ":< " + value;
+ } else {
+ isDn = fieldname.toLower() == QLatin1String( "dn" );
+ //SAFE-INIT-CHAR
+ if ( value.size() > 0 && value[0] > 0 && value[0] != '\n' &&
+ value[0] != '\r' && value[0] != ':' && value[0] != '<' ) safe = true;
+
+ //SAFE-CHAR
+ if ( safe ) {
+ for ( int i=1; i < value.size(); i++ ) {
+ //allow utf-8 in Distinguished Names
+ if ( ( isDn && value[i] == 0 ) ||
+ ( !isDn && value[i] <= 0 ) ||
+ value[i] == '\r' || value[i] == '\n' ) {
+ safe = false;
+ break;
+ }
+ }
+ }
+
+ if ( value.size() == 0 ) {
+ safe = true;
+ }
+
+ if ( safe ) {
+ result = fieldname.toUtf8() + ": " + value;
+ } else {
+ result = fieldname.toUtf8() + ":: " + value.toBase64();
+ }
+
+ if ( linelen > 0 ) {
+ int i = (uint)( fieldname.length() + 2 ) > linelen ? fieldname.length() + 2 : linelen;
+ while ( i < result.length() ) {
+ result.insert( i, "\n " );
+ i += linelen+2;
+ }
+ }
+ }
+ return result;
+}
+
+QByteArray Ldif::assembleLine( const QString &fieldname, const QString &value,
+ uint linelen, bool url )
+{
+ return assembleLine( fieldname, value.toUtf8(), linelen, url );
+}
+
+bool Ldif::splitLine( const QByteArray &line, QString &fieldname, QByteArray &value )
+{
+ int position;
+ QByteArray tmp;
+ int linelen;
+
+// kDebug() << "line:" << QString::fromUtf8(line);
+
+ position = line.indexOf( ":" );
+ if ( position == -1 ) {
+ // strange: we did not find a fieldname
+ fieldname = QLatin1String( "" );
+ value = line.trimmed();
+// kDebug() << "value :" << value[0];
+ return false;
+ }
+
+ linelen = line.size();
+ fieldname = QString::fromUtf8( line.left( position ).trimmed() );
+
+ if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) {
+ // String is BASE64 encoded -> decode it now.
+ if ( linelen <= ( position + 3 ) ) {
+ value.resize( 0 );
+ return false;
+ }
+ value = QByteArray::fromBase64( line.mid( position + 3 ) );
+ return false;
+ }
+
+ if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) {
+ // String is an URL.
+ if ( linelen <= ( position + 3 ) ) {
+ value.resize( 0 );
+ return false;
+ }
+ value = QByteArray::fromBase64( line.mid( position + 3 ) );
+ return true;
+ }
+
+ if ( linelen <= ( position + 2 ) ) {
+ value.resize( 0 );
+ return false;
+ }
+ value = line.mid( position + 2 );
+ return false;
+}
+
+bool Ldif::splitControl( const QByteArray &line, QString &oid, bool &critical,
+ QByteArray &value )
+{
+ QString tmp;
+ critical = false;
+ bool url = splitLine( line, tmp, value );
+
+ kDebug() << "value:" << QString::fromUtf8( value, value.size() );
+ if ( tmp.isEmpty() ) {
+ tmp = QString::fromUtf8( value, value.size() );
+ value.resize( 0 );
+ }
+ if ( tmp.endsWith( QLatin1String( "true" ) ) ) {
+ critical = true;
+ tmp.truncate( tmp.length() - 5 );
+ } else if ( tmp.endsWith( QLatin1String( "false" ) ) ) {
+ critical = false;
+ tmp.truncate( tmp.length() - 6 );
+ }
+ oid = tmp;
+ return url;
+}
+
+Ldif::ParseValue Ldif::processLine()
+{
+
+ if ( d->mIsComment ) {
+ return None;
+ }
+
+ ParseValue retval = None;
+ if ( d->mLastParseValue == EndEntry ) {
+ d->mEntryType = Entry_None;
+ }
+
+ d->mUrl = splitLine( d->mLine, d->mAttr, d->mValue );
+
+ QString attrLower = d->mAttr.toLower();
+
+ switch ( d->mEntryType ) {
+ case Entry_None:
+ if ( attrLower == QLatin1String( "version" ) ) {
+ if ( !d->mDn.isEmpty() ) {
+ retval = Err;
+ }
+ } else if ( attrLower == QLatin1String( "dn" ) ) {
+ kDebug() << "ldapentry dn:" << QString::fromUtf8( d->mValue, d->mValue.size() );
+ d->mDn = LdapDN( QString::fromUtf8( d->mValue, d->mValue.size() ) );
+ d->mModType = Mod_None;
+ retval = NewEntry;
+ } else if ( attrLower == QLatin1String( "changetype" ) ) {
+ if ( d->mDn.isEmpty() ) {
+ retval = Err;
+ } else {
+ QString tmpval = QString::fromUtf8( d->mValue, d->mValue.size() );
+ kDebug() << "changetype:" << tmpval;
+ if ( tmpval == QLatin1String( "add" ) ) {
+ d->mEntryType = Entry_Add;
+ } else if ( tmpval == QLatin1String( "delete" ) ) {
+ d->mEntryType = Entry_Del;
+ } else if ( tmpval == QLatin1String( "modrdn" ) || tmpval == QLatin1String( "moddn" ) ) {
+ d->mNewRdn = QLatin1String( "" );
+ d->mNewSuperior = QLatin1String( "" );
+ d->mDelOldRdn = true;
+ d->mEntryType = Entry_Modrdn;
+ } else if ( tmpval == QLatin1String( "modify" ) ) {
+ d->mEntryType = Entry_Mod;
+ } else {
+ retval = Err;
+ }
+ }
+ } else if ( attrLower == QLatin1String( "control" ) ) {
+ d->mUrl = splitControl( d->mValue, d->mOid, d->mCritical, d->mValue );
+ retval = Control;
+ } else if ( !d->mAttr.isEmpty() && d->mValue.size() > 0 ) {
+ d->mEntryType = Entry_Add;
+ retval = Item;
+ }
+ break;
+ case Entry_Add:
+ if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
+ retval = EndEntry;
+ } else {
+ retval = Item;
+ }
+ break;
+ case Entry_Del:
+ if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
+ retval = EndEntry;
+ } else {
+ retval = Err;
+ }
+ break;
+ case Entry_Mod:
+ if ( d->mModType == Mod_None ) {
+ kDebug() << "new modtype" << d->mAttr;
+ if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
+ retval = EndEntry;
+ } else if ( attrLower == QLatin1String( "add" ) ) {
+ d->mModType = Mod_Add;
+ } else if ( attrLower == QLatin1String( "replace" ) ) {
+ d->mModType = Mod_Replace;
+ d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
+ d->mValue = QByteArray();
+ retval = Item;
+ } else if ( attrLower == QLatin1String( "delete" ) ) {
+ d->mModType = Mod_Del;
+ d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
+ d->mValue = QByteArray();
+ retval = Item;
+ } else {
+ retval = Err;
+ }
+ } else {
+ if ( d->mAttr.isEmpty() ) {
+ if ( QString::fromUtf8( d->mValue, d->mValue.size() ) == QLatin1String( "-" ) ) {
+ d->mModType = Mod_None;
+ } else if ( d->mValue.size() == 0 ) {
+ retval = EndEntry;
+ } else {
+ retval = Err;
+ }
+ } else {
+ retval = Item;
+ }
+ }
+ break;
+ case Entry_Modrdn:
+ if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
+ retval = EndEntry;
+ } else if ( attrLower == QLatin1String( "newrdn" ) ) {
+ d->mNewRdn = QString::fromUtf8( d->mValue, d->mValue.size() );
+ } else if ( attrLower == QLatin1String( "newsuperior" ) ) {
+ d->mNewSuperior = QString::fromUtf8( d->mValue, d->mValue.size() );
+ } else if ( attrLower == QLatin1String( "deleteoldrdn" ) ) {
+ if ( d->mValue.size() > 0 && d->mValue[0] == '0' ) {
+ d->mDelOldRdn = false;
+ } else if ( d->mValue.size() > 0 && d->mValue[0] == '1' ) {
+ d->mDelOldRdn = true;
+ } else {
+ retval = Err;
+ }
+ } else {
+ retval = Err;
+ }
+ break;
+ }
+ return retval;
+}
+
+Ldif::ParseValue Ldif::nextItem()
+{
+ ParseValue retval = None;
+ char c=0;
+
+ while ( retval == None ) {
+ if ( d->mPos < (uint)d->mLdif.size() ) {
+ c = d->mLdif[d->mPos];
+ d->mPos++;
+ if ( d->mIsNewLine && c == '\r' ) {
+ continue; //handle \n\r line end
+ }
+ if ( d->mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding
+ d->mIsNewLine = false;
+ continue;
+ }
+ if ( d->mIsNewLine ) {
+ d->mIsNewLine = false;
+ retval = processLine();
+ d->mLastParseValue = retval;
+ d->mLine.resize( 0 );
+ d->mIsComment = ( c == '#' );
+ }
+ if ( c == '\n' || c == '\r' ) {
+ d->mLineNumber++;
+ d->mIsNewLine = true;
+ continue;
+ }
+ } else {
+ retval = MoreData;
+ break;
+ }
+
+ if ( !d->mIsComment ) {
+ d->mLine += c;
+ }
+ }
+ return retval;
+}
+
+void Ldif::endLdif()
+{
+ QByteArray tmp( 3, '\n' );
+ d->mLdif = tmp;
+ d->mPos = 0;
+}
+
+void Ldif::startParsing()
+{
+ d->mPos = d->mLineNumber = 0;
+ d->mDelOldRdn = false;
+ d->mEntryType = Entry_None;
+ d->mModType = Mod_None;
+ d->mDn = LdapDN();
+ d->mNewRdn.clear();
+ d->mNewSuperior.clear();
+ d->mLine = QByteArray();
+ d->mIsNewLine = false;
+ d->mIsComment = false;
+ d->mLastParseValue = None;
+}
+
+void Ldif::setLdif( const QByteArray &ldif )
+{
+ d->mLdif = ldif;
+ d->mPos = 0;
+}
+
+Ldif::EntryType Ldif::entryType() const
+{
+ return d->mEntryType;
+}
+
+int Ldif::modType() const
+{
+ return d->mModType;
+}
+
+LdapDN Ldif::dn() const
+{
+ return d->mDn;
+}
+
+QString Ldif::newRdn() const
+{
+ return d->mNewRdn;
+}
+
+QString Ldif::newSuperior() const
+{
+ return d->mNewSuperior;
+}
+
+bool Ldif::delOldRdn() const
+{
+ return d->mDelOldRdn;
+}
+
+QString Ldif::attr() const
+{
+ return d->mAttr;
+}
+
+QByteArray Ldif::value() const
+{
+ return d->mValue;
+}
+
+bool Ldif::isUrl() const
+{
+ return d->mUrl;
+}
+
+bool Ldif::isCritical() const
+{
+ return d->mCritical;
+}
+
+QString Ldif::oid() const
+{
+ return d->mOid;
+}
+
+uint Ldif::lineNumber() const
+{
+ return d->mLineNumber;
+}
diff --git a/kabc/ldif_p.h b/kabc/ldif_p.h
new file mode 100644
index 0000000..739427f
--- /dev/null
+++ b/kabc/ldif_p.h
@@ -0,0 +1,197 @@
+/*
+ A temporary copy to break dependency to KLDAP
+
+ This file is part of libkldap.
+ Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef LDIF_P_H
+#define LDIF_P_H
+
+#include <QtCore/QString>
+#include <QtCore/QByteArray>
+
+#include "ldapdn_p.h"
+
+/**
+ * Ldif
+ *
+ * Ldif implements an RFC 2849 compliant Ldif parser. Ldif files are used to
+ * represent directory information on LDAP-based servers, or to describe a set
+ * of changes which are to be applied to a directory.
+ */
+class Ldif
+{
+ public:
+
+ typedef enum {
+ None, NewEntry, EndEntry, Item, Control, Err, MoreData
+ } ParseValue;
+
+ typedef enum {
+ Entry_None, Entry_Add, Entry_Del, Entry_Mod, Entry_Modrdn
+ } EntryType;
+
+ typedef enum {
+ Mod_None, Mod_Add, Mod_Replace, Mod_Del
+ } ModType;
+
+ Ldif();
+
+ Ldif( const Ldif &that );
+ Ldif &operator=( const Ldif &that );
+
+ virtual ~Ldif();
+
+ /**
+ * Assembles fieldname and value into a valid Ldif line, BASE64 encodes the
+ * value if necessary and optionally splits into more lines.
+ * @param fieldname The name of the entry.
+ * @param value The value of the entry.
+ * @param linelen Maximum length of the lines in the result.
+ * @param url If true, encode value as url ( use :< ).
+ */
+ static QByteArray assembleLine( const QString &fieldname,
+ const QByteArray &value, uint linelen=0,
+ bool url=false );
+ /**
+ * This is the same as the above function, the only difference that
+ * this accepts QString as the value.
+ */
+ static QByteArray assembleLine( const QString &fieldname,
+ const QString &value, uint linelen=0,
+ bool url=false );
+
+ /**
+ * Splits one line from an Ldif file to attribute and value components.
+ * @return true if value is an URL, false otherwise
+ */
+ static bool splitLine( const QByteArray &line, QString &fieldname,
+ QByteArray &value );
+
+ /**
+ * Splits a control specification (without the "control:" directive)
+ * @param line is the control directive
+ * @param oid will contain the OID
+ * @param critical will contain the criticality of control
+ * @param value is the control value
+ */
+ static bool splitControl( const QByteArray &line, QString &oid,
+ bool &critical, QByteArray &value );
+
+ /**
+ * Starts the parsing of a new Ldif
+ */
+ void startParsing();
+
+ /**
+ * Process one Ldif line
+ */
+ ParseValue processLine();
+
+ /**
+ * Process the Ldif until a complete item can be returned
+ * @return NewEntry if a new DN encountered, Item if a new item returned,
+ * Err if the Ldif contains error, EndEntry if the parser reached the end
+ * of the current entry and MoreData if the parser encountered the end of
+ * the current chunk of the Ldif.
+ *
+ * If you want to finish the parsing after receiving MoreData, then call
+ * endLdif(), so the parser can safely flush the current entry.
+ */
+ ParseValue nextItem();
+
+ /**
+ * Sets a chunk of Ldif. Call before startParsing(), or if nextItem()
+ * returned MoreData.
+ */
+ void setLdif( const QByteArray &ldif );
+
+ /**
+ * Indicates the end of the Ldif file/stream. Call if nextItem() returned
+ * MoreData, but actually you don't have more data.
+ */
+ void endLdif();
+
+ /**
+ * Returns the requested LDAP operation extracted from the current entry.
+ */
+ EntryType entryType() const;
+
+ /**
+ * Returns the LDAP modify request type if entryType() returned Entry_Mod.
+ */
+ int modType() const;
+
+ /**
+ * Returns the Distinguished Name of the current entry.
+ */
+ LdapDN dn() const;
+
+ /**
+ * Returns the new Relative Distinguished Name if modType() returned
+ * Entry_Modrdn.
+ */
+ QString newRdn() const;
+
+ /**
+ * Returns the new parent of the entry if modType() returned Entry_Modrdn.
+ */
+ QString newSuperior() const;
+
+ /**
+ * Returns if the delete of the old RDN is required.
+ */
+ bool delOldRdn() const;
+
+ /**
+ * Returns the attribute name.
+ */
+ QString attr() const;
+
+ /**
+ * Returns the attribute value.
+ */
+ QByteArray value() const;
+
+ /**
+ * Returns if val() is an url
+ */
+ bool isUrl() const;
+
+ /**
+ * Returns the criticality level when modType() returned Control.
+ */
+ bool isCritical() const;
+
+ /**
+ * Returns the OID when modType() returned Control.
+ */
+ QString oid() const;
+
+ /**
+ * Returns the line number which the parser processes.
+ */
+ uint lineNumber() const;
+
+ private:
+ class LdifPrivate;
+ LdifPrivate *const d;
+};
+
+#endif
diff --git a/kabc/ldifconverter.cpp b/kabc/ldifconverter.cpp
new file mode 100644
index 0000000..b425ce2
--- /dev/null
+++ b/kabc/ldifconverter.cpp
@@ -0,0 +1,561 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Helge Deller <deller@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/*
+ Useful links:
+ - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html
+ - http://www.faqs.org/rfcs/rfc2849.html
+
+ Not yet handled items:
+ - objectclass microsoftaddressbook
+ - info,
+ - initials,
+ - otherfacsimiletelephonenumber,
+ - otherpager,
+ - physicaldeliveryofficename,
+*/
+
+#include "ldifconverter.h"
+#include "vcardconverter.h"
+#include "address.h"
+#include "addressee.h"
+
+#include "ldif_p.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QStringList>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+using namespace KABC;
+
+/* generate LDIF stream */
+
+bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str )
+{
+ AddresseeList::ConstIterator it;
+ AddresseeList::ConstIterator end( addrList.constEnd() );
+ for ( it = addrList.constBegin(); it != end; ++it ) {
+ addresseeToLDIF( *it, str );
+ }
+ return true;
+}
+
+static void ldif_out( QTextStream &t, const QString &formatStr,
+ const QString &value )
+{
+ if ( value.isEmpty() ) {
+ return;
+ }
+
+ const QByteArray txt = Ldif::assembleLine( formatStr, value, 72 );
+
+ // write the string
+ t << QString::fromUtf8( txt ) << "\n";
+}
+
+bool LDIFConverter::addresseeToLDIF( const Addressee &addr, QString &str )
+{
+ if ( addr.isEmpty() ) {
+ return false;
+ }
+
+ QTextStream t( &str, QIODevice::WriteOnly|QIODevice::Append );
+ t.setCodec( QTextCodec::codecForName( "UTF-8" ) );
+
+ const Address homeAddr = addr.address( Address::Home );
+ const Address workAddr = addr.address( Address::Work );
+
+ ldif_out( t, QLatin1String( "dn" ), QString::fromLatin1( "cn=%1,mail=%2" ).
+ arg( addr.formattedName().simplified() ).
+ arg( addr.preferredEmail() ) );
+ ldif_out( t, QLatin1String( "givenname" ), addr.givenName() );
+ ldif_out( t, QLatin1String( "sn" ), addr.familyName() );
+ ldif_out( t, QLatin1String( "cn" ), addr.formattedName().simplified() );
+ ldif_out( t, QLatin1String( "uid" ), addr.uid() );
+ ldif_out( t, QLatin1String( "nickname" ), addr.nickName() );
+ ldif_out( t, QLatin1String( "xmozillanickname" ), addr.nickName() );
+ ldif_out( t, QLatin1String( "mozillanickname" ), addr.nickName() );
+
+ ldif_out( t, QLatin1String( "mail" ), addr.preferredEmail() );
+ if ( addr.emails().count() > 1 ) {
+ ldif_out( t, QLatin1String( "mozillasecondemail" ), addr.emails()[ 1 ] );
+ }
+//ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" );
+
+ ldif_out( t, QLatin1String( "telephonenumber" ),
+ addr.phoneNumber( PhoneNumber::Work ).number() );
+ ldif_out( t, QLatin1String( "facsimiletelephonenumber" ),
+ addr.phoneNumber( PhoneNumber::Fax ).number() );
+ ldif_out( t, QLatin1String( "homephone" ),
+ addr.phoneNumber( PhoneNumber::Home ).number() );
+ ldif_out( t, QLatin1String( "mobile" ),
+ addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7
+ ldif_out( t, QLatin1String( "cellphone" ),
+ addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x
+ ldif_out( t, QLatin1String( "pager" ),
+ addr.phoneNumber( PhoneNumber::Pager ).number() );
+ ldif_out( t, QLatin1String( "pagerphone" ),
+ addr.phoneNumber( PhoneNumber::Pager ).number() );
+
+ ldif_out( t, QLatin1String( "streethomeaddress" ), homeAddr.street() );
+ ldif_out( t, QLatin1String( "postalcode" ), workAddr.postalCode() );
+ ldif_out( t, QLatin1String( "postofficebox" ), workAddr.postOfficeBox() );
+
+ QStringList streets = homeAddr.street().split( QLatin1Char( '\n' ) );
+ if ( streets.count() > 0 ) {
+ ldif_out( t, QLatin1String( "homepostaladdress" ), streets[ 0 ] ); // Netscape 7
+ }
+ if ( streets.count() > 1 ) {
+ ldif_out( t, QLatin1String( "mozillahomepostaladdress2" ), streets[ 1 ] ); // Netscape 7
+ }
+ ldif_out( t, QLatin1String( "mozillahomelocalityname" ), homeAddr.locality() ); // Netscape 7
+ ldif_out( t, QLatin1String( "mozillahomestate" ), homeAddr.region() );
+ ldif_out( t, QLatin1String( "mozillahomepostalcode" ), homeAddr.postalCode() );
+ ldif_out( t, QLatin1String( "mozillahomecountryname" ),
+ Address::ISOtoCountry( homeAddr.country() ) );
+ ldif_out( t, QLatin1String( "locality" ), workAddr.locality() );
+ ldif_out( t, QLatin1String( "streetaddress" ), workAddr.street() ); // Netscape 4.x
+
+ streets = workAddr.street().split( QLatin1Char( '\n' ) );
+ if ( streets.count() > 0 ) {
+ ldif_out( t, QLatin1String( "postaladdress" ), streets[ 0 ] );
+ }
+ if ( streets.count() > 1 ) {
+ ldif_out( t, QLatin1String( "mozillapostaladdress2" ), streets[ 1 ] );
+ }
+ ldif_out( t, QLatin1String( "countryname" ), Address::ISOtoCountry( workAddr.country() ) );
+ ldif_out( t, QLatin1String( "l" ), workAddr.locality() );
+ ldif_out( t, QLatin1String( "c" ), Address::ISOtoCountry( workAddr.country() ) );
+ ldif_out( t, QLatin1String( "st" ), workAddr.region() );
+
+ ldif_out( t, QLatin1String( "title" ), addr.title() );
+ ldif_out( t, QLatin1String( "vocation" ), addr.prefix() );
+ ldif_out( t, QLatin1String( "ou" ), addr.role() );
+ ldif_out( t, QLatin1String( "o" ), addr.organization() );
+ ldif_out( t, QLatin1String( "organization" ), addr.organization() );
+ ldif_out( t, QLatin1String( "organizationname" ), addr.organization() );
+
+ // Compatibility with older kabc versions.
+ if ( !addr.department().isEmpty() ) {
+ ldif_out( t, QLatin1String( "department" ), addr.department() );
+ } else {
+ ldif_out( t, QLatin1String( "department" ), addr.custom( QLatin1String( "KADDRESSBOOK" ),
+ QLatin1String( "X-Department" ) ) );
+ }
+
+ ldif_out( t, QLatin1String( "workurl" ), addr.url().prettyUrl() );
+ ldif_out( t, QLatin1String( "homeurl" ), addr.url().prettyUrl() );
+ ldif_out( t, QLatin1String( "mozillahomeurl" ), addr.url().prettyUrl() );
+
+ ldif_out( t, QLatin1String( "description" ), addr.note() );
+ if ( addr.revision().isValid() ) {
+ ldif_out( t, QLatin1String( "modifytimestamp" ), dateToVCardString( addr.revision() ) );
+ }
+
+ const QDateTime birthday = addr.birthday();
+ if ( birthday.isValid() ) {
+ const QDate date = birthday.date();
+ ldif_out( t, QLatin1String( "birthyear" ), QString::number( date.year() ) );
+ ldif_out( t, QLatin1String( "birthmonth" ), QString::number( date.month() ) );
+ ldif_out( t, QLatin1String( "birthday" ), QString::number( date.day() ) );
+ }
+
+ t << "objectclass: top\n";
+ t << "objectclass: person\n";
+ t << "objectclass: organizationalPerson\n";
+
+ t << "\n";
+
+ return true;
+}
+
+/* convert from LDIF stream */
+
+bool LDIFConverter::LDIFToAddressee( const QString &str, AddresseeList &addrList,
+ const QDateTime &dt )
+{
+ if ( str.isEmpty() ) {
+ return true;
+ }
+
+ bool endldif = false, end = false;
+ Ldif ldif;
+ Ldif::ParseValue ret;
+ Addressee a;
+ Address homeAddr, workAddr;
+ int birthday = -1;
+ int birthmonth = -1;
+ int birthyear = -1;
+
+ ldif.setLdif( str.toLatin1() );
+ QDateTime qdt = dt;
+ if ( !qdt.isValid() ) {
+ qdt = QDateTime::currentDateTime();
+ }
+ a.setRevision( qdt );
+ homeAddr = Address( Address::Home );
+ workAddr = Address( Address::Work );
+
+ do {
+ ret = ldif.nextItem();
+ switch ( ret ) {
+ case Ldif::Item:
+ {
+ QString fieldname = ldif.attr().toLower();
+ QString value = QString::fromUtf8( ldif.value(), ldif.value().size() );
+ evaluatePair( a, homeAddr, workAddr, fieldname, value, birthday, birthmonth, birthyear );
+ break;
+ }
+ case Ldif::EndEntry:
+ {
+ // if the new address is not empty, append it
+ QDateTime birthDate( QDate( birthyear, birthmonth, birthday ) );
+ if ( birthDate.isValid() ) {
+ a.setBirthday( birthDate );
+ }
+
+ if ( !a.formattedName().isEmpty() || !a.name().isEmpty() ||
+ !a.familyName().isEmpty() ) {
+ if ( !homeAddr.isEmpty() ) {
+ a.insertAddress( homeAddr );
+ }
+ if ( !workAddr.isEmpty() ) {
+ a.insertAddress( workAddr );
+ }
+ addrList.append( a );
+ }
+ a = Addressee();
+ a.setRevision( qdt );
+ homeAddr = Address( Address::Home );
+ workAddr = Address( Address::Work );
+ }
+ break;
+ case Ldif::MoreData:
+ {
+ if ( endldif ) {
+ end = true;
+ } else {
+ ldif.endLdif();
+ endldif = true;
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ } while ( !end );
+
+ return true;
+}
+
+bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr,
+ Address &workAddr,
+ QString &fieldname, QString &value,
+ int &birthday, int &birthmonth, int &birthyear )
+{
+ if ( fieldname == QLatin1String( "dn" ) ) { // ignore & return false!
+ return false;
+ }
+
+ if ( fieldname.startsWith( QLatin1Char( '#' ) ) ) {
+ return true;
+ }
+
+ if ( fieldname.isEmpty() && !a.note().isEmpty() ) {
+ // some LDIF export filters are borken and add additional
+ // comments on stand-alone lines. Just add them to the notes for now.
+ a.setNote( a.note() + QLatin1Char( '\n' ) + value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "givenname" ) ) {
+ a.setGivenName( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "xmozillanickname" ) ||
+ fieldname == QLatin1String( "nickname" ) ||
+ fieldname == QLatin1String( "mozillanickname" ) ) {
+ a.setNickName( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "sn" ) ) {
+ a.setFamilyName( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "uid" ) ) {
+ a.setUid( value );
+ return true;
+ }
+ if ( fieldname == QLatin1String( "mail" ) ||
+ fieldname == QLatin1String( "mozillasecondemail" ) ) { // mozilla
+ if ( a.emails().indexOf( value ) == -1 ) {
+ a.insertEmail( value );
+ }
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "title" ) ) {
+ a.setTitle( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "vocation" ) ) {
+ a.setPrefix( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "cn" ) ) {
+ a.setFormattedName( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "o" ) ||
+ fieldname == QLatin1String( "organization" ) || // Exchange
+ fieldname == QLatin1String( "organizationname" ) ) { // Exchange
+ a.setOrganization( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "description" ) ) {
+addComment:
+ if ( !a.note().isEmpty() ) {
+ a.setNote( a.note() + QLatin1Char( '\n' ) );
+ }
+ a.setNote( a.note() + value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "custom1" ) ||
+ fieldname == QLatin1String( "custom2" ) ||
+ fieldname == QLatin1String( "custom3" ) ||
+ fieldname == QLatin1String( "custom4" ) ) {
+ goto addComment;
+ }
+
+ if ( fieldname == QLatin1String( "homeurl" ) ||
+ fieldname == QLatin1String( "workurl" ) ||
+ fieldname == QLatin1String( "mozillahomeurl" ) ) {
+ if ( a.url().isEmpty() ) {
+ a.setUrl( KUrl( value ) );
+ return true;
+ }
+ if ( a.url().prettyUrl() == KUrl( value ).prettyUrl() ) {
+ return true;
+ }
+ // TODO: current version of kabc only supports one URL.
+ // TODO: change this with KDE 4
+ }
+
+ if ( fieldname == QLatin1String( "homephone" ) ) {
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "telephonenumber" ) ) {
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mobile" ) ) { // mozilla/Netscape 7
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "cellphone" ) ) {
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "pager" ) || // mozilla
+ fieldname == QLatin1String( "pagerphone" ) ) { // mozilla
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "facsimiletelephonenumber" ) ) {
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "xmozillaanyphone" ) ) { // mozilla
+ a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "street" ) ||
+ fieldname == QLatin1String( "streethomeaddress" ) ) {
+ homeAddr.setStreet( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "postaladdress" ) ) { // mozilla
+ workAddr.setStreet( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillapostaladdress2" ) ) { // mozilla
+ workAddr.setStreet( workAddr.street() + QLatin1String( "\n" ) + value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "postalcode" ) ) {
+ workAddr.setPostalCode( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "postofficebox" ) ) {
+ workAddr.setPostOfficeBox( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "homepostaladdress" ) ) { // Netscape 7
+ homeAddr.setStreet( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillahomepostaladdress2" ) ) { // mozilla
+ homeAddr.setStreet( homeAddr.street() + QLatin1String( "\n" ) + value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillahomelocalityname" ) ) { // mozilla
+ homeAddr.setLocality( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillahomestate" ) ) { // mozilla
+ homeAddr.setRegion( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillahomepostalcode" ) ) { // mozilla
+ homeAddr.setPostalCode( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "mozillahomecountryname" ) ) { // mozilla
+ if ( value.length() <= 2 ) {
+ value = Address::ISOtoCountry( value );
+ }
+ homeAddr.setCountry( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "locality" ) ) {
+ workAddr.setLocality( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "streetaddress" ) ) { // Netscape 4.x
+ workAddr.setStreet( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "countryname" ) ||
+ fieldname == QLatin1String( "c" ) ) { // mozilla
+ if ( value.length() <= 2 ) {
+ value = Address::ISOtoCountry( value );
+ }
+ workAddr.setCountry( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "l" ) ) { // mozilla
+ workAddr.setLocality( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "st" ) ) {
+ workAddr.setRegion( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "ou" ) ) {
+ a.setRole( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "department" ) ) {
+ a.setDepartment( value );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "member" ) ) {
+ // this is a mozilla list member (cn=xxx, mail=yyy)
+ QStringList list = value.split( QLatin1Char( ',' ) );
+ QString name, email;
+
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ if ( (*it).startsWith( QLatin1String( "cn=" ) ) ) {
+ name = (*it).mid( 3 ).trimmed();
+ }
+ if ( (*it).startsWith( QLatin1String( "mail=" ) ) ) {
+ email = (*it).mid( 5 ).trimmed();
+ }
+ }
+ if ( !name.isEmpty() && !email.isEmpty() ) {
+ email = QLatin1String( " <" ) + email + QLatin1Char( '>' );
+ }
+ a.insertEmail( name + email );
+ a.insertCategory( i18n( "List of Emails" ) );
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "modifytimestamp" ) ) {
+ if ( value == QLatin1String( "0Z" ) ) { // ignore
+ return true;
+ }
+ QDateTime dt = VCardStringToDate( value );
+ if ( dt.isValid() ) {
+ a.setRevision( dt );
+ return true;
+ }
+ }
+
+ if ( fieldname == QLatin1String( "objectclass" ) ) { // ignore
+ return true;
+ }
+
+ if ( fieldname == QLatin1String( "birthyear" ) ) {
+ birthyear = value.toInt();
+ return true;
+ }
+ if ( fieldname == QLatin1String( "birthmonth" ) ) {
+ birthmonth = value.toInt();
+ return true;
+ }
+ if ( fieldname == QLatin1String( "birthday" ) ) {
+ birthday = value.toInt();
+ return true;
+ }
+
+ kWarning(5700) << QString::fromLatin1( "LDIFConverter: Unknown field for '%1': '%2=%3'\n" ).
+ arg( a.formattedName() ).arg( fieldname ).arg( value );
+
+ return true;
+}
diff --git a/kabc/ldifconverter.h b/kabc/ldifconverter.h
new file mode 100644
index 0000000..975d8dd
--- /dev/null
+++ b/kabc/ldifconverter.h
@@ -0,0 +1,88 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Helge Deller <deller@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 only as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_LDIFCONVERTER_H
+#define KABC_LDIFCONVERTER_H
+
+#include "addressee.h"
+#include "addresseelist.h"
+
+#include <QtCore/QDateTime>
+#include <QtCore/QString>
+
+namespace KABC {
+
+ /**
+ A set of functions to convert a string with LDIF information to addressees
+ and vice versa. It is useful for addressbook import- and exportfilters
+ and might be used to read and write Mozilla and Netscape addresssbooks.
+ */
+
+ namespace LDIFConverter {
+
+ /**
+ Converts a LDIF string to a list of addressees.
+
+ @param str The vcard string.
+ @param addrList The addresseelist.
+ @param dt The date & time value of the last modification (e.g. file modification time).
+ */
+ KABC_EXPORT bool LDIFToAddressee( const QString &str, AddresseeList &addrList,
+ const QDateTime &dt = QDateTime::currentDateTime() );
+
+ /**
+ Converts a list of addressees to a LDIF string.
+
+ @param addrList The addresseelist.
+ @param str The LDIF string.
+ */
+ KABC_EXPORT bool addresseeToLDIF( const AddresseeList &addrList, QString &str );
+
+ /**
+ Converts an addressee to a LDIF string.
+
+ @param addr The addressee.
+ @param str The LDIF string.
+ */
+ KABC_EXPORT bool addresseeToLDIF( const Addressee &addr, QString &str );
+
+ /* internal functions - do not use !! */
+
+ /**
+ @internal
+
+ Evaluates @p fieldname and sets the @p value at the addressee or the address
+ objects when appropriate.
+
+ @param a The addressee to store information into
+ @param homeAddr The home address to store respective information into
+ @param workAddr The work address to store respective information into
+ @param fieldname LDIF field name to evaluate
+ @param value The value of the field addressed by @p fieldname
+ */
+ KABC_EXPORT bool evaluatePair( Addressee &a, Address &homeAddr,
+ Address &workAddr,
+ QString &fieldname, QString &value,
+ int &birthday, int &birthmonth, int &birthyear );
+
+ }
+
+}
+#endif
+
diff --git a/kabc/lock.cpp b/kabc/lock.cpp
new file mode 100644
index 0000000..73408f6
--- /dev/null
+++ b/kabc/lock.cpp
@@ -0,0 +1,182 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "lock.h"
+
+#include <krandom.h>
+#include <kcomponentdata.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace KABC;
+
+class Lock::Private
+{
+ public:
+ Private( const QString &identifier )
+ : mIdentifier( identifier ),
+ mOrigIdentifier( identifier )
+ {
+ mIdentifier.replace( QLatin1Char( '/' ), QLatin1Char( '_' ) );
+#ifdef Q_WS_WIN
+ mIdentifier.replace( QLatin1Char( ':' ), QLatin1Char( '_' ) );
+#endif
+ }
+
+ QString mIdentifier;
+ QString mOrigIdentifier;
+ QString mLockUniqueName;
+ QString mError;
+};
+
+Lock::Lock( const QString &identifier )
+ : d( new Private( identifier ) )
+{
+}
+
+Lock::~Lock()
+{
+ unlock();
+
+ delete d;
+}
+
+QString Lock::locksDir()
+{
+ return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/lock/" ) );
+}
+
+bool Lock::readLockFile( const QString &filename, int &pid, QString &app )
+{
+ QFile file( filename );
+ if ( !file.open( QIODevice::ReadOnly ) ) {
+ return false;
+ }
+
+ QTextStream t( &file );
+ t >> pid >> ws >> app;
+
+ return true;
+}
+
+bool Lock::writeLockFile( const QString &filename )
+{
+ QFile file( filename );
+ if ( !file.open( QIODevice::WriteOnly ) ) {
+ return false;
+ }
+
+ QTextStream t( &file );
+ t << ::getpid() << endl << QString( KGlobal::mainComponent().componentName() );
+
+ return true;
+}
+
+QString Lock::lockFileName() const
+{
+ return locksDir() + d->mIdentifier + QLatin1String( ".lock" );
+}
+
+bool Lock::lock()
+{
+ QString lockName = lockFileName();
+ kDebug() << "-- lock name:" << lockName;
+
+ if ( QFile::exists( lockName ) ) { // check if it is a stale lock file
+ int pid;
+ QString app;
+
+ if ( !readLockFile( lockFileName(), pid, app ) ) {
+ d->mError = i18n( "Unable to open lock file." );
+ return false;
+ }
+
+ int retval = ::kill( pid, 0 );
+ if ( retval == -1 && errno == ESRCH ) { // process doesn't exists anymore
+ QFile::remove( lockName );
+ kWarning() << "Removed stale lock file from process '" << app << "'";
+ } else {
+ d->mError = i18n( "The resource '%1' is locked by application '%2'.",
+ d->mOrigIdentifier, app );
+ return false;
+ }
+ }
+
+ QString lockUniqueName;
+ lockUniqueName = d->mIdentifier + KRandom::randomString( 8 );
+ d->mLockUniqueName = KStandardDirs::locateLocal(
+ "data", QLatin1String( "kabc/lock/" ) + lockUniqueName );
+ kDebug() << "-- lock unique name:" << d->mLockUniqueName;
+
+ // Create unique file
+ writeLockFile( d->mLockUniqueName );
+
+ // Create lock file
+ int result = ::link( QFile::encodeName( d->mLockUniqueName ),
+ QFile::encodeName( lockName ) );
+
+ if ( result == 0 ) {
+ d->mError.clear();
+ emit locked();
+ return true;
+ }
+
+ // TODO: check stat
+
+ d->mError = i18n( "Error" );
+ return false;
+}
+
+bool Lock::unlock()
+{
+ int pid;
+ QString app;
+ if ( readLockFile( lockFileName(), pid, app ) ) {
+ if ( pid == getpid() ) {
+ QFile::remove( lockFileName() );
+ QFile::remove( d->mLockUniqueName );
+ emit unlocked();
+ } else {
+ d->mError = i18n( "Unlock failed. Lock file is owned by other process: %1 (%2)", app, pid );
+ kDebug() << d->mError;
+ return false;
+ }
+ }
+
+ d->mError.clear();
+
+ return true;
+}
+
+QString Lock::error() const
+{
+ return d->mError;
+}
+
diff --git a/kabc/lock.h b/kabc/lock.h
new file mode 100644
index 0000000..178bccc
--- /dev/null
+++ b/kabc/lock.h
@@ -0,0 +1,119 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KABC_LOCK_H
+#define KABC_LOCK_H
+
+#include "kabc_export.h"
+#include <QtCore/QString>
+#include <QtCore/QObject>
+
+namespace KABC {
+
+/**
+ This class provides locking functionality for a file, directory or an
+ arbitrary string-represented resource.
+*/
+class KABC_EXPORT_DEPRECATED Lock : public QObject
+{
+ Q_OBJECT
+ public:
+ /**
+ Constructor.
+
+ @param identifier An identifier for the resource to be locked, e.g. a file
+ name.
+ */
+ Lock( const QString &identifier );
+
+ /**
+ Destruct lock object. This also removes the lock on the resource.
+ */
+ ~Lock();
+
+ /**
+ Lock resource.
+ */
+ virtual bool lock();
+
+ /**
+ Unlock resource.
+ */
+ virtual bool unlock();
+
+ /**
+ Returns the lastest error message.
+ */
+ virtual QString error() const;
+
+ /**
+ Returns the path of the lock file.
+
+ The file will be located in the directory returned by locksDir()
+ and have the file extension @c .lock
+ */
+ QString lockFileName() const;
+
+ /**
+ Reads the process ID and the application name from a lock file.
+
+ @param filename The lock file to read from. Full path or relative to
+ current working directory
+ @param pid The variable the process ID will be read into
+ @param app The variable the application name will be read into
+
+ @return @c false if @p filename could not be read, otherwise @c true, even
+ when reading the values fails
+ */
+ static bool readLockFile( const QString &filename, int &pid, QString &app );
+
+ /**
+ Writes the process ID and the application name to a lock file.
+
+ @param filename The lock file to write to
+
+ @return @c false if the file could not be opened for writing, otherwise
+ @c true
+ */
+ static bool writeLockFile( const QString &filename );
+
+ /**
+ Returns the path of the directory where locks are created.
+ */
+ static QString locksDir();
+
+ Q_SIGNALS:
+ /**
+ Emitted after the lock has been locked.
+ */
+ void locked();
+ /**
+ Emitted after the lock has been unlocked.
+ */
+ void unlocked();
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+}
+
+#endif
diff --git a/kabc/locknull.cpp b/kabc/locknull.cpp
new file mode 100644
index 0000000..eff1aa5
--- /dev/null
+++ b/kabc/locknull.cpp
@@ -0,0 +1,78 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "locknull.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+
+using namespace KABC;
+
+class LockNull::Private
+{
+ public:
+ Private( bool allowAccess )
+ : mAllowAccess( allowAccess )
+ {
+ }
+
+ bool mAllowAccess;
+};
+
+LockNull::LockNull( bool allowAccess )
+ : Lock( QString() ), d( new Private( allowAccess ) )
+{
+}
+
+LockNull::~LockNull()
+{
+ unlock();
+
+ delete d;
+}
+
+bool LockNull::lock()
+{
+ if ( !d->mAllowAccess ) {
+ return false;
+ }
+
+ kWarning(5700) << "LockNull::lock() force success. Doesn't actually lock.";
+
+ emit locked();
+
+ return true;
+}
+
+bool LockNull::unlock()
+{
+ emit unlocked();
+ return true;
+}
+
+QString LockNull::error() const
+{
+ if ( d->mAllowAccess ) {
+ return i18n( "LockNull: All locks succeed but no actual locking is done." );
+ } else {
+ return i18n( "LockNull: All locks fail." );
+ }
+}
diff --git a/kabc/locknull.h b/kabc/locknull.h
new file mode 100644
index 0000000..5d0b47e
--- /dev/null
+++ b/kabc/locknull.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KABC_LOCKNULL_H
+#define KABC_LOCKNULL_H
+
+#include "lock.h"
+#include <QtCore/QString>
+
+namespace KABC {
+
+/**
+ This class provides a lock without actually locking. It can be constructed in
+ two ways: One that let all locks succeed and one that let all locks fail.
+*/
+class KABC_EXPORT_DEPRECATED LockNull : public Lock
+{
+ public:
+ /**
+ Creates an instance of the null lock.
+
+ @param allowAccess if @c true all calls to lock() will "succeed",
+ if @c false all calls to lock() will "fail"
+ */
+ LockNull( bool allowAccess );
+ ~LockNull();
+
+ bool lock();
+ bool unlock();
+
+ QString error() const;
+
+ private:
+ class Private;
+ Private *const d;
+};
+
+}
+
+#endif
diff --git a/kabc/phonenumber.cpp b/kabc/phonenumber.cpp
new file mode 100644
index 0000000..de12e99
--- /dev/null
+++ b/kabc/phonenumber.cpp
@@ -0,0 +1,283 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "phonenumber.h"
+
+#include <klocale.h>
+#include <krandom.h>
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+static QString cleanupNumber( const QString &input )
+{
+ return input.simplified();
+}
+
+class PhoneNumber::Private : public QSharedData
+{
+ public:
+ Private( Type type )
+ : mId( KRandom::randomString( 8 ) ), mType( type )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mId = other.mId;
+ mType = other.mType;
+ mNumber = other.mNumber;
+ }
+
+ QString mId;
+ Type mType;
+ QString mNumber;
+};
+
+PhoneNumber::PhoneNumber()
+ : d( new Private( Home ) )
+{
+}
+
+PhoneNumber::PhoneNumber( const QString &number, Type type )
+ : d( new Private( type ) )
+{
+ d->mNumber = cleanupNumber( number );
+}
+
+PhoneNumber::PhoneNumber( const PhoneNumber &other )
+ : d( other.d )
+{
+}
+
+PhoneNumber::~PhoneNumber()
+{
+}
+
+bool PhoneNumber::operator==( const PhoneNumber &other ) const
+{
+ if ( d->mId != other.d->mId ) {
+ return false;
+ }
+
+ if ( d->mNumber != other.d->mNumber ) {
+ return false;
+ }
+
+ if ( d->mType != other.d->mType ) {
+ return false;
+ }
+
+ return true;
+}
+
+bool PhoneNumber::operator!=( const PhoneNumber &other ) const
+{
+ return !( other == *this );
+}
+
+PhoneNumber &PhoneNumber::operator=( const PhoneNumber &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool PhoneNumber::isEmpty() const
+{
+ return d->mNumber.isEmpty();
+}
+
+void PhoneNumber::setId( const QString &id )
+{
+ d->mId = id;
+}
+
+QString PhoneNumber::id() const
+{
+ return d->mId;
+}
+
+void PhoneNumber::setNumber( const QString &number )
+{
+ d->mNumber = cleanupNumber( number );
+}
+
+QString PhoneNumber::number() const
+{
+ return d->mNumber;
+}
+
+void PhoneNumber::setType( Type type )
+{
+ d->mType = type;
+}
+
+PhoneNumber::Type PhoneNumber::type() const
+{
+ return d->mType;
+}
+
+QString PhoneNumber::typeLabel() const
+{
+ return typeLabel( type() );
+}
+
+PhoneNumber::TypeList PhoneNumber::typeList()
+{
+ static TypeList list;
+
+ if ( list.isEmpty() ) {
+ list << Home << Work << Msg << Pref << Voice << Fax << Cell << Video
+ << Bbs << Modem << Car << Isdn << Pcs << Pager;
+ }
+
+ return list;
+}
+
+QString PhoneNumber::typeFlagLabel( TypeFlag type )
+{
+ switch ( type ) {
+ case Home:
+ return i18nc( "Home phone", "Home" );
+ break;
+ case Work:
+ return i18nc( "Work phone", "Work" );
+ break;
+ case Msg:
+ return i18n( "Messenger" );
+ break;
+ case Pref:
+ return i18nc( "Preferred phone", "Preferred" );
+ break;
+ case Voice:
+ return i18n( "Voice" );
+ break;
+ case Fax:
+ return i18n( "Fax" );
+ break;
+ case Cell:
+ return i18nc( "Mobile Phone", "Mobile" );
+ break;
+ case Video:
+ return i18nc( "Video phone", "Video" );
+ break;
+ case Bbs:
+ return i18n( "Mailbox" );
+ break;
+ case Modem:
+ return i18n( "Modem" );
+ break;
+ case Car:
+ return i18nc( "Car Phone", "Car" );
+ break;
+ case Isdn:
+ return i18n( "ISDN" );
+ break;
+ case Pcs:
+ return i18n( "PCS" );
+ break;
+ case Pager:
+ return i18n( "Pager" );
+ break;
+ default:
+ return i18nc( "another type of phone", "Other" );
+ }
+}
+
+QString PhoneNumber::typeLabel( Type type )
+{
+ QString label;
+ bool first = true;
+
+ // special cases
+ // Pref stand alone -> Preferred Number
+ // Home+Fax or Work+Fax -> combine as initial string
+ if ( type == Pref ) {
+ return i18n( "Preferred Number" );
+ }
+
+ if ( type & Fax ) {
+ if ( type & Home ) {
+ label = i18n( "Home Fax" );
+ first = false;
+ type &= ~Fax;
+ type &= ~Home;
+ } else if ( type & Work ) {
+ label = i18n( "Work Fax" );
+ first = false;
+ type &= ~Fax;
+ type &= ~Work;
+ }
+ }
+
+ const TypeList list = typeList();
+
+ TypeList::ConstIterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ // these are actually flags
+ const TypeFlag flag = static_cast<TypeFlag>( static_cast<int>( *it ) );
+ if ( type & flag ) {
+ if ( !first ) {
+ label.append( QLatin1Char( '/' ) );
+ }
+
+ label.append( typeFlagLabel( flag ) );
+
+ if ( first ) {
+ first = false;
+ }
+ }
+ }
+
+ return label;
+}
+
+QString PhoneNumber::toString() const
+{
+ QString str;
+
+ str += QString::fromLatin1( "PhoneNumber {\n" );
+ str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId );
+ str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) );
+ str += QString::fromLatin1( " Number: %1\n" ).arg( d->mNumber );
+ str += QString::fromLatin1( "}\n" );
+
+ return str;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const PhoneNumber &phone )
+{
+ return s << phone.d->mId << (uint)phone.d->mType << phone.d->mNumber;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, PhoneNumber &phone )
+{
+ uint type;
+ s >> phone.d->mId >> type >> phone.d->mNumber;
+ phone.d->mType = PhoneNumber::Type( type );
+
+ return s;
+}
diff --git a/kabc/phonenumber.h b/kabc/phonenumber.h
new file mode 100644
index 0000000..f1b414e
--- /dev/null
+++ b/kabc/phonenumber.h
@@ -0,0 +1,229 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_PHONENUMBER_H
+#define KABC_PHONENUMBER_H
+
+#include "kabc_export.h"
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QString>
+
+namespace KABC {
+
+/**
+ * @short Phonenumber information.
+ *
+ * This class provides phone number information. A phone number is classified by
+ * a type. The following types are available, it's possible to use multiple types
+ * Types for a number by combining them through a logical or.
+*/
+class KABC_EXPORT PhoneNumber
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const PhoneNumber & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, PhoneNumber & );
+
+ public:
+ /**
+ Phone number types.
+ */
+ enum TypeFlag {
+ Home = 1, /**< Home number */
+ Work = 2, /**< Office number */
+ Msg = 4, /**< Messaging */
+ Pref = 8, /**< Preferred number */
+ Voice = 16, /**< Voice */
+ Fax = 32, /**< Fax machine */
+ Cell = 64, /**< Cell phone */
+ Video = 128, /**< Video phone */
+ Bbs = 256, /**< Mailbox */
+ Modem = 512, /**< Modem */
+ Car = 1024, /**< Car phone */
+ Isdn = 2048, /**< ISDN connection */
+ Pcs = 4096, /**< Personal Communication Service*/
+ Pager = 8192 /**< Pager */
+ };
+
+ Q_DECLARE_FLAGS( Type, TypeFlag )
+
+ /**
+ * List of phone number types.
+ */
+ typedef QList<TypeFlag> TypeList;
+
+ /**
+ * List of phone numbers.
+ */
+ typedef QList<PhoneNumber> List;
+
+ /**
+ * Creates an empty phone number object.
+ */
+ PhoneNumber();
+
+ /**
+ * Creates a phone number object.
+ *
+ * @param number Number
+ * @param type Type as defined in enum. Multiple types can be
+ * specified by combining them by a logical or.
+ */
+ PhoneNumber( const QString &number, Type type = Home ); //krazy:exclude=explicit
+
+ /**
+ * Copy constructor.
+ *
+ * Fast operation, PhoneNumber's data is implicitly shared.
+ *
+ * @param other The PhoneNumber object to copy from
+ */
+ PhoneNumber( const PhoneNumber &other );
+
+ /**
+ * Destroys the phone number.
+ */
+ ~PhoneNumber();
+
+ /**
+ * Equality operator.
+ *
+ * @return @c true if number, type and identifier are equal,
+ * otherwise @c false
+ */
+ bool operator==( const PhoneNumber & ) const;
+
+ /**
+ * Not-Equal operator.
+ */
+ bool operator!=( const PhoneNumber & ) const;
+
+ /**
+ * Assignment operator.
+ *
+ * Fast operation, PhoneNumber's data is implicitly shared.
+ *
+ * @param other The PhoneNumber object to asssign to @c this
+ */
+ PhoneNumber &operator=( const PhoneNumber &other );
+
+ /**
+ * Returns true, if the phone number is empty.
+ */
+ bool isEmpty() const;
+
+ /**
+ * Sets the unique @p identifier.
+ */
+ void setId( const QString &identifier );
+
+ /**
+ * Returns the unique identifier.
+ */
+ QString id() const;
+
+ /**
+ * Sets the phone @p number.
+ */
+ void setNumber( const QString &number );
+
+ /**
+ * Returns the phone number.
+ */
+ QString number() const;
+
+ /**
+ * Sets the @p type.
+ * Multiple types can be specified by combining them by a logical or.
+ *
+ * @param type The #Type of the phone number
+ */
+ void setType( Type type );
+
+ /**
+ * Returns the type. Can be a multiple types combined by a logical or.
+ *
+ * @see #TypeFlag
+ * @see typeLabel()
+ */
+ Type type() const;
+
+ /**
+ * Returns a translated string of the address' type.
+ */
+ QString typeLabel() const;
+
+ /**
+ * Returns a list of all available types
+ */
+ static TypeList typeList();
+
+ /**
+ * Returns the translated label for phone number @p type.
+ *
+ * In opposite to typeFlagLabel( TypeFlag type ), it returns all types
+ * of the phone number concatenated by '/'.
+ *
+ * @param type An OR'ed combination of #TypeFlag
+ *
+ * @see type()
+ */
+ static QString typeLabel( Type type );
+
+ /**
+ * Returns the translated label for phone number @p type.
+ *
+ * @param type An OR'ed combination of #TypeFlag
+ *
+ * @see typeLabel()
+ * @since 4.5
+ */
+ static QString typeFlagLabel( TypeFlag type );
+
+ /**
+ * Returns a string representation of the phone number.
+ */
+ QString toString() const;
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( PhoneNumber::Type )
+
+/**
+ * Serializes the phone @p number object into the @p stream.
+ *
+ * @param stream The stream to write into
+ * @param number The phone number object to serialize
+ */
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const PhoneNumber &number );
+
+/**
+ * Initializes the phone @p number object from the @p stream.
+ *
+ * @param stream The stream to read from
+ * @param number The phone number object to deserialize into
+ */
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, const PhoneNumber &number );
+
+}
+
+#endif
diff --git a/kabc/picture.cpp b/kabc/picture.cpp
new file mode 100644
index 0000000..0a51c8b
--- /dev/null
+++ b/kabc/picture.cpp
@@ -0,0 +1,187 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "picture.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+class Picture::Private : public QSharedData
+{
+ public:
+ Private()
+ : mIntern( false )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mUrl = other.mUrl;
+ mType = other.mType;
+ mData = other.mData;
+ mIntern = other.mIntern;
+ }
+
+ QString mUrl;
+ QString mType;
+ QImage mData;
+
+ bool mIntern;
+};
+
+Picture::Picture()
+ : d( new Private )
+{
+}
+
+Picture::Picture( const QString &url )
+ : d( new Private )
+{
+ d->mUrl = url;
+}
+
+Picture::Picture( const QImage &data )
+ : d( new Private )
+{
+ d->mIntern = true;
+ d->mData = data;
+}
+
+Picture::Picture( const Picture &other )
+ : d( other.d )
+{
+}
+
+Picture::~Picture()
+{
+}
+
+Picture &Picture::operator=( const Picture &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool Picture::operator==( const Picture &p ) const
+{
+ if ( d->mIntern != p.d->mIntern ) {
+ return false;
+ }
+
+ if ( d->mIntern ) {
+ if ( d->mData != p.d->mData ) {
+ return false;
+ }
+ } else {
+ if ( d->mUrl != p.d->mUrl ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Picture::operator!=( const Picture &p ) const
+{
+ return !( p == *this );
+}
+
+bool Picture::isEmpty() const
+{
+ return
+ ( ( d->mIntern == false && d->mUrl.isEmpty() ) || ( d->mIntern == true && d->mData.isNull() ) );
+}
+
+void Picture::setUrl( const QString &url )
+{
+ d->mUrl = url;
+ d->mIntern = false;
+}
+
+void Picture::setData( const QImage &data )
+{
+ d->mData = data;
+ d->mIntern = true;
+}
+
+void Picture::setType( const QString &type )
+{
+ d->mType = type;
+}
+
+bool Picture::isIntern() const
+{
+ return d->mIntern;
+}
+
+QString Picture::url() const
+{
+ return d->mUrl;
+}
+
+QImage Picture::data() const
+{
+ return d->mData;
+}
+
+QString Picture::type() const
+{
+ return d->mType;
+}
+
+QString Picture::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Picture {\n" );
+ str += QString::fromLatin1( " Type: %1\n" ).arg( d->mType );
+ str += QString::fromLatin1( " IsIntern: %1\n" ).
+ arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) );
+ if ( d->mIntern ) {
+ QByteArray data;
+ QBuffer buffer( &data );
+ buffer.open( QIODevice::WriteOnly );
+ d->mData.save( &buffer, "PNG" );
+ str += QString::fromLatin1( " Data: %1\n" ).arg( QString::fromLatin1( data.toBase64() ) );
+ } else {
+ str += QString::fromLatin1( " Url: %1\n" ).arg( d->mUrl );
+ }
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Picture &picture )
+{
+ return s << picture.d->mIntern << picture.d->mUrl << picture.d->mType << picture.d->mData;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Picture &picture )
+{
+ s >> picture.d->mIntern >> picture.d->mUrl >> picture.d->mType >> picture.d->mData;
+
+ return s;
+}
diff --git a/kabc/picture.h b/kabc/picture.h
new file mode 100644
index 0000000..42cedc7
--- /dev/null
+++ b/kabc/picture.h
@@ -0,0 +1,168 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_PICTURE_H
+#define KABC_PICTURE_H
+
+#include "kabc_export.h"
+
+#include <QtCore/QDataStream>
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+#include <QImage>
+
+namespace KABC {
+
+/**
+ A class to store a picture of an addressee. It can store the data directly or
+ an url reference to a picture.
+*/
+class KABC_EXPORT Picture
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Picture & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Picture & );
+
+ public:
+ /**
+ * Creates an empty picture.
+ */
+ Picture();
+
+ /**
+ * Creates a picture which points to the given url.
+ *
+ * @param url A URL that describes the location of the picture file.
+ */
+ Picture( const QString &url );
+
+ /**
+ * Creates a picture with the given data.
+ *
+ * @param data The raw data of the picture.
+ */
+ Picture( const QImage &data );
+
+ /**
+ * Copy constructor.
+ *
+ * Fast operation, Picture's data is implicitly shared.
+ *
+ * @param picture The Picture instance to copy from
+ */
+ Picture( const Picture &picture );
+
+ /**
+ * Destructor.
+ */
+ ~Picture();
+
+ /**
+ * Assignment operator
+ *
+ * Fast operation, Picture's data is implicitly shared.
+ *
+ * @param other The Picture instance to assign to @c this
+ */
+ Picture &operator=( const Picture &other );
+
+ /**
+ * Equality operator.
+ */
+ bool operator==( const Picture & ) const;
+
+ /**
+ * Not-Equal operator.
+ */
+ bool operator!=( const Picture & ) const;
+
+ /**
+ * Returns true, if the picture is empty.
+ */
+ bool isEmpty() const;
+
+ /**
+ * Sets a URL for the location of the picture file. When using this
+ * function, isIntern() will return 'false' until you use
+ * setData().
+ *
+ * @param url The location URL of the picture file.
+ */
+ void setUrl( const QString &url );
+
+ /**
+ * Sets the raw data of the picture. When using this function,
+ * isIntern() will return 'true' until you use setUrl().
+ *
+ * @param data The raw data of the picture.
+ */
+ void setData( const QImage &data );
+
+ /**
+ * Sets the type of the picture.
+ */
+ void setType( const QString &type );
+
+ /**
+ * Returns whether the picture is described by a URL (extern) or
+ * by the raw data (intern).
+ * When this method returns 'true' you can use data() to
+ * get the raw data. Otherwise you can request the URL of this
+ * picture by url() and load the raw data from that location.
+ */
+ bool isIntern() const;
+
+ /**
+ * Returns the location URL of this picture.
+ */
+ QString url() const;
+
+ /**
+ * Returns the raw data of this picture.
+ */
+ QImage data() const;
+
+ /**
+ * Returns the type of this picture.
+ */
+ QString type() const;
+
+ /**
+ * Returns string representation of the picture.
+ */
+ QString toString() const;
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+/**
+ * Serializes the @p picture object into the @p stream.
+ */
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Picture &picture );
+
+/**
+ * Initializes the @p picture object from the @p stream.
+ */
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Picture &picture );
+
+}
+
+#endif
diff --git a/kabc/plugin.cpp b/kabc/plugin.cpp
new file mode 100644
index 0000000..ee8a910
--- /dev/null
+++ b/kabc/plugin.cpp
@@ -0,0 +1,71 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "plugin.h"
+
+using namespace KABC;
+
+class Plugin::Private
+{
+ public:
+ QString mType;
+ QString mNameLabel;
+ QString mDescriptionLabel;
+};
+
+Plugin::Plugin()
+ : d( new Private )
+{
+}
+
+Plugin::~Plugin()
+{
+ delete d;
+}
+
+void Plugin::setType( const QString &type )
+{
+ d->mType = type;
+}
+
+QString Plugin::type() const
+{
+ return d->mType;
+}
+
+void Plugin::setNameLabel( const QString &label )
+{
+ d->mNameLabel = label;
+}
+
+QString Plugin::nameLabel() const
+{
+ return d->mNameLabel;
+}
+
+void Plugin::setDescriptionLabel( const QString &label )
+{
+ d->mDescriptionLabel = label;
+}
+
+QString Plugin::descriptionLabel() const
+{
+ return d->mDescriptionLabel;
+}
diff --git a/kabc/plugin.h b/kabc/plugin.h
new file mode 100644
index 0000000..5d6a8dd
--- /dev/null
+++ b/kabc/plugin.h
@@ -0,0 +1,92 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_PLUGIN_H
+#define KABC_PLUGIN_H
+
+#include "kabc_export.h"
+#include <QtCore/QString>
+
+namespace KABC {
+
+/**
+ * Base class for Plugins. Defines the interface for the basic
+ * plugin properties.
+ *
+ * @see FormatInfo
+ */
+class KABC_EXPORT Plugin
+{
+ public:
+ /**
+ * Creates the Plugin instance.
+ */
+ Plugin();
+
+ /**
+ * Destroys the plugin instance
+ */
+ virtual ~Plugin();
+
+ /**
+ * Sets the plugin's type.
+ *
+ * @param type The type of the plugin
+ */
+ virtual void setType( const QString &type );
+
+ /**
+ * Returns the plugin's type.
+ */
+ virtual QString type() const;
+
+ /**
+ * Sets the plugin's name.
+ *
+ * @param label The localized string to display as the name
+ */
+ virtual void setNameLabel( const QString &label );
+
+ /**
+ * Returns the plugin's name.
+ */
+ virtual QString nameLabel() const;
+
+ /**
+ * Sets the plugin's description.
+ *
+ * @param label The localized string to display as a description
+ */
+ virtual void setDescriptionLabel( const QString &label );
+
+ /**
+ * Returns the plugin's description.
+ */
+ virtual QString descriptionLabel() const;
+
+ private:
+ class Private;
+ Private *const d;
+
+ Q_DISABLE_COPY( Plugin )
+};
+
+}
+#endif
diff --git a/kabc/resourceabc.h b/kabc/resourceabc.h
new file mode 100644
index 0000000..99e41f0
--- /dev/null
+++ b/kabc/resourceabc.h
@@ -0,0 +1,118 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEABC_H
+#define RESOURCEABC_H
+
+#include "kabc_export.h"
+#include "resource.h"
+#include <QtCore/QMap>
+
+// This is here because it can't go to kdelibs/kabc yet, but ultimately
+// it should probably go there (maybe redesigned to have a real object
+// for subresources).
+
+namespace KABC {
+
+/**
+ * This class is the implementation of subfolder resources for KABC.
+ * More methods will be added to give KAddressBook the possibility to
+ * handle subresources.
+ */
+
+class KABC_EXPORT_DEPRECATED ResourceABC : public Resource
+{
+ Q_OBJECT
+
+ public:
+ ResourceABC();
+ ResourceABC( const KConfigGroup &group );
+ virtual ~ResourceABC();
+
+ /**
+ * Get the UID to subresource map. This is necessary to implement
+ * the search order.
+ * The returned map has the UID as key and the resource it's in as
+ * the data.
+ */
+ virtual QMap<QString, QString> uidToResourceMap() const = 0;
+
+ /**
+ * If this resource has subresources, return a QStringList of them.
+ * In most cases, resources do not have subresources, so this is
+ * by default just empty.
+ */
+ virtual QStringList subresources() const;
+
+ /**
+ * Is the given subresource writable?
+ */
+ virtual bool subresourceWritable( const QString & ) const = 0;
+
+ /**
+ * Is this subresource active or not?
+ */
+ virtual bool subresourceActive( const QString & ) const;
+
+ /**
+ * Completion weight for a given subresource
+ */
+ virtual int subresourceCompletionWeight( const QString &subResource ) const = 0;
+
+ /**
+ * Label for a given subresource
+ */
+ virtual QString subresourceLabel( const QString &subResource ) const = 0;
+
+ public Q_SLOTS:
+ /**
+ * (De-)activate a subresource.
+ */
+ virtual void setSubresourceActive( const QString &subResource, bool active ) = 0;
+
+ /**
+ * Set completion weight for a given subresource
+ */
+ virtual void setSubresourceCompletionWeight( const QString &subResource, int weight ) = 0;
+
+ Q_SIGNALS:
+ /**
+ * This signal is emitted when a subresource is added.
+ */
+ void signalSubresourceAdded( KABC::ResourceABC *, const QString &type,
+ const QString &subResource );
+
+ /**
+ * This signal is emitted when a subresource is removed.
+ */
+ void signalSubresourceRemoved( KABC::ResourceABC *, const QString &type,
+ const QString &subResource );
+
+ /**
+ * This signal is emitted when subresource properties have changed.
+ */
+ void signalSubresourceChanged( KABC::ResourceABC *, const QString &type,
+ const QString &subResource );
+};
+
+}
+
+#endif // RESOURCEABC_H
diff --git a/kabc/scripts/addressee.src.cpp b/kabc/scripts/addressee.src.cpp
new file mode 100644
index 0000000..384f730
--- /dev/null
+++ b/kabc/scripts/addressee.src.cpp
@@ -0,0 +1,1091 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2003 Carsten Pfeiffer <pfeiffer@kde.org>
+ Copyright (c) 2005 Ingo Kloecker <kloecker@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <QtCore/QList>
+#include <QtCore/QRegExp>
+#include <QtCore/QSharedData>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <krandom.h>
+
+#include "addresseehelper.h"
+#include "field.h"
+#include "sortmode.h"
+
+#include "addressee.h"
+
+using namespace KABC;
+
+static bool matchBinaryPattern( int value, int pattern );
+
+template <class L>
+static bool listEquals( const QList<L>&, const QList<L>& );
+static bool listEquals( const QStringList&, const QStringList& );
+static bool emailsEquals( const QStringList&, const QStringList& );
+
+class Addressee::Private : public QSharedData
+{
+ public:
+ Private()
+ : mUid( KRandom::randomString( 10 ) ),
+ mEmpty( true ), mChanged( false )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mUid = other.mUid;
+ --VARIABLES_ASSIGNMENT--
+
+ mPhoneNumbers = other.mPhoneNumbers;
+ mAddresses = other.mAddresses;
+ mKeys = other.mKeys;
+ mEmails = other.mEmails;
+ mCategories = other.mCategories;
+ mCustom = other.mCustom;
+ mEmpty = other.mEmpty;
+ mChanged = other.mChanged;
+ }
+
+ ~Private()
+ {
+ }
+
+ QString mUid;
+ --VARIABLES--
+
+ PhoneNumber::List mPhoneNumbers;
+ Address::List mAddresses;
+ Key::List mKeys;
+ QStringList mEmails;
+ QStringList mCategories;
+ QStringList mCustom;
+
+ bool mEmpty :1;
+ bool mChanged :1;
+
+ static KABC::SortMode *mSortMode;
+};
+
+KABC::SortMode *Addressee::Private::mSortMode = 0;
+
+Addressee::Addressee()
+ : d( new Private )
+{
+}
+
+Addressee::~Addressee()
+{
+}
+
+Addressee::Addressee( const Addressee &other )
+ : d( other.d )
+{
+}
+
+Addressee& Addressee::operator=( const Addressee &other )
+{
+ if ( this != &other )
+ d = other.d;
+
+ return *this;
+}
+
+bool Addressee::operator==( const Addressee &a ) const
+{
+ if ( d->mUid != a.d->mUid ) {
+ kDebug() << "uid differs";
+ return false;
+ }
+ --EQUALSTEST--
+ if ( ( d->mUrl.isValid() || a.d->mUrl.isValid() ) &&
+ ( d->mUrl != a.d->mUrl ) ) {
+ kDebug() << "url differs";
+ return false;
+ }
+ if ( !listEquals( d->mPhoneNumbers, a.d->mPhoneNumbers ) ) {
+ kDebug() << "phoneNumbers differs";
+ return false;
+ }
+ if ( !listEquals( d->mAddresses, a.d->mAddresses ) ) {
+ kDebug() << "addresses differs";
+ return false;
+ }
+ if ( !listEquals( d->mKeys, a.d->mKeys ) ) {
+ kDebug() << "keys differs";
+ return false;
+ }
+ if ( !emailsEquals( d->mEmails, a.d->mEmails ) ) {
+ kDebug() << "emails differs";
+ return false;
+ }
+ if ( !listEquals( d->mCategories, a.d->mCategories ) ) {
+ kDebug() << "categories differs";
+ return false;
+ }
+ if ( !listEquals( d->mCustom, a.d->mCustom ) ) {
+ kDebug() << "custom differs";
+ return false;
+ }
+
+ return true;
+}
+
+bool Addressee::operator!=( const Addressee &a ) const
+{
+ return !( a == *this );
+}
+
+bool Addressee::isEmpty() const
+{
+ return d->mEmpty;
+}
+
+void Addressee::setUid( const QString &id )
+{
+ if ( id == d->mUid ) return;
+ d->mEmpty = false;
+ d->mUid = id;
+}
+
+QString Addressee::uid() const
+{
+ return d->mUid;
+}
+
+QString Addressee::uidLabel()
+{
+ return i18n("Unique Identifier");
+}
+
+--DEFINITIONS--
+
+void Addressee::setNameFromString( const QString &s )
+{
+ QString str = s;
+ //remove enclosing quotes from string
+ if ( str.length() > 1 && s[ 0 ] == QLatin1Char( '"' ) && s[ s.length() - 1 ] == QLatin1Char( '"' ) )
+ str = s.mid( 1, s.length() - 2 );
+
+ setFormattedName( str );
+ setName( str );
+
+ // clear all name parts
+ setPrefix( QString() );
+ setGivenName( QString() );
+ setAdditionalName( QString() );
+ setFamilyName( QString() );
+ setSuffix( QString() );
+
+ if ( str.isEmpty() )
+ return;
+
+ static QString spaceStr = QString::fromLatin1( " " );
+ static QString emptyStr = QString::fromLatin1( "" );
+ AddresseeHelper *helper = AddresseeHelper::self();
+
+ int i = str.indexOf( QLatin1Char( ',' ) );
+ if ( i < 0 ) {
+ QStringList parts = str.split( spaceStr );
+ int leftOffset = 0;
+ int rightOffset = parts.count() - 1;
+
+ QString suffix;
+ while ( rightOffset >= 0 ) {
+ if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
+ suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr));
+ rightOffset--;
+ } else
+ break;
+ }
+ setSuffix( suffix );
+
+ if ( rightOffset < 0 )
+ return;
+
+ if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].toLower() ) ) {
+ setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
+ rightOffset--;
+ } else {
+ if ( helper->tradeAsFamilyName() )
+ setFamilyName( parts[ rightOffset ] );
+ else
+ setGivenName( parts[ rightOffset ] );
+ }
+
+ QString prefix;
+ while ( leftOffset < rightOffset ) {
+ if ( helper->containsTitle( parts[ leftOffset ] ) ) {
+ prefix.append( (prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
+ leftOffset++;
+ } else
+ break;
+ }
+ setPrefix( prefix );
+
+ if ( leftOffset < rightOffset ) {
+ setGivenName( parts[ leftOffset ] );
+ leftOffset++;
+ }
+
+ QString additionalName;
+ while ( leftOffset < rightOffset ) {
+ additionalName.append( (additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
+ leftOffset++;
+ }
+ setAdditionalName( additionalName );
+ } else {
+ QString part1 = str.left( i );
+ QString part2 = str.mid( i + 1 );
+
+ QStringList parts = part1.split( spaceStr );
+ int leftOffset = 0;
+ int rightOffset = parts.count() - 1;
+
+ if ( parts.count() > 0 ) {
+
+ QString suffix;
+ while ( rightOffset >= 0 ) {
+ if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
+ suffix.prepend( parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr) );
+ rightOffset--;
+ } else
+ break;
+ }
+ setSuffix( suffix );
+
+ if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].toLower() ) ) {
+ setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
+ rightOffset--;
+ } else
+ setFamilyName( parts[ rightOffset ] );
+
+ QString prefix;
+ while ( leftOffset < rightOffset ) {
+ if ( helper->containsTitle( parts[ leftOffset ] ) ) {
+ prefix.append( (prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
+ leftOffset++;
+ } else
+ break;
+ }
+ } else {
+ setPrefix( QString() );
+ setFamilyName( QString() );
+ setSuffix( QString() );
+ }
+
+ parts = part2.split( spaceStr );
+
+ leftOffset = 0;
+ rightOffset = parts.count();
+
+ if ( parts.count() > 0 ) {
+
+ QString prefix;
+ while ( leftOffset < rightOffset ) {
+ if ( helper->containsTitle( parts[ leftOffset ] ) ) {
+ prefix.append( (prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
+ leftOffset++;
+ } else
+ break;
+ }
+ setPrefix( prefix );
+
+ if ( leftOffset < rightOffset ) {
+ setGivenName( parts[ leftOffset ] );
+ leftOffset++;
+ }
+
+ QString additionalName;
+ while ( leftOffset < rightOffset ) {
+ additionalName.append( (additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
+ leftOffset++;
+ }
+ setAdditionalName( additionalName );
+ } else {
+ setGivenName( QString() );
+ setAdditionalName( QString() );
+ }
+ }
+}
+
+QString Addressee::realName() const
+{
+ QString n( formattedName() );
+ if ( !n.isEmpty() )
+ return n;
+
+ n = assembledName();
+ if ( !n.isEmpty() )
+ return n;
+
+ n = name();
+ if ( !n.isEmpty() )
+ return n;
+
+ return organization();
+}
+
+QString Addressee::assembledName() const
+{
+ const QString name = prefix() + QLatin1Char( ' ' ) +
+ givenName() + QLatin1Char( ' ' ) +
+ additionalName() + QLatin1Char( ' ' ) +
+ familyName() + QLatin1Char( ' ' ) +
+ suffix();
+
+ return name.simplified();
+}
+
+QString Addressee::fullEmail( const QString &email ) const
+{
+ QString e;
+ if ( email.isNull() ) {
+ e = preferredEmail();
+ } else {
+ e = email;
+ }
+ if ( e.isEmpty() ) return QString();
+
+ QString text;
+ if ( realName().isEmpty() )
+ text = e;
+ else {
+ QRegExp needQuotes( QLatin1String( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" ) );
+ if ( realName().indexOf( needQuotes ) != -1 ) {
+ QString name = realName();
+ name.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
+ text = QLatin1String( "\"" ) + name + QLatin1String( "\" <" ) + e + QLatin1Char( '>' );
+ } else
+ text = realName() + QLatin1String( " <" ) + e + QLatin1Char( '>' );
+ }
+
+ return text;
+}
+
+void Addressee::insertEmail( const QString &email, bool preferred )
+{
+ if ( email.simplified().isEmpty() )
+ return;
+
+ if ( d->mEmails.contains( email ) ) {
+ if ( !preferred || d->mEmails.first() == email )
+ return;
+
+ d->mEmails.removeAll( email );
+ d->mEmails.prepend( email );
+ } else {
+ d->mEmpty = false;
+ if ( preferred ) {
+ d->mEmails.prepend( email );
+ } else {
+ d->mEmails.append( email );
+ }
+ }
+}
+
+void Addressee::removeEmail( const QString &email )
+{
+ if ( d->mEmails.contains( email ) ) {
+ d->mEmails.removeAll( email );
+ }
+}
+
+QString Addressee::preferredEmail() const
+{
+ if ( d->mEmails.count() == 0 )
+ return QString();
+ else
+ return d->mEmails.first();
+}
+
+QStringList Addressee::emails() const
+{
+ return d->mEmails;
+}
+
+void Addressee::setEmails( const QStringList& emails )
+{
+ d->mEmails = emails;
+}
+void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber )
+{
+ d->mEmpty = false;
+
+ PhoneNumber::List::Iterator it;
+ for ( it = d->mPhoneNumbers.begin(); it != d->mPhoneNumbers.end(); ++it ) {
+ if ( (*it).id() == phoneNumber.id() ) {
+ *it = phoneNumber;
+ return;
+ }
+ }
+ if ( !phoneNumber.number().simplified().isEmpty() )
+ d->mPhoneNumbers.append( phoneNumber );
+}
+
+void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber )
+{
+ PhoneNumber::List::Iterator it;
+ for ( it = d->mPhoneNumbers.begin(); it != d->mPhoneNumbers.end(); ++it ) {
+ if ( (*it).id() == phoneNumber.id() ) {
+ d->mPhoneNumbers.erase( it );
+ return;
+ }
+ }
+}
+
+PhoneNumber Addressee::phoneNumber( PhoneNumber::Type type ) const
+{
+ PhoneNumber phoneNumber( QString(), type );
+ PhoneNumber::List::ConstIterator it;
+ for ( it = d->mPhoneNumbers.constBegin(); it != d->mPhoneNumbers.constEnd(); ++it ) {
+ if ( matchBinaryPattern( (*it).type(), type ) ) {
+ if ( (*it).type() & PhoneNumber::Pref )
+ return (*it);
+ else if ( phoneNumber.number().isEmpty() )
+ phoneNumber = (*it);
+ }
+ }
+
+ return phoneNumber;
+}
+
+PhoneNumber::List Addressee::phoneNumbers() const
+{
+ return d->mPhoneNumbers;
+}
+
+PhoneNumber::List Addressee::phoneNumbers( PhoneNumber::Type type ) const
+{
+ PhoneNumber::List list;
+
+ PhoneNumber::List::ConstIterator it;
+ PhoneNumber::List::ConstIterator end(d->mPhoneNumbers.constEnd());
+ for ( it = d->mPhoneNumbers.constBegin(); it != end; ++it ) {
+ if ( matchBinaryPattern( (*it).type(), type ) ) {
+ list.append( *it );
+ }
+ }
+ return list;
+}
+
+PhoneNumber Addressee::findPhoneNumber( const QString &id ) const
+{
+ PhoneNumber::List::ConstIterator it;
+ PhoneNumber::List::ConstIterator end(d->mPhoneNumbers.constEnd());
+ for ( it = d->mPhoneNumbers.constBegin(); it != end; ++it ) {
+ if ( (*it).id() == id ) {
+ return *it;
+ }
+ }
+ return PhoneNumber();
+}
+
+void Addressee::insertKey( const Key &key )
+{
+ d->mEmpty = false;
+
+ Key::List::Iterator it;
+ for ( it = d->mKeys.begin(); it != d->mKeys.end(); ++it ) {
+ if ( (*it).id() == key.id() ) {
+ *it = key;
+ return;
+ }
+ }
+ d->mKeys.append( key );
+}
+
+void Addressee::removeKey( const Key &key )
+{
+ Key::List::Iterator it;
+ for ( it = d->mKeys.begin(); it != d->mKeys.end(); ++it ) {
+ if ( (*it).id() == key.id() ) {
+ d->mKeys.removeAll( key );
+ return;
+ }
+ }
+}
+
+Key Addressee::key( Key::Type type, const QString& customTypeString ) const
+{
+ Key::List::ConstIterator it;
+ Key::List::ConstIterator end(d->mKeys.constEnd());
+ for ( it = d->mKeys.constBegin(); it != end; ++it ) {
+ if ( (*it).type() == type ) {
+ if ( type == Key::Custom ) {
+ if ( customTypeString.isEmpty() ) {
+ return *it;
+ } else {
+ if ( (*it).customTypeString() == customTypeString )
+ return (*it);
+ }
+ } else {
+ return *it;
+ }
+ }
+ }
+ return Key( QString(), type );
+}
+
+void Addressee::setKeys( const Key::List& list )
+{
+ d->mKeys = list;
+}
+
+Key::List Addressee::keys() const
+{
+ return d->mKeys;
+}
+
+Key::List Addressee::keys( Key::Type type, const QString& customTypeString ) const
+{
+ Key::List list;
+
+ Key::List::ConstIterator it;
+ Key::List::ConstIterator end(d->mKeys.constEnd());
+ for ( it = d->mKeys.constBegin(); it != end; ++it ) {
+ if ( (*it).type() == type ) {
+ if ( type == Key::Custom ) {
+ if ( customTypeString.isEmpty() ) {
+ list.append( *it );
+ } else {
+ if ( (*it).customTypeString() == customTypeString )
+ list.append( *it );
+ }
+ } else {
+ list.append( *it );
+ }
+ }
+ }
+ return list;
+}
+
+Key Addressee::findKey( const QString &id ) const
+{
+ Key::List::ConstIterator it;
+ Key::List::ConstIterator end(d->mKeys.constEnd());
+ for ( it = d->mKeys.constBegin(); it != end; ++it ) {
+ if ( (*it).id() == id ) {
+ return *it;
+ }
+ }
+ return Key();
+}
+
+QString Addressee::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Addressee {\n" );
+ str += QString::fromLatin1( " Uid: %1\n" ).arg( uid() );
+
+ --DEBUG--
+
+ str += QLatin1String( " Emails {\n" );
+ const QStringList e = emails();
+ QStringList::ConstIterator it;
+ for ( it = e.begin(); it != e.end(); ++it ) {
+ str += QString::fromLatin1( " %1\n" ).arg( *it );
+ }
+ str += QLatin1String( " }\n" );
+
+ str += QLatin1String( " PhoneNumbers {\n" );
+ const PhoneNumber::List p = phoneNumbers();
+ PhoneNumber::List::ConstIterator it2;
+ for ( it2 = p.begin(); it2 != p.end(); ++it2 ) {
+ str += (*it2).toString();
+ }
+ str += QLatin1String( " }\n" );
+
+ str += QLatin1String( " Addresses {\n" );
+ const Address::List a = addresses();
+ Address::List::ConstIterator it3;
+ for ( it3 = a.begin(); it3 != a.end(); ++it3 ) {
+ str += (*it3).toString();
+ }
+ str += QLatin1String( " }\n" );
+
+ str += QLatin1String( " Keys {\n" );
+ const Key::List k = keys();
+ Key::List::ConstIterator it4;
+ for ( it4 = k.begin(); it4 != k.end(); ++it4 ) {
+ str += (*it4).toString();
+ }
+ str += QLatin1String( " }\n" );
+
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+
+void Addressee::insertAddress( const Address &address )
+{
+ if ( address.isEmpty() )
+ return;
+
+ d->mEmpty = false;
+
+ Address::List::Iterator it;
+ for ( it = d->mAddresses.begin(); it != d->mAddresses.end(); ++it ) {
+ if ( (*it).id() == address.id() ) {
+ *it = address;
+ return;
+ }
+ }
+
+ d->mAddresses.append( address );
+}
+
+void Addressee::removeAddress( const Address &address )
+{
+ Address::List::Iterator it;
+ for ( it = d->mAddresses.begin(); it != d->mAddresses.end(); ++it ) {
+ if ( (*it).id() == address.id() ) {
+ d->mAddresses.erase( it );
+ return;
+ }
+ }
+}
+
+Address Addressee::address( Address::Type type ) const
+{
+ Address address( type );
+ Address::List::ConstIterator it;
+ Address::List::ConstIterator end(d->mAddresses.constEnd());
+ for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
+ if ( matchBinaryPattern( (*it).type(), type ) ) {
+ if ( (*it).type() & Address::Pref )
+ return (*it);
+ else if ( address.isEmpty() )
+ address = (*it);
+ }
+ }
+
+ return address;
+}
+
+Address::List Addressee::addresses() const
+{
+ return d->mAddresses;
+}
+
+Address::List Addressee::addresses( Address::Type type ) const
+{
+ Address::List list;
+
+ Address::List::ConstIterator it;
+ Address::List::ConstIterator end(d->mAddresses.constEnd());
+ for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
+ if ( matchBinaryPattern( (*it).type(), type ) ) {
+ list.append( *it );
+ }
+ }
+
+ return list;
+}
+
+Address Addressee::findAddress( const QString &id ) const
+{
+ Address::List::ConstIterator it;
+ Address::List::ConstIterator end(d->mAddresses.constEnd());
+ for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
+ if ( (*it).id() == id ) {
+ return *it;
+ }
+ }
+ return Address();
+}
+
+void Addressee::insertCategory( const QString &c )
+{
+ d->mEmpty = false;
+
+ if ( d->mCategories.contains( c ) )
+ return;
+
+ d->mCategories.append( c );
+}
+
+void Addressee::removeCategory( const QString &category )
+{
+ if ( d->mCategories.contains( category ) ) {
+ d->mCategories.removeAll( category );
+ }
+}
+
+bool Addressee::hasCategory( const QString &category ) const
+{
+ return d->mCategories.contains( category );
+}
+
+void Addressee::setCategories( const QStringList &c )
+{
+ d->mEmpty = false;
+
+ d->mCategories = c;
+}
+
+QStringList Addressee::categories() const
+{
+ return d->mCategories;
+}
+
+void Addressee::insertCustom( const QString &app, const QString &name,
+ const QString &value )
+{
+ if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) return;
+
+ d->mEmpty = false;
+
+ QString qualifiedName = app + QLatin1Char( '-' ) + name + QLatin1Char( ':' );
+
+ QStringList::Iterator it;
+ QStringList::Iterator end(d->mCustom.end());
+ for ( it = d->mCustom.begin(); it != end; ++it ) {
+ if ( (*it).startsWith( qualifiedName ) ) {
+ (*it) = qualifiedName + value;
+ return;
+ }
+ }
+
+ d->mCustom.append( qualifiedName + value );
+}
+
+void Addressee::removeCustom( const QString &app, const QString &name )
+{
+ const QString qualifiedName = app + QLatin1Char( '-' ) + name + QLatin1Char( ':' );
+
+ QStringList::Iterator it;
+ for ( it = d->mCustom.begin(); it != d->mCustom.end(); ++it ) {
+ if ( (*it).startsWith( qualifiedName ) ) {
+ d->mCustom.erase( it );
+ return;
+ }
+ }
+}
+
+QString Addressee::custom( const QString &app, const QString &name ) const
+{
+ QString qualifiedName = app + QLatin1Char( '-' ) + name + QLatin1Char( ':' );
+ QString value;
+
+ QStringList::ConstIterator it;
+ QStringList::ConstIterator end(d->mCustom.constEnd());
+ for ( it = d->mCustom.constBegin(); it != end; ++it ) {
+ if ( (*it).startsWith( qualifiedName ) ) {
+ value = (*it).mid( (*it).indexOf( QLatin1Char( ':' ) ) + 1 );
+ break;
+ }
+ }
+
+ return value;
+}
+
+void Addressee::setCustoms( const QStringList &l )
+{
+ d->mEmpty = false;
+ d->mCustom = l;
+}
+
+QStringList Addressee::customs() const
+{
+ return d->mCustom;
+}
+
+void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName,
+ QString &email )
+{
+ // This is a simplified version of KPIM::splitAddress().
+
+ fullName.clear();
+ email.clear();
+ if ( rawEmail.isEmpty() )
+ return; // KPIM::AddressEmpty;
+
+ // The code works on 8-bit strings, so convert the input to UTF-8.
+ QByteArray address = rawEmail.toUtf8();
+
+ QByteArray displayName;
+ QByteArray addrSpec;
+ QByteArray comment;
+
+ // The following is a primitive parser for a mailbox-list (cf. RFC 2822).
+ // The purpose is to extract a displayable string from the mailboxes.
+ // Comments in the addr-spec are not handled. No error checking is done.
+
+ enum { TopLevel, InComment, InAngleAddress } context = TopLevel;
+ bool inQuotedString = false;
+ int commentLevel = 0;
+ bool stop = false;
+
+ for ( char* p = address.data(); *p && !stop; ++p ) {
+ switch ( context ) {
+ case TopLevel : {
+ switch ( *p ) {
+ case '"' : inQuotedString = !inQuotedString;
+ displayName += *p;
+ break;
+ case '(' : if ( !inQuotedString ) {
+ context = InComment;
+ commentLevel = 1;
+ }
+ else
+ displayName += *p;
+ break;
+ case '<' : if ( !inQuotedString ) {
+ context = InAngleAddress;
+ }
+ else
+ displayName += *p;
+ break;
+ case '\\' : // quoted character
+ displayName += *p;
+ ++p; // skip the '\'
+ if ( *p )
+ displayName += *p;
+ else
+ //return KPIM::UnexpectedEnd;
+ goto ABORT_PARSING;
+ break;
+ case ',' : if ( !inQuotedString ) {
+ //if ( allowMultipleAddresses )
+ // stop = true;
+ //else
+ // return KPIM::UnexpectedComma;
+ goto ABORT_PARSING;
+ }
+ else
+ displayName += *p;
+ break;
+ default : displayName += *p;
+ }
+ break;
+ }
+ case InComment : {
+ switch ( *p ) {
+ case '(' : ++commentLevel;
+ comment += *p;
+ break;
+ case ')' : --commentLevel;
+ if ( commentLevel == 0 ) {
+ context = TopLevel;
+ comment += ' '; // separate the text of several comments
+ }
+ else
+ comment += *p;
+ break;
+ case '\\' : // quoted character
+ comment += *p;
+ ++p; // skip the '\'
+ if ( *p )
+ comment += *p;
+ else
+ //return KPIM::UnexpectedEnd;
+ goto ABORT_PARSING;
+ break;
+ default : comment += *p;
+ }
+ break;
+ }
+ case InAngleAddress : {
+ switch ( *p ) {
+ case '"' : inQuotedString = !inQuotedString;
+ addrSpec += *p;
+ break;
+ case '>' : if ( !inQuotedString ) {
+ context = TopLevel;
+ }
+ else
+ addrSpec += *p;
+ break;
+ case '\\' : // quoted character
+ addrSpec += *p;
+ ++p; // skip the '\'
+ if ( *p )
+ addrSpec += *p;
+ else
+ //return KPIM::UnexpectedEnd;
+ goto ABORT_PARSING;
+ break;
+ default : addrSpec += *p;
+ }
+ break;
+ }
+ } // switch ( context )
+ }
+
+ABORT_PARSING:
+ displayName = displayName.trimmed();
+ comment = comment.trimmed();
+ addrSpec = addrSpec.trimmed();
+
+ fullName = QString::fromUtf8( displayName );
+ email = QString::fromUtf8( addrSpec );
+
+ // check for errors
+ if ( inQuotedString )
+ return; // KPIM::UnbalancedQuote;
+ if ( context == InComment )
+ return; // KPIM::UnbalancedParens;
+ if ( context == InAngleAddress )
+ return; // KPIM::UnclosedAngleAddr;
+
+ if ( addrSpec.isEmpty() ) {
+ if ( displayName.isEmpty() )
+ return; // KPIM::NoAddressSpec;
+ else {
+ //addrSpec = displayName;
+ //displayName.truncate( 0 );
+ // Address of the form "foo@bar" or "foo@bar (Name)".
+ email = fullName;
+ fullName = QString::fromUtf8( comment );
+ }
+ }
+
+ // Check that we do not have any extra characters on the end of the
+ // strings
+ unsigned int len = fullName.length();
+ if ( fullName[ 0 ] == QLatin1Char( '"' ) && fullName[ len - 1 ] == QLatin1Char( '"' ) )
+ fullName = fullName.mid( 1, len - 2 );
+}
+
+void Addressee::setChanged( bool value )
+{
+ d->mChanged = value;
+}
+
+bool Addressee::changed() const
+{
+ return d->mChanged;
+}
+
+void Addressee::setSortMode( KABC::SortMode *mode )
+{
+ Private::mSortMode = mode;
+}
+
+bool Addressee::operator< ( const Addressee &addr ) const
+{
+ if ( !Private::mSortMode )
+ return false;
+ else
+ return Private::mSortMode->lesser( *this, addr );
+}
+
+QString Addressee::mimeType()
+{
+ return QLatin1String( "text/directory" );
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a )
+{
+ s << a.d->mUid;
+
+ --STREAMOUT--
+ s << a.d->mPhoneNumbers;
+ s << a.d->mAddresses;
+ s << a.d->mEmails;
+ s << a.d->mCategories;
+ s << a.d->mCustom;
+ s << a.d->mKeys;
+ return s;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Addressee &a )
+{
+ s >> a.d->mUid;
+
+ --STREAMIN--
+ s >> a.d->mPhoneNumbers;
+ s >> a.d->mAddresses;
+ s >> a.d->mEmails;
+ s >> a.d->mCategories;
+ s >> a.d->mCustom;
+ s >> a.d->mKeys;
+
+ a.d->mEmpty = false;
+
+ return s;
+}
+
+bool matchBinaryPattern( int value, int pattern )
+{
+ /**
+ We want to match all telephonnumbers/addresses which have the bits in the
+ pattern set. More are allowed.
+ if pattern == 0 we have a special handling, then we want only those with
+ exactly no bit set.
+ */
+ if ( pattern == 0 )
+ return ( value == 0 );
+ else
+ return ( pattern == ( pattern & value ) );
+}
+
+template <class L>
+bool listEquals( const QList<L> &list, const QList<L> &pattern )
+{
+ if ( list.count() != pattern.count() )
+ return false;
+ const int numberOfElement(list.count());
+ for ( int i = 0; i < numberOfElement; ++i )
+ if ( !pattern.contains( list[ i ] ) )
+ return false;
+
+ return true;
+}
+
+bool listEquals( const QStringList &list, const QStringList &pattern )
+{
+ if ( list.count() != pattern.count() )
+ return false;
+
+ const int numberOfElement(list.count());
+ for ( int i = 0; i < numberOfElement; ++i )
+ if ( !pattern.contains( list[ i ] ) )
+ return false;
+
+ return true;
+}
+
+bool emailsEquals( const QStringList &list, const QStringList &pattern )
+{
+ if ( list.count() != pattern.count() )
+ return false;
+
+ if ( list.isEmpty() )
+ return true;
+
+ if ( list.first() != pattern.first() )
+ return false;
+
+ QStringList::ConstIterator it;
+ QStringList::ConstIterator end(list.constEnd());
+ for ( it = list.constBegin(); it != end; ++it )
+ if ( !pattern.contains( *it ) )
+ return false;
+
+ return true;
+}
diff --git a/kabc/scripts/addressee.src.h b/kabc/scripts/addressee.src.h
new file mode 100644
index 0000000..ffc438c
--- /dev/null
+++ b/kabc/scripts/addressee.src.h
@@ -0,0 +1,483 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_ADDRESSEE_SRC_H
+#define KABC_ADDRESSEE_SRC_H
+
+#include <QtCore/QDateTime>
+#include <QtCore/QStringList>
+#include <QtCore/QSharedDataPointer>
+
+#include <kurl.h>
+
+#include "address.h"
+#include "geo.h"
+#include "key.h"
+#include "phonenumber.h"
+#include "picture.h"
+#include "secrecy.h"
+#include "sound.h"
+#include "timezone.h"
+#include "addresseelist.h" // for typedef QList<Addressee> List;
+
+namespace KABC {
+
+class SortMode;
+
+/**
+ @short address book entry
+
+ This class represents an entry in the address book.
+
+ The data of this class is implicitly shared. You can pass this class by value.
+
+ If you need the name of a field for presenting it to the user you should use
+ the functions ending in Label(). They return a translated string which can be
+ used as label for the corresponding field.
+
+ About the name fields:
+
+ givenName() is the first name and familyName() the last name. In some
+ countries the family name comes first, that's the reason for the
+ naming. formattedName() is the full name with the correct formatting.
+ It is used as an override, when the correct formatting can't be generated
+ from the other name fields automatically.
+
+ realName() returns a fully formatted name(). It uses formattedName, if set,
+ otherwise it constucts the name from the name fields. As fallback, if
+ nothing else is set it uses name().
+
+ name() is the NAME type of RFC2426. It can be used as internal name for the
+ data enty, but shouldn't be used for displaying the data to the user.
+ */
+class KABC_EXPORT Addressee
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Addressee & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Addressee & );
+
+ public:
+ /**
+ A list of addressee objects
+ */
+ typedef AddresseeList List;
+ /**
+ A map from unique identifier to addressee.
+
+ @see uid()
+ */
+ typedef QMap<QString, Addressee> Map;
+
+ /**
+ Construct an empty address book entry.
+ */
+ Addressee();
+
+ /**
+ Destroys the address book entry.
+ */
+ ~Addressee();
+
+ /**
+ Copy constructor.
+ */
+ Addressee( const Addressee & );
+
+ /**
+ Assignment operator.
+
+ @return a reference to @c this
+ */
+ Addressee &operator=( const Addressee & );
+
+ /**
+ Equality operator.
+
+ @return @c true if @c this and the given addressee are equal,
+ otherwise @c false
+ */
+ bool operator==( const Addressee & ) const;
+
+ /**
+ Not-equal operator.
+
+ @return @c true if @c this and the given addressee are not equal,
+ otherwise @c false
+ */
+ bool operator!=( const Addressee & ) const;
+
+ /**
+ Return, if the address book entry is empty.
+ */
+ bool isEmpty() const;
+
+ /**
+ Set unique identifier.
+
+ @param uid the KABC unique identifier
+ */
+ void setUid( const QString &uid );
+ /**
+ Return unique identifier.
+ */
+ QString uid() const;
+ /**
+ Return translated label for uid field.
+ */
+ static QString uidLabel();
+
+ --DECLARATIONS--
+ /**
+ Set name fields by parsing the given string and trying to associate the
+ parts of the string with according fields. This function should probably
+ be a bit more clever.
+ */
+ void setNameFromString( const QString & );
+
+ /**
+ Return the name of the addressee. This is calculated from all the name
+ fields.
+ */
+ QString realName() const;
+
+ /**
+ Return the name that consists of all name parts.
+ */
+ QString assembledName() const;
+
+ /**
+ Return email address including real name.
+
+ @param email Email address to be used to construct the full email string.
+ If this is QString() the preferred email address is used.
+ */
+ QString fullEmail( const QString &email=QString() ) const;
+
+ /**
+ Insert an email address. If the email address already exists in this
+ addressee it is not duplicated.
+
+ @param email Email address
+ @param preferred Set to true, if this is the preferred email address of
+ the addressee.
+ */
+ void insertEmail( const QString &email, bool preferred=false );
+
+ /**
+ Remove email address. If the email address doesn't exist, nothing happens.
+
+ @param email Email address to remove
+ */
+ void removeEmail( const QString &email );
+
+ /**
+ Return preferred email address. This is the first email address or the
+ last one added with insertEmail() with a set preferred parameter.
+ */
+ QString preferredEmail() const;
+
+ /**
+ Return list of all email addresses.
+ */
+ QStringList emails() const;
+
+ /**
+ Set the emails to @p list.
+ The first email address gets the preferred one!
+ @param list The list of email addresses.
+ */
+ void setEmails( const QStringList& list);
+
+ /**
+ Insert a phone number. If a phone number with the same id already exists
+ in this addressee it is not duplicated.
+
+ @param phoneNumber The telephone number to insert to the addressee
+ */
+ void insertPhoneNumber( const PhoneNumber &phoneNumber );
+
+ /**
+ Remove phone number. If no phone number with the given id exists for this
+ addresse nothing happens.
+
+ @param phoneNumber The telephone number to remove from the addressee
+ */
+ void removePhoneNumber( const PhoneNumber &phoneNumber );
+
+ /**
+ Return phone number, which matches the given type.
+
+ @param type The type of phone number to get
+ */
+ PhoneNumber phoneNumber( PhoneNumber::Type type ) const;
+
+ /**
+ Return list of all phone numbers.
+ */
+ PhoneNumber::List phoneNumbers() const;
+
+ /**
+ Return list of phone numbers with a special type.
+
+ @param type The type of phone number to get
+ */
+ PhoneNumber::List phoneNumbers( PhoneNumber::Type type ) const;
+
+ /**
+ Return phone number with the given id.
+
+ @param id The identifier of the phone number to look for.
+ See PhoneNumber::id()
+ */
+ PhoneNumber findPhoneNumber( const QString &id ) const;
+
+ /**
+ Insert a key. If a key with the same id already exists
+ in this addressee it is not duplicated.
+
+ @param key The key to insert
+ */
+ void insertKey( const Key &key );
+
+ /**
+ Remove a key. If no key with the given id exists for this
+ addresse nothing happens.
+
+ @param key The key to remove
+ */
+ void removeKey( const Key &key );
+
+ /**
+ Return key, which matches the given type.
+ If @p type == Key::Custom you can specify a string
+ that should match. If you leave the string empty, the first
+ key with a custom value is returned.
+
+ @param type The type of key to look for
+ @param customTypeString A string to match custom keys against when
+ @p type is @c Key::Custom
+ */
+ Key key( Key::Type type, const QString& customTypeString = QString() ) const;
+
+ /**
+ Return list of all keys.
+ */
+ Key::List keys() const;
+
+ /**
+ Set the list of keys
+ @param keys The keys to be set.
+ */
+ void setKeys( const Key::List& keys);
+
+ /**
+ Return list of keys with a special type.
+ If @p type == Key::Custom you can specify a string
+ that should match. If you leave the string empty, all custom
+ keys will be returned.
+
+ @param type The type of key to look for
+ @param customTypeString A string to match custom keys against when
+ @p type is @c Key::Custom
+ */
+ Key::List keys( Key::Type type, const QString& customTypeString = QString() ) const;
+
+ /**
+ Return key with the given id.
+
+ @param id The identifier of the key to look for. See Key::id()
+ */
+ Key findKey( const QString &id ) const;
+
+ /**
+ Insert an address. If an address with the same id already exists
+ in this addressee it is not duplicated.
+
+ @param address The address to insert
+ */
+ void insertAddress( const Address &address );
+
+ /**
+ Remove address. If no address with the given id exists for this
+ addresse nothing happens.
+
+ @param address The address to remove
+ */
+ void removeAddress( const Address &address );
+
+ /**
+ Return address, which matches the given type.
+
+ @param type The type of address to look for
+ */
+ Address address( Address::Type type ) const;
+
+ /**
+ Return list of all addresses.
+ */
+ Address::List addresses() const;
+
+ /**
+ Return list of addresses with a special type.
+
+ @param type The type of addresses to look for
+ */
+ Address::List addresses( Address::Type type ) const;
+
+ /**
+ Return address with the given id.
+
+ @param id The identifier of the address to look for. See Address::id()
+ */
+ Address findAddress( const QString &id ) const;
+
+ /**
+ Insert category. If the category already exists it is not duplicated.
+ */
+ void insertCategory( const QString & );
+
+ /**
+ Remove category.
+ */
+ void removeCategory( const QString & );
+
+ /**
+ Return, if addressee has the given category.
+ */
+ bool hasCategory( const QString & ) const;
+
+ /**
+ Set categories to given value.
+ */
+ void setCategories( const QStringList & );
+
+ /**
+ Return list of all set categories.
+ */
+ QStringList categories() const;
+
+ /**
+ Insert custom entry. The entry is identified by the name of the inserting
+ application and a unique name. If an entry with the given app and name
+ already exists its value is replaced with the new given value.
+
+ An empty value isn't allowed (nothing happens if this is called with
+ any of the three arguments being empty)
+
+ @param app Name of the application inserting this custom entry
+ @param name Name of this application specific custom entry
+ @param value Value of this application specific custom entry
+ */
+ void insertCustom( const QString &app, const QString &name,
+ const QString &value );
+
+ /**
+ Remove custom entry.
+
+ @param app Name of the application which has inserted this custom entry
+ @param name Name of this application specific custom entry
+ */
+ void removeCustom( const QString &app, const QString &name );
+
+ /**
+ Return value of custom entry, identified by app and entry name.
+
+ @param app Name of the application which has inserted this custom entry
+ @param name Name of this application specific custom entry
+ */
+ QString custom( const QString &app, const QString &name ) const;
+
+ /**
+ Set all custom entries.
+ */
+ void setCustoms( const QStringList & );
+
+ /**
+ Return list of all custom entries.
+ */
+ QStringList customs() const;
+
+ /**
+ Parse full email address. The result is given back in fullName and email.
+
+ @param rawEmail The input string to parse for name and email
+ @param fullName The name part of the @p rawEmail input, if it contained one
+ @param email The email part of the @p rawEmail input, if it contained one
+ */
+ static void parseEmailAddress( const QString &rawEmail, QString &fullName,
+ QString &email );
+
+ /**
+ Returns string representation of the addressee.
+ */
+ QString toString() const;
+
+ /**
+ Mark addressee as changed.
+
+ @param value Sets the status indicating changed data
+ */
+ void setChanged( bool value );
+
+ /**
+ Return whether the addressee is changed.
+ */
+ bool changed() const;
+
+ /**
+ Sets the sort mode implementation.
+
+ Comparing to addressee objects is delegated to an instance
+ of a subclass of KABC::SortMode.
+
+ @param mode The sort mode implementator to use
+ */
+ static void setSortMode( KABC::SortMode *mode );
+
+ /**
+ Return whether this addressee is "less-than" a given one
+
+ @param addr The addressee object to compare with
+
+ @see setSortMode()
+ */
+ bool operator< ( const Addressee &addr ) const;
+
+ /**
+ Returns the MIME type used for Addressees
+ */
+ static QString mimeType();
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+#ifdef MAKE_KABC_LIB
+KDE_DUMMY_QHASH_FUNCTION(Addressee)
+#endif
+
+KABC_EXPORT QDataStream &operator<<( QDataStream &, const Addressee & );
+KABC_EXPORT QDataStream &operator>>( QDataStream &, Addressee & );
+
+}
+
+#define KABC_ADDRESSEE_METATYPE_DEFINED 1
+Q_DECLARE_METATYPE(KABC::Addressee)
+
+#endif
diff --git a/kabc/scripts/createisomap.pl b/kabc/scripts/createisomap.pl
new file mode 100755
index 0000000..2726e20
--- /dev/null
+++ b/kabc/scripts/createisomap.pl
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+#
+# Create a translation table countryname->iso-code from the entry.desktop
+# files in kdebase/l10n/*/
+#
+# USAGE EXAMPLE:
+# ./createisomap.pl $KDEDIR/share/locale/l10n > countrytransl.map
+#
+# Don't laugh at me. I put this together with an old perl book, perl
+# being a language I've never used before.
+
+@entries = <$ARGV[0]/*/entry.desktop>;
+chomp @entries;
+foreach $entry (@entries) {
+ local ( $entryiso, @entryfile, @mappings );
+ # print "--> $entry\n";
+ $entryiso = $entry;
+ $entryiso =~ s/$ARGV[0]\///;
+ $entryiso =~ s/\/entry\.desktop//;
+ # print " $entryiso\n";
+ open (IN, $entry);
+ @entryfile = <IN>;
+ close IN;
+ chomp @entryfile;
+ foreach $entryfileline (@entryfile) {
+ if ( $entryfileline =~ /^Name.*=(.*)$/ ) {
+ # push (@mappings, $1 . "\t" . $entryiso );
+ print "$1\t$entryiso\n";
+ }
+ }
+}
+
diff --git a/kabc/scripts/doxygen-preprocess-addressee.sh b/kabc/scripts/doxygen-preprocess-addressee.sh
new file mode 100755
index 0000000..a4cfc24
--- /dev/null
+++ b/kabc/scripts/doxygen-preprocess-addressee.sh
@@ -0,0 +1,5 @@
+if test "$1" = "create"; then
+ ./makeaddressee
+elif test "$1" = "cleanup"; then
+ rm -f ../addressee.h ../addressee.cpp ../field.cpp
+fi
diff --git a/kabc/scripts/entrylist b/kabc/scripts/entrylist
new file mode 100644
index 0000000..328512d
--- /dev/null
+++ b/kabc/scripts/entrylist
@@ -0,0 +1,83 @@
+# This file describes the fields of an address book entry.
+#
+# The following comma-separated fields are used:
+#
+# Control: A generates accessor functions.
+# L generates a static function for returning a tranlsated label
+# F generates a Field id and object for generic field handling
+# E generate an equality test in Addressee::operator==().
+# Field Name : A descriptive name which is shown to the user.
+# Comment : A comment helping translators to understand the field name
+# Type : C++ type of field.
+# Identifier : A string used in code as variable name etc.
+# Field Category : Categories the field belongs to (see Field::FieldCategory).
+# Output function: Function used to convert type to string for debug output (optional)
+
+ALE,name,,QString,name
+
+ALFE,formatted name,,QString,formattedName,Frequent
+
+ALFE,family name,,QString,familyName,Frequent
+ALFE,given name,,QString,givenName,Frequent
+ALFE,additional names,,QString,additionalName
+ALFE,honorific prefixes,,QString,prefix
+ALFE,honorific suffixes,,QString,suffix
+
+ALFE,nick name,,QString,nickName,Personal
+
+ALFE,birthday,,QDateTime,birthday,Personal,.toString()
+
+#Address address
+LF,home address street,,QString,homeAddressStreet,Address|Personal
+LF,home address post office box,,QString,homeAddressPostOfficeBox,Address|Personal
+LF,home address city,,QString,homeAddressLocality,Address|Personal
+LF,home address state,,QString,homeAddressRegion,Address|Personal
+LF,home address zip code,,QString,homeAddressPostalCode,Address|Personal
+LF,home address country,,QString,homeAddressCountry,Address|Personal
+LF,home address label,,QString,homeAddressLabel,Address|Personal
+
+LF,business address street,,QString,businessAddressStreet,Address|Organization
+LF,business address post office box,,QString,businessAddressPostOfficeBox,Address|Organization
+LF,business address city,,QString,businessAddressLocality,Address|Organization
+LF,business address state,,QString,businessAddressRegion,Address|Organization
+LF,business address zip code,,QString,businessAddressPostalCode,Address|Organization
+LF,business address country,,QString,businessAddressCountry,Address|Organization
+LF,business address label,,QString,businessAddressLabel,Address|Organization
+
+#phoneNumbers
+LF,home phone,,QString,homePhone,Personal|Frequent
+LF,business phone,,QString,businessPhone,Organization|Frequent
+LF,mobile phone,,QString,mobilePhone,Frequent
+LF,home fax,,QString,homeFax
+LF,business fax,,QString,businessFax
+LF,car phone,,QString,carPhone
+LF,ISDN,,QString,isdn
+LF,pager,,QString,pager
+
+#emails
+LF,email address,,QString,email,Email|Frequent
+
+ALFE,mail client,,QString,mailer,Email
+
+ALE,time zone,,TimeZone,timeZone,,.toString()
+ALE,geographic position,,Geo,geo,,.toString()
+
+ALFE,title,a person's title,QString,title,Organization
+ALFE,role,of a person in an organization,QString,role,Organization
+ALFE,organization,,QString,organization,Organization
+ALFE,department,,QString,department,Organization
+
+ALFE,note,,QString,note
+
+ALE,product identifier,,QString,productId
+ALE,revision date,,QDateTime,revision,,.toString()
+
+ALE,sort string,,QString,sortString
+
+ALF,homepage,,KUrl,url,,.url()
+
+ALE,security class,,Secrecy,secrecy,,.toString()
+
+ALE,logo,,Picture,logo,,.toString()
+ALE,photo,,Picture,photo,,.toString()
+ALE,sound,,Sound,sound,,.toString()
diff --git a/kabc/scripts/field.src.cpp b/kabc/scripts/field.src.cpp
new file mode 100644
index 0000000..e1048fb
--- /dev/null
+++ b/kabc/scripts/field.src.cpp
@@ -0,0 +1,386 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kconfiggroup.h>
+
+#include "field.h"
+
+using namespace KABC;
+
+class Field::Private
+{
+ public:
+ Private( int fieldId, int category = 0,
+ const QString &label = QString(),
+ const QString &key = QString(),
+ const QString &app = QString() )
+ : mFieldId( fieldId ), mCategory( category ), mLabel( label ),
+ mKey( key ), mApp( app ) {}
+
+ enum FieldId
+ {
+ CustomField,
+ --ENUMS--
+ };
+
+ int fieldId() { return mFieldId; }
+ int category() { return mCategory; }
+
+ QString label() { return mLabel; }
+ QString key() { return mKey; }
+ QString app() { return mApp; }
+
+ static Field::List mAllFields;
+ static Field::List mDefaultFields;
+ static Field::List mCustomFields;
+
+ private:
+ int mFieldId;
+ int mCategory;
+
+ QString mLabel;
+ QString mKey;
+ QString mApp;
+};
+
+Field::List Field::Private::mAllFields;
+Field::List Field::Private::mDefaultFields;
+Field::List Field::Private::mCustomFields;
+
+Field::Field( Private *p )
+ : d( p )
+{
+}
+
+Field::~Field()
+{
+ delete d;
+}
+
+QString Field::label()
+{
+ switch ( d->fieldId() ) {
+ --CASELABEL--
+ case Private::CustomField:
+ return d->label();
+ default:
+ return i18n("Unknown Field");
+ }
+}
+
+int Field::category()
+{
+ return d->category();
+}
+
+QString Field::categoryLabel( int category )
+{
+ switch ( category ) {
+ case All:
+ return i18n("All");
+ case Frequent:
+ return i18n("Frequent");
+ case Address:
+ return i18nc("street/postal","Address");
+ case Email:
+ return i18n("Email");
+ case Personal:
+ return i18n("Personal");
+ case Organization:
+ return i18n("Organization");
+ case CustomCategory:
+ return i18n("Custom");
+ default:
+ return i18n("Undefined");
+ }
+}
+
+QString Field::value( const KABC::Addressee &a )
+{
+ switch ( d->fieldId() ) {
+ --CASEVALUE--
+ case Private::Email:
+ return a.preferredEmail();
+ case Private::Birthday:
+ if ( a.birthday().isValid() )
+ return a.birthday().date().toString( Qt::ISODate );
+ else
+ return QString();
+ case Private::Url:
+ return a.url().prettyUrl();
+ case Private::HomePhone:
+ {
+ PhoneNumber::List::ConstIterator it;
+
+ {
+ // check for preferred number
+ const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home | PhoneNumber::Pref );
+ for ( it = list.begin(); it != list.end(); ++it )
+ if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Home )
+ return (*it).number();
+ }
+
+ {
+ // check for normal home number
+ const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home );
+ for ( it = list.begin(); it != list.end(); ++it )
+ if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Home )
+ return (*it).number();
+ }
+
+ return QString();
+ }
+ case Private::BusinessPhone:
+ {
+ PhoneNumber::List::ConstIterator it;
+
+ {
+ // check for preferred number
+ const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work | PhoneNumber::Pref );
+ for ( it = list.begin(); it != list.end(); ++it )
+ if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Work )
+ return (*it).number();
+ }
+
+ {
+ // check for normal work number
+ const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work );
+ for ( it = list.begin(); it != list.end(); ++it )
+ if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Work )
+ return (*it).number();
+ }
+
+ return QString();
+ }
+ case Private::MobilePhone:
+ return a.phoneNumber( PhoneNumber::Cell ).number();
+ case Private::HomeFax:
+ return a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ).number();
+ case Private::BusinessFax:
+ return a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ).number();
+ case Private::CarPhone:
+ return a.phoneNumber( PhoneNumber::Car ).number();
+ case Private::Isdn:
+ return a.phoneNumber( PhoneNumber::Isdn ).number();
+ case Private::Pager:
+ return a.phoneNumber( PhoneNumber::Pager ).number();
+ case Private::HomeAddressStreet:
+ return a.address( Address::Home ).street();
+ case Private::HomeAddressPostOfficeBox:
+ return a.address( Address::Home ).postOfficeBox();
+ case Private::HomeAddressLocality:
+ return a.address( Address::Home ).locality();
+ case Private::HomeAddressRegion:
+ return a.address( Address::Home ).region();
+ case Private::HomeAddressPostalCode:
+ return a.address( Address::Home ).postalCode();
+ case Private::HomeAddressCountry:
+ return a.address( Address::Home ).country();
+ case Private::BusinessAddressStreet:
+ return a.address( Address::Work ).street();
+ case Private::BusinessAddressPostOfficeBox:
+ return a.address( Address::Work ).postOfficeBox();
+ case Private::BusinessAddressLocality:
+ return a.address( Address::Work ).locality();
+ case Private::BusinessAddressRegion:
+ return a.address( Address::Work ).region();
+ case Private::BusinessAddressPostalCode:
+ return a.address( Address::Work ).postalCode();
+ case Private::BusinessAddressCountry:
+ return a.address( Address::Work ).country();
+ case Private::CustomField:
+ return a.custom( d->app(), d->key() );
+ default:
+ return QString();
+ }
+}
+
+bool Field::setValue( KABC::Addressee &a, const QString &value )
+{
+ switch ( d->fieldId() ) {
+ --CASESETVALUE--
+ case Private::Birthday:
+ a.setBirthday( QDateTime::fromString( value, Qt::ISODate ) );
+ return true;
+ case Private::CustomField:
+ a.insertCustom( d->app(), d->key(), value );
+ return true;
+ default:
+ return false;
+ }
+}
+
+QString Field::sortKey( const KABC::Addressee &a )
+{
+ switch ( d->fieldId() ) {
+ --CASEVALUE--
+ case Private::Birthday:
+ if ( a.birthday().isValid() ) {
+ QDate date = a.birthday().date();
+ QString key;
+ key.sprintf( "%02d-%02d", date.month(), date.day() );
+ return key;
+ } else
+ return QLatin1String( "00-00" );
+ default:
+ return value( a ).toLower();
+ }
+}
+
+bool Field::isCustom()
+{
+ return d->fieldId() == Private::CustomField;
+}
+
+Field::List Field::allFields()
+{
+ if ( Private::mAllFields.isEmpty() ) {
+ --CREATEFIELDS--
+ }
+
+ return Private::mAllFields;
+}
+
+Field::List Field::defaultFields()
+{
+ if ( Private::mDefaultFields.isEmpty() ) {
+ createDefaultField( Private::FormattedName );
+ createDefaultField( Private::Email );
+ }
+
+ return Private::mDefaultFields;
+}
+
+void Field::createField( int id, int category )
+{
+ Private::mAllFields.append( new Field( new Private( id, category ) ) );
+}
+
+void Field::createDefaultField( int id, int category )
+{
+ Private::mDefaultFields.append( new Field( new Private( id, category ) ) );
+}
+
+void Field::deleteFields()
+{
+ Field::List::ConstIterator it;
+
+ for ( it = Private::mAllFields.constBegin(); it != Private::mAllFields.constEnd(); ++it ) {
+ delete (*it);
+ }
+ Private::mAllFields.clear();
+
+ for ( it = Private::mDefaultFields.constBegin(); it != Private::mDefaultFields.constEnd(); ++it ) {
+ delete (*it);
+ }
+ Private::mDefaultFields.clear();
+
+ for ( it = Private::mCustomFields.constBegin(); it != Private::mCustomFields.constEnd(); ++it ) {
+ delete (*it);
+ }
+ Private::mCustomFields.clear();
+}
+
+void Field::saveFields( const QString &identifier,
+ const Field::List &fields )
+{
+ KConfigGroup cg( KGlobal::config(), "KABCFields" );
+
+ saveFields( cg, identifier, fields );
+}
+
+void Field::saveFields( KConfigGroup &cfg, const QString &identifier,
+ const Field::List &fields )
+{
+ QList<int> fieldIds;
+
+ int custom = 0;
+ Field::List::ConstIterator it;
+ for ( it = fields.begin(); it != fields.end(); ++it ) {
+ fieldIds.append( (*it)->d->fieldId() );
+ if ( (*it)->isCustom() ) {
+ QStringList customEntry;
+ customEntry << (*it)->d->label();
+ customEntry << (*it)->d->key();
+ customEntry << (*it)->d->app();
+ cfg.writeEntry( QLatin1String( "KABC_CustomEntry_" ) + identifier + QLatin1Char( '_' ) +
+ QString::number( custom++ ), customEntry );
+ }
+ }
+
+ cfg.writeEntry( identifier, fieldIds );
+}
+
+Field::List Field::restoreFields( const QString &identifier )
+{
+ KConfigGroup cg( KGlobal::config(), "KABCFields" );
+
+ return restoreFields( cg, identifier );
+}
+
+Field::List Field::restoreFields( const KConfigGroup &cfg, const QString &identifier )
+{
+ const QList<int> fieldIds = cfg.readEntry( identifier,QList<int>() );
+
+ Field::List fields;
+
+ int custom = 0;
+ QList<int>::ConstIterator it;
+ for ( it = fieldIds.begin(); it != fieldIds.end(); ++it ) {
+ Private *f = 0;
+ if ( (*it) == Private::CustomField ) {
+ QStringList customEntry = cfg.readEntry( QLatin1String( "KABC_CustomEntry_" ) +
+ identifier + QLatin1Char( '_' ) +
+ QString::number( custom++ ),QStringList() );
+ f = new Private( *it, CustomCategory, customEntry[ 0 ],
+ customEntry[ 1 ], customEntry[ 2 ] );
+ } else {
+ f = new Private( *it );
+ }
+ fields.append( new Field( f ) );
+ }
+
+ return fields;
+}
+
+bool Field::equals( Field *field )
+{
+ bool sameId = ( d->fieldId() == field->d->fieldId() );
+
+ if ( !sameId ) return false;
+
+ if ( d->fieldId() != Private::CustomField ) return true;
+
+ return d->key() == field->d->key();
+}
+
+Field *Field::createCustomField( const QString &label, int category,
+ const QString &key, const QString &app )
+{
+ Field *field = new Field( new Private( Private::CustomField,
+ category | CustomCategory,
+ label, key, app ) );
+ Private::mCustomFields.append( field );
+
+ return field;
+}
diff --git a/kabc/scripts/makeaddressee b/kabc/scripts/makeaddressee
new file mode 100755
index 0000000..d8c8f5b
--- /dev/null
+++ b/kabc/scripts/makeaddressee
@@ -0,0 +1,224 @@
+#!/usr/bin/perl
+use Cwd;
+use File::Basename;
+
+my $srcdir;
+my $builddir = cwd();
+$srcdir = dirname($0) || die "Can't determine \$srcdir.";
+chomp $srcdir;
+
+chdir $srcdir;
+
+if (!open( ENTRIES, "$srcdir/entrylist" ) ) {
+ print "Can't open $srcdir/entrylist\n";
+ exit 1;
+}
+
+ while(<ENTRIES>) {
+ if (/^#/) { next; }
+ chop;
+ @entries = split /,/;
+ if (!/^.+,(\w+),(\w+)/) { next; }
+ push @entryCtrl, @entries[0];
+ push @entryRealNames, @entries[1];
+ push @entryComments, @entries[2];
+ push @entryTypes, @entries[3];
+ push @entryNames, @entries[4];
+ push @entryCategory, @entries[5];
+ push @entryDebug, @entries[6];
+ }
+
+close ENTRIES;
+
+if (!open( H_IN, "$srcdir/addressee.src.h" ) ) {
+ print "Can't open $srcdir/addressee.src.h\n";
+ exit 1;
+}
+if (!open( H_OUT, ">$builddir/../addressee.h" ) ) {
+ print "Can't open addressee.h\n";
+ exit 1;
+}
+ print H_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n";
+
+ while( <H_IN> ) {
+ if (/--DECLARATIONS--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] =~ /A/ ) {
+ print H_OUT " /**\n";
+ print H_OUT " Set $entryRealNames[$i].\n";
+ print H_OUT " */\n";
+ print H_OUT " void set" . ucfirst($entryNames[$i]);
+ print H_OUT "( const $entryTypes[$i] &$entryNames[$i] );\n";
+
+ print H_OUT " /**\n";
+ print H_OUT " Return $entryRealNames[$i].\n";
+ print H_OUT " */\n";
+ print H_OUT " $entryTypes[$i] $entryNames[$i]() const;\n";
+ }
+
+ if ( $entryCtrl[$i] !~ /L/ ) { next; }
+ print H_OUT " /**\n";
+ print H_OUT " Return translated label for $entryNames[$i] field.\n";
+ print H_OUT " */\n";
+ print H_OUT " static QString $entryNames[$i]Label();\n\n";
+ }
+ } else {
+ print H_OUT;
+ }
+ }
+
+close H_OUT;
+close H_IN;
+
+if (!open( CPP_IN, "$srcdir/addressee.src.cpp" ) ) {
+ print "Can't open $srcdir/addressee.src.cpp\n";
+ exit 1;
+}
+if (!open( CPP_OUT, ">$builddir/../addressee.cpp" ) ) {
+ print "Can't open addressee.cpp\n";
+ exit 1;
+}
+ print CPP_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n";
+
+ while( <CPP_IN> ) {
+ if (/--VARIABLES--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /A/ ) { next; }
+ print CPP_OUT " $entryTypes[$i] m".ucfirst($entryNames[$i]).";\n";
+ }
+ } elsif (/--VARIABLES_ASSIGNMENT--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /A/ ) { next; }
+ print CPP_OUT " m".ucfirst($entryNames[$i])." = other.m".ucfirst($entryNames[$i]).";\n";
+ }
+ } elsif (/--DEFINITIONS--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] =~ /A/ ) {
+ print CPP_OUT "void Addressee::set" . ucfirst($entryNames[$i]);
+ print CPP_OUT "( const $entryTypes[$i] &$entryNames[$i] )\n{\n";
+ print CPP_OUT " if ( $entryNames[$i] == d->m".ucfirst($entryNames[$i])." ) return;\n";
+ print CPP_OUT " d->mEmpty = false;\n";
+ print CPP_OUT " d->m".ucfirst($entryNames[$i])." = $entryNames[$i];\n}\n\n";
+ print CPP_OUT "$entryTypes[$i] Addressee::$entryNames[$i]() const\n{\n";
+ print CPP_OUT " return d->m".ucfirst($entryNames[$i]).";\n}\n\n";
+ }
+
+ if ( $entryCtrl[$i] !~ /L/ ) { next; }
+ @labelwords = split ' ', $entryRealNames[$i];
+ for( $j=0; $j < @labelwords; ++$j ) {
+ $labelwords[$j] = ucfirst $labelwords[$j];
+ }
+ $label = join ' ', @labelwords;
+ print CPP_OUT "QString Addressee::$entryNames[$i]Label()\n{\n";
+ if ( $entryComments[$i] ) {
+ print CPP_OUT " return i18nc(\"$entryComments[$i]\",\"$label\");\n";
+ } else {
+ print CPP_OUT " return i18n(\"$label\");\n";
+ }
+ print CPP_OUT "}\n\n\n";
+ }
+ } elsif (/--EQUALSTEST--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] =~ /E/ ) {
+ if ( $entryNames[$i] !~ "revision" ) {
+ if ( $entryTypes[$i] =~ "QString" ) {
+ print CPP_OUT " if ( d->m".ucfirst($entryNames[$i])." != a.d->m".ucfirst($entryNames[$i])." &&\n";
+ print CPP_OUT " !( d->m".ucfirst($entryNames[$i]).".isEmpty() && a.d->m".ucfirst($entryNames[$i]).".isEmpty() ) ) {\n";
+ print CPP_OUT " kDebug(5700) << \"$entryNames[$i] differs\";\n";
+ print CPP_OUT " return false;\n";
+ print CPP_OUT " }\n";
+ } else {
+ print CPP_OUT " if ( d->m".ucfirst($entryNames[$i])." != a.d->m".ucfirst($entryNames[$i])." ) {\n";
+ print CPP_OUT " kDebug(5700) << \"$entryNames[$i] differs\";\n";
+ print CPP_OUT " return false;\n";
+ print CPP_OUT " }\n";
+ }
+ }
+ }
+ }
+ } elsif (/--STREAMOUT--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] =~ /A/ ) {
+ print CPP_OUT " s << a.d->m".ucfirst($entryNames[$i]).";\n";
+ }
+ }
+ } elsif (/--STREAMIN--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] =~ /A/ ) {
+ print CPP_OUT " s >> a.d->m".ucfirst($entryNames[$i]).";\n";
+ }
+ }
+ } elsif (/--DEBUG--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /A/ ) { next; }
+ print CPP_OUT " str += QString::fromLatin1( \" " . ucfirst($entryNames[$i]);
+ print CPP_OUT ": %1\\n\" ).arg( $entryNames[$i]()$entryDebug[$i] );\n";
+ }
+ } else {
+ print CPP_OUT;
+ }
+ }
+
+close CPP_OUT;
+close CPP_IN;
+
+if (!open( CPP_IN, "$srcdir/field.src.cpp" ) ) {
+ print "Can't open $srcdir/field.src.cpp\n";
+ exit 1;
+}
+if (!open( CPP_OUT, ">$builddir/../field.cpp" ) ) {
+ print "Can't open field.cpp\n";
+ exit 1;
+}
+ print CPP_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n";
+
+ while( <CPP_IN> ) {
+ if (/--ENUMS--/) {
+ $first = 1;
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /F/ ) { next; }
+ if ( $first ) { $first = 0; }
+ else { print CPP_OUT ",\n"; }
+ print CPP_OUT " " . ucfirst($entryNames[$i]);
+ }
+ print CPP_OUT "\n";
+ } elsif (/--CASELABEL--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /F/ ) { next; }
+ if ( $entryCtrl[$i] !~ /L/ ) { next; }
+ print CPP_OUT " case Private::" . ucfirst($entryNames[$i]) . ":\n";
+ print CPP_OUT " return Addressee::$entryNames[$i]Label();\n";
+ }
+ } elsif (/--CASEVALUE--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /A/ ) { next; }
+ if ( $entryCtrl[$i] !~ /F/ ) { next; }
+ if ( $entryTypes[$i] ne "QString" ) { next; }
+ print CPP_OUT " case Private::" . ucfirst($entryNames[$i]) . ":\n";
+ print CPP_OUT " return a.$entryNames[$i]();\n";
+ }
+ } elsif (/--CASESETVALUE--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /A/ ) { next; }
+ if ( $entryCtrl[$i] !~ /F/ ) { next; }
+ if ( $entryTypes[$i] ne "QString" ) { next; }
+ print CPP_OUT " case Private::" . ucfirst($entryNames[$i]) . ":\n";
+ print CPP_OUT " a.set" . ucfirst($entryNames[$i]) . "( value );\n";
+ print CPP_OUT " return true;\n";
+ }
+ } elsif (/--CREATEFIELDS--/) {
+ for( $i=0; $i<@entryNames; ++$i ) {
+ if ( $entryCtrl[$i] !~ /F/ ) { next; }
+ print CPP_OUT " createField( Private::" . ucfirst($entryNames[$i]);
+ if ( $entryCategory[$i] ) {
+ print CPP_OUT ", $entryCategory[$i]";
+ }
+ print CPP_OUT " );\n";
+ }
+ } else {
+ print CPP_OUT;
+ }
+ }
+
+close CPP_OUT;
+close CPP_IN;
diff --git a/kabc/secrecy.cpp b/kabc/secrecy.cpp
new file mode 100644
index 0000000..e5ed8aa
--- /dev/null
+++ b/kabc/secrecy.cpp
@@ -0,0 +1,162 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "secrecy.h"
+
+#include <klocale.h>
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+class Secrecy::PrivateData : public QSharedData
+{
+ public:
+ PrivateData()
+ : mType( Secrecy::Invalid )
+ {
+ }
+
+ PrivateData( const PrivateData &other )
+ : QSharedData( other )
+ {
+ mType = other.mType;
+ }
+
+ Type mType;
+};
+
+Secrecy::Secrecy( Type type )
+ : d( new PrivateData )
+{
+ d->mType = type;
+}
+
+Secrecy::Secrecy( const Secrecy &other )
+ : d( other.d )
+{
+}
+
+Secrecy::~Secrecy()
+{
+}
+
+Secrecy &Secrecy::operator=( const Secrecy &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool Secrecy::operator==( const Secrecy &other ) const
+{
+ return d->mType == other.d->mType;
+}
+
+bool Secrecy::operator!=( const Secrecy &other ) const
+{
+ return !( *this == other );
+}
+
+bool Secrecy::isValid() const
+{
+ return d->mType != Invalid;
+}
+
+void Secrecy::setType( Type type )
+{
+ d->mType = type;
+}
+
+Secrecy::Type Secrecy::type() const
+{
+ return d->mType;
+}
+
+Secrecy::TypeList Secrecy::typeList()
+{
+ static TypeList list;
+
+ if ( list.isEmpty() ) {
+ list << Public << Private << Confidential;
+ }
+
+ return list;
+}
+
+QString Secrecy::typeLabel( Type type )
+{
+ switch ( type ) {
+ case Public:
+ return i18nc( "access is for everyone", "Public" );
+ break;
+ case Private:
+ return i18nc( "access is by owner only", "Private" );
+ break;
+ case Confidential:
+ return i18nc( "access is by owner and a controlled group", "Confidential" );
+ break;
+ default:
+ return i18nc( "unknown secrecy type", "Unknown type" );
+ break;
+ }
+}
+
+QString Secrecy::toString() const
+{
+ QString str;
+
+ str += QString::fromLatin1( "Secrecy {\n" );
+ str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) );
+ str += QString::fromLatin1( "}\n" );
+
+ return str;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Secrecy &secrecy )
+{
+ return s << (uint)secrecy.d->mType;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Secrecy &secrecy )
+{
+ uint type;
+ s >> type;
+
+ switch ( type ) {
+ case 0:
+ secrecy.d->mType = Secrecy::Public;
+ break;
+ case 1:
+ secrecy.d->mType = Secrecy::Private;
+ break;
+ case 2:
+ secrecy.d->mType = Secrecy::Confidential;
+ break;
+ default:
+ secrecy.d->mType = Secrecy::Invalid;
+ break;
+ }
+
+ return s;
+}
diff --git a/kabc/secrecy.h b/kabc/secrecy.h
new file mode 100644
index 0000000..dd482f3
--- /dev/null
+++ b/kabc/secrecy.h
@@ -0,0 +1,125 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_SECRECY_H
+#define KABC_SECRECY_H
+
+#include "kabc_export.h"
+#include <QtCore/QList>
+#include <QtCore/QSharedDataPointer>
+
+namespace KABC {
+
+class KABC_EXPORT Secrecy
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Secrecy & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Secrecy & );
+
+ public:
+ /**
+ * Secrecy types
+ *
+ * @li Public - for public access
+ * @li Private - only private access
+ * @li Confidential - access for confidential persons
+ */
+ enum Type {
+ Public,
+ Private,
+ Confidential,
+ Invalid
+ };
+
+ /**
+ * List of secrecy types.
+ */
+ typedef QList<Type> TypeList;
+
+ /**
+ * Creates a new secrecy of the given type.
+ *
+ * @param type The secrecy type. @see Type
+ */
+ Secrecy( Type type = Invalid );
+
+ /**
+ * Copy constructor.
+ */
+ Secrecy( const Secrecy &other );
+
+ /**
+ * Destroys the secrecy.
+ */
+ ~Secrecy();
+
+ Secrecy &operator=( const Secrecy & );
+
+ bool operator==( const Secrecy & ) const;
+ bool operator!=( const Secrecy & ) const;
+
+ /**
+ * Returns if the Secrecy object has a valid value.
+ */
+ bool isValid() const;
+
+ /**
+ * Sets the @p type.
+ *
+ * @param type The #Type of secrecy
+ */
+ void setType( Type type );
+
+ /**
+ * Returns the type.
+ */
+ Type type() const;
+
+ /**
+ * Returns a list of all available secrecy types.
+ */
+ static TypeList typeList();
+
+ /**
+ * Returns a translated label for a given secrecy @p type.
+ */
+ static QString typeLabel( Type type );
+
+ /**
+ * Returns a string representation of the secrecy.
+ */
+ QString toString() const;
+
+ private:
+ class PrivateData;
+ QSharedDataPointer<PrivateData> d;
+};
+
+/**
+ * Serializes the @p secrecy object into the @p stream.
+ */
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Secrecy &secrecy );
+
+/**
+ * Initializes the @p secrecy object from the @p stream.
+ */
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Secrecy &secrecy );
+
+}
+#endif
diff --git a/kabc/sortmode.cpp b/kabc/sortmode.cpp
new file mode 100644
index 0000000..57d1898
--- /dev/null
+++ b/kabc/sortmode.cpp
@@ -0,0 +1,114 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "sortmode.h"
+#include "field.h"
+
+using namespace KABC;
+
+SortMode::~SortMode()
+{
+}
+
+class NameSortMode::Private
+{
+ public:
+ NameType mNameType;
+ bool mAscendingOrder;
+};
+
+NameSortMode::NameSortMode()
+ : d( new Private )
+{
+ d->mNameType = FormattedName;
+ d->mAscendingOrder = true;
+}
+
+NameSortMode::NameSortMode( NameType type, bool ascending )
+ : d( new Private )
+{
+ d->mNameType = type;
+ d->mAscendingOrder = ascending;
+}
+
+NameSortMode::~NameSortMode()
+{
+ delete d;
+}
+
+bool NameSortMode::lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const
+{
+ bool lesser = false;
+
+ switch ( d->mNameType ) {
+ case FormattedName:
+ lesser = QString::localeAwareCompare( first.formattedName(), second.formattedName() ) < 0;
+ break;
+ case FamilyName:
+ lesser = QString::localeAwareCompare( first.familyName(), second.familyName() ) < 0;
+ break;
+ case GivenName:
+ lesser = QString::localeAwareCompare( first.givenName(), second.givenName() ) < 0;
+ break;
+ default:
+ lesser = false;
+ break;
+ }
+
+ if ( !d->mAscendingOrder ) {
+ lesser = !lesser;
+ }
+
+ return lesser;
+}
+
+class FieldSortMode::Private
+{
+ public:
+ KABC::Field *mField;
+ bool mAscendingOrder;
+};
+
+FieldSortMode::FieldSortMode( KABC::Field *field, bool ascending )
+ : d( new Private )
+{
+ d->mField = field;
+ d->mAscendingOrder = ascending;
+}
+
+FieldSortMode::~FieldSortMode()
+{
+ delete d;
+}
+
+bool FieldSortMode::lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const
+{
+ if ( !d->mField ) {
+ return false;
+ } else {
+ bool lesser =
+ QString::localeAwareCompare( d->mField->value( first ), d->mField->value( second ) ) < 0;
+ if ( !d->mAscendingOrder ) {
+ lesser = !lesser;
+ }
+
+ return lesser;
+ }
+}
diff --git a/kabc/sortmode.h b/kabc/sortmode.h
new file mode 100644
index 0000000..61ac76f
--- /dev/null
+++ b/kabc/sortmode.h
@@ -0,0 +1,136 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_SORTMODE_H
+#define KABC_SORTMODE_H
+
+#include "kabc_export.h"
+#include "addressee.h"
+
+namespace KABC {
+
+class Field;
+
+/**
+ @short Sort method for sorting an addressee list.
+
+ This interface should be reimplemented by classes which shall act as
+ SortModes for KABC::AddresseeList.
+*/
+class KABC_EXPORT SortMode
+{
+ public:
+ virtual ~SortMode();
+
+ /**
+ Reimplement this method and return whether the first contact is 'smaller'
+ than the second.
+ */
+ virtual bool lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const = 0;
+};
+
+/**
+ @short Implements comparison by name.
+
+ This class implements a comparison of two Addressee objects by name.
+ */
+class KABC_EXPORT NameSortMode : public SortMode
+{
+ public:
+ /**
+ Specifies which parts of the name are used for comparison.
+ */
+ enum NameType {
+ FormattedName, /**< use the formatted name, e.g. "John Doe" */
+ FamilyName, /**< use the last name, e.g. "Doe" */
+ GivenName /**< use the first name, e.g. "John" */
+ };
+
+ /**
+ Constructor.
+
+ Creates a NameSortMethod with FormattedName as name type set.
+ */
+ NameSortMode();
+
+ /**
+ Constructor.
+
+ Creates a NameSortMethod with the specified name type.
+
+ @param type The name type.
+ @param ascending if @c true, Addressee object are sorted in
+ ascending order; if @c false, objects are sorted in
+ descending order
+ */
+ explicit NameSortMode( NameType type, bool ascending = true );
+
+ virtual ~NameSortMode();
+
+ /**
+ Returns whether the first contact is 'smaller' then the second.
+ */
+ virtual bool lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const;
+
+ private:
+ class Private;
+ Private *const d;
+
+ Q_DISABLE_COPY( NameSortMode )
+};
+
+/**
+ @short Implements comparison by an arbitrary field.
+
+ This class implements a comparison of two Addressee objects by the
+ value of an arbitrary field.
+ */
+class KABC_EXPORT FieldSortMode : public SortMode
+{
+ public:
+ /**
+ Constructor.
+
+ Creates a FieldSortMethod with the specified @p field.
+
+ @param field The field.
+ @param ascending if @c true, Addressee object are sorted in
+ ascending order; if @c false, objects are sorted in
+ descending order
+ */
+ explicit FieldSortMode( KABC::Field *field, bool ascending = true );
+
+ virtual ~FieldSortMode();
+
+ /**
+ Returns whether the first contact is 'smaller' then the second.
+ */
+ virtual bool lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const;
+
+ private:
+ class Private;
+ Private *const d;
+
+ Q_DISABLE_COPY( FieldSortMode )
+};
+
+}
+
+#endif
diff --git a/kabc/sound.cpp b/kabc/sound.cpp
new file mode 100644
index 0000000..fa65a06
--- /dev/null
+++ b/kabc/sound.cpp
@@ -0,0 +1,171 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "sound.h"
+
+#include <QtCore/QDataStream>
+#include <QtCore/QSharedData>
+
+using namespace KABC;
+
+class Sound::Private : public QSharedData
+{
+ public:
+ Private()
+ : mIntern( false )
+ {
+ }
+
+ Private( const Private &other )
+ : QSharedData( other )
+ {
+ mUrl = other.mUrl;
+ mData = other.mData;
+ mIntern = other.mIntern;
+ }
+
+ QString mUrl;
+ QByteArray mData;
+
+ bool mIntern;
+};
+
+Sound::Sound()
+ : d( new Private )
+{
+}
+
+Sound::Sound( const QString &url )
+ : d( new Private )
+{
+ d->mUrl = url;
+}
+
+Sound::Sound( const QByteArray &data )
+ : d( new Private )
+{
+ d->mIntern = true;
+ d->mData = data;
+}
+
+Sound::Sound( const Sound &other )
+ : d( other.d )
+{
+}
+
+Sound::~Sound()
+{
+}
+
+Sound &Sound::operator=( const Sound &other )
+{
+ if ( this != &other ) {
+ d = other.d;
+ }
+
+ return *this;
+}
+
+bool Sound::operator==( const Sound &other ) const
+{
+ if ( d->mIntern != other.d->mIntern ) {
+ return false;
+ }
+
+ if ( d->mIntern ) {
+ if ( d->mData != other.d->mData ) {
+ return false;
+ }
+ } else {
+ if ( d->mUrl != other.d->mUrl ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Sound::operator!=( const Sound &other ) const
+{
+ return !( other == *this );
+}
+
+void Sound::setUrl( const QString &url )
+{
+ d->mIntern = false;
+ d->mUrl = url;
+}
+
+void Sound::setData( const QByteArray &data )
+{
+ d->mIntern = true;
+ d->mData = data;
+}
+
+bool Sound::isIntern() const
+{
+ return d->mIntern;
+}
+
+bool Sound::isEmpty() const
+{
+ return
+ ( ( d->mIntern && d->mData.isEmpty() ) || ( !d->mIntern && d->mUrl.isEmpty() ) );
+}
+
+QString Sound::url() const
+{
+ return d->mUrl;
+}
+
+QByteArray Sound::data() const
+{
+ return d->mData;
+}
+
+QString Sound::toString() const
+{
+ QString str;
+
+ str += QLatin1String( "Sound {\n" );
+ str += QString::fromLatin1( " IsIntern: %1\n" ).
+ arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) );
+ if ( d->mIntern ) {
+ str += QString::fromLatin1( " Data: %1\n" ).
+ arg( QString::fromLatin1( d->mData.toBase64() ) );
+ } else {
+ str += QString::fromLatin1( " Url: %1\n" ).arg( d->mUrl );
+ }
+ str += QLatin1String( "}\n" );
+
+ return str;
+}
+
+QDataStream &KABC::operator<<( QDataStream &s, const Sound &sound )
+{
+ return s << sound.d->mIntern << sound.d->mUrl << sound.d->mData;
+}
+
+QDataStream &KABC::operator>>( QDataStream &s, Sound &sound )
+{
+ s >> sound.d->mIntern >> sound.d->mUrl >> sound.d->mData;
+
+ return s;
+}
diff --git a/kabc/sound.h b/kabc/sound.h
new file mode 100644
index 0000000..09822b0
--- /dev/null
+++ b/kabc/sound.h
@@ -0,0 +1,182 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_SOUND_H
+#define KABC_SOUND_H
+
+#include "kabc_export.h"
+#include <QtCore/QString>
+#include <QtCore/QSharedDataPointer>
+
+namespace KABC {
+
+/** @short Class that holds a Sound clip for a contact.
+ *
+ * The sound can be played doing something like this:
+ *
+ * \code
+ * KTempFile tmp;
+ * if ( sound.isIntern() ) {
+ * tmp.file()->write( sound.data() );
+ * tmp.close();
+ * KAudioPlayer::play( tmp.name() );
+ * } else if( !sound.url().isEmpty() ) {
+ * QString tmpFile;
+ * if ( !KIO::NetAccess::download( KUrl( themeURL.url() ), tmpFile, 0 ) ) {
+ * KMessageBox::error( 0,
+ * KIO::NetAccess::lastErrorString(),
+ * i18n( "Failed to download sound file" ),
+ * KMessageBox::Notify
+ * );
+ * return;
+ * }
+ * KAudioPlayer::play( tmpFile );
+ * }
+ * \endcode
+ *
+ * Unfortunately, KAudioPlayer::play is ASync, so to delete the temporary file
+ * the best you can really do is set a timer.
+ *
+ */
+class KABC_EXPORT Sound
+{
+ friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Sound & );
+ friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Sound & );
+
+ public:
+
+ /**
+ * Creates an empty sound object.
+ */
+ Sound();
+
+ /**
+ * Creates a sound object for the given url.
+ *
+ * @param url A url that describes the position of the sound file.
+ */
+ Sound( const QString &url );
+
+ /**
+ * Creates a sound object for the given data.
+ *
+ * @param data The raw data of the sound.
+ */
+ Sound( const QByteArray &data );
+
+ /**
+ * Copy constructor.
+ */
+ Sound( const Sound &other );
+
+ /**
+ * Destroys the sound object.
+ */
+ ~Sound();
+
+ /**
+ * Assignment operator.
+ *
+ * @param other The sound object to assign to @c this
+ */
+ Sound &operator=( const Sound &other );
+
+ /**
+ * Equality operator.
+ *
+ * @param other The object to compare with
+ *
+ * @return @c true if the two objects are equal, otherwise @c false
+ */
+ bool operator==( const Sound &other ) const;
+
+ /**
+ * Not-Equal operator.
+ *
+ * @param other The object to compare with
+ *
+ * @return @c true if the two objects are not equal, otherwise @c false
+ */
+ bool operator!=( const Sound &other ) const;
+
+ /**
+ * Sets a URL for the location of the sound file. When using this
+ * function, isIntern() will return 'false' until you use
+ * setData().
+ *
+ * @param url The location URL of the sound file.
+ */
+ void setUrl( const QString &url );
+
+ /**
+ * Returns true, if the sound object is empty.
+ */
+ bool isEmpty() const;
+
+ /**
+ * Sets the raw data of the sound. When using this function,
+ * isIntern() will return 'true' until you use setUrl().
+ *
+ * @param data The raw data of the sound.
+ */
+ void setData( const QByteArray &data );
+
+ /**
+ * Returns whether the sound is described by a URL (extern) or
+ * by the raw data (intern).
+ * When this method returns 'true' you can use data() to
+ * get the raw data. Otherwise you can request the URL of this
+ * sound by url() and load the raw data from that location.
+ */
+ bool isIntern() const;
+
+ /**
+ * Returns the location URL of this sound.
+ */
+ QString url() const;
+
+ /**
+ * Returns the raw data of this sound.
+ */
+ QByteArray data() const;
+
+ /**
+ * Returns string representation of the sound.
+ */
+ QString toString() const;
+
+ private:
+ class Private;
+ QSharedDataPointer<Private> d;
+};
+
+/**
+ * Serializes the @p sound object into the @p stream.
+ */
+KABC_EXPORT QDataStream &operator<<( QDataStream &stream, const Sound &sound );
+
+/**
+ * Initializes the @p sound object from the @p stream.
+ */
+KABC_EXPORT QDataStream &operator>>( QDataStream &stream, Sound &sound );
+
+}
+
+#endif
diff --git a/kabc/tests/CMakeLists.txt b/kabc/tests/CMakeLists.txt
new file mode 100644
index 0000000..332acf7
--- /dev/null
+++ b/kabc/tests/CMakeLists.txt
@@ -0,0 +1,109 @@
+set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
+include_directories( ${CMAKE_SOURCE_DIR}/kabc )
+
+########### next target ###############
+
+set(addresstest_SRCS addresstest.cpp)
+
+
+kde4_add_unit_test(addresstest TESTNAME kabc-addresstest ${addresstest_SRCS})
+
+target_link_libraries(addresstest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(addresseetest_SRCS addresseetest.cpp)
+
+
+kde4_add_unit_test(addresseetest TESTNAME kabc-addresseetest ${addresseetest_SRCS})
+
+target_link_libraries(addresseetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(geotest_SRCS geotest.cpp)
+
+
+kde4_add_unit_test(geotest TESTNAME kabc-geotest ${geotest_SRCS})
+
+target_link_libraries(geotest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(keytest_SRCS keytest.cpp)
+
+
+kde4_add_unit_test(keytest TESTNAME kabc-keytest ${keytest_SRCS})
+
+target_link_libraries(keytest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(phonenumbertest_SRCS phonenumbertest.cpp)
+
+
+kde4_add_unit_test(phonenumbertest TESTNAME kabc-phonenumbertest ${phonenumbertest_SRCS})
+
+target_link_libraries(phonenumbertest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(picturetest_SRCS picturetest.cpp)
+
+
+kde4_add_unit_test(picturetest TESTNAME kabc-picturetest ${picturetest_SRCS})
+
+target_link_libraries(picturetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(secrecytest_SRCS secrecytest.cpp)
+
+
+kde4_add_unit_test(secrecytest TESTNAME kabc-secrecytest ${secrecytest_SRCS})
+
+target_link_libraries(secrecytest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(soundtest_SRCS soundtest.cpp)
+
+
+kde4_add_unit_test(soundtest TESTNAME kabc-soundtest ${soundtest_SRCS})
+
+target_link_libraries(soundtest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+set(timezonetest_SRCS timezonetest.cpp)
+
+
+kde4_add_unit_test(timezonetest TESTNAME kabc-timezonetest ${timezonetest_SRCS})
+
+target_link_libraries(timezonetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY})
+
+########### next target ###############
+
+#set(testaddresseelist_SRCS testaddresseelist.cpp)
+
+
+#kde4_add_unit_test(testaddresseelist TESTNAME kabc-testaddresseelist ${testaddresseelist_SRCS})
+
+#target_link_libraries(testaddresseelist ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY})
+
+########### next target ###############
+
+set(contactgrouptest_SRCS contactgrouptest.cpp)
+
+
+kde4_add_unit_test(contactgrouptest TESTNAME kabc-contactgrouptest ${contactgrouptest_SRCS})
+
+target_link_libraries(contactgrouptest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY})
+
+########### next target ###############
+
+set(vcarddragtest_SRCS vcarddragtest.cpp)
+
+kde4_add_unit_test(vcarddragtest TESTNAME kabc-vcarddragtest ${vcarddragtest_SRCS})
+
+target_link_libraries(vcarddragtest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY})
diff --git a/kabc/tests/addresseetest.cpp b/kabc/tests/addresseetest.cpp
new file mode 100644
index 0000000..10464b1
--- /dev/null
+++ b/kabc/tests/addresseetest.cpp
@@ -0,0 +1,352 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+//krazy:excludeall=contractions
+
+#include "addresseetest.h"
+#include "kabc/addressee.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( AddresseeTest, NoGUI )
+
+void AddresseeTest::emptyTest()
+{
+ KABC::Addressee addressee;
+ QVERIFY( addressee.isEmpty() );
+
+ KABC::Addressee addresseeWithMail;
+ addresseeWithMail.insertEmail( QLatin1String( "foo@bar.org" ) );
+ QVERIFY( !addresseeWithMail.isEmpty() );
+}
+
+void AddresseeTest::storeTest()
+{
+ KABC::Addressee addressee;
+
+ KABC::Picture logo( QLatin1String( "http://scottlandyard.info/pics/logo.png" ) );
+ KABC::Picture photo( QLatin1String( "http://scottlandyard.info/~sinclair/photo.png" ) );
+ KABC::Sound sound( QLatin1String( "http://scottlandyard.info/~sinclair/sound.wav" ) );
+
+ QStringList emails;
+ emails << QLatin1String( "john@sinclair.com" ) << QLatin1String( "ghosthunter@sinclair.com" );
+
+ KABC::Key::List keys;
+ keys << KABC::Key( QLatin1String( "SecretKey" ) );
+
+ QStringList categories;
+ categories << QLatin1String( "Helper" ) << QLatin1String( "Friend" );
+
+ QStringList customs;
+ customs << QLatin1String( "X-Danger: high" );
+
+ addressee.setUid( QLatin1String( "My uid" ) );
+ addressee.setName( QLatin1String( "John Sinclair" ) );
+ addressee.setFormattedName( QLatin1String( "Sinclair, John" ) );
+ addressee.setFamilyName( QLatin1String( "Sinclair" ) );
+ addressee.setGivenName( QLatin1String( "John" ) );
+ addressee.setAdditionalName( QLatin1String( "Bob" ) );
+ addressee.setPrefix( QLatin1String( "Sir" ) );
+ addressee.setSuffix( QLatin1String( "II" ) );
+ addressee.setNickName( QLatin1String( "ghosthunter" ) );
+ addressee.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) );
+ addressee.setMailer( QLatin1String( "mutt" ) );
+ addressee.setTimeZone( KABC::TimeZone( 2 ) );
+ addressee.setGeo( KABC::Geo( 42, 23 ) );
+ addressee.setTitle( QLatin1String( "Ghost Hunter" ) );
+ addressee.setRole( QLatin1String( "Leader" ) );
+ addressee.setOrganization( QLatin1String( "Scottland Yard" ) );
+ addressee.setNote( QLatin1String( "Don't cross black deads way..." ) );
+ addressee.setProductId( QLatin1String( "ProductId45" ) );
+ addressee.setRevision( QDateTime( QDate( 1982, 9, 15 ) ) );
+ addressee.setSortString( QLatin1String( "Name" ) );
+ addressee.setUrl( KUrl( QLatin1String( "www.scottlandyard.info" ) ) );
+ addressee.setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ addressee.setLogo( logo );
+ addressee.setPhoto( photo );
+ addressee.setSound( sound );
+ addressee.setEmails( emails );
+ addressee.setKeys( keys );
+ addressee.setCategories( categories );
+ addressee.setCustoms( customs );
+ addressee.setChanged( false );
+
+ QVERIFY( addressee.uid() == QLatin1String( "My uid" ) );
+ QVERIFY( addressee.name() == QLatin1String( "John Sinclair" ) );
+ QVERIFY( addressee.formattedName() == QLatin1String( "Sinclair, John" ) );
+ QVERIFY( addressee.familyName() == QLatin1String( "Sinclair" ) );
+ QVERIFY( addressee.givenName() == QLatin1String( "John" ) );
+ QVERIFY( addressee.additionalName() == QLatin1String( "Bob" ) );
+ QVERIFY( addressee.prefix() == QLatin1String( "Sir" ) );
+ QVERIFY( addressee.suffix() == QLatin1String( "II" ) );
+ QVERIFY( addressee.nickName() == QLatin1String( "ghosthunter" ) );
+ QVERIFY( addressee.birthday() == QDateTime( QDate( 1982, 7, 19 ) ) );
+ QVERIFY( addressee.mailer() == QLatin1String( "mutt" ) );
+ QVERIFY( addressee.timeZone() == KABC::TimeZone( 2 ) );
+ QVERIFY( addressee.geo() == KABC::Geo( 42, 23 ) );
+ QVERIFY( addressee.title() == QLatin1String( "Ghost Hunter" ) );
+ QVERIFY( addressee.role() == QLatin1String( "Leader" ) );
+ QVERIFY( addressee.organization() == QLatin1String( "Scottland Yard" ) );
+ QVERIFY( addressee.note() == QLatin1String( "Don't cross black deads way..." ) );
+ QVERIFY( addressee.productId() == QLatin1String( "ProductId45" ) );
+ QVERIFY( addressee.revision() == QDateTime( QDate( 1982, 9, 15 ) ) );
+ QVERIFY( addressee.sortString() == QLatin1String( "Name" ) );
+ QVERIFY( addressee.url() == KUrl( "www.scottlandyard.info" ) );
+ QVERIFY( addressee.secrecy() == KABC::Secrecy( KABC::Secrecy::Public ) );
+ QVERIFY( addressee.logo() == logo );
+ QVERIFY( addressee.photo() == photo );
+ QVERIFY( addressee.sound() == sound );
+ QVERIFY( addressee.emails() == emails );
+ QVERIFY( addressee.keys() == keys );
+ QVERIFY( addressee.categories() == categories );
+ QVERIFY( addressee.customs() == customs );
+ QVERIFY( addressee.changed() == false );
+}
+
+void AddresseeTest::equalsTest()
+{
+ KABC::Addressee addressee1, addressee2;
+
+ KABC::Picture logo( QLatin1String( "http://scottlandyard.info/pics/logo.png" ) );
+ KABC::Picture photo( QLatin1String( "http://scottlandyard.info/~sinclair/photo.png" ) );
+ KABC::Sound sound( QLatin1String( "http://scottlandyard.info/~sinclair/sound.wav" ) );
+
+ QStringList emails;
+ emails << QLatin1String( "john@sinclair.com" ) << QLatin1String( "ghosthunter@sinclair.com" );
+
+ KABC::Key::List keys;
+ keys << KABC::Key( QLatin1String( "SecretKey" ) );
+
+ QStringList categories;
+ categories << QLatin1String( "Helper" ) << QLatin1String( "Friend" );
+
+ QStringList customs;
+ customs << QLatin1String( "X-Danger: high" );
+
+ addressee1.setUid( QLatin1String( "My uid" ) );
+ addressee1.setName( QLatin1String( "John Sinclair" ) );
+ addressee1.setFormattedName( QLatin1String( "Sinclair, John" ) );
+ addressee1.setFamilyName( QLatin1String( "Sinclair" ) );
+ addressee1.setGivenName( QLatin1String( "John" ) );
+ addressee1.setAdditionalName( QLatin1String( "Bob" ) );
+ addressee1.setPrefix( QLatin1String( "Sir" ) );
+ addressee1.setSuffix( QLatin1String( "II" ) );
+ addressee1.setNickName( QLatin1String( "ghosthunter" ) );
+ addressee1.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) );
+ addressee1.setMailer( QLatin1String( "mutt" ) );
+ addressee1.setTimeZone( KABC::TimeZone( 2 ) );
+ addressee1.setGeo( KABC::Geo( 42, 23 ) );
+ addressee1.setTitle( QLatin1String( "Ghost Hunter" ) );
+ addressee1.setRole( QLatin1String( "Leader" ) );
+ addressee1.setOrganization( QLatin1String( "Scottland Yard" ) );
+ addressee1.setNote( QLatin1String( "Don't cross black deads way..." ) );
+ addressee1.setProductId( QLatin1String( "ProductId45" ) );
+ addressee1.setRevision( QDateTime( QDate( 1982, 9, 15 ) ) );
+ addressee1.setSortString( QLatin1String( "Name" ) );
+ addressee1.setUrl( KUrl( QLatin1String( "www.scottlandyard.info" ) ) );
+ addressee1.setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ addressee1.setLogo( logo );
+ addressee1.setPhoto( photo );
+ addressee1.setSound( sound );
+ addressee1.setEmails( emails );
+ addressee1.setKeys( keys );
+ addressee1.setCategories( categories );
+ addressee1.setCustoms( customs );
+ addressee1.setChanged( false );
+
+ addressee2.setUid( QLatin1String( "My uid" ) );
+ addressee2.setName( QLatin1String( "John Sinclair" ) );
+ addressee2.setFormattedName( QLatin1String( "Sinclair, John" ) );
+ addressee2.setFamilyName( QLatin1String( "Sinclair" ) );
+ addressee2.setGivenName( QLatin1String( "John" ) );
+ addressee2.setAdditionalName( QLatin1String( "Bob" ) );
+ addressee2.setPrefix( QLatin1String( "Sir" ) );
+ addressee2.setSuffix( QLatin1String( "II" ) );
+ addressee2.setNickName( QLatin1String( "ghosthunter" ) );
+ addressee2.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) );
+ addressee2.setMailer( QLatin1String( "mutt" ) );
+ addressee2.setTimeZone( KABC::TimeZone( 2 ) );
+ addressee2.setGeo( KABC::Geo( 42, 23 ) );
+ addressee2.setTitle( QLatin1String( "Ghost Hunter" ) );
+ addressee2.setRole( QLatin1String( "Leader" ) );
+ addressee2.setOrganization( QLatin1String( "Scottland Yard" ) );
+ addressee2.setNote( QLatin1String( "Don't cross black deads way..." ) );
+ addressee2.setProductId( QLatin1String( "ProductId45" ) );
+ addressee2.setRevision( QDateTime( QDate( 1982, 9, 15 ) ) );
+ addressee2.setSortString( QLatin1String( "Name" ) );
+ addressee2.setUrl( KUrl( QLatin1String( "www.scottlandyard.info" ) ) );
+ addressee2.setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ addressee2.setLogo( logo );
+ addressee2.setPhoto( photo );
+ addressee2.setSound( sound );
+ addressee2.setEmails( emails );
+ addressee2.setKeys( keys );
+ addressee2.setCategories( categories );
+ addressee2.setCustoms( customs );
+ addressee2.setChanged( false );
+
+ QVERIFY( addressee1 == addressee2 );
+}
+
+void AddresseeTest::differsTest()
+{
+ KABC::Addressee addressee1, addressee2;
+
+ addressee1.setNameFromString( QLatin1String( "John Sinclair" ) );
+ addressee2.setNameFromString( QLatin1String( "Suko" ) );
+
+ QVERIFY( addressee1 != addressee2 );
+}
+
+void AddresseeTest::assignmentTest()
+{
+ KABC::Addressee addressee1, addressee2;
+
+ KABC::Picture logo( QLatin1String( "http://scottlandyard.info/pics/logo.png" ) );
+ KABC::Picture photo( QLatin1String( "http://scottlandyard.info/~sinclair/photo.png" ) );
+ KABC::Sound sound( QLatin1String( "http://scottlandyard.info/~sinclair/sound.wav" ) );
+
+ QStringList emails;
+ emails << QLatin1String( "john@sinclair.com" ) << QLatin1String( "ghosthunter@sinclair.com" );
+
+ KABC::Key::List keys;
+ keys << KABC::Key( QLatin1String( "SecretKey" ) );
+
+ QStringList categories;
+ categories << QLatin1String( "Helper" ) << QLatin1String( "Friend" );
+
+ QStringList customs;
+ customs << QLatin1String( "X-Danger: high" );
+
+ addressee1.setUid( QLatin1String( "My uid" ) );
+ addressee1.setName( QLatin1String( "John Sinclair" ) );
+ addressee1.setFormattedName( QLatin1String( "Sinclair, John" ) );
+ addressee1.setFamilyName( QLatin1String( "Sinclair" ) );
+ addressee1.setGivenName( QLatin1String( "John" ) );
+ addressee1.setAdditionalName( QLatin1String( "Bob" ) );
+ addressee1.setPrefix( QLatin1String( "Sir" ) );
+ addressee1.setSuffix( QLatin1String( "II" ) );
+ addressee1.setNickName( QLatin1String( "ghosthunter" ) );
+ addressee1.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) );
+ addressee1.setMailer( QLatin1String( "mutt" ) );
+ addressee1.setTimeZone( KABC::TimeZone( 2 ) );
+ addressee1.setGeo( KABC::Geo( 42, 23 ) );
+ addressee1.setTitle( QLatin1String( "Ghost Hunter" ) );
+ addressee1.setRole( QLatin1String( "Leader" ) );
+ addressee1.setOrganization( QLatin1String( "Scottland Yard" ) );
+ addressee1.setNote( QLatin1String( "Don't cross black deads way..." ) );
+ addressee1.setProductId( QLatin1String( "ProductId45" ) );
+ addressee1.setRevision( QDateTime( QDate( 1982, 9, 15 ) ) );
+ addressee1.setSortString( QLatin1String( "Name" ) );
+ addressee1.setUrl( KUrl( QLatin1String( "www.scottlandyard.info" ) ) );
+ addressee1.setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ addressee1.setLogo( logo );
+ addressee1.setPhoto( photo );
+ addressee1.setSound( sound );
+ addressee1.setEmails( emails );
+ addressee1.setKeys( keys );
+ addressee1.setCategories( categories );
+ addressee1.setCustoms( customs );
+ addressee1.setChanged( false );
+
+ addressee2 = addressee1;
+
+ QVERIFY( addressee1 == addressee2 );
+}
+
+void AddresseeTest::serializeTest()
+{
+ KABC::Addressee addressee1, addressee2;
+
+ KABC::Picture logo( QLatin1String( "http://scottlandyard.info/pics/logo.png" ) );
+ KABC::Picture photo( QLatin1String( "http://scottlandyard.info/~sinclair/photo.png" ) );
+ KABC::Sound sound( QLatin1String( "http://scottlandyard.info/~sinclair/sound.wav" ) );
+
+ QStringList emails;
+ emails << QLatin1String( "john@sinclair.com" ) << QLatin1String( "ghosthunter@sinclair.com" );
+
+ KABC::Key::List keys;
+ keys << KABC::Key( QLatin1String( "SecretKey" ) );
+
+ QStringList categories;
+ categories << QLatin1String( "Helper" ) << QLatin1String( "Friend" );
+
+ QStringList customs;
+ customs << QLatin1String( "X-Danger: high" );
+
+ addressee1.setUid( QLatin1String( "My uid" ) );
+ addressee1.setName( QLatin1String( "John Sinclair" ) );
+ addressee1.setFormattedName( QLatin1String( "Sinclair, John" ) );
+ addressee1.setFamilyName( QLatin1String( "Sinclair" ) );
+ addressee1.setGivenName( QLatin1String( "John" ) );
+ addressee1.setAdditionalName( QLatin1String( "Bob" ) );
+ addressee1.setPrefix( QLatin1String( "Sir" ) );
+ addressee1.setSuffix( QLatin1String( "II" ) );
+ addressee1.setNickName( QLatin1String( "ghosthunter" ) );
+ addressee1.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) );
+ addressee1.setMailer( QLatin1String( "mutt" ) );
+ addressee1.setTimeZone( KABC::TimeZone( 2 ) );
+ addressee1.setGeo( KABC::Geo( 42, 23 ) );
+ addressee1.setTitle( QLatin1String( "Ghost Hunter" ) );
+ addressee1.setRole( QLatin1String( "Leader" ) );
+ addressee1.setOrganization( QLatin1String( "Scottland Yard" ) );
+ addressee1.setNote( QLatin1String( "Don't cross black deads way..." ) );
+ addressee1.setProductId( QLatin1String( "ProductId45" ) );
+ addressee1.setRevision( QDateTime( QDate( 1982, 9, 15 ) ) );
+ addressee1.setSortString( QLatin1String( "Name" ) );
+ addressee1.setUrl( KUrl( QLatin1String( "www.scottlandyard.info" ) ) );
+ addressee1.setSecrecy( KABC::Secrecy( KABC::Secrecy::Public ) );
+ addressee1.setLogo( logo );
+ addressee1.setPhoto( photo );
+ addressee1.setSound( sound );
+ addressee1.setEmails( emails );
+ addressee1.setKeys( keys );
+ addressee1.setCategories( categories );
+ addressee1.setCustoms( customs );
+ addressee1.setChanged( false );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << addressee1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> addressee2;
+
+ QVERIFY( addressee1 == addressee2 );
+}
+
+void AddresseeTest::fullEmailTest()
+{
+ KABC::Addressee a;
+ QStringList emails;
+ emails << QLatin1String( "foo@bar.com" );
+ a.setEmails( emails );
+ a.setFormattedName( QLatin1String( "firstname \"nickname\" lastname" ) );
+ QCOMPARE( a.fullEmail(),
+ QLatin1String( "\"firstname \\\"nickname\\\" lastname\" <foo@bar.com>" ) );
+}
+
+void AddresseeTest::nameFromStringTest()
+{
+ KABC::Addressee a;
+ a.setNameFromString( QLatin1String( "Firstname Lastname" ) );
+ QCOMPARE( a.givenName(), QLatin1String( "Firstname" ) );
+ QCOMPARE( a.familyName(), QLatin1String( "Lastname" ) );
+ QCOMPARE( a.formattedName(), QLatin1String( "Firstname Lastname" ) );
+}
+
diff --git a/kabc/tests/addresseetest.h b/kabc/tests/addresseetest.h
new file mode 100644
index 0000000..6d49276
--- /dev/null
+++ b/kabc/tests/addresseetest.h
@@ -0,0 +1,41 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ADDRESSEE_TEST_H
+#define ADDRESSEE_TEST_H
+
+#include <QtCore/QObject>
+
+class AddresseeTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void emptyTest();
+ void storeTest();
+ void equalsTest();
+ void differsTest();
+ void assignmentTest();
+ void serializeTest();
+ void fullEmailTest();
+ void nameFromStringTest();
+};
+
+#endif
diff --git a/kabc/tests/addresstest.cpp b/kabc/tests/addresstest.cpp
new file mode 100644
index 0000000..ddc547a
--- /dev/null
+++ b/kabc/tests/addresstest.cpp
@@ -0,0 +1,223 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "addresstest.h"
+#include "kabc/address.h"
+#include <kconfig.h>
+#include <kconfiggroup.h>
+#include "kstandarddirs.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( AddressTest, NoGUI )
+
+void AddressTest::emptyTest()
+{
+ KABC::Address address;
+
+ QVERIFY( address.isEmpty() );
+}
+
+void AddressTest::storeTest()
+{
+ KABC::Address address;
+
+ address.setId( QLatin1String( "My Id" ) );
+ address.setType( KABC::Address::Home );
+ address.setPostOfficeBox( QLatin1String( "1234" ) );
+ address.setExtended( QLatin1String( "My Extended Label" ) );
+ address.setStreet( QLatin1String( "My Street" ) );
+ address.setLocality( QLatin1String( "My Locality" ) );
+ address.setRegion( QLatin1String( "My Region" ) );
+ address.setPostalCode( QLatin1String( "My PostalCode" ) );
+ address.setCountry( QLatin1String( "My Country" ) );
+ address.setLabel( QLatin1String( "My Label" ) );
+
+ QCOMPARE( address.id(), QLatin1String( "My Id" ) );
+ QCOMPARE( address.type(), KABC::Address::Home );
+ QCOMPARE( address.postOfficeBox(), QLatin1String( "1234" ) );
+ QCOMPARE( address.extended(), QLatin1String( "My Extended Label" ) );
+ QCOMPARE( address.street(), QLatin1String( "My Street" ) );
+ QCOMPARE( address.locality(), QLatin1String( "My Locality" ) );
+ QCOMPARE( address.region(), QLatin1String( "My Region" ) );
+ QCOMPARE( address.postalCode(), QLatin1String( "My PostalCode" ) );
+ QCOMPARE( address.country(), QLatin1String( "My Country" ) );
+ QCOMPARE( address.label(), QLatin1String( "My Label" ) );
+}
+
+void AddressTest::equalsTest()
+{
+ KABC::Address address1, address2;
+
+ address1.setId( QLatin1String( "My Id" ) );
+ address1.setType( KABC::Address::Home );
+ address1.setPostOfficeBox( QLatin1String( "1234" ) );
+ address1.setExtended( QLatin1String( "My Extended Label" ) );
+ address1.setStreet( QLatin1String( "My Street" ) );
+ address1.setLocality( QLatin1String( "My Locality" ) );
+ address1.setRegion( QLatin1String( "My Region" ) );
+ address1.setPostalCode( QLatin1String( "My Postalcode" ) );
+ address1.setCountry( QLatin1String( "My country" ) );
+ address1.setLabel( QLatin1String( "My Label" ) );
+
+ address2.setId( QLatin1String( "My Id" ) );
+ address2.setType( KABC::Address::Home );
+ address2.setPostOfficeBox( QLatin1String( "1234" ) );
+ address2.setExtended( QLatin1String( "My Extended Label" ) );
+ address2.setStreet( QLatin1String( "My Street" ) );
+ address2.setLocality( QLatin1String( "My Locality" ) );
+ address2.setRegion( QLatin1String( "My Region" ) );
+ address2.setPostalCode( QLatin1String( "My Postalcode" ) );
+ address2.setCountry( QLatin1String( "My country" ) );
+ address2.setLabel( QLatin1String( "My Label" ) );
+
+ QVERIFY( address1 == address2 );
+}
+
+void AddressTest::differsTest()
+{
+ KABC::Address address1( KABC::Address::Home );
+ KABC::Address address2( KABC::Address::Work );
+
+ QVERIFY( address1 != address2 );
+}
+
+void AddressTest::assignmentTest()
+{
+ KABC::Address address1, address2;
+
+ address1.setId( QLatin1String( "My Id" ) );
+ address1.setType( KABC::Address::Home );
+ address1.setPostOfficeBox( QLatin1String( "1234" ) );
+ address1.setExtended( QLatin1String( "My Extended Label" ) );
+ address1.setStreet( QLatin1String( "My Street" ) );
+ address1.setLocality( QLatin1String( "My Locality" ) );
+ address1.setRegion( QLatin1String( "My Region" ) );
+ address1.setPostalCode( QLatin1String( "My Postalcode" ) );
+ address1.setCountry( QLatin1String( "My country" ) );
+ address1.setLabel( QLatin1String( "My Label" ) );
+
+ address2 = address1;
+
+ QVERIFY( address1 == address2 );
+}
+
+void AddressTest::serializeTest()
+{
+ KABC::Address address1, address2;
+
+ address1.setType( KABC::Address::Work );
+ address1.setPostOfficeBox( QLatin1String( "1234" ) );
+ address1.setExtended( QLatin1String( "My Extended Label" ) );
+ address1.setStreet( QLatin1String( "My Street" ) );
+ address1.setLocality( QLatin1String( "My Locality" ) );
+ address1.setRegion( QLatin1String( "My Region" ) );
+ address1.setPostalCode( QLatin1String( "My Postalcode" ) );
+ address1.setCountry( QLatin1String( "My country" ) );
+ address1.setLabel( QLatin1String( "My Label" ) );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << address1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> address2;
+
+ QVERIFY( address1 == address2 );
+}
+
+void AddressTest::formatTest()
+{
+ {
+ // check availability of country to ISO code mapping data file
+ const QString mapfile = KGlobal::dirs()->findResource( "data", QLatin1String( "kabc/countrytransl.map" ) );
+ QVERIFY2( !mapfile.isEmpty(), "Country to ISO code mapping data file does not exist" );
+
+ QFileInfo fileInfo( mapfile );
+ QVERIFY2( fileInfo.exists(), "Country to ISO code mapping data file does not exist" );
+ QVERIFY2( fileInfo.isReadable(), "Country to ISO code mapping data file is not readable" );
+ }
+
+ {
+ const QString templateFile = KStandardDirs::locate( "locale",
+ QLatin1String( "l10n/de/entry.desktop" ) );
+ QVERIFY2( !templateFile.isEmpty(), "Address format template file for 'de' does not exist" );
+
+ const KConfig templateConfig( templateFile );
+ QVERIFY2( templateConfig.hasGroup( "KCM Locale" ),
+ "Address format config for 'de' is missing expected 'KCM Locale' group" );
+ const KConfigGroup templateGroup = templateConfig.group( "KCM Locale" );
+ QVERIFY2( templateGroup.hasKey( "AddressFormat" ),
+ "Address format config is missing expected key 'AddressFormat'" );
+ const QString addressTemplate = templateGroup.readEntry( "AddressFormat" );
+ QVERIFY2( !addressTemplate.isEmpty(),
+ "Address format template for 'de' is empty" );
+
+ KABC::Address address;
+ address.setStreet( QLatin1String( "Lummerlandstr. 1" ) );
+ address.setPostalCode( QLatin1String( "12345" ) );
+ address.setLocality( QLatin1String( "Lummerstadt" ) );
+ address.setCountry ( QLatin1String( "Germany" ) );
+
+ const QString result( QLatin1String( "Jim Knopf\nLummerlandstr. 1\n"
+ "12345 Lummerstadt\n\nGERMANY" ) );
+
+ QCOMPARE( address.formattedAddress( QLatin1String( "Jim Knopf" ) ), result );
+ }
+
+ {
+ KABC::Address address;
+ address.setStreet( QLatin1String( "457 Foobar Ave" ) );
+ address.setPostalCode( QLatin1String( "1A2B3C" ) );
+ address.setLocality( QLatin1String( "Nervousbreaktown" ) );
+ address.setRegion( QLatin1String( "DC" ) );
+ address.setCountry( QLatin1String( "United States of America" ) );
+
+ const QString result(
+ QLatin1String( "Huck Finn\n457 Foobar Ave\nNervousbreaktown,"
+ " DC 1A2B3C\n\nUNITED STATES OF AMERICA" ) );
+ QCOMPARE( address.formattedAddress( QLatin1String( "Huck Finn" ) ), result );
+ }
+
+ {
+ KABC::Address address;
+ address.setStreet( QLatin1String( "Lummerlandstr. 1" ) );
+ address.setPostalCode( QLatin1String( "12345" ) );
+ address.setLocality( QLatin1String( "Lummerstadt" ) );
+ address.setCountry( QLatin1String( "Deutschland" ) );
+
+ const QString result( QLatin1String( "Jim Knopf\nLummerlandstr. 1\n"
+ "12345 Lummerstadt\n\nDEUTSCHLAND" ) );
+
+ QCOMPARE( address.formattedAddress( QLatin1String( "Jim Knopf" ) ), result );
+ }
+
+ {
+ KABC::Address address;
+ address.setStreet( QLatin1String( "Lummerlandstr. 1" ) );
+ address.setPostalCode( QLatin1String( "12345" ) );
+ address.setLocality( QLatin1String( "Lummerstadt" ) );
+ address.setCountry( QString() );
+
+ const QString result( QLatin1String( "Jim Knopf\nLummerlandstr. 1\nLummerstadt, 12345" ) );
+
+ QCOMPARE( address.formattedAddress( QLatin1String( "Jim Knopf" ) ), result );
+ }
+}
+
diff --git a/kabc/tests/addresstest.h b/kabc/tests/addresstest.h
new file mode 100644
index 0000000..37325c6
--- /dev/null
+++ b/kabc/tests/addresstest.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ADDRESS_TEST_H
+#define ADDRESS_TEST_H
+
+#include <QtCore/QObject>
+
+class AddressTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void emptyTest();
+ void storeTest();
+ void equalsTest();
+ void differsTest();
+ void assignmentTest();
+ void serializeTest();
+ void formatTest();
+};
+
+#endif
diff --git a/kabc/tests/bigread.cpp b/kabc/tests/bigread.cpp
new file mode 100644
index 0000000..00e96c3
--- /dev/null
+++ b/kabc/tests/bigread.cpp
@@ -0,0 +1,80 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 KDE-PIM team <kde-pim@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kabc/plugins/file/resourcefile.h"
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+
+#include <sys/times.h>
+
+using namespace KABC;
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "bigread", 0, ki18n( "BigReadKabc" ), "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication app( false );
+
+ AddressBook ab;
+
+ ResourceFile r( QLatin1String( "my.kabc" ), QLatin1String( "vcard2" ) );
+ ab.addResource( &r );
+
+#if 0
+ ResourceSql rsql( &ab, "root", "kde4ever", "localhost" );
+ ab.addResource( &rsql );
+#endif
+
+ struct tms start;
+
+ times( &start );
+
+#if 0
+ kDebug() << "utime :" << int( start.tms_utime );
+ kDebug() << "stime :" << int( start.tms_stime );
+ kDebug() << "cutime:" << int( start.tms_cutime );
+ kDebug() << "cstime:" << int( start.tms_cstime );
+#endif
+
+ kDebug() << "Start load";
+ ab.load();
+ kDebug() << "Finished load";
+
+ struct tms end;
+
+ times( &end );
+
+#if 0
+ kDebug() << "utime :" << int( end.tms_utime );
+ kDebug() << "stime :" << int( end.tms_stime );
+ kDebug() << "cutime:" << int( end.tms_cutime );
+ kDebug() << "cstime:" << int( end.tms_cstime );
+#endif
+
+ kDebug() << "UTime:" << int( end.tms_utime ) - int( start.tms_utime );
+ kDebug() << "STime:" << int( end.tms_stime ) - int( start.tms_stime );
+
+// ab.dump();
+}
diff --git a/kabc/tests/bigwrite.cpp b/kabc/tests/bigwrite.cpp
new file mode 100644
index 0000000..216c943
--- /dev/null
+++ b/kabc/tests/bigwrite.cpp
@@ -0,0 +1,90 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 KDE-PIM team <kde-pim@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kabc/addressbook.h"
+#include "kabc/vcardformat.h"
+#include "kabc/plugins/file/resourcefile.h"
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+
+#include <sys/times.h>
+
+using namespace KABC;
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "bigwrite", 0, ki18n( "BigWriteKabc" ), "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication app( false );
+
+ AddressBook ab;
+ ResourceFile r( QLatin1String( "my.kabc" ), QLatin1String( "vcard" ) );
+ ab.addResource( &r );
+
+ for ( int i = 0; i < 5000; ++i ) {
+ Addressee a;
+ a.setGivenName( QLatin1String( "number" ) + QString::number( i ) );
+ a.setFamilyName( QLatin1String( "Name" ) );
+ a.insertEmail( QString::number( i ) + QLatin1String( "@domain" ) );
+
+ ab.insertAddressee( a );
+ }
+ printf( "\n" );
+
+ Ticket *t = ab.requestSaveTicket( &r );
+ if ( t ) {
+ struct tms start;
+
+ times( &start );
+
+#if 0
+ kDebug() << "utime :" << int( start.tms_utime );
+ kDebug() << "stime :" << int( start.tms_stime );
+ kDebug() << "cutime:" << int( start.tms_cutime );
+ kDebug() << "cstime:" << int( start.tms_cstime );
+#endif
+
+ if ( !ab.save( t ) ) {
+ kDebug() << "Can't save.";
+ }
+
+ struct tms end;
+
+ times( &end );
+
+#if 0
+ kDebug() << "utime :" << int( end.tms_utime );
+ kDebug() << "stime :" << int( end.tms_stime );
+ kDebug() << "cutime:" << int( end.tms_cutime );
+ kDebug() << "cstime:" << int( end.tms_cstime );
+#endif
+
+ kDebug() << "UTime:" << int( end.tms_utime ) - int( start.tms_utime );
+ kDebug() << "STime:" << int( end.tms_stime ) - int( start.tms_stime );
+
+ } else {
+ kDebug() << "No ticket for save.";
+ }
+}
diff --git a/kabc/tests/contactgrouptest.cpp b/kabc/tests/contactgrouptest.cpp
new file mode 100644
index 0000000..8eb3af4
--- /dev/null
+++ b/kabc/tests/contactgrouptest.cpp
@@ -0,0 +1,380 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qtest_kde.h>
+
+#include "kabc/contactgroup.h"
+#include "kabc/contactgrouptool.h"
+
+#include <QBuffer>
+
+using namespace KABC;
+
+class ContactGroupTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void contactGroupContactReference();
+ void contactGroupContactGroupReference();
+ void contactGroupData();
+ void contactGroup();
+ void testGroupRoundTrip();
+ void testGroupListRoundTrip();
+};
+
+QTEST_KDEMAIN( ContactGroupTest, NoGUI )
+
+void ContactGroupTest::contactGroupContactReference()
+{
+ const QLatin1String uid( "MyReferenceId" );
+ const QLatin1String preferredEMail( "tokoe@kde.org" );
+ const QLatin1String customKey( "MyCustomKey" );
+ const QLatin1String customValue( "MyCustomValue" );
+
+ // uid test
+ {
+ ContactGroup::ContactReference ref( uid );
+ QCOMPARE( ref.uid(), uid );
+ }
+
+ // uid test
+ {
+ ContactGroup::ContactReference ref;
+ ref.setUid( uid );
+ QCOMPARE( ref.uid(), uid );
+ }
+
+ // preferredEmail test
+ {
+ ContactGroup::ContactReference ref( uid );
+ ref.setPreferredEmail( preferredEMail );
+ QCOMPARE( ref.preferredEmail(), preferredEMail );
+ }
+
+ // custom test
+ {
+ ContactGroup::ContactReference ref( uid );
+ ref.insertCustom( customKey, customValue );
+ QCOMPARE( ref.custom( customKey ), customValue );
+ ref.removeCustom( customKey );
+ QCOMPARE( ref.custom( customKey ), QString() );
+ }
+
+ // assignment test
+ {
+ ContactGroup::ContactReference ref( uid );
+ ref.setPreferredEmail( preferredEMail );
+ ref.insertCustom( customKey, customValue );
+
+ ContactGroup::ContactReference ref2( ref );
+ QCOMPARE( ref.uid(), ref2.uid() );
+ QCOMPARE( ref.preferredEmail(), ref2.preferredEmail() );
+ QCOMPARE( ref.custom( customKey ), ref2.custom( customKey ) );
+
+ QVERIFY( ref == ref2 );
+ }
+
+ // const test
+ {
+ ContactGroup::ContactReference ref( uid );
+ ref.setPreferredEmail( preferredEMail );
+ ref.insertCustom( customKey, customValue );
+
+ const ContactGroup::ContactReference constRef( ref );
+ constRef.uid();
+ constRef.preferredEmail();
+ constRef.custom( customKey );
+ }
+}
+
+void ContactGroupTest::contactGroupContactGroupReference()
+{
+ const QLatin1String uid( "MyReferenceId" );
+ const QLatin1String customKey( "MyCustomKey" );
+ const QLatin1String customValue( "MyCustomValue" );
+
+ // uid test
+ {
+ ContactGroup::ContactGroupReference ref( uid );
+ QCOMPARE( ref.uid(), uid );
+ }
+
+ // uid test
+ {
+ ContactGroup::ContactGroupReference ref;
+ ref.setUid( uid );
+ QCOMPARE( ref.uid(), uid );
+ }
+
+ // custom test
+ {
+ ContactGroup::ContactGroupReference ref( uid );
+ ref.insertCustom( customKey, customValue );
+ QCOMPARE( ref.custom( customKey ), customValue );
+ ref.removeCustom( customKey );
+ QCOMPARE( ref.custom( customKey ), QString() );
+ }
+
+ // assignment test
+ {
+ ContactGroup::ContactGroupReference ref( uid );
+ ref.insertCustom( customKey, customValue );
+
+ ContactGroup::ContactGroupReference ref2( ref );
+ QCOMPARE( ref.uid(), ref2.uid() );
+ QCOMPARE( ref.custom( customKey ), ref2.custom( customKey ) );
+
+ QVERIFY( ref == ref2 );
+ }
+
+ // const test
+ {
+ ContactGroup::ContactGroupReference ref( uid );
+ ref.insertCustom( customKey, customValue );
+
+ const ContactGroup::ContactGroupReference constRef( ref );
+ constRef.uid();
+ constRef.custom( customKey );
+ }
+}
+
+void ContactGroupTest::contactGroupData()
+{
+ const QLatin1String name( "Tobias Koenig" );
+ const QLatin1String email( "tokoe@kde.org" );
+ const QLatin1String customKey( "MyCustomKey" );
+ const QLatin1String customValue( "MyCustomValue" );
+
+ // name/email test
+ {
+ ContactGroup::Data data( name, email );
+ QCOMPARE( data.name(), name );
+ QCOMPARE( data.email(), email );
+ }
+
+ // name test
+ {
+ ContactGroup::Data data;
+ data.setName( name );
+ QCOMPARE( data.name(), name );
+ }
+
+ // email test
+ {
+ ContactGroup::Data data;
+ data.setEmail( email );
+ QCOMPARE( data.email(), email );
+ }
+
+ // custom test
+ {
+ ContactGroup::Data data( name, email );
+ data.insertCustom( customKey, customValue );
+ QCOMPARE( data.custom( customKey ), customValue );
+ data.removeCustom( customKey );
+ QCOMPARE( data.custom( customKey ), QString() );
+ }
+
+ // assignment test
+ {
+ ContactGroup::Data data( name, email );
+ data.insertCustom( customKey, customValue );
+
+ ContactGroup::Data data2( data );
+ QCOMPARE( data.name(), data2.name() );
+ QCOMPARE( data.email(), data2.email() );
+ QCOMPARE( data.custom( customKey ), data2.custom( customKey ) );
+
+ QVERIFY( data == data2 );
+ }
+
+ // const test
+ {
+ ContactGroup::Data data( name, email );
+ data.insertCustom( customKey, customValue );
+
+ const ContactGroup::Data constData( data );
+ constData.name();
+ constData.email();
+ constData.custom( customKey );
+ }
+}
+
+void ContactGroupTest::contactGroup()
+{
+ const QLatin1String groupName( "MyGroupName" );
+ const QLatin1String groupId( "MyGroupID" );
+ const QLatin1String name( "Tobias Koenig" );
+ const QLatin1String email( "tokoe@kde.org" );
+ const QLatin1String uid( "MyUid" );
+
+ // name test
+ {
+ ContactGroup group( groupName );
+ QCOMPARE( group.name(), groupName );
+ }
+
+ // id test
+ {
+ ContactGroup group( groupName );
+ group.setId( groupId );
+ QCOMPARE( group.id(), groupId );
+ }
+
+ // contact reference test
+ {
+ ContactGroup group( groupName );
+ QCOMPARE( group.contactReferenceCount(), (unsigned int)0 );
+
+ ContactGroup::ContactReference ref( uid );
+ ref.setPreferredEmail( email );
+
+ group.append( ref );
+ QCOMPARE( group.contactReferenceCount(), (unsigned int)1 );
+
+ const ContactGroup::ContactReference ref2 = group.contactReference( 0 );
+ QCOMPARE( ref, ref2 );
+
+ group.remove( ref );
+ QCOMPARE( group.contactReferenceCount(), (unsigned int)0 );
+ }
+
+ // contact group reference test
+ {
+ ContactGroup group( groupName );
+ QCOMPARE( group.contactGroupReferenceCount(), (unsigned int)0 );
+
+ ContactGroup::ContactGroupReference ref( uid );
+
+ group.append( ref );
+ QCOMPARE( group.contactGroupReferenceCount(), (unsigned int)1 );
+
+ const ContactGroup::ContactGroupReference ref2 = group.contactGroupReference( 0 );
+ QCOMPARE( ref, ref2 );
+
+ group.remove( ref );
+ QCOMPARE( group.contactGroupReferenceCount(), (unsigned int)0 );
+ }
+
+ // data test
+ {
+ ContactGroup group( groupName );
+ QCOMPARE( group.dataCount(), (unsigned int)0 );
+
+ ContactGroup::Data data( name, email );
+
+ group.append( data );
+ QCOMPARE( group.dataCount(), (unsigned int)1 );
+
+ const ContactGroup::Data data2 = group.data( 0 );
+ QCOMPARE( data, data2 );
+
+ group.remove( data );
+ QCOMPARE( group.dataCount(), (unsigned int)0 );
+ }
+
+ // mimetype test
+ {
+ ContactGroup group( groupName );
+ QCOMPARE( group.mimeType(), QLatin1String( "application/x-vnd.kde.contactgroup" ) );
+ }
+}
+
+void ContactGroupTest::testGroupRoundTrip()
+{
+ // TODO should also test empty group
+
+ ContactGroup group( QLatin1String( "TestGroup" ) );
+ group.append( ContactGroup::ContactReference( QLatin1String( "Xggdjetw" ) ) );
+ group.append( ContactGroup::ContactGroupReference( QLatin1String( "aaXggdjetw" ) ) );
+ group.append( ContactGroup::Data( QLatin1String( "Tobias Koenig" ),
+ QLatin1String( "tokoe@kde.org" ) ) );
+ group.append( ContactGroup::Data( QLatin1String( "Kevin Krammer" ),
+ QLatin1String( "kevin.krammer@gmx.at" ) ) );
+
+ QBuffer buffer;
+ buffer.open( QIODevice::WriteOnly );
+
+ QString errorMessage;
+ bool result = ContactGroupTool::convertToXml( group, &buffer, &errorMessage );
+
+ QVERIFY( result );
+ QVERIFY( errorMessage.isEmpty() );
+ buffer.close();
+ QVERIFY( buffer.size() > 0 );
+ buffer.open( QIODevice::ReadOnly );
+
+ ContactGroup group2;
+ result = ContactGroupTool::convertFromXml( &buffer, group2, &errorMessage );
+ QVERIFY( result );
+ QVERIFY( errorMessage.isEmpty() );
+ QCOMPARE( group, group2 );
+}
+
+void ContactGroupTest::testGroupListRoundTrip()
+{
+ // TODO should also test empty list
+
+ ContactGroup::List list;
+
+ ContactGroup group1( QLatin1String( "TestGroup1" ) );
+ group1.append( ContactGroup::ContactReference( QLatin1String( "Xggdjetw" ) ) );
+ group1.append( ContactGroup::Data( QLatin1String( "Tobias Koenig" ),
+ QLatin1String( "tokoe@kde.org" ) ) );
+ group1.append( ContactGroup::Data( QLatin1String( "Kevin Krammer" ),
+ QLatin1String( "kevin.krammer@gmx.at" ) ) );
+
+ list.append( group1 );
+
+ ContactGroup group2( QLatin1String( "TestGroup2" ) );
+ group2.append( ContactGroup::ContactReference( QLatin1String( "Xggdjetw" ) ) );
+ group2.append( ContactGroup::Data( QLatin1String( "Tobias Koenig" ),
+ QLatin1String( "tokoe@kde.org" ) ) );
+ group2.append( ContactGroup::Data( QLatin1String( "Kevin Krammer" ),
+ QLatin1String( "kevin.krammer@gmx.at" ) ) );
+
+ list.append( group2 );
+
+ QBuffer buffer;
+ buffer.open( QIODevice::WriteOnly );
+
+ QString errorMessage;
+ bool result = ContactGroupTool::convertToXml( list, &buffer, &errorMessage );
+
+ QVERIFY( result );
+ QVERIFY( errorMessage.isEmpty() );
+ buffer.close();
+ QVERIFY( buffer.size() > 0 );
+
+ buffer.open( QIODevice::ReadOnly );
+
+ ContactGroup::List list2;
+ result = ContactGroupTool::convertFromXml( &buffer, list2, &errorMessage );
+ QVERIFY( result );
+ QVERIFY( errorMessage.isEmpty() );
+ QVERIFY( list2.size() == 2 );
+ QCOMPARE( list2[0], group1 );
+ QCOMPARE( list2[1], group2 );
+}
+
+#include "contactgrouptest.moc"
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/kabc/tests/geotest.cpp b/kabc/tests/geotest.cpp
new file mode 100644
index 0000000..1322fc8
--- /dev/null
+++ b/kabc/tests/geotest.cpp
@@ -0,0 +1,91 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 KDE-PIM team <kde-pim@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "geotest.h"
+#include "kabc/geo.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( GeoTest, NoGUI )
+
+void GeoTest::constructor()
+{
+ KABC::Geo geo( 1.2f, 3.4f );
+
+ QVERIFY( (float)geo.latitude() == (float)1.2 );
+ QVERIFY( (float)geo.longitude() == (float)3.4 );
+}
+
+void GeoTest::isValid()
+{
+ KABC::Geo geo;
+
+ QVERIFY( !geo.isValid() );
+
+ geo.setLatitude( 23 );
+
+ QVERIFY( !geo.isValid() );
+
+ geo.setLongitude( 45 );
+
+ QVERIFY( geo.isValid() );
+}
+
+void GeoTest::setData()
+{
+ KABC::Geo geo;
+
+ geo.setLatitude( 22.5f );
+ geo.setLongitude( 45.1f );
+
+ QVERIFY( (float)geo.latitude() == (float)22.5 );
+ QVERIFY( (float)geo.longitude() == (float)45.1 );
+}
+
+void GeoTest::equals()
+{
+ KABC::Geo geo1( 22.5f, 33.7f );
+ KABC::Geo geo2( 22.5f, 33.7f );
+
+ QVERIFY( geo1 == geo2 );
+}
+
+void GeoTest::differs()
+{
+ KABC::Geo geo1( 22.5f, 33.7f );
+ KABC::Geo geo2( 22.5f, 33.6f );
+
+ QVERIFY( geo1 != geo2 );
+}
+
+void GeoTest::serialization()
+{
+ KABC::Geo geo1( 22.5f, 33.7f );
+ QByteArray data;
+
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << geo1;
+
+ KABC::Geo geo2;
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> geo2;
+
+ QVERIFY( geo1 == geo2 );
+}
+
diff --git a/kabc/tests/geotest.h b/kabc/tests/geotest.h
new file mode 100644
index 0000000..305920e
--- /dev/null
+++ b/kabc/tests/geotest.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 KDE-PIM team <kde-pim@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef GEOTEST_H
+#define GEOTEST_H
+
+#include <QtCore/QObject>
+
+class GeoTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void constructor();
+ void isValid();
+ void setData();
+ void equals();
+ void differs();
+ void serialization();
+};
+
+#endif
diff --git a/kabc/tests/kabcargl.cpp b/kabc/tests/kabcargl.cpp
new file mode 100644
index 0000000..b87655d
--- /dev/null
+++ b/kabc/tests/kabcargl.cpp
@@ -0,0 +1,70 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kabc/stdaddressbook.h"
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kcmdlineargs.h>
+#include <kstandarddirs.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <QtCore/QTextCodec>
+#include <QtCore/QRegExp>
+
+using namespace KABC;
+
+int main( int argc, char **argv )
+{
+ KAboutData aboutData( "kabcargl", 0, ki18n( "Fix broken pre3.0rc3 format" ), "0.1" );
+ aboutData.addAuthor( ki18n( "Cornelius Schumacher" ), KLocalizedString(), "schumacher@kde.org" );
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication app;
+
+ QString filename = StdAddressBook::fileName();
+
+ QFile f( filename );
+ if ( !f.open( QIODevice::ReadOnly ) ) {
+ kDebug() << "Error opening file '" << filename << "' for reading.";
+ return 1;
+ }
+
+ QTextStream t( &f );
+ t.setCodec( QTextCodec::codecForName( "UTF-8" ) );
+ QString text = t.readAll();
+ f.close();
+
+ text = QString::fromUtf8( text.toLocal8Bit() );
+ text.replace( QLatin1String( "\n" ), QLatin1String( "\r\n" ) );
+
+ if ( !f.open( QIODevice::WriteOnly ) ) {
+ kDebug() << "Error opening file '" << filename << "' for writing.";
+ return 1;
+ }
+
+ QTextStream t2( &f );
+ t2.setCodec( QTextCodec::codecForName( "UTF-8" ) );
+ t2 << text;
+ f.close();
+}
diff --git a/kabc/tests/keytest.cpp b/kabc/tests/keytest.cpp
new file mode 100644
index 0000000..1c631d1
--- /dev/null
+++ b/kabc/tests/keytest.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "keytest.h"
+#include "kabc/key.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( KeyTest, NoGUI )
+
+void KeyTest::storeTest()
+{
+ KABC::Key key;
+
+ key.setId( QLatin1String( "My Id" ) );
+ key.setType( KABC::Key::Custom );
+ key.setCustomTypeString( QLatin1String( "GnuPG" ) );
+ key.setTextData( QLatin1String( "That's my super secret key" ) );
+
+ QVERIFY( key.id() == QLatin1String( "My Id" ) );
+ QVERIFY( key.type() == KABC::Key::Custom );
+ QVERIFY( key.customTypeString() == QLatin1String( "GnuPG" ) );
+ QVERIFY( key.textData() == QLatin1String( "That's my super secret key" ) );
+ QVERIFY( key.isBinary() == false );
+}
+
+void KeyTest::equalsTest()
+{
+ KABC::Key key1, key2;
+
+ key1.setId( QLatin1String( "My Id" ) );
+ key1.setType( KABC::Key::Custom );
+ key1.setCustomTypeString( QLatin1String( "GnuPG" ) );
+ key1.setTextData( QLatin1String( "That's my super secret key" ) );
+
+ key2.setId( QLatin1String( "My Id" ) );
+ key2.setType( KABC::Key::Custom );
+ key2.setCustomTypeString( QLatin1String( "GnuPG" ) );
+ key2.setTextData( QLatin1String( "That's my super secret key" ) );
+
+ QVERIFY( key1 == key2 );
+}
+
+void KeyTest::differsTest()
+{
+ KABC::Key key1( QLatin1String( "TextKey" ), KABC::Key::PGP );
+ KABC::Key key2( QLatin1String( "TextKey" ), KABC::Key::Custom );
+
+ QVERIFY( key1 != key2 );
+}
+
+void KeyTest::assignmentTest()
+{
+ KABC::Key key1, key2;
+
+ key1.setId( QLatin1String( "My Id" ) );
+ key1.setType( KABC::Key::Custom );
+ key1.setCustomTypeString( QLatin1String( "GnuPG" ) );
+ key1.setTextData( QLatin1String( "That's my super secret key" ) );
+
+ key2 = key1;
+
+ QVERIFY( key1 == key2 );
+}
+
+void KeyTest::serializeTest()
+{
+ KABC::Key key1, key2;
+
+ key1.setId( QLatin1String( "My Id" ) );
+ key1.setType( KABC::Key::Custom );
+ key1.setCustomTypeString( QLatin1String( "GnuPG" ) );
+ key1.setTextData( QLatin1String( "That's my super secret key" ) );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << key1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> key2;
+
+ QVERIFY( key1 == key2 );
+}
+
diff --git a/kabc/tests/keytest.h b/kabc/tests/keytest.h
new file mode 100644
index 0000000..80a7bb5
--- /dev/null
+++ b/kabc/tests/keytest.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KEY_TEST_H
+#define KEY_TEST_H
+
+#include <QtCore/QObject>
+
+class KeyTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void storeTest();
+ void equalsTest();
+ void differsTest();
+ void assignmentTest();
+ void serializeTest();
+};
+
+#endif
diff --git a/kabc/tests/phonenumbertest.cpp b/kabc/tests/phonenumbertest.cpp
new file mode 100644
index 0000000..7d7103b
--- /dev/null
+++ b/kabc/tests/phonenumbertest.cpp
@@ -0,0 +1,173 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "phonenumbertest.h"
+#include "kabc/phonenumber.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( PhoneNumberTest, NoGUI )
+
+void PhoneNumberTest::emptyTest()
+{
+ KABC::PhoneNumber number;
+
+ QVERIFY( number.isEmpty() );
+}
+
+void PhoneNumberTest::storeTest()
+{
+ KABC::PhoneNumber number;
+
+ number.setId( QLatin1String( "My Id" ) );
+ number.setType( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
+ number.setNumber( QLatin1String( "2734826345" ) );
+
+ QVERIFY( number.id() == QLatin1String( "My Id" ) );
+ QVERIFY( number.type() == ( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell ) );
+ QVERIFY( number.number() == QLatin1String( "2734826345" ) );
+}
+
+void PhoneNumberTest::equalsTest()
+{
+ KABC::PhoneNumber number1, number2;
+
+ number1.setId( QLatin1String( "My Id" ) );
+ number1.setType( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
+ number1.setNumber( QLatin1String( "2734826345" ) );
+
+ number2.setId( QLatin1String( "My Id" ) );
+ number2.setType( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
+ number2.setNumber( QLatin1String( "2734826345" ) );
+
+ QVERIFY( number1 == number2 );
+}
+
+void PhoneNumberTest::differsTest()
+{
+ KABC::PhoneNumber number1( QLatin1String( "123" ), KABC::PhoneNumber::Home );
+ KABC::PhoneNumber number2( QLatin1String( "123" ), KABC::PhoneNumber::Work );
+
+ QVERIFY( number1 != number2 );
+}
+
+void PhoneNumberTest::assignmentTest()
+{
+ KABC::PhoneNumber number1, number2;
+
+ number1.setId( QLatin1String( "My Id" ) );
+ number1.setType( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
+ number1.setNumber( QLatin1String( "2734826345" ) );
+
+ number1 = number2;
+
+ QVERIFY( number1 == number2 );
+}
+
+void PhoneNumberTest::serializeTest()
+{
+ KABC::PhoneNumber number1, number2;
+
+ number1.setId( QLatin1String( "My Id" ) );
+ number1.setType( KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell );
+ number1.setNumber( QLatin1String( "2734826345" ) );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << number1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> number2;
+
+ QVERIFY( number1 == number2 );
+}
+
+void PhoneNumberTest::labelTest()
+{
+ QMap<KABC::PhoneNumber::Type, QString> labels;
+
+ const KABC::PhoneNumber::TypeList types = KABC::PhoneNumber::typeList();
+
+ // check all types standalone
+ Q_FOREACH( KABC::PhoneNumber::Type type, types ) {
+ const KABC::PhoneNumber phone( QLatin1String( "1" ), type );
+ QCOMPARE( phone.type(), type );
+
+ // Pref is special cased
+ if ( type != KABC::PhoneNumber::Pref ) {
+ QCOMPARE( phone.typeLabel(), KABC::PhoneNumber::typeFlagLabel( (KABC::PhoneNumber::TypeFlag)(int)type ) );
+ labels.insert( type, phone.typeLabel() );
+ } else {
+ labels.insert( type, KABC::PhoneNumber::typeFlagLabel( (KABC::PhoneNumber::TypeFlag)(int)type ) );
+ }
+ QCOMPARE( KABC::PhoneNumber::typeLabel( type ), phone.typeLabel() );
+ }
+
+ // combine all with Pref
+ Q_FOREACH( KABC::PhoneNumber::Type type, types ) {
+ KABC::PhoneNumber::Type combinedType = type | KABC::PhoneNumber::Pref;
+ const KABC::PhoneNumber phone( QLatin1String( "1" ), combinedType );
+ QCOMPARE( phone.type(), combinedType );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( combinedType ), phone.typeLabel() );
+
+ if ( type < KABC::PhoneNumber::Pref ) {
+ const QString expectedCombinedString = QString::fromLatin1( "%1/%2" ).arg( labels[ type ] ).arg( labels[ KABC::PhoneNumber::Pref ] );
+ QCOMPARE( phone.typeLabel(), expectedCombinedString );
+ } else if ( type > KABC::PhoneNumber::Pref ) {
+ const QString expectedCombinedString = QString::fromLatin1( "%1/%2" ).arg( labels[ KABC::PhoneNumber::Pref ] ).arg( labels[ type ] );
+ QCOMPARE( phone.typeLabel(), expectedCombinedString );
+ }
+ }
+
+ // combine all with Fax
+ Q_FOREACH( KABC::PhoneNumber::Type type, types ) {
+ KABC::PhoneNumber::Type combinedType = type | KABC::PhoneNumber::Fax;
+ const KABC::PhoneNumber phone( QLatin1String( "1" ), combinedType );
+ QCOMPARE( phone.type(), combinedType );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( combinedType ), phone.typeLabel() );
+
+ if ( type == KABC::PhoneNumber::Home || type == KABC::PhoneNumber::Work ) {
+ // special cased
+ } else if ( type < KABC::PhoneNumber::Fax ) {
+ const QString expectedCombinedString = QString::fromLatin1( "%1/%2" ).arg( labels[ type ] ).arg( labels[ KABC::PhoneNumber::Fax ] );
+ QCOMPARE( phone.typeLabel(), expectedCombinedString );
+ } else if ( type > KABC::PhoneNumber::Fax ) {
+ const QString expectedCombinedString = QString::fromLatin1( "%1/%2" ).arg( labels[ KABC::PhoneNumber::Fax ] ).arg( labels[ type ] );
+ QCOMPARE( phone.typeLabel(), expectedCombinedString );
+ }
+ }
+
+ // special cases
+ QCOMPARE( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Pref ), QLatin1String( "Preferred Number" ) );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Home |
+ KABC::PhoneNumber::Fax ),
+ QLatin1String( "Home Fax" ) );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Work |
+ KABC::PhoneNumber::Fax ),
+ QLatin1String( "Work Fax" ) );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Home |
+ KABC::PhoneNumber::Fax |
+ KABC::PhoneNumber::Pref ),
+ QLatin1String( "Home Fax/Preferred" ) );
+ QCOMPARE( KABC::PhoneNumber::typeLabel( KABC::PhoneNumber::Work |
+ KABC::PhoneNumber::Fax |
+ KABC::PhoneNumber::Pref ),
+ QLatin1String( "Work Fax/Preferred" ) );
+}
+
diff --git a/kabc/tests/phonenumbertest.h b/kabc/tests/phonenumbertest.h
new file mode 100644
index 0000000..8d64171
--- /dev/null
+++ b/kabc/tests/phonenumbertest.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PHONENUMBER_TEST_H
+#define PHONENUMBER_TEST_H
+
+#include <QtCore/QObject>
+
+class PhoneNumberTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void emptyTest();
+ void storeTest();
+ void equalsTest();
+ void differsTest();
+ void assignmentTest();
+ void serializeTest();
+ void labelTest();
+};
+
+#endif
diff --git a/kabc/tests/picturetest.cpp b/kabc/tests/picturetest.cpp
new file mode 100644
index 0000000..6b5e2ea
--- /dev/null
+++ b/kabc/tests/picturetest.cpp
@@ -0,0 +1,152 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "picturetest.h"
+#include "kabc/picture.h"
+#include <QPainter>
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( PictureTest, NoGUI )
+
+static QImage testImage()
+{
+ static QImage image;
+
+ if ( image.isNull() ) {
+ image = QImage( 200, 200, QImage::Format_RGB32 );
+ QPainter p( &image );
+ p.drawRect( 10, 10, 50, 50 );
+ }
+
+ return image;
+}
+
+void PictureTest::emptyTest()
+{
+ KABC::Picture picture;
+
+ QVERIFY( picture.isEmpty() );
+}
+
+void PictureTest::storeTestIntern()
+{
+ KABC::Picture picture;
+
+ picture.setType( QLatin1String( "image/png" ) );
+ picture.setData( testImage() );
+
+ QVERIFY( picture.isIntern() == true );
+ QVERIFY( picture.type() == QLatin1String( QLatin1String( "image/png" ) ) );
+ QVERIFY( picture.data() == testImage() );
+}
+
+void PictureTest::storeTestExtern()
+{
+ KABC::Picture picture;
+
+ picture.setType( QLatin1String( "image/png" ) );
+ picture.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+
+ QVERIFY( picture.isIntern() == false );
+ QVERIFY( picture.type() == QLatin1String( QLatin1String( "image/png" ) ) );
+ QVERIFY( picture.url() == QLatin1String( QLatin1String( "http://myhomepage.com/foto.png" ) ) );
+}
+
+void PictureTest::equalsTestIntern()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setData( testImage() );
+
+ picture2.setType( QLatin1String( "image/png" ) );
+ picture2.setData( testImage() );
+
+ QVERIFY( picture1 == picture2 );
+}
+
+void PictureTest::equalsTestExtern()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+
+ picture2.setType( QLatin1String( "image/png" ) );
+ picture2.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+
+ QVERIFY( picture1 == picture2 );
+}
+
+void PictureTest::differsTest()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+
+ picture2.setType( QLatin1String( "image/png" ) );
+ picture2.setData( testImage() );
+
+ QVERIFY( picture1 != picture2 );
+}
+
+void PictureTest::assignmentTestIntern()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setData( testImage() );
+
+ picture2 = picture1;
+
+ QVERIFY( picture1 == picture2 );
+}
+
+void PictureTest::assignmentTestExtern()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+
+ picture2 = picture1;
+
+ QVERIFY( picture1 == picture2 );
+}
+
+void PictureTest::serializeTest()
+{
+ KABC::Picture picture1, picture2;
+
+ picture1.setType( QLatin1String( "image/png" ) );
+ picture1.setUrl( QLatin1String( "http://myhomepage.com/foto.png" ) );
+ picture1.setData( testImage() );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << picture1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> picture2;
+
+ QVERIFY( picture1 == picture2 );
+}
+
diff --git a/kabc/tests/picturetest.h b/kabc/tests/picturetest.h
new file mode 100644
index 0000000..2b33e18
--- /dev/null
+++ b/kabc/tests/picturetest.h
@@ -0,0 +1,42 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PICTURE_TEST_H
+#define PICTURE_TEST_H
+
+#include <QtCore/QObject>
+
+class PictureTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void emptyTest();
+ void storeTestIntern();
+ void storeTestExtern();
+ void equalsTestIntern();
+ void equalsTestExtern();
+ void differsTest();
+ void assignmentTestIntern();
+ void assignmentTestExtern();
+ void serializeTest();
+};
+
+#endif
diff --git a/kabc/tests/secrecytest.cpp b/kabc/tests/secrecytest.cpp
new file mode 100644
index 0000000..fc3cda0
--- /dev/null
+++ b/kabc/tests/secrecytest.cpp
@@ -0,0 +1,86 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "secrecytest.h"
+#include "kabc/secrecy.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( SecrecyTest, NoGUI )
+
+void SecrecyTest::emptyTest()
+{
+ KABC::Secrecy secrecy;
+
+ QVERIFY( secrecy.type() == KABC::Secrecy::Invalid );
+}
+
+void SecrecyTest::storeTest()
+{
+ KABC::Secrecy secrecy;
+
+ secrecy.setType( KABC::Secrecy::Private );
+
+ QVERIFY( secrecy.type() == KABC::Secrecy::Private );
+}
+
+void SecrecyTest::equalsTest()
+{
+ KABC::Secrecy secrecy1, secrecy2;
+
+ secrecy1.setType( KABC::Secrecy::Confidential );
+ secrecy2.setType( KABC::Secrecy::Confidential );
+
+ QVERIFY( secrecy1 == secrecy2 );
+}
+
+void SecrecyTest::differsTest()
+{
+ KABC::Secrecy secrecy1( KABC::Secrecy::Private );
+ KABC::Secrecy secrecy2( KABC::Secrecy::Confidential );
+
+ QVERIFY( secrecy1 != secrecy2 );
+}
+
+void SecrecyTest::assignmentTest()
+{
+ KABC::Secrecy secrecy1, secrecy2;
+
+ secrecy1.setType( KABC::Secrecy::Confidential );
+ secrecy1 = secrecy2;
+
+ QVERIFY( secrecy1 == secrecy2 );
+}
+
+void SecrecyTest::serializeTest()
+{
+ KABC::Secrecy secrecy1, secrecy2;
+
+ secrecy1.setType( KABC::Secrecy::Confidential );
+
+ QByteArray data;
+ QDataStream s( &data, QIODevice::WriteOnly );
+ s << secrecy1;
+
+ QDataStream t( &data, QIODevice::ReadOnly );
+ t >> secrecy2;
+
+ QVERIFY( secrecy1 == secrecy2 );
+}
+
diff --git a/kabc/tests/secrecytest.h b/kabc/tests/secrecytest.h
new file mode 100644
index 0000000..4342f73
--- /dev/null
+++ b/kabc/tests/secrecytest.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SECRECY_TEST_H
+#define SECRECY_TEST_H
+
+#include <QtCore/QObject>
+
+class SecrecyTest : public QObject
+{
+ Q_OBJECT
+
+ private Q_SLOTS:
+ void emptyTest();
+ void storeTest();
+ void equalsTest();
+ void differsTest();
+ void assignmentTest();
+ void serializeTest();
+};
+
+#endif
diff --git a/kabc/tests/soundtest.cpp b/kabc/tests/soundtest.cpp
new file mode 100644
index 0000000..5846d2d
--- /dev/null
+++ b/kabc/tests/soundtest.cpp
@@ -0,0 +1,135 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "soundtest.h"
+#include "kabc/sound.h"
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( SoundTest, NoGUI )
+
+static QByteArray testData()
+{
+ static QByteArray data;
+
+ if ( data.isNull() ) {
+ for ( int i = 0; i < 20; ++i ) {
+ data.append( char( i ) );
+ }
+ }
+
+ return data;
+}
+
+void SoundTest::emptyTest()
+{
+ KABC::Sound sound;
+
+ QVERIFY( sound.isEmpty() );
+}
+
+void SoundTest::storeTestIntern()
+{
+ KABC::Sound sound;
+
+ sound.setData( testData() );
+
+ QVERIFY( sound.isIntern() == true );
+ QVERIFY( sound.data() == testData() );
+}
+
+void SoundTest::storeTestExtern()
+{
+ KABC::Sound sound;
+
+ sound.setUrl( QLatin1String( "http://myhomepage.com/sound.wav" ) );
+
+ QVERIFY( sound.isIntern() == false );
+ QVERIFY( sound.url() == QLatin1String( QLatin1String( "http://myhomepage.com/sound.wav" ) ) );
+}
+
+void SoundTest::equalsTestIntern()
+{
+ KABC::Sound sound1, sound2;
+
+ sound1.setData( testData() );
+ sound2.setData( testData() );
+
+ QVERIFY( sound1 == sound2 );
+}
+
+void SoundTest::equalsTestExtern()
+{
+ KABC::Sound sound1, sound2;
+
+ sound1.setUrl( QLatin1String( "http://myhomepage.com/sound.wav" ) );
+ sound2.setUrl( QLatin1String( "http://myhomepage.com/sound.wav" ) );
+
+ QVERIFY( sound1 == sound2 );
+}
+
+void SoundTest::differsTest()
+{
+ KABC::Sound sound1, sound2;
+
+ sound1.setUrl( QLatin1String( "http://myhomepage.com/sound.wav" ) );
+ sound2.setData( testData() );
+
+ QVERIFY( sound1 != sound2 );
+}
+
+void SoundTest::assignmentTestIntern()
+{
+ KABC::Sound sound1, sound2;
+
+ sound1.setData( testData() );
+
+ sound2 = sound1;
+
+ QVERIFY( sound1 ==