diff options
Diffstat (limited to 'kabc')
307 files changed, 49938 insertions, 0 deletions
diff --git a/kabc/HACKING b/kabc/HACKING new file mode 100644 index 000000000..429ae0865 --- /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 000000000..37f7ccefe --- /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: kdDebug() << "Name = " << addr.formattedName() << endl; + 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: kdDebug() << "Unable to open resource" << endl; + 8: return 1; + 9: } +10: +11: if ( !ab.load() ) { +12: kdDebug() << "Unable to load address book!" << endl; +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: kdError() << "Resource is locked by other application!" << endl; +77: } else { +78: if ( !ab.save( ticket ) ) { +79: kdError() << "Saving failed!" << endl; +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: kdDebug() << list->name() << endl; +11: +12: QStringList emails = list->emails(); +13: QStringList::Iterator eit; +14: for ( eit = emails.begin(); eit != emails.end(); ++eit ) +15: kdDebug() << QString( "\t%1" ).arg( (*eit).latin1() ) << endl; +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/Makefile.am b/kabc/Makefile.am new file mode 100644 index 000000000..b41946f34 --- /dev/null +++ b/kabc/Makefile.am @@ -0,0 +1,72 @@ +SUBDIRS = vcard vcardparser . formats plugins scripts tests + +# Make sure $(all_includes) remains last! +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc -I$(top_srcdir)/kab \ + -I$(srcdir)/vcard/include -I$(srcdir)/vcardparser/ \ + -I$(srcdir)/vcard/include/generated \ + -I$(srcdir)/vcardparser $(all_includes) + +field.cpp: addressee.h addressee.cpp +addressee.cpp: addressee.h +addressee.cpp addressee.h field.cpp: \ + $(srcdir)/scripts/makeaddressee \ + $(srcdir)/scripts/addressee.src.cpp \ + $(srcdir)/scripts/addressee.src.h \ + $(srcdir)/scripts/entrylist \ + $(srcdir)/scripts/field.src.cpp + mysrcdir=`cd $(srcdir)/scripts && pwd` ;\ + cd scripts && $(PERL) $$mysrcdir/makeaddressee + +CLEANFILES = addressee.h addressee.cpp field.cpp + +lib_LTLIBRARIES = libkabc.la +libkabc_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 3:0:2 -no-undefined +libkabc_la_LIBADD = vcard/libvcard.la vcardparser/libvcards.la $(LIB_KIO) \ + $(top_builddir)/kresources/libkresources.la +libkabc_la_COMPILE_FIRST = addressee.h + +libkabc_la_SOURCES = \ + address.cpp addressbook.cpp addressee.cpp addresseedialog.cpp agent.cpp \ + distributionlist.cpp distributionlistdialog.cpp distributionlisteditor.cpp \ + errorhandler.cpp field.cpp formatfactory.cpp geo.cpp key.cpp \ + phonenumber.cpp picture.cpp plugin.cpp resource.cpp \ + resourceselectdialog.cpp secrecy.cpp sound.cpp stdaddressbook.cpp \ + timezone.cpp vcard21parser.cpp vcardconverter.cpp vcardformat.cpp \ + vcardformatimpl.cpp vcardformatplugin.cpp ldifconverter.cpp addresslineedit.cpp \ + ldapclient.cpp addresseelist.cpp vcardtool.cpp addresseehelper.cpp \ + addresseehelper.skel lock.cpp locknull.cpp ldif.cpp ldapurl.cpp ldapconfigwidget.cpp \ + sortmode.cpp + + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = address.h addressbook.h addressee.h addresseedialog.h \ + agent.h distributionlist.h distributionlistdialog.h distributionlisteditor.h \ + errorhandler.h field.h format.h formatfactory.h formatplugin.h geo.h key.h \ + phonenumber.h picture.h plugin.h resource.h \ + resourceselectdialog.h secrecy.h sound.h stdaddressbook.h timezone.h \ + vcardconverter.h vcardformat.h vcardformatplugin.h ldifconverter.h \ + addresslineedit.h ldapclient.h addresseelist.h lock.h locknull.h ldif.h \ + ldapurl.h ldapconfigwidget.h sortmode.h + +METASOURCES = AUTO + +bin_PROGRAMS = kab2kabc + +kab2kabc_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kab2kabc_LDADD = libkabc.la ../kab/libkab.la +kab2kabc_SOURCES = kab2kabc.cpp + +autostart_DATA = kab2kabc.desktop +autostartdir = $(datadir)/autostart + +manager_DATA = kabc_manager.desktop +managerdir = $(kde_servicesdir)/kresources + +DOXYGEN_REFERENCES = kdecore kdeui + +map_DATA = countrytransl.map +mapdir = $(kde_datadir)/kabc + +EXTRA_DIST = $(map_DATA) + +include ../admin/Doxyfile.am diff --git a/kabc/README b/kabc/README new file mode 100644 index 000000000..4aa9a063e --- /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: LPGL + +DATE: 13 Oct 2001 diff --git a/kabc/README.AddressFormat b/kabc/README.AddressFormat new file mode 100644 index 000000000..8079e4914 --- /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 000000000..41644b818 --- /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 000000000..0db0f8236 --- /dev/null +++ b/kabc/address.cpp @@ -0,0 +1,592 @@ +/* + 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 <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kstaticdeleter.h> + +#include <qfile.h> + +using namespace KABC; + +QMap<QString, QString> *Address::mISOMap = 0; +static KStaticDeleter< QMap<QString, QString> > isoMapDeleter; + +Address::Address() : + mEmpty( true ), mType( 0 ) +{ + mId = KApplication::randomString( 10 ); +} + +Address::Address( int type ) : + mEmpty( true ), mType( type ) +{ + mId = KApplication::randomString( 10 ); +} + +bool Address::operator==( const Address &a ) const +{ + if ( mPostOfficeBox != a.mPostOfficeBox ) return false; + if ( mExtended != a.mExtended ) return false; + if ( mStreet != a.mStreet ) return false; + if ( mLocality != a.mLocality ) return false; + if ( mRegion != a.mRegion ) return false; + if ( mPostalCode != a.mPostalCode ) return false; + if ( mCountry != a.mCountry ) return false; + if ( mLabel != a.mLabel ) return false; + + return true; +} + +bool Address::operator!=( const Address &a ) const +{ + return !( a == *this ); +} + +bool Address::isEmpty() const +{ + if ( mPostOfficeBox.isEmpty() && + mExtended.isEmpty() && + mStreet.isEmpty() && + mLocality.isEmpty() && + mRegion.isEmpty() && + mPostalCode.isEmpty() && + mCountry.isEmpty() && + mLabel.isEmpty() ) { + return true; + } + return false; +} + +void Address::clear() +{ + *this = Address(); +} + +void Address::setId( const QString &id ) +{ + mEmpty = false; + + mId = id; +} + +QString Address::id() const +{ + return mId; +} + +void Address::setType( int type ) +{ + mEmpty = false; + + mType = type; +} + +int Address::type() const +{ + return 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 ) ) { + label.append( ( first ? "" : "/" ) + typeLabel( *it ) ); + if ( first ) + first = false; + } + } + + return label; +} + +void Address::setPostOfficeBox( const QString &s ) +{ + mEmpty = false; + + mPostOfficeBox = s; +} + +QString Address::postOfficeBox() const +{ + return mPostOfficeBox; +} + +QString Address::postOfficeBoxLabel() +{ + return i18n("Post Office Box"); +} + + +void Address::setExtended( const QString &s ) +{ + mEmpty = false; + + mExtended = s; +} + +QString Address::extended() const +{ + return mExtended; +} + +QString Address::extendedLabel() +{ + return i18n("Extended Address Information"); +} + + +void Address::setStreet( const QString &s ) +{ + mEmpty = false; + + mStreet = s; +} + +QString Address::street() const +{ + return mStreet; +} + +QString Address::streetLabel() +{ + return i18n("Street"); +} + + +void Address::setLocality( const QString &s ) +{ + mEmpty = false; + + mLocality = s; +} + +QString Address::locality() const +{ + return mLocality; +} + +QString Address::localityLabel() +{ + return i18n("Locality"); +} + + +void Address::setRegion( const QString &s ) +{ + mEmpty = false; + + mRegion = s; +} + +QString Address::region() const +{ + return mRegion; +} + +QString Address::regionLabel() +{ + return i18n("Region"); +} + + +void Address::setPostalCode( const QString &s ) +{ + mEmpty = false; + + mPostalCode = s; +} + +QString Address::postalCode() const +{ + return mPostalCode; +} + +QString Address::postalCodeLabel() +{ + return i18n("Postal Code"); +} + + +void Address::setCountry( const QString &s ) +{ + mEmpty = false; + + mCountry = s; +} + +QString Address::country() const +{ + return mCountry; +} + +QString Address::countryLabel() +{ + return i18n("Country"); +} + + +void Address::setLabel( const QString &s ) +{ + mEmpty = false; + + mLabel = s; +} + +QString Address::label() const +{ + return 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( int type ) +{ + if ( type & Pref ) + return i18n( "Preferred address", "Preferred" ); + + switch ( type ) { + case Dom: + return i18n("Domestic"); + break; + case Intl: + return i18n("International"); + break; + case Postal: + return i18n("Postal"); + break; + case Parcel: + return i18n("Parcel"); + break; + case Home: + return i18n("Home Address", "Home"); + break; + case Work: + return i18n("Work Address", "Work"); + break; + case Pref: + return i18n("Preferred Address"); + break; + default: + return i18n("Other"); + break; + } +} + +void Address::dump() const +{ + kdDebug(5700) << " Address {" << endl; + kdDebug(5700) << " Id: " << id() << endl; + kdDebug(5700) << " Extended: " << extended() << endl; + kdDebug(5700) << " Street: " << street() << endl; + kdDebug(5700) << " Postal Code: " << postalCode() << endl; + kdDebug(5700) << " Locality: " << locality() << endl; + kdDebug(5700) << " }" << endl; +} + + +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(); + } + KSimpleConfig entry( locate( "locale", + QString( "l10n/" ) + ciso + QString( "/entry.desktop" ) ) ); + entry.setGroup( "KCM Locale" ); + + // decide whether this needs special business address formatting + if ( orgaName.isEmpty() ) { + addrTemplate = entry.readEntry( "AddressFormat" ); + } else { + addrTemplate = entry.readEntry( "BusinessAddressFormat" ); + if ( addrTemplate.isEmpty() ) + addrTemplate = entry.readEntry( "AddressFormat" ); + } + + // in the case there's no format found at all, default to what we've always + // used: + if ( addrTemplate.isEmpty() ) { + kdWarning(5700) << "address format database incomplete " + << "(no format for locale " << ciso + << " found). Using default address formatting." << endl; + addrTemplate = "%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 ); + + // now add the country line if needed (formatting this time according to + // the rules of our own system country ) + if ( !country().isEmpty() ) { + KSimpleConfig entry( locate( "locale", QString( "l10n/" ) + + KGlobal::locale()->country() + QString( "/entry.desktop" ) ) ); + entry.setGroup( "KCM Locale" ); + QString cpos = entry.readEntry( "AddressCountryPosition" ); + if ( "BELOW" == cpos || cpos.isEmpty() ) { + ret = ret + "\n\n" + country().upper(); + } else if ( "below" == cpos ) { + ret = ret + "\n\n" + country(); + } else if ( "ABOVE" == cpos ) { + ret = country().upper() + "\n\n" + ret; + } else if ( "above" == cpos ) { + ret = country() + "\n\n" + ret; + } + } + + return ret; +} + +bool Address::parseAddressTemplateSection( const QString &tsection, + QString &result, const QString &realName, const QString &orgaName ) const +{ + // 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.find( 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 ( '(' == 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 ); + if ( purge ) { + // purge -> remove all + // replace with !_P_!, so conditional tags work later + result.replace( fpos, bpos2 - fpos + 1, "!_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.find( 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.find(R_TAG, false) != -1 ) { \ + QString rpl = R_FIELD.isEmpty() ? QString("!_P_!") : R_FIELD; \ + result.replace( R_TAG, rpl ); \ + if ( !R_FIELD.isEmpty() ) { \ + ret = true; \ + } \ + } + REPLTAG( KABC_FMTTAG_realname, realName ); + REPLTAG( KABC_FMTTAG_REALNAME, realName.upper() ); + REPLTAG( KABC_FMTTAG_company, orgaName ); + REPLTAG( KABC_FMTTAG_COMPANY, orgaName.upper() ); + REPLTAG( KABC_FMTTAG_pobox, postOfficeBox() ); + REPLTAG( KABC_FMTTAG_street, street() ); + REPLTAG( KABC_FMTTAG_STREET, street().upper() ); + REPLTAG( KABC_FMTTAG_zipcode, postalCode() ); + REPLTAG( KABC_FMTTAG_location, locality() ); + REPLTAG( KABC_FMTTAG_LOCATION, locality().upper() ); + REPLTAG( KABC_FMTTAG_region, region() ); + REPLTAG( KABC_FMTTAG_REGION, region().upper() ); + result.replace( KABC_FMTTAG_newline, "\n" ); +#undef REPLTAG + + // conditional comma + fpos = result.find( KABC_FMTTAG_condcomma, 0 ); + while ( -1 != fpos ) { + QString str1 = result.mid( fpos - 5, 5 ); + QString str2 = result.mid( fpos + 2, 5 ); + if ( str1 != "!_P_!" && str2 != "!_P_!" ) { + result.replace( fpos, 2, ", " ); + } else { + result.remove( fpos, 2 ); + } + fpos = result.find( KABC_FMTTAG_condcomma, fpos ); + } + // conditional whitespace + fpos = result.find( KABC_FMTTAG_condwhite, 0 ); + while ( -1 != fpos ) { + QString str1 = result.mid( fpos - 5, 5 ); + QString str2 = result.mid( fpos + 2, 5 ); + if ( str1 != "!_P_!" && str2 != "!_P_!" ) { + result.replace( fpos, 2, " " ); + } else { + result.remove( fpos, 2 ); + } + fpos = result.find( KABC_FMTTAG_condwhite, fpos ); + } + + // remove purged: + result.remove( "!_P_!" ); + + return ret; +} + +int Address::findBalancedBracket( const QString &tsection, int pos ) const +{ + int balancecounter = 0; + for( unsigned int i = pos + 1; i < tsection.length(); i++ ) { + if ( ')' == tsection[i] && 0 == balancecounter ) { + // found end of brackets + return i; + } else + if ( '(' == tsection[i] ) { + // nested brackets + balancecounter++; + } + } + return -1; +} + +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. + if ( !mISOMap ) + isoMapDeleter.setObject( mISOMap, new QMap<QString, QString>() ); + + QMap<QString, QString>::ConstIterator it; + it = mISOMap->find( cname ); + if ( it != mISOMap->end() ) + return it.data(); + + QString mapfile = KGlobal::dirs()->findResource( "data", + QString::fromLatin1( "kabc/countrytransl.map" ) ); + + QFile file( mapfile ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream s( &file ); + QString strbuf = s.readLine(); + while( !strbuf.isEmpty() ) { + QStringList countryInfo = QStringList::split( '\t', strbuf, true ); + if ( countryInfo[ 0 ] == cname ) { + file.close(); + mISOMap->insert( cname, countryInfo[ 1 ] ); + return countryInfo[ 1 ]; + } + strbuf = s.readLine(); + } + file.close(); + } + + // fall back to system country + mISOMap->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.simplifyWhiteSpace().isEmpty() ) + return QString::null; + + QString mapfile = KGlobal::dirs()->findResource( "data", + QString::fromLatin1( "kabc/countrytransl.map" ) ); + + QFile file( mapfile ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream s( &file ); + QString searchStr = "\t" + ISOname.simplifyWhiteSpace().lower(); + QString strbuf = s.readLine(); + int pos; + while ( !strbuf.isEmpty() ) { + if ( (pos = strbuf.find( searchStr )) != -1 ) { + file.close(); + return i18n( strbuf.left( pos ).utf8() ); + } + strbuf = s.readLine(); + } + file.close(); + } + + return ISOname; +} + +QDataStream &KABC::operator<<( QDataStream &s, const Address &addr ) +{ + return s << addr.mId << addr.mType << addr.mPostOfficeBox << + addr.mExtended << addr.mStreet << addr.mLocality << + addr.mRegion << addr.mPostalCode << addr.mCountry << + addr.mLabel; +} + +QDataStream &KABC::operator>>( QDataStream &s, Address &addr ) +{ + s >> addr.mId >> addr.mType >> addr.mPostOfficeBox >> addr.mExtended >> + addr.mStreet >> addr.mLocality >> addr.mRegion >> + addr.mPostalCode >> addr.mCountry >> addr.mLabel; + + addr.mEmpty = false; + + return s; +} diff --git a/kabc/address.h b/kabc/address.h new file mode 100644 index 000000000..9125c71be --- /dev/null +++ b/kabc/address.h @@ -0,0 +1,341 @@ +/* + 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 <qmap.h> +#include <qstring.h> +#include <qvaluelist.h> + +#include <kdelibs_export.h> + +// template tags for address formatting localization +#define KABC_FMTTAG_realname QString("%n") +#define KABC_FMTTAG_REALNAME QString("%N") +#define KABC_FMTTAG_company QString("%cm") +#define KABC_FMTTAG_COMPANY QString("%CM") +#define KABC_FMTTAG_pobox QString("%p") +#define KABC_FMTTAG_street QString("%s") +#define KABC_FMTTAG_STREET QString("%S") +#define KABC_FMTTAG_zipcode QString("%z") +#define KABC_FMTTAG_location QString("%l") +#define KABC_FMTTAG_LOCATION QString("%L") +#define KABC_FMTTAG_region QString("%r") +#define KABC_FMTTAG_REGION QString("%R") +#define KABC_FMTTAG_newline QString("\\n") +#define KABC_FMTTAG_condcomma QString("%,") +#define KABC_FMTTAG_condwhite QString("%w") +#define KABC_FMTTAG_purgeempty QString("%0") + +namespace KABC { + +/** + @short Postal address information. + + This class represents information about a postal address. +*/ +class KABC_EXPORT Address +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Address & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Address & ); + + public: + /** + List of addresses. + */ + typedef QValueList<Address> List; + typedef QValueList<int> TypeList; + + /** + Address types: + + @li @p Dom - domestic + @li @p Intl - international + @li @p Postal - postal + @li @p Parcel - parcel + @li @p Home - home address + @li @p Work - address at work + @li @p Pref - preferred address + */ + enum Type { Dom = 1, Intl = 2, Postal = 4, Parcel = 8, Home = 16, Work = 32, + Pref = 64 }; + + /** + Constructor that creates an empty Address, which is initialized + with a unique id (see id()). + */ + Address(); + + /** + This is like Address() just above, with the difference + that you can specify the type. + */ + Address( int ); + + bool operator==( const Address & ) const; + bool operator!=( const Address & ) const; + + /** + Returns true, if the address is empty. + */ + bool isEmpty() const; + + /** + Clears all entries of the address. + */ + void clear(); + + /** + Sets the unique id. + */ + void setId( const QString & ); + + /* + Returns the unique id. + */ + 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( int type ); + + /** + Returns the type of address. Can be a bitwise or of multiple types. + */ + int type() const; + + /** + Returns a translated string of all types the address has. + */ + QString typeLabel() const; + + /** + Sets the post office box. + */ + void setPostOfficeBox( const QString & ); + + /** + Returns the post office box. + */ + QString postOfficeBox() const; + + /** + Returns the translated label for post office box field. + */ + static QString postOfficeBoxLabel(); + + /** + Sets the extended address information. + */ + void setExtended( const QString & ); + + /** + Returns the extended address information. + */ + QString extended() const; + + /** + Returns the translated label for extended field. + */ + static QString extendedLabel(); + + /** + Sets the street (including number). + */ + void setStreet( const QString & ); + + /** + Returns the street. + */ + QString street() const; + + /** + Returns the translated label for street field. + */ + static QString streetLabel(); + + /** + Sets the locality, e.g. city. + */ + void setLocality( const QString & ); + + /** + Returns the locality. + */ + QString locality() const; + + /** + Returns the translated label for locality field. + */ + static QString localityLabel(); + + /** + Sets the region, e.g. state. + */ + void setRegion( const QString & ); + + /** + Returns the region. + */ + QString region() const; + + /** + Returns the translated label for region field. + */ + static QString regionLabel(); + + /** + Sets the postal code. + */ + void setPostalCode( const QString & ); + + /** + Returns the postal code. + */ + QString postalCode() const; + + /** + Returns the translated label for postal code field. + */ + static QString postalCodeLabel(); + + /** + Sets the country. + */ + void setCountry( const QString & ); + + /** + Returns the country. + */ + QString country() const; + + /** + Returns the translated label for country field. + */ + static QString countryLabel(); + + /** + Sets the delivery label. This is the literal text to be used as label. + */ + void setLabel( const QString & ); + + /** + 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 a special type. + */ + static QString typeLabel( int type ); + + /** + Used for debug output. + */ + void dump() 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::null + , const QString &orgaName=QString::null ) 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 + @since 3.2 + */ + static QString ISOtoCountry( const QString &ISOname ); + + private: + /** + 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 + */ + bool parseAddressTemplateSection( const QString &tsection + , QString &result + , const QString &realName + , const QString &orgaName ) const; + + /** + Finds the balanced closing bracket starting from the opening bracket at + pos in tsection. + @return position of closing bracket, -1 for unbalanced brackets + */ + int findBalancedBracket( const QString &tsection, int pos ) const; + + bool mEmpty; + + QString mId; + int mType; + + QString mPostOfficeBox; + QString mExtended; + QString mStreet; + QString mLocality; + QString mRegion; + QString mPostalCode; + QString mCountry; + QString mLabel; + + static QMap<QString, QString> *mISOMap; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Address & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Address & ); + +} + +#endif diff --git a/kabc/addressbook.cpp b/kabc/addressbook.cpp new file mode 100644 index 000000000..474975344 --- /dev/null +++ b/kabc/addressbook.cpp @@ -0,0 +1,842 @@ +/* + 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 <qfile.h> +#include <qregexp.h> +#include <qtimer.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kinstance.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include "errorhandler.h" +#include "resource.h" + +#include "addressbook.h" +#include "addressbook.moc" + +using namespace KABC; + +struct AddressBook::AddressBookData +{ + Field::List mAllFields; + ErrorHandler *mErrorHandler; + KConfig *mConfig; + KRES::Manager<Resource> *mManager; + QPtrList<Resource> mPendingLoadResources; + QPtrList<Resource> mPendingSaveResources; + Iterator end; +}; + +struct AddressBook::Iterator::IteratorData +{ + Resource::Iterator mIt; + QValueList<Resource*> mResources; + int mCurrRes; +}; + +struct AddressBook::ConstIterator::ConstIteratorData +{ + Resource::ConstIterator mIt; + QValueList<Resource*> mResources; + int mCurrRes; +}; + +AddressBook::Iterator::Iterator() + : d( new IteratorData ) +{ +} + +AddressBook::Iterator::Iterator( const AddressBook::Iterator &i ) + : d( new IteratorData ) +{ + d->mIt = i.d->mIt; + d->mResources = i.d->mResources; + d->mCurrRes = i.d->mCurrRes; +} + +AddressBook::Iterator &AddressBook::Iterator::operator=( const AddressBook::Iterator &i ) +{ + if ( this == &i ) + return *this; // guard against self assignment + + delete d; // delete the old data the Iterator was completely constructed before + d = new IteratorData; + d->mIt = i.d->mIt; + d->mResources = i.d->mResources; + d->mCurrRes = i.d->mCurrRes; + + return *this; +} + +AddressBook::Iterator::~Iterator() +{ + delete d; + d = 0; +} + +const Addressee &AddressBook::Iterator::operator*() const +{ + return *(d->mIt); +} + +Addressee &AddressBook::Iterator::operator*() +{ + return *(d->mIt); +} + +Addressee *AddressBook::Iterator::operator->() +{ + return &(*(d->mIt)); +} + +AddressBook::Iterator &AddressBook::Iterator::operator++() +{ + do { + bool jumped = false; + while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ) { // at end of addressee list of resource + if ( (uint)d->mCurrRes == d->mResources.count() - 1 ) { + return *this; + } + + d->mCurrRes++; // jump to next resource + + jumped = true; + d->mIt = (d->mResources[ d->mCurrRes ])->begin(); + } + + if ( !jumped ) + (d->mIt)++; + + } while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ); + + return *this; +} + +AddressBook::Iterator &AddressBook::Iterator::operator++( int ) +{ + do { + bool jumped = false; + while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ) { // at end of addressee list of resource + if ( (uint)d->mCurrRes == d->mResources.count() - 1 ) { + return *this; + } + + d->mCurrRes++; // jump to next resource + + jumped = true; + d->mIt = (d->mResources[ d->mCurrRes ])->begin(); + } + + if ( !jumped ) + (d->mIt)++; + + } while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ); + + return *this; +} + +AddressBook::Iterator &AddressBook::Iterator::operator--() +{ + (d->mIt)--; + + return *this; +} + +AddressBook::Iterator &AddressBook::Iterator::operator--( int ) +{ + (d->mIt)--; + + return *this; +} + +bool AddressBook::Iterator::operator==( const Iterator &it ) +{ + return ( d->mIt == it.d->mIt ); +} + +bool AddressBook::Iterator::operator!=( const Iterator &it ) +{ + return ( d->mIt != it.d->mIt ); +} + + +AddressBook::ConstIterator::ConstIterator() + : d( new ConstIteratorData ) +{ +} + +AddressBook::ConstIterator::ConstIterator( const AddressBook::ConstIterator &i ) + : d( new ConstIteratorData ) +{ + d->mIt = i.d->mIt; + d->mResources = i.d->mResources; + d->mCurrRes = i.d->mCurrRes; +} + +AddressBook::ConstIterator::ConstIterator( const AddressBook::Iterator &i ) +{ + d = new ConstIteratorData; + d->mIt = i.d->mIt; + d->mResources = i.d->mResources; + d->mCurrRes = i.d->mCurrRes; +} + +AddressBook::ConstIterator &AddressBook::ConstIterator::operator=( const AddressBook::ConstIterator &i ) +{ + if ( this == &i ) + return *this; // guard for self assignment + + delete d; // delete the old data because the Iterator was really constructed before + d = new ConstIteratorData; + d->mIt = i.d->mIt; + d->mResources = i.d->mResources; + d->mCurrRes = i.d->mCurrRes; + + return *this; +} + +AddressBook::ConstIterator::~ConstIterator() +{ + delete d; + d = 0; +} + +const Addressee &AddressBook::ConstIterator::operator*() const +{ + return *(d->mIt); +} + +const Addressee* AddressBook::ConstIterator::operator->() const +{ + return &(*(d->mIt)); +} + +AddressBook::ConstIterator &AddressBook::ConstIterator::operator++() +{ + do { + bool jumped = false; + while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ) { // at end of addressee list of resource + if ( (uint)d->mCurrRes == d->mResources.count() - 1 ) { + return *this; + } + + d->mCurrRes++; // jump to next resource + + jumped = true; + d->mIt = (d->mResources[ d->mCurrRes ])->begin(); + } + + if ( !jumped ) + (d->mIt)++; + + } while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ); + + return *this; +} + +AddressBook::ConstIterator &AddressBook::ConstIterator::operator++(int) +{ + do { + bool jumped = false; + while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ) { // at end of addressee list of resource + if ( (uint)d->mCurrRes == d->mResources.count() - 1 ) { + return *this; + } + + d->mCurrRes++; // jump to next resource + + jumped = true; + d->mIt = (d->mResources[ d->mCurrRes ])->begin(); + } + + if ( !jumped ) + (d->mIt)++; + + } while ( d->mIt == (d->mResources[ d->mCurrRes ])->end() ); + + return *this; +} + +AddressBook::ConstIterator &AddressBook::ConstIterator::operator--() +{ + (d->mIt)--; + return *this; +} + +AddressBook::ConstIterator &AddressBook::ConstIterator::operator--(int) +{ + (d->mIt)--; + return *this; +} + +bool AddressBook::ConstIterator::operator==( const ConstIterator &it ) +{ + return ( d->mIt == it.d->mIt ); +} + +bool AddressBook::ConstIterator::operator!=( const ConstIterator &it ) +{ + return ( d->mIt != it.d->mIt ); +} + + +AddressBook::AddressBook() + : d( new AddressBookData ) +{ + d->mErrorHandler = 0; + d->mConfig = 0; + d->mManager = new KRES::Manager<Resource>( "contact" ); + d->end.d->mResources = QValueList<Resource*>(); + d->end.d->mCurrRes = -1; +} + +AddressBook::AddressBook( const QString &config ) + : d( new AddressBookData ) +{ + d->mErrorHandler = 0; + if ( config.isEmpty() ) + d->mConfig = 0; + else + d->mConfig = new KConfig( config ); + d->mManager = new KRES::Manager<Resource>( "contact" ); + d->mManager->readConfig( d->mConfig ); + d->end.d->mResources = QValueList<Resource*>(); + d->end.d->mCurrRes = -1; +} + +AddressBook::~AddressBook() +{ + delete d->mManager; d->mManager = 0; + delete d->mConfig; d->mConfig = 0; + delete d->mErrorHandler; d->mErrorHandler = 0; + delete d; d = 0; +} + +bool AddressBook::load() +{ + kdDebug(5700) << "AddressBook::load()" << endl; + + clear(); + + KRES::Manager<Resource>::ActiveIterator it; + bool ok = true; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + if ( !(*it)->load() ) { + error( i18n("Unable to load resource '%1'").arg( (*it)->resourceName() ) ); + ok = false; + } + } + + return ok; +} + +bool AddressBook::asyncLoad() +{ + kdDebug(5700) << "AddressBook::asyncLoad()" << endl; + + clear(); + + KRES::Manager<Resource>::ActiveIterator it; + bool ok = true; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + d->mPendingLoadResources.append( *it ); + if ( !(*it)->asyncLoad() ) { + error( i18n("Unable to load resource '%1'").arg( (*it)->resourceName() ) ); + ok = false; + } + } + + return ok; +} + +bool AddressBook::save( Ticket *ticket ) +{ + kdDebug(5700) << "AddressBook::save()"<< endl; + + if ( ticket->resource() ) { + deleteRemovedAddressees(); + bool ok = ticket->resource()->save( ticket ); + if ( ok ) ticket->resource()->releaseSaveTicket( ticket ); + return ok; + } + + return false; +} + +bool AddressBook::asyncSave( Ticket *ticket ) +{ + kdDebug(5700) << "AddressBook::asyncSave()"<< endl; + + if ( ticket->resource() ) { + d->mPendingSaveResources.append( ticket->resource() ); + bool ok = ticket->resource()->asyncSave( ticket ); + if ( ok ) ticket->resource()->releaseSaveTicket( ticket ); + return ok; + } + + return false; +} + +AddressBook::Iterator AddressBook::begin() +{ + QValueList<Resource*> list; + KRES::Manager<Resource>::ActiveIterator resIt; + for ( resIt = d->mManager->activeBegin(); resIt != d->mManager->activeEnd(); ++resIt ) + list.append( *resIt ); + + if ( list.count() == 0 ) + return end(); + + Iterator it = Iterator(); + it.d->mResources = list; + it.d->mCurrRes = 0; + it.d->mIt = (it.d->mResources[ it.d->mCurrRes ])->begin(); + + while ( it.d->mIt == (it.d->mResources[ it.d->mCurrRes ])->end() ) { + if ( (uint)it.d->mCurrRes == it.d->mResources.count() - 1 ) + return end(); + + it.d->mCurrRes++; + + it.d->mIt = (it.d->mResources[ it.d->mCurrRes ])->begin(); + } + + return it; +} + +AddressBook::ConstIterator AddressBook::begin() const +{ + QValueList<Resource*> list; + KRES::Manager<Resource>::ActiveIterator resIt; + for ( resIt = d->mManager->activeBegin(); resIt != d->mManager->activeEnd(); ++resIt ) + list.append( *resIt ); + + if ( list.count() == 0 ) + return end(); + + Iterator it = Iterator(); + it.d->mResources = list; + it.d->mCurrRes = 0; + it.d->mIt = (it.d->mResources[ it.d->mCurrRes ])->begin(); + + while ( it.d->mIt == (it.d->mResources[ it.d->mCurrRes ])->end() ) { + if ( (uint)it.d->mCurrRes == it.d->mResources.count() - 1 ) + return end(); + + it.d->mCurrRes++; + + it.d->mIt = (it.d->mResources[ it.d->mCurrRes ])->begin(); + } + + return it; +} + +AddressBook::Iterator AddressBook::end() +{ + KRES::Manager<Resource>::ActiveIterator resIt = d->mManager->activeEnd(); + + if ( resIt == d->mManager->activeBegin() || ! *(--resIt) ) { // no resource available + d->end.d->mIt = Resource::Iterator(); + } else { + d->end.d->mIt = (*resIt)->end(); + } + + return d->end; +} + +AddressBook::ConstIterator AddressBook::end() const +{ + KRES::Manager<Resource>::ActiveIterator resIt = d->mManager->activeEnd(); + + if ( resIt == d->mManager->activeBegin() || ! *(--resIt) ) { // no resource available + d->end.d->mIt = Resource::Iterator(); + } else { + d->end.d->mIt = (*resIt)->end(); + } + + return d->end; +} + +void AddressBook::clear() +{ + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) + (*it)->clear(); +} + +Ticket *AddressBook::requestSaveTicket( Resource *resource ) +{ + kdDebug(5700) << "AddressBook::requestSaveTicket()" << endl; + + if ( !resource ) + resource = standardResource(); + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + if ( (*it) == resource ) { + if ( (*it)->readOnly() || !(*it)->isOpen() ) + return 0; + else + return (*it)->requestSaveTicket(); + } + } + + return 0; +} + +void AddressBook::releaseSaveTicket( Ticket *ticket ) +{ + if ( !ticket ) + return; + + if ( ticket->resource() ) { + ticket->resource()->releaseSaveTicket( ticket ); + } +} + +void AddressBook::insertAddressee( const Addressee &a ) +{ + Resource *resource = a.resource(); + if ( resource == 0 ) + resource = standardResource(); + + Resource::Iterator it; + Addressee fAddr = resource->findByUid( a.uid() ); + + Addressee addr( a ); + if ( !fAddr.isEmpty() ) { + if ( fAddr != a ) + addr.setRevision( QDateTime::currentDateTime() ); + else { + if ( fAddr.resource() == 0 ) { + fAddr.setResource( resource ); + //NOTE: Should we have setChanged( true ) here? + resource->insertAddressee( fAddr ); + } + return; + } + } + + addr.setResource( resource ); + addr.setChanged( true ); + resource->insertAddressee( addr ); +} + +void AddressBook::removeAddressee( const Addressee &a ) +{ + if ( a.resource() ) + a.resource()->removeAddressee( a ); +} + +void AddressBook::removeAddressee( const Iterator &it ) +{ + if ( (*it).resource() ) + (*it).resource()->removeAddressee( *it ); +} + +AddressBook::Iterator AddressBook::find( const Addressee &a ) +{ + Iterator it; + for ( it = begin(); it != end(); ++it ) { + if ( a.uid() == (*it).uid() ) + return it; + } + + return end(); +} + +Addressee AddressBook::findByUid( const QString &uid ) +{ + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + Addressee addr = (*it)->findByUid( uid ); + if ( !addr.isEmpty() ) + return addr; + } + + return Addressee(); +} + +Addressee::List AddressBook::allAddressees() +{ + Addressee::List list; + + ConstIterator it; + for ( it = begin(); it != end(); ++it ) + list.append( *it ); + + return list; +} + +Addressee::List AddressBook::findByName( const QString &name ) +{ + Addressee::List results; + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) + results += (*it)->findByName( name ); + + return results; +} + +Addressee::List AddressBook::findByEmail( const QString &email ) +{ + Addressee::List results; + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) + results += (*it)->findByEmail( email ); + + return results; +} + +Addressee::List AddressBook::findByCategory( const QString &category ) +{ + Addressee::List results; + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) + results += (*it)->findByCategory( category ); + + return results; +} + +void AddressBook::dump() const +{ + kdDebug(5700) << "AddressBook::dump() --- begin ---" << endl; + + ConstIterator it; + for( it = begin(); it != end(); ++it ) { + (*it).dump(); + } + + kdDebug(5700) << "AddressBook::dump() --- end ---" << endl; +} + +QString AddressBook::identifier() +{ + QStringList identifier; + + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + if ( !(*it)->identifier().isEmpty() ) + identifier.append( (*it)->identifier() ); + } + + return identifier.join( ":" ); +} + +Field::List AddressBook::fields( int category ) +{ + if ( d->mAllFields.isEmpty() ) { + d->mAllFields = Field::allFields(); + } + + if ( category == Field::All ) return d->mAllFields; + + Field::List result; + Field::List::ConstIterator it; + for ( it = d->mAllFields.constBegin(); it != d->mAllFields.constEnd(); ++it ) { + if ( (*it)->category() & category ) + result.append( *it ); + } + + return result; +} + +bool AddressBook::addCustomField( const QString &label, int category, + const QString &key, const QString &app ) +{ + if ( d->mAllFields.isEmpty() ) { + d->mAllFields = Field::allFields(); + } + + QString a = app.isNull() ? KGlobal::instance()->instanceName() : app; + QString k = key.isNull() ? label : key; + + Field *field = Field::createCustomField( label, category, k, a ); + + if ( !field ) return false; + + d->mAllFields.append( field ); + + return true; +} + +QDataStream &KABC::operator<<( QDataStream &s, const AddressBook &ab ) +{ + if (!ab.d) return s; + + return s;// << ab.d->mAddressees; +} + +QDataStream &KABC::operator>>( QDataStream &s, AddressBook &ab ) +{ + if (!ab.d) return s; + +// s >> ab.d->mAddressees; + + return s; +} + +bool AddressBook::addResource( Resource *resource ) +{ + if ( !resource->open() ) { + kdDebug(5700) << "AddressBook::addResource(): can't add resource" << endl; + return false; + } + + d->mManager->add( resource ); + resource->setAddressBook( this ); + + connect( resource, SIGNAL( loadingFinished( Resource* ) ), + this, SLOT( resourceLoadingFinished( Resource* ) ) ); + connect( resource, SIGNAL( savingFinished( Resource* ) ), + this, SLOT( resourceSavingFinished( Resource* ) ) ); + + connect( resource, SIGNAL( loadingError( Resource*, const QString& ) ), + this, SLOT( resourceLoadingError( Resource*, const QString& ) ) ); + connect( resource, SIGNAL( savingError( Resource*, const QString& ) ), + this, SLOT( resourceSavingError( Resource*, const QString& ) ) ); + + return true; +} + +bool AddressBook::removeResource( Resource *resource ) +{ + resource->close(); + + if ( resource == standardResource() ) + d->mManager->setStandardResource( 0 ); + + resource->setAddressBook( 0 ); + + disconnect( resource, SIGNAL( loadingFinished( Resource* ) ), + this, SLOT( resourceLoadingFinished( Resource* ) ) ); + disconnect( resource, SIGNAL( savingFinished( Resource* ) ), + this, SLOT( resourceSavingFinished( Resource* ) ) ); + + disconnect( resource, SIGNAL( loadingError( Resource*, const QString& ) ), + this, SLOT( resourceLoadingError( Resource*, const QString& ) ) ); + disconnect( resource, SIGNAL( savingError( Resource*, const QString& ) ), + this, SLOT( resourceLoadingError( Resource*, const QString& ) ) ); + + d->mManager->remove( resource ); + + return true; +} + +QPtrList<Resource> AddressBook::resources() +{ + QPtrList<Resource> list; + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { + if ( d->mManager->standardResource() == (*it) ) + list.prepend( *it ); + else + list.append( *it ); + } + + return list; +} + +void AddressBook::setErrorHandler( ErrorHandler *handler ) +{ + delete d->mErrorHandler; + d->mErrorHandler = handler; +} + +void AddressBook::error( const QString& msg ) +{ + if ( !d->mErrorHandler ) // create default error handler + d->mErrorHandler = new ConsoleErrorHandler; + + if ( d->mErrorHandler ) + d->mErrorHandler->error( msg ); + else + kdError(5700) << "no error handler defined" << endl; +} + +void AddressBook::deleteRemovedAddressees() +{ + // no any longer needed +} + +void AddressBook::setStandardResource( Resource *resource ) +{ + d->mManager->setStandardResource( resource ); +} + +Resource *AddressBook::standardResource() +{ + return d->mManager->standardResource(); +} + +KRES::Manager<Resource> *AddressBook::resourceManager() +{ + return d->mManager; +} + +void AddressBook::cleanUp() +{ +} + +bool AddressBook::loadingHasFinished() const +{ + return d->mPendingLoadResources.isEmpty(); +} + +void AddressBook::resourceLoadingFinished( Resource *res ) +{ + d->mPendingLoadResources.remove( res ); + emit loadingFinished( res ); + + if ( d->mPendingLoadResources.count() == 0 ) + emit addressBookChanged( this ); +} + +void AddressBook::resourceSavingFinished( Resource *res ) +{ + d->mPendingSaveResources.remove( res ); + + emit savingFinished( res ); +} + +void AddressBook::resourceLoadingError( Resource *res, const QString &errMsg ) +{ + error( errMsg ); + + d->mPendingLoadResources.remove( res ); + if ( d->mPendingLoadResources.count() == 0 ) + emit addressBookChanged( this ); +} + +void AddressBook::resourceSavingError( Resource *res, const QString &errMsg ) +{ + error( errMsg ); + + d->mPendingSaveResources.remove( res ); +} diff --git a/kabc/addressbook.h b/kabc/addressbook.h new file mode 100644 index 000000000..d12130201 --- /dev/null +++ b/kabc/addressbook.h @@ -0,0 +1,431 @@ +/* + 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_ADDRESSBOOK_H +#define KABC_ADDRESSBOOK_H + +#include <qobject.h> +#include <qptrlist.h> + +#include <kresources/manager.h> + +#include "addressee.h" +#include "field.h" + +namespace KABC { + +class ErrorHandler; +class Resource; +class Ticket; + +/** + @short Address Book + + This class provides access to a collection of address book entries. + */ +class KABC_EXPORT AddressBook : public QObject +{ + Q_OBJECT + + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const AddressBook & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, AddressBook & ); + friend class StdAddressBook; + + public: + /** + @short Address Book Iterator + + This class provides an iterator for address book entries. + */ + class KABC_EXPORT Iterator + { + public: + Iterator(); + Iterator( const Iterator & ); + ~Iterator(); + + Iterator &operator=( const Iterator & ); + const Addressee &operator*() const; + Addressee &operator*(); + Addressee* operator->(); + Iterator &operator++(); + Iterator &operator++(int); + Iterator &operator--(); + Iterator &operator--(int); + bool operator==( const Iterator &it ); + bool operator!=( const Iterator &it ); + + struct IteratorData; + IteratorData *d; + }; + + /** + @short Address Book Const Iterator + + This class provides a const iterator for address book entries. + */ + class KABC_EXPORT ConstIterator + { + public: + ConstIterator(); + ConstIterator( const ConstIterator & ); + ConstIterator( const Iterator & ); + ~ConstIterator(); + + ConstIterator &operator=( const ConstIterator & ); + const Addressee &operator*() const; + const Addressee* operator->() const; + ConstIterator &operator++(); + ConstIterator &operator++(int); + ConstIterator &operator--(); + ConstIterator &operator--(int); + bool operator==( const ConstIterator &it ); + bool operator!=( const ConstIterator &it ); + + struct ConstIteratorData; + ConstIteratorData *d; + }; + + /** + Constructs an address book object. + You have to add the resources manually before calling load(). + */ + AddressBook(); + + /** + Constructs an address book object. + The resources are loaded automatically. + + @param config The config file which contains the resource settings. + */ + AddressBook( const QString &config ); + + /** + Destructor. + */ + virtual ~AddressBook(); + + /** + Requests a ticket for saving the addressbook. Calling this function locks + the addressbook for all other processes. You need the returned ticket + object for calling the save() function. + + @param resource A pointer to the resource which shall be locked. If 0, + the default resource is locked. + @return 0 if the resource is already locked or a valid save ticket + otherwise. + @see save() + */ + Ticket *requestSaveTicket( Resource *resource = 0 ); + + /** + Releases the ticket requested previously with requestSaveTicket(). + Call this function, if you want to release a ticket without saving. + */ + void releaseSaveTicket( Ticket *ticket ); + + /** + Loads all addressees synchronously. + + @return Whether the loading was successfully. + */ + bool load(); + + /** + Loads all addressees asynchronously. This function returns immediately + and emits the addressBookChanged() signal as soon as the loading has + finished. + + @return Whether the synchronous part of loading was successfully. + */ + bool asyncLoad(); + + /** + Saves all addressees of one resource synchronously. If the save is + successfull the ticket is deleted. + + @param ticket The ticket returned by requestSaveTicket(). + @return Whether the saving was successfully. + */ + bool save( Ticket *ticket ); + + /** + Saves all addressees of one resource asynchronously. If the save is + successfull the ticket is deleted. + + @param ticket The ticket returned by requestSaveTicket(). + @return Whether the synchronous part of saving was successfully. + */ + bool asyncSave( Ticket *ticket ); + + /** + Returns an iterator pointing to the first addressee of address book. + This iterator equals end() if the address book is empty. + */ + ConstIterator begin() const; + + /** + This is an overloaded member function, provided for convenience. It + behaves essentially like the above function. + */ + Iterator begin(); + + /** + Returns an iterator pointing to the last addressee of address book. + This iterator equals begin() if the address book is empty. + */ + ConstIterator end() const; + + /** + This is an overloaded member function, provided for convenience. It + behaves essentially like the above function. + */ + Iterator end(); + + + /** + Removes all addressees from the address book. + */ + void clear(); + + /** + Insert an addressee into the address book. If an addressee with the same + unique id already exists, it is replaced by the new one, otherwise it is + appended. + + @param addr The addressee which shall be insert. + */ + void insertAddressee( const Addressee &addr ); + + /** + Removes an addressee from the address book. + + @param addr The addressee which shall be removed. + */ + void removeAddressee( const Addressee &addr ); + + /** + This is an overloaded member function, provided for convenience. It + behaves essentially like the above function. + + @param it An iterator pointing to the addressee which shall be removed. + */ + void removeAddressee( const Iterator &it ); + + /** + Returns an iterator pointing to the specified addressee. It will return + end() if no addressee matched. + + @param addr The addresee you are looking for. + */ + Iterator find( const Addressee &addr ); // KDE4: const + + /** + Searches an addressee with the specified unique identifier. + + @param uid The unique identifier you are looking for. + @return The addressee with the specified unique identifier or an + empty addressee. + */ + Addressee findByUid( const QString &uid ); // KDE4: const + + /** + Returns a list of all addressees in the address book. + */ + Addressee::List allAddressees(); // KDE4: const + + /** + Searches all addressees which match the specified name. + + @param name The name you are looking for. + @return A list of all matching addressees. + */ + Addressee::List findByName( const QString &name ); // KDE4: const + + /** + Searches all addressees which match the specified email address. + + @param email The email address you are looking for. + @return A list of all matching addressees. + */ + Addressee::List findByEmail( const QString &email ); // KDE4: const + + /** + Searches all addressees which belongs to the specified category. + + @param category The category you are looking for. + @return A list of all matching addressees. + */ + Addressee::List findByCategory( const QString &category ); // KDE4: const + + /** + Returns a string identifying this addressbook. The identifier is + created by concatenation of the resource identifiers. + */ + virtual QString identifier(); // KDE4: const + + /** + Returns a list of all Fields known to the address book which are associated + with the given field category. + */ + Field::List fields( int category = Field::All ); // KDE4: const + + /** + Add custom field to address book. + + @param label User visible label of the field. + @param category Ored list of field categories. + @param key Identifier used as key for reading and writing the field. + @param app String used as application key for reading and writing + the field. + */ + bool addCustomField( const QString &label, int category = Field::All, + const QString &key = QString::null, + const QString &app = QString::null ); + + /** + Adds a resource to the address book. + + @param resource The resource you want to add. + @return Whether opening the resource was successfully. + */ + bool addResource( Resource *resource ); + + /** + Removes a resource from the address book. + + @param resource The resource you want to remove. + @return Whether closing the resource was successfully. + */ + bool removeResource( Resource *resource ); + + /** + Returns a list of all resources. + */ + QPtrList<Resource> resources(); // KDE4: const + + /** + Sets the @p ErrorHandler, that is used by error() to + provide GUI independent error messages. + + @param errorHandler The error handler you want to use. + */ + void setErrorHandler( ErrorHandler *errorHandler ); + + /** + Shows GUI independent error messages. + + @param msg The error message that shall be displayed. + */ + void error( const QString &msg ); + + /** + @deprecated There is no need to call this function anymore. + */ + void cleanUp() KDE_DEPRECATED; + + /** + Used for debug output. This function prints out the list + of all addressees to kdDebug(5700). + */ + void dump() const; + + /** + */ + void emitAddressBookLocked() { emit addressBookLocked( this ); } + void emitAddressBookUnlocked() { emit addressBookUnlocked( this ); } + void emitAddressBookChanged() { emit addressBookChanged( this ); } + + /** + Returns true when the loading of the addressbook has finished, + otherwise false. + + @since 3.5 + */ + bool loadingHasFinished() const; + + signals: + /** + Emitted when one of the resources discovered a change in its backend + or the asynchronous loading of all resources has finished. + You should connect to this signal to update the presentation of + the contact data in your application. + + @param addressBook The address book which emitted this signal. + */ + void addressBookChanged( AddressBook *addressBook ); + + /** + Emitted when one of the resources has been locked for writing. + + @param addressBook The address book which emitted this signal. + */ + void addressBookLocked( AddressBook *addressBook ); + + /** + Emitted when one of the resources has been unlocked. + You should connect to this signal if you want to save your changes + to a resource which is currently locked, and want to get notified when + saving is possible again. + + @param addressBook The address book which emitted this signal. + */ + void addressBookUnlocked( AddressBook *addressBook ); + + /** + Emitted when the asynchronous loading of one resource has finished + after calling asyncLoad(). + + @param resource The resource which emitted this signal. + */ + void loadingFinished( Resource *resource ); + + /** + Emitted when the asynchronous saving of one resource has finished + after calling asyncSave(). + + @param resource The resource which emitted this signal. + */ + void savingFinished( Resource *resource ); + + protected slots: + void resourceLoadingFinished( Resource* ); + void resourceSavingFinished( Resource* ); + void resourceLoadingError( Resource*, const QString& ); + void resourceSavingError( Resource*, const QString& ); + + protected: + void deleteRemovedAddressees(); + void setStandardResource( Resource* ); + Resource *standardResource(); + KRES::Manager<Resource> *resourceManager(); + + private: + QPtrList<Resource> mDummy; // Remove in KDE 4 + struct AddressBookData; + AddressBookData *d; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const AddressBook & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, AddressBook & ); + +} + +#endif diff --git a/kabc/addresseedialog.cpp b/kabc/addresseedialog.cpp new file mode 100644 index 000000000..c7d353d3a --- /dev/null +++ b/kabc/addresseedialog.cpp @@ -0,0 +1,259 @@ +/* + 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 <qlayout.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qregexp.h> + +#include <klocale.h> +#include <kdebug.h> + +#include "stdaddressbook.h" + +#include "addresseedialog.h" +#include "addresseedialog.moc" + +using namespace KABC; + +AddresseeItem::AddresseeItem( QListView *parent, const Addressee &addressee ) : + QListViewItem( parent ), + mAddressee( addressee ) +{ + setText( Name, addressee.realName() ); + setText( Email, addressee.preferredEmail() ); +} + +QString AddresseeItem::key( int column, bool ) const +{ + if (column == Email) { + QString value = text(Email); + QRegExp emailRe("<\\S*>"); + int match = emailRe.search(value); + if (match > -1) + value = value.mid(match + 1, emailRe.matchedLength() - 2); + + return value.lower(); + } + + return text(column).lower(); +} + +AddresseeDialog::AddresseeDialog( QWidget *parent, bool multiple ) : + KDialogBase( KDialogBase::Plain, i18n("Select Addressee"), + Ok|Cancel, Ok, parent ), mMultiple( multiple ) +{ + QWidget *topWidget = plainPage(); + + QBoxLayout *topLayout = new QHBoxLayout( topWidget ); + QBoxLayout *listLayout = new QVBoxLayout; + topLayout->addLayout( listLayout ); + + mAddresseeList = new KListView( topWidget ); + mAddresseeList->addColumn( i18n("Name") ); + mAddresseeList->addColumn( i18n("Email") ); + mAddresseeList->setAllColumnsShowFocus( true ); + mAddresseeList->setFullWidth( true ); + listLayout->addWidget( mAddresseeList ); + connect( mAddresseeList, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( slotOk() ) ); + connect( mAddresseeList, SIGNAL( selectionChanged( QListViewItem * ) ), + SLOT( updateEdit( QListViewItem * ) ) ); + + mAddresseeEdit = new KLineEdit( topWidget ); + mAddresseeEdit->setCompletionMode( KGlobalSettings::CompletionAuto ); + connect( mAddresseeEdit->completionObject(), SIGNAL( match( const QString & ) ), + SLOT( selectItem( const QString & ) ) ); + mAddresseeEdit->setFocus(); + mAddresseeEdit->completionObject()->setIgnoreCase( true ); + listLayout->addWidget( mAddresseeEdit ); + + setInitialSize( QSize( 450, 300 ) ); + + if ( mMultiple ) { + QBoxLayout *selectedLayout = new QVBoxLayout; + topLayout->addLayout( selectedLayout ); + topLayout->setSpacing( spacingHint() ); + + QGroupBox *selectedGroup = new QGroupBox( 1, Horizontal, i18n("Selected"), + topWidget ); + selectedLayout->addWidget( selectedGroup ); + + mSelectedList = new KListView( selectedGroup ); + mSelectedList->addColumn( i18n("Name") ); + mSelectedList->addColumn( i18n("Email") ); + mSelectedList->setAllColumnsShowFocus( true ); + mSelectedList->setFullWidth( true ); + connect( mSelectedList, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( removeSelected() ) ); + + QPushButton *unselectButton = new QPushButton( i18n("Unselect"), selectedGroup ); + connect ( unselectButton, SIGNAL( clicked() ), SLOT( removeSelected() ) ); + + connect( mAddresseeList, SIGNAL( clicked( QListViewItem * ) ), + SLOT( addSelected( QListViewItem * ) ) ); + + setInitialSize( QSize( 650, 350 ) ); + } + + mAddressBook = StdAddressBook::self( true ); + connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ), + SLOT( addressBookChanged() ) ); + connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ), + SLOT( addressBookChanged() ) ); + + loadAddressBook(); +} + +AddresseeDialog::~AddresseeDialog() +{ +} + +void AddresseeDialog::loadAddressBook() +{ + mAddresseeList->clear(); + mItemDict.clear(); + mAddresseeEdit->completionObject()->clear(); + + AddressBook::Iterator it; + for( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) { + AddresseeItem *item = new AddresseeItem( mAddresseeList, (*it) ); + addCompletionItem( (*it).realName(), item ); + addCompletionItem( (*it).preferredEmail(), item ); + } +} + +void AddresseeDialog::addCompletionItem( const QString &str, QListViewItem *item ) +{ + if ( str.isEmpty() ) return; + + mItemDict.insert( str, item ); + mAddresseeEdit->completionObject()->addItem( str ); +} + +void AddresseeDialog::selectItem( const QString &str ) +{ + if ( str.isEmpty() ) return; + + QListViewItem *item = mItemDict.find( str ); + if ( item ) { + mAddresseeList->blockSignals( true ); + mAddresseeList->setSelected( item, true ); + mAddresseeList->ensureItemVisible( item ); + mAddresseeList->blockSignals( false ); + } +} + +void AddresseeDialog::updateEdit( QListViewItem *item ) +{ + mAddresseeEdit->setText( item->text( 0 ) ); + mAddresseeEdit->setSelection( 0, item->text( 0 ).length() ); +} + +void AddresseeDialog::addSelected( QListViewItem *item ) +{ + AddresseeItem *addrItem = dynamic_cast<AddresseeItem *>( item ); + if ( !addrItem ) return; + + Addressee a = addrItem->addressee(); + + QListViewItem *selectedItem = mSelectedDict.find( a.uid() ); + if ( !selectedItem ) { + selectedItem = new AddresseeItem( mSelectedList, a ); + mSelectedDict.insert( a.uid(), selectedItem ); + } +} + +void AddresseeDialog::removeSelected() +{ + QListViewItem *item = mSelectedList->selectedItem(); + AddresseeItem *addrItem = dynamic_cast<AddresseeItem *>( item ); + if ( !addrItem ) return; + + mSelectedDict.remove( addrItem->addressee().uid() ); + delete addrItem; +} + +Addressee AddresseeDialog::addressee() +{ + AddresseeItem *aItem = 0; + + if ( mMultiple ) + aItem = dynamic_cast<AddresseeItem *>( mSelectedList->firstChild() ); + else + aItem = dynamic_cast<AddresseeItem *>( mAddresseeList->selectedItem() ); + + if (aItem) return aItem->addressee(); + return Addressee(); +} + +Addressee::List AddresseeDialog::addressees() +{ + Addressee::List al; + AddresseeItem *aItem = 0; + + if ( mMultiple ) { + QListViewItem *item = mSelectedList->firstChild(); + while( item ) { + aItem = dynamic_cast<AddresseeItem *>( item ); + if ( aItem ) al.append( aItem->addressee() ); + item = item->nextSibling(); + } + } + else + { + aItem = dynamic_cast<AddresseeItem *>( mAddresseeList->selectedItem() ); + if (aItem) al.append( aItem->addressee() ); + } + + return al; +} + +Addressee AddresseeDialog::getAddressee( QWidget *parent ) +{ + AddresseeDialog *dlg = new AddresseeDialog( parent ); + Addressee addressee; + int result = dlg->exec(); + + if ( result == QDialog::Accepted ) { + addressee = dlg->addressee(); + } + + delete dlg; + return addressee; +} + +Addressee::List AddresseeDialog::getAddressees( QWidget *parent ) +{ + AddresseeDialog *dlg = new AddresseeDialog( parent, true ); + Addressee::List addressees; + int result = dlg->exec(); + if ( result == QDialog::Accepted ) { + addressees = dlg->addressees(); + } + + delete dlg; + return addressees; +} + +void AddresseeDialog::addressBookChanged() +{ + loadAddressBook(); +} diff --git a/kabc/addresseedialog.h b/kabc/addresseedialog.h new file mode 100644 index 000000000..2d15804b1 --- /dev/null +++ b/kabc/addresseedialog.h @@ -0,0 +1,161 @@ +/* + 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_ADDRESSEEDIALOG_H +#define KABC_ADDRESSEEDIALOG_H + +#include <qdict.h> + +#include <kdialogbase.h> +#include <klineedit.h> +#include <klistview.h> + +#include "addressbook.h" + +namespace KABC { + +/** + @short Special ListViewItem, that is used by the AddresseeDialog. +*/ +class KABC_EXPORT AddresseeItem : public QListViewItem +{ + public: + + /** + Type of column + @li @p Name - Name in Addressee + @li @p Email - Email in Addressee + */ + enum columns { Name = 0, Email = 1 }; + + /** + Constructor. + + @param parent The parent listview. + @param addressee The associated addressee. + */ + AddresseeItem( QListView *parent, const Addressee &addressee ); + + /** + Returns the addressee. + */ + Addressee addressee() const { return mAddressee; } + + /** + Method used by QListView to sort the items. + */ + virtual QString key( int column, bool ascending ) const; + + private: + Addressee mAddressee; +}; + +/** + @short Dialog for selecting address book entries. + + This class provides a dialog for selecting entries from the standard KDE + address book. Use the getAddressee() function to open a modal dialog, + returning an address book entry. + + In the dialog you can select an entry from the list with the mouse or type in + the first letters of the name or email address you are searching for. The + entry matching best is automatically selected. Use double click, pressing + return or pressing the ok button to return the selected addressee to the + application. +*/ +class KABC_EXPORT AddresseeDialog : public KDialogBase +{ + Q_OBJECT + + public: + /** + Construct addressbook entry select dialog. + + @param parent parent widget + @param multiple if true, indicates a multiple selection. + */ + AddresseeDialog( QWidget *parent=0, bool multiple=false ); + + /** + Destructor. + */ + virtual ~AddresseeDialog(); + + /** + Return the address chosen. + + If it is a multiple select, this will return only the first address chosen + */ + Addressee addressee(); + + /** + Return the list of addresses chosen + */ + Addressee::List addressees(); + + /** + Select a single address book entry. + + Open addressee select dialog and return the entry selected by the user. + If the user doesn't select an entry or presses cancel, the returned + addressee is empty. + */ + static Addressee getAddressee( QWidget *parent ); + + /** + Select multiple address book entries. + + Open addressee select dialog and return the entries selected by the user. + If the user doesn't select an entry or presses cancel, the returned + addressee list is empty. + */ + static Addressee::List getAddressees( QWidget *parent ); + + private slots: + void selectItem( const QString & ); + void updateEdit( QListViewItem *item ); + void addSelected( QListViewItem *item ); + void removeSelected(); + + protected slots: + void addressBookChanged(); + + private: + void loadAddressBook(); + void addCompletionItem( const QString &str, QListViewItem *item ); + + bool mMultiple; + + KListView *mAddresseeList; + KLineEdit *mAddresseeEdit; + + KListView *mSelectedList; + + AddressBook *mAddressBook; + + QDict<QListViewItem> mItemDict; + QDict<QListViewItem> mSelectedDict; + + class AddresseeDialogPrivate; + AddresseeDialogPrivate *d; +}; + +} +#endif diff --git a/kabc/addresseehelper.cpp b/kabc/addresseehelper.cpp new file mode 100644 index 000000000..96ab62578 --- /dev/null +++ b/kabc/addresseehelper.cpp @@ -0,0 +1,111 @@ +/* + 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 <qapplication.h> + +#include <kconfig.h> +#include <klocale.h> + +#include "addresseehelper.h" + +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 ), + DCOPObject( "KABC::AddresseeHelper" ) +{ + initSettings(); + + connectDCOPSignal( "kaddressbook", "KABC::AddressBookConfig", + "changed()", "initSettings()", false ); +} + +// static +void AddresseeHelper::addToSet( const QStringList& list, + std::set<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( "van" ); + mPrefixes.insert( "von" ); + mPrefixes.insert( "de" ); + + KConfig config( "kabcrc", true, false ); // readonly, no kdeglobals + config.setGroup( "General" ); + + addToSet( config.readListEntry( "Prefixes" ), mTitles ); + addToSet( config.readListEntry( "Inclusions" ), mPrefixes ); + addToSet( config.readListEntry( "Suffixes" ), mSuffixes ); + mTradeAsFamilyName = config.readBoolEntry( "TradeAsFamilyName", true ); +} + +bool AddresseeHelper::containsTitle( const QString& title ) const +{ + return mTitles.find( title ) != mTitles.end(); +} + +bool AddresseeHelper::containsPrefix( const QString& prefix ) const +{ + return mPrefixes.find( prefix ) != mPrefixes.end(); +} + +bool AddresseeHelper::containsSuffix( const QString& suffix ) const +{ + return mSuffixes.find( suffix ) != mSuffixes.end(); +} + +bool AddresseeHelper::tradeAsFamilyName() const +{ + return mTradeAsFamilyName; +} diff --git a/kabc/addresseehelper.h b/kabc/addresseehelper.h new file mode 100644 index 000000000..8e58f5988 --- /dev/null +++ b/kabc/addresseehelper.h @@ -0,0 +1,66 @@ +/* + 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 <qobject.h> +#include <qstringlist.h> + +#include <dcopobject.h> + +#include <set> + +/** + static data, shared by ALL addressee objects +*/ + +namespace KABC { + +class KABC_EXPORT AddresseeHelper : public QObject, public DCOPObject +{ + K_DCOP + + public: + static AddresseeHelper *self(); + + bool containsTitle( const QString& title ) const; + bool containsPrefix( const QString& prefix ) const; + bool containsSuffix( const QString& suffix ) const; + bool tradeAsFamilyName() const; + + k_dcop: + ASYNC initSettings(); + + private: + AddresseeHelper(); + + static void addToSet( const QStringList& list, + std::set<QString>& container ); + std::set<QString> mTitles; + std::set<QString> mPrefixes; + std::set<QString> mSuffixes; + bool mTradeAsFamilyName; + + static AddresseeHelper *s_self; +}; + +} + +#endif diff --git a/kabc/addresseelist.cpp b/kabc/addresseelist.cpp new file mode 100644 index 000000000..361364881 --- /dev/null +++ b/kabc/addresseelist.cpp @@ -0,0 +1,256 @@ +/* + 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 <kdebug.h> + +#include "addresseelist.h" + +#include "field.h" +#include "sortmode.h" + +using namespace KABC; + +// +// +// Traits +// +// + +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 ); +} + +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 ); +} + +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 ); +} + +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; + } +} + +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; + +AddresseeList::AddresseeList() + : QValueList<Addressee>() +{ + mReverseSorting = false; + mActiveSortingCriterion = FormattedName; +} + +AddresseeList::~AddresseeList() +{ +} + +AddresseeList::AddresseeList( const AddresseeList &l ) + : QValueList<Addressee>( l ) +{ + mReverseSorting = l.reverseSorting(); + mActiveSortingCriterion = l.sortingCriterion(); +} + +AddresseeList::AddresseeList( const QValueList<Addressee> &l ) + : QValueList<Addressee>( l ) +{ + mReverseSorting = false; +} + +void AddresseeList::dump() const +{ + kdDebug(5700) << "AddresseeList {" << endl; + kdDebug(5700) << "reverse order: " << ( mReverseSorting ? "true" : "false" ) << endl; + + QString crit; + if ( Uid == mActiveSortingCriterion ) { + crit = "Uid"; + } else if ( Name == mActiveSortingCriterion ) { + crit = "Name"; + } else if ( FormattedName == mActiveSortingCriterion ) { + crit = "FormattedName"; + } else if ( FamilyName == mActiveSortingCriterion ) { + crit = "FamilyName"; + } else if ( GivenName == mActiveSortingCriterion ) { + crit = "GivenName"; + } else { + crit = "unknown -- update dump method"; + } + + kdDebug(5700) << "sorting criterion: " << crit << endl; + + for ( const_iterator it = begin(); it != end(); ++it ) { + (*it).dump(); + } + + kdDebug(5700) << "}" << endl; +} + +void AddresseeList::sortBy( SortingCriterion c ) +{ + 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 { + kdError(5700) << "AddresseeList sorting criterion passed for which a trait is not known. No sorting done." << endl; + } +} + +void AddresseeList::sort() +{ + sortBy( 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 ( !mReverseSorting && Trait::lt( *j2, *j1 ) + || mReverseSorting && Trait::lt( *j1, *j2 ) ) { + qSwap( *j1, *j2 ); + } + ++j1; + ++j2; + } + ++i1; + --i2; + } +} + +void AddresseeList::sortByField( Field *field ) +{ + if ( !field ) { + kdWarning(5700) << "sortByField called with no active sort field" << endl; + return; + } + + sActiveField = field; + + if ( count() == 0 ) + return; + + KABC::FieldSortMode *mode = new KABC::FieldSortMode( sActiveField, !mReverseSorting ); + + KABC::Addressee::setSortMode( mode ); + qHeapSort( *this ); + KABC::Addressee::setSortMode( 0 ); + + delete mode; +} + +void AddresseeList::sortByMode( SortMode *mode ) +{ + if ( count() == 0 ) + return; + + KABC::Addressee::setSortMode( mode ); + qHeapSort( *this ); + KABC::Addressee::setSortMode( 0 ); +} + +Field* +AddresseeList::sortingField() const +{ + return sActiveField; +} diff --git a/kabc/addresseelist.h b/kabc/addresseelist.h new file mode 100644 index 000000000..2e6df06e4 --- /dev/null +++ b/kabc/addresseelist.h @@ -0,0 +1,221 @@ +/* + 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 <qvaluelist.h> + +#include "addressee.h" + +namespace KABC { + +class Field; +class SortField; +class SortMode; + +/** + * 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: + static bool eq( const Addressee &, const Addressee & ); + static bool lt( const Addressee &, const Addressee & ); +}; + +class KABC_EXPORT Name +{ + public: + static bool eq( const Addressee &, const Addressee & ); + static bool lt( const Addressee &, const Addressee & ); +}; + +class KABC_EXPORT FormattedName +{ + public: + static bool eq( const Addressee &, const Addressee & ); + static bool lt( const Addressee &, const Addressee & ); +}; + +class KABC_EXPORT FamilyName // fallback to given name +{ + public: + static bool eq( const Addressee &, const Addressee & ); + static bool lt( const Addressee &, const Addressee & ); +}; + +class KABC_EXPORT GivenName // fallback to family name +{ + public: + static bool eq( const Addressee &, const Addressee & ); + static bool lt( const Addressee &, const Addressee & ); +}; + +} + +/** + * 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 by QValueList 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 QValueList<Addressee> +{ + public: + AddresseeList(); + ~AddresseeList(); + AddresseeList( const AddresseeList & ); + AddresseeList( const QValueList<Addressee> & ); + + /** + * Debug output. + */ + void dump() const; + + /** + * Determines the direction of sorting. On change, the list + * will <em>not</em> automatically be resorted. + * @param r <tt>true</tt> if sorting should be done reverse, <tt>false</tt> otherwise + */ + void setReverseSorting( bool r = true ) { mReverseSorting = r; } + + /** + * Returns the direction of sorting. + * @return <tt>true</tt> if sorting is done reverse, <tt>false</tt> otherwise + */ + bool reverseSorting() const { return mReverseSorting; } + + /** + * 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 + * @since 3.4 + */ + 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<MySortingTrait>(); + * \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 { return mActiveSortingCriterion; } + + /** + * 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; + + private: + bool mReverseSorting; + SortingCriterion mActiveSortingCriterion; + //KDE 4.0 - add a d-pointer here! +}; + +} + +#endif diff --git a/kabc/addresslineedit.cpp b/kabc/addresslineedit.cpp new file mode 100644 index 000000000..8e20c7975 --- /dev/null +++ b/kabc/addresslineedit.cpp @@ -0,0 +1,610 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 Helge Deller <deller@gmx.de> + 2002 Lubos Lunak <llunak@suse.cz> + 2001,2003 Carsten Pfeiffer <pfeiffer@kde.org> + 2001 Waldo Bastian <bastian@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. +*/ + +// $Id$ + +#include "addresslineedit.h" + +#include <qapplication.h> +#include <qobject.h> +#include <qptrlist.h> +#include <qregexp.h> +#include <qevent.h> +#include <qdragobject.h> + +#include <kcompletionbox.h> +#include <kconfig.h> +#include <kcursor.h> +#include <kstandarddirs.h> +#include <kstaticdeleter.h> +#include <kstdaccel.h> +#include <kurldrag.h> + +#include <kabc/stdaddressbook.h> +#include <kabc/distributionlist.h> +#include "ldapclient.h" + +#include <kdebug.h> + +//============================================================================= +// +// Class AddressLineEdit +// +//============================================================================= + + +using namespace KABC; + +KCompletion * AddressLineEdit::s_completion = 0L; +bool AddressLineEdit::s_addressesDirty = false; +QTimer* AddressLineEdit::s_LDAPTimer = 0L; +LdapSearch* AddressLineEdit::s_LDAPSearch = 0L; +QString* AddressLineEdit::s_LDAPText = 0L; +AddressLineEdit* AddressLineEdit::s_LDAPLineEdit = 0L; +KConfig *AddressLineEdit::s_config = 0L; + +static KStaticDeleter<KCompletion> completionDeleter; +static KStaticDeleter<QTimer> ldapTimerDeleter; +static KStaticDeleter<LdapSearch> ldapSearchDeleter; +static KStaticDeleter<QString> ldapTextDeleter; +static KStaticDeleter<KConfig> configDeleter; + +AddressLineEdit::AddressLineEdit(QWidget* parent, + bool useCompletion, + const char *name) + : KLineEdit(parent,name) +{ + m_useCompletion = useCompletion; + m_completionInitialized = false; + m_smartPaste = false; + + init(); + + // Whenever a new AddressLineEdit is created (== a new composer is created), + // we set a dirty flag to reload the addresses upon the first completion. + // The address completions are shared between all AddressLineEdits. + // Is there a signal that tells us about addressbook updates? + if (m_useCompletion) + s_addressesDirty = true; +} + + +//----------------------------------------------------------------------------- +void AddressLineEdit::init() +{ + if ( !s_completion ) { + completionDeleter.setObject( s_completion, new KCompletion() ); + s_completion->setOrder( KCompletion::Sorted ); + s_completion->setIgnoreCase( true ); + } + + if( m_useCompletion ) { + if( !s_LDAPTimer ) { + ldapTimerDeleter.setObject( s_LDAPTimer, new QTimer ); + ldapSearchDeleter.setObject( s_LDAPSearch, new LdapSearch ); + ldapTextDeleter.setObject( s_LDAPText, new QString ); + } + connect( s_LDAPTimer, SIGNAL( timeout()), SLOT( slotStartLDAPLookup())); + connect( s_LDAPSearch, SIGNAL( searchData( const QStringList& )), + SLOT( slotLDAPSearchData( const QStringList& ))); + } + + if ( m_useCompletion && !m_completionInitialized ) + { + setCompletionObject( s_completion, false ); // we handle it ourself + connect( this, SIGNAL( completion(const QString&)), + this, SLOT(slotCompletion() )); + + KCompletionBox *box = completionBox(); + connect( box, SIGNAL( highlighted( const QString& )), + this, SLOT( slotPopupCompletion( const QString& ) )); + connect( box, SIGNAL( userCancelled( const QString& )), + SLOT( userCancelled( const QString& ))); + + m_completionInitialized = true; // don't connect muliple times. That's + // ugly, tho, better have completionBox() + // virtual in KDE 4 + // Why? This is only called once. Why should this be called more + // than once? And why was this protected? + } +} + +//----------------------------------------------------------------------------- +AddressLineEdit::~AddressLineEdit() +{ +} + +//----------------------------------------------------------------------------- + +KConfig* AddressLineEdit::config() +{ + if ( !s_config ) + configDeleter.setObject( s_config, new KConfig( "kabldaprc", false, false ) ); // Open read-write, no kdeglobals + + return s_config; +} + +void AddressLineEdit::setFont( const QFont& font ) +{ + KLineEdit::setFont( font ); + if ( m_useCompletion ) + completionBox()->setFont( font ); +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::keyPressEvent(QKeyEvent *e) +{ + bool accept = false; + + if (KStdAccel::shortcut(KStdAccel::SubstringCompletion).contains(KKey(e))) + { + doCompletion(true); + accept = true; + } + else if (KStdAccel::shortcut(KStdAccel::TextCompletion).contains(KKey(e))) + { + int len = text().length(); + + if (len == cursorPosition()) // at End? + { + doCompletion(true); + accept = true; + } + } + + if( !accept ) + KLineEdit::keyPressEvent( e ); + + if( e->isAccepted()) + { + if( m_useCompletion && s_LDAPTimer != NULL ) + { + if( *s_LDAPText != text()) + stopLDAPLookup(); + *s_LDAPText = text(); + s_LDAPLineEdit = this; + s_LDAPTimer->start( 500, true ); + } + } +} + +void AddressLineEdit::mouseReleaseEvent( QMouseEvent * e ) +{ + if (m_useCompletion && (e->button() == MidButton)) + { + m_smartPaste = true; + KLineEdit::mouseReleaseEvent(e); + m_smartPaste = false; + return; + } + KLineEdit::mouseReleaseEvent(e); +} + +void AddressLineEdit::insert(const QString &t) +{ + if (!m_smartPaste) + { + KLineEdit::insert(t); + return; + } + QString newText = t.stripWhiteSpace(); + if (newText.isEmpty()) + return; + + // remove newlines in the to-be-pasted string as well as an eventual + // mailto: protocol + newText.replace( QRegExp("\r?\n"), ", " ); + if ( newText.startsWith( "mailto:" ) ) + { + KURL u(newText); + newText = u.path(); + } + else if (newText.find(" at ") != -1) + { + // Anti-spam stuff + newText.replace( " at ", "@" ); + newText.replace( " dot ", "." ); + } + else if (newText.find("(at)") != -1) + { + newText.replace( QRegExp("\\s*\\(at\\)\\s*"), "@" ); + } + + QString contents = text(); + int start_sel = 0; + int end_sel = 0; + int pos = cursorPosition(); + if (getSelection(&start_sel, &end_sel)) + { + // Cut away the selection. + if (pos > end_sel) + pos -= (end_sel - start_sel); + else if (pos > start_sel) + pos = start_sel; + contents = contents.left(start_sel) + contents.right(end_sel+1); + } + + int eot = contents.length(); + while ((eot > 0) && contents[eot-1].isSpace()) eot--; + if (eot == 0) + { + contents = QString::null; + } + else if (pos >= eot) + { + if (contents[eot-1] == ',') + eot--; + contents.truncate(eot); + contents += ", "; + pos = eot+2; + } + + contents = contents.left(pos)+newText+contents.mid(pos); + setText(contents); + setCursorPosition(pos+newText.length()); +} + +void AddressLineEdit::paste() +{ + if (m_useCompletion) + m_smartPaste = true; + KLineEdit::paste(); + m_smartPaste = false; +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::cursorAtEnd() +{ + setCursorPosition( text().length() ); +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::enableCompletion(bool enable) +{ + m_useCompletion = enable; +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::doCompletion(bool ctrlT) +{ + if ( !m_useCompletion ) + return; + + QString prevAddr; + + QString s(text()); + int n = s.findRev(','); + + if (n >= 0) + { + n++; // Go past the "," + + int len = s.length(); + + // Increment past any whitespace... + while( n < len && s[n].isSpace() ) + n++; + + prevAddr = s.left(n); + s = s.mid(n,255).stripWhiteSpace(); + } + + if ( s_addressesDirty ) + loadAddresses(); + + if ( ctrlT ) + { + QStringList completions = s_completion->substringCompletion( s ); + if (completions.count() > 1) { + m_previousAddresses = prevAddr; + setCompletedItems( completions ); + } + else if (completions.count() == 1) + setText(prevAddr + completions.first()); + + cursorAtEnd(); + return; + } + + KGlobalSettings::Completion mode = completionMode(); + + switch ( mode ) + { + case KGlobalSettings::CompletionPopupAuto: + { + if (s.isEmpty()) + break; + } + case KGlobalSettings::CompletionPopup: + { + m_previousAddresses = prevAddr; + QStringList items = s_completion->allMatches( s ); + items += s_completion->allMatches( "\"" + s ); + items += s_completion->substringCompletion( '<' + s ); + uint beforeDollarCompletionCount = items.count(); + + if( s.find( ' ' ) == -1 ) // one word, possibly given name + items += s_completion->allMatches( "$$" + s ); + + if ( !items.isEmpty() ) + { + if ( items.count() > beforeDollarCompletionCount ) + { + // remove the '$$whatever$' part + for( QStringList::Iterator it = items.begin(); + it != items.end(); + ++it ) + { + int pos = (*it).find( '$', 2 ); + if( pos < 0 ) // ??? + continue; + (*it)=(*it).mid( pos + 1 ); + } + } + + items = removeMailDupes( items ); + + // We do not want KLineEdit::setCompletedItems to perform text + // completion (suggestion) since it does not know how to deal + // with providing proper completions for different items on the + // same line, e.g. comma-separated list of email addresses. + bool autoSuggest = (mode != KGlobalSettings::CompletionPopupAuto); + setCompletedItems( items, autoSuggest ); + + if (!autoSuggest) + { + int index = items.first().find( s ); + QString newText = prevAddr + items.first().mid( index ); + //kdDebug() << "OLD TEXT: " << text() << endl; + //kdDebug() << "NEW TEXT: " << newText << endl; + setUserSelection(false); + setCompletedText(newText,true); + } + } + + break; + } + + case KGlobalSettings::CompletionShell: + { + QString match = s_completion->makeCompletion( s ); + if ( !match.isNull() && match != s ) + { + setText( prevAddr + match ); + cursorAtEnd(); + } + break; + } + + case KGlobalSettings::CompletionMan: // Short-Auto in fact + case KGlobalSettings::CompletionAuto: + { + if (!s.isEmpty()) + { + QString match = s_completion->makeCompletion( s ); + if ( !match.isNull() && match != s ) + { + QString adds = prevAddr + match; + setCompletedText( adds ); + } + break; + } + } + case KGlobalSettings::CompletionNone: + default: // fall through + break; + } +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::slotPopupCompletion( const QString& completion ) +{ + setText( m_previousAddresses + completion ); + cursorAtEnd(); +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::loadAddresses() +{ + s_completion->clear(); + s_addressesDirty = false; + + QStringList adrs = addresses(); + for( QStringList::ConstIterator it = adrs.begin(); it != adrs.end(); ++it) + addAddress( *it ); +} + +void AddressLineEdit::addAddress( const QString& adr ) +{ + s_completion->addItem( adr ); + int pos = adr.find( '<' ); + if( pos >= 0 ) + { + ++pos; + int pos2 = adr.find( pos, '>' ); + if( pos2 >= 0 ) + s_completion->addItem( adr.mid( pos, pos2 - pos )); + } +} + +void AddressLineEdit::slotStartLDAPLookup() +{ + if( !s_LDAPSearch->isAvailable() || s_LDAPLineEdit != this ) + return; + startLoadingLDAPEntries(); +} + +void AddressLineEdit::stopLDAPLookup() +{ + s_LDAPSearch->cancelSearch(); + s_LDAPLineEdit = NULL; +} + +void AddressLineEdit::startLoadingLDAPEntries() +{ + QString s( *s_LDAPText ); + // TODO cache last? + QString prevAddr; + int n = s.findRev(','); + if (n>= 0) + { + prevAddr = s.left(n+1) + ' '; + s = s.mid(n+1,255).stripWhiteSpace(); + } + if( s.length() == 0 ) + return; + + loadAddresses(); // TODO reuse these? + s_LDAPSearch->startSearch( s ); +} + +void AddressLineEdit::slotLDAPSearchData( const QStringList& adrs ) +{ + if( s_LDAPLineEdit != this ) + return; + for( QStringList::ConstIterator it = adrs.begin(); it != adrs.end(); ++it ) { + QString name(*it); + int pos = name.find( " <" ); + int pos_comma = name.find( ',' ); + // put name in quotes, if we have a comma in the name + if (pos>0 && pos_comma>0 && pos_comma<pos) { + name.insert(pos, '\"'); + name.prepend('\"'); + } + addAddress( name ); + } + + if( hasFocus() || completionBox()->hasFocus()) + { + if( completionMode() != KGlobalSettings::CompletionNone ) + { + doCompletion( false ); + } + } +} + +QStringList AddressLineEdit::removeMailDupes( const QStringList& adrs ) +{ + QStringList src = adrs; + qHeapSort( src ); + QString last; + for( QStringList::Iterator it = src.begin(); it != src.end(); ) { + if( *it == last ) + { + it = src.remove( it ); + continue; // dupe + } + last = *it; + ++it; + } + return src; +} + +//----------------------------------------------------------------------------- +void AddressLineEdit::dropEvent(QDropEvent *e) +{ + KURL::List uriList; + if(KURLDrag::canDecode(e) && KURLDrag::decode( e, uriList )) + { + QString ct = text(); + KURL::List::Iterator it = uriList.begin(); + for (; it != uriList.end(); ++it) + { + if (!ct.isEmpty()) ct.append(", "); + KURL u(*it); + if ((*it).protocol() == "mailto") + ct.append( (*it).path() ); + else + ct.append( (*it).url() ); + } + setText(ct); + setEdited( true ); + } + else { + if (m_useCompletion) + m_smartPaste = true; + QLineEdit::dropEvent(e); + m_smartPaste = false; + } +} + + +QStringList AddressLineEdit::addresses() +{ + QApplication::setOverrideCursor( KCursor::waitCursor() ); // loading might take a while + + QStringList result; + QString space(" "); + QRegExp needQuotes("[^ 0-9A-Za-z\\x0080-\\xFFFF]"); + QString endQuote("\" "); + QString addr, email; + + KABC::AddressBook *addressBook = KABC::StdAddressBook::self(); + KABC::AddressBook::Iterator it; + for( it = addressBook->begin(); it != addressBook->end(); ++it ) { + QStringList emails = (*it).emails(); + + QString n = (*it).prefix() + space + + (*it).givenName() + space + + (*it).additionalName() + space + + (*it).familyName() + space + + (*it).suffix(); + + n = n.simplifyWhiteSpace(); + + QStringList::ConstIterator mit; + + for ( mit = emails.begin(); mit != emails.end(); ++mit ) { + email = *mit; + if (!email.isEmpty()) { + if (n.isEmpty() || (email.find( '<' ) != -1)) + addr = QString::null; + else { /* do we really need quotes around this name ? */ + if (n.find(needQuotes) != -1) + addr = '"' + n + endQuote; + else + addr = n + space; + } + + if (!addr.isEmpty() && (email.find( '<' ) == -1) + && (email.find( '>' ) == -1) + && (email.find( ',' ) == -1)) + addr += '<' + email + '>'; + else + addr += email; + addr = addr.stripWhiteSpace(); + result.append( addr ); + } + } + } + + KABC::DistributionListManager manager( addressBook ); + manager.load(); + result += manager.listNames(); + + QApplication::restoreOverrideCursor(); + + return result; +} + +#include "addresslineedit.moc" diff --git a/kabc/addresslineedit.h b/kabc/addresslineedit.h new file mode 100644 index 000000000..05a0a7c58 --- /dev/null +++ b/kabc/addresslineedit.h @@ -0,0 +1,123 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 Helge Deller <deller@gmx.de> + 2002 Lubos Lunak <llunak@suse.cz> + + 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_ADDRESSLINEEDIT_H +#define KABC_ADDRESSLINEEDIT_H +// $Id$ + +#include <qobject.h> +#include <qptrlist.h> +#include <qtimer.h> + +#include "klineedit.h" +#include "kcompletion.h" + +class KConfig; + +namespace KABC { + +class LdapSearch; + +/** + * A lineedit with LDAP and kabc completion + * + * This lineedit is supposed to be used wherever the user types email addresses + * and might want a completion. You can simply use it as a replacement for + * KLineEdit or QLineEdit. + * + * You can enable or disable the lineedit at any time. + * + * @see AddressLineEdit::enableCompletion() + */ +class KABC_EXPORT AddressLineEdit : public KLineEdit +{ + Q_OBJECT +public: + AddressLineEdit(QWidget* parent, bool useCompletion = true, + const char *name = 0L); + virtual ~AddressLineEdit(); + + /** + * Reimplented for internal reasons. + * @ see KLineEdit::setFont() + */ + virtual void setFont( const QFont& ); + + static KConfig *config(); + +public slots: + /** + * Set cursor to end of line. + */ + void cursorAtEnd(); + /** + * Toggle completion. + */ + void enableCompletion( bool enable ); + +protected: + /** + * Always call AddressLineEdit::loadAddresses() as the first thing. + * Use addAddress() to add addresses. + */ + virtual void loadAddresses(); + void addAddress( const QString& ); + virtual void keyPressEvent(QKeyEvent*); + virtual void dropEvent(QDropEvent *e); + virtual void paste(); + virtual void insert(const QString &t); + virtual void mouseReleaseEvent( QMouseEvent * e ); + void doCompletion(bool ctrlT); + +private slots: + void slotCompletion() { doCompletion(false); } + void slotPopupCompletion( const QString& ); + void slotStartLDAPLookup(); + void slotLDAPSearchData( const QStringList& ); + +private: + void init(); + void startLoadingLDAPEntries(); + void stopLDAPLookup(); + QStringList addresses(); + QStringList removeMailDupes( const QStringList& adrs ); + + QString m_previousAddresses; + bool m_useCompletion; + bool m_completionInitialized; + bool m_smartPaste; + QString m_typedText; // unused + + static bool s_addressesDirty; + static KCompletion *s_completion; + static QTimer *s_LDAPTimer; + static LdapSearch *s_LDAPSearch; + static QString *s_LDAPText; + static AddressLineEdit *s_LDAPLineEdit; + static KConfig *s_config; + +private: + class AddressLineEditPrivate* d; +}; + +} + +#endif /* KABC_ADDRESSLINEEDIT_H */ diff --git a/kabc/agent.cpp b/kabc/agent.cpp new file mode 100644 index 000000000..780beb4ae --- /dev/null +++ b/kabc/agent.cpp @@ -0,0 +1,148 @@ +/* + 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 "addressee.h" + +#include "agent.h" + +using namespace KABC; + +Agent::Agent() + : mAddressee( 0 ), mIntern( false ) +{ +} + +Agent::Agent( const QString &url ) + : mAddressee( 0 ),mUrl( url ), mIntern( false ) +{ +} + +Agent::Agent( Addressee *addressee ) + : mAddressee( addressee ), mIntern( true ) +{ +} + +Agent::~Agent() +{ + delete mAddressee; + mAddressee = 0; +} + +bool Agent::operator==( const Agent &a ) const +{ + if ( mIntern != a.mIntern ) + return false; + + if ( !mIntern ) { + if ( mUrl != a.mUrl ) + return false; + } else { + if ( mAddressee && !a.mAddressee ) return false; + if ( !mAddressee && a.mAddressee ) return false; + if ( !mAddressee && !a.mAddressee ) return false; + if ( (*mAddressee) != (*a.mAddressee) ) return false; + } + + return true; +} + +bool Agent::operator!=( const Agent &a ) const +{ + return !( a == *this ); +} + +Agent &Agent::operator=( const Agent &addr ) +{ + if ( this == &addr ) + return *this; + + if ( addr.mIntern && addr.mAddressee ) { + if ( mAddressee ) + delete mAddressee; + + mAddressee = new Addressee; + *mAddressee = *(addr.mAddressee); + } + + mUrl = addr.mUrl; + mIntern = addr.mIntern; + + return *this; +} + +void Agent::setUrl( const QString &url ) +{ + mUrl = url; + mIntern = false; +} + +void Agent::setAddressee( Addressee *addressee ) +{ + mAddressee = addressee; + mIntern = true; +} + +bool Agent::isIntern() const +{ + return mIntern; +} + +QString Agent::url() const +{ + return mUrl; +} + +Addressee *Agent::addressee() const +{ + return mAddressee; +} + +QString Agent::asString() const +{ + if ( mIntern ) + return "intern agent"; + else + return mUrl; +} + +QDataStream &KABC::operator<<( QDataStream &s, const Agent &agent ) +{ + Q_UINT32 hasAddressee = ( agent.mAddressee != 0 ); + + s << agent.mIntern << agent.mUrl << hasAddressee; + if ( hasAddressee ) + s << (*agent.mAddressee); + + return s; +} + +QDataStream &KABC::operator>>( QDataStream &s, Agent &agent ) +{ + Q_UINT32 hasAddressee; + + s >> agent.mIntern >> agent.mUrl >> hasAddressee; + + if ( hasAddressee ) { + agent.mAddressee = new Addressee; + s >> (*agent.mAddressee); + } + + return s; +} diff --git a/kabc/agent.h b/kabc/agent.h new file mode 100644 index 000000000..a235e0247 --- /dev/null +++ b/kabc/agent.h @@ -0,0 +1,128 @@ +/* + 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_AGENT_H +#define KABC_AGENT_H + +class QDataStream; + +#include <qstring.h> + +#include <kdelibs_export.h> + +namespace KABC { + +class Addressee; + +/** + * Important!!! + * + * At the moment the vcard format does not support saving and loading + * this entity. + */ +class KABC_EXPORT Agent +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Agent & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Agent & ); + +public: + + /** + * Consturctor. Creates an empty object. + */ + Agent(); + + /** + * Consturctor. + * + * @param url A URL that describes the position of the agent file. + */ + Agent( const QString &url ); + + /** + * Consturctor. + * + * @param addressee The addressee object of the agent. + */ + Agent( Addressee *addressee ); + + /** + * Destructor. + */ + ~Agent(); + + + bool operator==( const Agent & ) const; + bool operator!=( const Agent & ) const; + Agent &operator=( const Agent & ); + + /** + * Sets a URL for the location of the agent file. When using this + * function, isIntern() will return 'false' until you use + * setAddressee(). + * + * @param url The location URL of the agent file. + */ + void setUrl( const QString &url ); + + /** + * Sets the addressee of the agent. When using this function, + * isIntern() will return 'true' until you use setUrl(). + * + * @param addressee The addressee object of the agent. + */ + void setAddressee( Addressee *addressee ); + + /** + * Returns whether the agent is described by a URL (extern) or + * by a addressee (intern). + * When this method returns 'true' you can use addressee() to + * get a Addressee object. Otherwise you can request the URL + * of this agent by url() and load the data from that location. + */ + bool isIntern() const; + + /** + * Returns the location URL of this agent. + */ + QString url() const; + + /** + * Returns the addressee object of this agent. + */ + Addressee* addressee() const; + + /** + * Returns string representation of the agent. + */ + QString asString() const; + +private: + Addressee *mAddressee; + QString mUrl; + + int mIntern; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Agent & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Agent & ); + +} +#endif diff --git a/kabc/countrytransl.map b/kabc/countrytransl.map new file mode 100644 index 000000000..1459f0942 --- /dev/null +++ b/kabc/countrytransl.map @@ -0,0 +1,12381 @@ +Andorra ad +Andorra ad +أندورا ad +Ðндора ad +Ðндора ad +অà§à¦¯à¦¾à¦¨à¦¡à§‹à¦°à¦¾ ad +Andora ad +Andora ad +ΑνδόÏα ad +Andoro ad +آندورا ad +Andorre ad +Andóra ad +×× ×“×•×¨×” ad +अंडोरा ad +アンドラ ad +អង់ដូរ៉ា ad +안ë„ë¼ ad +àºàºµàº™à»€àº”ີຠad +Andora ad +Ðндора ad +Ðндорра ad +à¨à¨‚ਡੋਰਾ ad +Andora ad +Ðндорра ad +Andora ad +Ðндора ad +Andora ad +அனà¯à®Ÿà¯‹à®°à®¾ ad +Ðндора ad +à¹à¸à¸™à¹‚ดรา ad +Ðндорра ad +Ðндорра ad +Andore ad +安é“å°” ad +安é“爾 ad +United Arab Emirates ae +Vereenigde Arabiese Emirate ae +الإمارات العربية المتØدة ae +Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ ÐрабÑÐºÑ–Ñ Ðміраты ae +ОÐЕ ae +সংযà§à¦•à§à¦¤ আরব আমিরশাহি ae +Stadoù-Unanet Arabeg ae +Ujedinjeni arapski emirati ae +Emirats Àrabs Units ae +Spojené arabské emiráty ae +Emiraethau Arabaidd Unedig ae +Forenende Arabiske Emirater ae +Vereinigte Arabische Emirate ae +ΕνωμÎνα ΑÏαβικά ΕμιÏάτα ae +UniÄintaj Arabaj Emirlandoj ae +Emiratos árabes unidos ae +Araabia Ãœhendemiraadid ae +Arabiar Emirato Batuak ae +امارات متØده عربی ae +Yhdistyneet Arabiemiraatit ae +Émirats Arabes Unis ae +Ferienigde Arabyske Emiraten ae +Aontas na nÉimÃrÃochtaà Arabacha ae +Emiratos Ãrabes Unidos ae +×יחוד ×”×מירויות הערביות ae +संयà¥à¤•à¥à¤¤ अरब अमीरात ae +Ujedinjeni arapski emirati ae +Egyesült Arab Emirátusok ae +Sameinuðu arabÃsku furstadæmin ae +Emirati Arabi Uniti ae +アラブ首長国連邦 ae +អារ៉ាប់​រួម ae +ì•„ëž ì—ë¯¸ë ˆì´íŠ¸ ì—°í•© ae +ສະຫະລັດ ae +Jungtiniai Arabų Emiratai ae +Apvienotie ArÄbu EmerÄti ae +Обединети ÐрапÑки Емирати ae +ÐÑгдÑÑн арабын имрат ae +Emirati Għarab Magħquda ae +De forente arabiske emirater ae +Vereenigte Araabsche Emiraten ae +Verenigde Arabische Emiraten ae +Dei sameinte arabiske emirata ae +Di-Emirate tseo di Kopanego tsa Arab ae +ਸੰਯà©à¨•à¨¤ ਅਰਬ ਅਮੀਰਾਤ ae +Zjednoczone Emiraty Arabskie ae +Emiratos Ãrabes Unidos ae +Emirados Ãrabes Unidos ae +Emiratele Arabe Unite ae +Объединенные ÐрабÑкие Ðмираты ae +Leta Zunze Ubumwe z'Abarabu ae +Ovttastuvvon arábalaÅ¡ emiráhtat ae +Spojené arabské emiráty ae +Združeni arabski Emirati ae +Уједињени арапÑки емирати ae +Ujedinjeni arapski emirati ae +Förenade arabemiraten ae +யà¯à®©à¯ˆà®Ÿà¯†à®Ÿà¯ அரபி எமிரேடà¯à®¸à¯ ae +Ðморати муттаҳидаи Ðраб ae +สหรัà¸à¸à¸²à¸«à¸£à¸±à¸šà¸à¸µà¸¡à¸´à¹€à¸£à¸•à¸ªà¹Œ ae +BirleÅŸik Arap Emirlikleri ae +Berläşkän Ğäräp Ämirlekläre ae +Об'єднані ÐрабÑькі Емірати ae +Бирлашган Ðраб Ðмирликлари ae +Mashango o tangananaho a Emirates ae +Emirat Arabes Unis ae +阿è”é…‹ ae +阿拉伯è¯åˆå¤§å…¬åœ‹ ae +Izindawo zezinduna zase-United Arab ae +Afghanistan af +Ø£Ùغانستان af +ÐфганіÑтан af +ÐфганиÑтан af +আফগানিসà§à¦¤à¦¾à¦¨ af +Afganistan af +Afganistan af +Afganistan af +Afghanistán af +Affganistan af +Αφγανιστάν af +Afganio af +Afghanistán af +Afganistan af +اÙغانستان af +Afganistan af +An Afganastáin af +Afganistan af +××¤×’× ×™×¡×˜×Ÿ af +अफगानिसà¥à¤¤à¤¾à¤¨ af +Afganistan af +Afganisztán af +Afganistan af +Afganistan af +アフガニスタン af +អាហ្វកានីស្ážáž¶áž“ af +아프가니스탄 af +ລີທົ່ວເນີຠaf +AfganistÄna af +ÐвганиÑтан af +ÐфганÑтан af +Afganistan af +ਅਫਗਾਨਿਸਤਾਨ af +Afganistan af +Afeganistão af +Afeganistão af +Afganistan af +ÐфганиÑтан af +Afuganisitani af +Afganistan af +Afganistan af +ÐвганиÑтан af +Avganistan af +Afganistan af +ஆபà¯à®•à®¾à®©à®¿à®¸à¯à®¤à®¾à®©à¯ af +ÐфғониÑтон af +à¸à¸²à¸Ÿà¸à¸²à¸™à¸´à¸ªà¸–าน af +Afganistan af +Äfğänstan af +ÐфганіÑтан af +ÐфғониÑтон af +Afganistan af +阿富汗 af +阿富汗 af +Antigua and Barbuda ag +Antigue en Barbuda ag +أنتيغوا Ùˆ باربودا ag +Antigua vÉ™ Barbuda ag +Ðнтыгуа Ñ– Барбуда ag +Ðнтигуа и Барбуда ag +অà§à¦¯à¦¾à¦¨à§à¦Ÿà¦¿à¦—à§à§Ÿà¦¾ à¦à¦¬à¦‚ বারà§à¦¬à§à¦¡à¦¾ ag +Antigua ha Barbuda ag +Antigua i Barbuda ag +Antigua i Barbuda ag +Antigua a Barbuda ag +Antigwa a Barbwda ag +Antigua og Barbuda ag +Antigua und Barbuda ag +Αντίγκουα και ΜπαÏμποÏντα ag +Antigvo-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 +Antigua en Barbuda ag +Antigua agus Barbúda ag +Antiga e Barbuda ag +×× ×˜×™×’×•××” ובריבודה ag +à¤à¤¨à¥à¤Ÿà¤¿à¤—à¥à¤† और बारबूडा ag +Antigua i Barbuda ag +Antigua és Barbuda ag +Antigua dan Barbuda ag +AntÃgva og Barbúda ag +Antigua e Barbuda ag +アンティグアãƒãƒ¼ãƒ–ーダ ag +Antigua áž“áž·áž„ Barbuda ag +앤티가 바부다 ag +Antikva ir Barbuda ag +Antigva un Barbuda ag +Ðнтигва и Барбуда ag +Ðнтигуа ба Барбуда ag +Antigwa u Barbuda ag +Antigua og Barbuda ag +Antigua un Barbuda ag +Antigua en Barbuda ag +Antigua og Barbuda ag +Antigua le Barbuda ag +Antigua e Barbuda ag +à¨à¨‚ਟੀਗà©à¨† ਤੇ ਬਾਰਬà©à¨¡à¨¾ ag +Antigua i Barbuda ag +AntÃgua e Barbuda ag +Antigua e Barbuda ag +Antigua ÅŸi Barbuda ag +Ðнтигуа и Барбуда ag +Antigwa na Barubida ag +Antigua ja Barbuda ag +Antigua a Barbuda ag +Antigva in Barbuda ag +Ðнтигва и Барбуда ag +Antigva i Barbuda ag +I-Antigua kanye ne Barbuda ag +Antigua och Barbuda ag +ஆனà¯à®Ÿà®¿à®•à®¾ மறà¯à®±à¯à®®à¯ பெரà¯à®®à¯à®Ÿà®¾ ag +Ðнтигуо ва Барбудо ag +à¸à¸±à¸™à¸—ิà¸à¸±à¸§ à¹à¸¥à¸° บาร์บูดา ag +Antigua ve Barbuda ag +Antigua wä Barbuda ag +Трінідад Ñ– Тобаго 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 +Ðнгила ai +অà§à¦¯à¦¾à¦™à§à¦—à§à¦‡à¦²à¦¾ ai +Angilla ai +Angwila ai +Ανγκουίλα ai +Angvilo ai +آنگوییلا ai +×× ×’×•×•×™×œ×” ai +à¤à¤‚गà¥à¤à¤²à¤¾ ai +Angvilla ai +ã‚¤ã‚®ãƒªã‚¹å±žé ˜ã‚¢ãƒ³ã‚®ãƒ© ai +អង់ហ្ស៊ីឡា ai +ì•™ê¸¸ë¼ ai +à»àºžàº™àº§àº´àº™ ai +Ðнгилја ai +Ðнгуаилла ai +Angwilla ai +à¨à¨‚ਨਗà©à¨ˆà¨²à¨¾ ai +Anghila ai +Ðнгилла ai +Angwiya ai +Angvila ai +Ðнгвила ai +Angvila ai +ஆனà¯à®•à®¿à®²à¯à®²à®¾ ai +Ðнгуилло ai +à¹à¸à¸‡à¸à¸µà¸¥à¸² ai +ÐÐ½Ð³Ñ–Ð»ÑŒÑ ai +Ðнгвилла ai +Anguila ai +安åœæ‹‰ ai +阿爾åŠåˆ©äºž ai +Albania al +Albanië al +ألبانيا al +ÐÐ»ÑŒÐ±Ð°Ð½Ñ–Ñ al +ÐÐ»Ð±Ð°Ð½Ð¸Ñ al +অলবেনিয়া al +Albani al +Albanija al +Albà nia al +Albánie al +Albanien al +Albanien al +Αλβανία al +Albanio al +Albaania al +آلبانی al +Albanie al +Albanië al +An Albáin al +Albánia al +××œ×‘× ×™×” al +अलà¥à¤¬à¤¾à¤¨à¤¿à¤¯à¤¾ al +Albánia al +AlbanÃa al +アルãƒãƒ‹ã‚¢ al +អាល់បានី al +알바니아 al +à»àºàº”à»àº¥àº™àº•àº´àº al +Albanija al +AlbÄnija al +Ðлбанија al +Ðлбани al +Albanija al +Albanien al +Albanië al +ਅਲਬਾਨੀਆ al +Albânia al +Albânia al +ÐÐ»Ð±Ð°Ð½Ð¸Ñ al +Alubaniya al +Albánia al +Albánsko al +Albanija al +Ðлбанија al +Albanija al +Albanien al +ஆலà¯à®ªà®©à®¿à®¯à®¾ al +Олбанӣ al +à¸à¸±à¸¥à¹€à¸šà¹€à¸™à¸µà¸¢ al +Arnavutluk al +ÐÐ»Ð±Ð°Ð½Ñ–Ñ al +ÐÐ»Ð±Ð°Ð½Ð¸Ñ al +Albaneye al +阿尔巴尼亚 al +阿亞巴尼亞 al +Armenia am +Armenië am +أرمينيا am +ÐрмÑÐ½Ñ–Ñ am +ÐÑ€Ð¼ÐµÐ½Ð¸Ñ am +আরà§à¦®à§‡à¦¨à¦¿à§Ÿà¦¾ am +Armeni am +Armenija am +Armènia am +Arménie am +Armenien am +Armenien am +ΑÏμενία am +Armenio am +Armeenia am +ارمنستان am +Arménie am +Armenië am +An Airméin am +Arménia am +××¨×ž× ×™×” am +आरà¥à¤®à¥‡à¤¨à¤¿à¤¯à¤¾ am +Örményország am +ArmenÃa am +アルメニア am +អារមáŸáž“ី am +아르메니아 am +àºàº²à»€àºˆàº™àº•àº´àº™àº² am +ArmÄ—nija am +ArmÄ“nija am +Ерменија am +Ðрмен am +Armenien am +Armenië am +ਅਰਮੀਨੀਆ am +Arménia am +Armênia am +ÐÑ€Ð¼ÐµÐ½Ð¸Ñ am +Arumeniya am +Arménsko am +Armenija am +Јерменија am +Jermenija am +Armenien am +ஆரà¯à®®à¯‡à®©à®¿à®¯à®¾ am +ÐрманиÑтон am +à¸à¸²à¸£à¹Œà¹€à¸¡à¹€à¸™à¸µà¸¢ am +Ermenistan am +Ärmänstan am +Ð’Ñ–Ñ€Ð¼ÐµÐ½Ñ–Ñ am +ÐрманиÑтон am +Ã…rmeneye am +亚美尼亚 am +亞美尼亞 am +Netherlands Antilles an +Nederlandse Antilles an +أنتيل هولندا an +ÐідÑрлÑндÑÐºÑ–Ñ Ðнтылы an +ХоландÑки Ðнтили an +নেদারলà§à¦¯à¦¾à¦£à§à¦¡à¦¸ অà§à¦¯à¦¾à¦¨à§à¦Ÿà¦¿à¦²à§‡à¦¸ an +Antilh an Izelvroioù an +Nizozemski Antili an +Antilles del Països Baixos an +Nizozemské Antily an +Ynysoedd Iseldiraidd Y Carib? an +Nederlandske antiller an +Niederländische Antillen an +ΟλλανδικÎÏ‚ Αντίλλες an +Nederlandaj Antiloj an +Antillas holandesas an +Hollandi Antillid an +Antilla Holandarrak an +آنتیلس هلند an +Alankomaiden Antillit an +Antilles néerlandaises an +Nederlânske Antillen an +Aintillà na hÃsiltÃre an +Antillas Holandesas an +नीदरलैंड à¤à¤¨à¥à¤Ÿà¥€à¤²à¥€à¤¸ an +Nizozemski Antili an +Holland-Antillák an +Hollensku Antillur an +Antille Olandesi an +ã‚ªãƒ©ãƒ³ãƒ€é ˜ã‚¢ãƒ³ãƒãƒ« an +អង់ទីយáŸâ€‹áž ូល្លង់ an +네ëœëž€ë“œë ¹ ì•ˆí‹¸ë ˆìŠ¤ an +ເນເທີà»àº¥àº™ an +Nyderlandų Antilai an +NÄ«derlandes Antiļas an +ХоландÑки Ðнтили an +Ðедерландын ÐнтиллÑÑ an +De nederlandske Antillene an +Nedderlandsche Antillen an +Nederlandse Antillen an +Dei nederlandske Antillane an +ਨੀਂਦਰਲੈਂਡ à¨à¨‚ਟੀਲੀਸ an +Antyle Holenderskie an +Antilhas Holandês an +Antilhas Holandesas an +Antilele Olandeze an +ÐидерландÑкие ÐнтильÑкие оÑтрова an +Antiye z'Ubuholande an +HollándalaÅ¡ Antillat an +Holandské Antily an +Nizozemski Antili an +ХоландÑки антили an +Holandski antili an +Nederländska Antillerna an +நெதரà¯à®²à®¾à®¨à¯à®¤à¯ அனà¯à®Ÿà®¿à®²à¯à®¸à¯ an +ÐнтилиÑи Ҳолланд an +เนเธà¸à¸£à¹Œà¹à¸¥à¸™à¸”์ à¹à¸à¸™à¸—ิลีส an +Hollanda Antilleri an +Niderland Antilläre an +ÐнтільÑькі оÑтрови (Ðідерланди) an +Ðидерландлар Ðнтил Ороллари an +Hà Lan Antilles an +Antiyes Neyerlandesses an +è·å±žå®‰çš„列斯群岛 an +è·å±¬å®‰åœ°åˆ—斯群島 an +Angola ao +أنغولا ao +Ðнгола ao +Ðнгола ao +অà§à¦¯à¦¾à¦™à§à¦—োলা ao +Ανγκόλα ao +Angolo ao +آنگولا ao +Angóla ao +×× ×’×•×œ×” ao +अंगोला ao +Angóla ao +アンゴラ ao +អង់ហ្គោឡា ao +ì•™ê³¨ë¼ ao +ບັນà»àºà»€àº¥àºµàº ao +Ðнгола ao +Ðнгол ao +ਅੰਗੋਲਾ ao +Ðнгола ao +Ðнгола ao +ஆஙà¯à®•à¯‹à®²à®¾ ao +Ðнгуло ao +à¹à¸à¸‡à¹‚à¸à¸¥à¸² ao +Ðнгола ao +Ðнгола ao +安哥拉 ao +安哥拉 ao +Argentina ar +Argentinië ar +الأرجنتين ar +Ðргентына ar +Ðржентина ar +আরà§à¦œà§‡à¦¨à§à¦Ÿà¦¿à¦¨à¦¾ ar +Arc'hantina ar +Ariannin ar +Argentinien ar +ΑÏγεντινή ar +Argentino ar +آرژانتین ar +Agentiina ar +Argentine ar +Argentinië ar +An AirgintÃn ar +Arxentina ar +××¨×’× ×˜×™× ×” ar +अरà¥à¤œà¥‡à¤‚टीना ar +ArgentÃna ar +ArgentÃna ar +アルゼンãƒãƒ³ ar +អាហ្សង់ទីន ar +아르헨티나 ar +àºàº²à»€àºˆàº™àº•àº´àº™àº² ar +ArgentÄ«na ar +Ðргентина ar +Ðргентин ar +ArÄ¡entina ar +Argentinien ar +Argentinië ar +ਅਰਜ਼ਨਟੀਨਾ ar +Argentyna ar +Ðргентина ar +Arijantina ar +ArgentÃna ar +Ðргентина ar +I-Argentina ar +ஆரà¯à®šà¯†à®©à¯à®Ÿà®¿à®©à®¾ ar +Оржонтина ar +à¸à¸²à¸£à¹Œà¹€à¸ˆà¸™à¸•à¸´à¸™à¸² ar +Arjantin ar +Ðргентина ar +Ðргентина ar +Agenthina ar +Ã…rdjintene ar +é˜¿æ ¹å»· ar +é˜¿æ ¹å»· ar +American Samoa as +Amerikanse Samoa as +ساموا الأمريكية as +ÐмÑрыканÑкае Самоа as +ÐмериканÑки Самоа as +মারà§à¦•à¦¿à¦¨ সামোয়া as +Samoa amerikanek as +AmeriÄka Samoa as +Samoa Americana as +Americká Samoa as +Samoa Americanaidd as +Samoa (USA) as +Amerikanisches Samoa as +ΑμεÏικανική Σαμόα as +Amerika Samoo as +Samoa americana as +Ameerika Samoa as +Amerikar Samoa as +ساموای آمریکا as +Amerikan Samoa as +Samoa américaines as +Amerikaansk Samoa as +Samó Meiriceánach as +Samoa Americana as +סמו××” ×”××ž×¨×™×§× ×™×ª as +अमेरिकी सामोआ as +AmeriÄka Samoa as +Amerikai Szamoa as +BandarÃska Samóa as +Samoa Americane as +アメリカンサモア as +សាមូអា អាមáŸážšáž·áž€ as +미êµë ¹ 사모아 as +àºàº²à»€àº¡àº¥àº´àºàº²à»€àº«àº™àº·àº as +Amerikos Samoa as +Amerikas Samoa as +ÐмериканÑка Самоа as +Ðмерик, Самоа as +Samoa Amerikana as +Amerikansk Samoa as +Amerikaansch Samoa as +Amerikaans Samoa as +Amerikansk Samoa as +ਅਮਰੀਕੀ ਸਾਮੋਆ as +Samoa AmerykaÅ„skie as +Samoa Americana as +Samoa Americana as +Samoa americană as +ÐмериканÑкое Самоа as +Samowa Nyamerika as +AmerihkálaÅ¡ Samoa as +Americká Samoa as +AmeriÅ¡ka Samoa as +Ðмеричка Самоа as +AmeriÄka Samoa as +Amerikanska Samoa as +அமெரிகà¯à®•à®¾ சமோயா as +Самоаи Ðмрикоӣ as +à¸à¹€à¸¡à¸£à¸´à¸à¸±à¸™ ซามัว as +Amerika Samoası as +Amerikalı Samoa as +ÐмериканÑьке Самоа as +Ðмерика СамоаÑи as +Samowa Amerikinne as +美属è¨æ‘©äºš as +美屬薩摩亞 as +Austria at +Oostenryk at +النمسا at +Avstriya at +ÐÑžÑÑ‚Ñ€Ñ‹Ñ at +ÐвÑÑ‚Ñ€Ð¸Ñ at +অসà§à¦Ÿà§à¦°à¦¿à§Ÿà¦¾ at +Aostria at +Austrija at +Àustria at +Rakousko at +Awstria at +Østrig at +Österreich at +ΑυστÏία at +AÅstrio at +اتریش at +Itävalta at +EysturrÃki at +Autriche at +Eastenryk at +An Ostair at +×וסטריה at +आसà¥à¤Ÿà¥à¤°à¤¿à¤¯à¤¾ at +Austrija at +Ausztria at +AusturrÃki at +オーストリア at +អូទ្រីស at +오스트리아 at +àºàºàº”ສະເຕເລີຠat +Austrija at +Austrija at +ÐвÑтрија at +ÐвÑтри at +Awtrija at +Østerrike at +Österriek at +Oostenrijk at +Austerrike at +ਆਸਟਰੀਆ at +Ãustria at +Ãustria at +ÐвÑÑ‚Ñ€Ð¸Ñ at +Ositiriya at +Nuortariika at +Rakúsko at +Avstrija at +ÐуÑтрија at +Austrija at +I-Austria at +Österrike at +ஆஸà¯à®¤à¯à®¤à®¿à®°à®¿à®¯à®¾ at +ÐвÑÑ‚Ñ€Ð¸Ñ at +à¸à¸à¸ªà¹€à¸•à¸£à¸µà¸¢ at +Avusturya at +ÐвÑÑ‚Ñ€Ñ–Ñ at +ÐвÑÑ‚Ñ€Ð¸Ñ at +Ositiria at +Ão at +Otriche at +奥地利 at +奧地利 at +Australia au +Australië au +أستراليا au +Avustralya au +ÐÑžÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au +ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au +অসà§à¦Ÿà§à¦°à§‡à¦²à¦¿à§Ÿà¦¾ au +Aostralia au +Australija au +Austrà lia au +Austrálie au +Awstralia au +Australien au +Australien au +ΑυστÏαλία au +AÅstralio au +Austraalia au +استرالیا au +Australie au +Australië au +An Astráil au +Austrália au +×וסטרליה au +आसà¥à¤Ÿà¥à¤°à¥‡à¤²à¤¿à¤¯à¤¾ au +Australija au +Ausztrália au +ÃstralÃa au +オーストラリア au +អូស្ážáŸ’រាលី au +ì˜¤ìŠ¤íŠ¸ë ˆì¼ë¦¬ì•„ au +àºàºàº”ສະເຕເລີຠau +Australija au +AustrÄlija au +ÐвÑтралија au +ÐвÑтрали au +Awstralja au +Australien au +Australië au +ਅਸਟਰੇਲੀਆ au +Austrália au +Austrália au +ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au +Ositaraliya au +Austrália au +Austrália au +Avstralija au +ÐуÑтралија au +Australija au +I-Australia au +Australien au +ஆஸà¯à®¤à¯à®¤à®¿à®°à¯‡à®²à®¿à®¯à®¾ au +ОÑтролиё au +à¸à¸à¸ªà¹€à¸•à¸£à¹€à¸¥à¸µà¸¢ au +Avusturalya au +ÐвÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au +ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au +Ositiralia au +Úc au +Ostraleye au +澳大利亚 au +澳大利亞 au +Aruba aw +أروبا aw +Ðруба aw +আরà§à¦¬à¦¾ aw +Arwba aw +ΑÏοÏμπα aw +Arubo aw +آروبا aw +×רובה aw +अरूबा aw +Arúba aw +ã‚ªãƒ©ãƒ³ãƒ€è‡ªæ²»é ˜ã‚¢ãƒ«ãƒ aw +អារូបា aw +아루바 aw +ເàºàº¡à»„ັພ່ aw +Ðруба aw +Ðрува aw +ਅਰੂਬੀ aw +Ðруба aw +Ãruba aw +Ðруба aw +à®…à®°à¯à®ªà®¾ aw +Ðрубо aw +à¸à¸£à¸¹à¸šà¸² aw +Ðруба aw +Ðруба aw +Arouba aw +阿é²å·´ aw +阿é¯å·´ aw +Ã…land Islands ax +Ã…land Eilande ax +ОÑтрови Ðланд ax +Illes Ã…land ax +Ã…landské ostrovy ax +Ã…land-øerne ax +Aland ax +Îησιά Ã…land ax +Islas Aland ax +Ahvenamaa ax +Ã…land irlak ax +Ahvenanmaan saaret ax +ÃŽles Ã…land ax +Ã…land-eilannen ax +Na hOileáin Ã…land ax +Illas Ã…land ax +Ã…land-szigetek ax +Ãlandseyjar ax +Isole Ã…land ax +オーランド諸島 ax +កោះ Ã…land ax +Ã…land salos ax +ОÑтрови Оланд ax +Ã…land-øyene ax +Ã…land-Inseln ax +Ã…land-eilanden ax +Ã…land-øyane ax +ਅਮਾਨ ਟਾਪੂ ax +Wyspy Ã…land ax +Ilhas Ã…land ax +Ilhas Ã…land ax +ÐландÑкие оÑтрова ax +Ibirwa by'Ã…land ax +Ã…land sullot ax +Ã…landski otoki ax +ÐландÑка оÑтрва ax +Alandska ostrva ax +Ã…land ax +หมู่เà¸à¸²à¸°à¸à¸²à¸¥à¸±à¸™à¸”์ ax +Cayman Adaları ax +Aland Utrawları ax +ÐландÑькі оÑтрови ax +Ðланд Ороллари ax +阿兰群岛 ax +奧è˜ç¾¤å³¶ ax +Azerbaijan az +أذربيجان az +AzÉ™rbaycan az +ÐзÑрбайджан az +Ðзербайджан az +আজেরবাইজান az +Azerbeidjan az +Azerbejdžan az +Azerbaitjan az +Ãzerbajdžánský az +Aserbaijan az +Azerbajdjan az +Aserbaidschan az +ΑζεÏμπαϊτζάν az +AzerbajÄano az +Azerbaiján az +Aserbaidžaan az +آذربایجان az +Azerbaidäani az +Aserbadsjan az +Azerbeidjan az +An Asarbaiseáin az +×זרביג'ן az +अजरबैजान az +Azerbejdžan az +Azerbajdzsán az +AserbaÃdsjan az +Azerbaigian az +アゼルãƒã‚¤ã‚¸ãƒ£ãƒ³ az +អាហ្ស៊ែរបែហ្សង់ az +ì•„ì œë¥´ë°”ì´ìž” az +àºàº²à»€àºŠàºµà»„ບຈັນ az +Azerbaidžanas az +AzerbaidžÄna az +Ðзербејџан az +Ðзарбайжан az +AżerbajÄ¡an az +Aserbajdsjan az +Aserbaidschan az +Azerbeidjan az +Aserbajdsjan az +ਅਜ਼ਰਬਾਈਜਾਨ az +Azerbejdżan az +Azerbaijão az +Azerbaijão az +Ðзербайджан az +Azeribayijani az +Aserbaižan az +Ãzerbajdžánsky az +Azerbajdžan az +Ðзербејџан az +Azerbejdžan az +I-Azerbaijan az +அசரà¯à®ªà¯ˆà®šà®¾à®©à¯ az +Озарбойҷон az +à¸à¸²à¸£à¹Œà¹€à¸‹à¸à¸£à¹Œà¹„บจัน az +Azerice az +Äzärbaycan az +Ðзербайджан az +Озарбайжон az +Azerbaydjan az +阿塞拜疆 az +亞塞拜然 az +Bosnia and Herzegovina ba +Bosnië en Herzegovina ba +البوسنا Ùˆ الهرسك ba +БоÑÑŒÐ½Ñ–Ñ Ñ– Герцагавіна ba +БоÑна и Херцеговина ba +বসনিয়া à¦à¦¬à¦‚ হারজিগোà¦à¦¿à¦¨à¦¾ ba +Bosni hag Herzigovi ba +Bosna i Hercegovina ba +Bòsnia i Hercegovina ba +Bosna a Herzegovina ba +Bosnia a Hertsegofina 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 +Bosnië en Herzegovina ba +An Bhoisnia agus Heirseagóivéin ba +Bosnia e Herzegovina ba +×‘×•×¡× ×™×” ×”×¨×¦×’×•×‘×™× ×” ba +बोसà¥à¤¨à¤¿à¤¯à¤¾ और हरà¥à¤œà¥‡à¤—ोविना ba +Bosna i Hercegovina ba +Bosznia-Hercegovina ba +BosnÃa og HersegóvÃna ba +Bosnia e Erzegovina ba +ボスニアヘルツェゴビナ ba +បូស្ន៊ី និង​ហឺហ្ស៊áŸáž ្គោវីណា ba +보스니아어와 í—¤ë¥´ì²´ê³ ë¹„ë‚˜ ba +ບàºàºªà»€àº™àºµàº à»àº¥àº° ເຫີເຊີໂàºàº§àº´àº™àº² ba +Bosnija ir Hercegovina ba +Bosnija un Hercogovina ba +БоÑна и Херцеговина ba +БоÑни ба Херцеговина ba +Bożnia u Ħerżegovina ba +Bosnia-Hercegovina ba +Bosnien-Herzegowina ba +Bosnië en Herzegovina ba +Bosnia-Hercegovina ba +Bosnia le Herzegovina ba +ਬੋਸਨੀਆ ਤੇ ਹਰਜ਼ੀਗੋਵਿਨਾ ba +BoÅ›nia i Hercegowina ba +Bósnia e Herzegovina ba +Bósnia Herzegovina ba +Bosnia ÅŸi HerÅ£egovina ba +БоÑÐ½Ð¸Ñ Ð¸ Герцеговина ba +Bosiniya na Herizegovina ba +Bosnia ja Hercegovina ba +Bosna a Hercegovina ba +Bosna in Hercegovina ba +БоÑна и Херцеговина ba +Bosna i Hercegovina ba +I-Bosnia kanye ne Herzegovina ba +Bosnien och Herzegovina ba +பொசà¯à®©à®¿à®¯à®¾ மறà¯à®±à¯à®®à¯ ஹரà¯à®œà®¿à®•à¯‹à®µà®¿à®©à®¾ ba +БоÑÐ½Ð¸Ñ Ð²Ð° ГерÑогавина ba +บà¸à¸ªà¹€à¸™à¸µà¸¢à¹à¸¥à¸°à¹€à¸®à¸à¸£à¹Œà¹€à¸‹à¹‚à¸à¸§à¸´à¸™à¸² ba +Bosna Hersek ba +Bosnia wä Herzegovina ba +БоÑÐ½Ñ–Ñ Ñ– Герцеговина ba +БоÑÐ½Ð¸Ñ Ð²Ð° Герцоговина ba +Mubosinia na Muhezegovina ba +Bosnia và Herzegovina ba +Bosneye ba +Bosnia ne Herzegovina ba +波斯尼亚和黑塞哥维那 ba +波士尼亞與赫塞哥ç¶ç´ ba +Bosnia kanye ne-Herzegovina ba +Barbados bb +بربادوس bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +Ð‘Ð°Ñ€Ð±ÐµÐ¹Ð´Ð¾Ñ bb +বারবাডোস bb +ΜπαÏμπάντος bb +Barbado bb +باربادوس bb +Barbade bb +Barbadós bb +ברבדוס bb +बारबाडोस bb +ãƒãƒ«ãƒãƒ‰ã‚¹ bb +បារបាដូស bb +바르바ë„스 bb +ບາລບາດàºàº”ສ bb +Barbadosas bb +Barbadosa bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +Ð‘Ð°Ñ€Ð±Ð¾Ð´Ð°Ñ bb +ਬਾਰਬਾਡੋਸ bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +Barubadosi bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +I-Barbados bb +பாரà¯à®ªà¯‡à®Ÿà®¾à®šà¯ bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +บาร์บาดà¸à¸ª bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb +BÃ¥rbades bb +巴巴多斯 bb +å·´è²å¤š bb +Bangladesh bd +بنغلاديش bd +BanqladeÅŸ bd +БанглÑдÑш bd +Бангладеш bd +বাংলাদেশ bd +Bangladaech bd +BangladeÅ¡ bd +Bangladéš bd +Bangladesch bd +ΜπαγκλαντÎÏ‚ bd +BangladeÅo bd +بنگلادش bd +An Bhanglaidéis bd +×‘× ×’×œ×“×© bd +बांगà¥à¤²à¤¾à¤¦à¥‡à¤¶ bd +BangladeÅ¡ bd +Banglades bd +Bangladess bd +ãƒãƒ³ã‚°ãƒ©ãƒ‡ã‚·ãƒ¥ bd +បង់ក្លាដáŸážŸáŸ’áž bd +방글ë¼ë°ì‹œ bd +ບັງຄະລາເທດ bd +BangladeÅ¡as bd +BangladeÅ¡a bd +Бангладеш bd +Бангладеш bd +Bangladexx bd +Bangladesch bd +ਬੰਗਲਾਦੇਸ਼ bd +Bangladesz bd +BangladeÅŸ bd +Бангладеш bd +Bangaladeshi bd +Bangladéš bd +BangladeÅ¡ bd +Бангладеш bd +BangladeÅ¡ bd +I-Bangladesh bd +பஙà¯à®•à®³à®¾à®¤à¯‡à®šà¯ bd +Банглодеш bd +บังคลาเทศ bd +BangladeÅŸ bd +BangladeÅŸ bd +Бангладеш bd +Бангладеш bd +åŸåŠ 拉国 bd +åŸåŠ 拉 bd +Belgium be +België be +بلجيكا be +Belçika be +БÑÐ»ÑŒÐ³Ñ–Ñ be +Ð‘ÐµÐ»Ð³Ð¸Ñ be +বেলজিয়াম be +Belgia be +Belgija be +Bèlgica be +Belgie be +Gwlad Belg be +Belgien be +Belgien be +Î’Îλγιο be +Belgio be +Bélgica be +Belgia be +Belgika be +بلژیک be +Belgia be +Belgia be +Belgique be +België be +An Bheilg be +Bélxica be +בלגיה be +बेलà¥à¤œà¤¿à¤¯à¤® be +Belgija be +Belgia be +BelgÃa be +Belgio be +ベルギー be +បែលហ្ស៊ិក be +ë²¨ê¸°ì— be +ເບລຢ່ງມ be +Belgija be +Beļģija be +Белгија be +Белги be +BelÄ¡ju be +Belgia be +Belgien be +België be +Belgia be +Bèlgica be +ਬੈਲਜੀਅਮ be +Belgia be +Bélgica be +Bélgica be +Belgia be +Ð‘ÐµÐ»ÑŒÐ³Ð¸Ñ be +Ububiligi be +Belgia be +Belgicko be +Belgija be +Белгија be +Belgija be +I-Belgium be +Belgien be +பெலà¯à®šà®¿à®¯à®®à¯ be +Ð‘ÐµÐ»Ð³Ð¸Ñ be +เบลเยียม be +Belçika be +Belgia be +Ð‘ÐµÐ»ÑŒÐ³Ñ–Ñ be +Ð‘ÐµÐ»Ð³Ð¸Ñ be +Bỉ be +Beldjike be +比利时 be +比利時 be +Burkina Faso bf +بوركينا Ùاسو bf +Буркіна ФаÑо bf +Буркина ФаÑо bf +বারকিনা ফাসো bf +Bwrcina Ffaso bf +ΜπουÏκίνα Φάσο bf +Burkino bf +بورکیناÙاسو bf +BuircÃne Fasó bf +×‘×•×¨× ×™×§×” פ×סו bf +बà¥à¤°à¥à¤•à¤¿à¤¨à¤¾ फासो bf +Burkina faso bf +BúrkÃna Fasó bf +ブルã‚ナファソ bf +ប៊ូរគីណាហ្វាសូ bf +부르키나 파소 bf +ຕຸລະàºàºµ bf +Буркина ФаÑо bf +Буркина ФаÑо bf +ਬà©à¨°à¨•à¨¿à¨¨à¨¾ ਫਾਸੋ bf +Буркина-ФаÑо bf +Burukina Faso bf +Буркина ФаÑо bf +பரà¯à®•à®¿à®©à®¾ ஃபசோ bf +Буркина ФаÑу bf +เบà¸à¸£à¹Œà¸à¸´à¸™à¸²à¸Ÿà¸²à¹‚ซ bf +Буркіна-ФаÑо bf +Буркина-ФаÑÑо bf +Bourkina Fasso bf +布基纳法索 bf +布å‰ç´æ³•ç´¢ bf +Bulgaria bg +Bulgarye bg +بلغاريا bg +Bolgarıstan bg +Ð‘Ð°ÑžÐ³Ð°Ñ€Ñ‹Ñ bg +Ð‘ÑŠÐ»Ð³Ð°Ñ€Ð¸Ñ bg +বà§à¦²à¦—েরিয়া bg +Bulgari bg +Bugarska bg +Bulgà ria bg +Bulharsko bg +Bwlgaria bg +Bulgarien bg +Bulgarien bg +ΒουλγαÏία bg +Bulgario bg +Bulgaaria bg +بلغارستان bg +Bulgarie bg +Bulgarije bg +An Bhulgáir bg +Bulgária bg +בולגריה bg +बà¥à¤²à¥à¤—ारिया bg +Bugarska bg +Bulgária bg +BúlgarÃa bg +ブルガリア bg +ប៊ុលហ្ការី bg +불가리아 bg +ບັນà»àºà»€àº¥àºµàº bg +Bulgarija bg +BulgÄrija bg +Бугарија bg +Болгари bg +Bulgarija bg +Bulgarien bg +Bulgarije bg +ਬà©à¨²à¨—ਾਰੀਆ bg +BuÅ‚garia bg +Bulgária bg +Bulgária bg +Ð‘Ð¾Ð»Ð³Ð°Ñ€Ð¸Ñ bg +Buligariya bg +Bulgária bg +Bulharsko bg +Bolgarija bg +БугарÑка bg +Bugarska bg +I-Bulgaria bg +Bulgarien bg +பலà¯à®•à¯‡à®°à®¿à®¯à®¾ bg +БулғориÑтон bg +บัลà¹à¸à¹€à¸£à¸µà¸¢ bg +Bulgaristan bg +Ð‘Ð¾Ð»Ð³Ð°Ñ€Ñ–Ñ bg +Ð‘Ð¾Ð»Ð³Ð°Ñ€Ð¸Ñ bg +Baligaria bg +BulgÃ¥reye bg +ä¿åŠ 利亚 bg +ä¿åŠ 利亞 bg +Bahrain bh +البØرين bh +БахрÑйн bh +Бахрейн bh +বাহরেন bh +Barein bh +Bahrein bh +Bahrajn bh +ΜπαχÏÎιν bh +Barejno bh +Bahrein bh +Bahrein bh +بØرین bh +Baghrein bh +Bairéin bh +Barein bh +בחריין bh +बहारीन bh +Barein bh +ãƒãƒ¼ãƒ¬ãƒ¼ãƒ³ bh +បារ៉ែន bh +ë°”ë ˆì¸ bh +ຖັàºàºà»ˆàº‡àº§ bh +Bahreinas bh +Bahreina bh +Бахреин bh +Бахрайн bh +Baħrain bh +Baghrein bh +ਬਹਿਰੀਨ bh +Bahrajn bh +Bahrein bh +Бахрейн bh +Bahirayini bh +Bahrajn bh +Bahrajn bh +Бахреин bh +Bahrein bh +I-Bahrain bh +Bahrein bh +பஹà¯à®°à¯ˆà®©à¯ bh +Баҳрайн bh +บาห์เรียน bh +Bahreyn bh +Bahreyn bh +Бахрейн bh +Баҳрайн bh +Bareyn bh +å·´æž— bh +å·´æž— bh +Burundi bi +بوروندي bi +Бурундзі bi +Бурунди bi +বà§à¦°à§à¦¨à§à¦¡à¦¿ bi +Bwrwndi bi +ΜπουÏουντί bi +Burundo bi +بروندی bi +An Bhurúin bi +×‘×•×¨×•× ×“×™ bi +बà¥à¤°à¥‚ंडी bi +Búrúndà bi +ブルンジ bi +ប៊ូរុនឌី bi +부룬디 bi +ເຄàºàº£àº” bi +Burundija bi +Бурунди bi +Бурунди bi +ਬà©à¨°à©à¨¨à¨¡à©€ bi +Бурунди bi +Бурунди bi +பà¯à®°à¯à®©à¯à®Ÿà®¿ bi +Бурундӣ bi +บูรันดิ bi +Бурунді bi +Бурунди bi +Bouroundi bi +布隆迪 bi +浦隆地 bi +Benin bj +Denin bj +بينين bj +БÑнін bj +Бенин bj +বেনিন bj +Μπενίν bj +Benino bj +بنین bj +Bénin bj +Beinin bj +×‘× ×™×Ÿ bj +बेनिन bj +BenÃn bj +ベナン bj +áž”áŸážŽáž¶áŸ†áž„ bj +ë² ëƒ‰ bj +ບàºàºªà»€àº™àºµàº bj +Benina bj +Бенин bj +Бенин bj +ਬੀਨਿਨ bj +Benim bj +Бенин bj +Bene bj +Бенин bj +பெனின௠bj +Бенини bj +เบนิน bj +Бенін bj +Бенин bj +è´å® bj +è²å— bj +Bermuda bm +برمودا bm +БÑрмуды bm +Бермуда bm +বারà§à¦®à§à¦¡à¦¾ bm +Bermud bm +Bermudy bm +Bermwda bm +Bermudas bm +ΒεÏμοÏδες bm +Bermudoj bm +برمودا bm +Bermudes bm +Beirmiúda bm +ברמודה bm +बरमूडा bm +Bermúdaeyjar bm +è‹±é ˜ãƒãƒ¼ãƒŸãƒ¥ãƒ¼ãƒ€ bm +ប៊áŸážšáž˜áž¼ážŠáž¶ bm +버뮤다 bm +ເàºàº¥àº¥àº°àº¡àº±àº™ bm +Bermudų bm +Bermudas bm +Бермуди bm +Бермуда bm +ਬੀਰਮà©à¨¡à¨¾ bm +Bermudy bm +Bermude bm +БермудÑкие ОÑтрова bm +Berimuda bm +Bermudy bm +Bermudi bm +Бермуда bm +பெரà¯à®®à¯à®Ÿà®¾ bm +Бермудо bm +เบà¸à¸£à¹Œà¸¡à¸´à¸§à¸”า bm +Бермуди bm +Бермуда Ороллари bm +Bermudes bm +百慕大 bm +ç™¾æ…•é” bm +Brunei Darussalam bn +بروناي دار السلام bn +БрунÑй bn +Бруней bn +বà§à¦°à§à¦¨à§‡à¦‡ দারà¦à¦¸à¦¸à¦²à¦¾à¦® bn +Darussalam Brunei bn +Brunej bn +Brwnei Darwsalam bn +Brunei bn +ΜπÏουνÎι ÎταÏουσαλάμ bn +Brunejo bn +Brunei bn +برونویی بیت‌المقدس bn +Brunei bn +Brúiné bn +×‘×•×¨× ×™×™ ×“×¨×•×¡×œ× bn +बà¥à¤°à¥‚नेई दारेसà¥à¤¸à¤²à¤¾à¤® bn +Brunei Szultánság bn +Brúnei Darussalam bn +Brunei bn +ブルãƒã‚¤ bn +ប្រ៊ុយណ០bn +ë¸Œë£¨ë‚˜ì´ bn +ເບລາລັສເຊີຠbn +Bruneja Darusalama bn +Брунеи Дар ÐµÑ Ð¡Ð°Ð»Ð°Ð¼ bn +Бруней ДаруÑÑалам bn +Brunei bn +Brunei bn +Brunei bn +ਬਰੂਨੀ ਡਾਰੂਸਲਾਮ bn +Brunei Dar-es-Salam bn +Brunei bn +Бруней bn +Buruneyi Darusalamu bn +Brunei bn +Brunei Darusalam bn +Брунеј ДаруÑалам bn +Brunej Darusalam bn +பà¯à®°à¯‚னை டரà¯à®šà®²à®¾à®®à¯ bn +Брунеи Ð‘Ð°Ð¹Ñ‚ÑƒÐ»Ð¼ÑƒÒ›Ð°Ð´Ð´Ð°Ñ bn +บรูไนดูรัสซาลาม bn +Brunei bn +Бруней ДаруÑÑалам bn +Бруней ДоруÑÑалом bn +Bruney Darussalam bn +文莱达é²è¨å…° bn +æ–‡èŠé”é¯è–©è˜ bn +Bolivia bo +Bolivië bo +بوليÙيا bo +Boliviya bo +Ð‘Ð°Ð»Ñ–Ð²Ñ–Ñ bo +Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo +বলিà¦à¦¿à§Ÿà¦¾ bo +Bolivija bo +BolÃvia bo +BolÃvie bo +Bolifia bo +Bolivien bo +Βολιβία bo +Bolivio bo +Boliivia bo +بولیوی bo +Bolivie bo +An Bholaiv bo +BolÃvia bo +בוליביה bo +बोलिविया bo +Bolivija bo +BolÃvia bo +BólivÃa bo +ボリビア bo +បូលីវី bo +볼리비아 bo +ໂບລີເວີຠbo +Bolivija bo +BolÄ«vija bo +Боливија bo +Боливи bo +Bolivja bo +Bolivien bo +ਬੋਲਵੀਆ bo +Boliwia bo +BolÃvia bo +BolÃvia bo +Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo +Boliviya bo +BolÃvia bo +Bolivija bo +Боливија bo +Bolivija bo +I-Bolivia bo +பொலிவியா bo +Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo +โบลิเวีย bo +Bolivya bo +Ð‘Ð¾Ð»Ñ–Ð²Ñ–Ñ bo +Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo +Boliveye bo +玻利维亚 bo +玻利ç¶äºž bo +Brazil br +Brazilië br +البرازيل br +Braziliya br +Ð‘Ñ€Ð°Ð·Ñ‹Ð»Ñ–Ñ br +Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br +বà§à¦°à¦¾à¦œà¦¿à¦² br +Brasil br +BrazÃlie br +Brasil br +Brasilien br +Brasilien br +Î’Ïαζιλία br +Brazilo br +Brasil br +Brasiilia br +Brasil br +برزیل br +Brasilia br +Brésil br +Brazilië br +An BhrasaÃl br +Brasil br +ברזיל br +बà¥à¤°à¤¾à¤œà¥€à¤² br +BrazÃlia br +BrasilÃa br +Brasile br +ブラジル br +ប្រáŸáž ្ស៊ីល br +브ë¼ì§ˆ br +ບາຊີລ br +Brazilija br +BrazÄ«lija br +Бразил br +Бразил br +Brażil br +Brasil br +Brasilien br +Brazilië br +Brasil br +Brasil br +ਬਰਾਜ਼ੀਲ br +Brazylia br +Brasil br +Brasil br +Brazilia br +Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br +Burezile br +Brasil br +BrazÃlia br +Brazilija br +Бразил br +I-Brazil br +Brasilien br +பிரேசில௠br +Бразил br +บราซิล br +Brezilya br +Ð‘Ñ€Ð°Ð·Ð¸Ð»Ñ–Ñ br +Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br +Burazili br +Braezi br +巴西 br +巴西 br +Bahamas bs +جزر الباهاما bs +Багамы bs +БахамÑки оÑтрови bs +বাহামাস bs +Bahami bs +Bahames bs +Bahamy bs +Ynysoedd Bahama bs +Μπαχάμες bs +Bahamoj bs +Bahama bs +باهاماس bs +Bahaman saaret bs +Na Bahámaà bs +Baamas bs +בהמס bs +बहामा bs +Bahamák bs +Bahamaeyjar bs +ãƒãƒãƒž bs +បាហាម៉ា bs +바하마 bs +ປານາມາ bs +Bahamų bs +Бахами bs +Ð‘Ð°Ñ…Ð°Ð¼Ð°Ñ bs +Baħamas bs +ਬਾਹਾਮਾਸ bs +Bahamy bs +БагамÑкие оÑтрова bs +Bahamasi bs +Bahamy bs +Bahami bs +Бахами bs +Bahami bs +பனாமா bs +Ð‘Ð¾Ò³Ð¾Ð¼Ð¾Ñ bs +บาฮามา bs +Bahamalar bs +Багами bs +Багама Ороллари bs +巴哈马 bs +巴拿馬 bs +Bhutan bt +بوتان bt +Бутан bt +Бутан bt +à¦à§‚টান bt +Butañ bt +Butan bt +Bhútán bt +Bhwtan bt +Μπουτάν bt +Butano bt +Bhután bt +بوتان bt +Bhoutan bt +An Bhútáin bt +Bután bt +בהוטן bt +à¤à¥‚टान bt +Bhután bt +Bútan bt +ブータン bt +ប៊ូážáž¶áž“ bt +부탄 bt +ຖັàºàºà»ˆàº‡àº§ bt +Bhutano bt +ButÄna bt +Бутан bt +Бутан bt +Butan bt +à¨à©à¨Ÿà¨¾à¨¨ bt +Butão bt +Butão bt +Butan bt +Бутан bt +Butani bt +Butan bt +Бутан bt +Butan bt +பூடான௠bt +Бутон bt +ภูà¸à¸²à¸™ bt +Butan bt +Бутан bt +Бутан bt +Boutan bt +ä¸ä¸¹ bt +ä¸ä¸¹ bt +Botswana bw +بوتسوانا bw +БатÑвана bw +БотÑуана bw +বটসওয়ানা bw +Bocvana bw +Μποτσουάνα bw +Bocvano bw +بوتسووانا bw +An Bhotsuáin bw +Botsuana bw +בוצ××•× ×” bw +बोतà¥à¤¸à¤µà¤¾à¤¨à¤¾ bw +Botsvana bw +Botsvana bw +ボツワナ bw +បុážážŸáŸ’វាណា bw +ë³´ì¸ ì™€ë‚˜ bw +ບàºàº”ສເນີຠbw +Botsvanos bw +BotsvÄna bw +Боцвана bw +БотÑвана bw +ਬੋਟਸਵਾਨਾ bw +Botsuana bw +БотÑвана bw +Botsvana bw +Боцвана bw +Bocvana bw +பாடà¯à®¸à¯à®µà®©à®¾ bw +БотÑвана bw +บà¸à¸—สวานา bw +Botsvana bw +БотÑвана bw +Боцвана bw +Boswana bw +åšèŒ¨ç“¦çº³ bw +æ³¢æœé‚£ bw +Belarus by +روسيا البيضاء by +БеларуÑÑŒ by +Ð‘ÐµÐ»Ð°Ñ€ÑƒÑ by +বেলারà§à¦¸ by +Belarusi by +Bjelorusija by +Bielorússia by +BÄ›lorusko by +Belarws by +Hviderusland by +Weißrussland by +ΛευκοÏωσία by +Belorusio by +Valgevene by +بلاروس by +Valkovenäjä by +HvÃtarusland by +Bélarus by +Wyt-Rusland by +An Bhealarúis by +Bielorúsia by +בלרוס by +बेलारूस by +Bjelorusija by +Fehéroroszország by +HvÃta-Rússland by +Bielorussia by +ベラルーシ by +áž”áŸáž¡áž¶ážšáž»ážŸáŸ’ស by +벨ë¼ë£¨ìŠ¤ by +ເບລາລັສ by +Baltarusija by +Baltkrievija by +БелоруÑија by +Цагаан Ð¾Ñ€Ð¾Ñ by +Hviterussland by +Wittrussland by +Wit-Rusland by +Kviterussland by +ਬੇਲਾਰੂਸ by +BiaÅ‚oruÅ› by +Bielorrússia by +БеларуÑÑŒ by +Belarusi by +Vilges-RuoÅ¡Å¡a by +Bielorusko by +Belorusija by +БелоруÑија by +Belorusija by +I-Belarus by +Vitryssland by +பெலாரூச௠by +БелоруÑиё by +เบลารุส by +БілоруÑÑ–Ñ by +Ð‘ÐµÐ»Ð¾Ñ€ÑƒÑ by +Belaruss by +白俄罗斯 by +白俄羅斯 by +Belize bz +بيليز bz +БÑлізе bz +Белийз bz +বেলিজ bz +Beliz bz +Bel?s bz +Μπελίζε bz +Belizo bz +بلیز bz +An BheilÃs bz +בליז bz +बेलिज bz +BelÃs bz +ベリーズ bz +áž”áŸáž›áž¸áž ្ស bz +벨리즈 bz +ເບລàºà»ˆàº‡àº¡ bz +Belizo bz +Beliza bz +Белизе bz +Ð‘ÐµÐ»Ð¸Ð·Ñ bz +Beliż bz +ਬੀਲੀਜ਼ਿ bz +Белиз bz +Белиз bz +Beliz bz +பெலà¯à®šà®¿à®¯à®®à¯ bz +Белиз bz +เบลไลซ์ bz +Beliz bz +Беліз bz +Белиз bz +伯利兹 bz +比利時 bz +Default C +Standaard C +اÙتراضي C +Ön QurÄŸulu C +Па ўмаўчаньні C +По подразбиране C +ডিফলà§à¦Ÿ C +Dre ziouer C +Omissió C +Výchozà C +Rhagosodedig C +Standard C +Standard C +Î ÏοκαθοÏισμÎνο C +Apriora C +Predeterminado C +Vaikimisi C +Lehenetsia C +پیش‌Ùرض C +Oletus C +Forsettur C +Par défaut C +Standert C +Réamhshocrú C +Por Omisión C +ברירת מחדל C +डिफ़ॉलà¥à¤Ÿ C +UobiÄajeno C +Standard C +Alapértelmezett C +Standar C +Sjálfgefið C +Predefinito C +標準 C +លំនាំដើម C +기본 C +ຄ່າປະລິàºàº²àº C +Numatyta C +NoklusÄ“tais C +Почетно C +Стандарт C +Normali C +Standard C +Standard C +Standaard C +Standard C +Thuso ya Tshoganetso C +Omission C +ਮੂਲ C +DomyÅ›lnie C +Por Omissão C +Padrão C +Implicit C +По умолчанию C +Mburabuzi C +Standárda C +Å tandardný C +Privzeto C +Подразумевано C +Podrazumevano C +Förval C +à®®à¯à®©à¯à®©à®¿à®°à¯à®ªà¯à®ªà¯ C +Пешфарзӣ C +ค่าปริยาย C +Öntanımlı C +Ğädäti C +Типовий C +Ðндоза C +Mặc định C +Prémetou C +Okwendalo C +默认 C +é è¨ C +Okwendalo C +Canada ca +Kanada ca +كندا ca +Kanada ca +Канада 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 +Kanada ca +Ceanada ca +Canadá ca +×§× ×“×” ca +कनाडा ca +Kanada ca +Kanada ca +Kanada ca +Kanada ca +カナダ ca +កាណាដា ca +ìºë‚˜ë‹¤ ca +à»àº„ນາດາ ca +Kanada ca +KanÄda ca +Канада ca +Канад ca +Kanada ca +Kanada ca +ਕੈਨੇਡਾ ca +Kanada ca +Canadá ca +Canadá ca +Канада ca +Kanada ca +Kanada ca +Kanada ca +Канада ca +Kanada ca +I-Canada ca +Kanada ca +கனடா ca +Канада ca +à¹à¸„นาดา ca +Kanada ca +Kanada ca +Канада ca +Канада ca +åŠ æ‹¿å¤§ ca +åŠ æ‹¿å¤§ ca +Cocos (Keeling) Islands cc +Kokos Eilande cc +جزر كوكوس (كيلينغ) cc +КокоÑови оÑтрови cc +কোকোস (কীলিং) দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ cc +Inizi Koko (Keeling) cc +Kokosovo (Keeling) ostrvo cc +Illes Cocos (Keeling) cc +Kokosové ostrovy (Keeling) cc +Ynysoedd y Cocos (Keeling) cc +Cocos/Keeling-Inseln cc +Îήσοι Κόκος (Κήλινγκ) cc +Kokosinsuloj cc +Islas Cocos (Keeling) cc +Kookossaared cc +Cocos Irlak cc +جزایر کوکوس کیلینگ cc +Cookinsaaret cc +ÃŽles Cocos cc +Oileán na gCócónna (Keeling) cc +Illas Cocos (Keeling) cc +××™×™ קוקוס cc +कोकोस (कीलिंग) आइलैंडà¥à¤¸ cc +Cocos (Keeling) Otoci cc +Kókusz-szigetek (Keeling) cc +Kókoseyjar cc +Isole Cocos (Keeling) cc +ã‚ªãƒ¼ã‚¹ãƒˆãƒ©ãƒªã‚¢é ˜ã‚³ã‚³ã‚¹å³¶ cc +កោះ Cocos (Keeling) cc +코코스 ì œë„ cc +Kokosu salas cc +ОÑтрови ÐšÐ¾ÐºÐ¾Ñ (Килинг) cc +Cocos (Keeling) арлууд cc +Gżejjer Cocos (Keeling) cc +Kokosøyene cc +Cocos- (Keeling-) Inseln cc +Kokosøyane cc +ਕੋਕੋਸ(ਕਿਨਿੰਗ) ਟਾਪੂ cc +Wyspy Kokosowe (Keelinga) cc +Ilhas Cocos (Keeling) cc +Ilhas Cocos cc +Insulele Cocos (Keeling) cc +КокоÑовые (Килинг) оÑтрова cc +Ibirwa Kokosi cc +Kokosullut cc +Kokosove Ostrovy cc +Kokosovi (Keelingovi) otoki cc +КокоÑова (Килингова) оÑтрва cc +Kokosova (Kilingova) ostrva cc +Kokosöarna cc +கோகோஸ௠(கீலிஙà¯) தீவà¯à®•à®³à¯ cc +Ҷазираи ÐšÐ¾ÐºÐ¾Ñ (Килинг) cc +หมู่เà¸à¸²à¸°à¹‚คคà¸à¸ª (Keeling) cc +Keeling Adaları cc +Kokos (Keeling) Utrawları cc +КокоÑові оÑтрови cc +ÐšÐ¾ÐºÐ¾Ñ (Килинг) Ороллари cc +Iyes Cocos cc +科科斯群岛 cc +å¯å¯æ–¯ç¾¤å³¶ cc +Congo, The Democratic Republic of the cd +Kongo, Demokratiese republiek van die cd +ДÑÐ¼Ð°ÐºÑ€Ð°Ñ‚Ñ‹Ñ‡Ð½Ð°Ñ Ð ÑÑпубліка Конга cd +ДРКонго cd +কঙà§à¦—োর গণতানà§à¦¤à§à¦°à¦¿à¦• পà§à¦°à¦œà¦¾à¦¤à¦¨à§à¦¤à§à¦° cd +Kongo, Demokratska republika cd +Congo, República Democrà tica del cd +Kongo cd +Congo, Gweriniaeth Democrataidd y cd +Congo, den demokratiske republik cd +Kongo, Republik cd +Κονγκό, ΔημοκÏατία του cd +Kongo, la Demokratia Respubliko de la cd +Congo, República democrática del cd +Kongo (DV) cd +Kongoko Errepublika Demokratikoa cd +Kongon demokraattinen tasavalta cd +République Démocratique du Congo cd +Kongo, de democratische republyk van de cd +Poblacht Dhaonlathach an Chongó cd +Congo, República Democrática do cd +×§×•× ×’×•, הרפובליקה הדמוקרטית של cd +डेमोकà¥à¤°à¥‡à¤Ÿà¤¿à¤• रिपबà¥à¤²à¤¿à¤• ऑफ कॉगो cd +Kongói Demokratikus Köztársaság cd +Kongó, Austur cd +Congo, Repubblica Democratica del cd +コンゴ,民主共和国 cd +សាធារណរដ្ឋ​ប្រជាធិបážáŸáž™áŸ’យ​កុងហ្គោ cd +Kongo demokratinÄ— respublika cd +Kongo demokrÄtiskÄ republika cd +Конго, ДемократÑка Република на cd +Kongo (RD) cd +Kongo cd +Kongo (De demokraatsche Republiek) cd +Congo, Democratische republiek cd +Kongo cd +ਕਾਂਗੋ, ਲੋਕਤੰਤਰੀ ਗਣਰਾਜ cd +Republika Demokratyczna Kongo cd +Congo, República Democrática do cd +República Democrática do Congo cd +Congo, Republica Democrată cd +ДемократичеÑÐºÐ°Ñ Ð ÐµÑпублика Конго cd +Kongo, Repubulika Iharanira Demokarasi ya cd +Kongo cd +Demokratická Republika Kongo cd +Kongo, demokratiÄna republika cd +Конго, ДемократÑка Република cd +Kongo, Demokratska Republika cd +Demokratiska republiken Kongo cd +கானà¯à®•à¯‹, கà¯à®Ÿà®¿à®¯à®°à®šà¯ cd +Ҷумҳурии демократии Ҳонконг cd +สาธารณรัà¸à¸›à¸£à¸°à¸Šà¸²à¸˜à¸´à¸›à¹„ตยคà¸à¸‡à¹‚ภcd +Demokratik Kongo Cumhuriyeti cd +Kongo, Demokrat Cömhüriäte cd +Конго, демократична реÑпубліка cd +Конго Демократик РеÑпубликаÑи cd +Congo, republike democratike cd +刚果民主共和国 cd +剛果民主共和國 cd +Central African Republic cf +Sentrale Afrika Republiek cf +جمهورية Ø£Ùريقيا الوسطى cf +ЦÑнтральнаафрыканÑÐºÐ°Ñ Ð ÑÑпубліка cf +ЦÐÐ cf +মধà§à¦¯ আফà§à¦°à¦¿à¦•à¦¾à¦¨ রিপাবলিক cf +Republik centrafricaine cf +CentralnoafriÄka Republika cf +República Centro Africana cf +StÅ™edoafrická republika cf +Gweriniaeth Canolig Affrica cf +Central-afrikanske Republik cf +Zentralafrikanische Republik cf +ΔημοκÏατία ΚεντÏικής ΑφÏικής cf +Mezafrika Respubliko cf +República Centroafricana cf +Kesk-Aafrika Vabariik cf +Afrika Erdiko Errepublika cf +جمهوری اÙریقای مرکزی cf +Keski-Afrikan tasavalta cf +République centrafricaine cf +Sintraal Afrikaanse Republyk cf +Poblacht na hAfraice Láir cf +República Centro Africana cf +הרפובליקה ×”××¤×¨×™×§× ×™×ª ×”×ª×™×›×•× ×” cf +सेंटà¥à¤°à¤² अफà¥à¤°à¥€à¤•à¤¨ रिपबà¥à¤²à¤¿à¤• cf +Centralna AfriÄka Republika cf +Közép-Afrikai Köztársaság cf +Mið-AfrÃkulýðveldið cf +Repubblica Centrafricana cf +ä¸å¤®ã‚¢ãƒ•ãƒªã‚«å…±å’Œå›½ cf +សាធារណរដ្ឋ​អាហ្វ្រិក​កណ្ដាល cf +중앙 아프리카 ê³µí™”êµ cf +ໂດມິນິàºàº±àº™ cf +CentrinÄ—s Afrikos Respublika cf +CentrÄlÄfrikas republika cf +ЦентралноафриканÑка Република cf +Төв африкын ард ÑƒÐ»Ñ cf +Repubblika ÄŠentrali Afrikana cf +Den sentralafrikanske republikk cf +Zentraalafrikaansche Republiek cf +Centraal Afrikaanse Republiek cf +Den sentralafrikanske republikken cf +ਕੇਂਦਰੀ ਅਫਰੀਕੀ ਗਣਰਾਜ cf +Republika Åšrodkowej Afryki cf +República Central Africana cf +República da Ãfrica Central cf +Republica Centrafricană cf +Центрально-ÐфриканÑÐºÐ°Ñ Ð ÐµÑпублика cf +Repubulika ya Santara Afurika cf +GuovddášafrihkálaÅ¡ republihkka cf +Stredoafrická Republika cf +CentralnoafriÅ¡ka republika cf +Централноафричка Република cf +CentralnoafriÄka Republika cf +Centralafrikanska Republiken cf +மைய ஆபà¯à®ªà®¿à®°à®¿à®•à¯à®• கà¯à®Ÿà®¿à®¯à®°à®šà¯ cf +Ҷумҳурии Ðфриқои Марказӣ cf +สาธารณรัà¸à¸à¸±à¸Ÿà¸£à¸´à¸à¸²à¸à¸¥à¸²à¸‡ cf +Orta Afrika Cumhuriyeti cf +Ãœzäk Afrika Cömhüriäte cf +Центральна африканÑька реÑпубліка cf +Марказий Ðфрика РеÑпубликаÑи cf +Cá»™ng hoà Trung Phi cf +Cintrafrike cf +ä¸éžå…±å’Œå›½ cf +å¤šæ˜Žå°¼åŠ å…±å’Œåœ‹ cf +Congo cg +Konsole cg +الكونغو cg +Конга cg +Конго cg +কঙà§à¦—ো cg +Kongo cg +Kongo cg +Kongo cg +Kongo cg +Κονγκό cg +Kongo (Brazavila) cg +Kongo cg +Kongo cg +Ú©Ù†Ú¯Ùˆ cg +Kongo cg +Kongo cg +Congó cg +×§×•× ×’×• cg +कोंगो cg +Kongo cg +Kongó cg +Kongó, Vestur cg +コンゴ cg +កុងហ្គោ cg +ì½©ê³ cg +ຄàºàº™à»‚à»àºŠàº¥ cg +Kongo cg +Kongo cg +Конго cg +Конго cg +Kongo cg +Kongo-Brazaville cg +Kongo cg +Kongo-Brazaville cg +ਕਾਂਗੋ cg +Kongo cg +Конго cg +Kongo cg +Kongo cg +Kongo cg +Kongo cg +Конго cg +Kongo cg +Kongo cg +கானà¯à®•à¯‹ cg +Конго cg +คà¸à¸‡à¹‚ภcg +Kongo cg +Kongo cg +Конго cg +Конго cg +刚果 cg +剛果 cg +Switzerland ch +Switserland ch +سويسرا ch +Ä°sveçrÉ™ ch +ШвÑÐ¹Ñ†Ð°Ñ€Ñ‹Ñ ch +Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch +সà§à¦‡à¦œà¦¾à¦°à¦²à§à¦¯à¦¾à¦£à§à¦¡ ch +Suis ch +Å vicarska ch +Suïssa ch +Å výcarsko ch +Y Swistir ch +Schweiz ch +Schweiz ch +Ελβετία ch +Svislando ch +Suiza ch +Å veits ch +Suitza ch +سوییس ch +Sveitsi ch +Suisse ch +Switserlân ch +An Eilvéis ch +SuÃza ch +שוייץ ch +सà¥à¤µà¤¿à¤Ÿà¥à¤œà¤°à¤²à¥ˆà¤‚ड ch +Å vicarska ch +Svájc ch +Swiss ch +Sviss ch +Svizzera ch +スイス ch +ស្វ៊ីស ch +스위스 ch +ສະວິສເຊີà»àº¥àº™ ch +Å veicarija ch +Å veice ch +Швајцарија ch +Швецарь ch +Svizzera ch +Sveits ch +Swiez ch +Zwitserland ch +Sveits ch +Suissa ch +ਸਵਿਟਜ਼ਰਲੈਂਡ ch +Szwajcaria ch +SuÃça ch +SuÃça ch +ElveÅ£ia ch +Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch +Swazilande ch +Å veica ch +Å vajÄiarsko ch +Å vica ch +ШвајцарÑка ch +Å vajcarska ch +I-Switzerland ch +Schweiz ch +சà¯à®µà®¿à®Ÿà¯à®šà®°à¯à®²à®¾à®¨à¯à®¤à¯ ch +Свитзерланд ch +สวิสเซà¸à¸£à¹Œà¹à¸¥à¸™à¸”์ ch +Ä°sviçre ch +Ä°swiçrä ch +Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ñ–Ñ ch +Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch +Thuỵ SÄ© ch +Swisse ch +瑞士 ch +瑞士 ch +Cote d'ivoire ci +ساØÙ„ العاج ci +Бераг Слановай КоÑьці ci +Кот Дивоар ci +Aod an Olifant ci +Obala SlonovaÄe ci +Costa d'ivori ci +PobÅ™ežà slonoviny ci +Y Traeth Ifori ci +Elfenbenskysten ci +Ακτή Î•Î»ÎµÏ†Î±Î½Ï„Î¿ÏƒÏ„Î¿Ï ci +Eburio ci +Costa de Marfil ci +Cote d'Ivoire ci +Boli kosta ci +Ú©Ùت٠دیوÙیر ci +Côte d'Ivoire ci +Ivoorkust ci +An Cósta Eabhair ci +कोट डि'वॉरे ci +Baci kocke ci +Elefántcsontpart ci +FÃlabeinsströndin ci +Costa d'Avorio ci +コートジボアール ci +កូដឌីវáŸážš ci +코트디부아르 ci +ປ່àºàºàº«àº¡àº²àºàºàº°àº¥àºàº ci +KotdivuÄra ci +Брегот на Слоновата КоÑка ci +Kosta tal-Avorju ci +Elfenbenskysten ci +Elfenbeenküst ci +Ivoorkust ci +Elfenbeinskysten ci +ਕਾਂਟੋ ਡੀਵੋਇਰੀ ci +Wybrzeże KoÅ›ci SÅ‚oniowej ci +Costa do Marfim ci +Coasta de Azur ci +Кот Д'Ивуар ci +Kote divuware ci +ElfenÄalánriddu ci +SlonokoÅ¡Äena obala ci +Обала Ñлоноваче ci +Obala slonovaÄe ci +Elfenbenskusten ci +Соҳили Оҷ ci +à¸à¹ˆà¸²à¸§à¹„à¸à¸§à¸à¸£à¸µ ci +Кот Д'Івуар ci +Кот д'Ивуар ci +Bá» biển ngà ci +Coisse d' Ivwere ci +科特迪瓦 ci +象牙海岸 ci +Cook islands ck +Cook Eilande ck +جزر كوك ck +ÐÑтравы Кука ck +ОÑтрови Кук ck +কà§à¦• দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ ck +Inizi Kook ck +Kukova ostrva ck +Illes Cook ck +Cookovy ostrovy ck +Ynysoedd Cook ck +Cook-øerne ck +Cook-Inseln ck +Îησιά Κουκ ck +Kukinsuloj ck +Islas Cook ck +Cooki saared ck +Cook Irlak ck +جزایر Ú©ÙˆÚ© ck +Cooksaaret ck +ÃŽles Cook ck +Oileáin Chook ck +Illas Cook ck +××™×™ קוק ck +कà¥à¤• आइलैंड ck +Cook otoci ck +Cook-szigetek ck +Cooks-eyjar ck +Isole Cook ck +ãƒ‹ãƒ¥ãƒ¼ã‚¸ãƒ¼ãƒ©ãƒ³ãƒ‰è‡ªæ²»é ˜ã‚¯ãƒƒã‚¯è«¸å³¶ ck +កោះ Cook ck +ì¿¡ ì œë„ ck +ຄຸàºàºàºµà»‰ ck +Kuko salų ck +Kuka salas ck +Кукови оÑтрови ck +Cook арлууд ck +Gżejjer Cook ck +Cookøyene ck +Cookinseln ck +Cook Eilanden ck +Cookøyane ck +ਕà©à©±à¨• ਟਾਪੂ ck +Wyspy Cooka ck +Ilhas Cook ck +Ilhas Cook ck +Insulele Cook ck +ОÑтрова Кука ck +Ibirwa bya Kuke ck +Cooksullut ck +Cookove ostrovy ck +Cookovi otoki ck +Кукова оÑтрва ck +Kukova ostrva ck +Cooköarna ck +கà¯à®•à¯ தீவ௠ck +Ҷазираи Кук ck +หมู่เà¸à¸²à¸°à¸„ุภck +Cook Adaları ck +Kok Utrawları ck +ОÑтрови Кука ck +Кук Ороллари ck +Iyes Cook ck +库克群岛 ck +庫克群島 ck +Chile cl +Chilië cl +تشيلي cl +Åžili cl +Чылі cl +Чили cl +চিলি cl +ÄŒile cl +Xile cl +Tsile cl +Χιλή cl +Ĉilio cl +TÅ¡iili cl +Txile cl +شیلی cl +Chili cl +Chili cl +An tSile cl +צ'ילה cl +चिली cl +ÄŒile cl +Chili cl +Cile cl +ãƒãƒª cl +ឈីលី cl +ì¹ ë ˆ cl +ຊີລີ cl +ÄŒilÄ— cl +Čīle cl +Чиле cl +Чили cl +ÄŠile cl +Chili cl +ਚਿੱਲੀ cl +Cile cl +Чили cl +Shili cl +ÄŒile cl +ÄŒile cl +Чиле cl +ÄŒile cl +I-Chile cl +சிலி cl +Чилли cl +ชิลี cl +Åžili cl +Çili cl +Чилі cl +Чили cl +Chi lê cl +Tchili cl +智利 cl +智利 cl +Cameroon cm +Kameroon cm +الكاميرون cm +КамÑрун cm +Камерун cm +কà§à¦¯à¦¾à¦®à§‡à¦°à§à¦¨ cm +Kameroun cm +Kamerun cm +Camerun cm +Kamerun cm +Y Camer?n cm +Cameroun cm +Kamerun cm +ΚαμεÏοÏν cm +Kameruno cm +Camerún cm +Kamerun cm +Kamerun cm +کامرون cm +Kamerun cm +Cameroun cm +Kameroen cm +Camarún cm +Camerún cm +קמרון cm +कैमरून cm +Kamerun cm +Kamerun cm +Kamerún cm +Camerun cm +カメルーン cm +កាមáŸážšáž¼áž“ cm +카메룬 cm +ຕາລາງງານ - K cm +KamerÅ«no cm +KamerÅ«na cm +Камерун cm +Камерун cm +Kamerun cm +Kamerun cm +Kamerun cm +Cameroen cm +Kamerun cm +ਕੈਮਰੂਨ cm +Kamerun cm +Camarões cm +Camarões cm +Camerun cm +Камерун cm +Kameruni cm +Kamerun cm +Komerun cm +Kamerun cm +Камерун cm +Kamerun cm +Kamerun cm +கமீரூன௠cm +Камерун cm +คาเมรูน cm +Kamerun cm +Kameroon cm +Камерун cm +Камерун cm +Camrone cm +喀麦隆 cm +喀麥隆 cm +China cn +الصين cn +Çin cn +Кітай cn +Китай cn +চীন cn +Sina cn +Kina cn +Xina cn +ÄŒÃna cn +Tseina cn +Kina cn +Κίνα cn +Ĉinujo cn +Hiina cn +Txina cn +چین cn +Kiina cn +Kina cn +Chine cn +An tSÃn cn +סין cn +चीन cn +Kina cn +KÃna cn +Cina cn +KÃna cn +Cina cn +ä¸å›½ cn +áž…áž·áž“ cn +ì¤‘êµ cn +ຈີນ cn +Kinija cn +Ķīna cn +Кина cn +Ð¥Ñтад cn +ÄŠina cn +Kina cn +Kina cn +Xina cn +ਚੀਨ cn +Chiny cn +Китай cn +Ubushinwa cn +Kiinná cn +ÄŒÃna cn +Kitajska cn +Кина cn +Kina cn +I-China cn +Kina cn +சீனா cn +Хитой cn +จีน cn +Çin cn +Çin cn +Китай cn +Хитой cn +Trung Quốc cn +Chine cn +ä¸å›½ cn +ä¸åœ‹ cn +Colombia co +Colombië co +كولمبيا co +ÐšÐ°Ð»ÑŽÐ¼Ð±Ñ–Ñ co +ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co +কলোমà§à¦¬à¦¿à§Ÿà¦¾ co +Kolumbi co +Kolumbija co +Colòmbia co +Kolumbie co +Kolumbien co +Κολομβία co +Kolumbio co +Kolumbia co +Kolonbia co +کلمبیا co +Kolumbia co +Colombie co +Columbia co +An Cholóim co +Colómbia co +קולומביה co +कोलमà¥à¤¬à¤¿à¤¯à¤¾ co +Kolumbija co +Kolumbia co +KólumbÃa co +コãƒãƒ³ãƒ“ã‚¢ co +កូឡុំប៊ី co +콜롬비아 co +ໂຄລຳເບີຠco +Kolumbija co +Kolumbija co +Колумбија co +Колумб co +Kolumbja co +Kolumbien co +Columbia co +ਕੋਲੰਬੀਆ co +Kolumbia co +Colômbia co +Colômbia co +Columbia co +ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co +Kolombiya co +Kolombia co +Kolumbia co +Kolumbija co +Колумбија co +Kolumbija co +I-Colombia co +கொலமà¯à®ªà®¿à®¯à®¾ co +ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co +โคลัมเบีย co +Kolombiya co +Kolombia co +ÐšÐ¾Ð»ÑƒÐ¼Ð±Ñ–Ñ co +ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co +Colombeye co +Columbia co +哥伦比亚 co +哥倫比亞 co +Costa Rica cr +كوستاريكا cr +КоÑта Рыка cr +КоÑта Рика cr +কোসà§à¦Ÿà¦¾ রিকা cr +Kosta Rika cr +Kostarika cr +Kostarika cr +Κόστα Ρίκα cr +Kostariko cr +کاستاریکا cr +Kosta Rika cr +Cósta RÃce cr +קוסטה ריקה cr +कोसà¥à¤Ÿà¤¾ रिका cr +Kosta rika cr +KostarÃka cr +コスタリカ cr +កូស្ážáž¶ážšáž¸áž€áž¶ cr +코스타 리카 cr +ໂຄເàºà»€àº—ີຠcr +Kosta Rika cr +Kostarika cr +КоÑта Рика cr +КоÑта Рика cr +ਕੋਸਟਾ ਰੀਕਾ cr +Kostaryka cr +КоÑта-Рика cr +Kosita Rika cr +Kostarika cr +Kostarika cr +КоÑтарика cr +Kostarika cr +I-Costa Rica cr +கோஸà¯à®Ÿà®¾ ரிகா cr +КоÑта Рика cr +คà¸à¸ªà¸•à¸²à¸£à¸´à¸à¸² cr +Kosta Rika cr +Kosta Rika cr +КоÑта-Ріка cr +КоÑта Рика cr +å“¥æ–¯è¾¾é»ŽåŠ cr +å“¥æ–¯å¤§é»ŽåŠ cr +Cuba cu +Kuba cu +كوبا cu +Куба cu +Куба cu +কিউবা cu +Kuba cu +Kuba cu +Kuba cu +Ciwba cu +Kuba cu +ΚοÏβα cu +Kubo cu +Kuuba cu +Kuba cu +کوبا cu +Kuuba cu +Kuba cu +Cúba cu +קובה cu +कà¥à¤¯à¥‚बा cu +Kuba cu +Kuba cu +Kúba cu +ã‚ュームcu +គុយបា cu +ì¿ ë°” cu +ເàºàº¡à»„ພ່ cu +Kuba cu +Kuba cu +Куба cu +Куба cu +Kuba cu +Kuba cu +ਕਿਊਬਾ cu +Kuba cu +Куба cu +Kuba cu +Kuba cu +Kuba cu +Куба cu +Kuba cu +I-Cuba cu +Kuba cu +கியà¯à®ªà®¾ cu +Куба cu +คิวบา cu +Küba cu +Kuba cu +Куба cu +Куба cu +å¤å·´ cu +å¤å·´ cu +Cape Verde cv +Kaap Verde cv +كاب Ùيردي cv +Кабо Верде cv +কেপ à¦à¦¾à¦°à¦¡à¦¿ cv +Penn Verde cv +Zelenortska ostrva cv +Cap Verd cv +Kapverdy cv +Cape Ferde cv +Kapverdiske øer cv +Cap Verdische Inseln cv +Î Ïάσινο ΑκÏωτήÏιο cv +Kapo-Verdo cv +Cabo Verde cv +Roheneeme saared cv +Cabo Verde cv +کیپ‌ورده cv +Kap Verde cv +Cap vert cv +Kaap Verdië cv +Rinn Verde cv +Cabo Verde cv +×›×£ וורדה cv +कैप वरà¥à¤¡à¥‡ cv +Zöldfoki-szigetek cv +Grænhöfðaeyjar cv +Capo Verde cv +カーãƒãƒ™ãƒ«ãƒ‡ cv +កាបវែរ cv +ì¹´ë³´ë² ë¥´ë° cv +ເàºàº¡à»„ພ່ cv +Kabaverde cv +Кејп Верде cv +Капе Ð’ÑÑ€Ð´Ñ cv +Kapp Verde cv +Kap Verde cv +Kaap Verdië cv +Kapp Verde cv +ਕੇਪ ਵੀਰਡੀ cv +Cabo Verde cv +Cabo Verde cv +Capul Verde cv +Кабо-Верде cv +Kapu Veri cv +Кејп Верд cv +Kejp Verd cv +Kap Verde cv +கேப௠வெரà¯à®Ÿà¯ cv +Димоғи Верде cv +à¹à¸«à¸¥à¸¡à¹€à¸§à¸à¸£à¹Œà¸”ี cv +Kape Verde cv +Кабо-Верде cv +Кейп Верде cv +Cap Vert cv +佛得角 cv +ç¶å¾·è§’ cv +Christmas Island cx +Kersfees Eiland cx +جزر الكريسماس cx +ОÑтров РождеÑтво cx +কà§à¦°à¦¿à¦¸à§à¦Ÿà¦®à¦¾à¦¸ দà§à¦¬à§€à¦ª cx +Inizi Nedeleg cx +BožiÄno ostrvo cx +Illa de Pascua cx +VánoÄnà ostrovy cx +Ynys y Nadolig cx +Juleøen cx +Weihnachtsinsel cx +Îήσος των ΧÏιστουγÎννων cx +Kristnaskinsulo cx +Islas Christmas cx +Jõulusaar cx +Eguberri Irla cx +جزایر کریسمس cx +Joulusaari cx +ÃŽle de Noël cx +Christmas Eilân cx +Oileán na Nollag cx +Illas Christmas cx +××™×™ כריסטמס cx +कà¥à¤°à¤¿à¤¸à¤®à¤¸ आइलैंड cx +UskrÅ¡nji otoci cx +Karácsony-szigetek cx +Jólaey cx +Isola Christmas cx +クリスマス諸島 cx +កោះ Christmas cx +í¬ë¦¬ìŠ¤ë§ˆìŠ¤ 섬 cx +ຄິດສະຕàºàº¥ cx +KalÄ—dų salos cx +ZiemassvÄ“tku salas cx +ВелигденÑки ОÑтрови cx +КриÑÑ‚Ð¼Ð°Ñ Ð°Ñ€Ð»ÑƒÑƒÐ´ cx +Christmasøya cx +Wiehnachtsinsel cx +Christmasøya cx +ਕà©à¨°à¨¿à¨¸à¨®à¨¿à¨¸ ਟਾਪੂ cx +Wyspy Bożego Narodzenia cx +Ilhas Natal cx +Ilhas do Natal cx +Insulele Christmas cx +ОÑтров РождеÑтва cx +Ikirwa cya Noheli cx +Christmassuollu cx +VianoÄné Ostrovy cx +BožiÄni otok cx +Божићно оÑтрво cx +Božićno ostrvo cx +Julön cx +கிரà¯à®¸à¯à®¤à¯à®®à®¸à¯ தீவ௠cx +Ҷазираи КриÑÑ‚Ð¼Ð°Ñ cx +เà¸à¸²à¸°à¸„ริสต์มาส cx +Yılbaşı Adaları cx +Christmas Utrawları cx +ОÑтрів Різдва cx +КриÑÐ¼Ð°Ñ ÐžÑ€Ð¾Ð»Ð¸ cx +Äảo giáng sinh cx +圣诞岛 cx +è–誕島 cx +Cyprus cy +Siprus cy +قبرص cy +Кіпр cy +Кипър cy +সাইপà§à¦°à¦¾à¦¸ cy +Chipr cy +Kipar cy +Xipre cy +Kypr cy +Cypern cy +Zypern cy +ΚÏÏ€Ïος cy +Cipro cy +Chipre cy +Küpros cy +Txipre cy +قبرس cy +Kypros cy +Chypre cy +An Chipir cy +Chipre cy +קפריסין cy +साइपà¥à¤°à¤¸ cy +Cipar cy +Ciprus cy +Kýpur cy +Cipro cy +ã‚プãƒã‚¹ cy +ស៊ីពរ០cy +키프로스 cy +ບີບàºàº±àº” cy +Kipro cy +Kipra cy +Кипар cy +Ð¡Ð¸Ð¿Ñ€ÑƒÑ cy +ÄŠipru cy +Kypros cy +Zypern cy +Kypros cy +ਕਿਉਪਰਸ cy +Cypr cy +Chipre cy +Chipre cy +Cipru cy +Кипр cy +Shipure cy +Kypros cy +Ciper cy +Кипар cy +Kipar cy +Cypern cy +சிபà¯à®°à®¸à¯ cy +Кипр cy +ไซปรัส cy +Kıbrıs cy +Kiper cy +Кіпр cy +Кипр cy +SÃp cy +Chîpe cy +塞浦路斯 cy +賽普勒斯 cy +Czechia cz +Czechië cz +التشيك cz +Çex Respublikası cz +ЧÑÑ…Ñ–Ñ cz +Чешка република cz +চেকিয়া cz +Tchekia cz +ÄŒeÅ¡ka cz +Txèquia cz +ÄŒesko cz +Y Weriniaeth Siec 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 +Tsjechië cz +Poblacht na Seice cz +Chéquia cz +צ'×›×™×” cz +चेक cz +ÄŒeÅ¡ka cz +Csehország cz +Tékkland cz +Repubblica Ceca cz +ãƒã‚§ã‚³ cz +ឆáŸáž€ cz +ì²´ì½” cz +ÄŒekija cz +ÄŒehija cz +Чешка cz +Чехиа cz +Cżekia cz +Tsjekkia cz +Tschechien cz +Tsjechië cz +Tsjekkia cz +Chèquia cz +ਚੈੱਚੀਆ cz +Czechy cz +República Checa cz +República Tcheca cz +Cehia cz +Ð§ÐµÑ…Ð¸Ñ cz +Ceke cz +ÄŒeahkka cz +ÄŒesko cz +ÄŒeÅ¡ka cz +Чешка cz +ÄŒeÅ¡ka cz +I-Czechia cz +Tjeckien cz +செகà¯à®¯à®¾ cz +Ð§ÐµÑ…Ð¸Ñ cz +เชค cz +Çek Cumhuriyeti cz +Çexiä cz +Ð§ÐµÑ…Ñ–Ñ cz +Ð§ÐµÑ…Ð¸Ñ cz +Séc cz +Tchekeye cz +æ·å…‹ cz +æ·å…‹ cz +Germany de +Duitsland de +ألمانيا de +Almaniya de +ÐÑмеччына de +Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de +জারà§à¦®à¦¾à¦¨à¦¿ de +Alamagn de +NjemaÄka de +Alemanya de +NÄ›mecko de +Yr Almaen de +Tyskland de +Deutschland de +ΓεÏμανία de +Germanio de +Alemania de +Saksamaa de +Alemania de +آلمان de +Saksa de +Týskland de +Allemagne de +Dûtslân de +An Ghearmáin de +Alemaña de +×’×¨×ž× ×™×” de +जरà¥à¤®à¤¨à¥€ de +NjemaÄka de +Németország de +Jerman de +Þýskaland de +Germania de +ドイツ de +អាល្លឺម៉ង់ de +ë…ì¼ de +ເàºàº¥àº¥àº°àº¡àº±àº™àº™àºµ de +Vokietija de +VÄcija de +Германија de +Герман de +Jerman de +Ä ermanja de +Tyskland de +Düütschland de +Duitsland de +Tyskland de +Alemanya de +ਜਰਮਨੀ de +Niemcy de +Alemanha de +Alemanha de +Germania de +Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de +Ubudage de +Duiska de +Nemecko de +NemÄija de +Ðемачка de +NemaÄka de +I-Germany de +Tyskland de +ஜெரà¯à®®à®©à®¿ de +Олмон de +เยà¸à¸£à¸¡à¸±à¸™à¸™à¸µ de +Almanya de +Almania de +Ðімеччина de +ÐžÐ»Ð¼Ð¾Ð½Ð¸Ñ de +Äức de +Almagne de +德国 de +德國 de +IJalimani de +Djibouti dj +جيبوتي dj +Джыбуці dj +Джибути dj +জিবৌতি dj +Äibuti dj +Džibuti dj +Jib?ti dj +Dschibuti dj +Τζιμπουτί dj +Äœibutio dj +جیبوتی dj +Xibuti dj +×’'יבוטי dj +डिबौती dj +Džibuti dj +Dzsibuti dj +DjÃbútà dj +Gibuti dj +ジブムdj +ហ្ស៊ីបូទី dj +지부티 dj +ພັດພາ dj +Džibutis dj +Džibutija dj +Ðибути dj +Жибут dj +DÄ¡ibuti dj +Dschibouti dj +ਡਜੀਬà©à¨‰à¨Ÿà©€ dj +Dżibuti dj +Djibuti dj +Djibuti dj +Джибути dj +Jibuti dj +Djibuhti dj +Džibuty dj +Džibuti dj +Ðибути dj +Džibuti dj +I-Djibouti dj +டிஜிபொடி dj +Ҷибойти dj +จิบูติ dj +Cibuti dj +Djibuti dj +Джібуті dj +Жибути dj +å‰å¸ƒæ dj +å‰å¸ƒåœ° dj +Denmark dk +Denemarke dk +الدنمارك dk +Danimarka dk +Ð”Ð°Ð½Ñ–Ñ dk +Ð”Ð°Ð½Ð¸Ñ dk +ডেনমারà§à¦• dk +Danmark dk +Danska dk +Dinamarca dk +Dánsko dk +Denmarc dk +Danmark dk +Dänemark dk +Δανία dk +Danlando dk +Dinamarca dk +Taani dk +Danimarka dk +دانمارک dk +Tanska dk +Danmark dk +Danemark dk +Denemarken dk +An Danmhairg dk +Dinamarca dk +×“× ×ž×¨×§ dk +डेनमारà¥à¤• dk +Danska dk +Dánia dk +Danmörk dk +Danimarca dk +デンマーク dk +ដាណឺម៉ាក dk +ë´ë§ˆí¬ dk +ເດນມາຠdk +Danija dk +DÄnija dk +ДанÑка dk +Дани dk +Danimarka dk +Danmark dk +Dänmark dk +Denemarken dk +Danmark dk +Dinamarca dk +ਡੈੱਨਮਾਰਕ dk +Dania dk +Dinamarca dk +Dinamarca dk +Danemarca dk +Ð”Ð°Ð½Ð¸Ñ dk +Danimarike dk +Dánmárku dk +Dánsko dk +Danska dk +ДанÑка dk +Danska dk +I-Denmark dk +Danmark dk +டெனà¯à®®à®¾à®°à¯à®•à¯ dk +Денмарк dk +เดนมาร์ภdk +Danimarka dk +Dania dk +Ð”Ð°Ð½Ñ–Ñ dk +Ð”Ð°Ð½Ð¸Ñ dk +Äan Mạch dk +DaenmÃ¥tche dk +丹麦 dk +丹麥 dk +Dominica dm +Dominisië dm +دومينيكا dm +Дамініка dm +Доминика dm +ডমিনিকা dm +Dominik dm +Dominika dm +Dominika dm +Dominikanische Republik dm +Îτομίνικα dm +Dominiko dm +دومینیکا dm +Dominique dm +Doiminice dm +×“×•×ž×™× ×§×” dm +डोमिनिका dm +Dominika dm +DóminÃka dm +ドミニカ dm +ដូមីនីកា dm +ë„미니카 dm +ໂລມາເນີຠdm +Dominika dm +Dominika dm +Доминика dm +Доминика dm +Dominika dm +ਡੋਮਾਨੀਕਾ dm +Dominika dm +Dominicana dm +Доминика dm +Dominikani dm +Dominikánsko dm +Dominikanska republika dm +Доминика dm +Dominika dm +டொமினிகா dm +Доминика dm +โดมินาà¸à¸±à¸™ dm +Dominik dm +Dominika dm +Домініка dm +Доминика dm +Dominike dm +å¤šç±³å°¼åŠ dm +å¤šæ˜Žå°¼åŠ dm +Dominican Republic do +Dominikaanse Republiek do +جمهورية الدومينيكان do +Dominik Respublikası do +ДамініканÑÐºÐ°Ñ Ð ÑÑпубліка do +ДоминиканÑка република do +ডমিনিকান রিপাবলিক do +Republik Dominikan do +Dominikanska Republika do +República Dominicana do +Dominikánská republika do +Gweriniaeth Dominica 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 +Dominicaanse Republyk do +An Phoblacht Dhoiminiceach do +República Dominicana do +הרפובליקה ×”×“×•×ž×™× ×™×§× ×™×ª 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 +ໂດມິນີàºàº±àº™ do +Dominikos Respublika do +Dominikas Republika do +ДоминиканÑка Република do +Домникан ард ÑƒÐ»Ñ do +Repubblika Dominikana do +Den dominikanske republikk do +Dominikaansche Republiek do +Dominicaanse Republiek do +Den dominikanske republikken do +Republica Dominicana do +ਡੋਮਾਨੀਕਾ ਗਣਰਾਜ do +Dominikana do +República Dominicana do +República Dominicana do +Republica Dominicană do +ДоминиканÑÐºÐ°Ñ Ñ€ÐµÑпублика do +Repubulika Dominikani do +DominihkalaÅ¡ republihkka do +Dominikánska republika do +Dominikanska republika do +ДоминиканÑка Република do +Dominikanska Republika do +I-Dominican Republic do +Dominikanska republiken do +டொமினிகà¯à®•à®©à¯ கà¯à®Ÿà®¿à®¯à®°à®šà¯ do +Ҷумҳурии Доминика do +สาธารณรัà¸à¹‚ดมินิà¸à¸±à¸™ do +Dominik Cumhuriyeti do +Dominika Cömhüriäte do +ДомініканÑька реÑпубліка 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 +অà§à¦¯à¦¾à¦²à¦œà§‡à¦°à¦¿à§Ÿà¦¾ dz +Aljeri 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 +Algerije dz +An Ailgéir dz +Alxéria dz +×לג'יריה dz +अलà¥à¤œà¥€à¤°à¤¿à¤¯à¤¾ dz +Alžir dz +Algéria dz +AlsÃr dz +アルジェリア dz +អាល់ហ្សáŸážšáž¸ dz +ì•Œì œë¦¬ dz +ບັນàºàº²à»€àº¥àºµàº dz +Alžyras dz +Alžīrija dz +Ðлжир dz +Ðлжер dz +AlÄ¡erija dz +Algerie dz +Algerien dz +Algerije dz +Algerie dz +ਅਲਜੀਰੀਆ dz +Algieria dz +Argélia dz +Argélia dz +Ðлжир dz +Aligeriya dz +AlžÃrsko dz +Alžirija dz +Ðлжир dz +Alžir dz +I-Algeria dz +Algeriet dz +அலà¯à®œà®¿à®°à®¿à®¯à®¾ dz +Ðлҷазоир dz +à¸à¸±à¸¥à¸ˆà¸µà¹€à¸£à¸µà¸¢ dz +Aljır dz +Ðлжир dz +Жазоир dz +Aldjereye dz +阿尔åŠåˆ©äºš dz +阿爾åŠåˆ©äºž dz +Equador ec +Ewenaar ec +الإكوادور ec +Ekvator ec +Ðквадор ec +Еквадор ec +ইকà§à§Ÿà§‡à¦¡à¦° ec +Ecuador ec +Ekvador ec +Ekvádor ec +Ecwador ec +Ecuador ec +ΙσημεÏινός ec +Ekvadoro ec +Ecuador ec +Ekuador ec +اکوادور ec +Équateur ec +Eacuadór ec +Ecuador ec +×קוודור ec +इकà¥à¤µà¥‡à¤¡à¥‰à¤° ec +Ekvador ec +Ecuador ec +Ekvador ec +Ecuador ec +エクアドル ec +អáŸáž€áŸ’វាឌáŸážš ec +ì—ì½°ë„르 ec +ເàºàºà»àº”à» ec +Ekvadoras ec +Ekvadora ec +Еквадор ec +Ðквадор ec +Ekwador ec +Ecuador ec +Ecuador ec +Ecuador ec +à¨à¨•à¨¾à¨µà©‡à¨¡à¨° ec +Ekwador ec +Ecuador ec +Ðквадор ec +Ekwateri ec +Ekvador ec +Ekvádor ec +Ekvador ec +Еквадор ec +Ekvador ec +I-Equador ec +ஈகà¯à®µà¯†à®Ÿà®¾à®°à¯ ec +Ðквадор ec +เà¸à¸à¸§à¸²à¸”à¸à¸£à¹Œ ec +Ekvator ec +Еквадор ec +Ðквадор ec +EcwÃ¥teur ec +厄瓜多尔 ec +厄瓜多 ec +Estonia ee +Estlandies ee +استونيا ee +Estoniya ee +ÐÑÑ‚Ð¾Ð½Ñ–Ñ ee +ЕÑÑ‚Ð¾Ð½Ð¸Ñ ee +à¦à¦¸à§à¦Ÿà§‹à¦¨à¦¿à§Ÿà¦¾ ee +Estonija ee +Estònia ee +Estonsko ee +Estland ee +Estland ee +Εσθονία ee +Estlando ee +Eesti ee +استونی ee +Eesti ee +Estonie ee +Estland ee +An Eastóin ee +××¡×˜×•× ×™×” ee +à¤à¤¸à¥à¤¤à¥‹à¤¨à¤¿à¤¯à¤¾ ee +Estonija ee +Észtország ee +Eistland ee +エストニア ee +អáŸážŸáŸ’ážáž¼áž“ី ee +ì—ìŠ¤í† ë‹ˆì•„ ee +ເàºà»‚ທເນີຠee +Estija ee +Igaunija ee +ЕÑтонија ee +ÐÑтони ee +Estonja ee +Estland ee +Estland ee +Estland ee +Estland ee +Estònia ee +ਈਸਟੋਨੀਆ ee +Estónia ee +Estônia ee +ÐÑÑ‚Ð¾Ð½Ð¸Ñ ee +Esitoniya ee +Estteeana ee +Estónsko ee +Estonija ee +ЕÑтонија ee +Estonija ee +I-Estonia ee +Estland ee +எசà¯à®Ÿà¯‹à®©à®¿à®¯à®¾ ee +ÐÑÑ‚Ð¾Ð½Ð¸Ñ ee +เà¸à¸ªà¹‚ทเนีย ee +Estonya ee +ЕÑÑ‚Ð¾Ð½Ñ–Ñ ee +ÐÑÑ‚Ð¾Ð½Ð¸Ñ ee +Estoneye ee +爱沙尼亚 ee +愛沙尼亞 ee +Egypt eg +Egipte eg +مصر eg +Misir eg +ÐгіпÑÑ‚ eg +Египет eg +মিশর eg +Ejipt eg +Egipat eg +Egipte eg +Yr Aifft eg +Egypten eg +Ägypten eg +Αίγυπτος eg +Egiptujo eg +Egipto eg +Egiptus eg +Egipto eg +مصر eg +Egypti eg +Egyptaland eg +Égypte eg +Egypte eg +An Éigipt eg +Exipto eg +×ž×¦×¨×™× eg +इजिपà¥à¤¤ eg +Egipat eg +Egyiptom eg +Egyptaland eg +Egitto eg +エジプト eg +អáŸáž ្ស៊ីប eg +ì´ì§‘트 eg +àºàºµàº¢àºµàºš eg +Egiptas eg +Ä’Ä£ipte eg +Египет eg +Египт eg +Mesir eg +EÄ¡ittu eg +Ägypten eg +Egypte eg +Egepeta eg +ਮਿਸਰ eg +Egipt eg +Egipto eg +Egito eg +Egipt eg +Египет eg +Misiri eg +Egypta eg +Egipt eg +Египат eg +Egipat eg +I-Egypt eg +Egypten eg +எகிபà¯à®¤à¯ eg +МиÑÑ€ eg +à¸à¸µà¸¢à¸´à¸›à¸•à¹Œ eg +Mısır eg +Mısır eg +Єгипет eg +МиÑÑ€ eg +Ai Cáºp eg +Edjipe eg +åŸƒåŠ eg +åŸƒåŠ eg +Igibhithe eg +Western Sahara eh +Westelike Sahara eh +الصØراء الغربية eh +ЗаходнÑÑ Ð¡Ð°Ñ…Ð°Ñ€Ð° eh +Западна Сахара eh +পশà§à¦šà¦¿à¦® সাহারা eh +Sahara occidental eh +Zapadna Sahara eh +Sà hara Occidental eh +Západnà Sahara eh +Gorllewin Sahara eh +Vestsahara eh +Westsahara eh +Δυτική ΣαχάÏα eh +Okcidenta Saharo eh +Sahara occidental eh +Lääne-Sahara eh +Mendebaldeko Sahara eh +صØرای غربی eh +Länsi-Sahara eh +Sahara occidental eh +West Sahara eh +An Sahára Thiar eh +Saara Ocidental eh +מערב סהרה eh +पशà¥à¤šà¤¿à¤®à¥€ सहारा eh +Westerm Sahara eh +Nyugat-Szahara eh +Vestur-Sahara eh +Sahara Occidentale eh +西サãƒãƒ© eh +សាហារ៉ា​ážáž¶áž„​លិច eh +ì„œì‚¬í•˜ë¼ eh +ພື້ນທີ່ທຳງານ eh +Vakarų Sahara eh +RietumsahÄra eh +Западна Сахара eh +Барууг Ñахар eh +Saħara tal-Punent eh +Vest-Sahara eh +Westsahara eh +West Sahara eh +Vest-Sahara eh +ਦੱਖਣੀ ਸਹਾਰਾ eh +Zachodnia Sahara eh +Sara Ocidental eh +Sahara Ocidental eh +Sahara de Vest eh +Ð—Ð°Ð¿Ð°Ð´Ð½Ð°Ñ Ð¡Ð°Ñ…Ð°Ñ€Ð° eh +Sahara y'Iburengerazuba eh +Oarje-Sahara eh +Západna Sahara eh +Zahodna Sahara eh +Западна Сахара eh +Zapadna Sahara eh +Västsahara eh +மேறà¯à®•à®¤à¯à®¤à®¿à®¯ சஹாரா eh +Саҳрои Ғарбӣ eh +ซาฮาร่าตะวันตภeh +Batı Sahara eh +Batış Sahara eh +Західна Сахара eh +Ғарбий Сахара eh +Tây Sahara eh +Sara Coûtchantrece eh +西撒哈拉 eh +西盛哈拉 eh +Eritrea er +اريتريا er +ÐрытрÑÑ er +Ð•Ñ€Ð¸Ñ‚Ñ€ÐµÑ er +à¦à¦°à¦¿à¦Ÿà§à¦°à¦¿à§Ÿà¦¾ er +Eritre er +Eritreja er +ΕÏυθÏαία er +Eritreo er +اریتره er +Érythrée er +Eiritré er +×ריתרי××” er +à¤à¤°à¤¿à¤Ÿà¥à¤°à¥€à¤¯à¤¾ er +Eritreja er +ErÃtrea er +エリトリア er +អáŸážšáž¸áž‘្រា er +ì—ë¦¬íŠ¸ë ˆì•„ er +à»àºà»‰à»„ຂà»àºŸà»‰àº¡àº—ຳງານ er +EritrÄ—ja er +Eritreja er +Еритреја er +Ðритреа er +ਈਰੀਟਰੀਆ er +Erytrea er +Eritreia er +Eritréia er +ÐÑ€Ð¸Ñ‚Ñ€ÐµÑ er +Eritereya er +Eritreja er +Еритреја er +Eritreja er +ரிடà¯à®°à®¿à®¯à®¾ er +ÐÑ€Ð¸Ñ‚Ñ€Ð¸Ñ er +เà¸à¸£à¸´à¹€à¸—รีย er +Eritre er +Ð•Ñ€Ñ–Ñ‚Ñ€ÐµÑ er +ÐÑ€Ð¸Ñ‚Ñ€Ð¸Ñ er +Eritrêye er +厄立特里亚 er +厄利垂亞 er +Spain es +Spanje es +أسبانيا es +Ä°spaniya es +Ð“Ñ–ÑˆÐ¿Ð°Ð½Ñ–Ñ es +ИÑÐ¿Ð°Ð½Ð¸Ñ es +সà§à¦ªà§‡à¦¨ es +Spagn es +Å panija es +Espanya es +Å panÄ›lsko es +Sbaen es +Spanien es +Spanien es +Ισπανία es +Hispanio es +España es +Hispaania es +Espainia es +اسپانیا es +Espanja es +Spania es +Espagne es +Spanje es +An Spáinn es +España es +ספרד es +सà¥à¤ªà¥‡à¤¨ es +Å panjolska es +Spanyolország es +Spanyol es +Spánn es +Spagna es +スペイン es +អáŸážŸáŸ’ប៉ាញ es +ìŠ¤íŽ˜ì¸ es +ສະເປັນ es +Ispanija es +SpÄnija es +Шпанија es +ИÑпани es +Sepanyol es +Spanja es +Spania es +Spanien es +Spanje es +Spania es +Espanha es +ਸਪੇਨ es +Hiszpania es +Espanha es +Espanha es +Spania es +ИÑÐ¿Ð°Ð½Ð¸Ñ es +Esipanye es +Spánia es +Å panielsko es +Å panija es +Шпанија es +Å panija es +I-Spain es +Spanien es +சà¯à®ªà¯†à®¯à®¿à®©à¯ es +ИÑпаниё es +สเปน es +Ä°spanya es +Ä°spania es +ІÑÐ¿Ð°Ð½Ñ–Ñ es +ИÑÐ¿Ð°Ð½Ð¸Ñ es +Tây Ban Nha es +Sipagne es +西ç牙 es +西ç牙 es +Ethiopia et +Ethiopië et +اثيوبيا et +ÐÑ‚Ñ‹Ñ‘Ð¿Ñ–Ñ et +Ð•Ñ‚Ð¸Ð¾Ð¿Ð¸Ñ et +ইথিওপিয়া et +Etiopi et +Etiopija et +Etiòpia et +Etiopie et +Ethiopien et +Äthiopien et +Αιθιοπία et +Etiopio et +EtiopÃa et +Etioopia et +Etiopia et +اتیوپی et +Etiopia et +Éthiopie et +Ethiopië et +An Aetóip et +Etiopia et +×תיופיה et +इथियोपिया et +Etiopija et +Etiópia et +EþÃópÃa et +Etiopia et +エãƒã‚ªãƒ”ã‚¢ et +អáŸážáŸ’យូពី et +ì—티오피아 et +ເàºà»‚ທເນີຠet +Etiopija et +Etiopija et +Етиопија et +Ðтопи et +Etjopia et +Etiopia et +Äthiopien et +Ethiopië et +Etiopia et +ਈਥੋਪੀਆ et +Etiopia et +Etiópia et +Etiópia et +Etiopia et +ÐÑ„Ð¸Ð¾Ð¿Ð¸Ñ et +Etiyopiya et +Etiopia et +Etiópia et +Etiopija et +Етиопија et +Etiopija et +Etiopien et +எதியோபியா et +ҲабашиÑтон et +เà¸à¸˜à¸´à¹‚à¸à¹€à¸›à¸µà¸¢ et +Etiyopya et +Efiopia et +Ð•Ñ„Ñ–Ð¾Ð¿Ñ–Ñ et +ÐÑ„Ð¸Ð¾Ð¿Ð¸Ñ et +Etiopeye et +埃塞俄比亚 et +衣索比亞 et +Finland fi +Ùنلندا fi +Finlandiya fi +ФінлÑÐ½Ð´Ñ‹Ñ fi +Ð¤Ð¸Ð½Ð»Ð°Ð½Ð´Ð¸Ñ fi +ফিনলà§à¦¯à¦¾à¦£à§à¦¡ fi +Finska fi +Finlà ndia fi +Finsko fi +Y Ffindir fi +Finnland fi +Φινλανδία fi +Finnlando fi +Finlandia fi +Soome fi +Finlandia fi +Ùنلاند fi +Suomi fi +Finnland fi +Finlande fi +Finlân fi +An Fhionlainn fi +Finlándia fi +×¤×™× ×œ× ×“ fi +फिनलैंड fi +Finska fi +Finnország fi +Finlandia fi +Finnland fi +Finlandia fi +フィンランド fi +ហ្វាំងឡង់ fi +핀란드 fi +ຟີນà»àº¥àº™ fi +Suomija fi +Somija fi +ФинÑка fi +Финнланд fi +Finlandja fi +Finnland fi +Finlandia fi +ਫਿਨਲੈਂਡ fi +Finlandia fi +Finlândia fi +Finlândia fi +Finlanda fi +ФинлÑÐ½Ð´Ð¸Ñ fi +Finilande fi +Suopma fi +FÃnsko fi +Finska fi +ФинÑка fi +Finska fi +I-Finland fi +பினà¯à®²à®¾à®¨à¯à®¤à¯ fi +Финлонд fi +ฟินà¹à¸¥à¸™à¸”์ fi +Finlandiya fi +Finland (Suomi) fi +ФінлÑÐ½Ð´Ñ–Ñ fi +ФинлÑÐ½Ð´Ð¸Ñ fi +Phần Lan fi +Finlande fi +芬兰 fi +èŠ¬è˜ fi +Fiji fj +Ùيجي fj +Фіджы fj +ОÑтрови Фиджи fj +ফিজি fj +Fidji fj +Fidži fj +Fidži fj +Ffiji fj +Fidschi fj +Φίτζι fj +FiÄioj fj +Fidži fj +Ùیجی fj +Fidji fj +Fidsà fj +פיג'×™ fj +फिजी fj +Fidzsi fj +FÃdjieyjar fj +Figi fj +フィジー fj +ហ្វ៊ីហ្ស៊ី fj +피지 fj +ມີດີ fj +Fidži fj +Фиџи fj +Фижи fj +FiÄ¡i fj +Fidschi fj +ਫਿੱਜੀ fj +Fidżi fj +Ilhas Fiji fj +Фиджи fj +Fidži fj +Fidži fj +Фиџи fj +Fidži fj +பிஜி fj +Фиҷи fj +ฟิจิ fj +Фіджі fj +Фижи fj +Fidji fj +æ–济 fj +è²æ¿Ÿ fj +Falkland Islands (Malvinas) fk +Falkland Eilande (Malvinas) fk +جزر الÙوكلاند (المالÙيناس) fk +ФалклендÑÐºÑ–Ñ Ð°Ñтравы (Мальвіны) fk +ФолклендÑки оÑтрови fk +ফকলà§à¦¯à¦¾à¦£à§à¦¡ দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ (মলà¦à¦¿à¦¨à¦¾à¦¸) fk +Inizi Falklandi (Malvinas) fk +Foklandska ostrva (Malvini) fk +Illes Falkland (Malvines) fk +Falklandy (MalvÃny) fk +Ynysoedd Y Ffalcland (Malfinas) fk +Falkland-øerne fk +Falkland-Inseln (Malvinen) fk +Îησιά Φώκλαντ (Malvinas) fk +Falklandoj fk +Islas Falkland (Malvinas) fk +Falklandi saared (Malviinid) fk +Falkland Irlak (Malvinak) fk +جزایر Ùالکلند مالویناس fk +Falklandin saaret (Malvinassaaret) fk +ÃŽles Falkland (Malvinas) fk +Falkland Eilannen (Malvinas) fk +Na hOileáin Fháclainne (Malvinas) fk +Illas Falkland (Malvinas) fk +××™×™ ×¤×•×œ×§×œ× ×“ fk +फाकलैंड आइलैंड (मालविनास) fk +Folklandska otoÄja (Malvini) fk +Falkland-szigetek fk +Falklandseyjar fk +Isole Falkland (Malvine) fk +フォークランド諸島 fk +កោះ Falkland (Malvinas) fk +í¬í´ëžœë“œ êµ°ë„ (ë§ë¹„나스) fk +Folklendu salas fk +ФокландÑки ОÑтрови (Малвини) fk +Фалкланд арлууд (МалвинаÑ) fk +Gżejjer Falkland (Malvinas) fk +Falklandsøyene fk +Falklandinseln (Malvinas) fk +Falkland Eilanden (Malvinas) fk +Falklandsøyane fk +ਫਾਕਲੈਂਡ ਟਾਪੂ fk +Wyspy Falklandzkie (Malwiny) fk +Ilhas Falkland (Malvinas) fk +Ilhas Malvinas fk +Insulele Falkland (Malvine) fk +ФолклендÑкие (МальвинÑкие) оÑтрова fk +Ibirwa bya Falikilande (Maluvinasi) fk +Falklánddasullot fk +Falklandské Ostrovy (Malviny) fk +Falklandski otoki (Malvini) fk +ФолкландÑка оÑтрва (Малвини) fk +Folklandska ostrva (Malvini) fk +Falklandsöarna fk +ஃபாலà¯à®•à¯ தீவà¯(மாலà¯à®µà®¿à®©à®¾à®¸à¯) fk +Ҷазираи фолкланд (Малвина) fk +หมู่เà¸à¸²à¸°à¸Ÿà¸à¸¥à¹Œà¸„à¹à¸¥à¸™à¸”์ (Malvinas) fk +Falkland Adaları fk +Falkland Utrawları (Malvinnar) fk +ФолклендÑькі оÑтрови (БританіÑ) fk +Фолкленд (Малвин) Ороллари fk +Iyes Malouwines fk +ç¦å…‹å…°ç¾¤å²›(马尔维纳斯) fk +ç¦å…‹è˜ç¾¤å³¶ (馬爾ç¶ç´æ–¯) fk +Micronesia, Federated States of fm +Micronesië, Vereenigde State van fm +ФедÑÑ€Ð°Ñ†Ñ‹Ñ ÐœiкранÑзіі fm +ÐœÐ¸ÐºÑ€Ð¾Ð½ÐµÐ·Ð¸Ñ fm +মাইকà§à¦°à§‹à¦¨à§‡à¦¶à¦¿à§Ÿà¦¾, ফেডারেটেড সà§à¦Ÿà§‡à¦Ÿà¦¸ অব fm +Mikronezija, Federalne države fm +Micronesia, Estats Federats de fm +Mikronésie fm +Micronesia, Taleithau Cyfunol fm +Mikronesien, de forenede stater af fm +Mikronesien, Föderation von fm +ΜικÏονησίας, Ομόσπονδες πολιτείες της fm +Mikronezio, Respubliko de fm +Micronesia, Estados federados de fm +Mikroneesia fm +Mikronesiako Estatu Federatuak fm +Mikronesian liittovaltio fm +Etats Fédérés de Micronésie fm +Micronesië, Federale staten Fan fm +Stáit Cónascacha na Micrinéise fm +Micronésia, Estados Federados de fm +×ž×™×§×¨×•× ×–×™×”, ×ž×“×™× ×•×ª הפדרציה של fm +फेडरेटेड सà¥à¤Ÿà¥‡à¤Ÿ ऑफ माइकà¥à¤°à¥‹à¤¨à¥‡à¤¸à¤¿à¤¯à¤¾ fm +Mikronézia fm +MÃkrónesÃa, SambandsrÃki fm +Micronesia, stati federati di fm +ミクãƒãƒã‚·ã‚¢,米自由連邦 fm +រដ្ឋ​សហពáŸáž“្ធ​មិក្រូនáŸážŸáŸŠáž¸ fm +Mikronezija fm +MikronÄ“zija fm +Микронезија, Федеративни Држави на fm +Mikronesja (Stati Federati ta') fm +Mikronesiaføderasjonen fm +Mikronesien, Vereenigte Staten vun fm +Micronesië, Federale staten van fm +Mikronesiaføderasjonen fm +ਮਾਇਕਰੋਨੀਸੀਆ, ਸੰਘੀ ਪà©à¨°à¨¾à¨‚ਤ fm +Federacja Stanów Mikronezji fm +Micronésia, Estados Federados da fm +Estados Federados da Micronésia fm +Micronezia, Statele Federative fm +ÐœÐ¸ÐºÑ€Ð¾Ð½ÐµÐ·Ð¸Ñ fm +Mikoronesiya, Leta Zishyizwehamwe fm +MikronesiafederaÅ¡uvdna fm +Spojené Å¡táty Mikronézie fm +Mikronezija, Združene države fm +Микронезија, Федерација држава fm +Mikronezija, Federacija država fm +Mikronesiska federationen fm +மைகà¯à®°à¯‹à®©à®¿à®šà®¾, à®’à®°à¯à®™à¯à®•à®¿à®£à¯ˆà®¨à¯à®¤ மாநிலம௠fm +สหพันธรัà¸à¸¡à¸´à¹‚ครนีเซีย fm +Mikronezya Federasyonu fm +Mikronesia, Berläşkän Ä°lläre fm +МікронезіÑ, федеративні штати fm +ÐœÐ¸ÐºÑ€Ð¾Ð½ÐµÐ·Ð¸Ñ fm +Micronezeye fm +密克罗尼西亚è”邦 fm +密克羅尼西亞è¯é‚¦ fm +Faroe Islands fo +Faroe Eilande fo +جزر الÙيرو fo +ОÑтрови Фаро fo +ফারো দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ fo +Enez Faroe fo +Farska ostrva fo +Illes Faroe fo +Faerské ostrovy fo +Ynysoedd Ffar?e fo +Færøerne fo +Färöer-Inseln fo +Îήσοι ΦεÏόε fo +Ferooj fo +islas Faroe fo +Fääri saared fo +Faroe Irlak fo +جزایر Ùارو fo +Färsaaret fo +ÃŽles Féroé fo +Faroe Eilannen fo +Na Scigirà (Oileáin Fharó) fo +Illas Feroe fo +××™×™ פ×רו fo +फारोठआइलैंड fo +Faroe Otoci fo +Faroe-szigetek fo +Færeyjar fo +Isole Fær Øer fo +フェãƒãƒ¼è«¸å³¶ fo +កោះ​ហ្វ៉ារ៉ូ fo +페로 ì œë„ fo +ໄàºà»àº¥àº™ fo +Faroe salos fo +FÄ“ru salas fo +ФарÑки ОÑтрови fo +Фарое арлууд fo +Gżejjer Faroe fo +Færøyene fo +Färöerinseln fo +Faroe Eilanden fo +Færøyane fo +ਫਾਰੋਈ ਟਾਪੂ fo +Wyspy Faroe fo +Ilhas Faroe fo +Ilhas Faroe fo +Insulele Feroe fo +ФарерÑкие оÑтрова fo +Ibirwa bya Farowe fo +Fearsuolu fo +Ostrovy Faroe fo +Otoki Faroe fo +ФарÑка оÑтрва fo +Farska ostrva fo +Färöarna fo +ஃபரோ தீவà¯à®•à®³à¯ fo +Ҷазираи Фару fo +หมู่เà¸à¸²à¸°à¸Ÿà¸²à¹‚ร fo +Faroe Adaları fo +Faroe Utrawları fo +ФарерÑькі оÑтрови fo +Фарер Ороллари fo +Äảo Faroe fo +Iye Faeroyé fo +法罗群岛 fo +法羅群島 fo +France fr +Frankryk fr +Ùرنسا fr +Fransa fr +Ð¤Ñ€Ð°Ð½Ñ†Ñ‹Ñ fr +Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr +ফà§à¦°à¦¾à¦¨à§à¦¸ fr +Frañs fr +Francuska fr +França fr +Francie fr +Ffrainc fr +Frankrig fr +Frankreich fr +Γαλλία fr +Francio fr +Francia fr +Prantsusmaa fr +Frantzia fr +Ùرانسه fr +Ranska fr +Frakland fr +Frankryk fr +An Fhrainc fr +Franza fr +צרפת fr +फà¥à¤°à¤¾à¤‚स fr +Francuska fr +Franciaország fr +Prancis fr +Frakkland fr +Francia fr +フランス fr +បារាំង fr +프랑스 fr +àºàº£àº±à»ˆàº‡ fr +PrancÅ«zija fr +Francija fr +Франција fr +Франц fr +Perancis fr +Franza fr +Frankrike fr +Frankriek fr +Frankrijk fr +Frankrike fr +Fora fr +França fr +ਫਰਾਂਸ fr +Francja fr +França fr +França fr +FranÅ£a fr +Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr +Ubufaransa fr +Fránkriika fr +Francúzsko fr +Francija fr +ФранцуÑка fr +Francuska fr +I-France fr +Frankrike fr +பிரானà¯à®šà¯ fr +ФаронÑа fr +à¸à¸£à¸±à¹ˆà¸‡à¹€à¸¨à¸ª fr +Fransa fr +Fransia fr +Ð¤Ñ€Ð°Ð½Ñ†Ñ–Ñ fr +Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr +Fura fr +Pháp fr +Fransi fr +法国 fr +法國 fr +Gabon ga +الغابون ga +Габон ga +Габон ga +গà§à¦¯à¦¾à¦¬à¦¨ ga +Gabun ga +Γκαμπόν ga +Gabono ga +Gabón ga +گابون ga +An Ghabúin ga +Gabón ga +גבון ga +गेबॉन ga +ガボン ga +ហ្គាបុង ga +가봉 ga +à»àºàº¥à»ˆàº‡àº™ ga +Gabonas ga +Gabona ga +Габон ga +Габон ga +Gabun ga +ਗਾਬੋਨ ga +Gabão ga +Gabão ga +Габон ga +Gabo ga +Габон ga +காபான௠ga +Габон ga +à¸à¸²à¸šà¸à¸™ ga +Габон ga +Габон ga +åŠ è“¬ ga +åŠ å½ ga +United Kingdom gb +Vereenigde Koninkryk gb +المملكة المتØدة gb +BirləşmiÅŸ Krallıq gb +Злучанае КаралеўÑтва gb +Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb +ইউনাইটেড কিংডম gb +Rouantelezh Unanet gb +Velika Britanija gb +Regne Unit gb +Spojené královstvà gb +Y Deyrnas Unedig gb +Storbritannien gb +Großbritannien gb +ΗνωμÎνο Βασίλειο gb +Britio gb +Reino Unido gb +Suurbritannia gb +Erresuma Batua gb +بریتانیا gb +Iso-Britannia gb +Stórabretland gb +Royaume Uni gb +Ferienigd Keninkryk gb +An RÃocht Aontaithe gb +Reino Unido gb +×‘×¨×™×˜× ×™×” gb +यूनाइटेड किंगडम gb +Ujedinjeno Kraljevstvo gb +Egyesült Királyság gb +Inggris gb +Bretland gb +Regno Unito gb +イギリス gb +ចក្រភព​អង់គ្លáŸážŸ gb +ì˜êµ gb +ສະຫະລາດສະàºàº²àº™àº²àºˆàº±àº gb +JungtinÄ— KaralystÄ— gb +ApvienotÄ Karaliste gb +Обединето КралÑтво gb +Их британ gb +Renju Unit gb +Storbritannia gb +Grootbritannien gb +Verenigd Koninkrijk gb +Storbritannia gb +Regne Unit gb +ਬਰਤਾਨੀਆ gb +Wielka Brytania gb +Reino Unido gb +Reino Unido gb +Anglia gb +Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb +Ubwongereza gb +Stuorrabrittania gb +Anglicko gb +Združeno kraljestvo gb +Уједињено КраљевÑтво gb +Ujedinjeno Kraljevstvo gb +I-United Kingdom gb +Storbritannien gb +à®à®•à¯à®•à®¿à®¯ ராஜà¯à®œà®¿à®¯à®®à¯ gb +Подшоҳии Муттаҳида gb +สหราชà¸à¸²à¸“าจัà¸à¸£ gb +BirleÅŸik Krallık gb +Berläşkän PadÅŸahlıq gb +Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ñ–Ñ gb +Буюк Ð‘Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb +Anh gb +RweyÃ¥me Uni gb +United Kingdom gb +英国 gb +è¯åˆçŽ‹åœ‹ gb +United Kingdom gb +Grenada gd +غرينادا gd +Qrenada gd +ГрÑнада gd +Гренада gd +গà§à¦°à§‡à¦¨à¦¾à¦¡à¦¾ gd +Granada gd +ΓÏενάδα gd +Grenado gd +Granada gd +گرانادا gd +Grenade gd +Granada gd +×’×¨× ×“×” gd +गà¥à¤°à¥‡à¤¨à¤¾à¤¡à¤¾ gd +Granada gd +グレナダ gd +ហ្គ្រីណាដា gd +그러네ì´ë‹¤ gd +ເàºàº™àº²àº”າ gd +GrenÄda gd +Гренада gd +Гренада gd +Granada gd +ਗਰੀਨਾਡਾ gd +Granada gd +Granada gd +Гренада gd +Gerenada gd +I-Grenada gd +கிரெனடா gd +Гронодо gd +เà¸à¸£à¸™à¸²à¸”า gd +Гренада gd +Гренада gd +GrenÃ¥de gd +æ ¼æž—çº³è¾¾ gd +æ ¼ç‘žé‚£é” gd +Georgia ge +Georgië ge +جورجيا ge +Ð“Ñ€ÑƒÐ·Ñ–Ñ ge +Ð“Ñ€ÑƒÐ·Ð¸Ñ ge +জরà§à¦œà¦¿à§Ÿà¦¾ ge +Jeorji ge +Gruzija ge +Geòrgia ge +Gruzie ge +Georgien ge +Georgien ge +ΓεωÏγία ge +Georgino ge +Gruusia ge +گرجستان ge +Géorgie ge +Georgië ge +An tSeoirsia ge +Xeórxia ge +×’'ורג'×™×” ge +जà¥à¤¯à¤¾à¤°à¥à¤œà¤¿à¤¯à¤¾ ge +Grúzia ge +GeorgÃa ge +ジョージア島 ge +ហ្សកហ្ស៊ី ge +그루지아 ge +ເຊີເບີຠge +Gruzija ge +Gruzija ge +Грузија ge +Георги ge +Ä orÄ¡ia ge +Georgien ge +Georgië ge +ਜਾਰਜੀਆ ge +Gruzja ge +Geórgia ge +Geórgia ge +Ð“Ñ€ÑƒÐ·Ð¸Ñ ge +Jeworugiya ge +Gruzija ge +Грузија ge +Gruzija ge +Georgien ge +ஜியோரà¯à®œà®¿à®¯à®¾ ge +ГурҷиÑтон ge +จà¸à¸£à¹Œà¹€à¸ˆà¸µà¸¢ ge +Gürcistan ge +Görcestan ge +Ð“Ñ€ÑƒÐ·Ñ–Ñ ge +ГуржиÑтон ge +Djeyordjeye ge +æ ¼é²å‰äºš ge +喬治亞 ge +Ghana gh +غانا gh +Гана gh +Гана gh +ঘানা gh +Gwana gh +Gana gh +Γκάνα gh +Ganao gh +غنا gh +Gána gh +Gana gh +×’×× ×” gh +घाना gh +Gana gh +ガーナ gh +ហ្កាណា gh +가나 gh +ຈີນ gh +Gana gh +Gana gh +Гана gh +Гана gh +Gana gh +ਘਾਨਾ gh +Gana gh +Gana gh +Gana gh +Гана gh +Gana gh +Gana gh +Гана gh +Gana gh +I-Ghana gh +கானா gh +Ғано gh +à¸à¸²à¸™à¸² gh +Гана gh +Гана gh +Gana gh +åŠ çº³ gh +è¿¦ç´ gh +Gibraltar gi +جبل طارق gi +Гібралтар gi +Гибралтар gi +জিবà§à¦°à¦²à§à¦Ÿà¦¾à¦° gi +Jibraltar gi +ΓιβÏÎ±Î»Ï„Î¬Ï gi +Gibraltaro gi +گیبرالتار gi +Giobráltar gi +Xibraltar gi +גיברלטר gi +जिबà¥à¤°à¤¾à¤²à¥à¤Ÿà¤° gi +Gibraltár gi +GÃbraltar gi +Gibilterra gi +ジブラルタル gi +지브롤터 gi +ມàºàº¥àº•àº² gi +Gibraltaras gi +GibraltÄrs gi +Гибралтар gi +Гибралтар gi +Ä ibiltar gi +ਗੀਬਰਾਲਟਾਰ gi +Гибралтар gi +Jiburalitari gi +Гибралтар gi +ஜிபà¯à®°à®²à¯à®Ÿà®¾à®°à¯ gi +Ҷабалуттариқ gi +ยิบรà¸à¸¥à¸•à¸² gi +Cebelitarık gi +Гібралтар gi +Гибралтар gi +Djibraltar gi +直布罗陀 gi +直布羅陀 gi +Greenland gl +Groenland gl +Ð“Ñ€ÐµÐ½Ð»Ð°Ð½Ð´Ð¸Ñ gl +গà§à¦°à§€à¦¨à¦²à§à¦¯à¦¾à¦£à§à¦¡ gl +Griñland gl +Groenlà ndia gl +Grónsko gl +Y Lasynys gl +Grønland gl +Grönland gl +Ισλανδία gl +Groenlandia gl +Gröönimaa gl +Gröönlanti gl +Groenland gl +Grienlân gl +An Ghraonlainn gl +Groenlándia gl +Grönland gl +Grænland gl +Groenlandia gl +グリーンランド gl +Grenlandija gl +Гренланд gl +Grønland gl +Gröönland gl +Groenland gl +Grønland gl +ਗਰੀਨਲੈਂਡ gl +Grenlandia gl +Gronelândia gl +Ð“Ñ€ÐµÐ½Ð»Ð°Ð½Ð´Ð¸Ñ gl +Goronilande gl +Ruonáeatnan gl +Grenlandija gl +Гренланд gl +Grenland gl +Grönland gl +Ð“Ñ€Ð¸Ð½Ð»Ð°Ð½Ð´Ð¸Ñ gl +à¸à¸£à¸µà¸™à¹à¸¥à¸™à¸”์ gl +Grönland gl +Ð“Ñ€ÐµÐ½Ð»Ð°Ð½Ð´Ñ–Ñ gl +Ð“Ñ€ÐµÐ½Ð»Ð°Ð½Ð´Ð¸Ñ gl +æ ¼é™µå…° gl +æ ¼é™µè˜ gl +Gambia gm +Gambië gm +غامبيا gm +Ð“Ð°Ð¼Ð±Ñ–Ñ gm +Ð“Ð°Ð¼Ð±Ð¸Ñ gm +গামবিয়া gm +Gambi gm +Gambija gm +Gà mbia gm +Gambie gm +Γκάμπια gm +Gambio gm +گامبیا gm +Gambie gm +An Ghaimbia gm +Gámbia gm +גמביה gm +जामà¥à¤¬à¤¿à¤¯à¤¾ gm +Gambija gm +GambÃa gm +ガンビア gm +ហ្កាំប៊ី gm +ê°ë¹„ì•„ gm +à»àºàº¡àº¡àº² gm +Gambija gm +Gambija gm +Гамбија gm +Гамби gm +Gambja gm +ਗੈਂਬੀਆ gm +Gâmbia gm +Gâmbia gm +Ð“Ð°Ð¼Ð±Ð¸Ñ gm +Gambiya gm +Gambija gm +Гамбија gm +Gambija gm +காமà¯à®ªà®¿à®¯à®¾ gm +Гомбиё gm +à¹à¸à¸¡à¹€à¸šà¸µà¸¢ gm +Ð“Ð°Ð¼Ð±Ñ–Ñ gm +Ð“Ð°Ð¼Ð±Ð¸Ñ gm +Gambeye gm +冈比亚 gm +甘比亞 gm +Guinea gn +غينيا gn +ГвінÑÑ gn +Ð“Ð²Ð¸Ð½ÐµÑ gn +গিনি gn +Gine gn +Gvineja gn +Gini gn +ΓουινÎα gn +Gvineo gn +Ginea gn +گینه gn +Guinée gn +An Ghuine gn +Guiné gn +×’×™× ××” gn +गà¥à¤ˆà¤¨à¤¾ gn +Gvineja gn +GÃnea gn +ギニア gn +ហ្គីណ០gn +기니 gn +ເຖາວັນ gn +GvinÄ—ja gn +Gvineja gn +Гвинеја gn +Гуйнеа gn +Ginea gn +ਗà©à¨‡à¨¨à©€à¨† gn +Gwinea gn +Guiné gn +Guiné gn +Ð“Ð²Ð¸Ð½ÐµÑ gn +Gineya gn +Gvineja gn +Гвинеја gn +Gvineja gn +கà¯à®¯à¯à®©à®¿à®¯à®¾ gn +Гине gn +à¸à¸´à¸™à¸µ gn +Gine gn +Ð“Ð²Ñ–Ð½ÐµÑ gn +Ð“Ð²Ð¸Ð½ÐµÑ gn +Guinêye gn +å‡ å†…äºš gn +幾內亞 gn +Guadeloupe gp +غواديلوب gp +ГвадÑлупа gp +Гваделупа gp +গাডেলà§à¦ª gp +Gwadeloup gp +Gvadalupe gp +Guadalupe gp +Gwadel?p gp +ΓουαδελοÏπη gp +Gvadelupo gp +Guadalupe gp +Guadalupe gp +گوادلوپ gp +Guadalúip gp +Guadalupe gp +×’×ודלופה gp +गà¥à¤µà¤¾à¤¡à¥‡à¤²à¥‹à¤ª gp +Gvadelúpeyjar gp +Guadalupa gp +ä»é ˜ã‚°ã‚¢ãƒ‰ãƒ«ãƒ¼ãƒ— gp +ហ្គាដឺលុប gp +과들루프 gp +ເດີລຸຠgp +Gvandelupa gp +Гваделупе gp +Gwadelup gp +ਗà©à¨†à¨¡à©€à¨“ਪੀ gp +Gwadelupa gp +Guadalupe gp +Guadalupe gp +Guadelupa gp +Гваделупа gp +Gwaderupe gp +Гвадалупе gp +Gvadalupe gp +கà¯à®µà®¾à®Ÿà¯†à®²à¯à®ªà¯‹à®ªà¯ gp +Гвадалуппо gp +เà¸à¸²à¸°à¸à¸±à¸§à¹€à¸”à¸à¸¥à¸¹à¸› gp +Guadelupa gp +Гваделупа gp +Гваделупа gp +瓜德罗普 gp +瓜德é¯æ™® gp +Equatorial Guinea gq +Ekwatoriaal Guinea gq +غينيا الاستوائية gq +ÐкватарыÑÐ»ÑŒÐ½Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ gq +Екваториална Ð“Ð²Ð¸Ð½ÐµÑ gq +ইকà§à§Ÿà§‡à¦Ÿà§‹à¦°à¦¿à§Ÿà¦¾à¦² গিনি gq +Guine équatoriale gq +Ekvatorijalna Gvineja gq +Guinea Equatorial gq +RovnÃková Guinea gq +Gini Gyhydeddol gq +Ækvatorial Guinea gq +Äquatorial-Guinea gq +ΙσημεÏινή ΓουινÎα gq +Ekvatora Gvineo gq +Guinea equatorial gq +Ekvatoriaal-Guinea gq +Ginea Ekuatoriala gq +گینه اکوادور gq +Päiväntasaajan Guinea gq +Guinée équatoriale gq +Guine Mheánchiorclach gq +Guinea Ecuatorial gq +×’×™× ××” ×”×ž×©×•×•× ×™×ª gq +इकà¥à¤µà¥‡à¤Ÿà¥‹à¤°à¤¿à¤¯à¤² गà¥à¤à¤¨à¤¾ gq +Ekvatorijalna Gvineja gq +EgyenlÃtÅ‘i Guinea gq +Miðbaugs-GÃnea gq +Guinea Equatoriale gq +赤é“ギニア gq +ហ្គីណáŸâ€‹áž¢áŸáž€áŸ’វាទáŸážš gq +ì ë„ ê¸°ë‹ˆ gq +àºàº²àº™àºªàºàº™ gq +Ekvatoriaus GvinÄ—ja gq +EkvatoriÄlÄ Gvineja gq +Екваторијална Гвинеја gq +Equatorial Гуйнеа gq +Ginea Ekwatorjali gq +Ekvatorial-Guinea gq +Äquatoriaal-Guinea gq +Equatoriaal Guinea gq +Ekvatorial-Guinea gq +à¨à¨•à©‚ਲੇਟਰਲ ਗà©à¨ˆà¨¨à¨¿à¨† gq +Gwinea Równikowa gq +Guiné Equatorial gq +Guiné Equatorial gq +Guinea Ecuatorială gq +ÐÐºÐ²Ð°Ñ‚Ð¾Ñ€Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð“Ð²Ð¸Ð½ÐµÑ gq +Gineya Ekwatoriyale gq +EkvatorialalaÅ¡-Guinea gq +RovnÃkova Guinea gq +Ekvatorialna Gvineja gq +Екваторијална Гвинеја gq +Ekvatorijalna Gvineja gq +Ekvatorialguinea gq +ஈகோடோரியல௠கà¯à®¯à¯à®©à®¿à®¯à®¾ gq +Гинеи Ðкваторӣ gq +à¸à¸´à¸™à¸µ ตรงเส้นศูนย์สูตร gq +Ekvatoral Gine gq +Equatorlı Guinea gq +Екваторіальна Ð“Ð²Ñ–Ð½ÐµÑ gq +Ðкваториал Ð“Ð²Ð¸Ð½ÐµÑ gq +Guinêye EcwÃ¥toriÃ¥le gq +赤é“å‡ å†…äºš gq +赤é“幾內亞 gq +Greece gr +Griekeland gr +اليونان gr +Yunanıstan gr +ГрÑÑ†Ñ‹Ñ gr +Ð“ÑŠÑ€Ñ†Ð¸Ñ gr +গà§à¦°à§€à¦¸ gr +Gres gr +GrÄka gr +Grècia gr +Řecko gr +Gwlad Groeg gr +Grækenland gr +Griechenland gr +Ελλάδα gr +Grekujo gr +Grecia gr +Kreeka gr +Grezia gr +یونان gr +Kreikka gr +Grikkaland gr +Grèce gr +Grikelân gr +An Ghréig gr +Grécia gr +יוון gr +गà¥à¤°à¥€à¤¸ gr +GrÄka gr +Görögország gr +Grikkland gr +Grecia gr +ギリシャ gr +ក្រិក gr +그리스 gr +àºàºµàºŠ gr +Graikija gr +GrieÄ·ija gr +Грција gr +Грек gr +GreÄ‹ja gr +Hellas gr +Grekenland gr +Griekenland gr +Hellas gr +Grèça gr +ਗਰੀਸ gr +Grecja gr +Grécia gr +Grécia gr +Grecia gr +Ð“Ñ€ÐµÑ†Ð¸Ñ gr +Ubugereki gr +Greika gr +Grécko gr +GrÄija gr +Грчка gr +GrÄka gr +I-Greece gr +Grekland gr +கிரீச௠gr +Юнон gr +à¸à¸£à¸µà¸‹ gr +Yunanistan gr +Yunanstan gr +Ð“Ñ€ÐµÑ†Ñ–Ñ gr +ЮнониÑтон gr +Hy Lạp gr +Grece gr +希腊 gr +希臘 gr +Guatemala gt +Gautemala gt +غواتيمالا gt +Quatemala gt +ГватÑмала gt +Гватемала gt +গà§à§Ÿà¦¾à¦¤à§‡à¦®à¦¾à¦²à¦¾ gt +Gvatemala gt +Gwatemala gt +Γουατεμάλα gt +Gvatemalo gt +گواتمالا gt +Guatamala gt +גו×טמלה gt +गà¥à¤µà¤¾à¤Ÿà¥‡à¤®à¤¾à¤²à¤¾ gt +Gvatemala gt +Gvatemala gt +グァテマラ gt +ហ្គាážáŸáž˜áŸ‰áž¶áž¡áž¶ gt +과테ë§ë¼ gt +àºàº±àº§à»€àº•àº¡àº²àº¥àº² gt +Gvatemala gt +Gvatemala gt +Гватемала gt +ГуÑтемала gt +Gwatemala gt +ਗà©à¨†à¨Ÿà©‡à¨®à¨¾à¨²à¨¾ gt +Gwatemala gt +Гватемала gt +Gwatemala gt +Gvatemala gt +Гватемала gt +Gvatemala gt +I-Guatemala gt +கà¯à®µà®¾à®¤à¯à®¤à®®à®¾à®²à®¾ gt +Гватемоло gt +à¸à¸±à¸§à¹€à¸•à¸¡à¸²à¸¥à¸² gt +Гватемала gt +Гватемала gt +Gwatemala gt +å±åœ°é©¬æ‹‰ gt +瓜地馬拉 gt +Guam gu +غوام gu +Гуам gu +Гуам gu +গà§à§Ÿà¦¾à¦® gu +Gwam gu +Gw?m gu +Γκουάμ gu +Gvamo gu +گوام gu +גו×× gu +गà¥à¤µà¤¾à¤® gu +Gvam gu +グァムgu +ហ្គាំម gu +ê´Œ gu +à»àºàº¡àº¡àº² gu +Guama gu +Гвам gu +Гуам gu +Gwam gu +ਗà©à¨†à¨® gu +Гуам gu +Gwamu gu +Гуам gu +காம௠gu +Гуамма gu +à¸à¸§à¸¡ gu +Гуам gu +Гуам gu +Gwam gu +关岛 gu +關島 gu +Guinea-Bissau gw +غينيا-بيساو gw +ГвінÑÑ-БіÑаў gw +Ð“Ð²Ð¸Ð½ÐµÑ Ð‘Ð¸Ñау gw +গিনি-বিসো gw +Gine-Biso gw +Gvineja-Bisau gw +Gini-Bisaw gw +ΓουινÎα-Μπισσάου gw +Gvineo BisaÅa gw +Ginea-Bissau gw +گینه بیسائو gw +Guinée-Bissau gw +Guine-Bhissau gw +×’×™× ××” ביס×ו gw +गà¥à¤à¤¨à¤¾-बिसाऊ gw +Bissau-Guinea gw +GÃnea-Bissá gw +ギニアビサオ gw +ហ្គីណáŸáž”៊ីសៅ gw +기니비사 gw +ລັດເຊີຠgw +Gvineja-Bisava gw +Гвинеја БиÑао gw +Гуйнеа-БиÑÑау gw +Ginea-Bissaw gw +ਗà©à¨‡à¨¨à¨¿à¨†-ਬਿਸ਼ਾਉ gw +Gwinea-Bissau gw +Guiné Bissau gw +Guiné-Bissau gw +ГвинеÑ-БиÑау gw +Gineya-Bisawu gw +Гвинеја БиÑао gw +Gvineja Bisao gw +கà¯à®¯à¯à®©à®¿à®¯à®¾-பிஸà¯à®¸à®¾ gw +Гвинеи БиÑÑои gw +à¸à¸´à¸™à¸µ - บิสซภgw +Gine-Bissau gw +ГвінеÑ-БіÑау gw +ГвинеÑ-БиÑÑау gw +Guinêye-Bissaw gw +å‡ å†…äºšæ¯”ç» gw +幾內亞比紹 gw +Guyana gy +غيانا gy +ГвіÑна gy +Гуайана gy +গায়ানা gy +Gwiana gy +Gvajana gy +Giana gy +Γουιάνα gy +Gujano gy +گویان gy +Guyane gy +An Ghuáin gy +Guiana gy +גוי×× ×” gy +गà¥à¤¯à¤¾à¤¨à¤¾ gy +Gvæjana gy +ガイアナ gy +ហ្គីយ៉ាណា gy +ê°€ì´ì•„나 gy +ຈີນ gy +Gviana gy +Gajana gy +Гвајана gy +ГуÑна gy +Gujana gy +ਗà©à¨†à¨¨à¨¾ gy +Gujana gy +Guiana gy +Guiana gy +Guiana gy +Гайана gy +Giyana gy +Gvajana gy +Гвајана gy +Gvajana gy +கானா gy +Гуана gy +à¸à¸¹à¸¢à¸²à¸™à¹ˆà¸² gy +Guana gy +ГайÑна gy +Гвиана gy +åœäºšé‚£ gy +è“‹äºžç´ gy +Hong Kong SAR(China) hk +Hong Kong SAR (China) hk +Хонг Конг (Китай) hk +হং কং SAR(চীন) hk +Hong Kong SAR(Sina) hk +Hong Kong SAR(Xina) hk +Hong Kong SAR (ÄŒÃna) hk +Hongkong SAR(Kina) hk +Χονγκ Κονγκ SAR (Κίνα) hk +Hongkong hk +Hong Kong SAR(Txina) hk +Hong Kong SAR (Kiina) hk +Hong Kong SAR (Chine) hk +Hong Cong SAR(An tSÃn) hk +Hong Kong hk +×”×•× ×’ ×§×•× ×’ SAR (סין) hk +Hongkong (KÃna) hk +Hong Kong (sjálfstjórnarhérað à KÃna) hk +Hong Kong SAR(Cina) hk +香港(ä¸å›½) hk +ហុងចិន (áž…áž·áž“) hk +Hong Kongas SAR(Kinija) hk +Хонг Конг СÐÐ (Кина) hk +Hongkong SAR(Kina) hk +Hong Kong hk +Hongkong SAR(Kina) hk +ਹਾਂਗ-ਕਾਂਗ SAR(ਚੀਨ) hk +Hong Kong SAR (Chiny) hk +Hong Kong SAR (China) hk +Гонконг hk +Hong Kong SAR (Ubushinwa) hk +Hongkong SAR(Kiinná) hk +Hong Kong SAR (Kitajska) hk +SAR Hong Kong (Кина) hk +SAR Hong Kong (Kina) hk +Hong Kong (Kina) hk +ஹாஙà¯à®•à®¾à®™à¯ SAR(சீனா) hk +ฮ่à¸à¸‡à¸à¸‡ hk +Hong Kong (Çin) hk +Гонконг SAR (Китай) hk +Гонконг (Хитой) hk +ä¸å›½é¦™æ¸¯ç‰¹åˆ«è¡Œæ”¿åŒº hk +香港 SAR(ä¸åœ‹) hk +Honduras hn +هندوراس hn +Ð“Ð°Ð½Ð´ÑƒÑ€Ð°Ñ hn +Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +হণà§à¦¡à§à¦°à¦¾à¦¸ hn +Hondures hn +Hondwras hn +ΟνδοÏÏα hn +Honduro hn +هندوراس hn +Hondúras hn +×”×•× ×“×•×¨×¡ hn +होंडà¥à¤°à¤¾à¤¸ hn +Hondúras hn +ホンジュラス hn +ហុងឌូរ៉ាស់ hn +온ë‘ë¼ìŠ¤ hn +ຫàºàº™àº”ູລັດ hn +HondÅ«ras hn +Hondurasa hn +Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +Ħonduras hn +Hondures hn +ਹੰਨਡੂਰਸ hn +Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +Hondirasi hn +Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +I-Honduras hn +ஆணà¯à®Ÿà¯à®°à®¾à®¸à¯ hn +Ò²Ð¸Ð½Ð´ÑƒÑ€Ð¾Ñ hn +ฮà¸à¸™à¸”ูรัส hn +Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn +洪都拉斯 hn +å®éƒ½æ‹‰æ–¯ hn +Croatia hr +Kroasië hr +كرواتيا hr +Xırvatıstan hr +Ð¥Ð°Ñ€Ð²Ð°Ñ‚Ñ‹Ñ 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 +Kroatië hr +An Chróit hr +Croácia hr +קרו×טיה hr +कà¥à¤°à¥‹à¤à¤¶à¤¿à¤¯à¤¾ hr +Hrvatska hr +Horvátország hr +Kroasia hr +KróatÃa hr +Croazia hr +クãƒã‚¢ãƒã‚¢ hr +ក្រូអាហhr +í¬ë¡œì•„í‹°ì•„ hr +ໂຄເàºà»€àº—ີຠhr +Kroatija hr +HorvÄtija hr +ХрватÑка hr +Кроати hr +Kroazja hr +Kroatia hr +Kroatien hr +Kroatië hr +Kroatia hr +Croacia hr +ਕਰੋਆਟਿਆ hr +Chorwacja hr +Croácia hr +Croácia hr +CroaÅ£ia hr +Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ð¸Ñ hr +Korowasiya hr +Kroátia hr +Chorvátsko hr +HrvaÅ¡ka hr +ХрватÑка hr +Hrvatska hr +I-Croatia hr +Kroatien hr +கà¯à®°à¯‹à®Ÿà®¿à®¯à®¾ hr +Хорватӣ hr +โครเà¸à¹€à¸˜à¸µà¸¢ hr +Hırvatistan hr +Kroatia hr +Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ñ–Ñ hr +Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ð¸Ñ hr +CrowÃ¥ceye hr +克罗地亚 hr +克羅埃西亞 hr +Haiti ht +Haïti ht +هايتي ht +Гаіці ht +Хаити ht +হাইতি ht +Haità ht +Αϊτή ht +Haitio ht +Haità ht +هاییتی ht +Haïti ht +HáÃtà ht +×”×יטי ht +हैती ht +HaÃtà ht +ãƒã‚¤ãƒ ht +ហែទី ht +ì•„ì´í‹° ht +ວາດຮູບ - K ht +Haitis ht +Хаити ht +Хайти ht +Ħaiti ht +ਹਾਇਟੀ ht +Гаити ht +Hayiti ht +Хаити ht +ஹைதி ht +Ҳаити ht +ไฮติ ht +Гаїті ht +Гаити ht +Hayiti ht +海地 ht +海地 ht +Hungary hu +Hongarye hu +هنغاريا hu +Macarıstan hu +Вугоршчына hu +Ð£Ð½Ð³Ð°Ñ€Ð¸Ñ hu +হাঙà§à¦—েরী hu +Hungaria hu +MaÄ‘arska hu +Hongria hu +MaÄarsko hu +Hwngari hu +Ungarn hu +Ungarn hu +ΟυγγαÏία hu +Hungario hu +HungrÃa hu +Ungari hu +Hungaria hu +مجارستان hu +Unkari hu +Ungarn hu +Hongrie hu +Hongarije hu +An Ungáir hu +Hungria hu +×”×•× ×’×¨×™×” hu +हंगरी hu +MaÄ‘jarska hu +Magyarország hu +Hungaria hu +Ungverjaland hu +Ungheria hu +ãƒãƒ³ã‚¬ãƒªãƒ¼ hu +ហុងគ្រី hu +í—가리 hu +ຫັງàºàº²àº¥àºµ hu +Vengrija hu +UngÄrija hu +Унгарија hu +Унгар hu +Ungerija hu +Ungarn hu +Ungarn hu +Hongarije hu +Ungarn hu +Hongria hu +ਹੰਗਰੀ hu +WÄ™gry hu +Hungria hu +Hungria hu +Ungaria hu +Ð’ÐµÐ½Ð³Ñ€Ð¸Ñ hu +Hongiriya hu +Ungár hu +MaÄarsko hu +Madžarska hu +МађарÑка hu +MaÄ‘arska hu +I-Hungary hu +Ungern hu +ஹஙà¯à®•à¯‡à®°à®¿ hu +МаҷориÑтон hu +ฮังà¸à¸²à¸£à¸µ hu +Macaristan hu +Macarstan hu +Угорщина hu +Ð’ÐµÐ½Ð³Ñ€Ð¸Ñ hu +Hongreye hu +匈牙利 hu +匈牙利 hu +Indonesia id +Indonesië id +إندونيسيا id +Ä°ndoneziya id +ІнданÑÐ·Ñ–Ñ id +Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id +ইনà§à¦¦à§‹à¦¨à§‡à¦¶à¦¿à§Ÿà¦¾ id +Indonezi id +Indonezija id +Indonèsia id +Indonésie id +Indonesien id +Indonesien id +Ινδονησία id +Indonezio id +Indoneesia id +اندونزی id +Indonésie id +Indonesië id +An Indinéis id +Indonésia id +××™× ×“×•× ×–×™×” id +इंडोनेशिया id +Indonezija id +Indonézia id +IndónesÃa id +インドãƒã‚·ã‚¢ id +ឥណ្ឌូនáŸážŸáŸŠáž¸ id +ì¸ë„네시아 id +àºàºµàºà»‚ດນີເຊີຠid +Indonezija id +IndonÄ“zija id +Индонезија id +Индонез id +Indoneżja id +Indonesien id +Indonesië id +ਇੰਡੋਨੇਸ਼ੀਆ id +Indonezja id +Indonésia id +Indonésia id +Indonezia id +Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id +Indonesiya id +Indonézia id +Indonezija id +Индонезија id +Indonezija id +I-Indonesia id +Indonesien id +இநà¯à®¤à¯‹à®©à¯€à®šà®¿à®¯à®¾ id +Индонезӣ id +à¸à¸´à¸™à¹‚ดนีเซีย id +Ä°ndonezya id +Ä°ndonesia id +Ð†Ð½Ð´Ð¾Ð½ÐµÐ·Ñ–Ñ id +Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id +Indonezeye id +å°åº¦å°¼è¥¿äºš id +å°å°¼ id +Ireland ie +Ierland ie +أيرلندا ie +Ä°rlandiya ie +ІрлÑÐ½Ð´Ñ‹Ñ ie +Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie +আয়ারলà§à¦¯à¦¾à¦£à§à¦¡ ie +Iwerzhon ie +Irska ie +Irlanda ie +Irsko ie +Iwerddon ie +Irland ie +Irland ie +ΙÏλανδία ie +Islando ie +Irlanda ie +Iirimaa ie +Irlanda ie +ایرلند ie +Irlanti ie +Ãrland ie +Irlande ie +Ierlân ie +Éire ie +Irlanda ie +××™×¨×œ× ×“ ie +आयरलैंड ie +Irska ie +Ãrország ie +Irlandia ie +Ãrland ie +Irlanda ie +アイルランド ie +អៀរឡង់ ie +ì•„ì¼ëžœë“œ ie +ໄàºà»àº¥àº™ ie +Airija ie +Īrija ie +ИрÑка ie +Ирланд ie +Irlanda ie +Irland ie +Irland ie +Ierland ie +Irland ie +Irlanda ie +ਆਇਰਲੈਂਡ ie +Irlandia ie +Irlanda ie +Irlanda ie +Irlanda ie +Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie +Irilande ie +Irlánda ie +Ãrsko ie +Irska ie +ИрÑка ie +Irska ie +I-Ireland ie +Irland ie +அயரà¯à®²à®¾à®¨à¯à®¤à¯ ie +Ирлонд ie +ไà¸à¸£à¹Œà¹à¸¥à¸™à¸”์ ie +Ä°rlanda ie +Ä°reland, Ä°rlandia ie +Ð†Ñ€Ð»Ð°Ð½Ð´Ñ–Ñ ie +Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie +Irlande ie +伊朗 ie +æ„›çˆ¾è˜ ie +Israel il +اسرائيل il +Ä°zrail il +Ізраіль il +Израел il +ইসরাইল il +Izrael il +Izrael il +ΙσÏαήλ il +Israelo il +Iisrael il +اسراییل il +Ãsrael il +Israël il +Iosrael il +ישר×ל il +इज़राइल il +Izrael il +Izrael il +Ãsrael il +Israele il +イスラエル il +អ៊ីស្រាអែល il +ì´ìŠ¤ë¼ì—˜ il +àºàº´àº”ສະລະເàºàº¥ il +Izraelis il +IzraÄ“la il +Израел il +Изриал il +Iżrael il +ਇਜ਼ਰਾਈਲ il +Izrael il +Израиль il +Isirayeli il +Izrael il +Izrael il +Израел il +Izrael il +I-Israel il +இசà¯à®°à¯‡à®²à¯ il +ИÑроил il +à¸à¸´à¸ªà¸£à¸²à¹€à¸à¸¥ il +Ä°srail il +Ä°srael il +Ізраїль il +ИÑроил il +Israyel il +USirayeli il +以色列 il +以色列 il +India in +Indië in +الهند in +Hindistan in +Ð†Ð½Ð´Ñ‹Ñ in +Ð˜Ð½Ð´Ð¸Ñ in +à¦à¦¾à¦°à¦¤ in +Indez in +Indija in +Ãndia in +Indie in +Indien in +Indien in +Ινδία in +Hindujo in +هندوستان in +Intia in +Inde in +An India in +Ãndia in +הודו in +à¤à¤¾à¤°à¤¤ in +Indija in +Indland in +インド in +ឥណ្ឌា in +ì¸ë„ in +àºàº´àº™à»€àº”ີຠin +Indija in +Indija in +Индија in +ÐнÑÑ‚Ñ…Ñг in +Indja in +Indien in +à¨à¨¾à¨°à¨¤ in +Indie in +Ãndia in +Ãndia in +Ð˜Ð½Ð´Ð¸Ñ in +Ubuhinde in +Indija in +Индија in +Indija in +I-India in +Indien in +இநà¯à®¤à®¿à®¯à®¾ in +ҲиндуÑтон in +à¸à¸´à¸™à¹€à¸”ีย in +Hindistan in +Hindstan in +Ð†Ð½Ð´Ñ–Ñ in +ҲиндиÑтон in +Ấn Äá»™ in +Inde in +å°åº¦ in +å°åº¦ in +Endiya in +Iraq iq +Irak iq +العراق iq +Ä°raq iq +Ірак iq +Ирак iq +ইরাক iq +Irak iq +Irak iq +Irák iq +Irac iq +Irak iq +Irak iq +ΙÏάκ iq +Irako iq +Irak iq +Iraak iq +Irak iq +عراق iq +Irak iq +Irak iq +Irak iq +Irak iq +An Iaráic iq +עיר×ק iq +इराक iq +Irak iq +Irak iq +Ãrak iq +イラク iq +អ៊ីរ៉ាក់ iq +ì´ë¼í¬ iq +àºàºµàº¥àº±àº iq +Irakas iq +IrÄka iq +Ирак iq +Ирак iq +Irak iq +Irak iq +Irak iq +Irak iq +ਇਰਾਕ iq +Irak iq +Iraque iq +Iraque iq +Irak iq +Ирак iq +Iraki iq +Iráka iq +Irák iq +Irak iq +Ирак iq +Irak iq +I-Iraq iq +Irak iq +ஈராக௠iq +Ироқ iq +à¸à¸´à¸£à¸±à¸ iq +Irak iq +ÄžÃraq iq +Ірак iq +Ироқ iq +Irak iq +伊拉克 iq +伊拉克 iq +Iran ir +أيران ir +Іран ir +Иран ir +ইরান ir +Ãrán ir +ΙÏάν ir +Irano ir +Iraan ir +ایران ir +An Iaráin ir +Irán ir +×יר×ן ir +इरान ir +Irán ir +Ãran ir +イラン ir +អ៊ីរ៉ង់ ir +ì´ëž€ ir +àºàºµàº¥àº±àº ir +Iranas ir +IrÄna ir +Иран ir +Иран ir +ਈਰਾਨ ir +Irão ir +Irã ir +Иран ir +Irani ir +Irána ir +Irán ir +Иран ir +I-Iran ir +ஈரான௠ir +Ðрон ir +à¸à¸´à¸«à¸£à¹ˆà¸²à¸™ ir +Ä°ran ir +Ä°ran ir +Іран ir +Ðрон ir +伊朗 ir +伊朗 ir +Iceland is +Ysland is +أيسلندا is +Ä°slandiya is +ІÑьлÑÐ½Ð´Ñ‹Ñ is +ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is +আইসলà§à¦¯à¦¾à¦£à§à¦¡ is +Island is +Island is +Islà ndia is +Island is +Ynys yr I? is +Island is +Island is +Ισλανδία is +Islando is +Islandia is +Island is +Islandia is +ایسلند is +Islanti is +Ãsland is +Islande is +Yslân is +An Ãoslainn is +Islándia is +××™×¡×œ× ×“ is +आयरलैंड is +Island is +Izland is +Islandia is +Ãsland is +Islanda is +アイスランド is +អ៊ីស្លង់ is +ì•„ì´ìŠ¬ëž€ë“œ is +ໄàºàºŠà»àº¥àº™ is +Islandija is +Islande is +ИÑланд is +ИÑланд is +Islandja is +Island is +Island is +IJsland is +Island is +Islandia is +ਆਈਸਲੈਂਡ is +Islandia is +Islândia is +Islândia is +Islanda is +ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is +Isilande is +Islánda is +Island is +Islandija is +ИÑланд is +Island is +I-Iceland is +Island is +தீவ௠is +ИÑлонд is +ไà¸à¸‹à¹Œà¹à¸¥à¸™à¸”์ is +Ä°zlanda is +Ä°sland is +ІÑÐ»Ð°Ð½Ð´Ñ–Ñ is +ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is +Izlande is +冰岛 is +冰島 is +Icelandi is +Italy it +Italië it +ايطاليا it +Ä°talyia it +Ð†Ñ‚Ð°Ð»Ñ–Ñ it +Ð˜Ñ‚Ð°Ð»Ð¸Ñ it +ইতালী it +Italia it +Italija it +Ità lia it +Itálie it +Yr Eidal it +Italien it +Italien it +Ιταλία it +Italio it +Italia it +Itaalia it +Italia it +ایتالیا it +Italia it +Italia it +Italie it +Italië it +An Iodáil it +Itália it +×יטליה it +इटली it +Italija it +Olaszország it +Italia it +ÃtalÃa it +Italia it +イタリア it +អ៊ីážáž¶áž›áž¸ it +ì´íƒˆë¦¬ì•„ it +àºàºµàº•àº²àº¥àºµ it +Italija it +ItÄlija it +Италија it +Итали it +Itali it +Italja it +Italia it +Italien it +Italië it +Italia it +Italia it +ਇਟਲੀ it +WÅ‚ochy it +Itália it +Itália it +Italia it +Ð˜Ñ‚Ð°Ð»Ð¸Ñ it +Ubutaliyani it +Itália it +Taliansko it +Italija it +Италија it +Italija it +I-Italy it +Italien it +இதà¯à®¤à®¾à®²à®¿ it +Итолиё it +à¸à¸´à¸•à¸²à¸¥à¸µ it +Ä°talya it +Ä°talia it +Ð†Ñ‚Ð°Ð»Ñ–Ñ it +Ð˜Ñ‚Ð°Ð»Ð¸Ñ it +à it +ItÃ¥leye it +Ithali it +æ„大利 it +義大利 it +Jamaica jm +Jamaika jm +جامايكا jm +Yamayka jm +Ямайка jm +Ямайка jm +জামাইকা jm +Jamaika jm +Jamajka jm +Jamajka jm +Jamaika jm +Τζαμάικα jm +Jamajko jm +Jamaika jm +جاماییکا jm +Jamaika jm +Jamaïque jm +An Iamáice jm +Xamaica jm +×’'מייקה jm +जमैका jm +Jamajka jm +Jamaika jm +Jamaika jm +JamaÃka jm +Giamaica jm +ジャマイカ jm +ហ្សាម៉ាអ៊ិគ jm +ìžë©”ì´ì¹´ jm +ຈາໄມàºàº² jm +Jamaika jm +Jamaika jm +Јамајка jm +Ямайк jm +Ä amajka jm +Jamaika jm +ਜੈਮੇਕਾ jm +Jamajka jm +Ямайка jm +Jamayika jm +Jamajka jm +Jamajka jm +Јамајка jm +Jamajka jm +I-Jamaica jm +சமெயà¯à®•à¯à®•à®¾ jm +Ҷомойко jm +จาไมà¸à¹‰à¸² jm +Jamaika jm +Jamayka jm +Ямайка jm +Ямайка jm +Djamayike jm +ç‰™ä¹°åŠ jm +ç‰™è²·åŠ jm +Jordan jo +Jordaan jo +الأردن jo +Ä°ordaniya jo +Ð¯Ñ€Ð´Ð°Ð½Ñ–Ñ jo +Ð™Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo +জরà§à¦¡à¦¾à¦¨ jo +Jordani jo +Jordà nia jo +Jordán jo +Gwlad Iorddonen jo +Jordanien jo +ΙοÏδανία jo +Jordanio jo +Jordania jo +Jordaania jo +Jordania jo +اردن jo +Jordania jo +Jordanie jo +Jordanië jo +An Iordáin jo +Xordánia jo +ירדן jo +जॉरà¥à¤¡à¤¨ jo +Jordánia jo +JórdanÃa jo +Giordania jo +ヨルダン jo +ហ្ស៊កដានី jo +요르단 jo +ຈà»à»àº”ນ jo +Jordanija jo +JordÄnija jo +Јордан jo +Ðрдан jo +Ä ordan jo +Jordanien jo +Jordanië jo +ਜਾਰਡਨ jo +Jordania jo +Jordânia jo +Jordânia jo +Iordania jo +Ð˜Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo +Yorudani jo +Jordánia jo +Jordánsko jo +Jordanija jo +Јордан jo +I-Jordan jo +Jordanien jo +ஜோரà¯à®Ÿà®¾à®©à¯ jo +Урдон jo +จà¸à¸£à¹Œà¹à¸”น jo +Ãœrdün jo +Ð™Ð¾Ñ€Ð´Ð°Ð½Ñ–Ñ jo +Иордан jo +Djordaneye jo +约旦 jo +ç´„æ—¦ jo +Ijolidani jo +Japan jp +اليابان jp +Yaponiya jp +Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp +Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp +জাপান jp +Japon jp +Japó jp +Japonsko jp +Siapan jp +Ιαπωνία jp +Japanio jp +Japón jp +Jaapan jp +Japonia jp +ژاپن jp +Japani jp +Japon jp +An tSeapáin jp +Xapón jp +יפן jp +जापान jp +Japán jp +Jepang jp +Giappone jp +日本 jp +ជប៉ុន jp +ì¼ë³¸ jp +àºàºµà»ˆàº›àº¸à»ˆàº™ jp +Japonija jp +JapÄna jp +Јапонија jp +Япон jp +Jepun jp +Ä appun jp +Japon jp +ਜਾਪਾਨ jp +Japonia jp +Japão jp +Japão jp +Japonia jp +Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp +Ubuyapani jp +Japána jp +Japonsko jp +Japonska jp +Јапан jp +I-Japan jp +சபà¯à®ªà®¾à®©à¯ jp +Ҷопон jp +à¸à¸µà¹ˆà¸›à¹ˆà¸¸à¸™ jp +Japonya jp +Japan, Yaponia jp +Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp +Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp +Nháºt bản jp +Djapon jp +日本 jp +日本 jp +Kenya ke +Kenië ke +كينيا ke +ÐšÐµÐ½Ñ–Ñ ke +ÐšÐµÐ½Ð¸Ñ ke +কেনিয়া ke +Kenija ke +Keňa ke +Cenia ke +Kenia ke +ΚÎνυα ke +Kenjo ke +Kenia ke +کنیا ke +Kenia ke +An Chéinia ke +Kenia ke +×§× ×™×” ke +केनà¥à¤¯à¤¾ ke +Kenija ke +KenÃa ke +ケニア ke +កáŸáž“យ៉ា ke +ì¼€ëƒ ke +ເວນດາ ke +Kenija ke +Kenija ke +Кенија ke +ÐšÐµÐ½Ð¸Ñ ke +Kenja ke +Kenia ke +ਕੀਨੀਆ ke +Kenia ke +Quénia ke +Quênia ke +Kenia ke +ÐšÐµÐ½Ð¸Ñ ke +Keňa ke +Kenija ke +Кенија ke +Kenija ke +கெனà¯à®¯à®¾ ke +Куниё ke +เคนยา ke +Kenia ke +ÐšÐµÐ½Ñ–Ñ ke +ÐšÐµÐ½Ð¸Ñ ke +Kenia ke +肯尼亚 ke +肯亞 ke +Kyrgyzstan kg +قيرغيزستان kg +КыргызÑтан kg +КиргизÑтан kg +কিরà§à¦—িজসà§à¦¤à¦¾à¦¨ kg +Kirgistan kg +Kirgistan kg +Kyrgigstan kg +Kyrgyzstán kg +Cyrgystan kg +Kirgizistan kg +Kirgisien kg +ΚιÏγιζιστάν kg +Kirgizujo kg +Kyrgyzstán kg +Kõrgõzstan kg +قرقیزستان kg +Kirghizstan kg +An Chirgeastáin kg +Kirguizistán kg +קירגיסטן kg +किरà¥à¤—िजिसà¥à¤¤à¤¾à¤¨ kg +Kirgizisztán kg +Kirgisistan kg +Kirghizistan kg +ã‚ルギスタン kg +គៀរហ្គីស្ážáž„់ kg +키르기스스탄 kg +ຄສິຕັລ kg +Kirgistanas kg +KirgizstÄna kg +КиргиÑтан kg +КиргизÑтан kg +Kirgiżstan kg +Kirgisistan kg +Kirgisien kg +Kirgizië kg +Kirgisistan kg +ਕਿਰਗਸਤਾਨ kg +Kigistan kg +Quirguistão kg +Quirguistão kg +Kirgiztan kg +КиргизÑтан kg +Kirigizisitani kg +Kirgisistan kg +Kirgizstan kg +КиргиÑтан kg +Kirgistan kg +Kirgizistan kg +கிரà¯à®•à®¿à®¸à¯à®¤à®¾à®©à¯ kg +ҚирғизиÑтон kg +คีจิสถาน kg +Kırgızistan kg +Qırğızstan kg +КиргизÑтан kg +ҚирғизиÑтон kg +Kirguiztan kg +å‰å°”å‰æ–¯æ–¯å¦ kg +å‰çˆ¾å‰æ–¯ kg +Cambodia kh +Kambodië kh +كمبوديا kh +Камбоджа kh +Камбоджа kh +কামবোডিয়া kh +Kambodj kh +KamboÄ‘a kh +Cambodja kh +Kambodža kh +Kambodscha kh +Καμπότζη kh +KamboÄo kh +Kambodža kh +Canbodia kh +کامبوج kh +Kambodza kh +Cambodge kh +Cambodja kh +An Chambóid kh +Camboia kh +קמבודיה kh +कमà¥à¤¬à¥‹à¤¡à¤¿à¤¯à¤¾ kh +KamboÄ‘a kh +Kambodzsa kh +KambódÃa kh +Cambogia kh +カンボジア kh +កម្ពុជា kh +캄보디아 kh +ໂຄລຳເບີຠkh +Kambodža kh +Kambodža kh +Камбоџа kh +Камбодиа kh +Kemboja kh +Kambodja kh +Kambodsja kh +Kambodscha kh +Cambodja kh +Kambodsja kh +ਕੰਬੋਡੀਆ kh +Kambodża kh +Cambodja kh +Cambodja kh +Cambogia kh +Камбоджа kh +Kamboji kh +Kamboža kh +Kambodža kh +Kambodža kh +Камбоџа kh +Kambodža kh +Kambodja kh +கமà¯à®ªà¯‹à®Ÿà®¿à®¯à®¾ kh +Камбуҷа kh +à¸à¸±à¸¡à¸žà¸¹à¸Šà¸² kh +Kamboçya kh +Kambodia kh +Камбоджа kh +Камбоджа kh +Cam pu chia kh +Cambodje kh +柬埔寨 kh +柬埔寨 kh +Kiribati ki +كيريباتي ki +Кiрыбацi ki +Кирибати ki +কিরিবাটি ki +Ciribati ki +ΚιÏιμπάτι ki +Kiribato ki +کیریباتی ki +Ciribeas ki +קיריב×טי ki +किरीबाती ki +KÃribatà ki +ã‚リãƒã‚¹ ki +គិរិបាទី ki +키리바시 ki +à»àºŸàº„ທັລ - K ki +Кирибати ki +Крибати ki +ਕਿਰਿਬਟੀ ki +Кирибати ki +Кирибати ki +கிரிபடி ki +Карибот ki +คิริบาติ ki +Кірібаті ki +Кирибати ki +基里巴斯 ki +å‰é‡Œå·´æ–¯ ki +Comoros km +جزر القمر km +Каморы km +КоморÑки оÑтрови km +কমোরস km +Komoros km +Komori km +Komory km +Ynysoedd Y Comoros km +Comorerne km +Komoren km +ΚομόÏες km +Komoroj km +Komoorid km +کوموروس km +Komorit km +Comores km +Na Comóir km +קומורוס km +कोमोरो km +Kómoreyjar km +Comore km +コモムkm +កុំម៉ូរ៉ូស km +코모로 km +ສີ km +Komoru salas km +КоморÑки оÑтрови km +Ð¡Ð¾Ð¼Ð¾Ñ€Ð¾Ñ km +Komoros km +Komorene km +Komoren km +Komorane km +ਕੋਮੋਰੋਸ km +Komory km +КоморÑкие оÑтрова km +Komore km +Komorot km +Komori km +Комора km +Komora km +Komorerna km +காமாரோஸ௠km +ÐšÐ¾Ð¼Ð¾Ñ€Ð¾Ñ km +โคโมรà¸à¸ª km +Komoros km +Komorlar km +КоморÑькі оÑтрови km +ÐšÐ¾Ð¼Ð¾Ñ€Ð¾Ñ km +Comores km +科摩罗 km +葛摩 km +St. Kitts and Nevis kn +St. Kitts en Nevis kn +سانت كيتس Ùˆ نيÙيس kn +St. Kitts vÉ™ Nevis kn +СÑнт-КрыÑтофер Ñ– ÐÑÐ²Ñ–Ñ kn +Св. ÐšÐ¸Ñ‚Ñ Ð¸ ÐÐµÐ²Ð¸Ñ kn +সেনà§à¦Ÿ কিটস à¦à¦¬à¦‚ নেà¦à¦¿à¦¸ kn +S. Kitts ha Nevis kn +St. Kitts i Nevis kn +Sv. Kitts a Nevis kn +Ynysoedd St. Kitts a Nevis kn +St. Kitts-Nevis kn +St. Kitts und Nevis kn +Άγιος ΧÏιστόφοÏος (Σαιντ Κιτς) και ÎÎβις kn +Sent-Kristofo kaj Neviso 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 +St. Kitts en Nevis kn +San CrÃostóir Nimheas kn +Saint Kitts e Nevis kn +×¡× ×˜ קיטס ×•× ×‘×™×¡ kn +सेंट किटà¥à¤¸ तथा नेविस kn +St. Kitts és Nevis kn +St. Kitts dan Nevis kn +Sankti Kristófer og Nevis kn +Saint Kitts e Nevis kn +セントクリストファーãƒã‚¤ãƒ“ス kn +សង់ឃីហនិង áž“áŸážœáž¸ážŸ kn +세ì¸íŠ¸ í‚¤ì¸ ë„¤ë¹„ìŠ¤ kn +Å v. Kitts ir Nevis kn +Senkitsa un Nevisa kn +Св. ÐšÐ¸Ñ‚Ñ Ð¸ ÐÐµÐ²Ð¸Ñ kn +St. ÐšÐ¸Ñ‚Ñ‚Ñ Ð±Ð° ÐÐµÐ²Ð¸Ñ kn +St. Kitts u Nevis kn +St. Kitts og Nevis kn +St. Kitts un Nevis kn +St. Kitts en Nevis kn +St. Kitts og Nevis kn +St. Kitts le Nevis kn +St. Kitts e Nevis kn +ਸੇਂਟ ਕਿਟਸ ਤੇ ਨਿਵੀਸ kn +St. Kitts e Nevis kn +St Kitts e Nevis kn +Sf. Kitts ÅŸi Nevis kn +Сент-ÐšÐ¸Ñ‚Ñ Ð¸ ÐÐµÐ²Ð¸Ñ kn +Mutagatifu Kitsi na Nevisi kn +St. Kitts ja Nevis kn +St. Kitts a Nevis kn +St. Kitts in Nevis kn +Св. ÐšÐ¸Ñ‚Ñ Ð¸ ÐÐµÐ²Ð¸Ñ kn +Sv. Kits i Nevis kn +I-St. Kitts and Nevis kn +St. Kitts och Nevis kn +செயினà¯à®Ÿà¯ கிடà¯à®šà¯ & நெவிச௠kn +Синт ÐšÐ¸Ñ‚Ñ‚Ñ Ð²Ð° ÐÐµÐ²Ð¸Ñ kn +เซนต์à¸à¸´à¸•à¸ªà¹Œà¹à¸¥à¸°à¹€à¸™à¸§à¸´à¸ª kn +St. Kitts ve Nevis kn +Santa Kitts wä Nevis kn +Ð¤ÐµÐ´ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¡ÐµÐ½Ñ‚-ÐšÑ–Ñ‚Ñ Ñ– ÐÐµÐ²Ñ–Ñ kn +Сент-КриÑтофер ва ÐÐµÐ²Ð¸Ñ kn +St. Kitts na Nevis kn +St. Kitts và 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 +উতà§à¦¤à¦° কোরিয়া kp +Norzh-Korea kp +Sjeverna Koreja kp +Corea del Nord kp +Severnà Korea kp +Gogledd Corea 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 +Noard-Korea kp +An Chóiré Thuaidh kp +Corea do Norte kp +צפון קורי××” kp +उतà¥à¤¤à¤°à¥€ कोरिया kp +Sjeverna Koreja kp +Észak-Korea kp +Korea Utara kp +Norður-Kórea kp +Corea del Nord kp +æœé®®æ°‘主主義人民共和国 kp +កូរ៉áŸâ€‹ážáž¶áž„​ជើង kp +ì¡°ì„ ë¯¼ì£¼ì£¼ì˜ ì¸ë¯¼ê³µí™”êµ kp +ເàºàº»àº²àº¥àºµà»€àº«àº™àº·àº kp +Å iaurÄ—s KorÄ—ja kp +ZiemeļKoreja kp +Северна Кореја kp +Хойд ÑÐ¾Ð»Ð¾Ð½Ð³Ð¾Ñ kp +Korea ta' Fuq kp +Nord-Korea kp +Noordkorea kp +Noord-Korea kp +Nord-Korea kp +Lebowa la Korea kp +Corea dèu Nord kp +ਉੱਤਰੀ ਕੋਰੀਆ kp +Korea Północna kp +Coreia do Norte kp +Coréia do Norte kp +Coreea de Nord kp +Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kp +Koreya y'Amajyaruguru kp +Davvi-Korea kp +severná Kórea kp +Severna Koreja kp +Северна Кореја kp +Severna Koreja kp +I-North Korea kp +Nordkorea kp +வட கொரியா kp +КореÑи Шимолӣ kp +เà¸à¸²à¸«à¸¥à¸µà¹€à¸«à¸™à¸·à¸ kp +Kuzey Kore kp +Tönyaq Korea kp +Північна ÐšÐ¾Ñ€ÐµÑ kp +Шимолий ÐšÐ¾Ñ€ÐµÑ kp +Devhula ha Korea kp +Bắc Triá»u Tiên kp +Bijhe Corêye kp +Umntla Korea kp +æœé²œ kp +北韓 kp +Enyakatho ne-Korea kp +South Korea kr +Suid Korea kr +كوريا الجنوبية kr +CÉ™nubi Koreya kr +ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ ÐšÐ°Ñ€ÑÑ kr +Южна ÐšÐ¾Ñ€ÐµÑ kr +দকà§à¦·à¦¿à¦£ কোরিয়া kr +Su-Korea kr +Južna Koreja kr +Corea del Sud kr +Jižnà Korea kr +De Corea 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 +Sûd-Korea kr +An Chóiré Theas kr +Corea do Sur kr +×“×¨×•× ×§×•×¨×™××” kr +दकà¥à¤·à¤¿à¤£à¥€ कोरिया kr +Južna Koreja kr +Dél-Korea kr +Korea Selatan kr +Suður-Kórea kr +Corea del Sud kr +大韓民国 kr +កូរ៉áŸâ€‹ážáž¶áž„​ážáŸ’បូង kr +ëŒ€í•œë¯¼êµ kr +ເàºàº»àº²àº¥àºµà»ƒàº•à»‰ kr +Pietų KorÄ—ja kr +DievidKoreja kr +Јужна Кореја kr +Өмнөд ÑÐ¾Ð»Ð¾Ð½Ð³Ð¾Ñ kr +Korea t'Isfel kr +Sør-Korea kr +Söödkorea kr +Zuid-Korea kr +Sør-Korea kr +Borwa bja Korea kr +Corea dèu Sud kr +ਦੱਖਣੀ ਕੋਰੀਆ kr +Korea PoÅ‚udniowa kr +Coreia do Sul kr +Coréia do Sul kr +Coreea de Sud kr +Ð®Ð¶Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kr +Koreya y'Amajyepfo kr +Lulli-Korea kr +Južná Kórea kr +Južna Koreja kr +Јужна Кореја kr +Južna Koreja kr +I-South Korea kr +Sydkorea kr +தென௠கொரியா kr +КореÑи Ҷанубӣ kr +เà¸à¸²à¸«à¸¥à¸µà¹ƒà¸•à¹‰ kr +Güney Kore kr +Könyaq Korea kr +Південна ÐšÐ¾Ñ€ÐµÑ kr +Жанубий ÐšÐ¾Ñ€ÐµÑ kr +Korea tshipembe kr +Hà n Quốc kr +Nonne Corêye kr +Umzantsi Korea kr +韩国 kr +å—韓 kr +Emzansi Korea kr +Kuwait kw +Kuwaït kw +الكويت kw +КувÑйт kw +Кувейт kw +কà§à§Ÿà§‡à¦¤ kw +Kowaet kw +Kuvajt kw +Kuvajt kw +Coweit kw +ΚουβÎιτ kw +Kuvajto kw +Kuveit kw +کویت kw +Kuvait kw +Kowait kw +Koeweit kw +Cuáit kw +כווית kw +कà¥à¤µà¥ˆà¤¤ kw +Kuvajt kw +Kuvait kw +Kúveit kw +クェート kw +គុយវ៉ែហkw +ì¿ ì›¨ì´íŠ¸ kw +à»àº•à»‰àº¡àº®àº¹àºš- K kw +Kuveitas kw +Kuveita kw +Кувајт kw +Кувейт kw +Koeweit kw +ਕà©à¨µà©ˆà¨¤ kw +Koweit kw +Kuveit kw +Кувейт kw +Koweti kw +Kuvajt kw +Kuvajt kw +Кувајт kw +Kuvajt kw +I-Kuwait kw +கà¯à®µà¯ˆà®¤à¯ kw +Қувейт kw +คูเวต kw +Küwäyt kw +KКувейт kw +Кувайт kw +Kuweyt kw +科å¨ç‰¹ kw +科å¨ç‰¹ kw +Cayman Islands ky +Cayman Eilande ky +جزر الكايمان ky +Кайманови оÑтрови ky +কেমà§à¦¯à¦¾à¦¨ দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ ky +Inizi Kaeman ky +Kajmanska ostrva ky +Illes Caimà ky +Kajmanské ostrovy ky +Ynysoedd Caiman ky +Cayman-øerne ky +Kaiman-Inseln ky +Îησιά Κάυμαν ky +Kejmanoj ky +Islas Caimán ky +Kaimanisaared ky +Kaiman Irlak ky +جزایر Ú©Ùیمن ky +Cayman-saaret ky +ÃŽles Caïman ky +Kaaiman Eilannen ky +Oileáin na gCadhman ky +Illas Caimán ky +××™×™ קיימן ky +केमन आइलैंड ky +Kajmanski Otoci ky +Kajmán-szigetek ky +Cayman-eyjar ky +Isole Cayman ky +è‹±é ˜ã‚±ã‚¤ãƒžãƒ³è«¸å³¶ ky +កោះ​កៃម៉ាន ky +ì¼€ì´ë§¨ ì œë„ ky +ຄາຕາລັນ ky +Kaimanų salos ky +Kaimanu salas ky +КајманÑки ОÑтрови ky +Cayman арлууд ky +Gżejjer Cayman ky +Caymanøyene ky +Kayman-Inseln ky +Kaaiman Eilanden ky +Caymanøyane ky +ਕਾਅਮਾਨ ਟਾਪੂ ky +Kajmany ky +Ilhas Caimão ky +Ilhas Cayman ky +Insulele Cayman ky +Каймановы оÑтрова ky +Ibirwa bya Kayimani ky +Caymansullot ky +Kajmanske Ostrovy ky +Kajmanski otoki ky +КајманÑка оÑтрва ky +Kajmanska ostrva ky +Caymanöarna ky +கேமான௠தீவà¯à®•à®³à¯ ky +Ҷазираи Кайман ky +หมู่เà¸à¸²à¸°à¹€à¸„ย์à¹à¸¡à¸™ ky +Cayman Adaları ky +Kayman Utrawları ky +Кайман оÑтрів ky +Кайман Ороллари ky +Iyes Cayman ky +开曼群岛 ky +開曼群島 ky +Kazakhstan kz +كازاخستان kz +КазахÑтан kz +КазахÑтан kz +কাজাকসà§à¦¤à¦¾à¦¨ kz +Kazakstan kz +Kazahstan kz +Kazachstán kz +Casacstan kz +Kasachstan kz +Καζακστάν kz +KazaÄ¥ujo kz +Kazakhstán kz +Kasahstan kz +قزاقستان kz +Kazakstan kz +Kazachstan kz +An Chasacstáin kz +Kazaxistán kz +קזחסט×ן kz +कज़ाखिसà¥à¤¤à¤¾à¤¨ kz +Kazahstan kz +Kazahsztán kz +Kasakstan kz +Kazakistan kz +カザフスタン kz +កាហ្សាក់ស្ážáž„់ kz +ì¹´ìží스탄 kz +à»àºà»àº¥àºàº•àº´àº - K kz +Kazachstanas kz +KazahstÄna kz +КазакÑтан kz +Казак kz +Każakstan kz +Kasakhstan kz +Kasachstan kz +Kazachstan kz +Kasakhstan kz +ਕਾਜ਼ਾਕਸਤਾਨ kz +Kazachstan kz +Cazaquistão kz +Cazaquistão kz +Cazahstan kz +КазахÑтан kz +Kazakisitani kz +Kasakhstan kz +Kazachstan kz +Kazahstan kz +КазахÑтан kz +Kazahstan kz +Kazakstan kz +கஜஸà¯à®¤à®¾à®©à¯` kz +ҚазоқиÑтон kz +คาซัคสถาน kz +Kazakistan kz +Qazaqstan kz +КазахÑтан kz +ҚозоғиÑтон kz +Kazaxhtan kz +哈è¨å…‹æ–¯å¦ kz +哈薩克 kz +Laos la +لاوس la +Ð›Ð°Ð¾Ñ la +Ð›Ð°Ð¾Ñ la +লাওস la +Λάος la +Laoso la +لائوس la +Láós la +ל×וס la +लाओस la +Laosz la +ラオス la +ឡាវ la +ë¼ì˜¤ìŠ¤ la +ລາວ la +Laosas la +Laosa la +Ð›Ð°Ð¾Ñ la +Ð›Ð°Ð¾Ñ la +ਲਿਉਸ la +Ð›Ð°Ð¾Ñ la +Lawosi la +Ð›Ð°Ð¾Ñ la +லாஸ௠la +Ð›Ð°Ð¾Ñ la +ลาว la +Ð›Ð°Ð¾Ñ la +Ð›Ð°Ð¾Ñ la +Là o la +Lawosse la +è€æŒ la +寮國 la +Lebanon lb +Libanon lb +لبنان lb +Ліван lb +Ливан lb +লেবানন lb +Liban lb +Liban lb +LÃban lb +Libanon lb +Libanus lb +Libanon lb +Libanon lb +Λίβανος lb +Libano lb +LÃbano lb +Liibanon lb +Libano lb +لبنان lb +Libanon lb +Libanon lb +Liban lb +Libanon lb +An Liobáin lb +LÃbano lb +×œ×‘× ×•×Ÿ lb +लेबनान lb +Libanon lb +Libanon lb +LÃbanon lb +Libano lb +レãƒãƒŽãƒ³ lb +លីបង់ lb +ë ˆë°”ë…¼ lb +ເດນ່ງນ lb +Libanas lb +LibÄna lb +Либан lb +Либанон lb +Lubnan lb +Libanu lb +Libanon lb +Libanon lb +Libanon lb +Libanon lb +ਲਿਬਨਾਨ lb +Liban lb +LÃbano lb +LÃbano lb +Liban lb +Ливан lb +Libani lb +Libanon lb +Libanon lb +Libanon lb +Либан lb +Liban lb +I-Lebanon lb +Libanon lb +லெபனான௠lb +Лубнон lb +เลบานà¸à¸™ lb +Ліван lb +Лебанон lb +Li Băng lb +Liban lb +黎巴嫩 lb +黎巴嫩 lb +St. Lucia lc +سانت لوسيا lc +СÑнт-ЛюÑÑ–Ñ lc +Св. Ð›ÑƒÑ‡Ð¸Ñ lc +সেনà§à¦Ÿ লà§à¦¸à¦¿à§Ÿà¦¾ lc +S. Lucia lc +Svatá Lucie lc +St. Lwsia lc +Σάντα Λουτσία lc +Sent-Lucio lc +Santa LucÃa lc +سن لوسیا lc +Sankta Lusia lc +Sainte Lucie lc +San Lúisia lc +Santa Lucia lc +×¡× ×˜×” לוסיה lc +सेंट लूसिया lc +Sankti LúsÃa lc +Santa Lucia lc +セントルシア lc +សង់លូស៊ីយ៉ា lc +세ì¸íŠ¸ 루시아 lc +ເຊັນລູເຊີຠlc +Å v Liucija lc +Sv. LÅ«cija lc +Св. Луција lc +St. ЛуÑиа lc +St. LuÄ‹ija lc +ਸੇਂਟ ਲੂਉਸ lc +Santa Lúcia lc +Santa Lúcia lc +Sf. Lucia lc +Сент-ЛюÑÐ¸Ñ lc +Mutagatifu Lusiya lc +Sv. Júlia lc +Sv. Lucija lc +Св. Луција lc +Sv. Lucija lc +I-St. Lucia lc +செனà¯à®Ÿà¯ லூசியா lc +Синт ЛуÑиё lc +เซนต์ลูเซีย lc +Santa Lüçiä lc +Сент-ЛюÑÑ–Ñ lc +Сент-ЛюÑÐ¸Ñ lc +Ste Luceye lc +圣å¢è¥¿äºš lc +è–露西亞 lc +Liechtenstein li +ليشتنشتاين li +ЛіхтÑнштÑйн li +Лихтенщайн li +লিখটেনসà§à¦Ÿà¦¾à¦‡à¦¨ li +LihtenÅ¡tajn li +LichtenÅ¡tejnsko li +Λίχτενσταϊν li +LiÄ¥tenÅtejno li +Liechtestein li +لیختن اشتاین li +An Lichtinstéin li +×œ×™×›×˜× ×©×˜×™×Ÿ li +लिचटेनसà¥à¤Ÿà¥€à¤¨ li +LihtenÅ¡tajn li +リヒテンシュタイン li +លិចទáŸáž“ស្ážáŸ‚áž“ li +리히í…ìŠˆíƒ€ì¸ li +ຟ້າà»àº¡àºš li +LichtenÅ¡teinas li +LihtenÅ¡teina li +Лихтенштајн li +ЛихтÑнштайн li +Liechtensteen li +ਲੀਚਟੀਨਸਟੀਨ li +Lichtensztajn li +Лихтенштейн li +Liyeshitensiteyini li +Лихтенштајн li +LihtenÅ¡tajn li +லசà¯à®šà¯†à®©à¯à®¸à¯à®Ÿà¯†à®©à¯ li +Лихтанштоин li +ลิชเทนสไตน์ li +LihtenÅŸtayn li +Lihtenstein li +Ліхтенштейн li +Лихтенштейн li +Lîchtensteyn li +列支敦士登 li +列支敦斯登 li +Sri Lanka lk +سريلانكا lk +Шры-Ланка lk +Шри Ланка lk +শà§à¦°à§€à¦²à¦™à§à¦•à¦¾ lk +Å ri Lanka lk +Srà Lanka lk +Sri Lanca lk +ΣÏι Λάνκα lk +Sri-Lanko lk +سریلانکا lk +Srà Lanca lk +סרי ×œ× ×§×” lk +शà¥à¤°à¥€ लंका lk +Å ri Lanka lk +Srà Lanka lk +スリランカ lk +ស្រីលង្កា lk +스리랑카 lk +ເຊີເບີຠlk +Å ri Lanka lk +Å rilanka lk +Шри Ланка lk +Шириланк lk +ਸà©à¨°à©€à¨²à©°à¨•à¨¾ lk +Шри-Ланка lk +Siri Lanka lk +Å ri Lanka lk +Шри Ланка lk +Å ri Lanka lk +இலஙà¯à®•à¯ˆ lk +Сри Лонко lk +ศรีลังà¸à¸² lk +Åžri Lanka lk +Шрі-Ланка lk +Шри Ланка lk +æ–¯é‡Œå…°å¡ lk +斯里è˜å¡ lk +Liberia lr +Liberië lr +ليبيريا lr +ЛібÑÑ€Ñ‹Ñ lr +Ð›Ð¸Ð±ÐµÑ€Ð¸Ñ lr +লাইবেরিয়া lr +Liberija lr +Libèria lr +Libérie lr +ΛιβεÏία lr +Liberio lr +Libeeria lr +لیبریا lr +Libéria lr +An Libéir lr +Libéria lr +לוב lr +लाइबेरिया lr +Liberija lr +Libéria lr +LÃberÃa lr +リベリア lr +លីបáŸážšáž¸áž™áŸ‰áž¶ lr +ë¼ì´ë² 리아 lr +ລິຊາ lr +LibÄ“rija lr +Либерија lr +Либери lr +Liberja lr +ਲੀਬਿਰੀਆ lr +Libéria lr +Libéria lr +Ð›Ð¸Ð±ÐµÑ€Ð¸Ñ lr +Liberiya lr +Lýbia lr +Liberija lr +Либерија lr +Liberija lr +லிபிரியா lr +Либериё lr +ไลบีเรีย lr +Liberya lr +Ð›Ñ–Ð±ÐµÑ€Ñ–Ñ lr +Ð›Ð¸Ð±ÐµÑ€Ð¸Ñ lr +利比里亚 lr +賴比瑞亞 lr +Lesotho ls +ليسوتو ls +ЛеÑота ls +ЛеÑото ls +লেসোথো ls +Lesoto ls +Lesoto ls +Λεσόθο ls +Lesoto ls +Lesoto ls +لسوتو ls +Leosóta ls +Lesoto ls +לסוטו ls +लेसोथो ls +Lesótó ls +レソト ls +áž¡áŸážŸáž¼ážáž¼ ls +ë ˆì†Œí† ls +ທົດສàºàºš ls +Lesoto ls +ЛеÑото ls +ЛиÑото ls +Leżoto ls +ਲਿਉਥੂ ls +Lesoto ls +Lesoto ls +Lesoto ls +ЛеÑото ls +Lesoto ls +Lesoto ls +ЛеÑото ls +Lesoto ls +லஸொதோ ls +ЛиÑуту ls +เลโซโต ls +Lesoto ls +Lesoto ls +ЛеÑото ls +ЛеÑото ls +Lessoto ls +莱索托 ls +賴索扥 ls +Lithuania lt +Lithuanië lt +ليتوانيا lt +Litvaniya lt +Літва lt +Литва lt +লিথà§à§Ÿà§‡à¦¨à¦¿à§Ÿà¦¾ lt +Lituani lt +Litvanija lt +Lituà nia lt +Litva lt +Lithwania lt +Litauen lt +Litauen lt +Λιθουανία lt +Litovio lt +Lituania lt +Leedu lt +Lituania lt +لیتوانی lt +Liettua lt +Lituanie lt +Litouwen lt +An Liotuáin lt +Lituánia lt +×œ×™×˜× lt +लिथà¥à¤†à¤¨à¤¿à¤¯à¤¾ lt +Litva lt +Litvánia lt +Litháen lt +Lituania lt +リトアニア lt +លីទុយអានី lt +리투아니아 lt +ລິທົ່ວເນີຠlt +Lietuva lt +Lietuva lt +Литванија lt +Литва lt +Litwanja lt +Litauen lt +Litauen lt +Litouwen lt +Litauen lt +ਲੀਥੂਨੀਆ lt +Litwa lt +Lituânia lt +Lituânia lt +Lituania lt +Литва lt +Litwaniya lt +Lietuva lt +Litva lt +Litva lt +Литванија lt +Litvanija lt +I-Lithuania lt +Litauen lt +லிதà¯à®¤à¯à®µà¯‡à®©à®¿à®¯à®¾ lt +Литвониё lt +ลิธัวเนีย lt +Litvanya lt +Lituania lt +Литва lt +Литва lt +Litwaneye lt +立陶宛 lt +立陶宛 lt +Luxembourg lu +Luxenburg lu +لوكسمبورغ lu +Lüksemburq lu +ЛюкÑÑмбург lu +ЛюкÑембург lu +লাকà§à¦¸à§‡à¦®à¦¬à§à¦°à§à¦— lu +Luksembourg lu +Luksemburg lu +Luxemburg lu +Lucembursko lu +Lwcsembwrg lu +Luxemburg lu +ΛουξεμβοÏÏγο lu +Luksemburgo lu +Luxemburgo lu +Luksemburg lu +Luxenburgo lu +لوگزامبورگ lu +Luxemburg lu +Luksemborg lu +Luxemburg lu +Lucsamburg lu +Luxemburgo lu +לוקסמבורג lu +लकà¥à¤¸à¤®à¤¬à¤°à¥à¤— lu +Luksemburg lu +Luxemburg lu +Lúxemborg lu +Lussemburgo lu +ルクセンブルグ lu +លុចហ្សំបួរ lu +ë£©ì…ˆë¶€ë¥´í¬ lu +ລັàºà»àºŠàº¡à»€àºšàºµàº lu +Liuksemburgas lu +Luksemburga lu +ЛукÑембург lu +ЛюкÑембүрг lu +Lussemburgu lu +Luxemborg lu +Luxemburg lu +ਲਕਸ਼ਮਬਰਗ lu +Luksemburg lu +Luxemburgo lu +Luxemburgo lu +Luxemburg lu +ЛюкÑембург lu +Lugizamburu lu +Luxemburg lu +Luxemburg lu +Luksemburg lu +ЛукÑембург lu +Luksemburg lu +I-Luxembourg lu +Luxemburg lu +லகà¯à®šà®®à¯à®ªà¯‹à®°à¯à®•à¯ lu +Лукзамбург lu +ลัà¸à¹€à¸‹à¸¡à¹€à¸šà¸à¸£à¹Œà¸ lu +Lüksemburg lu +Lüksemburg lu +ЛюкÑембург lu +ЛюкÑембург lu +Lussimbork lu +å¢æ£®å ¡ lu +ç›§æ£®å ¡ lu +Latvia lv +لاتÙيا lv +Latviya lv +Ð›Ð°Ñ‚Ð²Ñ–Ñ lv +Ð›Ð°Ñ‚Ð²Ð¸Ñ lv +লাতà¦à¦¿à§Ÿà¦¾ lv +Latvija lv +Letònia lv +LotyÅ¡sko lv +Latfia lv +Letland lv +Lettland lv +Λεττονία lv +Latvio lv +Letonia lv +Läti lv +لاتویا lv +Lettonie lv +Letland lv +An Laitvia lv +Letónia lv +לטביה lv +लाटविया lv +Latvija lv +Lettország lv +Lettland lv +Lettonia lv +ラトビア lv +ឡាážážœáž¸áž™áŸ‰áž¶ lv +ë¼íŠ¸ë¹„ì•„ lv +ລັດເວີຠlv +Latvija lv +Latvija lv +Латвија lv +Латви lv +Latvja lv +Lettland lv +Letland lv +ਲਾਟਵੀਆ lv +Åotwa lv +Letónia lv +Ð›Ð°Ñ‚Ð²Ð¸Ñ lv +Lativiya lv +Látvia lv +LotyÅ¡sko lv +Latvija lv +Латвија lv +Latvija lv +I-Latvia lv +Lettland lv +லடà¯à®µà®¿à®¯à®¾ lv +Латвонӣ lv +ลัธเวีย lv +Litvanya lv +Ð›Ð°Ñ‚Ð²Ñ–Ñ lv +Ð›Ð°Ñ‚Ð²Ð¸Ñ lv +Lativia lv +Letoneye lv +拉脱维亚 lv +拉脫ç¶äºž lv +Libya ly +Libië ly +ليبيا ly +Ð›Ñ–Ð²Ñ–Ñ ly +Ð›Ð¸Ð±Ð¸Ñ ly +লিবিয়া ly +Julia ly +Libija ly +LÃbia ly +Lýbie ly +Libia ly +Libyen ly +Libyen ly +ΛιβÏη ly +Libio ly +Libia ly +Liibüa ly +Libia ly +لیبی ly +Lybie ly +Libië ly +An Libia ly +LÃbia ly +לוב ly +लीबिया ly +Libija ly +LÃbia ly +LÃbÃa ly +Libia ly +リビア ly +លីប៊ី ly +리비아 ly +ລິຊາ ly +Libija ly +LÄ«bija ly +Либија ly +Ð›Ð¸Ð±Ñ ly +Libja ly +Libyen ly +Libië ly +ਲੀਬੀਆ ly +Libia ly +LÃbia ly +LÃbia ly +Libia ly +Ð›Ð¸Ð²Ð¸Ñ ly +Libiya ly +Lýbia ly +Libija ly +Либија ly +Libija ly +I-Libya ly +Libyen ly +லிபியா ly +Ð›Ð¸Ð±Ð¸Ñ ly +ลิเบีย ly +Libia ly +Ð›Ñ–Ð²Ñ–Ñ ly +Ð›Ð¸Ð±Ð¸Ñ ly +Libeye ly +利比亚 ly +利比亞 ly +Morocco ma +Morokko ma +المغرب ma +Марока ma +Мароко ma +মরকà§à¦•à§‹ ma +Marok ma +Maroko ma +Marroc ma +Maroko ma +Moroco ma +Marokko ma +Marokko ma +ΜαÏόκο ma +Maroko ma +Marruecos ma +Maroko ma +Maroko ma +مراکش ma +Marokko ma +Marokko ma +Maroc ma +Marokko ma +Maracó ma +Marrocos ma +מרוקו ma +मोरकà¥à¤•à¥‹ ma +Maroko ma +Marokkó ma +Marokkó ma +Marocco ma +モãƒãƒƒã‚³ ma +ម៉ារ៉ុក ma +모로코 ma +ເມົາລິ ma +Marokas ma +Maroka ma +Мароко ma +Морокко ma +Marokk ma +Marokko ma +Marokko ma +Marokko ma +Marokko ma +ਮੋਰਕੋ ma +Maroko ma +Marrocos ma +Marrocos ma +Maroc ma +Марокко ma +Maroke ma +Marokko ma +Maroko ma +Maroko ma +Мароко ma +Maroko ma +I-Morocco ma +Marocko ma +மோராகோ ma +Марокко ma +โมร็à¸à¸„โค ma +Morokko ma +Марокко ma +Марокаш ma +Ma rốc ma +Marok ma +摩洛哥 ma +摩洛哥 ma +Monaco mc +Monako mc +موناكو mc +Манака mc +Монако mc +মোনাকো mc +Monako mc +Monako mc +Mònaco mc +Monako mc +Μονακό mc +Monako mc +Mónaco mc +موناکو mc +Monacó mc +Mónaco mc +×ž×•× ×§×• mc +मोनेको mc +Monako mc +Mónakó mc +モナコ mc +ម៉ូណាកូ mc +모나코 mc +ເມົາລິ mc +Monakas mc +Monako mc +Монако mc +Монако mc +Monako mc +ਮੋਨਕੋ mc +Monako mc +Mónaco mc +Mônaco mc +Монако mc +Monako mc +Monako mc +Monako mc +Монако mc +Monako mc +மனாகோ mc +Монако mc +โมนาโค mc +Monako mc +Manako mc +Монако mc +Монако mc +摩纳哥 mc +æ‘©ç´å“¥ mc +Moldova md +مولدوÙا md +Малдова md +ÐœÐ¾Ð»Ð´Ð°Ð²Ð¸Ñ md +মলডোà¦à¦¾ md +Moldavi md +Moldà via md +Moldávie md +Moldofa md +Moldawien md +Μολδαβία md +Moldavujo md +Moldavia md +Moldavia md +مولداوی md +Moldavie md +An Mholdóiv md +Moldávia md +מולדובה md +मॉलà¥à¤¦à¥‹à¤µà¤¾ md +Moldóva md +Moldavia md +モルドムmd +ម៉ុលដូវ៉ា md +몰ë„ë°” md +ສະໂລວັຠmd +MoldÄvija md +Молдавија md +Молдав md +Moldavja md +Moldawien md +Moldavië md +ਮੋਡੋਵਾ md +MoÅ‚dawia md +Moldávia md +Молдова md +Molidova md +Moldávsko md +Молдавија md +Moldavija md +Moldavien md +மாலà¯à®Ÿà¯‹à®µà®¾ md +Молдавӣ md +มà¸à¸¥à¹‚ดวา md +Молдова md +Молдова md +摩尔多瓦 md +摩爾多瓦 md +Madagascar mg +Madagaskar mg +مدغشقر mg +МадагаÑкар mg +МадагаÑкар mg +মাদাগাসà§à¦•à¦¾à¦° mg +Madagaskar mg +Madagaskar mg +Madagaskar mg +Madagaskar mg +ΜαδαγασκάÏη mg +Madagaskaro mg +Madagaskar mg +ماداگاسکار mg +Madagaskar mg +מדגסקר mg +मेडागासà¥à¤•à¤° mg +Madagaskar mg +Madagaszkár mg +Madagaskar mg +マダガスカル mg +ម៉ាដាហ្កាស្ការ mg +마다카스카르 mg +ຄາສະບາລ - K mg +Madagaskaras mg +Madagaskara mg +МадаÑкар mg +МадагаÑкар mg +Madagaskar mg +Madagaskar mg +Madagaskar mg +Madagaskar mg +ਮੈਡਾਗਾਸਕਰ mg +Madagaskar mg +Madagáscar mg +МадагаÑкар mg +Madagasikari mg +Madagaskar mg +Madagaskar mg +Madagaskar mg +МадагаÑкар mg +Madagaskar mg +Madagaskar mg +மடகஸà¯à®•à®¾à®°à¯ mg +МадогоÑкор mg +มาดาà¸à¸±à¸ªà¸à¸² mg +Madagaskar mg +Madagaskar mg +МадагаÑкар mg +МадагаÑкар mg +é©¬è¾¾åŠ æ–¯åŠ mg +馬é”åŠ æ–¯åŠ mg +Marshall Islands mh +Marshall EIlande mh +جزر مارشال mh +Маршалавы аÑтравы mh +МаршалÑки оÑтрови mh +মারশাল দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ mh +Inizi Marshall mh +MarÅ¡alova ostrva mh +Illes Marshall mh +Marshallovy ostrovy mh +Ynysoedd Marshall mh +Marshall-øerne mh +Marshall-Inseln mh +Îησιά ΜάÏσαλ mh +MarÅaloj mh +Islas Marshall mh +Marshalli saared mh +Marshall Irlak mh +جزایر مارشال mh +Marshallinsaaret mh +ÃŽles Marshall mh +Marshall Eilânen mh +Oileáin Mharshall mh +Illas Marshall mh +××™×™ מרשל mh +मारà¥à¤¶à¤² आइलैंड mh +Marshall Otoci mh +Marshall-szigetek mh +Marshall-eyjar mh +Isole Marshall mh +米自由連åˆãƒžãƒ¼ã‚·ãƒ£ãƒ«è«¸å³¶ mh +កោះ Marshall mh +마샬 ì œë„ mh +ລາດສະàºàº²àº™àº²àºˆàº±àºà»„ທຠmh +Marshalo salos mh +MÄrÅ¡alu salas mh +Маршалови ОÑтрови mh +Маршаллын арлууд mh +Gżejjer Marshall mh +Marshalløyene mh +Marshallinseln mh +Marshall Eilanden mh +Marshalløyane mh +ਮਾਰਸ਼ਲ ਟਾਪੂ mh +Wyspy Marshalla mh +Ilhas Marshall mh +Ilhas Marshall mh +Insulele Marshall mh +Маршалловы оÑтрова mh +Ibirwa bya Marishali mh +Marshallsullot mh +Maršálove ostrovy mh +Marshallovi otoki mh +Маршалова оÑтрва mh +MarÅ¡alova ostrva mh +Marshallöarna mh +மாரà¯à®·à®²à¯ தீவà¯à®•à®³à¯ mh +Ҷазираи Маршал mh +หมู่เà¸à¸²à¸°à¸¡à¸²à¹à¸Šà¸¥ mh +MarÅŸal Adaları mh +MarÅŸal Utrawları mh +МаршальÑькі оÑтрови mh +Маршалл Ороллари mh +Iyes Marshall mh +马ç»ç¾¤å²› mh +馬紹爾群島 mh +Macedonia mk +Makedoniese mk +مقدونيا mk +Makedonya mk +ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk +ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk +মà§à¦¯à¦¾à¦¸à¦¿à¦¡à§‹à¦¨à¦¿à§Ÿà¦¾ mk +Makedonia mk +Makedonija mk +Macedònia mk +Makedonie mk +Makedonien mk +Makedonien mk +Σλαβομακεδονία mk +Makedonujo mk +Makedoonia mk +Mazedonia mk +مقدونیه mk +Makedonia mk +Macédoine mk +Macedonië mk +An Mhacadóin (IPIM) mk +Macedónia mk +×ž×§×“×•× ×™×” mk +मकदूनिया mk +Makedonija mk +Macedónia mk +Masedonia mk +MakedónÃa mk +マケドニア mk +ម៉ាសáŸážŠáž“ mk +마케ë„니아 mk +ມາເຊໂດເນີຠmk +Makedonija mk +MaÄ·edonija mk +Македонија mk +Макидон mk +MaÄ‹edonja mk +Makedonia mk +Makedonien mk +Macedonië mk +Makedonia mk +Macedònian mk +ਮੈਕਡੋਨੀਆ mk +Macedónia mk +Macedônia mk +ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk +Masedoniya mk +Makedonia mk +Macedónsky mk +Makedonija mk +Македонија mk +Makedonija mk +I-Macedonia mk +Makedonien mk +மாசிடோ னியா mk +Мақдуниё mk +มาเซโดเนีย mk +Makedonya mk +Makedonia mk +ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk +ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk +Masedonia mk +Macedoneye mk +马其顿 mk +é¦¬å…¶é “ mk +Mali ml +مالي ml +Малі ml +Мали ml +মালি ml +Μαλί ml +Malio ml +مالی ml +Mailà ml +מ×לי ml +माली ml +Malà ml +マリ ml +ម៉ាលី ml +ë§ë¦¬ ml +ຈົດຫມາຠml +Мали ml +Мали ml +ਮਾਲੀ ml +Мали ml +Мали ml +மாலி ml +Молӣ ml +มาลี ml +Малі ml +Мали ml +马里 ml +馬利 ml +Myanmar mm +ميانمار mm +Ðœ'Ñнма mm +Мианмар mm +মিয়ানমার mm +Mjanmar mm +Mianmar mm +Burma mm +Burma (Myanmar) mm +ÎœÎ¹Î±Î½Î¼Î¬Ï mm +Mjanmao mm +Birmania mm +میانمار mm +Maenmar mm +×ž×™× ×ž×¨ mm +मà¥à¤¯à¤¨à¤®à¤¾à¤° mm +Mianmar mm +Mjanmar mm +ミャンマー mm +មីយ៉ាន់ម៉ា mm +미얀마 mm +ຕົວຮງàºàºžàºµàº·à»‰àº™àº—ີ່ທຳງານ - K mm +Mjanma mm +Мијанмар mm +ÐœÑнмар mm +Mjanmar mm +Myanmar (Birma) mm +ਮਿਆਂਮਾਰ mm +Mianmar mm +МьÑнма (Бирма) mm +Mjanmar mm +Мијанмар mm +Mijanmar mm +மயனà¯à®®à®¾à®°à¯ mm +Миёнмор mm +เมียนมาร์ mm +Mianmar mm +Ðœ'Ñнма mm +ÐœÑнмар mm +Miến Äiện mm +Birmaneye mm +缅甸 mm +緬甸 mm +Mongolia mn +Mongolië mn +منغوليا mn +ÐœÐ°Ð½Ð³Ð¾Ð»Ñ–Ñ mn +ÐœÐ¾Ð½Ð³Ð¾Ð»Ð¸Ñ mn +মোঙà§à¦—োলিয়া mn +Mongoli mn +Mongolija mn +Mongòlia mn +Mongolsko mn +Mongoliet mn +Mongolei mn +Μογγολία mn +Mongolio mn +Mongoolia mn +مغولستان mn +Mongolie mn +Mongolië mn +An Mhongóil mn +Mongólia mn +×ž×•× ×’×•×œ×™×” mn +मंगोलिया mn +Mongolija mn +Mongólia mn +MongólÃa mn +モンゴル mn +ម៉ុងហ្គោលី mn +몽골 mn +ລàºàºàºàº´àº™ mn +Mongolija mn +Mongolija mn +Монголија mn +МОÐГОЛ mn +Mongolja mn +Mongolei mn +Mongolië mn +ਮੰਗੋਲੀਆ mn +Mongólia mn +Mongólia mn +ÐœÐ¾Ð½Ð³Ð¾Ð»Ð¸Ñ mn +Mongoliya mn +Mongolsko mn +Mongolija mn +Монголија mn +Mongolija mn +Mongoliet mn +மாஙà¯à®•à¯‹à®²à®¿à®¯à®¾ mn +МуғулиÑтон mn +มà¸à¸‡à¹‚à¸à¹€à¸¥à¸µà¸¢ mn +MoÄŸolistan mn +MoÄŸolstan mn +ÐœÐ¾Ð½Ð³Ð¾Ð»Ñ–Ñ mn +МуғилиÑтон mn +Mông cổ mn +Mongoleye mn +è’™å¤ mn +è’™å¤ mn +Macau SAR(China) mo +Macau SAR (China) mo +Макао (Китай) mo +মাকাউ SAR(চীন) mo +Makav SAR(Sina) mo +Macau SAR(Xina) mo +Macau SAR (ÄŒÃna) mo +Macau SAR(Kina) mo +Macao SAR (China) mo +Μακάο SAR (Κίνα) mo +Macau mo +Macau SAR(Txina) mo +Makao SAR(Kiina) mo +Macao SAR (Chine) mo +Macao SAR(An tSÃn) mo +מק×ו SAR (סין) mo +Makaó (KÃna) mo +Makaó (sjálfstjórnarhérað à KÃna) mo +Macau SAR(Cina) mo +マカオ(ä¸å›½) mo +ម៉ាកាវ (áž…áž·áž“) mo +Macau SAR(Kinija) mo +Макао СÐÐ (Кина) mo +Macao SAR (Kina) mo +Macao mo +Macao SAR (Kina) mo +ਮੈਕਿਉ SAR(ਚੀਨ) mo +Makao SAR (Chiny) mo +Macau (China) mo +Macao SAR(China) mo +Макао mo +Makawu SAR (Ubushinwa) mo +Macau SAR (Kiinná) mo +Macau SAR (Kitajska) mo +SAR Macau (Кина) mo +SAR Macau (Kina) mo +Macao (Kina) mo +Macau SAR(சீனா) mo +มาเà¸à¹Šà¸² mo +Makau (Çin) mo +Macau SAR(Китай) mo +Макау (Хитой) mo +ä¸å›½æ¾³é—¨ç‰¹åˆ«è¡Œæ”¿åŒº mo +澳門 SAR(ä¸åœ‹) mo +Martinique mq +مارتينيك mq +Мартыніка mq +Мартиника mq +মারà§à¦Ÿà¦¿à¦¨à¦¿à¦•à§ mq +Martinik mq +Martinik mq +Martinica mq +Martinik mq +Martin?c mq +ΜαÏτινίκα mq +Martiniko mq +Martinica mq +Martinika mq +مارتینیک mq +MartainÃc mq +Martinica mq +×ž×¨×˜×™× ×™×§ mq +मारà¥à¤Ÿà¥€à¤¨à¥€à¤• mq +MartinÃk mq +Martinica mq +フランス海外県マルãƒãƒ‹ãƒ¼ã‚¯ mq +ម៉ារទីនីគ mq +ë§ˆë¥´í‹°ë‹ˆí¬ mq +ເມົາລິ mq +Martinika mq +Martinika mq +Мартиник mq +Мартиники mq +Martinik mq +ਮਾਰਟੀਨਿਕਿਉ mq +Martynika mq +Martinica mq +Martinica mq +Martinica mq +Мартиника mq +Maritinike mq +Martinik mq +Мартиник mq +Martinik mq +மாரà¯à®¤à®¿à®©à®¿à®•à¯à®¯à¯ mq +Мартиник mq +มาทินิค mq +Martinik mq +Martinik mq +Мартініка mq +Мартиника mq +Martinike mq +马æ尼克 mq +馬æ尼克 mq +Mauritania mr +Mauritanië mr +موريتانيا mr +ÐœÐ°ÑžÑ€Ñ‹Ñ‚Ð°Ð½Ñ–Ñ mr +ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ mr +মরিটানিয়া mr +Maouritani mr +Mauritanija mr +Maurità nia mr +Mauretánie mr +Mawritania mr +Mauretanien mr +Mauretanien mr +ΜαυÏιτανία mr +MaÅritanujo mr +Mauritaania mr +موراتانی mr +Mauritanie mr +Mauritanië mr +An Mháratáin mr +Mauritánia mr +מ××•×¨×™×˜× ×™×” mr +मारीतानिया mr +Mauritanija mr +Mauritánia mr +MáritanÃa mr +モーリタニア mr +ម៉ូរីážáž¶áž“ី mr +모리타니 mr +ລິທົວເນີຠmr +Mauritanija mr +MauritÄnija mr +Мавританија mr +Мауритани mr +Mawritanja mr +Mauretanien mr +Mauritanië mr +ਮਾਉਰੀਟਨਿਆ mr +Mauretania mr +Mauritânia mr +Mauritânia mr +ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ mr +Moritaniya mr +Mavretanija mr +Мауританија mr +Mauritanija mr +Mauretanien mr +மௌரிடானியா mr +Мавритонӣ mr +มà¸à¸£à¸´à¸—าเนีย mr +Mauritanya mr +ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ñ–Ñ mr +ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ mr +Moritanreye mr +毛里塔尼亚 mr +茅利塔尼亞 mr +Montserrat ms +مونتسيرات ms +МонÑерат ms +মনà§à¦Ÿà¦¸à§‡à¦°à¦¾à¦Ÿ ms +Monsera ms +ΜοντσεÏάτ ms +Moncerato ms +مون‌سرات ms +Montsarat ms +×ž×•× ×˜×¡×¨×˜ ms +मॉटसेरट ms +Monserrat ms +è‹±é ˜ãƒ¢ãƒ³ãƒˆã‚»ãƒ©ãƒˆ ms +ម៉ុងសáŸážšáŸ‰áž¶ ms +몬트세ë¼íŠ¸ ms +ຈà»àºžàº²àºš ms +Monserata ms +МонÑерат ms +МонтÑеррат ms +ਮੋਨਟਸੀਰਾਟ ms +МонтÑеррат ms +Monserati ms +МонÑерат ms +Monserat ms +மானà¯à®Ÿà¯à®šà¯†à®°à¯à®°à®Ÿà¯ ms +МунтеÑирот ms +มà¸à¸™à¸•à¹Œà¹€à¸‹à¸à¸£à¹Œà¸£à¸±à¸— ms +МонтÑеррат ms +Монцеррат ms +蒙特塞拉特 ms +蒙的塞拉特 ms +Malta mt +مالطة mt +Мальта mt +Малта mt +মলটা mt +Malt mt +Μάλτα mt +Malto mt +مالت mt +Malte mt +Málta mt +מלטה mt +मालà¥à¤Ÿà¤¾ mt +Málta mt +マルタ mt +ម៉ាល់ážáž¶ mt +몰타 mt +ມàºàº¥àº•àº² mt +Малта mt +Малта mt +ਮਾਲਟਾ mt +Мальта mt +Malita mt +Малта mt +I-Malta mt +மாலà¯à®Ÿà®¾ mt +Молет mt +มà¸à¸¥à¸•à¸² mt +Мальта mt +Малта mt +Male mt +马耳他 mt +馬爾他 mt +Mauritius mu +موريشيوس mu +Маўрыцы mu +ОÑтров Мавриций mu +মরিশাস mu +Mauris mu +Mauricijus mu +Maurici mu +Mauricius mu +Mawrisiws mu +ΜαυÏίκιος mu +MaÅricio mu +Mauricio mu +Maurizio mu +موریتیس mu +ÃŽle Maurice mu +Oileán MhuirÃs mu +MaurÃcio mu +מ×וריציוס mu +मॉरीशस mu +Mauricijus mu +MáritÃus mu +モーリシャス mu +ម៉ូរីទុស mu +모리셔스 mu +ພາທິຊັ້ນ mu +MaurÄ«cija mu +ÐœÐ°Ð²Ñ€Ð¸Ñ†Ð¸ÑƒÑ mu +ÐœÐ°Ð²Ñ€Ð¸Ñ‚ÑƒÑ mu +Mawriju mu +ਮਾਉਰੀਟਿਸ mu +Mauritânia mu +Ilhas MaurÃcio mu +MauriÅ£ius mu +Маврикий mu +Ibirwa bya Morise mu +MaurÃcius mu +Mavricij mu +ÐœÐ°ÑƒÑ€Ð¸Ñ†Ð¸Ñ˜ÑƒÑ mu +Mauricijus mu +மௌரிடியஸ௠mu +Мавритӣ mu +มà¸à¸£à¸´à¹€à¸Šà¸µà¸¢à¸ª mu +Mauritus mu +Маврікій mu +Маврикий mu +Iye Môrice mu +毛里求斯 mu +毛里求斯 mu +Maldives mv +جزر المالدي٠mv +Мальдывы mv +МалдивÑки оÑтрови mv +মালদà§à¦¬à§€à¦ª mv +Inizi Maldiv mv +Maldivi mv +Maledivy mv +Ynysoedd y Mald?f mv +Maldiverne mv +Malediven mv +Μαλδίβες mv +Maldivoj mv +Maldivas mv +Maldiivid mv +Maldibak mv +مالدیو mv +Malediivit mv +Malediven mv +Na Maildivà mv +Maldivas mv +מולדבה mv +मालदीव mv +Maldivi mv +MaldÃv-szigetek mv +MaldÃveyjar mv +Maldive mv +モルジブ mv +ម៉ាល់ឌីវ mv +몰디브 mv +ມັລດິສ mv +Maldyvai mv +Maldivu salas mv +Малдиви mv +Малдив mv +Maldivene mv +Malediven mv +Malediven mv +Maldivane mv +ਮਾਲਦੀਵ mv +Malediwy mv +Maldivas mv +Maldivas mv +Maldive mv +МальдивÑкие оÑтрова mv +Malidive mv +Maldiivat mv +Maldiv mv +Малдиви mv +Maldivi mv +Maldiverna mv +மாலà¯à®¤à¯€à®µà¯à®•à®³à¯ mv +Молдивӣ mv +มัลดิฟ mv +Maldivler mv +Maldivlar mv +Мальдіви mv +Малдив Ороллари mv +马尔代夫 mv +馬爾地夫 mv +Malawi mw +مالاوي mw +Малаві mw +Малави mw +মালাওয়ি mw +Malavi mw +Μαλάουι mw +Malavio mw +مالاوی mw +An Mhaláiv mw +Malavi mw +מל×ווי mw +मलावी mw +Malavi mw +Malavà mw +マラウイ mw +ម៉ាឡាវី mw +ë§ë¼ìœ„ mw +ມàºàº¥àº•àº² mw +Malavi mw +Малави mw +Малави mw +ਮਾਲਾਵੀ mw +Малави mw +Малави mw +Malavi mw +மலவி mw +Моловӣ mw +มาลาวี mw +Malavi mw +Малаві mw +Малави mw +马拉维 mw +é¦¬æ‹‰å¨ mw +Mexico mx +Meksiko mx +المكسيك mx +Meksika mx +ÐœÑкÑыка mx +МекÑико mx +মেকà§à¦¸à¦¿à¦•à§‹ mx +Mec'hiko mx +Meksiko mx +Mèxic mx +Mexiko mx +Mecsico mx +Mexiko mx +Μεξικό mx +Meksiko mx +México mx +Mehhiko mx +Mexiko mx +مکزیک mx +Meksiko mx +Meksiko mx +Mexique mx +Meicsiceo mx +México mx +מקסיקו mx +मेकà¥à¤¸à¤¿à¤•à¥‹ mx +Meksiko mx +Mexikó mx +Meksiko mx +MexÃkó mx +Messico mx +メã‚シコ mx +ម៉ិចស៊ិក mx +멕시코 mx +ເມັàºàºŠàºµà»‚ຠmx +Meksika mx +Meksika mx +МекÑико mx +МекÑико mx +Messiku mx +Mexiko mx +Mèxic mx +ਮੈਕਸਿਕੋ mx +Meksyk mx +México mx +México mx +Mexic mx +МекÑика mx +Megizike mx +Mexiko mx +Mehika mx +МекÑико mx +Meksiko mx +I-Mexico mx +மெகà¯à®šà®¿à®•à¯‹ mx +МекÑико mx +เม็à¸à¸‹à¸´à¹‚ภmx +Meksika mx +Meksiko mx +МекÑика mx +МекÑика mx +Mê hi cô mx +Mecsike mx +墨西哥 mx +墨西哥 mx +Malaysia my +Malysië my +ماليزيا my +ÐœÐ°Ð»Ð°Ð¹Ð·Ñ‹Ñ my +ÐœÐ°Ð»Ð°Ð¹Ð·Ð¸Ñ my +মালয়েশিয়া my +Malezia my +Malezija my +Malà sia my +Malajsie my +Maleisia my +Μαλαισία my +Malajzio my +Malasia my +Malaisia my +Malasia my +مالزی my +Malesia my +Malaisie my +Maleisië my +An Mhalaeisia my +Malásia my +מלזיה my +मलेशिया my +Malezija my +Malajzia my +MalasÃa my +マレーシア my +ម៉ាឡáŸážŸáŸŠáž¸ my +ë§ë ˆì´ì‹œì•„ my +ມàºàº¥àº•àº² my +Malaizija my +Malaizija my +Малезија my +Малайз my +Malażja my +Maleisië my +ਮਲੇਸ਼ੀਆ my +Malezja my +Malásia my +Malásia my +Malaezia my +ÐœÐ°Ð»Ð°Ð¹Ð·Ð¸Ñ my +Maleziya my +Malajzia my +Malezija my +Малезија my +Malezija my +மலேசியா my +Малайзӣ my +มาเลเซีย my +Malezya my +ÐœÐ°Ð»Ð°Ð¹Ð·Ñ–Ñ my +ÐœÐ°Ð»Ð°Ð¹Ð·Ð¸Ñ my +Malaizeye my +马æ¥è¥¿äºš my +馬來西亞 my +Mozambique mz +Mosambiek mz +موزمبيق mz +Мазамбік mz +Мозамбик mz +মোজামবিক mz +Mozambik mz +Mozambik mz +Moçambic mz +Mozambik mz +Mosamb?c mz +Μοζαμβίκη mz +Mozambiko mz +Mosambiik mz +Mozanbike mz +موزامبیک mz +Mosambik mz +MósaimbÃc mz +מוזמביק mz +मोज़ामà¥à¤¬à¥€à¤• mz +Mozambik mz +Mozambik mz +MósambÃk mz +Mozambico mz +モザンビーク mz +ម៉ូហ្សាំប៊ិក mz +ëª¨ìž ë¹„í¬ mz +ຫນ່ວàºàº„ວາມຈຳ mz +Mozambikas mz +Mozambika mz +Мозамбик mz +Мозамбайк mz +Możambik mz +Mosambik mz +Mosambik mz +Mosambik mz +ਮੋਜ਼ਾਨਬਿਕਿਉ mz +Mozambik mz +Moçambique mz +Moçambique mz +Mozambic mz +Мозамбик mz +Mosambik mz +Mozambik mz +Mozambik mz +Мозамбик mz +Mozambik mz +Moçambique mz +மோசாமà¯à®ªà®¿à®•à¯ mz +Мозамбик mz +โมà¹à¸‹à¸¡à¸šà¸´à¸ mz +Mozambik mz +Mozambik mz +Мозамбік mz +Мозамбик mz +Mozambike mz +莫桑比克 mz +莫三比克 mz +Namibia na +Namibië na +ناميبيا na +ÐÐ°Ð¼Ñ–Ð±Ñ–Ñ na +ÐÐ°Ð¼Ð¸Ð±Ð¸Ñ na +নামিবিয়া na +Namibi na +Namibija na +NamÃbia na +NamÃbie na +Îαμίμπια na +Namibio na +Namiibia na +نامیبیا na +Namibie na +Namibië na +An Namaib na +NamÃbia na +× ×ž×™×‘×™×” na +नामीबिया na +Namibija na +NamÃbia na +NamibÃa na +ナミビア na +ណាមីប៊ី na +나미비아 na +ຈາໄມàºàº² na +Namibija na +NamÄ«bija na +Ðамибија na +Ðамиби na +Namibja na +Namibië na +ਨਾਮੀਬੀਆ na +NamÃbia na +NamÃbia na +ÐÐ°Ð¼Ð¸Ð±Ð¸Ñ na +Namibiya na +NamÃbia na +Namibija na +Ðамибија na +Namibija na +நாமிபியா na +Ðамибиё na +นามิเบีย na +Namibya na +ÐÐ°Ð¼Ñ–Ð±Ñ–Ñ na +ÐÐ°Ð¼Ð¸Ð±Ð¸Ñ na +Namibeye na +纳米比亚 na +那米比亞 na +New Caledonia nc +Nuwe Caledonië nc +كاليدونيا الجديدة nc +ÐÐ¾Ð²Ð°Ñ ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ñ–Ñ nc +Ðова ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸Ñ nc +নিউ কà§à¦¯à¦¾à¦²à¦¿à¦¡à§‹à¦¨à¦¿à§Ÿà¦¾ nc +Kaledoni-nevez nc +Nova Kaledonija nc +Nova Caledònia nc +Nová Kaledonie nc +Caledonia Newydd nc +Ny Caledonien nc +Neukaledonien nc +ÎÎα Καληδονία nc +Nov-Kaledonio nc +Nueva Caledonia nc +Uus-Kaledoonia nc +Kaledonia Berria nc +کالدونیا نو nc +Uusi-Kaledonia nc +Nouvelle Calédonie nc +Nij Caledonië nc +An Nua-Chaladóin nc +Nova Caledónia nc +×§×œ×“×•× ×™×” החדשה nc +नà¥à¤¯à¥‚ केलेदूनिया nc +Nova Kaledonija nc +Új-Kaledónia nc +Nýja-KaledónÃa nc +Nuova Caledonia nc +ニューカレドニア nc +នូវែលកាលáŸážŠáž¼áž“ី nc +뉴 ì¹¼ë ˆë„니아 nc +ມາເຊໂດເນີຠnc +Naujoji Kaledonija nc +Jaunkaledonija nc +Ðова Каледонија nc +Ð¨Ð¸Ð½Ñ ÐºÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸ nc +Kaledonja Ä dida nc +Ny-Caledonia nc +Nieg Kaledonien nc +Nieuw Caledonië nc +Ny-Caledonia nc +ਨਵਾਂ ਕਾਲੀਡੋਨਾ nc +Nowa Kaledonia nc +Nova Caledónia nc +Nova Caledônia nc +Noua Caledonie nc +ÐÐ¾Ð²Ð°Ñ ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸Ñ nc +Kaledoniya nc +OÄ‘Ä‘a Kaledonia nc +Nová Kaledónia nc +Nova Kaledonija nc +Ðова Каледонија nc +Nova Kaledonija nc +Nya Caledonien nc +நியூ கலடோனியா nc +КаледониÑи Ðав nc +นิวคาเลโดเนีย nc +Yeni Kaledonya nc +Yaña Kaledonia nc +Ðова ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ñ–Ñ nc +Янги ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸Ñ nc +Nouve Caledonreye nc +新喀里多尼亚 nc +新喀里多尼亞 nc +Niger ne +النيجر ne +Ðігер ne +Ðигер ne +নাইজের ne +Nijer ne +NÃger ne +ÎίγηÏας ne +NiÄero ne +نیجر ne +Nigeria ne +An NÃgir ne +NÃxer ne +× ×™×’'ר ne +निगर ne +NÃger ne +ニジェール ne +នីហ្សáŸážš ne +ë‹ˆì œë¥´ ne +ຕົວຮງàºàºžàº·à»‰àº™àº—ີ່ທຳງານ ne +NigÄ“ra ne +Ðигер ne +Ðигер ne +NiÄ¡er ne +ਨਿਜੀਰ ne +Nigéria ne +Nigéria ne +Ðигер ne +Nijeri ne +Nigéria ne +Ðигер ne +நிஜர௠ne +Ðигерӣ ne +ไนเจà¸à¸£à¹Œ ne +Nijerya ne +Ðігер ne +Ðигер ne +Nidjer ne +尼日尔 ne +尼日 ne +Norfolk Island nf +Norfolk Eiland nf +جزيرة نورÙولك nf +Ðорфалк nf +ОÑтров Ðорфолк nf +নরফোক দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ nf +Enez Norfolk nf +Norfolk ostrvo nf +Illa Norfolk nf +Ynys Norffolc nf +Norfolk-øerne (Australien) nf +Norfolk-Insel nf +Îήσος ÎÏŒÏφοκ nf +Norfolkinsulo nf +Isla Norfolk nf +Norfolki saar nf +Norfok Irla nf +جزایر نورÙولک nf +Norfolkinsaari nf +ÃŽle Norfolk nf +Norfolk Eilân nf +Oileán Norfolc nf +Illa Norfolk nf +××™×™ × ×•×¨×¤×•×œ×§ nf +नॉरफाक आइलैंड nf +Otok Norfolk nf +Norfolk-szigetek nf +Norfolkeyja nf +Isola Norfolk nf +ã‚ªãƒ¼ã‚¹ãƒˆãƒ©ãƒªã‚¢é ˜ãƒŽãƒ¼ãƒ•ã‚©ãƒ¼ã‚¯è«¸å³¶ nf +កោះ Norfolk nf +ë…¸í¬í¬ ì œë„ nf +ໂປà»àº¥àº™ nf +Norfolko sala nf +Norfolka nf +Ðорфолшки ОÑтров nf +Norfolk арлууд nf +Gżira ta' Norfolk nf +Norfolkøya nf +Norfolkinsel nf +Norfolk Eiland nf +Norfolkøya nf +ਨੋਰਫੋਲਕ ਟਾਪੂ nf +Wyspy Norfolk nf +Ilha Norfolk nf +Ilhas Norfolk nf +Insulele Norfolk nf +ОÑтров Ðорфолк nf +Ikirwa cya Norufolika nf +Norfolksuolu nf +Ostrov Norfolk nf +Otok Norfolk nf +Ðорфолкшко оÑтрво nf +NorfolkÅ¡ko ostrvo nf +Norfolkön nf +நாரà¯à®ªà¯‹à®•à¯ தீவ௠nf +Ҷазираи Ðурфолк nf +เà¸à¸²à¸°à¸™à¸à¸£à¹Œà¸Ÿà¸à¸¥à¹Œà¸„ nf +Norfolk Adaları nf +Norfolk Utrawları nf +ОÑтрів Ðорфолк nf +Ðорфолк Ороли nf +Iye di Norfolk nf +诺ç¦å…‹å²› nf +諾ç¦å…‹å³¶ nf +Nigeria ng +Nigerië ng +نيجيريا ng +ÐÑ–Ð³ÐµÑ€Ñ‹Ñ ng +ÐÐ¸Ð³ÐµÑ€Ð¸Ñ ng +নাইজেরিয়া ng +Nijeria ng +Nigerija ng +Nigèria ng +Nigérie ng +ÎιγηÏία ng +NiÄerio ng +Nigeeria ng +نیجریه ng +Nigéria ng +An Nigéir ng +Nixéria ng +× ×™×’×¨×™×” ng +नाइजीरिया ng +Nigerija ng +Nigéria ng +NÃgerÃa ng +ナイジェリア ng +នីហ្សáŸážšáž¸áž™áŸ‰áž¶ ng +나ì´ì§€ë¦¬ì•„ ng +ບັນà»àºà»€àº¥àºµàº ng +Nigerija ng +NigÄ“rija ng +Ðигерија ng +Ðигери ng +NiÄ¡erja ng +ਨੀਜੀਰਿਆ ng +Nigéria ng +Nigéria ng +ÐÐ¸Ð³ÐµÑ€Ð¸Ñ ng +Nigeriya ng +Nigéria ng +Nigerija ng +Ðигерија ng +Nigerija ng +நிஜேரியா ng +Ðигерӣ ng +ไนจีเรีย ng +Nijerya ng +ÐÑ–Ð³ÐµÑ€Ñ–Ñ ng +ÐÐ¸Ð³ÐµÑ€Ð¸Ñ ng +Nidjeria ng +尼日利亚 ng +奈åŠåˆ©äºž ng +Nicaragua ni +Nikaragua ni +نيكاراغوا ni +Ðікарагуа ni +Ðикарагуа ni +নিকারাগà§à§Ÿà¦¾ ni +Nikwaraga ni +Nikaragva ni +Nikaragua ni +Nicaragwa ni +ÎικαÏάγουα ni +Nikaragvo ni +Nikaraagua ni +Nikaragua ni +نیکاراگویه ni +Nikaragua ni +Nikaragua ni +Nicearagua ni +× ×™×§×¨×’×•×•×” ni +निकारागà¥à¤† ni +Nikaragva ni +NÃkaragva ni +ニカラグア ni +នីការ៉ាហ្គáŸážš ni +니카ë¼ê³¼ ni +ປາລາàºàºàº§àº ni +Nikaragva ni +Nikaragva ni +Ðикарагва ni +Ðикрагуа ni +Nikaragwa ni +ਨਿਕਾਰਗà©à¨† ni +Nikaragua ni +Nicarágua ni +Nicarágua ni +Ðикарагуа ni +Nikaragwa ni +Nikaragua ni +Nikaragva ni +Ðикарагва ni +Nikaragva ni +I-Nicaragua ni +நிகராகà¯à®µà¯‡ ni +Ðикарагуа ni +นิคาราà¸à¸±à¸§ ni +Nikaragua ni +Nikaragua ni +Ðікарагуа ni +Ðикарагуа ni +Nicaragwa ni +å°¼åŠ æ‹‰ç“œ ni +å°¼åŠ æ‹‰ç“œ ni +Netherlands nl +Nederland nl +هولندا nl +Hollandiya nl +ГалÑÐ½Ð´Ñ‹Ñ nl +Ð¥Ð¾Ð»Ð°Ð½Ð´Ð¸Ñ nl +হলà§à¦¯à¦¾à¦£à§à¦¡ nl +Izelvroioù nl +Nizozemska nl +Holanda nl +Nizozemà nl +Yr Iseldiroedd 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 +Nederlân nl +An ÃsiltÃr nl +PaÃses Baixos nl +×”×•×œ× ×“ nl +नीदरलैंडà¥à¤¸ nl +Nizozemska nl +Hollandia nl +Belanda nl +Holland nl +Paesi Bassi nl +オランダ nl +ហុល្លង់ nl +네ëœëž€ë“œ nl +ເນເທີà»àº¥àº™à¹Œ nl +Olandija nl +NÄ«derlande nl +Холандија nl +Ðедерланд nl +Nederland nl +Nedderlanne nl +Nederland nl +Nederland nl +Holanda nl +ਨੀਂਦਰਲੈਂਡ nl +Holandia nl +Holanda nl +Holanda nl +Olanda nl +Ðидерланды nl +Ubuholandi nl +Hollánda nl +Holandsko nl +Nizozemska nl +Холандија nl +Holandija nl +I-Netherlands nl +Nederländerna nl +நெதரà¯à®²à®¾à®¨à¯à®¤à¯ nl +Ҳуланд nl +เนเธà¸à¸£à¹Œà¹à¸¥à¸™à¸”์ nl +Hollanda nl +Niderlandlar nl +Ð“Ð¾Ð»Ð»Ð°Ð½Ð´Ñ–Ñ nl +Ðидерландлар nl +Hà Lan nl +Bas Payis nl +è·å…° nl +è·è˜ nl +Norway no +Noorweë no +النرويج no +Norveç no +ÐарвÑÐ³Ñ–Ñ no +ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no +নরওয়ে no +Norvegia no +NorveÅ¡ka no +Noruega no +Norsko no +Norwy no +Norge no +Norwegen no +ÎοÏβηγία no +Norvegio no +Noruega no +Norra no +Norvegia no +نروژ no +Norja no +Norra no +Norvège no +Noorwegen no +An Iorua no +Noruega no +× ×•×¨×‘×’×™×” no +नारà¥à¤µà¥‡ no +NorveÅ¡ka no +Norvégia no +Norwegia no +Noregur no +Norvegia no +ノルウェー no +áž“áŸážšážœáŸ‚ស no +ë…¸ë¥´ì›¨ì´ no +ນà»à»€àº§ no +Norvegija no +NorvÄ“Ä£ija no +Ðорвешка no +Ðорвеги no +NorveÄ¡ja no +Norge no +Norwegen no +Noorwegen no +Noreg no +Noruega no +ਨਾਰਵੇ no +Norwegia no +Noruega no +Noruega no +Norvegia no +ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no +Noruveje no +Norga no +Nórsko no +NorveÅ¡ka no +Ðорвешка no +NorveÅ¡ka no +I-Norway no +Norge no +நாரà¯à®µà¯‡ no +Ðорвегӣ no +นà¸à¸£à¹Œà¹€à¸§à¸¢à¹Œ no +Norveç no +ÐÐ¾Ñ€Ð²ÐµÐ³Ñ–Ñ no +ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no +Na uy no +Norvedje no +æŒªå¨ no +æŒªå¨ no +Nepal np +نيبال np +ÐÑпал np +Ðепал np +নেপাল np +Nepál np +Îεπάλ np +Nepalo np +نپال np +Népal np +Neipeal np +× ×¤×ל np +नेपाल np +Nepál np +ãƒãƒ‘ール np +áž“áŸáž”៉ាល់ np +네팔 np +ເວນດາ np +Nepalas np +NepÄla np +Ðепал np +Ðепал np +ਨੇਪਾਲ np +Ðепал np +Nepali np +Ðепал np +நேபாளம௠np +Ðипол np +เนปาล np +Ðепал np +Ðепал np +尼泊尔 np +尼泊爾 np +Nauru nr +ناورو nr +Ðауру nr +Ðауру nr +নাউরৠnr +Naurueg nr +Nawrw nr +ÎαουÏÎ¿Ï nr +NaÅro nr +Naurú nr +نائورو nr +Naurusaaret nr +Nárúis nr +× ×ורו nr +नौरू nr +Naurski nr +Nárú nr +ナウル nr +ណូរូ nr +나우루 nr +ປາລາàºàºàº§àº nr +Ðауру nr +Ðауру nr +Nawru nr +ਨਾਉਰੂ nr +Ðауру nr +Ikinawuru nr +Ðауру nr +நௌர௠nr +Ðауру nr +นาวรู nr +Ðауру nr +Ðауру nr +Nawouro nr +ç‘™é² nr +è«¾é¯ nr +Niue nu +Nieu nu +نيوي nu +ÐÑ–ÑžÑ nu +Ðиуе nu +নিউই nu +Niwe nu +ÎιοÏε nu +Niuo nu +نیئو nu +× ×™×•×•×” nu +नियू nu +ãƒ‹ãƒ¥ãƒ¼ã‚¸ãƒ¼ãƒ©ãƒ³ãƒ‰è‡ªæ²»é ˜ãƒ‹ã‚¦ã‚¨ nu +នីវ nu +ë‹ˆìš°ì— nu +ເນ໊ຕ nu +Ðије nu +Ðиуе nu +Niwe nu +ਨੀਉਈ nu +Ðиуе nu +Ðиуе nu +நீய௠nu +Ðиу nu +นิà¸à¸¸à¹€à¸ nu +Nive nu +Niu nu +Ðіуе nu +Ðиуе nu +Niuwé nu +纽埃 nu +ç´é„‚島 nu +New Zealand nz +Nuwe Seeland nz +نيوزيلاندا nz +Yeni Zellandiya nz +ÐÐ¾Ð²Ð°Ñ Ð—ÑлÑÐ½Ð´Ñ‹Ñ nz +Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz +নিউজিলà§à¦¯à¦¾à¦£à§à¦¡ nz +Zeland nevez nz +Novi Zeland nz +Nova Zelanda nz +Nový Zéland nz +Seland Newydd nz +Neuseeland nz +ÎÎα Ζηλανδία nz +Nov-Zelando nz +Nueva Zelanda nz +Uus-Meremaa nz +Zelanda Berria nz +زلاندنو nz +Uusi-Seelanti nz +Nýsæland nz +Nouvelle Zélande nz +Nij Seelân nz +An Nua-Shéalainn nz +Nova Celándia nz +× ×™×• ×–×™×œ× ×“ nz +नà¥à¤¯à¥‚जीलैंड nz +Novi Zeland nz +Új-Zéland nz +Selandia Baru nz +Nýja-Sjáland nz +Nuova Zelanda nz +ニュージーランド nz +នូវែលហ្សáŸáž¡áž„់ nz +뉴질랜드 nz +ນີວຊີà»àº¥àº™ nz +Naujoji Zelandija nz +JaunZÄ“lande nz +Ðов Зеланд nz +Ð¨Ð¸Ð½Ñ Ð·ÐµÐ°Ð»Ð°Ð½Ð´ nz +Nieg Seeland nz +Nieuw Zeeland nz +Navera Zelanda nz +ਨਿਊਜ਼ੀਲੈਂਡ nz +Nowa Zelandia nz +Nova Zelândia nz +Nova Zelândia nz +Noua Zeelandă nz +ÐÐ¾Ð²Ð°Ñ Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz +Nuveli Zelande nz +OÄ‘Ä‘a Zealánda nz +Nový Zéland nz +Nova Zelandija nz +Ðови Зеланд nz +Novi Zeland nz +I-New Zealand nz +Nya Zeeland nz +நியூசிலாநà¯à®¤à¯ nz +Зилонди Ðав nz +นิวซีà¹à¸¥à¸™à¸”์ nz +Yeni Zelanda nz +Yaña Zealand nz +Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ñ–Ñ nz +Янги Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz +Nouve Zelande nz +新西兰 nz +ç´è¥¿è˜ nz +Oman om +عÙمان om +Ðман om +Оман om +ওমান om +Omán om +Ομάν om +Omano om +Omán om +Omaan om +عمان om +Omán om +עומן om +ओमन om +Omán om +Óman om +オマーン om +អូម៉ង់ om +오만 om +ເàºàºµàºàº¥àº°àº¡àº±àº™ om +Omanas om +OmÄna om +Оман om +Оман om +ਓਮਾਨ om +Omã om +Omã om +Оман om +Omani om +Omán om +Оман om +I-Oman om +ஓமன௠om +Оман om +โà¸à¸¡à¸²à¸™ om +Umman om +Оман om +Уммон om + Oman om +阿曼 om +阿曼 om +Panama pa +بنما pa +Панама pa +Панама pa +পানামা pa +Panamà pa +Παναμάς pa +Panamo pa +Panamá pa +پاناما pa +Panamá pa +×¤× ×ž×” pa +पनामा pa +パナマ pa +ប៉ាណាម៉ា pa +파나마 pa +ປານາມາ pa +Панама pa +Панама pa +ਪੈਨਾਮਾ pa +Panamá pa +Panamá pa +Панама pa +Панама pa +I-Panama pa +பனாமா pa +Панама pa +ปานามา pa +Панама pa +Панама pa +巴拿马 pa +巴拿馬 pa +Peru pe +البيرو pe +ПÑру pe +Перу pe +পেরৠpe +Perou pe +Perú pe +Periw pe +ΠεÏÎ¿Ï pe +Peruo pe +Perú pe +Peruu pe +پرو pe +Pérou pe +Peiriú pe +Perú pe +פרו pe +पेरू pe +Perú pe +Perù pe +ペルー pe +ប៉áŸážšáž¼ pe +페루 pe +ເປລູ pe +Перу pe +Перу pe +Pero pe +ਪੇਰੂ pe +Перу pe +Перу pe +I-Peru pe +பெர௠pe +Перу pe +เปรู pe +Перу pe +Перу pe +Perou pe +ç§˜é² pe +ç§˜é¯ pe +French Polynesia pf +Fraans Polynesië pf +بولينيزيا الÙرنسية pf +ФранцуÑÐºÐ°Ñ ÐŸÐ°Ð»Ñ–Ð½ÑÐ·Ñ–Ñ pf +ÐŸÐ¾Ð»Ð¸Ð½ÐµÐ·Ð¸Ñ pf +ফরাসী পলিনেশিয়া pf +Polinezi galleg pf +Francuska Polinezija pf +Polinèsia francessa pf +Francouzská Polynésie pf +Polynesia Ffrengig pf +Fransk Polynesien pf +Französisch Polynesien pf +Γαλλική Πολυνησία pf +Franca Polinezio pf +Polinesia francesa pf +Prantsuse Polüneesia pf +Polinesia Frantziarra pf +پولونزی Ùرانسه pf +Ranskan Polynesia pf +Polynésie française pf +Frânsk Polinesië pf +Polainéis na Fraince pf +Polinésia Francesa pf +×¤×•×œ×™× ×–×™×” הצרפתית pf +फà¥à¤°à¥‡à¤‚च पॉलीनेसिया pf +Francuska Polinezija pf +Francia-Polinézia pf +Franska PólýnesÃa pf +Polinesia Francese pf +ãƒ•ãƒ©ãƒ³ã‚¹é ˜ãƒãƒªãƒã‚·ã‚¢ pf +ប៉ូលីនáŸážŸáŸŠáž¸â€‹áž”ារាំង pf +í”„ëž‘ìŠ¤ë ¹ í´ë¦¬ë„¤ì‹œì•„ pf +àºàº£àº±à»ˆàº‡à»€àºªàº” pf +PrancÅ«zų Polinezija pf +FranÄu PolinÄ“zija pf +ФранцуÑка Полинезија pf +Франц полинеÑи pf +Polineżja FranÄ‹iża pf +Fransk Polynesia pf +Franzöösch Polynesien pf +Frans Polinesië pf +Fransk Polynesia pf +ਫਰੈਂਚ ਪੋਲੀਂਸੀਆ pf +Polinezja Francuska pf +Polinésia Francesa pf +Polinésia Francesa pf +Polinezia Franceză pf +ФранцузÑÐºÐ°Ñ ÐŸÐ¾Ð»Ð¸Ð½ÐµÐ·Ð¸Ñ pf +Polinesiya Mfaransa pf +FránskkalaÅ¡ Polynesia pf +Francúzska Polynézia pf +Francoska Polinezija pf +ФранцуÑка Полинезија pf +Francuska Polinezija pf +Franska Polynesien pf +பிரனà¯à®šà¯ போலினேசியா pf +ПулинезиÑи ФаронÑа pf +à¸à¸£à¸±à¹ˆà¸‡à¹€à¸¨à¸ªà¹‚พลีนีเซีย pf +Fransız Polinezyası pf +Frans Polinesia pf +Французька ÐŸÐ¾Ð»Ñ–Ð½ÐµÐ·Ñ–Ñ pf +Француз ÐŸÐ¾Ð»Ð¸Ð½ÐµÐ·Ð¸Ñ pf +Polynesia thuá»™c Pháp pf +Polinezeye francesse pf +法属波利尼西亚 pf +法屬波利尼西亞 pf +Papua New Guinea pg +بابوا غينيا الجديدة pg +Papua Yeni Gvineya pg +Папуа–ÐÐ¾Ð²Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ pg +Папуа Ðова Ð“Ð²Ð¸Ð½ÐµÑ pg +পাপà§à§Ÿà¦¾ নিউ গিনি pg +Papouazi Gine Nevez pg +Papua Nova Gvineja pg +Papua Nova Guinea pg +Papua - Nová Guinea pg +Papwa Gini Newydd pg +Papua Neu-Guinea pg +ΠαποÏα ÎÎα ΓουινÎα pg +Papuo-Nov-Gvineo pg +Papua Nueva Guinea pg +Paapua Uus-Guinea pg +Papua Ginea Berria pg +پاپوا گینه نو pg +Papua-Uusi-Guinea pg +Papouasie-Nouvelle-Guinée pg +Papua Nij Guinea pg +Nua-Ghuine Phapua pg +Papúa Nova Guiné pg +פפו××” × ×™×• ×’×™× ×™ pg +पापà¥à¤† नà¥à¤¯à¥‚ गियाना pg +Papua Nova Gvineja pg +Pápua Új-Guinea pg +Papúa Nýja-GÃnea pg +Papua Nuova Guinea pg +パプアニューギニア pg +ប៉ាពូញូវហ្គីណ០pg +파푸아뉴기니 pg +ເທົາàºà»ˆàºàº™ pg +Papua Naujoji GvinÄ—ja pg +Papua Jaungvineja pg +Папуа Ðова Гвинеја pg +Папуа ÑˆÐ¸Ð½Ñ Ð“ÑƒÐ¹Ð½ÐµÐ° pg +Papwa Ginea pg +Papua Ny-Guinea pg +Papua-Niegguinea pg +Papua Ny-Guinea pg +ਪਾਪੂਆ ਨਵਾਂ ਗੂਈਆ pg +Papua Nowa Gwinea pg +Papua Nova Guiné pg +Papua Nova Guiné pg +Papua Noua Guinee pg +Папуа-ÐÐ¾Ð²Ð°Ñ Ð“Ð²Ð¸Ð½ÐµÑ pg +Papuwa Gineya Nshya pg +Papua OÄ‘Ä‘a-Guinea pg +Papua Nová Guinea pg +Papua Nova Gvineja pg +Папуа Ðова Гвинеја pg +Papua Nova Gvineja pg +Papua Nya Guinea pg +பாபà¯à®ªà®¾ நியூ ஜினியா pg +Папуа ГвинеиÑи Ðав pg +ปาปัวนิวà¸à¸´à¸™à¸µ pg +Papua Yeni Gine pg +Papua Yaña Guinea pg +Папуа Ðова Ð“Ð²Ñ–Ð½ÐµÑ pg +Папуа Янги Ð“Ð²Ð¸Ð½ÐµÑ pg +Papouwazeye Nouve Guinêye pg +å·´å¸ƒäºšæ–°å‡ å†…äºš pg +巴布ç´å¹¾å…§äºž pg +Philippines ph +Fillipyne ph +الÙلبين ph +FillipinlÉ™r ph +Філіпіны ph +Филипини ph +ফিলিপিনস ph +Filipin ph +Filipini ph +Filipines ph +FilipÃny ph +Ynysoedd Y Philipinau ph +Filippinerne ph +Philippinen ph +Φιλιππίνες ph +Filipinoj ph +Filipinas ph +Filipiinid ph +Filipinak ph +Ùیلیپین ph +Filippiinit ph +Filippijnen ph +Na hOileáin FhilipÃneacha ph +Filipinas ph +×¤×™×œ×™×¤×™× ×™× ph +फिलिपà¥à¤ªà¥€à¤¨à¥à¤¸ ph +Filipini ph +Fülöp-szigetek ph +Filippseyjar ph +Filippine ph +フィリピン ph +ហ្វ៊ីលីពីន ph +필리핀 ph +àºàº²àº¥àº°àº›àº°à»‚ຫàºàº” ph +Filipinai ph +FilipÄ«nas ph +Филипини ph +Плиппин ph +Filippini ph +Filippinene ph +Philippinen ph +Filippijnen ph +Filippinane ph +ਫਿਲੀਪੀਨਜ਼ ph +Filipiny ph +Filipinas ph +Filipinas ph +Filipine ph +Филиппины ph +Filipine ph +Filippiinat ph +FilipÃny ph +Filipini ph +Филипини ph +Filipini ph +Filippinerna ph +பிலிபà¯à®ªà¯ˆà®©à¯à®¸à¯ ph +Филипин ph +ฟิลิปปินส์ ph +Filipinler ph +Filippinnär ph +Філіппіни ph +Филиппин ph +Filipenes ph +è²å¾‹å®¾ ph +è²å¾‹è³“ ph +Pakistan pk +باكستان pk +ПакіÑтан pk +ПакиÑтан pk +পাকিসà§à¦¤à¦¾à¦¨ pk +Paquistà pk +Pákistán pk +Pacistan pk +Πακιστάν pk +Pakistano pk +پاکستان pk +An Phacastáin pk +Paquistán pk +פ×קיסטן pk +पाकिसà¥à¤¤à¤¾à¤¨ pk +Pakisztán pk +パã‚スタン pk +ប៉ាគីស្ážáž¶áž“ pk +파키스탄 pk +ລງບ pk +Pakistanas pk +PakistÄna pk +ПакиÑтан pk +ПакиÑтан pk +ਪਾਕਿਸਤਾਨ pk +Paquistão pk +Paquistão pk +ПакиÑтан pk +Pakisitani pk +ПакиÑтан pk +பாகிஸà¯à®¤à®¾à®©à¯ pk +ПокиÑтон pk +ปาà¸à¸µà¸ªà¸–าน pk +Päqstan pk +ПакиÑтан pk +ПокиÑтон pk +å·´åŸºæ–¯å¦ pk +å·´åŸºæ–¯å¦ pk +Poland pl +بولندا pl +PolÅŸa pl +Польшча pl +Полша pl +পোলà§à¦¯à¦¾à¦£à§à¦¡ pl +Polonia pl +Poljska pl +Polònia pl +Polsko pl +Gwlad Pwyl pl +Polen pl +Polen pl +Πολωνία pl +Pollando pl +Polonia pl +Poola pl +Polonia pl +لهستان pl +Puola pl +Pólland pl +Pologne pl +Polen pl +An Pholainn pl +Polónia pl +פולין pl +पोलैंड pl +Poljska pl +Lengyelország pl +Polandia pl +Pólland pl +Polonia pl +ãƒãƒ¼ãƒ©ãƒ³ãƒ‰ pl +ប៉ូឡូញ pl +í´ëž€ë“œ pl +ໂປà»àº¥àº™ pl +Lenkija pl +Polija pl +ПолÑка pl +Польш pl +Polonja pl +Polen pl +Polen pl +Polen pl +Polen pl +Polònia pl +ਪੋਲੈਂਡ pl +Polska pl +Polónia pl +Polônia pl +Polonia pl +Польша pl +Polonye pl +Polska pl +Poľsko pl +Poljska pl +ПољÑка pl +Poljska pl +I-Poland pl +Polen pl +போலாநà¯à®¤à¯ pl +ÐŸÐ¾Ð»Ð°Ð½Ð´Ð¸Ñ pl +โปà¹à¸¥à¸™à¸”์ pl +Polonya pl +Polonia, PolÅŸa pl +Польща pl +Полша pl +Pholandi pl +Ba Lan pl +Pologne pl +波兰 pl +æ³¢è˜ pl +Saint Pierre and Miquelon pm +St Pierre en Miquelon pm +سانت بيير Ùˆ ميكيلون pm +Saint Pierre vÉ™ Miquelon pm +СÑн-П'ер Ñ– Мікелон pm +Св. Пиер и Магелан pm +সেনà§à¦Ÿ পিয়ের à¦à¦¬à¦‚ মিকেলন pm +Sant Per ha Mikelon pm +Sveti Pjer i Migelon pm +Saint Pierre i Miquelon pm +Saint Pierre a Miquelon pm +Ynysoedd Sant Pierre a Micwelon pm +Saint Pierre og Miquelon pm +Saint Pierre und Miquelon pm +Σαιν ΠιÎÏ (Άγιος Î ÎÏ„Ïος) και Μικελόν pm +Sent-Piero kaj Mikelono pm +Saint Pierre y Miquelon pm +Saint Pierre ja Miquelon pm +Saint Pierre eta Miquelon pm +سنت Ù¾ÛŒÙر Ùˆ میکولئون pm +Saint-Pierre ja Miquelon pm +Saint-Pierre-et-Miquelon pm +Saint Pierre en Miquelon pm +Peadar Naofa agus MicilÃn pm +Saint Pierre e Miquelon pm +ס×ן פייר ומיקלון pm +सेंट पियरे तथा मिकà¥à¤µà¥‡à¤²à¤¨ pm +Saint Pierre i Miquelon pm +Saint Pierre és Miquelon pm +Sankti Pierre og Miquelon pm +Saint Pierre e Miquelon pm +ãƒ•ãƒ©ãƒ³ã‚¹æµ·å¤–é ˜åœŸã‚µãƒ³ãƒ”ã‚¨ãƒ¼ãƒ«ãƒŸã‚¯ãƒãƒ³è«¸å³¶ pm +세ì¸íŠ¸ 피ì—르 ë¯¸ì¿ ì—˜ë¡ pm +SenpjÄ“ra un Mikelona pm +Свети Пјер и Микелон pm +Сайнт пиерре ба микуелон pm +Saint Pierre u Miquelon pm +Saint-Pierre-et-Miquelon pm +Sankt Pierre un Miquelon pm +Saint Pierre en Miquelon pm +Saint-Pierre-et-Miquelon pm +ਸੇਂਟ ਪੀਈਰੀ ਤੇ ਮਾਕਿਉਲੋਨ pm +Saint Pierre i Miquelon pm +S. Pedro e Miquelão pm +Saint Pierre e Miquelon pm +Saint Pierre ÅŸi Miquelon pm +Сен-Пьер и Микелон pm +Mutagatifu Petero na Mikelo pm +Saint-Pierre-et-Miquelon pm +Saint Pierre a Miquelon pm +Sveti Pierre in Miquelon pm +Св. Пјер и Микелон pm +Sv. Pjer i Mikelon pm +Saint Pierre och Miquelon pm +செயினà¯à®Ÿà¯ பியரி மறà¯à®±à¯à®®à¯ மிகà¯à®¯à¯à®²à®©à¯ pm +Синт Пир Миколеюн pm +เซนต์ปิà¹à¸à¸£à¹Œ à¹à¸¥à¸°à¸¡à¸´à¹€à¸„à¸à¸¥à¸à¸™ pm +Saint Pierre ve Miquelon pm +Saint Pierre wä Miquelon pm +Сент-П'єр Ñ– Мікелон pm +Сент-Пер ва Микелон pm +Sint Pire et Miquelon pm +圣皮埃尔和密克隆 pm +è–皮埃爾島åŠå¯†å…‹éš†å³¶ pm +Pitcairn pn +بيتكايرن pn +ПіткÑрн pn +ОÑтрови Питкерн pn +পিটকেম pn +Pitkern pn +Ynys Pitcairn pn +ΠίτκαιÏν pn +Pitkarna Insulo pn +پیت Ú©Ùرن pn +פיטקרן pn +पिटकैरà¥à¤¨ pn +è‹±é ˜ãƒ”ãƒˆã‚±ã‚¢ãƒ³è«¸å³¶ pn +í•ì¼€ì–¸ pn +ລງບ pn +PitkÄ“rna pn +Питкерн pn +Питкайрн pn +ਪੀਟਕਾਰਨ pn +Питкаирн pn +பிடà¯à®•à®¾à®¯à¯à®©à¯ pn +Питкорин pn +เà¸à¸²à¸°à¸žà¸´à¸•à¹à¸„ร์น pn +Pitkairn pn +Питкерн pn +çš®ç‰¹å¼€æ© pn +匹特開æ©å³¶ pn +Puerto Rico pr +بورتوريكو pr +Puerto Riko pr +ПуÑрта Рыка pr +Порто Рико pr +পà§à§Ÿà§‡à¦°à§à¦¤à§‹ রিকো pr +Porto Rico pr +Portoriko pr +Portoriko pr +Pwerto Rico pr +ΠουÎÏτο Ρίκο pr +Puerto-Riko pr +پورتوریکو pr +Porto Rico pr +Portó RÃce pr +Porto Rico pr +פורטו ריקו pr +पà¥à¤¯à¥‚रà¥à¤Ÿà¥‹ रिको pr +Portoriko pr +Púertó RÃkó pr +Portorico pr +プエルトリコ pr +áž–áŸážšážáž¼ážšáž¸áž€áž¼ pr +푸ì—ë¥´í† ë¦¬ì½” pr +ໂປຣໂຕຄàºàº™ pr +Puerto Rikas pr +Puertoriko pr +Порто Рико pr +Пуерто Рико pr +ਰੂਇਰਟੂ ਰੀਕੋ pr +Porto Rico pr +Porto Rico pr +ПуÑрто-Рико pr +Porito Riko pr +Portoriko pr +Порторико pr +Portoriko pr +பà¯à®¯à¯à®°à¯à®Ÿà¯‹ ரிகோ pr +Пурто Рико pr +เปà¸à¸£à¹Œà¹‚ตริโภpr +Porta Riko pr +Puerto Riko pr +Пуерто-Ріко pr +ПуÑрто-Рико pr +Porto Rico pr +æ³¢å¤šé»Žå„ pr +æ³¢å¤šé»Žå„ pr +Palestinian Territory ps +Palesteinse Gebied ps +السلطة الÙلسطينية ps +FÉ™lÉ™stin SahÉ™si ps +ПалеÑтынÑÐºÐ°Ñ Ñ‚ÑÑ€Ñ‹Ñ‚Ð¾Ñ€Ñ‹Ñ ps +ПалеÑтина ps +পà§à¦¯à¦¾à¦²à§‡à¦¸à§à¦Ÿà¦¿à¦¨à¦¿à§Ÿà¦¾à¦¨ টেরিটরি ps +Palestinska teritorija ps +Territori Palestà ps +Palestinské územà ps +Tiriogaeth Palesteina ps +Palæstinensiske selvstyreomrÃ¥der ps +Palästinensisches Gebiet ps +Παλαιστίνη ps +Palestina Teritorio ps +Territorio palestino ps +Palestiina ps +Palestina ps +Ùلسطین ps +Palestiinalaisalue ps +Palestinensiska økið ps +Territoire palestinien ps +Palestijnsk territorium ps +CrÃoch na bPalaistÃneach ps +Território Palestino ps +×”×©×˜×—×™× ×”×¤×œ×¡×˜×™× ×™×™× ps +फिलीसà¥à¤¤à¥€à¤¨à¥€ टेरिटरी ps +Palestinski teritorij ps +Palesztin területek ps +PalestÃna ps +Palestina ps +パレスãƒãƒŠè‡ªæ²»åŒº ps +ប៉ាលáŸážŸáŸ’ទីន ps +íŒ”ë ˆìŠ¤íƒ€ì¸ ìžì¹˜êµ¬ ps +àºàº²àº™àºžàº´àº¡àºœàº´àº”ພາດ ps +Palestinos teritorija ps +PalestÄ«nieÅ¡u treitorija ps +ПалеÑтинÑки територии ps +ПалеÑтины газар нутаг ps +Palestina ps +Palestinske territorier ps +De palästinensche sülvenregeerte Regioon ps +Palestijns territorium ps +Palestinske territorium ps +Bohwa bja Palestina ps +ਫਲਾਸਤੀਨ ਖੇਤਰ ps +Palestyna ps +Território Palestiniano ps +Território Palestino ps +Teritoriul Palestinian ps +ПалеÑтинÑкие территории ps +Igihugu cya Palesitina ps +PalestiinnalaÅ¡ territoria ps +PalestÃnske územia ps +Palestinski teritorij ps +ПалеÑтина ps +Palestina ps +I-Palestinian Territory ps +Palestina ps +பாலஸà¯à®¤à¯€à®© ஆணையம௠ps +ФалаÑтин ps +เขตปà¸à¸„รà¸à¸‡à¸›à¸²à¹€à¸¥à¸ªà¹„ตน์ ps +Filistin Bölgesi ps +Fälestin ps +ПалеÑтинÑька Ñ‚ÐµÑ€Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ ps +ФалаÑтин Ерлари ps +Mukano wa maphalesitina ps +Lãnh thổ của Palestine ps +Palestene ps +Umhlaba wePalestina ps +å·´å‹’æ–¯å¦åœ°åŒº ps +å·´å‹’æ–¯å¦é ˜åœ° ps +Indawo yama-Phalesitina ps +Portugal pt +البرتغال pt +Portuqaliya pt +ÐŸÐ°Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt +ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt +পোরà§à¦¤à§à¦—াল pt +Portugalsko pt +Portiwgal pt +ΠοÏτογαλία pt +Portugalo pt +پرتغال pt +Portugali pt +An Phortaingéil pt +פורטוגל pt +पà¥à¤°à¥à¤¤à¤—ाल pt +Portugália pt +Portúgal pt +Portogallo pt +ãƒãƒ«ãƒˆã‚¬ãƒ« pt +áž–áŸážšáž‘ុយហ្គាល់ pt +í¬ë¥´íˆ¬ê°ˆ pt +ໂປຣຕຸເàºàºª pt +Portugalija pt +PortugÄle pt +Португалија pt +Португал pt +Portugall pt +ਪà©à¨°à¨¤à¨—ਾਲ pt +Portugalia pt +Portugalia pt +ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt +Poritigali pt +Portugalsko pt +Portugalska pt +Португал pt +I-Portugal pt +போரà¯à®¤à¯à®¤à¯à®•à®²à¯ pt +Пуртуқол pt +โปรตุเà¸à¸ª pt +Portekiz pt +Portugalia pt +ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt +ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt +Bồ Äà o Nha pt +è‘¡è„牙 pt +è‘¡è„牙 pt +Palau pw +بالاو pw +Палау pw +Палау pw +পালাউ pw +Palaw pw +Παλάου pw +Palao pw +پالائو pw +פל×ו pw +पलाऊ pw +Palá pw +パラオ pw +ប៉ាឡូ pw +팔ë¼ìš° pw +ມàºàº¥àº•àº² pw +Палау pw +Палау pw +ਪਾਲਾਉ pw +Палау pw +Palawu pw +Палау pw +பலாவ௠pw +Палау pw +เà¸à¸²à¸°à¸žà¸²à¹€à¸¥à¸² pw +Палау pw +Палау pw +Palawou pw +帕劳 pw +å¸›ç‰ pw +Paraguay py +Paraguaai py +باراغواي py +Paraqvay py +Парагвай py +Парагвай py +পà§à¦¯à¦¾à¦°à¦¾à¦—à§à§Ÿà§‡ py +Paragwae py +Paragvaj py +Paraguai py +Paragw?i py +ΠαÏαγουάη py +Paragvajo py +Paraguai py +پاراگویه py +Paragua py +Paraguai py +פרגו××™ py +पैरागà¥à¤ py +Paragvaj py +Paragvæ py +パラグアイ py +ប៉ារ៉ាហ្គាយ py +파ë¼ê³¼ì´ py +ປາລາàºàºàº§àº py +Paragvajus py +Paragvaja py +Парагвај py +Парагвай py +Paragwaj py +Paraguai py +ਪਾਰਾਗà©à¨† py +Paragwaj py +Paraguai py +Paraguai py +Paraguai py +Парагвай py +Paragwe py +Portugalsko py +Paragvaj py +Парагвај py +Paragvaj py +I-Paraguay py +பராகà¯à®µà¯‡ py +Порогвие py +ปาราà¸à¸§à¸±à¸¢ py +Парагвай py +Парагвай py +Paragway py +å·´æ‹‰åœ py +å·´æ‹‰åœ py +Qatar qa +قطر qa +Катар qa +Катар qa +কাতার qa +Kwatar qa +Katar qa +Katar qa +Catar qa +Katar qa +ÎšÎ±Ï„Î¬Ï qa +Kataro qa +Katar qa +قطر qa +Katar qa +Catar qa +קטר qa +क़तर qa +Katar qa +Katar qa +Katar qa +カタール qa +កាážáž¶ážš qa +카타르 qa +ມàºàº¥àº•àº² qa +Kataras qa +Katara qa +Катар qa +Катар qa +Katar qa +ਕਤਰ qa +Katar qa +Катар qa +Katari qa +Katar qa +Katar qa +Катар qa +Katar qa +I-Qatar qa +கதார௠qa +Қатар qa +ควาตาร์ qa +Katar qa +Катар qa +Қатар qa +Katar qa +å¡å¡”å°” qa +å¡é” qa +Romania ro +Romenië ro +رومانيا ro +Rumıniya ro +Ð ÑƒÐ¼Ñ‹Ð½Ñ–Ñ ro +Ð ÑƒÐ¼ÑŠÐ½Ð¸Ñ ro +রà§à¦®à§‡à¦¨à¦¿à§Ÿà¦¾ ro +Roumani 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 +Roemenië ro +An Rómáin ro +Románia ro +×¨×•×ž× ×™×” ro +रोमानिया ro +Rumunjska ro +Románia ro +Rumania ro +RúmenÃa ro +ルーマニア ro +រូម៉ានី ro +루마니아 ro +ໂລມາເນີຠro +Rumunija ro +RumÄnija ro +Романија ro +Румын ro +Rumanija ro +Rumänien ro +Roemenië ro +ਰੋਮਾਨੀਆ ro +Rumunia ro +Roménia ro +Romênia ro +România ro +Ð ÑƒÐ¼Ñ‹Ð½Ð¸Ñ ro +Romaniya ro +Románia ro +Rumunsko ro +Romunija ro +Румунија ro +Rumunija ro +I-Romania ro +Rumänien ro +à®°à¯à®®à¯‡à®©à®¿à®¯à®¾ ro +Ð ÑƒÐ¼Ð¸Ð½Ð¸Ñ ro +โรมาเนีย ro +Romanya ro +Ð ÑƒÐ¼ÑƒÐ½Ñ–Ñ ro +Ð ÑƒÐ¼Ð¸Ð½Ð¸Ñ ro +Roumaneye ro +罗马尼亚 ro +羅馬尼亞 ro +Russia ru +Rusland ru +روسيا ru +Rusiya ru +РаÑÐµÑ ru +РуÑÐ¸Ñ ru +রাশিয়া ru +Rusia ru +Rusija ru +Rússia ru +Rusko ru +Rwsia ru +Rusland ru +Russland ru +Ρωσία ru +Ruslando ru +Rusia ru +Venemaa ru +Errusia ru +روسیه ru +Venäjä ru +Russland ru +Russie ru +Rusland ru +An Rúis ru +Rúsia ru +רוסיה ru +रà¥à¤¸ ru +Rusija ru +Oroszország ru +Rusia ru +Rússland ru +ãƒã‚·ã‚¢ ru +រូស្ស៊ី ru +러시아 ru +ລັດເຊີຠru +Rusija ru +Krievija ru +РуÑија ru +ÐžÑ€Ð¾Ñ ru +Russja ru +Russland ru +Russland ru +Rusland ru +Russland ru +ਰੂਸ ru +Rosja ru +Rússia ru +Rússia ru +Rusia ru +РоÑÑÐ¸Ñ ru +Uburusiya ru +RuoÅ¡Å¡a ru +Rusko ru +Rusija ru +РуÑија ru +Rusija ru +I-Russia ru +Ryssland ru +ரசியா ru +РуÑÑÐ¸Ñ ru +รัสเซีย ru +Rusya ru +Urısia, Räsäy ru +РоÑÑ–Ñ ru +РоÑÑÐ¸Ñ ru +Rashia ru +Nga ru +Rûsseye ru +Rashiya ru +ä¿„ç½—æ–¯ ru +ä¿„ç¾…æ–¯ ru +Rwanda rw +رواندا rw +Ruanda rw +Руанда rw +Руанда rw +রোয়ানà§à¦¡à¦¾ rw +Ruanda rw +Ruanda rw +Ruanda rw +Ρουάντα rw +Ruando rw +Ruanda rw +رواندا rw +Ruanda rw +Ruanda rw +Ruanda rw +רו×× ×“×” rw +रवांडा rw +Ruanda rw +Ruanda rw +Rúanda rw +Ruanda rw +ルワンダ rw +រវ៉ាន់ដា rw +르완다 rw +à»àºžàº™àº”້າ rw +Ruanda rw +Ruanda rw +Руанда rw +Рванда rw +Ruanda rw +ਰਵਾਂਡਾ rw +Ruanda rw +Ruanda rw +Ruanda rw +Ruanda rw +Руанда rw +Ruanda rw +Руанда rw +Ruanda rw +வானà¯à®Ÿà®¾ rw +Руондо rw +รวันด้า rw +Ruanda rw +Руанда rw +Рванда rw +å¢æ—ºè¾¾ rw +ç›§å®‰é” rw +Saudi Arabia sa +Saudi Arabië sa +السعودية sa +SÉ™udi ÆrÉ™bistan sa +СаудаўÑÐºÐ°Ñ ÐÑ€Ð°Ð±Ñ–Ñ sa +СаудитÑка ÐÑ€Ð°Ð±Ð¸Ñ sa +সৌদি আরব sa +Arabi Saudiet sa +Saudijska Arabija sa +Arà bia Saurà sa +Saúdská Arábie sa +Sawdi Arabia sa +Saudi Arabien sa +Saudi-Arabien sa +Σαουδική ΑÏαβία sa +SaÅda Arabio sa +Arabia Saudà sa +Saudi Araabia sa +عربستان سعودی sa +Saudi-Arabia sa +Arabie Saoudite sa +Saudi-Arabië sa +An Araib Shádach sa +Arabia Saudita sa +ערב הסעודית sa +सऊदी अरब sa +Saudijska Arabija sa +Szaúd-Arábia sa +Sádi-ArabÃa sa +Arabia Saudita sa +サウジアラビア sa +អារ៉ាប៊ីសាអ៊ូឌីហsa +사우디 ì•„ë¼ë¹„ì•„ sa +àºàº²àº¥àº°àºšàº´àº sa +Saudo Arabija sa +SaÅ«da ArÄbija sa +СаудиÑка Ðрабија sa +Саудын араб sa +Għarabja Sawdita sa +Saudi-Arabia sa +Saudi Arabien sa +Saudi-Arabië sa +Saudi-Arabia sa +ਸਾਊਦੀ ਅਰਬ sa +Arabia Saudyjska sa +Arábia Saudita sa +Arábia Saudita sa +Arabia Saudită sa +СаудовÑÐºÐ°Ñ ÐÑ€Ð°Ð²Ð¸Ñ sa +Arabiya Sawudite sa +Saudi Arábia sa +Saudská arábia sa +Saudova Arabija sa +СаудијÑка Ðрабија sa +Saudijska Arabija sa +I-Saudi Arabia sa +Saudiarabien sa +சவà¯à®¤à®¿ அரேபியா sa +ÐрабиÑтони Саудӣ sa +ซาà¸à¸¸à¸”ิà¸à¸²à¸£à¸°à¹€à¸šà¸µà¸¢ sa +Suudi Arabistan sa +Söğüd Ğäräbstan sa +СаудівÑька ÐÑ€Ð°Ð²Ñ–Ñ sa +Ð¡Ð°ÑƒÐ´Ð¸Ñ ÐрабиÑтони sa +Ẩráºp Saudi sa +Arabeye Sawoudite sa +沙特阿拉伯 sa +æ²™çƒåœ°é˜¿æ‹‰ä¼¯ sa +Solomon Islands sb +Solomon Eilande sb +جزر سليمان sb +Solomon Adaları sb +Саламонавы аÑтравы sb +Соломонови оÑтрови sb +সলোমন দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ sb +Inizi Salaun sb +Solomonska ostrva sb +Illes Solomon sb +Å alamounovy ostrovy sb +Ynysoedd Solomon sb +Salomon-øerne sb +Salomon-Inseln sb +Îήσοι Σολομώντος sb +Salomonoj sb +Islas Salomón sb +Saalomoni saared sb +Solomon Irlak sb +جزایر سلیمان sb +Solomon-saaret sb +ÃŽles Salomon sb +Solomon Eilannen sb +Oileáin Sholamón sb +Illas Salomón sb +××™×™ שלמה sb +सोलोमन आइलैंड sb +Solomonova otoÄja sb +Salamon-szigetek sb +Salómonseyjar sb +Isole Salomone sb +ソãƒãƒ¢ãƒ³è«¸å³¶ sb +កោះ​សូឡូម៉ូន sb +솔로몬 ì œë„ sb +ສະໂລວະເນີຠsb +Saliamono salos sb +Solomonu salas sb +СоломонÑки ОÑтрови sb +Соломоны арлууд sb +Gżejjer Solomon sb +Salomonøyene sb +Salomonen sb +Solomon Eilanden sb +Salomonøyane sb +ਸੋਲੋਮੋਨ ਆਈਸਲੈਂਡ sb +Wyspy Salomona sb +Ilhas Salomão sb +Ilhas Salomão sb +Insulele Solomon sb +Соломоновы оÑтрова sb +Ibirwa bya Salomo sb +Salomonsullot sb +Å alamúnove ostrovy sb +Solomonovi otoki sb +Соломонова оÑтрва sb +Solomonova ostrva sb +Salomonöarna sb +சாலமன௠தீவà¯à®•à®³à¯ sb +Ҷазираи Сулаймон sb +หมู่เà¸à¸²à¸°à¹‚ซโลมà¸à¸™ sb +Solomon Adaları sb +Solomon Utrawları sb +Соломонові оÑтрови sb +Соломон Ороллари sb +Quần đảo Solomon sb +Iyes Salomon sb +所罗门群岛 sb +索羅門群島 sb +Seychelles sc +سيشل sc +СÑйшÑлы sc +СейшелÑки оÑтрови sc +সীচিলিস sc +Sechell sc +SejÅ¡eli sc +Ynysoedd y Seisi?l sc +Seychellerne sc +Seychellen sc +ΣεϋχÎλλες sc +SejÅeloj sc +SeiÅ¡ellid sc +سیشل sc +Seychellit sc +Seychellen sc +Na Séiséil sc +Seicheles sc +××™×™ סיישל sc +शेसेलà¥à¤¸ sc +SejÅ¡eli sc +Seychelles-eyjar sc +セイシェル sc +សីស្ហែល sc +세ì´ì…¸ sc +ເຊລ sc +SeiÅ¡eļu salas sc +Сејшели sc +Ð¡ÐµÐ¹Ñ‡ÐµÐ»Ð»Ð¸Ñ sc +Seychellene sc +Seychellen sc +Seychellen sc +Seychellane sc +ਸੀਲਚੀਲੀਸ sc +Seszele sc +Ilhas Seychelles sc +СейшельÑкие оÑтрова sc +Seyishele sc +SeyÅ¡ellat sc +SejÅ¡eli sc +Сејшели sc +SejÅ¡eli sc +Seychellerna sc +சேசெலà¯à®²à®¸à¯ sc +Сейшелӣ sc +ซีเชลล์ sc +SeyÅŸeller sc +SeyÅŸellär sc +СейшельÑькі оÑтрови sc +Сейшел Ороллари sc +Seycheles sc +塞舌尔 sc +å¡žå¸çˆ¾ sc +Sudan sd +السودان sd +Судан sd +Судан sd +সà§à¦¦à¦¾à¦¨ sd +Sondan sd +Sudán sd +Swdan sd +Σουδάν sd +Sudano sd +Sudán sd +Sudaan sd +سودان sd +Sudania sd +Soudan sd +An tSúdáin sd +Sudán sd +סודן sd +सूडान sd +Szudán sd +Súdan sd +スーダン sd +ស៊ូដង់ sd +수단 sd +ຊູດານ sd +Sudanas sd +SudÄna sd +Судан sd +Судан sd +ਸੂਡਾਨ sd +Sudão sd +Sudão sd +Судан sd +Sudani sd +Sudán sd +Судан sd +I-Sudan sd +சூடான௠sd +Судон sd +ซูดาน sd +Судан sd +Судан sd +Sudani sd +Soudan sd +è‹ä¸¹ sd +蘇丹 sd +Sweden se +Swede se +السويد se +Ä°sveç se +ШвÑÑ†Ñ‹Ñ se +Ð¨Ð²ÐµÑ†Ð¸Ñ se +সà§à¦‡à¦¡à§‡à¦¨ 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 +Zweden se +An tSualainn se +Suécia se +שבדיה se +सà¥à¤µà¥€à¤¡à¤¨ se +Å vedska se +Svédország se +Swedia se +SvÃþjóð se +Svezia se +スウェーデン se +ស៊ុយអែដ se +ìŠ¤ì›¨ë´ se +ສະວີເດນ se +Å vedija se +Zviedrija se +ШведÑка se +Швед se +Svezja se +Sverige se +Zweden se +Sverige se +Suècia se +ਸਵੀਡਨ se +Szwecja se +Suécia se +Suécia se +Suedia se +Ð¨Ð²ÐµÑ†Ð¸Ñ se +Suwede se +Ruoŧŧa se +Å védsko se +Å vedska se +ШведÑка se +Å vedska se +I-Sweden se +Sverige se +சà¯à®µà¯€à®Ÿà®©à¯ se +Шведӣ se +สวีเดน se +Ä°sveç se +Ä°swäc, Åžwedsia se +Ð¨Ð²ÐµÑ†Ñ–Ñ se +Ð¨Ð²ÐµÑ†Ð¸Ñ se +Swidene se +Thuỵ Äiển se +Suwede se +ç‘žå…¸ se +ç‘žå…¸ se +Singapore sg +سنغاÙورة sg +Sinqapur sg +Сынгапур sg +Сингапур sg +সিঙà§à¦—াপà§à¦° sg +Singapour sg +Singapur sg +Singapur sg +Singapur sg +Singap?r sg +Singapur sg +ΣινγκαποÏÏη sg +Singapuro sg +Singapur sg +Singapur sg +سنگاپور sg +Singapour sg +Singeapór sg +Singapur sg +×¡×™× ×’×¤×•×¨ sg +सिंगापोर sg +Singapur sg +Szingapúr sg +Singapúr sg +シンガãƒãƒ¼ãƒ« sg +សិង្ហបុរី sg +싱가í¬ë¥´ sg +ໂຊນາ sg +SingapÅ«ras sg +SingapÅ«ra sg +Сингапур sg +Сингафур sg +Singapura sg +Singapor sg +Singapur sg +ਸਿੰਘਾਪà©à¨° sg +Singapur sg +Singapura sg +Singapura sg +Сингапур sg +Singapur sg +Singapur sg +Сингапур sg +Singapur sg +சிஙà¯à®•à®ªà¯à®ªà¯‚ர௠sg +Сингопур sg +สิงคโปร์ sg +Singapur sg +Singapur sg +Сінгапур sg +Сингапур sg +Singapour sg +æ–°åŠ å¡ sg +æ–°åŠ å¡ sg +Saint Helena sh +St Helena sh +سانت هيلانة sh +ВоÑтраў СьвÑтой Ðлены sh +Св. Елена sh +সেনà§à¦Ÿ হেলেনা sh +Sant Lena sh +Sveta Helena sh +Santa Helena sh +Svatá Helena sh +Ynys Santes Helena sh +St. Helena sh +St. Helena sh +Αγία ΕλÎνη sh +Sent-Heleno sh +Santa Helena sh +سنت هلن sh +Sainte-Hélène sh +Sint Helena sh +San Héilin sh +Santa Helena sh +סט. ×”×œ× ×” sh +सेंट हेलेना sh +Sveta Helena sh +Szent Heléna sh +Sankti Helena sh +Sant'Elena sh +è‹±é ˜ã‚»ãƒ³ãƒˆãƒ˜ãƒ¬ãƒŠå³¶ sh +សង់ហáŸáž¡áŸážŽáž¶ sh +세ì¸íŠ¸í—¬ë ˆë‚˜ sh +ຫົວເລື່àºàº‡ sh +Å v. Elenos sala sh +Sv. HelÄ“nas sala sh +Света Елена sh +Сайнт Хелена sh +St. Helena sh +Sankt Helena sh +St. Helena sh +ਸੇਂਟ ਹੀਲੀਨਆ sh +ÅšwiÄ™ta Helena sh +Santa Helena sh +Santa Helena sh +Sfînta Elena sh +оÑтров СвÑтой Елены sh +Mutagatifu Helena sh +St. Helena sh +Svätá Helena sh +Sveta Helena sh +Света Јелена sh +Sveta Jelena sh +செயினà¯à®Ÿà¯ ஹேலேனா sh +Синт Ҳилин sh +เซนต์เฮเลน่า sh +ОÑтрів СвÑтої Єлени sh +Ðвлиё Елена Ороли sh +Sint Elene sh +圣赫勒拿 sh +è–赫勒拿島 sh +Slovenia si +Slovenië si +سلوÙينيا si +Sloveniya si +Ð¡Ð»Ð°Ð²ÐµÐ½Ñ–Ñ si +Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si +সà§à¦²à§‹à¦à§‡à¦¨à¦¿à§Ÿà¦¾ si +Sloveni si +Slovenija si +Eslovènia si +Slovinsko si +Slofenia si +Slovenien si +Slowenien si +Σλοβενία si +Slovenio si +Eslovenia si +Sloveenia si +Eslovenia si +اسلوانی si +Slovénie si +Slowenië si +An tSlóivéin si +Eslovénia si +×¡×œ×•×‘× ×™×” si +सà¥à¤²à¥‹à¤µà¥‡à¤¨à¤¿à¤¯à¤¾ si +Slovenija si +Szlovénia si +SlóvenÃa si +スãƒãƒ™ãƒ‹ã‚¢ si +ស្លូវ៉ានី si +ìŠ¬ë¡œë² ë‹ˆì•„ si +ສະໂລວະເນີຠsi +SlovÄ—nija si +SlovÄ“nija si +Словенија si +Слован si +Slovenja si +Slowenien si +Slowenië si +Eslovenia si +ਸਲੋਵੀਨੀਆ si +SÅ‚owenia si +Eslovénia si +Eslovênia si +Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si +Siloveniya si +Slovinsko si +Slovenija si +Словенија si +Slovenija si +I-Slovenia si +Slovenien si +சà¯à®²à¯‹à®µà®¿à®©à®¿à®¯à®¾ si +УÑлувонӣ si +สโลเวเนีย si +Slovenya si +Ð¡Ð»Ð¾Ð²ÐµÐ½Ñ–Ñ si +Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si +Esloveneye si +斯洛文尼亚 si +斯洛ç¶å°¼äºž si +Slovakia sk +Slovakië sk +سلوÙاكيا sk +Slovakiya sk +Ð¡Ð»Ð°Ð²Ð°ÐºÑ–Ñ sk +Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk +সà§à¦²à§‹à¦à¦¾à¦•à¦¿à§Ÿà¦¾ sk +Slovaki sk +SlovaÄka sk +Eslovà quia sk +Slovensko sk +Slofacia sk +Slovakiet sk +Slowakien sk +Σλοβακία sk +Slovakujo sk +Eslovaquia sk +Slovakkia sk +Eslovakia sk +اسلواکی sk +Slovaquie sk +Slowakije sk +An tSlóvaic sk +Eslováquia sk +סלובקיה sk +सà¥à¤²à¥‹à¤µà¤¾à¤•à¤¿à¤¯à¤¾ sk +SlovaÄka sk +Szlovákia sk +SlóvakÃa sk +Slovacchia sk +スãƒãƒã‚ã‚¢ sk +ស្លូវ៉ាគី sk +슬로바키아 sk +ສະໂລວັຠsk +Slovakija sk +SlovÄkija sk +Словачка sk +Словак sk +Slovakja sk +Slowakei sk +Slowakije sk +ਸਲੋਵਾਕਿਆ sk +SÅ‚owacja sk +Eslováquia sk +Eslováquia sk +Slovacia sk +Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk +Silovakiya sk +Slovákia sk +Slovensko sk +SlovaÅ¡ka sk +Словачка sk +SlovaÄka sk +I-Slovakia sk +Slovakien sk +சà¯à®²à¯‹à®µà®¾à®•à¯à®•à®¿à®¯ sk +УÑлувок sk +สโลวาเà¸à¸µà¸¢ sk +Slovakya sk +Ð¡Ð»Ð¾Ð²Ð°ÐºÑ–Ñ sk +Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk +Eslovakeye sk +斯洛ä¼å…‹ sk +斯洛ä¼å…‹ sk +San Marino sm +سان مارينو sm +Сан-Марына sm +Сан Марино sm +সান মারিনো sm +Σαν ΜαÏίνο sm +San-Marino sm +سن‌مارینو sm +Saint-Marin sm +San MairÃne sm +סן ×ž×¨×™× ×• sm +सेन मेरिनो sm +San MarÃnó sm +サンマリノ sm +សាន់ម៉ារីណូ sm +산마리노 sm +ໂຊນາ sm +San Marinas sm +SanmarÄ«no sm +Сан Марино sm +Сан Марино sm +ਸਨ ਮਰੀਨੋ sm +São Marino sm +Сан-Марино sm +Mutagatifu Marini sm +Сан Марино sm +சான௠மரினோ sm +Сан Морину sm +ซานมาริโน sm +Сан-Маріно sm +Сан-Марино sm +Sint Marin sm +圣马力诺 sm +è–馬力諾 sm +Senegal sn +السنغال sn +Seneqal sn +СÑнÑгал sn +Сенегал sn +সেনেগল sn +Σενεγάλη sn +Senegalo sn +سنگال sn +Senegali sn +Sénégal sn +An tSeineagáil sn +×¡× ×’×œ sn +सेनेगल sn +Szenegál sn +ã‚»ãƒã‚¬ãƒ« sn +សáŸáž“áŸáž ្គាល់ sn +세네갈 sn +ທົ່ວໄປ sn +Senegalas sn +SenegÄla sn +Сенегал sn +Сенегал sn +Senegall sn +ਸੈਨੇਗਾਲ sn +Сенегал sn +Senegali sn +Сенегал sn +சீனேகல௠sn +Синегол sn +เซนีà¸à¸±à¸¥ sn +Сенегал sn +Сенегал sn +SenegÃ¥l sn +å¡žå†…åŠ å°” sn +å¡žå…§åŠ çˆ¾ sn +Somalia so +Somalië so +صومال so +Somali so +Самалі so +Ð¡Ð¾Ð¼Ð°Ð»Ð¸Ñ so +সোমালিয়া so +Somali so +Somalija so +Somà lia so +Somálsko so +Σομαλία so +Somalio so +Somaalia so +سومالی so +Somalie so +Somalie so +An tSomáil so +Somália so +סומליה so +सोमालिया so +Somalija so +Szomália so +SómalÃa so +ソマリア so +សូម៉ាលី so +소ë§ë¦¬ì•„ so +ໂລມາເນີຠso +Somalis so +SomÄlija so +Сомалија so +Сомали so +Somalija so +Somalien so +Somalie so +ਸੋਮਾਲੀਆ so +Somália so +Somália so +Сомали so +Somaliya so +Somália so +Somálsko so +Somalija so +Сомалија so +Somalija so +I-Somalia so +சோமாலியா so +Сумалӣ so +โซมาเลีย so +Somali so +Сомалі so +Сомали so +Somaleye so +索马里 so +索馬利亞 so +Suriname sr +سورينام sr +Surinam sr +Сурынам sr +Суринам sr +সà§à¦°à¦¿à¦¨à¦¾à¦® sr +Surinam sr +Surinam sr +Surinam sr +Swrinam sr +Surinam sr +ΣουÏινάμ sr +Surinamo sr +Surinam sr +Surinam sr +سورینام sr +Surinam sr +Suranam sr +×¡×•×¨×™× ×× sr +सूरीनाम sr +Surinam sr +SúrÃnam sr +スリナムsr +ស៊ូរីណាមី sr +수리남 sr +ເຊີເບີຠsr +Surinamas sr +Surinama sr +Суринам sr +Суринам sr +Surinam sr +Surinam sr +Surinam sr +Surinam sr +ਸੂਰੀਨਾਮੀ sr +Surinam sr +Surinam sr +Суринам sr +Surinamu sr +Surinam sr +Surinam sr +Surinam sr +Суринам sr +Surinam sr +Surinam sr +சà¯à®°à®¿à®¨à¯‡à®®à¯ sr +Суринам sr +ซูรีนามิ sr +Surinam sr +Surinam sr +Сурінам sr +Суринам sr +è‹é‡Œå— sr +è˜‡åˆ©å— sr +Sao Tome and Principe st +Sao Tome en Principe st +ساو تومي Ùˆ البرنسيب st +Sao Tome vÉ™ Principe st +Сан-Ð¢Ð°Ð¼Ñ Ñ– ПрынÑіпі st +Сао Томе и ПринÑипи st +সাও টোম à¦à¦¬à¦‚ পà§à¦°à¦¿à¦¨à§à¦¸à¦¿à¦ª st +Sao Tome ha Principe st +Sao Tome i Principe st +Sao Tome i Principe st +Sao Tome a Principe st +Ynysoedd Sao Tome a Principe st +Sao Tomé og Principe st +Sao Tome und Principe st +Σάο ΤομΠκαι Î Ïίνσιπε st +Sao-Tomeo kaj Principeo st +Sao Tome y PrÃncipe st +Sao Tome ja Principe st +Sao Tome eta Principe st +سائوتومه Ùˆ پرینسیپه st +São Tomé ja PrÃncipe st +Sao Tomé et Principe st +Sao Tome en Principe st +São Tomé agus PrÃncipe st +Santo Tomé e PrÃncipe st +साओ टोम तथा पà¥à¤°à¤¿à¤‚सिपी st +Sv. Toma i Princip st +Sao Tome és Principe st +Saó Tóme og PrinsÃpe st +São Tomé e PrÃncipe st +サントメプリンシペ st +ìƒíˆ¬ë©” 프린시페 st +ບà»àº¥àº´àºàº²àº™ st +Santome un Prinsipi st +Сао Томе и ПринÑипе st +Сао Ð¢Ð¾Ð¼Ñ Ð±Ð° Принцип st +Sao Tome u Principe st +São Tomé og PrÃncipe st +São Tomé un PrÃncipe st +Sao Tome en Principe st +São Tomé og PrÃncipe st +ਸਾਓ ਟੋਮੀ ਤੇ ਪਰੀਸਿਪੀ st +Sao Tome i Principe st +São Tomé and PrÃncipe st +São Tome e PrÃncipe st +Sao Tome ÅŸi Principe st +Сан-Томе и ПринÑипи st +Sawo Tome na Purencipe st +São Tomé ja PrÃncipe st +Sao Tome a Principe st +Sao Tome in Principe st +Св. Тома и Принцип st +Sv. Toma i Princip st +São Tomé och PrÃncipe st +சயோ டோம௠மறà¯à®±à¯à®®à¯ பிரினà¯à®¸à®¿à®ªà®¿ st +Синт Том ва ПринÑип st +ซาวโทม à¹à¸¥à¸° พรินซิป st +Sao Tome ve Principe st +Sao Tome wä Principe st +Сан-Томе Ñ– ПрінÑіпі st +Сан-Томе ва ПринÑипи st +São Tomé et Prince st +圣多美和普林西比 st +è–多美åŠæ™®æž—西比 st +El Salvador sv +السلÙادور sv +Сальвадор sv +Салвадор sv +à¦à¦² সালà¦à¦¾à¦¡à§‹à¦° sv +Ar Salvador sv +Salvador sv +El Salfador sv +Ελ Î£Î±Î»Î²Î±Î½Ï„ÏŒÏ sv +Salvadoro sv +Salvador sv +السالوادور sv +Salvador sv +An tSalvadóir sv +O Salvador sv +×ל סלבדור sv +अल सलà¥à¤µà¤¾à¤¡à¥‹à¤° sv +Salvador sv +エルサルãƒãƒ‰ãƒ« sv +អែលសាល់វ៉ាឌáŸážš sv +엘살바ë„르 sv +ເàºàº¥àºŠàº±àº™àº§àº²àº”ດ໠sv +Salvadoras sv +Salvadora sv +Ел Салвадор sv +Ðл Салвадор sv +ਈਲ ਸਾਲਵੇਡੋਰ sv +Salwador sv +Salvador sv +Сальвадор sv +Eli Salivadoro sv +Salvádor sv +Salvador sv +Ел Салвадор sv +I-El Salvador sv +எல௠சாலà¯à®µà®Ÿà¯‹ ர௠sv +Ðл Салвадур sv +เà¸à¸¥à¸‹à¸±à¸¥à¸§à¸²à¸”à¸à¸£à¹Œ sv +Ель-Сальвадор sv +Салвадор sv +è¨å°”瓦多 sv +薩爾瓦多 sv +Syria sy +Sirië sy +سوريا sy +SuriyÉ™ sy +Ð¡Ñ‹Ñ€Ñ‹Ñ sy +Ð¡Ð¸Ñ€Ð¸Ñ sy +সিরিয়া sy +Siri 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 +Syrië sy +An tSiria sy +SÃria sy +סוריה sy +सीरिया sy +Sirija sy +SzÃria sy +Sýrland sy +Siria sy +シリア sy +ស៊ីរី sy +시리아 sy +ເຊີເບີຠsy +Sirija sy +SÄ«rija sy +Сирија sy +Сири sy +Siria sy +Syrien sy +Syrië sy +ਸੀਰੀਆ sy +SÃria sy +SÃria sy +Siria sy +Ð¡Ð¸Ñ€Ð¸Ñ sy +Siriya sy +Sýria sy +Sirija sy +Сирија sy +Sirija sy +I-Syria sy +Syrien sy +சிரியா sy +Ð¡ÑƒÑ€Ð¸Ñ sy +ซีเรีย sy +Suriye sy +Süriä sy +Ð¡Ð¸Ñ€Ñ–Ñ sy +Ð¡ÑƒÑ€Ð¸Ñ sy +Sireye sy +å™åˆ©äºš sy +敘利亞 sy +Swaziland sz +Swasiland sz +سوازيلاند sz +Svaziland sz +СвазылÑнд sz +Свазиленд sz +সোয়াজিলà§à¦¯à¦¾à¦£à§à¦¡ sz +Svazilend sz +Neozelà ndia sz +Gwlad y Swasi sz +Swasiland sz +Σουαζιλάνδη sz +Svazilando sz +Swazilandia sz +Svaasimaa sz +Swazilandia sz +سووازیلند sz +Swazimaa sz +An tSuasalainn sz +Suacilándia sz +סוו××–×™×œ× ×“ sz +सà¥à¤µà¤¾à¤œà¥€à¤²à¥ˆà¤‚ड sz +Svazilend sz +Szváziföld sz +SvasÃland sz +スワジランド sz +ស្វាហ្ស៊ីឡង់ sz +스와질란드 sz +ລາດສະນາຈັàºà»„ທຠsz +Svazilenda sz +Свазиленд sz +Свациланд sz +Sważilandja sz +Swasiland sz +ਸਵਾਜ਼ੀਲੈਂਡ sz +Suazi sz +Suazilândia sz +Suazilândia sz +Suaziland sz +Свазиленд sz +Swazilande sz +Swazijsko sz +Svazi sz +Свазиленд sz +Svazilend sz +ஸà¯à®µà®¾à®šà®¿à®²à®¾à®©à¯à®Ÿà¯ sz +Свозиланд sz +สวาซิà¹à¸¥à¸™à¸”์ sz +Свазіленд sz +Свазиленд sz +Suwazilande sz +æ–¯å¨å£«å…° sz +å²ç“¦æ¿Ÿè˜ sz +Turks and Caicos Islands tc +Turks en Caicos Eilande tc +جزر الترك Ùˆ الكايكوس tc +Türk vÉ™ Caicos Adaları tc +ÐÑтравы ТÑÑ€ÐºÑ Ñ– ÐšÐ°Ð¹ÐºÐ°Ñ tc +ОÑтрови Ð¢ÑŠÑ€ÐºÑ Ð¸ ÐšÐ°Ð¹ÐºÐ¾Ñ tc +টারà§à¦•à¦¸ à¦à¦¬à¦‚ কাইকোস দà§à¦¬à§€à¦ªà¦ªà§à¦žà§à¦œ tc +Inizi Turks ha Kaikos tc +Turks i Kaikos ostrva tc +Illes Turks i Caicos tc +Turks a Caicos ostrovy tc +Ynysoedd Twrc a Chaicos tc +Turks- og Caicosøerne tc +Turks- und Caicos-Inseln tc +Îήσοι ΤεÏκς και Κάικος tc +Turkoj kaj Kajkoj tc +Islas Turcos y Caicos tc +Turks ja Caicos tc +Turks eta Caicos Irlak tc +جزایر تورکس Ùˆ کایکوس tc +Turks- ja Caicos-saaret tc +ÃŽles Turks et Caicos tc +Turks en Caicos Eilânen tc +Na hOileáin Turks agus Caicos tc +Illas Caicos e Turks tc +××™×™ ק×יקוס וטורקס tc +तà¥à¤°à¥à¤• तथा कैकोस आइलैंड tc +Turks i Caicos otoÄje tc +Turks- és Caicos-szigetek tc +Turks- og Caicos-eyjar tc +Isole Turks e Caicos tc +è‹±é ˜ã‚¿ãƒ¼ã‚¯ã‚¹è«¸å³¶ カイコス諸島 tc +កោះ​ទួក និង​ កៃកូស tc +í„°í¬ìŠ¤ ì¼€ì´ì»¤ìŠ¤ ì œë„ tc +TÄ“rksa un Kaikosa tc +ОÑтрови Турк и ÐšÐ°Ð¸ÐºÐ¾Ñ tc +Турк ба Кайкогийн арлууд tc +Gżejjer Turks u Caicos tc +Turks- og Caicosøyene tc +Turks- un Caicosinseln tc +Turks en Caicos Eilanden tc +Turks- og Caicosøyane tc +ਤà©à¨°à¨•à¨¸ ਤੇ ਕਾਇਕੋਸ ਟਾਪੂ tc +Wyspy Turks i Caicos tc +Ilhas Turks e Caicos tc +Ilhas Caicos e Turca tc +Insulele Turks ÅŸi Caicos tc +ОÑтрова Ð¢ÐµÑ€ÐºÑ Ð¸ ÐšÐ°Ð¹ÐºÐ¾Ñ tc +Ibirwa bya Turike na Kayikosi tc +Turks- ja Kaikossullot tc +Turks a Caicos ostrovy tc +Otoka Turks in Caicos tc +Турка и Кајкошка оÑтрва tc +Turka i KajkoÅ¡ka ostrva tc +Turks- och Caicosöarna tc +தà¯à®°à¯à®•à¯à®•à®¿à®•à®³à¯ மறà¯à®±à¯à®®à¯ காயà¯à®•à¯‹à®¸à¯ தீவà¯à®•à®³à¯ tc +Ҷазираи Турк ва ÐšÐ¾Ð¹ÐºÑƒÑ tc +เà¸à¸²à¸°à¸”ติร์à¸à¹à¸¥à¸°à¹€à¸„คà¸à¸ª tc +Turks ve Caicos Adaları tc +Türks wä Caicos Utrawları tc +ОÑтрови Ð¢ÐµÑ€ÐºÑ Ñ– ÐšÐ°Ð¹ÐºÐ¾Ñ tc +Ð¢ÑƒÑ€ÐºÑ Ð²Ð° ÐšÐ°Ð¸ÐºÐ¾Ñ ÐžÑ€Ð¾Ð»Ð»Ð°Ñ€Ð¸ tc +Quần đảo Turks và Caicos tc +Iyes Turks et Caicos tc +特克斯和凯科斯群岛 tc +土克斯和開å¡æ–¯ç¾¤å³¶ tc +Chad td +تشاد td +Çad td +Чад td +Чад td +চà§à¦¯à¦¾à¦¡ td +Tchad td +ÄŒad td +Txad td +ÄŒad td +Tsiad td +Tchad td +Tschad td +Τσαντ td +Ĉado td +TÅ¡aad td +Txad td +چاد td +Tchad td +Tsjaad td +Sead td +Chade td +צ'×ד td +चाड td +Äad td +Csád td +Tsjad td +Ciad td +ãƒãƒ£ãƒ‰ td +ឆាដ td +차드 td +ເàºàº¡à»„ພ່ td +ÄŒada td +Чад td +Чад td +ÄŠad td +Tsjad td +Tschad td +Tsjaad td +Tsjad td +ਚਾਂਦ td +Czad td +Chade td +Chade td +Ciad td +Чад td +Cade td +ÄŒad td +ÄŒad td +ÄŒad td +Чад td +ÄŒad td +Tchad td +சாட௠td +Чод td +ชาด td +Çad td +Çad td +Чад td +Чад td +Tchad td +ä¹å¾— td +查德 td +Togo tg +توغو tg +Тога tg +Того tg +টোগো tg +Τόγκο tg +توگو tg +Tógó tg +טוגו tg +टोगो tg +Tógó tg +トーゴ tg +ážáž¼áž ្គោ tg +í† ê³ tg +ຂàºàº‡à»€àº¥à»ˆàº™àºªàº°àº™àº¸àº tg +Того tg +Того tg +ਤੋਗੋ tg +Того tg +Того tg +டோகோ tg +Того tg +โตโภtg +Того tg +Того tg +多哥 tg +多哥 tg +Thailand th +تايلاند th +Tayland th +ТайлÑнд th +Тайланд th +থাইলà§à¦¯à¦¾à¦£à§à¦¡ th +Tajland th +Tailà ndia th +Thajsko th +Gwlad y Tai th +Ταϊλάνδη th +Tajlando th +Tailandia th +Tai th +Thailandia th +تایلند th +Thaimaa th +Tailand th +Thaïlande th +Thailân th +An Téalainn th +Tailándia th +ת××™×œ× ×“ th +थाइलैंड th +Tajland th +Thaiföld th +TaÃland th +Tailandia th +タイ th +ážáŸƒ th +íƒœêµ th +ລາດສະນາຈັàºà»„ທຠth +Tailandas th +Taizeme th +Тајланд th +Тайланд th +Tajlandja th +Tailandia th +ਥਾਈਲੈਂਡ th +Tajlandia th +Tailândia th +Tailândia th +Tailanda th +Таиланд th +Tayilande th +Thajsko th +Tajska th +Тајланд th +Tajland th +I-Thailand th +தாயà¯à®²à®¾à®¨à¯à®¤à¯ th +Тойлонд th +ราชà¸à¸²à¸“าจัà¸à¸£à¹„ทย th +Tayland th +Tayland th +Таїланд th +Таиланд th +Thái Lan th +Taylande th +泰国 th +泰國 th +Tajikistan tj +طاجيكستان tj +Tacikistan tj +ТаджыкіÑтан tj +ТаджикиÑтан tj +তাজিকিসà§à¦¤à¦¾à¦¨ tj +Tadjikistan tj +Tadžikistan tj +Tadjikistan tj +Tádžikistán tj +Tajicistan tj +Tadschikistan tj +Τατζικιστάν tj +TaÄikujo tj +Tajikistán tj +Tadžikistan tj +تاجیکستان tj +Tadjikistan tj +An TáidsÃceastáin tj +Taxiquistán tj +טג'קיסטן tj +ताजिकिसà¥à¤¤à¤¾à¤¨ tj +Tadžikistan tj +Tadzsikisztán tj +Tadsjikistan tj +Tagikistan tj +タジã‚スタン tj +ážáž¶áž ្ស៊ីគីស្ážáž„់ tj +타지키스탄 tj +ໃຕ້ຫວັນ tj +Tadžikistanas tj +TadžikistÄna tj +ТаџикиÑтан tj +ТажикÑтан tj +TaÄ¡ikistan tj +Tadsjikistan tj +Tadschikistan tj +Tadjikistan tj +Tadsjikistan tj +ਤਜ਼ਾਕਸਤਾਨ tj +Tadżykistan tj +Tajiquistão tj +Tajiquistão tj +ТаджикиÑтан tj +Tajikisitani tj +Tažikistan tj +Tadžikistan tj +Tadžikistan tj +ТаџикиÑтан tj +Tadžikistan tj +Tadzjikistan tj +தஜிகிஸà¯à®¤à®¾à®©à¯ tj +ТоҷикиÑтон tj +ธาจีà¸à¸´à¸ªà¸–าน tj +Tacikistan tj +Tajıqstan tj +ТаджикиÑтан tj +ТожикиÑтон tj +Tadjikistan tj +å¡”å‰å…‹æ–¯å¦ tj +å¡”å‰å…‹ tj +Tokelau tk +توكيلاو tk +Такелау tk +Токело tk +টোকেলো tk +Tokelo tk +Tocelaw tk +Τοκελάου tk +Tokelao tk +توکلائو tk +Na hOileáin Tócala tk +טוקל×ו tk +तोकेलाऊ tk +Tókelá tk +ãƒ‹ãƒ¥ãƒ¼ã‚¸ãƒ¼ãƒ©ãƒ³ãƒ‰è‡ªæ²»é ˜ãƒˆã‚±ãƒ©ã‚¦ tk +ážáž¼áž€áŸáž¡áž¼ tk +í† ì¼ˆë¡œ tk +ເບລາລັສ tk +Токелау tk +Токелау tk +Tokelaw tk +ਤੋਕੀਲਾਉ tk +Токелау tk +Tokelawu tk +Токелау tk +டோகேலா tk +Токилау tk +โทเคเลา tk +Tokelauça tk +Токелау tk +Токелау tk +托克劳 tk +托克勞 tk +Turkmenistan tm +تركمانستان tm +TürkmÉ™nistan tm +ТуркмÑніÑтан tm +ТуркмениÑтан tm +তà§à¦°à§à¦•à¦®à§‡à¦¨à¦¿à¦¸à§à¦¤à¦¾à¦¨ tm +Turcmenistan tm +Turkmenistán tm +Twrcmenistan tm +ΤουÏκμενιστάν tm +Turkmenujo tm +Turkmenistán tm +Türkmenistan tm +ترکمنستان tm +Turkménistan tm +An Tuircméanastáin tm +Turkmenistán tm +×˜×•×¨×§×ž× ×™×¡×˜×Ÿ tm +तà¥à¤°à¥à¤•à¤®à¥‡à¤¨à¤¿à¤¸à¥à¤¤à¤¾à¤¨ tm +Türkmenisztán tm +Túrkmenistan tm +トルクメニスタン tm +ទួគមáŸáž“ីស្ážáž„់ tm +투르í¬ë©”니스탄 tm +ຕຸລະàºàºµ tm +TurkmenistÄna tm +ТуркмениÑтан tm +ТуркменÑтан tm +ਤà©à¨°à¨•à©‡à¨®à¨¸à¨¤à¨¾à¨¨ tm +Turquemenistão tm +Turcomenistão tm +Turcmenistan tm +ТуркмениÑтан tm +Turikimenisitani tm +ТуркмениÑтан tm +தà¯à®°à¯à®•à¯à®®à¯†à®©à®¿à®¸à¯à®¤à®¾à®©à¯ tm +ТуркманиÑтон tm +เตà¸à¸£à¹Œà¸à¹€à¸¡à¸™à¸´à¸ªà¸–าน tm +Türkmenistan tm +ТуркменіÑтан tm +ТуркманиÑтон tm +Turcmenistan tm +åœŸåº“æ›¼æ–¯å¦ tm +土庫曼 tm +Tunisia tn +Tunisië tn +تونس tn +Tunis tn +Ð¢ÑƒÐ½Ñ–Ñ tn +Ð¢ÑƒÐ½Ð¸Ñ tn +টিউনিসিয়া tn +Tunizi tn +Tunis tn +TunÃsia tn +Tunisko tn +Tiwnisia tn +Tunesien tn +Tunesien tn +Τυνησία tn +Tunizio tn +Túnez tn +Tuneesia tn +تونس tn +Tunesia tn +Tunisie tn +Tunisie tn +An Túinéis tn +Túnez tn +×ª×•× ×™×¡×™×” tn +टà¥à¤¯à¥‚नीशिया tn +Tunis tn +Tunézia tn +Túnis tn +ãƒãƒ¥ãƒ‹ã‚¸ã‚¢ tn +ទុយនáŸážŸáŸŠáž¸ tn +튀니지 tn +ລັດເຊີຠtn +Tunisas tn +Tunisija tn +Ð¢ÑƒÐ½Ð¸Ñ tn +Ð¢ÑƒÐ½Ð¸Ñ tn +Tuneżija tn +Tunesien tn +Tunisie tn +ਟà©à¨¨à©€à¨¶à©€à¨† tn +Tunezja tn +TunÃsia tn +TunÃsia tn +Ð¢ÑƒÐ½Ð¸Ñ tn +Tuniziya tn +Tunisko tn +Tunizija tn +Ð¢ÑƒÐ½Ð¸Ñ tn +Tunis tn +I-Tunisia tn +Tunisien tn +தà¯à®©à®¿à®šà®¿à®¯à®¾ tn +Ð¢ÑƒÐ½Ð¸Ñ tn +ตูนีเซีย tn +Tunus tn +Ð¢ÑƒÐ½Ñ–Ñ tn +Ð¢ÑƒÐ½Ð¸Ñ tn +Tunizeye tn +çªå°¼æ–¯ tn +çªå°¼è¥¿äºž tn +Tonga to +تونغا to +Tonqa to +Тонга to +Тонга to +টোংগা to +Inizi Tonga to +Τόνγκα to +Tongo to +تونگو to +×˜×•× ×’×” to +टोंगा to +トンガ to +ážáž»áž„ហ្គោ to +통가 to +ໂຊນາ to +Тонга to +Тонга to +ਟਾਂਗਾ to +Тонга to +Тонга to +டோஙà¯à®•à®¾ to +Тонго to +ตà¸à¸‡à¸à¹‰à¸² to +Тонга to +Тонга to +æ±¤åŠ to +æ±åŠ to +East Timor tp +Oos Timor tp +تيمور الشرقية tp +Şərqi Timor tp +УÑходні Тымор tp +Източен Тимор tp +পূরà§à¦¬ টিমর tp +Timor reter tp +IstoÄni Timor tp +Timor Est tp +Východnà Timor tp +Dwyrain Timor tp +Østtimor tp +Ost-Timor tp +Ανατολικό Î¤Î¹Î¼ÏŒÏ tp +Orienta Timoro tp +Timor oriental tp +Ida-Timor tp +Ekialdeko Timor tp +تیمور شرقی tp +Itä-Timor tp +Timor oriental tp +Oost Timor tp +TÃomór Thoir tp +Timor do Leste tp +מזרח טימור tp +पूरà¥à¤µà¥€ तिमोर tp +IstoÄni Timor tp +Kelet-Timor tp +Austur-TÃmor tp +Timor Est tp +æ±ãƒ†ã‚£ãƒ¢ãƒ¼ãƒ« tp +ទីមáŸážšâ€‹ážáž¶áž„​កើហtp +ë™í‹°ëª¨ë¥´ tp +ວັນà»àº¥àº°à»€àº§àº¥àº² tp +Rytų Timoras tp +Austrumtimora tp +ИÑточен Тимор tp +Зүүн тимор tp +Timor Timur tp +Timor tal-Lvant tp +Øst-Timor tp +Oosttimor tp +Oost Timor tp +Aust-Timor tp +ਪੂਰਬੀ ਤਾਮੋਰ tp +Timor Wschodni tp +Timor Leste tp +Timor Leste tp +Timorul de Est tp +ВоÑточный Тимор tp +Timoro y'Uburasirazuba tp +Nuorta-Timor tp +Východný Timor tp +Vzhodni Timor tp +ИÑточни Тимор tp +IstoÄni Timor tp +Östtimor tp +கிழகà¯à®•à¯ திமார௠tp +Тимури Шарқ tp +ติมà¸à¸£à¹Œà¸•à¸°à¸§à¸±à¸™à¸à¸à¸ tp +DoÄŸu Timur tp +Çığış Timor tp +Східний Тімор tp +Шарқий Тимур tp +Äông Timo tp +Timor Ess tp +东å¸æ±¶ tp +æ±å¸æ±¶ tp +Turkey tr +Turkeye tr +تركيا tr +TürkiyÉ™ tr +Ð¢ÑƒÑ€Ñ†Ñ‹Ñ tr +Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr +তà§à¦°à§à¦•à§€ tr +Turkia tr +Turska tr +Turquia tr +Turecko tr +Twrci tr +Tyrkiet tr +Türkei tr +ΤουÏκία tr +Turkujo tr +TurquÃa tr +Türgi tr +Turkia tr +ترکیه tr +Turkki tr +Turkaland tr +Turquie tr +Turkije tr +An Tuirc tr +Turquia tr +טורקיה tr +तà¥à¤°à¥à¤•à¥€ tr +Turska tr +Törökország tr +Turki tr +Tyrkland tr +Turchia tr +トルコ tr +ទួរគី tr +터키 tr +ຕຸລະàºàºµ tr +Turkija tr +Turcija tr +Турција tr +Турк tr +Turki tr +Turkija tr +Tyrkia tr +Törkei tr +Turkije tr +Tyrkia tr +Turquia tr +ਤà©à¨°à¨•à©€ tr +Turcja tr +Turquia tr +Turquia tr +Turcia tr +Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr +Turukiya tr +Durka tr +Turecko tr +TurÄija tr +ТурÑка tr +Turska tr +I-Turkey tr +Turkiet tr +தà¯à®°à¯à®•à¯à®•à®¿ tr +Туркиё tr +ตุรà¸à¸µ tr +Türkiye tr +Törkiä tr +Туреччина tr +Ð¢ÑƒÑ€ÐºÐ¸Ñ tr +Thổ NhÄ© Kì tr +Turkeye tr +土耳其 tr +土耳其 tr +Trinidad and Tobago tt +Trinidad en Tobago tt +ترينيداد Ùˆ توباغو tt +Trinidad vÉ™ Tabaqo tt +Трынідад Ñ– Табага tt +Тринидад и Тобаго tt +তà§à¦°à¦¿à¦¨à¦¿à¦¦à¦¾à¦¦ à¦à¦¬à¦‚ টোবাগো tt +Trinidad ha Tobago tt +Trinidad i Tobago tt +Trinidad i Tobago tt +Trinidad a Tobago tt +Ynysoedd Trinidad a Thobago 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 +Trinidad en Tobago tt +Oileán na TrÃonóide agus Tobága tt +Trinidade e Tobago tt +×˜×¨×™× ×™×“×“ וטובגו tt +टà¥à¤°à¤¿à¤¨à¤¿à¤¡à¤¾à¤¡ और टोबैगो tt +Trinidad i Tobago tt +Trinidad és Tobago tt +Trinidad dan Tobago tt +TrÃnidad og Tóbagó tt +Trinidad e Tobago tt +トリニダードトãƒã‚³ tt +ទ្រីនីដាដ និង​​ ážáž¼áž”ាហ្គោ tt +트리니다드 í† ë°”ê³ tt +ຕີນິà»àº”ດà»àº¥àº°à»‚ທບາໂຠtt +Trinidadas ir Tobagas tt +Trinidada un Tobago tt +Тринидад и Тобаго tt +Тринида ба Тобаго tt +Trinidad dan Tobago tt +Trinidad u Tobago tt +Trinidad og Tobago tt +Trinidad un Tobago tt +Trinidad en Tobago tt +Trinidad og Tobago tt +Trinidad le Tobago tt +Trinidad e Tobago tt +ਤਰੀਨੀਡਾਡ ਤੇ ਤੋਬਾਗੋ tt +Trinidad i Tobago tt +Trindade e Tobago tt +Trinidad e Tobago tt +Trinidad ÅŸi Tobago tt +Тринидад и Тобаго tt +Tirinida na Tobago tt +Trinidad ja Tobago tt +Trinidad a Tobago tt +Trinidad in Tabago tt +Тринидад и Тобаго tt +Trinidad i Tobago tt +I-Trinidad kanye neTobago tt +Trinidad och Tobago tt +டà¯à®°à®¿à®©à®¿à®Ÿà®¾à®Ÿà¯ & டொபாகோ tt +Туриндод ва Тубогу tt +ตรีนิà¹à¸”ดà¹à¸¥à¸°à¹‚ทบาโภtt +Trinidad veTabago tt +Trinidad wä Tobago tt +РеÑпубліка Трінідад та Тобаго tt +Тринидад ва Тобаго tt +Trinidad na Tobago tt +Trinidad và Tobago tt +Trinité et Tobago tt +Trinidad ne Tobago tt +特立尼达和多巴哥 tt +åƒé‡Œé”åŠæ‰˜è²å“¥ tt +Trinidad knaye ne-Tobago tt +Tuvalu tv +توÙالو tv +Тувалу tv +Тувалу tv +টà§à¦à¦¾à¦²à§ tv +Twfalw tv +Î¤Î¿Ï…Î²Î±Î»Î¿Ï tv +Tuvalo tv +توالو tv +טוב×לו tv +तà¥à¤µà¤¾à¤²à¥‚ tv +Túvalú tv +ツãƒãƒ« tv +ទុយវ៉ាលុយ tv +투발루 tv +ຊູລູ tv +Тувалу tv +Тувалу tv +ਤà©à¨µà¨¾à¨²à©‚ tv +Тувалу tv +Тувалу tv +தà¯à®µà®²à¯ tv +Тувалу tv +ตูวาลู tv +Tuvaluça tv +Тувалу tv +Тувалу tv +Touvalou tv +å›¾ç“¦å¢ tv +åç“¦é¯ tv +Taiwan tw +تايوان tw +Tayvan tw +Тайвань tw +Тайван tw +তাইওয়ান tw +Tajvan tw +Ταϊβάν tw +Tajvano tw +Taiwán tw +تایوان tw +Taivan tw +Taïwan tw +An Téaváin tw +Taiwán tw +טיוו×ן tw +ताईवान tw +Tajvan tw +Tajvan tw +TaÃvan tw +å°æ¹¾ tw +ážáŸƒážœáŸ‰áž¶áž“់ tw +대만 tw +ໃຕ້ຫວັນ tw +Taivanis tw +TaivÄna tw +Тајван tw +Тайван tw +Tajwan tw +ਤਾਈਵਾਨ tw +Tajwan tw +Formosa tw +Taivan tw +Тайвань tw +Tayiwani tw +Tajvan tw +Тајван tw +Tajvan tw +I-Taiwan tw +தாயà¯à®µà®¾à®©à¯ tw +Тойвон tw +ไต้หวัน tw +Tayvan tw +Taywan tw +Тайвань tw +Тайван tw +Äà i Loan tw +ä¸å›½å°æ¹¾ tw +å°ç£ tw +Tanzania, United Republic of tz +Tanzanië, Vereenigde Republiek van tz +جمهورية تنزانيا المتØدة tz +Tanzaniya tz +Ð—Ð»ÑƒÑ‡Ð°Ð½Ð°Ñ Ð ÑÑпубліка Ð¢Ð°Ð½Ð·Ð°Ð½Ñ–Ñ tz +Ð¢Ð°Ð½Ð·Ð°Ð½Ð¸Ñ tz +তানজানিয়া tz +Tanzanija, Ujedinjena Republika tz +Tanzà nia, República Unida de tz +Tanzánie tz +Tansania, Gweriniaeth Unedig tz +Tanzania tz +Tansania, vereinigte Republik tz +Τανζανία, ΕνωμÎνη δημοκÏατία της tz +Tanzanio, UnuiÄinta Respubliko de tz +Tanzania, Republica de tz +Tansaania tz +Tanaziar Errepublika Batua tz +جمهوری متØده تانزانیا tz +Tansanian yhdistäytynyt tasavalta tz +Tanzanie, République unie de tz +Tanzanië, Ferienigd republyk fan tz +An Tansáin tz +República Unida de Tanzánia tz +×˜× ×–× ×™×”, הרפובליקה המ×וחדת של tz +तंजानिया यूनाइटेड रिपबà¥à¤²à¤¿à¤• tz +Ujedinjena Republika Tanzanija tz +Tanzánia tz +TansanÃa tz +Tanzania tz +タンザニア,共和国連邦 tz +ážáž„់ហ្សានី tz +탄ìžë‹ˆì•„ í•©ì¤‘êµ tz +ໂດມິນິàºàº±àº™ tz +Tanzanijos Respublika tz +TanzÄnija tz +Танзанија, Обединета Република tz +Танканы нÑгдÑÑн ÑƒÐ»Ñ tz +Republik Bersatu Tanzania tz +Tanżania tz +Tanzania tz +Tansania tz +Tanzania, Verenigde republiek van tz +Tanzania tz +ਤਾਨਜ਼ੂਈਆ, ਸੰਯà©à¨•à¨¤ ਗਣਰਾਜ tz +Zjednoczna Republika Tanzanii tz +República da União da Tanzânia tz +República da Tanzânia tz +Tanzania, Republica Unită tz +Ð¢Ð°Ð½Ð·Ð°Ð½Ð¸Ñ tz +Tanzaniya, Repubulika Yunze Ubumwe ya tz +Tanzania tz +Tanzánia, Spojená republika tz +Tanzanija, Združena republika tz +Танзанија, Уједињена Република tz +Tanzanija, Ujedinjena Republika tz +Förenade republiken Tanzania tz +டானà¯à®œà®¾à®¨à®¿à®¯à®¾, à®à®•à¯à®•à®¿à®¯ கà¯à®Ÿà®¿à®¯à®°à®šà¯ tz +Ҷумҳурии Муттаҳидаи Тонзониё tz +สาธารณรัà¸à¹à¸—นซาเนีย tz +Tanzanya tz +Tanzania, Berläşkän Cömhüriätläre tz +ТанзаніÑ, об'єднана реÑпубліка tz +Ð¢Ð°Ð½Ð·Ð°Ð½Ð¸Ñ Ð‘Ð¸Ñ€Ð»Ð°ÑˆÐ³Ð°Ð½ РеÑпубликаÑи tz +Tanzania, Cá»™ng hoà thống nhât tz +Tanzaneye tz +å¦æ¡‘尼亚è”åˆå…±å’Œå›½ tz +å¦å°šå°¼äºž tz +Ukraine ua +Ukraïne ua +أوكرانيا ua +Ukrayna ua +Украіна ua +Украйна ua +ইউকà§à¦°à§‡à¦¨ ua +Ukraina ua +Ukrajina ua +Ucraïna ua +Ukrajina ua +Wcr?in ua +ΟυκÏανία ua +Ukrainio ua +Ucrania ua +Ukraina ua +Ukrania ua +اکراین ua +Ukraina ua +Ukraina ua +Oekraïne ua +An Úcráin ua +Ucrania ua +×וקר××™× ×” ua +उकà¥à¤°à¥‡à¤¨ ua +Ukrajina ua +Ukrajna ua +Ukraina ua +ÚkraÃna ua +Ucraina ua +ウクライナ ua +អ៊ុយក្រែន ua +ìš°í¬ë¼ì´ë‚˜ ua +àºàº¹à»€àº„ຣນ ua +Ukraina ua +Ukraina ua +Украина ua +Украйн ua +Ukranja ua +Ukraina ua +Oekraïne ua +Ukraina ua +Ucraina ua +ਯੂਕਰੇਨ ua +Ukraina ua +Ucrânia ua +Ucrânia ua +Ucraina ua +Украина ua +Ukerene ua +Ukraina ua +Ukrajina ua +Ukrajina ua +Украјина ua +Ukrajina ua +I-Ukraine ua +Ukraina ua +உகà¯à®°à¯†à®¯à¯à®©à¯ ua +Украина ua +ยูเครน ua +Ukrayna ua +Ukrain ua +Україна ua +Украина ua +Ukraina ua +Oucrinne ua +乌克兰 ua +çƒå…‹è˜ ua +Uganda ug +أوغندا ug +Uqanda ug +Уганда ug +Уганда ug +ইউগাণà§à¦¡à¦¾ ug +Ouganda ug +Wganda ug +Ουγκάντα ug +Ugando ug +اوگاندا ug +Ouganda ug +××•×’× ×“×” ug +उगांडा ug +Úganda ug +ウガンダ ug +អ៊ូហ្គង់ដា ug +우간다 ug +à»àºžàº™àº”້າ ug +Уганда ug +Уганда ug +ਯੂਗਾਂਡਾ ug +Уганда ug +Уганда ug +உகானà¯à®Ÿà®¾ ug +Угондо ug +ยูà¸à¸±à¸™à¸”า ug +Уганда ug +Уганда ug +Ouganda ug +乌干达 ug +çƒå¹²é” ug +United States of America us +Vereenigde State van Amerika us +الولايات المتØدة الأمريكية us +Amerika BirləşmiÅŸ Åžtatları us +Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ Ð¨Ñ‚Ð°Ñ‚Ñ‹ ÐмÑрыкі us +СÐЩ us +মারà§à¦•à¦¿à¦¨ যà§à¦•à§à¦¤à¦°à¦¾à¦·à§à¦Ÿà§à¦° us +Stadoù-Unanet Amerika us +Sjedinjene AmeriÄke Države us +Estats Units d'Amèrica us +Spojené státy americké us +Unol Daleithau America us +USA us +USA us +ΗνωμÎνες Πολιτείες της ΑμεÏικής us +Usono us +Estados Unidos de América us +Ameerika Ãœhendriigid us +Ameriketako Estatu Batuak us +ایالات متØده‌ی آمریکا us +Yhdysvallat us +SambandsrÃki Amerika (USA) us +États Unis d'Amérique us +Ferienigde Staten fan Amerika us +Stáit Aontaithe Mheiriceá us +Estados Unidos de América us +×רצות הברית us +संयà¥à¤•à¥à¤¤ राजà¥à¤¯ अमेरिका us +Sjedinjene AmeriÄke Države us +Amerikai Egyesült Ãllamok us +Amerika Serikat us +BandarÃkin us +Stati Uniti d'America us +アメリカåˆè¡†å›½ us +សហរដ្ឋអាមáŸážšáž·áž€ us +미 í•©ì¤‘êµ us +ສະຫະລັດàºàº²à»€àº¡àº¥àº´àºàº² us +JungtinÄ—s Amerikos Valstijos us +Amerikas SavienotÄs Valstis us +Соединети ÐмериканÑки Држави us +ÐÐУ us +Amerika Syarikat us +Stati Uniti us +USA us +Vereenigte Staten vun Amerika us +Verenigde Staten van Amerika us +USA us +Estats Units d'Amèrica us +ਸੰਯà©à¨•à¨¤ ਰਾਜ ਅਮਰੀਕਾ us +Stany Zjednoczone Ameryki us +Estados Unidos da América us +Estados Unidos da América us +Statele Unite ale Americii us +Соединённые Штаты Ðмерики us +Leta Zunze Ubumwe z'Amerika us +Amerihká ovttastuvvan stáhtat us +USA us +Združene države Amerike us +Сједињене америчке државе us +Sjedinjene ameriÄke države us +I-United States of America us +Amerikas förenta stater us +à®à®•à¯à®•à®¿à®¯ அமெரிகà¯à®•à®¾ us +Иёлоти Муттаҳидаи Ðмрико us +สหรัà¸à¸à¹€à¸¡à¸£à¸´à¸à¸² us +Amerika BirleÅŸik Devletleri us +Amerika QuÅŸma Åžtatları us +СШРus +Ðмерика Қўшма Штатлари us +mashango o tangananaho a America us +Hợp chủng quốc Hoa Kỳ us +Estats Unis us +United States ye Melika us +美国 us +ç¾Žåˆ©å …åˆçœ¾åœ‹ us +Uruguay uy +الأوروغواي uy +Uruqvay uy +Уругвай uy +Уругвай uy +উরà§à¦—à§à§Ÿà§‡ uy +Urugvaj uy +Uruguai uy +Wrwgw?i uy +ΟυÏουγουάη uy +Urugvajo uy +Uruguai uy +اروگویه uy +Uragua uy +Uruguai uy +×ורוגו××™ uy +उरूगà¥à¤µà¥‡ uy +Urugvaj uy +Úrúgvæ uy +ウルグアイ uy +អ៊ុយរុយហ្គាយ uy +ìš°ë£¨ê³¼ì´ uy +àºàº¸àº¥àº¸àºàºàº§àº uy +Urugvajus uy +Urugvaja uy +Уругвај uy +Уругвай uy +Urugwaj uy +Uruguai uy +ਉਰੂਗਵੇ uy +Urugwaj uy +Uruguai uy +Uruguai uy +Uruguai uy +Уругвай uy +Irigwe uy +Uruguaj uy +Urugvaj uy +Уругвај uy +Urugvaj uy +I-Uruguay uy +உரà¯à®•à¯à®µà¯‡ uy +Уругвай uy +à¸à¸¸à¸£à¸¸à¸à¸§à¸±à¸¢ uy +Уругвай uy +Уругвай uy +Ourougway uy +ä¹Œæ‹‰åœ uy +çƒæ‹‰åœ uy +Uzbekistan uz +أوزبكستان uz +ÖzbÉ™kistan uz +УзбÑкіÑтан uz +УзбекиÑтан uz +উজবেকিসà§à¦¤à¦¾à¦¨ uz +Ouzbekistan uz +Uzbekistán uz +Wsbecist?n uz +Usbekistan uz +Ουζμπεκιστάν uz +Uzbekujo uz +Uzbekistán uz +Usbekistan uz +ازبکستان uz +Ouzbékistan uz +Úisbéiceastáin uz +Uzbekistán uz +×וזבקיסטן uz +उजà¥à¤¬à¥‡à¤•à¤¿à¤¸à¥à¤¤à¤¾à¤¨ uz +Ãœzbegisztán uz +Úsbekistan uz +ウズベã‚スタン uz +អ៊ូហ្សបáŸáž‚ីស្ážáž„់ uz +ìš°ì¦ˆë² í‚¤ìŠ¤íƒ„ uz +ເດນ່ງນ uz +UzbekistÄna uz +УзбекиÑтан uz +УзбекÑтан uz +Użbekistan uz +Usbekistan uz +Usbekistan uz +Usbekistan uz +ਉਜ਼ੇਬਕਸਤਾਨ uz +Uzbequistão uz +Uzbequistão uz +УзбекиÑтан uz +Uzibekisitani uz +Usbekistan uz +УзбекиÑтан uz +உஸà¯à®ªà¯†à®•à®¿à®¸à¯à®¤à®¾à®©à¯ uz +ӮзбекиÑтон uz +à¸à¸¸à¸‹à¹€à¸šà¸à¸´à¸ªà¸–าน uz +Özbekistan uz +Özbäkstan uz +УзбекиÑтан uz +ЎзбекиÑтон uz +Ouzbekistan uz +ä¹Œå…¹åˆ«å…‹æ–¯å¦ uz +çƒèŒ²åˆ¥å…‹ uz +Vatican City va +Vatikaan Stad va +مدينة الÙاتيكان va +Vatican ŞəhÉ™ri va +Ватыкан va +Ватикана va +à¦à§à¦¯à¦¾à¦Ÿà¦¿à¦•à¦¾à¦¨ সিটি va +Ker Vatikan va +Vatikan va +Ciutat del Vaticà va +Vatikán va +Dinas y Fatican va +Vatikanstaten va +Vatikanstadt va +Βατικανό va +Vatikano va +Vaticano va +Vatikan va +Batikano Hiria va +شهر واتیکان va +Vatikaani va +Vatican va +Vaticaanstad va +An Chathaoir Naofa va +Cidade do Vaticano va +הוותיקן va +वेटिकन सिटी va +Vatikan va +Vatikán va +VatÃkanið va +Città del Vaticano va +ãƒãƒã‚«ãƒ³å¸‚国 va +ក្រុង​វ៉ាទីកង់ va +바티칸 시티 va +ລັດເວີຠva +VatikÄns va +Ватикан va +Ватикан Ñити va +Vatikan va +Vatikanstaten va +Vatikaan va +Vaticaanstad va +Vatikanstaten va +ਵਾਟੀਕੇਨ ਸਿਟੀ va +Watykan va +Cidade do Vaticano va +Cidade do Vaticano va +Vatican, OraÅŸul va +Ватикан va +Umujyi wa Vatikani va +Vatikanstáhta va +Vatikán va +Vatikan va +Ватикан va +Vatikan va +Vatikanstaten va +வாடிகன௠நகரம௠va +Шаҳри Ватикан va +นครรัà¸à¸§à¸²à¸•à¸´à¸à¸±à¸™ va +Vatikan va +Vatikan va +Ватікан va +Ватикан Шаҳри va +Thà nh phố Vatican va +Vatican va +梵蒂冈 va +梵諦岡城 va +St. Vincent and the Grenadines vc +St. Vincent en die Grenadene vc +سانت Ùينسنت Ùˆ الغرينادين vc +St. Vincent vÉ™ Grenadines vc +СÑнт-ВінÑÑнт Ñ– ГрÑнадыны vc +Св. ВинÑет и Гренадините vc +সেনà§à¦Ÿ à¦à¦¿à¦¨à¦¸à§‡à¦¨à§à¦Ÿ ও গà§à¦°à§‡à¦¨à¦¾à¦¡à¦¿à¦¨ vc +S. Visant hag ar Grenadinez vc +Sveti Vincent i Grenadini vc +St. Vincent i les Granadines vc +St. Vincent a Grenadiny vc +Ynysoedd St. Finsent a'r Grenadinau vc +St. Vincent og Grenadinerne vc +St. Vincent und Grenadinen vc +Άγιος ΒικÎντιος και ΓÏεναδίνες vc +Sent-Vincento kaj la Grenadinoj vc +San Vicente y las Granadinas vc +St. Vincent ja Grenadiinid vc +St. Vincent eta Grenadines vc +سن وینسن Ùˆ گرادینس vc +St. Vincent ja Grenadiinit vc +Sankta Vinsent og Grenadinoyggjar vc +St Vincent et les Grenadines vc +St. Vincent en de Grenadines vc +St. Vincent agus Grenadines vc +Santo Vicente e as Granadinas vc +×¡× ×˜ ×•×™× ×¡× ×˜ ×•×”×’×¨× ×“×™× ×™× vc +सेंट विंसेंट तथा गà¥à¤°à¥‡à¤¨à¥‡à¤¡à¤¾à¤‡à¤¨à¥à¤¸ vc +St. Vincent és Grenadines vc +St. Vincent dan the Grenadines vc +Sankti Vinsent og GrenadÃneyjar vc +Saint Vincent e Grenadines vc +セントヴィンセントグレナディン vc +សង់វាំងសង់ áž“áž·áž„ ​ហ្គ្រីណាឌីន vc +세ì¸íŠ¸ 빈센트 ê·¸ë ˆë‚˜ë”˜ vc +ເຊີນວິນà»àºŠàº™ à»àº¥àº°à»€àºàº™àº²àº”ີນ vc +Å v. Vincentas ir Grenadinai vc +Sentvinsenta un GrenadÄ«nes vc +Св. ВинÑент и Гренадите vc +St. ВинÑент ба Гренадин vc +St. Vincent dan Grenadines vc +St. VinÄ‹enz u l-Grenadini vc +St. Vincent og Grenadinene vc +St. Vincent un de Grenadinen vc +St. Vincent en de Grenadines vc +St. Vincent og Grenadinane vc +St. Vincent le Grenadines vc +St. Vincent e les Granadines vc +ਸੇਂਟ ਵੀਨਸੈਂਟ ਤੇ ਗਰੀਨਾਜੀਨਸ vc +St. Vincent i Grenadyny vc +São Vicente e Granadinas vc +São Vicente e Grenadines vc +Sf. Vincent ÅŸi Grenadines vc +Сент-ВинÑент и Гренадины vc +Mutagatifu Visenti na Gerenadine vc +St. Vincent ja the Grenadiinnat vc +St. Vincent a Grenadines vc +Sv. Vincent in Grenadini vc +Св. ВинÑент и Гренадини vc +Sv. Vinsent i Grenadini vc +I-St. Vincent and the Grenadines vc +St. Vincent och Grenadinerna vc +செயினà¯à®Ÿà¯ வினà¯à®šà¯†à®©à¯à®Ÿà¯ மறà¯à®±à¯à®®à¯ கà¯à®°à¯€à®©à®¾à®Ÿà¯ˆà®©à¯à®¸à¯ vc +Синт ВинÑент ва Гренадина vc +เà¸à¸²à¸°à¹€à¸‹à¸™à¸•à¹Œà¸§à¸´à¸™à¹€à¸‹à¸™à¸•à¹Œ vc +St. Vincent ve Grenadines vc +Sain Vinsent wä Grenadinnär vc +Сент-ВінÑент Ñ– Гренадіни vc +Сент-ВинÑент ва Гренадина vc +St. Vincent na Grenadines vc +St. Vincent và Grenadines vc +St. Vincint et les Grenadines vc +St. Vincent ne Grenadines vc +åœ£æ–‡æ£®ç‰¹å’Œæ ¼æž—çº³ä¸æ–¯ vc +è–文森åŠæ ¼ç´é‚£ä¸ vc +I-St. Vincent kanye ne-Grenadines vc +Venezuela ve +Ùنزويلا ve +Venesuella ve +Ð’ÑнÑÑуÑла ve +ВенеÑуела ve +à¦à§‡à¦¨à§‡à¦œà§à§Ÿà§‡à¦²à¦¾ ve +Venecuela ve +Veneçuela ve +Feneswela ve +ΒενεζουÎλα ve +Venezuelo ve +Venetsueela ve +ونزویلا ve +Venesuela ve +Vénézuela ve +Veiniséala ve +×•× ×¦×•×לה ve +वेनेजà¥à¤à¤²à¤¾ ve +Venecuela ve +Venesúela ve +ベãƒã‚ºã‚§ãƒ© ve +ážœáŸážŽáŸáž ្សុ៊យអáŸáž¡áž¶ ve +ë² ë„¤ìˆ˜ì—˜ë¼ ve +ເວເນຊຸເàºàº¥àº² ve +Venesuela ve +VenecuÄ“la ve +Венецуела ve +ВинеÑÑуел ve +Veneżwela ve +ਵੈਂਨਜ਼ੂà¨à¨²à¨¾ ve +Wenezuela ve +ВенеÑуÑла ve +Venezuwela ve +Венецуела ve +Venecuela ve +I-Venezuela ve +வெனிசà¯à®²à®¾ ve +ВинизуÑлло ve +เวเนซุเà¸à¸¥à¸² ve +ВенеÑуела ve +ВенеÑуÑла ve +Venezwela ve +委内瑞拉 ve +委內瑞拉 ve +Virgin Islands, British vg +Virgin Eilande, Brits vg +الجزر العذراء, بريطانيا vg +Virgin Adaları, Britanya vg +БрытанÑÐºÑ–Ñ Ð’Ñ–Ñ€Ð³Ñ–Ð½ÑÐºÑ–Ñ Ð°Ñтравы vg +БританÑки ВирджинÑки оÑтрови vg +à¦à¦¾à¦°à§à¦œà¦¿à¦¨ আইলà§à¦¯à¦¾à¦£à§à¦¡à¦¸, বà§à¦°à¦¿à¦Ÿà¦¿à¦¶ vg +DjeviÄanska ostrva, Britanska vg +Illes Verges, Angleses vg +Ynysoedd yr Wyryf, Prydeinig vg +Britiske jomfruøer vg +Virgin-Inseln, britisch vg +ΠαÏθÎνοι Îήσοι, Î’ÏετανικÎÏ‚ vg +Virgininsuloj, Britaj vg +Islas VÃrgenes Británicas vg +Briti Neitsisaared vg +Britaniar Irla Birjinak vg +جزایر ویرجین انگلیسی vg +Brittien Neitsytsaaret vg +ÃŽles Vierges britanniques vg +Virgin Eilannen, Britse vg +Oileáin Bhriotanacha na Maighdean vg +Illas Virxes, Británicas vg +××™×™ הבתולה, בריטי vg +वरà¥à¤œà¤¿à¤¨ आइलैंड, बà¥à¤°à¤¿à¤Ÿà¤¿à¤¶ vg +DjeviÄansko otoÄje, Britanski vg +Virgin-szigetek (brit) vg +Bresku Jómfrúareyjar vg +Isole Vergini Britanniche vg +è‹±é ˜ãƒãƒ¼ã‚¸ãƒ³è«¸å³¶ vg +កោះ​ស្មោង អង់គ្លáŸážŸ vg +ì˜êµë ¹ 버진 ì œë„ vg +Britu Virdžinu salas vg +ДевÑтвени ОÑтрови, БританÑки vg +Виржин арлууд, британи vg +Kepulauan Virgin, British vg +Jomfruøyene (Storbritannia) vg +Britsche Jumferninseln vg +Virgin Eilanden, Britse vg +Jomfruøyane (Storbritannia) vg +ਵੀਰਗੀਨ ਟਾਪੂ, ਬਰਤਾਨੀਆ vg +Wyspy Dziewicze (Brytyjskie) vg +Ilhas Virgens, Inglaterra vg +Ilhas Virgens, Inglaterra vg +Insulele Virgine, Anglia vg +ВиргинÑкие БританÑкие оÑтрова vg +Ibirwa by'Isugi, Nyongereza vg +Panenské Ostrovy, Britské vg +DeviÅ¡ki otoki, Britanski vg +ДевичанÑка оÑтрва, БританÑка vg +DeviÄanska ostrva, Britanska vg +Brittiska Jungfruöarna vg +விரà¯à®œà®¿à®©à¯ தீவà¯à®•à®³à¯, பிரிடà¯à®Ÿà®¿à®·à¯ vg +Ҷазираи ВирҷиниÑ, Бритониё vg +หมู่เà¸à¸²à¸°à¹€à¸§à¸à¸£à¹Œà¸ˆà¸´à¸™, à¸à¸±à¸‡à¸à¸¤à¸© vg +Virgin Adaları (Ä°ngiltere) vg +Virgin Utrawları, Britan vg +ВіргінÑькі оÑтрови (БританіÑ) vg +ÐÐ½Ð³Ð»Ð¸Ñ Ð’Ð¸Ñ€Ð¶Ð¸Ð½ Ороллари vg +Quần đảo Trinh nữ, VÆ°ong quốc Anh vg +Iyes Viedjes, britanikes vg +英属维京群岛 vg +英屬ç¶çˆ¾äº¬ç¾¤å³¶ vg +Virgin Islands, U.S. vi +Virgin Eilande, VSA vi +الجزر العذراء, الولايات المتØدة vi +Virgin Adaları, ABÅž vi +ÐмÑрыканÑÐºÑ–Ñ Ð’Ñ–Ñ€Ð³Ñ–Ð½ÑÐºÑ–Ñ Ð°Ñтравы vi +ÐмериканÑки ВирджинÑки оÑтрови vi +à¦à¦¾à¦°à§à¦œà¦¿à¦¨ আইলà§à¦¯à¦¾à¦£à§à¦¡à¦¸, মারà§à¦•à¦¿à¦¨ যà§à¦•à§à¦¤à¦°à¦¾à¦·à§à¦Ÿà§à¦° vi +DjeviÄanska ostrva, AmeriÄka vi +Illes Verges, Americanes vi +Panenské ostrovy, U.S. vi +Ynysoedd yr Wyryf, Americanaidd vi +Jomfruøerne vi +Virgin-Inseln, amerikanisch vi +ΠαÏθÎνοι Îήσοι, Η.Î .A. vi +Virgininsuloj, Usonaj vi +Islas VÃrgenes Americanas vi +USA Neitsisaared vi +Estatu Batuar Irla Birjinak vi +جزایر ویرجین امریکا. vi +USA:n Neitsytsaaret vi +ÃŽles Vierges américaines vi +Virgin Eilannen, U.S. vi +Oileáin na Maighdean S.A.M. vi +Illas Virxes, U.S. vi +××™×™ הבתולה, ×רצות־הברית vi +वरà¥à¤œà¤¿à¤¨ आइलैंड, यू.à¤à¤¸. vi +DjeviÄansko otoÄje, SAD vi +Virgin-szigetek (USA) vi +BandarÃsku Jómfrúareyjar vi +Isole Vergini Americane vi +ç±³é ˜ãƒãƒ¼ã‚¸ãƒ³è«¸å³¶ vi +កោះ​ស្មោង អាមáŸážšáž·áž€ vi +미êµë ¹ 버진 ì œë„ vi +Virdžinu salas, ASV. vi +ДевÑтвени ОÑтрови, СÐД vi +Виржин арлууд, ÐÐУ vi +Kepulauan Virgin, U.S. vi +Jomfruøyene (USA) vi +Jumferninseln, U.S. vi +Virgin Eilanden, U.S. vi +Jomfruøyane (USA) vi +ਵੀਰਗੀਨ ਟਾਪੂ, ਅਮਰੀਕਾ vi +Wyspy Dziewicze (USA) vi +Ilhas Virgens, E.U.A. vi +Ilhas Virgens, EUA vi +Insulele Virgine, S.U.A. vi +ВиргинÑкие оÑтрова (СШÐ) vi +Ibirwa by'Isugi, U.S. vi +Panenské Ostrovy, Americké vi +DeviÅ¡ki otoki, ZDA vi +ДевичанÑка оÑтрва, СÐД vi +DeviÄanska ostrva, SAD vi +Amerikanska Jungfruöarna vi +விரà¯à®œà®¿à®©à¯ தீவà¯à®•à®³à¯, U.S. vi +Ҷазираи ВирҷиниÑ, Ш.Ðœ.Ð vi +หมู่เà¸à¸²à¸°à¹€à¸§à¸à¸£à¹Œà¸ˆà¸´à¸™, สหรัà¸à¸à¹€à¸¡à¸£à¸´à¸à¸² vi +Virgin Adaları (ABD) vi +Virgin Utrawları, AQÅž vi +ВіргінÑькі оÑтрови (СШÐ) vi +ÐҚШ Виржин Ороллари vi +Quần đảo Trinh nữ, Hoa Kỳ vi +Iyes Viedjes, etazunyinnes vi +美属维京群岛 vi +美屬ç¶çˆ¾äº¬ç¾¤å³¶ vi +Vietnam vn +Viëtnam vn +Ùييتنام vn +Vyetnam vn +Віетнам vn +Виетнам vn +à¦à¦¿à§Ÿà§‡à¦¤à¦¨à¦¾à¦® vn +Vijetnam vn +Panenské ostrovy, U.K. vn +Fiet-nam vn +Βιετνάμ vn +Vjetnamio vn +ویتنام vn +Viëtnam vn +VÃtneam vn +×•×™×™×˜× ×× vn +विà¤à¤¤à¤¨à¤¾à¤® vn +Vijetnam vn +VÃetnam vn +ベトナムvn +វៀážážŽáž¶áž˜ vn +ë² íŠ¸ë‚¨ vn +ຫວງດນາມ vn +Vietnamas vn +Vjetnama vn +Виетнам vn +Витнам vn +Vjetnam vn +Viëtnam vn +ਵੀਅਤਨਾਮ vn +Wietnam vn +Vietname vn +Vietnã vn +Вьетнам vn +Viyetinamu vn +Вијетнам vn +Vijetnam vn +I-Vietnam vn +வியடà¯à®¨à®¾à®®à¯ vn +Ветнам vn +เวียตนาม vn +Ð’'єтнам vn +Ветнам vn +Việt Nam vn +è¶Šå— vn +è¶Šå— vn +Vanuatu vu +Ùانواتو vu +Вануату vu +Вануату vu +à¦à¦¾à¦¨à§à§Ÿà¦¾à¦Ÿà§ vu +Fanwatw vu +Βανουάτου vu +Vanuatuo vu +وانواتو vu +Vanuatú vu +×•× ×•×טו vu +वनौतू vu +Vanúatú vu +ãƒãƒŒã‚¢ãƒ„ vu +វ៉ានុយអាទុយ vu +바누아투 vu +ຈີນ vu +Вануату vu +Вануату vu +ਵਾਨà©à¨†à¨Ÿà©‚ vu +Vanatu vu +Вануату vu +Vanuwatu vu +Вануату vu +வனட௠vu +Вануату vu +à¹à¸§à¸™à¸±à¸§à¸•à¸¹ vu +Вануату vu +Вануату vu +瓦努阿图 vu +è¬é‚£æœ vu +Wallis and Futuna wf +Wallis en Futuna wf +واليس Ùˆ Ùوتونا wf +Vallis vÉ™ Futuna wf +ÐŽÐ¾Ð»Ñ–Ñ Ñ– Футуна wf +ОÑтрови Ð£Ð¾Ð»Ð¸Ñ Ð¸ Футина wf +ওয়ালিস à¦à¦¬à¦‚ ফà§à¦Ÿà§à¦¨à¦¾ wf +Wallis ha Futuna wf +Valis i Futuna wf +Wallis i Futuna wf +Wallis a Futuna wf +Ynysoedd Walis a Ffwtwna wf +Wallis- og Futuna-øerne wf +Wallis und Futuna wf +Βαλίς και ΦουτοÏνα wf +Valiso kaj Futuno wf +Wallis y Futuna wf +Wallis ja Futuna wf +Wallis eta Futuna wf +والیس Ùˆ Ùوتونا wf +Wallis ja Futuna wf +Wallis et Futuna wf +Wallis en Futuna wf +BhailÃs agus Futúna wf +Wallis e Futuna wf +ו×ליס ×•×¤×•×˜×•× ×” wf +वालिस तथा फà¥à¤¤à¥à¤¨à¤¾ wf +Wallis i Futuna wf +Wallis és Futuna wf +Wallis- og Fútúnaeyjar wf +Wallis e Futuna wf +ä»é ˜ãƒ¯ãƒªã‚¹ãƒ•ãƒ„ナ諸島 wf +월리스 후투나 ì œë„ wf +ປັàºàºàº´àº™àºžàº²àºš wf +Volisa salas un Futuna wf +Ð’Ð°Ð»Ð¸Ñ Ð¸ Футуна wf +ВилÑÐ¼Ñ Ð±Ð° футуна wf +Wallis dan Futuna wf +Wallis u Futuna wf +Wallis og Futuna wf +Wallis un Futuna wf +Wallis en Futuna wf +Wallis og Futuna wf +ਵਾਲਿਸ਼ ਤੇ ਫੂਟੂਨਾ wf +Wallis i Futuna wf +Wallis e Futuna wf +Wallis e Futuna wf +Wallis ÅŸi Futuna wf +ОÑтрова Ð£Ð¾Ð»Ð»Ð¸Ñ Ð¸ Футуна wf +Walisi na Futuna wf +Wallis ja Futuna wf +Wallis a Futuna wf +Wallis in Futuna wf +Ð’Ð°Ð»Ð¸Ñ Ð¸ Футуна wf +Valis i Futuna wf +Wallis och Futuna wf +வாலிஸ௠மறà¯à®±à¯à®®à¯ பà¯à®¯à¯à®Ÿà®©à®¾ wf +УÑÐ»Ñ Ð²Ð° Футуна wf +วà¸à¸¥à¸¥à¸´à¸ªà¹à¸¥à¸°à¸Ÿà¸¹à¸—ูนา wf +Wallis ve Futuna wf +Wallis wä Futuna wf +Ð£Ð¾Ð»Ð»Ð¸Ñ Ñ– Футуна wf +Ð£Ð¾Ð»Ð»Ð¸Ñ Ð²Ð° Футуна Ороллари wf +Wallis và Futuna wf +Wallis et Futuna wf +瓦利斯和富图纳群岛 wf +瓦利斯群島和富圖ç´ç¾¤å³¶ wf +Samoa ws +ساموا ws +Самоа ws +Самоа ws +সামোয়া ws +Inizi Samoe ws +Σαμόα ws +Samoo ws +ساموآ ws +Samó ws +סמו××” ws +सामोआ ws +Szamoa ws +Samóa ws +サモア ws +សាមូអា ws +사모아 ì œë„ ws +ໂຊນາ ws +Самоа ws +Самолоа ws +ਸਾਮੋਆ ws +Самоа ws +Samowa ws +Самоа ws +சாமோயா ws +Самоа ws +ซามัว ws +Самоа ws +Самоа ws +Samowa ws +è¨æ‘©äºšç¾¤å²› ws +薩摩亞 ws +Yemen ye +اليمن ye +YÉ™mÉ™n ye +Емен ye +Йемен ye +ইয়েমেন ye +Ihlemeñ ye +Jemen ye +Iemen ye +Jemen ye +Yr Iemen ye +Jemen ye +ΥεμÎνη ye +Jemeno ye +Jeemen ye +یمن ye +Jemen ye +Jemen ye +Jemen ye +Éimin ye +Iemen ye +תימן ye +यमन ye +Jemen ye +Jemen ye +Jemen ye +イエメン ye +áž™áŸáž˜áŸ‚áž“ ye +예멘 ye +ເດມàºàº™ ye +Jemenas ye +Jemena ye +Јемен ye +Емен ye +Yaman ye +Jemen ye +Jemen ye +Jemen ye +Jemen ye +Jemen ye +ਯਮਨ ye +Jemen ye +Iémen ye +Йемен ye +Yemeni ye +Jemen ye +Jemen ye +Jemen ye +Јемен ye +Jemen ye +I-Yemen ye +Jemen ye +யேமன௠ye +Яман ye +เยเมน ye +Ємен ye +Яман ye +也门 ye +葉門 ye +Serbia and Montenegro yu +Serbië en Montenegro yu +Ð¡ÑŠÑ€Ð±Ð¸Ñ Ð¸ Черна гора yu +সারà§à¦¬à¦¿à§Ÿà¦¾ à¦à¦¬à¦‚ মনà§à¦Ÿà§‡à¦¨à¦¿à¦—à§à¦°à§‹ yu +Serbi ha Montenegro yu +Sèrbia i Montenegro yu +Srbsko a ÄŒerná hora yu +Serbien og Montenegro yu +Serbien und Montenegro yu +ΣεÏβία - ΜαυÏοβοÏνιο yu +Serbia y Montenegro yu +Serbia ja TÅ¡ernogooria yu +Serbia eta Montenegro yu +Serbia ja Montenegro yu +Serbie and Monténégro yu +Servië en Montenegro yu +Sérbia e Montenegro yu +Szerbia és Montenegró yu +SerbÃa og Svartfjallaland yu +Serbia e Montenegro yu +セルビアモンテãƒã‚°ãƒ yu +សែប៊ី áž“áž·áž„ ម៉ុងážáŸážŽáŸáž ្ក្រូ yu +Serbija ir Juodkalnija yu +Србија и Црна Гора yu +Serbia og Montenegro yu +Serbien un Montenegro yu +Servië en Montenegro yu +Serbia og Montenegro yu +ਸਰਬੀਆ ਅਤੇ ਮਾਂਤਾਂਗਰੋ yu +Serbia i Czarnogóra yu +Sérvia e Montenegro yu +Sérvia e Montenegro yu +Ð¡ÐµÑ€Ð±Ð¸Ñ Ð¸ Ð§ÐµÑ€Ð½Ð¾Ð³Ð¾Ñ€Ð¸Ñ yu +Seribiya na Montenegoro yu +Serbia ja Montenegro yu +Srbija in ÄŒrna gora yu +Србија и Црна Гора yu +Srbija i Crna Gora yu +Serbien och Montenegro yu +เซà¸à¸£à¹Œà¹€à¸šà¸µà¸¢ à¹à¸¥à¸°à¸¡à¸à¸™à¸•à¸´à¹€à¸™à¹‚à¸à¸£ yu +Sırbistan KaradaÄŸ yu +Serbia wä Montenegro yu +Ð¡ÐµÑ€Ð±Ñ–Ñ Ñ– Ð§Ð¾Ñ€Ð½Ð¾Ð³Ð¾Ñ€Ñ–Ñ yu +Ð¡ÐµÑ€Ð±Ð¸Ñ Ð²Ð° Монтенегро yu +塞尔维亚和黑山 yu +塞爾ç¶äºžå’Œé»‘å±± yu +South Africa za +Suid-Afrika za +جنوب Ø£Ùريقيا za +CÉ™nubi Afrika za +ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ Ðфрыка za +Южна Ðфрика za +দকà§à¦·à¦¿à¦£ আফà§à¦°à¦¿à¦•à¦¾ za +Suafrika za +Južna Afrika za +Sudà frica za +Jižnà Afrika za +De Affrica 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 +Sûd-Afrika za +An Afraic Theas za +Ãfrica do Sur za +×“×¨×•× ×פריקה za +दकà¥à¤·à¤¿à¤£à¥€ अफà¥à¤°à¥€à¤•à¤¾ za +Južna Afrika za +Dél-Afrika za +Afrika Selatan za +Suður-AfrÃka za +Sud Africa za +å—アフリカ za +អាហ្វ្រិក​ážáž¶áž„​ážáŸ’បូង za +남 아프리카 ê³µí™”êµ za +à»àºàºšàºžàº´àºàº²à»ƒàº•à»‰ za +Afrika, Pietų za +DienvidÄfrika za +Јужна Ðфрика za +Өмнөд африк za +Afrika Selatan za +Afrika t'Isfel za +Sør-Afrika za +Söödafrika za +Zuid-Afrika za +Sør-Afrika za +Afrika Borwa za +Sudafrica za +ਦੱਖਣੀ ਅਫਰੀਕਾ za +Afryka PoÅ‚udniowa za +Ãfrica do Sul za +Ãfrica do Sul za +Africa de Sud za +Ð®Ð¶Ð½Ð°Ñ Ðфрика za +Afurika Yepfo za +Lulli-Afrihká za +Južná Afrika za +Južna Afrika za +Јужна Ðфрика za +Južna Afrika za +I-South Africa za +Sydafrika za +தென௠ஆபà¯à®°à®¿à®•à¯à®•à®¾ za +Ðфриқои Ҷанубӣ za +à¹à¸à¸Ÿà¸£à¸´à¸à¸²à¹ƒà¸•à¹‰ za +Güney Afrika za +Könyaq Afrika za +Південна Ðфрика za +Жанубий Ðфрика za +Afurika tshipembe za +Nam Phi za +Nonne Afrike za +Mzantsi Afrika za +å—éž za +å—éž za +Emzantsi Afrika za +Zambia zm +Zambië zm +زامبيا zm +Zambiya zm +Ð—Ð°Ð¼Ð±Ñ–Ñ zm +Ð—Ð°Ð¼Ð±Ð¸Ñ zm +জামবিয়া zm +Zambi zm +Zà mbia zm +Zambie zm +Sambia zm +Sambia zm +Ζάμπια zm +Zambio zm +Sambia zm +زامبیا zm +Sambia zm +Zambie zm +An tSaimbia zm +Zámbia zm +זמביה zm +ज़ामà¥à¤¬à¤¿à¤¯à¤¾ zm +Zambija zm +SambÃa zm +ザンビア zm +ហ្សាំប៊ី zm +ìž ë¹„ì•„ zm +ຈາໄມàºàº²à»‰ zm +Zambija zm +Замбија zm +Замби zm +Å»ambia zm +Sambia zm +ਜੈਂਬੀਆ zm +Zâmbia zm +Zâmbia zm +Ð—Ð°Ð¼Ð±Ð¸Ñ zm +Zambiya zm +Zambija zm +Замбија zm +Zambija zm +ஜாமà¯à®ªà®¿à®¯à®¾ zm +Зомбиё zm +à¹à¸‹à¸¡à¹€à¸šà¸µà¸¢ zm +Ð—Ð°Ð¼Ð±Ñ–Ñ zm +Ð—Ð°Ð¼Ð±Ð¸Ñ zm +Zambeye zm +赞比亚 zm +尚比亞 zm +Zimbabwe zw +زيمبابوي zw +Zimbabve zw +Ð—Ñ‹Ð¼Ð±Ð°Ð±Ð²Ñ zw +Зимбабве zw +জিমà§à¦¬à¦¾à¦¬à§‹à§Ÿà§‡ zw +Zimbabve zw +Simbabwe zw +Simbabwe zw +Ζιμπάμπουε zw +Zimbabvo zw +زیمبابوه zw +An tSiombáib zw +Zimbabué zw +זימבבווה zw +जिमà¥à¤¬à¤¾à¤¬à¤µà¥‡ zw +Zimbabve zw +Simbabve zw +ジンãƒãƒ–エ zw +ហ្ស៊ីមបាបវ៉០zw +ì§ë°”브웨 zw +ລິຊາ zw +Zimbabve zw +Зимбабве zw +Замбабив zw +Å»imbabwe zw +Simbabwe zw +ਜਿੰਬਾਬਵੇਂ zw +Zimbabue zw +Зимбабве zw +Zimbabve zw +Зимбабве zw +Zimbabve zw +ஜிமà¯à®ªà®¾à®ªà¯‡ zw +Зимбобве zw +ซิมบับเว zw +Зімбабве zw +Зимбабве zw +Zimbabwè zw +津巴布韦 zw +è¾›å·´å¨ zw +Czech Republic cz diff --git a/kabc/distributionlist.cpp b/kabc/distributionlist.cpp new file mode 100644 index 000000000..ec363e414 --- /dev/null +++ b/kabc/distributionlist.cpp @@ -0,0 +1,298 @@ +/* + 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 <qapplication.h> +#include <qpair.h> +#include <qvaluelist.h> + +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kdebug.h> + +#include "distributionlist.h" + +using namespace KABC; + +DistributionList::DistributionList( DistributionListManager *manager, + const QString &name ) : + mManager( manager ), mName( name ) +{ + mManager->insert( this ); +} + +DistributionList::~DistributionList() +{ + mManager->remove( this ); +} + +void DistributionList::setName( const QString &name ) +{ + mName = name; +} + +QString DistributionList::name() const +{ + return mName; +} + +void DistributionList::insertEntry( const Addressee &a, const QString &email ) +{ + Entry e( a, email ); + + QValueList<Entry>::Iterator it; + for( it = mEntries.begin(); it != mEntries.end(); ++it ) { + if ( (*it).addressee.uid() == a.uid() ) { + /** + We have to check if both email addresses contains no data, + a simple 'email1 == email2' wont work here + */ + if ( ( (*it).email.isNull() && email.isEmpty() ) || + ( (*it).email.isEmpty() && email.isNull() ) || + ( (*it).email == email ) ) { + *it = e; + return; + } + } + } + mEntries.append( e ); +} + +void DistributionList::removeEntry( const Addressee &a, const QString &email ) +{ + QValueList<Entry>::Iterator it; + for( it = mEntries.begin(); it != mEntries.end(); ++it ) { + if ( (*it).addressee.uid() == a.uid() && (*it).email == email ) { + mEntries.remove( it ); + return; + } + } +} + +QStringList DistributionList::emails() const +{ + QStringList emails; + + Entry::List::ConstIterator it; + for( it = mEntries.begin(); it != mEntries.end(); ++it ) { + Addressee a = (*it).addressee; + QString email = (*it).email.isEmpty() ? a.fullEmail() : + a.fullEmail( (*it).email ); + + if ( !email.isEmpty() ) { + emails.append( email ); + } + } + + return emails; +} + +DistributionList::Entry::List DistributionList::entries() const +{ + return mEntries; +} + +typedef QValueList< QPair<QString, QString> > MissingEntryList; + +class DistributionListManager::DistributionListManagerPrivate +{ + public: + AddressBook *mAddressBook; + QMap< QString, MissingEntryList > mMissingEntries; +}; + +DistributionListManager::DistributionListManager( AddressBook *ab ) + : d( new DistributionListManagerPrivate ) +{ + d->mAddressBook = ab; + mLists.setAutoDelete( true ); +} + +DistributionListManager::~DistributionListManager() +{ + mLists.clear(); + + delete d; + d = 0; +} + +DistributionList *DistributionListManager::list( const QString &name ) +{ + DistributionList *list; + for( list = mLists.first(); list; list = mLists.next() ) { + if ( list->name() == name ) return list; + } + + return 0; +} + +void DistributionListManager::insert( DistributionList *l ) +{ + if ( !l ) + return; + + DistributionList *list; + for( list = mLists.first(); list; list = mLists.next() ) { + if ( list->name() == l->name() ) { + mLists.remove( list ); + break; + } + } + mLists.append( l ); +} + +void DistributionListManager::remove( DistributionList *l ) +{ + if ( !l ) + return; + + DistributionList *list; + for( list = mLists.first(); list; list = mLists.next() ) { + if ( list->name() == l->name() ) { + mLists.remove( list ); + return; + } + } +} + +QStringList DistributionListManager::listNames() +{ + QStringList names; + + DistributionList *list; + for( list = mLists.first(); list; list = mLists.next() ) { + names.append( list->name() ); + } + + return names; +} + +bool DistributionListManager::load() +{ + KSimpleConfig cfg( locateLocal( "data", "kabc/distlists" ) ); + + QMap<QString,QString> entryMap = cfg.entryMap( "DistributionLists" ); + cfg.setGroup( "DistributionLists" ); + + // clear old lists + mLists.clear(); + d->mMissingEntries.clear(); + + QMap<QString,QString>::ConstIterator it; + for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it ) { + QString name = it.key(); + QStringList value = cfg.readListEntry( name ); + + kdDebug(5700) << "DLM::load(): " << name << ": " << value.join(",") << endl; + + DistributionList *list = new DistributionList( this, name ); + + MissingEntryList missingEntries; + QStringList::ConstIterator entryIt = value.constBegin(); + while( entryIt != value.constEnd() ) { + QString id = *entryIt++; + QString email = *entryIt; + + kdDebug(5700) << "----- Entry " << id << endl; + + Addressee a = d->mAddressBook->findByUid( id ); + if ( !a.isEmpty() ) { + list->insertEntry( a, email ); + } else { + missingEntries.append( qMakePair( id, email ) ); + } + + if ( entryIt == value.end() ) + break; + ++entryIt; + } + + d->mMissingEntries.insert( name, missingEntries ); + } + + return true; +} + +bool DistributionListManager::save() +{ + kdDebug(5700) << "DistListManager::save()" << endl; + + KSimpleConfig cfg( locateLocal( "data", "kabc/distlists" ) ); + + cfg.deleteGroup( "DistributionLists" ); + cfg.setGroup( "DistributionLists" ); + + DistributionList *list; + for( list = mLists.first(); list; list = mLists.next() ) { + kdDebug(5700) << " Saving '" << list->name() << "'" << endl; + + QStringList value; + const DistributionList::Entry::List entries = list->entries(); + DistributionList::Entry::List::ConstIterator it; + for( it = entries.begin(); it != entries.end(); ++it ) { + value.append( (*it).addressee.uid() ); + value.append( (*it).email ); + } + + if ( d->mMissingEntries.find( list->name() ) != d->mMissingEntries.end() ) { + const MissingEntryList missList = d->mMissingEntries[ list->name() ]; + MissingEntryList::ConstIterator missIt; + for ( missIt = missList.begin(); missIt != missList.end(); ++missIt ) { + value.append( (*missIt).first ); + value.append( (*missIt).second ); + } + } + + cfg.writeEntry( list->name(), value ); + } + + cfg.sync(); + + return true; +} + +DistributionListWatcher* DistributionListWatcher::mSelf = 0; + +DistributionListWatcher::DistributionListWatcher() + : QObject( qApp, "DistributionListWatcher" ) +{ + mDirWatch = new KDirWatch; + mDirWatch->addFile( locateLocal( "data", "kabc/distlists" ) ); + + connect( mDirWatch, SIGNAL( dirty( const QString& ) ), SIGNAL( changed() ) ); + mDirWatch->startScan(); +} + +DistributionListWatcher::~DistributionListWatcher() +{ + delete mDirWatch; + mDirWatch = 0; +} + +DistributionListWatcher *DistributionListWatcher::self() +{ + kdWarning( !qApp ) << "No QApplication object available, you'll get a memleak!" << endl; + + if ( !mSelf ) + mSelf = new DistributionListWatcher(); + + return mSelf; +} + +#include "distributionlist.moc" diff --git a/kabc/distributionlist.h b/kabc/distributionlist.h new file mode 100644 index 000000000..2aab60094 --- /dev/null +++ b/kabc/distributionlist.h @@ -0,0 +1,217 @@ +/* + 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_DISTRIBUTIONLIST_H +#define KABC_DISTRIBUTIONLIST_H + +#include <kdirwatch.h> + +#include "addressbook.h" + +namespace KABC { + +class DistributionListManager; + +/** + @short Distribution list of email addresses + + This class represents a list of email addresses. Each email address is + associated with an address book entry. If the address book entry changes, the + entry in the distribution list is automatically updated. +*/ +class KABC_EXPORT DistributionList +{ + public: + /** + @short Distribution List Entry + + This class represents an entry of a distribution list. It consists of an + addressee and an email address. If the email address is null, the + preferred email address of the addressee is used. + */ + struct Entry + { + typedef QValueList<Entry> List; + + Entry() {} + Entry( const Addressee &_addressee, const QString &_email ) : + addressee( _addressee ), email( _email ) {} + + Addressee addressee; + QString email; + }; + + /** + Create distribution list object. + + @param manager Managing object of this list. + @param name Name of this list. + */ + DistributionList( DistributionListManager *manager, const QString &name ); + + /** + Destructor. + */ + ~DistributionList(); + + /** + Set name of this list. The name is used as key by the + DistributinListManager. + */ + void setName( const QString & ); + + /** + Get name of this list. + */ + QString name() const; + + /** + Insert an entry into this distribution list. If the entry already exists + nothing happens. + */ + void insertEntry( const Addressee &, const QString &email=QString::null ); + + /** + Remove an entry from this distribution list. If the entry doesn't exist + nothing happens. + */ + void removeEntry( const Addressee &, const QString &email=QString::null ); + + /** + Return list of email addresses, which belong to this distributon list. + These addresses can be directly used by e.g. a mail client. + */ + QStringList emails() const; + + /** + Return list of entries belonging to this distribution list. This function + is mainly useful for a distribution list editor. + */ + Entry::List entries() const; + + private: + DistributionListManager *mManager; + QString mName; + + Entry::List mEntries; +}; + +/** + @short Manager of distribution lists + + This class represents a collection of distribution lists, which are associated + with a given address book. +*/ +class KABC_EXPORT DistributionListManager +{ + public: + /** + Create manager for given address book. + */ + DistributionListManager( AddressBook * ); + + /** + Destructor. + */ + ~DistributionListManager(); + + /** + Return distribution list with given name. + */ + DistributionList *list( const QString &name ); // KDE4: add bool caseSensitive = true + + /** + Insert distribution list. If a list with this name already exists, nothing + happens. The passed object is deleted by the manager. + */ + void insert( DistributionList * ); + + /** + Remove distribution list. If a list with this name doesn't exist, nothing + happens. + */ + void remove( DistributionList * ); + + /** + Return names of all distribution lists managed by this manager. + */ + QStringList listNames(); + + /** + Load distribution lists form disk. + */ + bool load(); + + /** + Save distribution lists to disk. + */ + bool save(); + + private: + class DistributionListManagerPrivate; + DistributionListManagerPrivate *d; + + QPtrList<DistributionList> mLists; +}; + +/** + @short Watchdog for distribution lists + + This class provides a changed() signal that i emitted when the + distribution lists has changed in some way. + + Exapmle: + + \code + KABC::DistributionListWatcher *watchdog = KABC::DistributionListWatcher::self() + + connect( watchdog, SIGNAL( changed() ), SLOT( doSomething() ) ); + \endcode +*/ + +class KABC_EXPORT DistributionListWatcher : public QObject +{ + Q_OBJECT + + public: + /** + * Returns the watcher object. + */ + static DistributionListWatcher *self(); + + signals: + /** + * This signal is emmitted whenever the distribution lists has + * changed (if a list was added or removed, when a list was + * renamed or the entries of the list changed). + */ + void changed(); + + protected: + DistributionListWatcher(); + ~DistributionListWatcher(); + + private: + static DistributionListWatcher* mSelf; + KDirWatch *mDirWatch; +}; + +} +#endif diff --git a/kabc/distributionlistdialog.cpp b/kabc/distributionlistdialog.cpp new file mode 100644 index 000000000..4533734da --- /dev/null +++ b/kabc/distributionlistdialog.cpp @@ -0,0 +1,399 @@ +/* + 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 <qlistview.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <kinputdialog.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include "addressbook.h" +#include "addresseedialog.h" +#include "distributionlist.h" + +#include "distributionlistdialog.h" +#include "distributionlistdialog.moc" + +using namespace KABC; + +DistributionListDialog::DistributionListDialog( AddressBook *addressBook, QWidget *parent) + : KDialogBase( parent, "", true, i18n("Configure Distribution Lists"), Ok, Ok, true) +{ + mEditor = new DistributionListEditorWidget( addressBook, this ); + setMainWidget( mEditor ); + + connect( this, SIGNAL( okClicked() ), mEditor, SLOT( save() ) ); +} + +DistributionListDialog::~DistributionListDialog() +{ +} + +// TODO KDE4: Add d-pointer to EmailSelector, make sEmailMap a member variable +static QMap<QWidget*,QString> *sEmailMap = 0; + +EmailSelector::EmailSelector( const QStringList &emails, const QString ¤t, + QWidget *parent ) : + KDialogBase( KDialogBase::Plain, i18n("Select Email Address"), Ok, Ok, + parent ) +{ + if (!sEmailMap) + sEmailMap = new QMap<QWidget*,QString>(); + QFrame *topFrame = plainPage(); + QBoxLayout *topLayout = new QVBoxLayout( topFrame ); + + mButtonGroup = new QButtonGroup( 1, Horizontal, i18n("Email Addresses"), + topFrame ); + topLayout->addWidget( mButtonGroup ); + + QStringList::ConstIterator it; + for( it = emails.begin(); it != emails.end(); ++it ) { + QRadioButton *button = new QRadioButton( *it, mButtonGroup ); + sEmailMap->insert( button, *it ); + if ( (*it) == current ) { + mButtonGroup->setButton(mButtonGroup->id(button)); + } + } +} + +QString EmailSelector::selected() +{ + QButton *button = mButtonGroup->selected(); + if ( button ) return (*sEmailMap)[button]; + return QString::null; +} + +QString EmailSelector::getEmail( const QStringList &emails, const QString ¤t, + QWidget *parent ) +{ + EmailSelector *dlg = new EmailSelector( emails, current, parent ); + dlg->exec(); + + QString result = dlg->selected(); + + delete dlg; + + return result; +} + +class EntryItem : public QListViewItem +{ + public: + EntryItem( QListView *parent, const Addressee &addressee, + const QString &email=QString::null ) : + QListViewItem( parent ), + mAddressee( addressee ), + mEmail( email ) + { + setText( 0, addressee.realName() ); + if( email.isEmpty() ) { + setText( 1, addressee.preferredEmail() ); + setText( 2, i18n("Yes") ); + } else { + setText( 1, email ); + setText( 2, i18n("No") ); + } + } + + Addressee addressee() const + { + return mAddressee; + } + + QString email() const + { + return mEmail; + } + + private: + Addressee mAddressee; + QString mEmail; +}; + +DistributionListEditorWidget::DistributionListEditorWidget( AddressBook *addressBook, QWidget *parent) : + QWidget( parent ), + mAddressBook( addressBook ) +{ + kdDebug(5700) << "DistributionListEditor()" << endl; + + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setSpacing( KDialog::spacingHint() ); + + QBoxLayout *nameLayout = new QHBoxLayout( topLayout) ; + + mNameCombo = new QComboBox( this ); + nameLayout->addWidget( mNameCombo ); + connect( mNameCombo, SIGNAL( activated( int ) ), SLOT( updateEntryView() ) ); + + mNewButton = new QPushButton( i18n("New List..."), this ); + nameLayout->addWidget( mNewButton ); + connect( mNewButton, SIGNAL( clicked() ), SLOT( newList() ) ); + + mEditButton = new QPushButton( i18n("Rename List..."), this ); + nameLayout->addWidget( mEditButton ); + connect( mEditButton, SIGNAL( clicked() ), SLOT( editList() ) ); + + mRemoveButton = new QPushButton( i18n("Remove List"), this ); + nameLayout->addWidget( mRemoveButton ); + connect( mRemoveButton, SIGNAL( clicked() ), SLOT( removeList() ) ); + + QGridLayout *gridLayout = new QGridLayout( topLayout, 3, 3 ); + gridLayout->setColStretch(1, 1); + + QLabel *listLabel = new QLabel( i18n("Available addresses:"), this ); + gridLayout->addWidget( listLabel, 0, 0 ); + + mListLabel = new QLabel( this ); + gridLayout->addMultiCellWidget( mListLabel, 0, 0, 1, 2 ); + + mAddresseeView = new QListView( this ); + mAddresseeView->addColumn( i18n("Name") ); + mAddresseeView->addColumn( i18n("Preferred Email") ); + mAddresseeView->setAllColumnsShowFocus( true ); + gridLayout->addWidget( mAddresseeView, 1, 0 ); + connect( mAddresseeView, SIGNAL( selectionChanged() ), + SLOT( slotSelectionAddresseeViewChanged() ) ); + connect( mAddresseeView, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( addEntry() ) ); + + mAddEntryButton = new QPushButton( i18n("Add Entry"), this ); + mAddEntryButton->setEnabled(false); + gridLayout->addWidget( mAddEntryButton, 2, 0 ); + connect( mAddEntryButton, SIGNAL( clicked() ), SLOT( addEntry() ) ); + + mEntryView = new QListView( this ); + mEntryView->addColumn( i18n("Name") ); + mEntryView->addColumn( i18n("Email") ); + mEntryView->addColumn( i18n("Use Preferred") ); + mEntryView->setEnabled(false); + mEntryView->setAllColumnsShowFocus( true ); + gridLayout->addMultiCellWidget( mEntryView, 1, 1, 1, 2 ); + connect( mEntryView, SIGNAL( selectionChanged() ), + SLOT( slotSelectionEntryViewChanged() ) ); + + mChangeEmailButton = new QPushButton( i18n("Change Email..."), this ); + gridLayout->addWidget( mChangeEmailButton, 2, 1 ); + connect( mChangeEmailButton, SIGNAL( clicked() ), SLOT( changeEmail() ) ); + + mRemoveEntryButton = new QPushButton( i18n("Remove Entry"), this ); + gridLayout->addWidget( mRemoveEntryButton, 2, 2 ); + connect( mRemoveEntryButton, SIGNAL( clicked() ), SLOT( removeEntry() ) ); + + mManager = new DistributionListManager( mAddressBook ); + mManager->load(); + + updateAddresseeView(); + updateNameCombo(); +} + +DistributionListEditorWidget::~DistributionListEditorWidget() +{ + kdDebug(5700) << "~DistributionListEditor()" << endl; + + delete mManager; +} + +void DistributionListEditorWidget::save() +{ + mManager->save(); +} + +void DistributionListEditorWidget::slotSelectionEntryViewChanged() +{ + EntryItem *entryItem = static_cast<EntryItem *>( mEntryView->selectedItem() ); + bool state=entryItem; + + mChangeEmailButton->setEnabled(state); + mRemoveEntryButton->setEnabled(state); +} + +void DistributionListEditorWidget::newList() +{ + bool ok; + QString name = KInputDialog::getText( i18n( "New Distribution List" ), + i18n( "Please enter &name:" ), QString::null, &ok ); + if (!ok) return; + + new DistributionList( mManager, name ); + + mNameCombo->clear(); + mNameCombo->insertStringList( mManager->listNames() ); + mNameCombo->setCurrentItem( mNameCombo->count() - 1 ); + + updateEntryView(); + slotSelectionAddresseeViewChanged(); +} + +void DistributionListEditorWidget::editList() +{ + QString oldName = mNameCombo->currentText(); + bool ok; + QString name = KInputDialog::getText( i18n( "Distribution List" ), + i18n( "Please change &name:" ), oldName, &ok ); + if (!ok) return; + + DistributionList *list = mManager->list( oldName ); + list->setName( name ); + + mNameCombo->clear(); + mNameCombo->insertStringList( mManager->listNames() ); + mNameCombo->setCurrentItem( mNameCombo->count() - 1 ); + + updateEntryView(); + slotSelectionAddresseeViewChanged(); +} + +void DistributionListEditorWidget::removeList() +{ + int result = KMessageBox::warningContinueCancel( this, + i18n("Delete distribution list '%1'?") .arg( mNameCombo->currentText() ), + QString::null, KStdGuiItem::del() ); + + if ( result != KMessageBox::Continue ) return; + + mManager->remove( mManager->list( mNameCombo->currentText() ) ); + mNameCombo->removeItem( mNameCombo->currentItem() ); + + updateEntryView(); + slotSelectionAddresseeViewChanged(); +} + +void DistributionListEditorWidget::addEntry() +{ + AddresseeItem *addresseeItem = + static_cast<AddresseeItem *>( mAddresseeView->selectedItem() ); + + if( !addresseeItem ) { + kdDebug(5700) << "DLE::addEntry(): No addressee selected." << endl; + return; + } + + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) { + kdDebug(5700) << "DLE::addEntry(): No dist list '" << mNameCombo->currentText() << "'" << endl; + return; + } + + list->insertEntry( addresseeItem->addressee() ); + updateEntryView(); + slotSelectionAddresseeViewChanged(); +} + +void DistributionListEditorWidget::removeEntry() +{ + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) return; + + EntryItem *entryItem = + static_cast<EntryItem *>( mEntryView->selectedItem() ); + if ( !entryItem ) return; + + list->removeEntry( entryItem->addressee(), entryItem->email() ); + delete entryItem; +} + +void DistributionListEditorWidget::changeEmail() +{ + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) return; + + EntryItem *entryItem = + static_cast<EntryItem *>( mEntryView->selectedItem() ); + if ( !entryItem ) return; + + QString email = EmailSelector::getEmail( entryItem->addressee().emails(), + entryItem->email(), this ); + list->removeEntry( entryItem->addressee(), entryItem->email() ); + list->insertEntry( entryItem->addressee(), email ); + + updateEntryView(); +} + +void DistributionListEditorWidget::updateEntryView() +{ + if ( mNameCombo->currentText().isEmpty() ) { + mListLabel->setText( i18n("Selected addressees:") ); + } else { + mListLabel->setText( i18n("Selected addresses in '%1':") + .arg( mNameCombo->currentText() ) ); + } + + mEntryView->clear(); + + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) { + mEditButton->setEnabled(false); + mRemoveButton->setEnabled(false); + mChangeEmailButton->setEnabled(false); + mRemoveEntryButton->setEnabled(false); + mAddresseeView->setEnabled(false); + mEntryView->setEnabled(false); + return; + } else { + mEditButton->setEnabled(true); + mRemoveButton->setEnabled(true); + mAddresseeView->setEnabled(true); + mEntryView->setEnabled(true); + } + + DistributionList::Entry::List entries = list->entries(); + DistributionList::Entry::List::ConstIterator it; + for( it = entries.begin(); it != entries.end(); ++it ) { + new EntryItem( mEntryView, (*it).addressee, (*it).email ); + } + + EntryItem *entryItem = static_cast<EntryItem *>( mEntryView->selectedItem() ); + bool state=entryItem; + + mChangeEmailButton->setEnabled(state); + mRemoveEntryButton->setEnabled(state); +} + +void DistributionListEditorWidget::updateAddresseeView() +{ + mAddresseeView->clear(); + + AddressBook::Iterator it; + for( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) { + new AddresseeItem( mAddresseeView, *it ); + } +} + +void DistributionListEditorWidget::updateNameCombo() +{ + mNameCombo->insertStringList( mManager->listNames() ); + + updateEntryView(); +} + +void DistributionListEditorWidget::slotSelectionAddresseeViewChanged() +{ + AddresseeItem *addresseeItem = + static_cast<AddresseeItem *>( mAddresseeView->selectedItem() ); + bool state=addresseeItem; + mAddEntryButton->setEnabled( state && !mNameCombo->currentText().isEmpty()); +} diff --git a/kabc/distributionlistdialog.h b/kabc/distributionlistdialog.h new file mode 100644 index 000000000..9a163ef7d --- /dev/null +++ b/kabc/distributionlistdialog.h @@ -0,0 +1,139 @@ +/* + 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_DISTRIBUTIONLISTDIALOG_H +#define KABC_DISTRIBUTIONLISTDIALOG_H + +#include <qwidget.h> + +#include <kdialogbase.h> + +class QListView; +class QComboBox; +class QButtonGroup; + +namespace KABC { + +class AddressBook; +class DistributionListEditorWidget; +class DistributionListManager; + +/** + @short Frontend to create distribution lists + + Creating a new DistributionListDialog does automatically + load all addressees and distribution lists from the config + files. The changes will be saved when clicking the 'OK' + button. + + Example: + + \code + KABC::DistributionListDialog *dlg = new + KABC::DistributionListDialog( KABC::StdAddressBook::self(), this ); + + dlg->exec(); + \endcode +*/ +class KABC_EXPORT DistributionListDialog : public KDialogBase +{ + Q_OBJECT + + public: + /** + Constructor. + + @param ab The addressbook, the addressees should be used from + @param parent The parent widget + */ + DistributionListDialog( AddressBook *ab, QWidget *parent ); + + /** + Destructor. + */ + virtual ~DistributionListDialog(); + + private: + DistributionListEditorWidget *mEditor; + + struct Data; + Data *d; +}; + +/** + @short Helper class +*/ +class KABC_EXPORT EmailSelector : public KDialogBase +{ + public: + EmailSelector( const QStringList &emails, const QString ¤t, + QWidget *parent ); + + QString selected(); + + static QString getEmail( const QStringList &emails, const QString ¤t, + QWidget *parent ); + + private: + QButtonGroup *mButtonGroup; +}; + +/** + @short Helper class +*/ +class KABC_EXPORT DistributionListEditorWidget : public QWidget +{ + Q_OBJECT + + public: + DistributionListEditorWidget( AddressBook *, QWidget *parent ); + virtual ~DistributionListEditorWidget(); + + private slots: + void newList(); + void editList(); + void removeList(); + void addEntry(); + void removeEntry(); + void changeEmail(); + void updateEntryView(); + void updateAddresseeView(); + void updateNameCombo(); + void slotSelectionEntryViewChanged(); + void slotSelectionAddresseeViewChanged(); + void save(); + + private: + QComboBox *mNameCombo; + QLabel *mListLabel; + QListView *mEntryView; + QListView *mAddresseeView; + + AddressBook *mAddressBook; + DistributionListManager *mManager; + QPushButton *mNewButton, *mEditButton, *mRemoveButton; + QPushButton *mChangeEmailButton, *mRemoveEntryButton, *mAddEntryButton; + + struct Data; + Data *d; +}; + +} +#endif diff --git a/kabc/distributionlisteditor.cpp b/kabc/distributionlisteditor.cpp new file mode 100644 index 000000000..c0de3f137 --- /dev/null +++ b/kabc/distributionlisteditor.cpp @@ -0,0 +1,310 @@ +/* + 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 <qlistview.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> + +#include <kinputdialog.h> +#include <klocale.h> +#include <kdebug.h> + +#include "addressbook.h" +#include "addresseedialog.h" +#include "distributionlist.h" + +#include "distributionlisteditor.h" +#include "distributionlisteditor.moc" + +using namespace KABC; + +EmailSelectDialog::EmailSelectDialog( const QStringList &emails, const QString ¤t, + QWidget *parent ) : + KDialogBase( KDialogBase::Plain, i18n("Select Email Address"), Ok, Ok, + parent ) +{ + QFrame *topFrame = plainPage(); + QBoxLayout *topLayout = new QVBoxLayout( topFrame ); + + mButtonGroup = new QButtonGroup( 1, Horizontal, i18n("Email Addresses"), + topFrame ); + mButtonGroup->setRadioButtonExclusive( true ); + topLayout->addWidget( mButtonGroup ); + + QStringList::ConstIterator it; + for( it = emails.begin(); it != emails.end(); ++it ) { + QRadioButton *button = new QRadioButton( *it, mButtonGroup ); + if ( (*it) == current ) { + button->setDown( true ); + } + } +} + +QString EmailSelectDialog::selected() +{ + QButton *button = mButtonGroup->selected(); + if ( button ) return button->text(); + return QString::null; +} + +QString EmailSelectDialog::getEmail( const QStringList &emails, const QString ¤t, + QWidget *parent ) +{ + EmailSelectDialog *dlg = new EmailSelectDialog( emails, current, parent ); + dlg->exec(); + + QString result = dlg->selected(); + + delete dlg; + + return result; +} + +class EditEntryItem : public QListViewItem +{ + public: + EditEntryItem( QListView *parent, const Addressee &addressee, + const QString &email=QString::null ) : + QListViewItem( parent ), + mAddressee( addressee ), + mEmail( email ) + { + setText( 0, addressee.realName() ); + if( email.isEmpty() ) { + setText( 1, addressee.preferredEmail() ); + setText( 2, i18n("Yes") ); + } else { + setText( 1, email ); + setText( 2, i18n("No") ); + } + } + + Addressee addressee() const + { + return mAddressee; + } + + QString email() const + { + return mEmail; + } + + private: + Addressee mAddressee; + QString mEmail; +}; + +DistributionListEditor::DistributionListEditor( AddressBook *addressBook, QWidget *parent) : + QWidget( parent ), + mAddressBook( addressBook ) +{ + kdDebug(5700) << "DistributionListEditor()" << endl; + + QBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setMargin( KDialog::marginHint() ); + topLayout->setSpacing( KDialog::spacingHint() ); + + QBoxLayout *nameLayout = new QHBoxLayout( topLayout) ; + + mNameCombo = new QComboBox( this ); + nameLayout->addWidget( mNameCombo ); + connect( mNameCombo, SIGNAL( activated( int ) ), SLOT( updateEntryView() ) ); + + newButton = new QPushButton( i18n("New List"), this ); + nameLayout->addWidget( newButton ); + connect( newButton, SIGNAL( clicked() ), SLOT( newList() ) ); + + removeButton = new QPushButton( i18n("Remove List"), this ); + nameLayout->addWidget( removeButton ); + connect( removeButton, SIGNAL( clicked() ), SLOT( removeList() ) ); + + mEntryView = new QListView( this ); + mEntryView->addColumn( i18n("Name") ); + mEntryView->addColumn( i18n("Email") ); + mEntryView->addColumn( i18n("Use Preferred") ); + topLayout->addWidget( mEntryView ); + connect(mEntryView,SIGNAL(selectionChanged ()),this, SLOT(slotSelectionEntryViewChanged())); + + changeEmailButton = new QPushButton( i18n("Change Email"), this ); + topLayout->addWidget( changeEmailButton ); + connect( changeEmailButton, SIGNAL( clicked() ), SLOT( changeEmail() ) ); + + removeEntryButton = new QPushButton( i18n("Remove Entry"), this ); + topLayout->addWidget( removeEntryButton ); + connect( removeEntryButton, SIGNAL( clicked() ), SLOT( removeEntry() ) ); + + addEntryButton = new QPushButton( i18n("Add Entry"), this ); + topLayout->addWidget( addEntryButton ); + connect( addEntryButton, SIGNAL( clicked() ), SLOT( addEntry() ) ); + + mAddresseeView = new QListView( this ); + mAddresseeView->addColumn( i18n("Name") ); + mAddresseeView->addColumn( i18n("Preferred Email") ); + topLayout->addWidget( mAddresseeView ); + + + connect(mAddresseeView,SIGNAL(selectionChanged ()),this, SLOT(slotSelectionAddresseeViewChanged())); + + mManager = new DistributionListManager( mAddressBook ); + mManager->load(); + + updateAddresseeView(); + updateNameCombo(); + removeButton->setEnabled(!mManager->listNames().isEmpty()); +} + +DistributionListEditor::~DistributionListEditor() +{ + kdDebug(5700) << "~DistributionListEditor()" << endl; + + mManager->save(); + delete mManager; +} + +void DistributionListEditor::slotSelectionEntryViewChanged() +{ + EditEntryItem *entryItem = dynamic_cast<EditEntryItem *>( mEntryView->selectedItem() ); + bool state = (entryItem != 0L); + + changeEmailButton->setEnabled(state); + removeEntryButton->setEnabled(state); +} + +void DistributionListEditor::newList() +{ + bool ok = false; + QString name = KInputDialog::getText( i18n("New Distribution List"), + i18n("Please enter name:"), + QString::null, &ok, this ); + if ( !ok ) + return; + + new DistributionList( mManager, name ); + + mNameCombo->insertItem( name ); + removeButton->setEnabled(true); + updateEntryView(); +} + +void DistributionListEditor::removeList() +{ + mManager->remove( mManager->list( mNameCombo->currentText() ) ); + mNameCombo->removeItem( mNameCombo->currentItem() ); + removeButton->setEnabled(!mManager->listNames().isEmpty()); + addEntryButton->setEnabled( !mNameCombo->currentText().isEmpty()); + updateEntryView(); +} + +void DistributionListEditor::addEntry() +{ + AddresseeItem *addresseeItem = + dynamic_cast<AddresseeItem *>( mAddresseeView->selectedItem() ); + + if( !addresseeItem ) { + kdDebug(5700) << "DLE::addEntry(): No addressee selected." << endl; + return; + } + + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) { + kdDebug(5700) << "DLE::addEntry(): No dist list '" << mNameCombo->currentText() << "'" << endl; + return; + } + + list->insertEntry( addresseeItem->addressee() ); + updateEntryView(); + slotSelectionAddresseeViewChanged(); +} + +void DistributionListEditor::removeEntry() +{ + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) return; + + EditEntryItem *entryItem = + dynamic_cast<EditEntryItem *>( mEntryView->selectedItem() ); + if ( !entryItem ) return; + + list->removeEntry( entryItem->addressee(), entryItem->email() ); + delete entryItem; +} + +void DistributionListEditor::changeEmail() +{ + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) return; + + EditEntryItem *entryItem = + dynamic_cast<EditEntryItem *>( mEntryView->selectedItem() ); + if ( !entryItem ) return; + + QString email = EmailSelectDialog::getEmail( entryItem->addressee().emails(), + entryItem->email(), this ); + list->removeEntry( entryItem->addressee(), entryItem->email() ); + list->insertEntry( entryItem->addressee(), email ); + + updateEntryView(); +} + +void DistributionListEditor::updateEntryView() +{ + DistributionList *list = mManager->list( mNameCombo->currentText() ); + if ( !list ) return; + + mEntryView->clear(); + DistributionList::Entry::List entries = list->entries(); + DistributionList::Entry::List::ConstIterator it; + for( it = entries.begin(); it != entries.end(); ++it ) { + new EditEntryItem( mEntryView, (*it).addressee, (*it).email ); + } + EditEntryItem *entryItem = dynamic_cast<EditEntryItem *>( mEntryView->selectedItem() ); + bool state = (entryItem != 0L); + + changeEmailButton->setEnabled(state); + removeEntryButton->setEnabled(state); +} + +void DistributionListEditor::updateAddresseeView() +{ + mAddresseeView->clear(); + + AddressBook::Iterator it; + for( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) { + new AddresseeItem( mAddresseeView, *it ); + } +} + +void DistributionListEditor::updateNameCombo() +{ + mNameCombo->insertStringList( mManager->listNames() ); + + updateEntryView(); +} + +void DistributionListEditor::slotSelectionAddresseeViewChanged() +{ + AddresseeItem *addresseeItem = + dynamic_cast<AddresseeItem *>( mAddresseeView->selectedItem() ); + bool state = (addresseeItem != 0L); + addEntryButton->setEnabled( state && !mNameCombo->currentText().isEmpty()); +} diff --git a/kabc/distributionlisteditor.h b/kabc/distributionlisteditor.h new file mode 100644 index 000000000..68bd917de --- /dev/null +++ b/kabc/distributionlisteditor.h @@ -0,0 +1,86 @@ +/* + 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_DISTRIBUTIONLISTEDITOR_H +#define KABC_DISTRIBUTIONLISTEDITOR_H + +#include <qwidget.h> + +#include <kdialogbase.h> + +class QListView; +class QComboBox; +class QButtonGroup; + +namespace KABC { + +class AddressBook; +class DistributionListManager; + +class KABC_EXPORT EmailSelectDialog : public KDialogBase +{ + public: + EmailSelectDialog( const QStringList &emails, const QString ¤t, + QWidget *parent ); + + QString selected(); + + static QString getEmail( const QStringList &emails, const QString ¤t, + QWidget *parent ); + + private: + QButtonGroup *mButtonGroup; +}; + +/** + @obsolete +*/ +class DistributionListEditor : public QWidget +{ + Q_OBJECT + public: + DistributionListEditor( AddressBook *, QWidget *parent ); + virtual ~DistributionListEditor(); + + private slots: + void newList(); + void removeList(); + void addEntry(); + void removeEntry(); + void changeEmail(); + void updateEntryView(); + void updateAddresseeView(); + void updateNameCombo(); + void slotSelectionEntryViewChanged(); + void slotSelectionAddresseeViewChanged(); + + private: + QComboBox *mNameCombo; + QListView *mEntryView; + QListView *mAddresseeView; + + AddressBook *mAddressBook; + DistributionListManager *mManager; + QPushButton *newButton, *removeButton; + QPushButton *changeEmailButton,*removeEntryButton,*addEntryButton; +}; + +} + +#endif diff --git a/kabc/errorhandler.cpp b/kabc/errorhandler.cpp new file mode 100644 index 000000000..1e3966ac8 --- /dev/null +++ b/kabc/errorhandler.cpp @@ -0,0 +1,55 @@ +/* + 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 <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include <qapplication.h> + +#include "errorhandler.h" + +using namespace KABC; + +void ConsoleErrorHandler::error( const QString &msg ) +{ + // no debug area is ok here + kdError() << msg << endl; +} + + +void GUIErrorHandler::error( const QString &msg ) +{ + KMessageBox::error( 0, msg, i18n( "Error in libkabc" ) ); +} + + +GuiErrorHandler::GuiErrorHandler( QWidget *parent ) + : mParent( parent ) +{ +} + +void GuiErrorHandler::error( const QString &msg ) +{ + if (qApp) + KMessageBox::error( mParent, msg ); +} diff --git a/kabc/errorhandler.h b/kabc/errorhandler.h new file mode 100644 index 000000000..e112ed605 --- /dev/null +++ b/kabc/errorhandler.h @@ -0,0 +1,95 @@ +/* + 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 <qstring.h> + +#include <kdelibs_export.h> + +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: + /** + Show error message. + */ + virtual void error( const QString &msg ) = 0; +}; + +/** + This class prints the error messages to stderr via kdError(). +*/ +class KABC_EXPORT ConsoleErrorHandler : public ErrorHandler +{ + public: + virtual void error( const QString &msg ); +}; + +/** + This class shows messages boxes for every + error message. + + \deprecated Use GuiErrorHandler instead. +*/ +class KABC_EXPORT GUIErrorHandler : public ErrorHandler +{ + public: + virtual void error( const QString &msg ); +}; + +/** + This class shows messages boxes for every + error message. +*/ +class KABC_EXPORT GuiErrorHandler : public ErrorHandler +{ + public: + /** + Create error handler. + + \param parent Widget which is used as parent for the error dialogs. + */ + GuiErrorHandler( QWidget *parent ); + + virtual void error( const QString &msg ); + + private: + QWidget *mParent; + + class Private; + Private *d; +}; + +} + +#endif diff --git a/kabc/field.h b/kabc/field.h new file mode 100644 index 000000000..6bc246a26 --- /dev/null +++ b/kabc/field.h @@ -0,0 +1,176 @@ +/* + 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 <qstring.h> +#include <qvaluelist.h> + +#include "addressee.h" + +class KConfig; + +namespace KABC { + +class KABC_EXPORT Field +{ + class FieldImpl; + friend class FieldImpl; + +public: + typedef QValueList<Field *> List; + + /** + * @li @p All - + * @li @p Frequent - + * @li @p Address - + * @li @p Email - + * @li @p Personal - + * @li @p Organization - + * @li @p CustomCategory - + */ + enum FieldCategory + { + All = 0x0, + Frequent = 0x01, + Address = 0x02, + Email = 0x04, + Personal = 0x08, + Organization = 0x10, + 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 field category. + */ + static QString categoryLabel( int category ); + + /** + * Returns a string representation of the value the field has in the given + * Addressee. Returns QString::null, 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. Returns true on success + * or 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. + */ + virtual bool isCustom(); + + /** + * Returns, if the field is equal with @a field. + */ + 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( KConfig *cfg, const QString &identifier, + const Field::List &fields ); + /** + * This is the same as above, with the difference, that + * the list is stored in KGlobal::config() in group "KABCFields". + */ + 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( KConfig *cfg, const QString &identifier ); + + /** + * This is the same as above, with the difference, that + * the list is loaded from KGlobal::config() from group "KABCFields". + */ + static Field::List restoreFields( const QString &identifier ); + +protected: + static void createField( int id, int category = 0 ); + static void createDefaultField( int id, int category = 0 ); + +private: + Field( FieldImpl * ); + virtual ~Field(); + + FieldImpl *mImpl; + + static Field::List mAllFields; + static Field::List mDefaultFields; + static Field::List mCustomFields; +}; + +} +#endif diff --git a/kabc/format.h b/kabc/format.h new file mode 100644 index 000000000..7c6abfb6c --- /dev/null +++ b/kabc/format.h @@ -0,0 +1,49 @@ +/* + 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_FORMAT_H +#define KABC_FORMAT_H + +#include <qstring.h> + +#include <kdelibs_export.h> + +namespace KABC { + +class AddressBook; + +/** + @deprecated use FormatPlugin instead +*/ +class KABC_EXPORT_DEPRECATED Format +{ + public: + /** + Load addressbook from file. + */ + virtual bool load( AddressBook *, const QString &fileName ) = 0; + /** + Save addressbook to file. + */ + virtual bool save( AddressBook *, const QString &fileName ) = 0; +}; + +} + +#endif diff --git a/kabc/formatfactory.cpp b/kabc/formatfactory.cpp new file mode 100644 index 000000000..13524e21d --- /dev/null +++ b/kabc/formatfactory.cpp @@ -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. +*/ + +#include <kdebug.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kstaticdeleter.h> + +#include <qfile.h> + +#include "vcardformatplugin.h" + +#include "formatfactory.h" + +using namespace KABC; + +FormatFactory *FormatFactory::mSelf = 0; +static KStaticDeleter<FormatFactory> factoryDeleter; + +FormatFactory *FormatFactory::self() +{ + kdDebug(5700) << "FormatFactory::self()" << endl; + + if ( !mSelf ) + factoryDeleter.setObject( mSelf, new FormatFactory ); + + return mSelf; +} + +FormatFactory::FormatFactory() +{ + mFormatList.setAutoDelete( true ); + + // dummy entry for default format + FormatInfo *info = new FormatInfo; + info->library = "<NoLibrary>"; + info->nameLabel = i18n( "vCard" ); + info->descriptionLabel = i18n( "vCard Format" ); + mFormatList.insert( "vcard", info ); + + const QStringList list = KGlobal::dirs()->findAllResources( "data" ,"kabc/formats/*.desktop", true, true ); + for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + { + KSimpleConfig config( *it, true ); + + if ( !config.hasGroup( "Misc" ) || !config.hasGroup( "Plugin" ) ) + continue; + + info = new FormatInfo; + + config.setGroup( "Plugin" ); + QString type = config.readEntry( "Type" ); + info->library = config.readEntry( "X-KDE-Library" ); + + config.setGroup( "Misc" ); + info->nameLabel = config.readEntry( "Name" ); + info->descriptionLabel = config.readEntry( "Comment", i18n( "No description available." ) ); + + mFormatList.insert( type, info ); + } +} + +FormatFactory::~FormatFactory() +{ + mFormatList.clear(); +} + +QStringList FormatFactory::formats() +{ + QStringList retval; + + // make sure 'vcard' is the first entry + retval << "vcard"; + + QDictIterator<FormatInfo> it( mFormatList ); + for ( ; it.current(); ++it ) + if ( it.currentKey() != "vcard" ) + retval << it.currentKey(); + + return retval; +} + +FormatInfo *FormatFactory::info( const QString &type ) +{ + if ( type.isEmpty() ) + return 0; + else + return mFormatList[ type ]; +} + +FormatPlugin *FormatFactory::format( const QString& type ) +{ + FormatPlugin *format = 0; + + if ( type.isEmpty() ) + return 0; + + if ( type == "vcard" ) { + format = new VCardFormatPlugin; + format->setType( type ); + format->setNameLabel( i18n( "vCard" ) ); + format->setDescriptionLabel( i18n( "vCard Format" ) ); + return format; + } + + FormatInfo *fi = mFormatList[ type ]; + if (!fi) + return 0; + QString libName = fi->library; + + KLibrary *library = openLibrary( libName ); + if ( !library ) + return 0; + + void *format_func = library->symbol( "format" ); + + if ( format_func ) { + format = ((FormatPlugin* (*)())format_func)(); + format->setType( type ); + format->setNameLabel( fi->nameLabel ); + format->setDescriptionLabel( fi->descriptionLabel ); + } else { + kdDebug( 5700 ) << "'" << libName << "' is not a format plugin." << endl; + return 0; + } + + return format; +} + + +KLibrary *FormatFactory::openLibrary( const QString& libName ) +{ + KLibrary *library = 0; + + QString path = KLibLoader::findLibrary( QFile::encodeName( libName ) ); + + if ( path.isEmpty() ) { + kdDebug( 5700 ) << "No format plugin library was found!" << endl; + return 0; + } + + library = KLibLoader::self()->library( QFile::encodeName( path ) ); + + if ( !library ) { + kdDebug( 5700 ) << "Could not load library '" << libName << "'" << endl; + return 0; + } + + return library; +} diff --git a/kabc/formatfactory.h b/kabc/formatfactory.h new file mode 100644 index 000000000..f3e270a4b --- /dev/null +++ b/kabc/formatfactory.h @@ -0,0 +1,101 @@ +/* + 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_FORMATFACTORY_H +#define KABC_FORMATFACTORY_H + +#include <qdict.h> +#include <qstring.h> + +#include <kconfig.h> +#include <klibloader.h> + +#include "formatplugin.h" + +namespace KABC { + +struct FormatInfo +{ + QString library; + QString nameLabel; + QString descriptionLabel; +}; + +/** + * Class for loading format plugins. + * + * Example: + * + * \code + * KABC::FormatFactory *factory = KABC::FormatFactory::self(); + * + * QStringList list = factory->formats(); + * QStringList::Iterator it; + * for ( it = list.begin(); it != list.end(); ++it ) { + * KABC::FormatPlugin *format = factory->format( (*it) ); + * // do something with format + * } + * \endcode + */ +class KABC_EXPORT FormatFactory +{ + public: + + /** + Destructor. + */ + ~FormatFactory(); + + /** + * Returns the global format factory. + */ + static FormatFactory *self(); + + /** + * Returns a pointer to a format object or a null pointer + * if format type doesn't exist. + * + * @param type The type of the format, returned by formats() + */ + FormatPlugin *format( const QString &type ); + + /** + * Returns a list of all available format types. + */ + QStringList formats(); + + /** + * Returns the info structure for a special type. + */ + FormatInfo *info( const QString &type ); + + protected: + FormatFactory(); + + private: + KLibrary *openLibrary( const QString& libName ); + + static FormatFactory *mSelf; + + QDict<FormatInfo> mFormatList; +}; + +} +#endif diff --git a/kabc/formatplugin.h b/kabc/formatplugin.h new file mode 100644 index 000000000..4a2e980d8 --- /dev/null +++ b/kabc/formatplugin.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_FORMATPLUGIN_H +#define KABC_FORMATPLUGIN_H + +#include <qfile.h> + +#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 FormatPlugin : 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/formats/Makefile.am b/kabc/formats/Makefile.am new file mode 100644 index 000000000..5de6d6485 --- /dev/null +++ b/kabc/formats/Makefile.am @@ -0,0 +1,22 @@ +INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes) + +kde_module_LTLIBRARIES = kabcformat_binary.la + +kabcformat_binary_la_SOURCES = binaryformat.cpp +kabcformat_binary_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) \ + -no-undefined +kabcformat_binary_la_LIBADD = $(top_builddir)/kabc/libkabc.la +kabcformat_binary_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +# these are the headers for your project +noinst_HEADERS = binaryformat.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabcformat_binary.pot + +linkdir = $(kde_datadir)/kabc/formats +link_DATA = binary.desktop +EXTRA_DIST = $(link_DATA) diff --git a/kabc/formats/binary.desktop b/kabc/formats/binary.desktop new file mode 100644 index 000000000..459ec148c --- /dev/null +++ b/kabc/formats/binary.desktop @@ -0,0 +1,89 @@ +[Misc] +Name=Binary +Name[af]=Binêre +Name[ar]=ثنائي +Name[az]=Ä°craçı +Name[be]=Двайковы +Name[bg]=Двоичен +Name[bn]=বাইনারি +Name[br]=Binarel +Name[bs]=Binarno +Name[ca]=Binari +Name[cs]=Binárnà +Name[csb]=Binarny +Name[cy]=Deuaidd +Name[da]=Binær +Name[de]=Binär +Name[el]=Δυαδικό +Name[eo]=Duuma +Name[es]=Binario +Name[et]=Binaar +Name[eu]=Bitarra +Name[fa]=دوگانی +Name[fi]=Binääri +Name[fr]=Binaire +Name[fy]=Binêr +Name[ga]=Dénártha +Name[gl]=Binário +Name[he]=×‘×™× ×¨×™×ª +Name[hi]=दà¥à¤µà¤¿à¤šà¤° +Name[hr]=Binarno +Name[hsb]=Binarny +Name[hu]=Bináris +Name[id]=Biner +Name[is]=TvÃunda +Name[it]=Binario +Name[ja]=ãƒã‚¤ãƒŠãƒª +Name[ka]=áƒáƒ áƒáƒ‘ითი +Name[kk]=Бинарлық +Name[km]=គោលពីរ +Name[ko]=ë°”ì´ë„ˆë¦¬ +Name[lb]=Binär +Name[lt]=Dvejetainis +Name[lv]=BinÄrs +Name[mk]=Бинарен +Name[mn]=Бинар +Name[ms]=Binari +Name[mt]=Binarju +Name[nb]=Binær +Name[nds]=Bineer +Name[ne]=बाइनरी +Name[nl]=Binair +Name[nn]=Binær +Name[nso]=Tselapedi +Name[pa]=ਬਾਈਨਰੀ +Name[pl]=Binarny +Name[pt]=Binário +Name[pt_BR]=Binário +Name[ro]=Binar +Name[ru]=Двоичный +Name[rw]=Nyabibiri +Name[se]=Binára +Name[sk]=Binárny +Name[sl]=DvojiÅ¡ko +Name[sq]=Binarë +Name[sr]=Бинарни +Name[sr@Latn]=Binarni +Name[ss]=Lokuhamab ngakubili +Name[sv]=Binär +Name[ta]=இரà¯à®®à®®à¯ +Name[te]=à°¦à±à°µà°¿à°¯à°¾à°¶à°‚ +Name[tg]=Дутартиба +Name[th]=ไบนารี +Name[tr]=Ä°kili +Name[tt]=Binar +Name[uk]=Двійковий +Name[uz]=Binar +Name[uz@cyrillic]=Бинар +Name[ven]=Zwivhili +Name[vi]=Nhị phân +Name[wa]=Binaire +Name[xh]=Ephindwe kabini +Name[zh_CN]=二进制 +Name[zh_HK]=äºŒé€²ä½ +Name[zh_TW]=äºŒé€²ä½ +Name[zu]=Okuhambisana ngambili + +[Plugin] +Type=binary +X-KDE-Library=kabcformat_binary diff --git a/kabc/formats/binaryformat.cpp b/kabc/formats/binaryformat.cpp new file mode 100644 index 000000000..82cfc0a2f --- /dev/null +++ b/kabc/formats/binaryformat.cpp @@ -0,0 +1,221 @@ +/* + 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 <qdatastream.h> +#include <qimage.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include "addressbook.h" +#include "addressee.h" +#include "picture.h" +#include "sound.h" + +#include "binaryformat.h" + +#define BINARY_FORMAT_VERSION 1 + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT FormatPlugin *format() + { + return new BinaryFormat; + } +} + +bool BinaryFormat::load( Addressee &addressee, QFile *file ) +{ + kdDebug(5700) << "BinaryFormat::load()" << endl; + QDataStream stream( file ); + + if ( !checkHeader( stream ) ) + return false; + + loadAddressee( addressee, stream ); + + return true; +} + +bool BinaryFormat::loadAll( AddressBook*, Resource *resource, QFile *file ) +{ + kdDebug(5700) << "BinaryFormat::loadAll()" << endl; + + QDataStream stream( file ); + + if ( !checkHeader( stream ) ) + return false; + + Q_UINT32 entries; + + stream >> entries; + + for ( uint i = 0; i < entries; ++i ) { + Addressee addressee; + loadAddressee( addressee, stream ); + addressee.setResource( resource ); + addressee.setChanged( false ); + resource->insertAddressee( addressee ); + } + + return true; +} + +void BinaryFormat::save( const Addressee &addressee, QFile *file ) +{ + kdDebug(5700) << "BinaryFormat::save()" << endl; + + QDataStream stream( file ); + + writeHeader( stream ); + + Q_UINT32 entries = 1; + stream << entries; + saveAddressee( addressee, stream ); +} + +void BinaryFormat::saveAll( AddressBook*, Resource *resource, QFile *file ) +{ + kdDebug(5700) << "BinaryFormat::saveAll()" << endl; + + Q_UINT32 counter = 0; + QDataStream stream( file ); + + writeHeader( stream ); + // set dummy number of entries + stream << counter; + + Resource::Iterator it; + for ( it = resource->begin(); it != resource->end(); ++it ) { + saveAddressee( (*it), stream ); + counter++; + (*it).setChanged( false ); + } + + // set real number of entries + stream.device()->at( 2 * sizeof( Q_UINT32 ) ); + stream << counter; +} + +bool BinaryFormat::checkFormat( QFile *file ) const +{ + kdDebug(5700) << "BinaryFormat::checkFormat()" << endl; + + QDataStream stream( file ); + + return checkHeader( stream ); +} + +bool BinaryFormat::checkHeader( QDataStream &stream ) const +{ + Q_UINT32 magic, version; + + stream >> magic >> version; + + QFile *file = dynamic_cast<QFile*>( stream.device() ); + + if ( !file ) { + kdError() << i18n("Not a file?") << endl; + return false; + } + + if ( magic != 0x2e93e ) { + kdError() << i18n("File '%1' is not binary format.").arg( file->name() ) << endl; + return false; + } + + if ( version != BINARY_FORMAT_VERSION ) { + kdError() << i18n("File '%1' is the wrong version.").arg( file->name() ) << endl; + return false; + } + + return true; +} + +void BinaryFormat::writeHeader( QDataStream &stream ) +{ + Q_UINT32 magic, version; + + magic = 0x2e93e; + version = BINARY_FORMAT_VERSION; + + stream << magic << version; +} + +void BinaryFormat::loadAddressee( Addressee &addressee, QDataStream &stream ) +{ + stream >> addressee; +/* + // load pictures + Picture photo = addressee.photo(); + Picture logo = addressee.logo(); + + if ( photo.isIntern() ) { + QImage img; + if ( !img.load( locateLocal( "data", "kabc/photos/" ) + addressee.uid() ) ) + kdDebug(5700) << "No photo available for '" << addressee.uid() << "'." << endl; + + addressee.setPhoto( img ); + } + + if ( logo.isIntern() ) { + QImage img; + if ( !img.load( locateLocal( "data", "kabc/logos/" ) + addressee.uid() ) ) + kdDebug(5700) << "No logo available for '" << addressee.uid() << "'." << endl; + + addressee.setLogo( img ); + } + + // load sound + // TODO: load sound data from file +*/ +} + +void BinaryFormat::saveAddressee( const Addressee &addressee, QDataStream &stream ) +{ + stream << addressee; +/* + // load pictures + Picture photo = addressee.photo(); + Picture logo = addressee.logo(); + + if ( photo.isIntern() ) { + QImage img = photo.data(); + QString fileName = locateLocal( "data", "kabc/photos/" ) + addressee.uid(); + + if ( !img.save( fileName, "PNG" ) ) + kdDebug(5700) << "Unable to save photo for '" << addressee.uid() << "'." << endl; + } + + if ( logo.isIntern() ) { + QImage img = logo.data(); + QString fileName = locateLocal( "data", "kabc/logos/" ) + addressee.uid(); + + if ( !img.save( fileName, "PNG" ) ) + kdDebug(5700) << "Unable to save logo for '" << addressee.uid() << "'." << endl; + } + + // save sound + // TODO: save the sound data to file +*/ +} diff --git a/kabc/formats/binaryformat.h b/kabc/formats/binaryformat.h new file mode 100644 index 000000000..af4df48bd --- /dev/null +++ b/kabc/formats/binaryformat.h @@ -0,0 +1,69 @@ +/* + 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_BINARYFORMAT_H +#define KABC_BINARYFORMAT_H + +#include "formatplugin.h" + +namespace KABC { + +class AddressBook; +class Addressee; + +/** + @short binary file format for addressbook entries. +*/ +class BinaryFormat : public FormatPlugin +{ +public: + /** + * Load single addressee from file. + */ + bool load( Addressee &, QFile *file ); + + /** + * Load whole addressee from file. + */ + bool loadAll( AddressBook *, Resource *, QFile *file ); + + /** + * Save single addressee to file. + */ + void save( const Addressee &, QFile *file ); + + /** + * Save all addressees to file. + */ + void saveAll( AddressBook *, Resource *, QFile *file ); + + /** + * Check for valid format of a file. + */ + bool checkFormat( QFile *file ) const; + +private: + void loadAddressee( Addressee &, QDataStream & ); + void saveAddressee( const Addressee &, QDataStream & ); + bool checkHeader( QDataStream & ) const; + void writeHeader( QDataStream & ); +}; + +} +#endif diff --git a/kabc/geo.cpp b/kabc/geo.cpp new file mode 100644 index 000000000..2380f2061 --- /dev/null +++ b/kabc/geo.cpp @@ -0,0 +1,109 @@ +/* + 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 <qdatastream.h> + +#include "geo.h" + +using namespace KABC; + +Geo::Geo() + : mLatitude( 91 ), mLongitude( 181 ), mValidLat( false ), mValidLong( false ) +{ +} + +Geo::Geo( float latitude, float longitude ) +{ + setLatitude( latitude ); + setLongitude( longitude ); +} + +void Geo::setLatitude( float latitude ) +{ + if ( latitude >= -90 && latitude <= 90 ) { + mLatitude = latitude; + mValidLat = true; + } else { + mLatitude = 91; + mValidLat = false; + } +} + +float Geo::latitude() const +{ + return mLatitude; +} + +void Geo::setLongitude( float longitude) +{ + if ( longitude >= -180 && longitude <= 180 ) { + mLongitude = longitude; + mValidLong = true; + } else { + mLongitude = 181; + mValidLong = false; + } +} + +float Geo::longitude() const +{ + return mLongitude; +} + +bool Geo::isValid() const +{ + return mValidLat && mValidLong; +} + +bool Geo::operator==( const Geo &g ) const +{ + if ( !g.isValid() && !isValid() ) return true; + if ( !g.isValid() || !isValid() ) return false; + if ( g.mLatitude == mLatitude && g.mLongitude == mLongitude ) return true; + return false; +} + +bool Geo::operator!=( const Geo &g ) const +{ + if ( !g.isValid() && !isValid() ) return false; + if ( !g.isValid() || !isValid() ) return true; + if ( g.mLatitude == mLatitude && g.mLongitude == mLongitude ) return false; + return true; +} + +QString Geo::asString() const +{ + return "(" + QString::number(mLatitude) + "," + QString::number(mLongitude) + ")"; +} + +QDataStream &KABC::operator<<( QDataStream &s, const Geo &geo ) +{ + return s << (float)geo.mLatitude << (float)geo.mLongitude; +} + +QDataStream &KABC::operator>>( QDataStream &s, Geo &geo ) +{ + s >> geo.mLatitude >> geo.mLongitude; + + geo.mValidLat = true; + geo.mValidLong = true; + + return s; +} diff --git a/kabc/geo.h b/kabc/geo.h new file mode 100644 index 000000000..318f348d0 --- /dev/null +++ b/kabc/geo.h @@ -0,0 +1,101 @@ +/* + 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 <qstring.h> + +#include <kdelibs_export.h> + +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: + /** + Construct invalid geographics position object. + */ + Geo(); + + /** + Construct geographics position object. + + @param latitude Geographical latitude + @param longitude Geographical longitude + */ + Geo( float latitude, float longitude ); + + /** + Sets the latitude. + */ + void setLatitude( float ); + + /** + Returns the latitude. + */ + float latitude() const; + + /** + Sets the longitude. + */ + void setLongitude( float ); + + /** + Returns the longitude. + */ + float longitude() const; + + /** + Returns, if this object contains a valid geographical position. + */ + bool isValid() const; + + bool operator==( const Geo & ) const; + bool operator!=( const Geo & ) const; + + /** + Returns string representation of geographical position. + */ + QString asString() const; + + private: + float mLatitude; + float mLongitude; + + bool mValid; + bool mValidLat; + bool mValidLong; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Geo & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Geo & ); + +} + +#endif diff --git a/kabc/kab2kabc.cpp b/kabc/kab2kabc.cpp new file mode 100644 index 000000000..2f88218ad --- /dev/null +++ b/kabc/kab2kabc.cpp @@ -0,0 +1,476 @@ +/* + 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 <qfile.h> +#include <qtextstream.h> + +#include <kabapi.h> +#include <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> + +#include "addressbook.h" +#include "stdaddressbook.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + { "disable-autostart", I18N_NOOP( "Disable automatic startup on login" ), 0 }, + { "quiet", "", 0 }, + { "o", 0, 0 }, + { "override", I18N_NOOP( "Override existing entries" ), "1" }, + KCmdLineLastOption +}; + +void readKMailEntry( const QString &kmailEntry, KABC::AddressBook *ab ) +{ + kdDebug() << "KMAILENTRY: " << kmailEntry << endl; + + QString entry = kmailEntry.simplifyWhiteSpace(); + if ( entry.isEmpty() ) return; + + QString email; + QString name; + QString comment; + + if ( entry.at( entry.length() -1 ) == ')' ) { + int br = entry.findRev( '(' ); + if ( br >= 0 ) { + comment = entry.mid( br + 1, entry.length() - br - 2 ); + entry.truncate( br ); + if ( entry.at( entry.length() - 1 ).isSpace() ) { + entry.truncate( br - 1 ); + } + } + } + + int posSpace = entry.findRev( ' ' ); + if ( posSpace < 0 ) { + email = entry; + if ( !comment.isEmpty() ) { + name = comment; + comment = ""; + } + } else { + email = entry.mid( posSpace + 1 ); + name = entry.left( posSpace ); + } + + if ( email.at( 0 ) == '<' && email.at( email.length() - 1) == '>' ) { + email = email.mid( 1, email.length() - 2 ); + } + if ( name.at( 0 ) == '"' && name.at( name.length() - 1) == '"' ) { + name = name.mid( 1, name.length() - 2 ); + } + if ( name.at( 0 ) == '\'' && name.at( name.length() - 1) == '\'' ) { + name = name.mid( 1, name.length() - 2 ); + } + + if ( name.at( name.length() -1 ) == ')' ) { + int br = name.findRev( '(' ); + if ( br >= 0 ) { + comment = name.mid( br + 1, name.length() - br - 2 ) + " " + comment; + name.truncate( br ); + if ( name.at( name.length() - 1 ).isSpace() ) { + name.truncate( br - 1 ); + } + } + } + + kdDebug() << " EMAIL : " << email << endl; + kdDebug() << " NAME : " << name << endl; + kdDebug() << " COMMENT : " << comment << endl; + + KABC::Addressee::List al = ab->findByEmail( email ); + if ( al.isEmpty() ) { + KABC::Addressee a; + a.setNameFromString( name ); + a.insertEmail( email ); + a.setNote( comment ); + + ab->insertAddressee( a ); + + kdDebug() << "--INSERTED: " << a.realName() << endl; + } +} + +void importKMailAddressBook( KABC::AddressBook *ab ) +{ + QString fileName = locateLocal( "data", "kmail/addressbook" ); + QString kmailConfigName = locate( "config", "kmailrc" ); + if ( !kmailConfigName.isEmpty() ) { + KConfig cfg( kmailConfigName ); + cfg.setGroup( "Addressbook" ); + fileName = cfg.readPathEntry( "default", fileName ); + } + if ( !KStandardDirs::exists( fileName ) ) { + kdDebug(5700) << "Couldn't find KMail addressbook." << endl; + return; + } + + QFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) { + kdDebug(5700) << "Couldn't open file '" << fileName << "'" << endl; + return; + } + + QStringList kmailEntries; + + QTextStream t( &f ); + while ( !t.eof() ) { + kmailEntries.append( t.readLine() ); + } + f.close(); + + QStringList::ConstIterator it; + for ( it = kmailEntries.begin(); it != kmailEntries.end(); ++it ) { + if ( (*it).at( 0 ) == '#' ) continue; + bool insideQuote = false; + int end = (*it).length() - 1; + for ( int i = end; i; i-- ) { + if ( (*it).at( i ) == '"' ) { + if ( insideQuote ) + insideQuote = false; + else + insideQuote = true; + } else if ( (*it).at( i ) == ',' && !insideQuote ) { + readKMailEntry( (*it).mid( i + 1, end - i ), ab ); + end = i - 1; + } + } + + readKMailEntry( (*it).mid( 0, end + 1 ), ab ); + } +} + +void readKAddressBookEntries( const QString &dataString, Addressee &a ) +{ + // Strip "KMail:1.0" prefix and "[EOS]" suffix. + QString str = dataString.mid( 11, dataString.length() - 24 ); + + QStringList entries = QStringList::split( "\n[EOR]\n ", str ); + + Address homeAddress( Address::Home ); + Address businessAddress( Address::Work ); + Address otherAddress; + + QStringList::ConstIterator it; + for ( it = entries.begin(); it != entries.end(); ++it ) { + int pos = (*it).find( "\n" ); + QString fieldName = (*it).left( pos ); + QString fieldValue = (*it).mid( pos + 2 ); + + if ( fieldName == "X-HomeFax" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Home | + PhoneNumber::Fax ) ); + } else if ( fieldName == "X-OtherPhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, 0 ) ); + } else if ( fieldName == "X-PrimaryPhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Pref ) ); + } else if ( fieldName == "X-BusinessFax" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Work | + PhoneNumber::Fax ) ); + } else if ( fieldName == "X-CarPhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Car ) ); + } else if ( fieldName == "X-MobilePhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Cell ) ); + } else if ( fieldName == "X-ISDN" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Isdn ) ); + } else if ( fieldName == "X-OtherFax" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Fax ) ); + } else if ( fieldName == "X-Pager" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Pager ) ); + } else if ( fieldName == "X-BusinessPhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Work ) ); + } else if ( fieldName == "X-HomePhone" ) { + a.insertPhoneNumber( PhoneNumber( fieldValue, PhoneNumber::Home ) ); + } else if ( fieldName == "X-HomeAddress" ) { + homeAddress.setLabel( fieldValue ); + } else if ( fieldName == "X-HomeAddressStreet" ) { + homeAddress.setStreet( fieldValue ); + } else if ( fieldName == "X-HomeAddressCity" ) { + homeAddress.setLocality( fieldValue ); + } else if ( fieldName == "X-HomeAddressPostalCode" ) { + homeAddress.setPostalCode( fieldValue ); + } else if ( fieldName == "X-HomeAddressState" ) { + homeAddress.setRegion( fieldValue ); + } else if ( fieldName == "X-HomeAddressCountry" ) { + homeAddress.setCountry( fieldValue ); + } else if ( fieldName == "X-BusinessAddress" ) { + businessAddress.setLabel( fieldValue ); + } else if ( fieldName == "X-BusinessAddressStreet" ) { + businessAddress.setStreet( fieldValue ); + } else if ( fieldName == "X-BusinessAddressCity" ) { + businessAddress.setLocality( fieldValue ); + } else if ( fieldName == "X-BusinessAddressPostalCode" ) { + businessAddress.setPostalCode( fieldValue ); + } else if ( fieldName == "X-BusinessAddressState" ) { + businessAddress.setRegion( fieldValue ); + } else if ( fieldName == "X-BusinessAddressCountry" ) { + businessAddress.setCountry( fieldValue ); + } else if ( fieldName == "X-OtherAddress" ) { + otherAddress.setLabel( fieldValue ); + } else if ( fieldName == "X-OtherAddressStreet" ) { + otherAddress.setStreet( fieldValue ); + } else if ( fieldName == "X-OtherAddressCity" ) { + otherAddress.setLocality( fieldValue ); + } else if ( fieldName == "X-OtherAddressPostalCode" ) { + otherAddress.setPostalCode( fieldValue ); + } else if ( fieldName == "X-OtherAddressState" ) { + otherAddress.setRegion( fieldValue ); + } else if ( fieldName == "X-OtherAddressCountry" ) { + otherAddress.setCountry( fieldValue ); + } else if ( fieldName == "NICKNAME" ) { + a.setNickName( fieldValue ); + } else if ( fieldName == "ORG" ) { + a.setOrganization( fieldValue ); + } else if ( fieldName == "ROLE" ) { + a.setRole( fieldValue ); + } else if ( fieldName == "BDAY" ) { + a.setBirthday( KGlobal::locale()->readDate( fieldValue ) ); + } else if ( fieldName == "WEBPAGE" ) { + a.setUrl( KURL( fieldValue ) ); + } else if ( fieldName == "N" ) { + } else if ( fieldName == "X-FirstName" ) { + } else if ( fieldName == "X-MiddleName" ) { + } else if ( fieldName == "X-LastName" ) { + } else if ( fieldName == "X-Title" ) { + } else if ( fieldName == "X-Suffix" ) { + } else if ( fieldName == "X-FileAs" ) { + } else if ( fieldName == "EMAIL" ) { + a.insertEmail( fieldValue, true ); + } else if ( fieldName == "X-E-mail2" ) { + a.insertEmail( fieldValue ); + } else if ( fieldName == "X-E-mail3" ) { + a.insertEmail( fieldValue ); + } else if ( fieldName == "X-Notes" ) { + } else { + a.insertCustom( "KADDRESSBOOK", fieldName, fieldValue ); + } + } + + if ( !homeAddress.isEmpty() ) a.insertAddress( homeAddress ); + if ( !businessAddress.isEmpty() ) a.insertAddress( businessAddress ); + if ( !otherAddress.isEmpty() ) a.insertAddress( otherAddress ); +} + +void importKab( KABC::AddressBook *ab, bool override, bool quiet ) +{ + QString fileName = KGlobal::dirs()->saveLocation( "data", "kab/" ); + fileName += "addressbook.kab"; + if ( !QFile::exists( fileName ) ) { + if ( !quiet ) { + KMessageBox::error( 0, "<qt>" + i18n( "Address book file <b>%1</b> not found! Make sure the old address book is located there and you have read permission for this file." ) + .arg( fileName ) + "</qt>" ); + } + kdDebug(5700) << "No KDE 2 addressbook found." << endl; + return; + } + + kdDebug(5700) << "Converting old-style kab addressbook to " + "new-style kabc addressbook." << endl; + + KabAPI kab( 0 ); + if ( kab.init() != ::AddressBook::NoError ) { + kdDebug(5700) << "Error initing kab" << endl; + exit( 1 ); + } + + KabKey key; + ::AddressBook::Entry entry; + + int num = kab.addressbook()->noOfEntries(); + + kdDebug(5700) << "kab Addressbook has " << num << " entries." << endl; + + for ( int i = 0; i < num; ++i ) { + if ( ::AddressBook::NoError != kab.addressbook()->getKey( i, key ) ) { + kdDebug(5700) << "Error getting key for index " << i << " from kab." << endl; + continue; + } + if ( ::AddressBook::NoError != kab.addressbook()->getEntry( key, entry ) ) { + kdDebug(5700) << "Error getting entry for index " << i << " from kab." << endl; + continue; + } + + Addressee a; + + // Convert custom entries + int count = 0; + bool idFound = false; + QStringList::ConstIterator customIt; + for ( customIt = entry.custom.begin(); customIt != entry.custom.end(); ++customIt ) { + if ( (*customIt).startsWith( "X-KABC-UID:" ) ) { + a.setUid( (*customIt).mid( (*customIt).find( ":" ) + 1 ) ); + idFound = true; + } else if ( (*customIt).startsWith( "KMail:1.0\n" ) ) { + readKAddressBookEntries( *customIt, a ); + } else { + a.insertCustom( "kab2kabc", QString::number( count++ ), *customIt ); + } + } + if ( idFound ) { + if ( !override ) continue; + } else { + entry.custom << "X-KABC-UID:" + a.uid(); + ::AddressBook::ErrorCode error = kab.addressbook()->change( key, entry ); + if ( error != ::AddressBook::NoError ) { + kdDebug(5700) << "kab.change returned with error " << error << endl; + } else { + kdDebug(5700) << "Wrote back to kab uid " << a.uid() << endl; + } + } + + a.setTitle( entry.title ); + a.setFormattedName( entry.fn ); + a.setPrefix( entry.nameprefix ); + a.setGivenName( entry.firstname ); + a.setAdditionalName( entry.middlename ); + a.setFamilyName( entry.lastname ); + a.setBirthday( entry.birthday ); + + QStringList::ConstIterator emailIt; + for ( emailIt = entry.emails.begin(); emailIt != entry.emails.end(); ++emailIt ) + a.insertEmail( *emailIt ); + + QStringList::ConstIterator phoneIt; + for ( phoneIt = entry.telephone.begin(); phoneIt != entry.telephone.end(); ++phoneIt ) { + int kabType = (*phoneIt++).toInt(); + if ( phoneIt == entry.telephone.end() ) break; + QString number = *phoneIt; + int type = 0; + if ( kabType == ::AddressBook::Fixed ) type = PhoneNumber::Voice; + else if ( kabType == ::AddressBook::Mobile ) type = PhoneNumber::Cell | PhoneNumber::Voice; + else if ( kabType == ::AddressBook::Fax ) type = PhoneNumber::Fax; + else if ( kabType == ::AddressBook::Modem ) type = PhoneNumber::Modem; + a.insertPhoneNumber( PhoneNumber( number, type ) ); + } + + if ( entry.URLs.count() > 0 ) { + a.setUrl( KURL( entry.URLs.first() ) ); + if ( entry.URLs.count() > 1 ) { + kdWarning() << "More than one URL. Ignoring all but the first." << endl; + } + } + + int noAdr = entry.noOfAddresses(); + for ( int j = 0; j < noAdr; ++j ) { + ::AddressBook::Entry::Address kabAddress; + entry.getAddress( j, kabAddress ); + + Address adr; + + adr.setStreet( kabAddress.address ); + adr.setPostalCode( kabAddress.zip ); + adr.setLocality( kabAddress.town ); + adr.setCountry( kabAddress.country ); + adr.setRegion( kabAddress.state ); + + QString label; + if ( !kabAddress.headline.isEmpty() ) label += kabAddress.headline + "\n"; + if ( !kabAddress.position.isEmpty() ) label += kabAddress.position + "\n"; + if ( !kabAddress.org.isEmpty() ) label += kabAddress.org + "\n"; + if ( !kabAddress.orgUnit.isEmpty() ) label += kabAddress.orgUnit + "\n"; + if ( !kabAddress.orgSubUnit.isEmpty() ) label += kabAddress.orgSubUnit + "\n"; + if ( !kabAddress.deliveryLabel.isEmpty() ) label += kabAddress.deliveryLabel + "\n"; + adr.setLabel( label ); + + a.insertAddress( adr ); + } + + QString note = entry.comment; + + if ( !entry.user1.isEmpty() ) note += "\nUser1: " + entry.user1; + if ( !entry.user2.isEmpty() ) note += "\nUser2: " + entry.user2; + if ( !entry.user3.isEmpty() ) note += "\nUser3: " + entry.user3; + if ( !entry.user4.isEmpty() ) note += "\nUser4: " + entry.user4; + + if ( !entry.keywords.count() == 0 ) note += "\nKeywords: " + entry.keywords.join( ", " ); + + QStringList::ConstIterator talkIt; + for ( talkIt = entry.talk.begin(); talkIt != entry.talk.end(); ++talkIt ) { + note += "\nTalk: " + (*talkIt); + } + + a.setNote( note ); + + a.setPrefix( entry.rank + a.prefix() ); // Add rank to prefix + + a.setCategories( entry.categories ); + + kdDebug(5700) << "Addressee: " << a.familyName() << endl; + + ab->insertAddressee( a ); + } + + kab.save( true ); +} + +int main( int argc, char **argv ) +{ + KAboutData aboutData( "kab2kabc", I18N_NOOP( "Kab to Kabc Converter" ), "0.1" ); + aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + bool override = false; + + if ( args->isSet( "override" ) ) { + kdDebug() << "Override existing entries." << endl; + + override = true; + } + + bool quiet = false; + + if ( args->isSet( "quiet" ) ) + quiet = true; + + if ( args->isSet( "disable-autostart" ) ) { + kdDebug() << "Disable autostart." << endl; + + KConfig *config = app.config(); + config->setGroup( "Startup" ); + config->writeEntry( "EnableAutostart", false ); + } + + KABC::AddressBook *kabcBook = StdAddressBook::self(); + + importKMailAddressBook( kabcBook ); + + importKab( kabcBook, override, quiet ); + + StdAddressBook::save(); + + kdDebug(5700) << "Saved kabc addressbook to '" << kabcBook->identifier() << "'" << endl; +} + diff --git a/kabc/kab2kabc.desktop b/kabc/kab2kabc.desktop new file mode 100644 index 000000000..ca56719fb --- /dev/null +++ b/kabc/kab2kabc.desktop @@ -0,0 +1,106 @@ +# KDE Config File +[Desktop Entry] +Name=kab2kabc +Name[af]=kab-na-kabc +Name[csb]=Kònwersëjô adresowi knéżczi +Name[eo]=Konvertilo de "kab" al "kabc" +Name[fr]=KAB2KABC +Name[fy]=Kab2kabc +Name[hu]=Kab2kabc +Name[it]=Kab2Kabc +Name[nl]=Kab2kabc +Name[pl]=Konwersja książki adresowej +Name[pt_BR]=Conversão de kab para kabc +Name[ro]=Kab2kabc +Name[sv]=Kab2kabc +Name[te]=కెఎబి2కెఎబిసి +Name[zu]=i-kab2kabc +Exec=kab2kabc --disable-autostart --quiet +Icon=misc +Type=Application +Comment=libkab to libkabc conversion tool. +Comment[af]=libkab na libkabc omskakeling program. +Comment[ar]=أداة تØويل libkab إلى libkabc. +Comment[az]=libkab - libkabc dönüşdürmÉ™ vasitÉ™si. +Comment[be]=ІнÑтрумент пераўтварÑÐ½Ð½Ñ libkab у libkabc. +Comment[bg]=Програма за конвертиране на libkab до libkabc. +Comment[bn]=libkab থেকে libkabc-তে পরিবরà§à¦¤à¦¨ করার পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¥¤ +Comment[bs]=alat za pretvaranje libkab u libkabc. +Comment[ca]=Eina de conversió de libkab a libkabc. +Comment[cs]=PÅ™evod dat z libkab do libkabc. +Comment[csb]=Nôrzãdze do kònwersëji z libkab do libkabc. +Comment[cy]=erfyn trosi libkab i libkabc +Comment[da]=libkab-til-libkabc-konverteringsværktøj. +Comment[de]=Konvertierung von libkab in libkabc +Comment[el]=ΕÏγαλείο μετατÏοπής από το libkab στο libkabc. +Comment[eo]=Konvertilo de "libkab" al "libkabc" +Comment[es]=Conversor libkab a libkabc. +Comment[et]=libkab -> libkabc teisendamine +Comment[eu]=libkab-etik libkabc-era bihurtzeko tresna. +Comment[fa]=ابزار تبدیل libkab به libcabc. +Comment[fi]=libkab-libkabc -muunnin +Comment[fr]=Outil de conversion de libkab vers libkabc. +Comment[fy]=Konversjeprogramma fan libkab nei libkabc. +Comment[ga]=Uirlis tiontaithe ó libkab go libkabc. +Comment[gl]=Ferramenta de conversión de libkab a libkabc. +Comment[he]=כלי המרה מ־libkab ל־libkabc +Comment[hi]=libkab से libkabc बदलने वाला औजार +Comment[hr]=Alat za pretvaranje iz libkab u libkabc +Comment[hsb]=libkab -> libkabc konwerter +Comment[hu]=libkab -> libkabc konvertáló. +Comment[id]=konverter libkab ke libkabc. +Comment[is]=libkab à libkabc breytingatól. +Comment[it]=Strumento di conversione da libkab a libkabc. +Comment[ja]=libkab ã‹ã‚‰ libkabc ã¸ã®å¤‰æ›ãƒ„ール +Comment[ka]=libkab => libkabc გáƒáƒ დáƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ხელსáƒáƒ¬áƒ§áƒ. +Comment[kk]=libkab дегеннен libkabc дегенге айналдыру құралы. +Comment[km]=ឧបករណáŸâ€‹áž”ម្លែង​ពី libkab ទៅ libkabc +Comment[ko]=libkabì„ libkabcë¡œ 바꿔주는 연장. +Comment[lb]=libkab op libkabc Konvertéierungs-Hëllefsmëttel. +Comment[lt]=libkab į libkabc konvertavimo įrankis. +Comment[lv]=libkab uz libkabc kovertÄ“Å¡anas rÄ«ks. +Comment[mk]=алатка за претворање од libkab во libkabc. +Comment[mn]=libkab-Ð°Ð°Ñ libkabc-руу хөрвүүлÑгч +Comment[ms]=perkakasan penukaran libkab to libkabc. +Comment[mt]=Għodda għall-konverżjoni libkab għal libkabc +Comment[nb]=libkab til libkabc konverteringsverktøy. +Comment[nds]=Warktüüch för't Ãœmwanneln vun libkab na libkabc. +Comment[ne]=libkab to libkabc रूपानà¥à¤¤à¤°à¤£ उपकरण । +Comment[nl]=Conversieprogramma van libkab naar libkabc. +Comment[nn]=Konverterer libkab til libkabc +Comment[nso]=Sebereka sa phetosetso ya libkab go libkabc +Comment[pa]=libkab ਤੋ libkabc ਤਬਦੀਲੀ ਸੰਦ। +Comment[pl]=NarzÄ™dzie do konwersji z libkab do libkabc. +Comment[pt]=Ferramenta de conversão de libkab para libkabc. +Comment[pt_BR]=Ferramenta de conversão de libkab para libkabc. +Comment[ro]=Utilitar de conversie de la "libkab" la "libkabc". +Comment[ru]=утилита Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ libkab в libkabc. +Comment[rw]=Igikoresho cy'ihindura libkab muri libkabc. +Comment[se]=konverterenreaidu libkab:as libkabc:ai +Comment[sk]=Prevod dát z libkab do libkabc. +Comment[sl]=Orodje za pretvorbo iz libkab v libkabc +Comment[sq]=Vegla për shëndrimin e libkab në libkabc. +Comment[sr]=Ðлат за конверзију из libkab-а у libkabc. +Comment[sr@Latn]=Alat za konverziju iz libkab-a u libkabc. +Comment[ss]=Lithulusi lekutjintja le-libkab kuya ku-libkabc. +Comment[sv]=Konverteringsverktyg frÃ¥n libkab till libkabc +Comment[ta]=libkab இலிரà¯à®¨à¯à®¤à¯ libkabc கà¯à®•à¯ மாறà¯à®±à¯à®®à¯ கரà¯à®µà®¿. +Comment[te]=libkab à°¨à±à°‚à°šà°¿ libkabc కౠమారà±à°šà± పనిమà±à°Ÿà±à°Ÿà± +Comment[tg]=аÑбоби дигаргунÑози libkab ба libkabc +Comment[th]=เครื่à¸à¸‡à¸¡à¸·à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™ libkab เป็น libkabc +Comment[tr]=libkab' tan libkabc' ye dönüştürme aracı +Comment[tt]=libkab-›libkabc äyländerü qoralı. +Comment[uk]=ЗаÑіб Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ libkab до libkabc. +Comment[uz]=libkab'ni libkabc'ga aylantiradigan vosita. +Comment[uz@cyrillic]=libkab'ни libkabc'га айлантирадиган воÑита. +Comment[ven]=Tshishumiswa tsha u shandukisa libkab itshi ya kha libkabc +Comment[vi]=Công cụ chuyển đổi libkab sang libkabc. +Comment[xh]=libkab kwi libkabc isixhobo sokuguqulela. +Comment[zh_CN]=libkab 到 libkabc 的转æ¢å·¥å…·ã€‚ +Comment[zh_HK]=libkab 至 libkabc 的轉æ›å·¥å…· +Comment[zh_TW]=libkab 至 libkabc 轉æ›å·¥å…· +Comment[zu]=Ithuluzi lokuguqula le-libkab kuyaku-libkabc +Terminal=false +NoDisplay=true +X-KDE-autostart-condition=kab2kabcrc:Startup:EnableAutostart:true +OnlyShowIn=KDE; diff --git a/kabc/kabc_manager.desktop b/kabc/kabc_manager.desktop new file mode 100644 index 000000000..ee0cf23a4 --- /dev/null +++ b/kabc/kabc_manager.desktop @@ -0,0 +1,77 @@ +# KDE Config File +[Desktop Entry] +Name=Contacts +Name[af]=Kontakte +Name[ar]=المراسلين +Name[be]=Кантакты +Name[br]=Darempredoù +Name[bs]=Kontakti +Name[ca]=Contactes +Name[cs]=Kontakty +Name[csb]=ÅÄ…czbë +Name[cy]=Cysylltau +Name[da]=Kontakter +Name[de]=Kontakte +Name[el]=ΕπαφÎÏ‚ +Name[eo]=Kontaktoj +Name[es]=Contactos +Name[et]=Kontaktid +Name[eu]=Kontaktuak +Name[fa]=تماسها +Name[fi]=Yhteystiedot +Name[fy]=Kontakten +Name[ga]=Teagmhálacha +Name[gl]=Contactos +Name[he]=×× ×©×™ קשר +Name[hi]=समà¥à¤ªà¤°à¥à¤• +Name[hr]=Kontakti +Name[hsb]=Adresy +Name[hu]=Névjegyek +Name[id]=Kontak +Name[is]=Tengiliðir +Name[it]=Contatti +Name[ja]=コンタクト +Name[ka]=კáƒáƒœáƒ¢áƒáƒ¥áƒ¢áƒ”ბი +Name[kk]=Контакттар +Name[km]=ទំនាក់ទំនង +Name[ku]=Tekilî +Name[lb]=Kontakter +Name[lt]=Kontaktai +Name[lv]=Kontakti +Name[mk]=Контакти +Name[ms]=Hubungan +Name[nb]=Kontakter +Name[nds]=Kontakten +Name[ne]=समà¥à¤ªà¤°à¥à¤• +Name[nl]=Contactpersonen +Name[nn]=Kontaktar +Name[pa]=ਸੰਪਰਕ +Name[pl]=Kontakty +Name[pt]=Contactos +Name[pt_BR]=Contatos +Name[ro]=Contacte +Name[ru]=Контакты +Name[rw]=Amaderesi +Name[se]=OktavuoÄ‘at +Name[sk]=Kontakty +Name[sl]=Stiki +Name[sr]=Контакти +Name[sr@Latn]=Kontakti +Name[sv]=Kontakter +Name[ta]=தொடரà¯à®ªà¯à®•à®³à¯ +Name[te]=సంపà±à°°à°¦à°¿à°‚à°ªà±à°²à± +Name[tg]=Ðлоқаҳо +Name[th]=รายชื่à¸à¸•à¸´à¸”ต่ภ+Name[tr]=BaÄŸlantılar +Name[tt]=Elemtälär +Name[uk]=Контакти +Name[uz]=Aloqalar +Name[uz@cyrillic]=Ðлоқалар +Name[vi]=Liên lạc +Name[zh_CN]=è”系人 +Name[zh_HK]=è¯çµ¡äºº +Name[zh_TW]=è¯çµ¡äºº +Type=Service +ServiceTypes=KResources/Manager + +X-KDE-ResourceFamily=contact diff --git a/kabc/key.cpp b/kabc/key.cpp new file mode 100644 index 000000000..e4fe50f2e --- /dev/null +++ b/kabc/key.cpp @@ -0,0 +1,153 @@ +/* + 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 <kapplication.h> +#include <klocale.h> + +#include "key.h" + +using namespace KABC; + +Key::Key( const QString &text, int type ) + : mTextData( text ), mIsBinary( false ), mType( type ) +{ + mId = KApplication::randomString(8); +} + +Key::~Key() +{ +} + +bool Key::operator==( const Key &k ) const +{ + if ( mIsBinary != k.mIsBinary ) return false; + if ( mIsBinary ) + if ( mBinaryData != k.mBinaryData ) return false; + else + if ( mTextData != k.mTextData ) return false; + if ( mType != k.mType ) return false; + if ( mCustomTypeString != k.mCustomTypeString ) return false; + + return true; +} + +bool Key::operator!=( const Key &k ) const +{ + return !( k == *this ); +} + +void Key::setId( const QString &id ) +{ + mId = id; +} + +QString Key::id() const +{ + return mId; +} + +void Key::setBinaryData( const QByteArray &binary ) +{ + mBinaryData = binary; + mIsBinary = true; +} + +QByteArray Key::binaryData() const +{ + return mBinaryData; +} + +void Key::setTextData( const QString &text ) +{ + mTextData = text; + mIsBinary = false; +} + +QString Key::textData() const +{ + return mTextData; +} + +bool Key::isBinary() const +{ + return mIsBinary; +} + +void Key::setType( int type ) +{ + mType = type; +} + +void Key::setCustomTypeString( const QString &custom ) +{ + mCustomTypeString = custom; +} + +int Key::type() const +{ + return mType; +} + +QString Key::customTypeString() const +{ + return mCustomTypeString; +} + +Key::TypeList Key::typeList() +{ + TypeList list; + list << X509; + list << PGP; + list << Custom; + + return list; +} + +QString Key::typeLabel( int type ) +{ + switch ( type ) { + case X509: + return i18n( "X509" ); + break; + case PGP: + return i18n( "PGP" ); + break; + case Custom: + return i18n( "Custom" ); + break; + default: + return i18n( "Unknown type" ); + break; + } +} + +QDataStream &KABC::operator<<( QDataStream &s, const Key &key ) +{ + return s << key.mId << key.mIsBinary << key.mTextData << key.mBinaryData << + key.mCustomTypeString << key.mType; +} + +QDataStream &KABC::operator>>( QDataStream &s, Key &key ) +{ + s >> key.mId >> key.mIsBinary >> key.mTextData >> key.mBinaryData >> + key.mCustomTypeString >> key.mType; + + return s; +} diff --git a/kabc/key.h b/kabc/key.h new file mode 100644 index 000000000..8c91fd6cf --- /dev/null +++ b/kabc/key.h @@ -0,0 +1,150 @@ +/* + 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 <qvaluelist.h> + +#include <kdelibs_export.h> + +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: + typedef QValueList<Key> List; + typedef QValueList<int> TypeList; + + /** + * Key types + * + * @li X509 - X509 key + * @li PGP - Pretty Good Privacy key + * @li Custom - Custom or IANA conform key + */ + enum Types { + X509, + PGP, + Custom + }; + + /** + * Constructor. + * + * @param text The text data. + * @param type The key type, see Types. + */ + Key( const QString &text = QString::null, int type = PGP ); + + /** + * Destructor. + */ + ~Key(); + + bool operator==( const Key & ) const; + bool operator!=( const Key & ) const; + + /** + * Sets the unique identifier. + */ + void setId( const QString &id ); + + /** + * Returns the unique identifier. + */ + QString id() const; + + /** + * Sets binary data. + */ + void setBinaryData( const QByteArray &binary ); + + /** + * Returns the binary data. + */ + QByteArray binaryData() const; + + /** + * Sets text data. + */ + void setTextData( const QString &text ); + + /** + * Returns the text data. + */ + QString textData() const; + + /** + * Returns whether the key contains binary or text data. + */ + bool isBinary() const; + + /** + * Sets the type, see Type. + */ + void setType( int type ); + + /** + * Sets custom type string. + */ + void setCustomTypeString( const QString &custom ); + + /** + * Returns the type, see Type. + */ + int type() const; + + /** + * Returns the custom type string. + */ + QString customTypeString() const; + + /** + * Returns a list of all available key types. + */ + static TypeList typeList(); + + /** + * Returns a translated label for a given key type. + */ + static QString typeLabel( int type ); + +private: + QByteArray mBinaryData; + QString mId; + QString mTextData; + QString mCustomTypeString; + + int mIsBinary; + int mType; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Key & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Key & ); + +} +#endif diff --git a/kabc/ldapclient.cpp b/kabc/ldapclient.cpp new file mode 100644 index 000000000..3e73b1c59 --- /dev/null +++ b/kabc/ldapclient.cpp @@ -0,0 +1,427 @@ +/* kldapclient.cpp - LDAP access + * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * + * Author: Steffen Hansen <hansen@kde.org> + * + * Ported to KABC by Daniel Molkentin <molkentin@kde.org> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + + +#include <qfile.h> +#include <qimage.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qtextstream.h> +#include <qurl.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kmdcodec.h> +#include <kprotocolinfo.h> + +#include "ldapclient.h" +#include "ldif.h" +#include "ldapurl.h" + +using namespace KABC; + +class LdapClient::LdapClientPrivate{ +public: + QString bindDN; + QString pwdBindDN; + LDIF ldif; +}; + +QString LdapObject::toString() const +{ + QString result = QString::fromLatin1( "\ndn: %1\n" ).arg( dn ); + for ( LdapAttrMap::ConstIterator it = attrs.begin(); it != attrs.end(); ++it ) { + QString attr = it.key(); + for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) { + result += QString::fromUtf8( LDIF::assembleLine( attr, *it2, 76 ) ) + "\n"; + } + } + + return result; +} + +void LdapObject::clear() +{ + dn = QString::null; + attrs.clear(); +} + +void LdapObject::assign( const LdapObject& that ) +{ + if ( &that != this ) { + dn = that.dn; + attrs = that.attrs; + client = that.client; + } +} + +LdapClient::LdapClient( QObject* parent, const char* name ) + : QObject( parent, name ), mJob( 0 ), mActive( false ) +{ + d = new LdapClientPrivate; +} + +LdapClient::~LdapClient() +{ + cancelQuery(); + delete d; d = 0; +} + +void LdapClient::setHost( const QString& host ) +{ + mHost = host; +} + +void LdapClient::setPort( const QString& port ) +{ + mPort = port; +} + +void LdapClient::setBase( const QString& base ) +{ + mBase = base; +} + +void LdapClient::setBindDN( const QString& bindDN ) +{ + d->bindDN = bindDN; +} + +void LdapClient::setPwdBindDN( const QString& pwdBindDN ) +{ + d->pwdBindDN = pwdBindDN; +} + +void LdapClient::setAttrs( const QStringList& attrs ) +{ + mAttrs = attrs; +} + +void LdapClient::startQuery( const QString& filter ) +{ + cancelQuery(); + LDAPUrl url; + + url.setProtocol( "ldap" ); + url.setUser( d->bindDN ); + url.setPass( d->pwdBindDN ); + url.setHost( mHost ); + url.setPort( mPort.toUInt() ); + url.setDn( mBase ); + url.setAttributes( mAttrs ); + url.setScope( mScope == "one" ? LDAPUrl::One : LDAPUrl::Sub ); + url.setFilter( "("+filter+")" ); + + kdDebug(5700) << "Doing query: " << url.prettyURL() << endl; + + startParseLDIF(); + mActive = true; + mJob = KIO::get( url, false, false ); + connect( mJob, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) ); + connect( mJob, SIGNAL( infoMessage( KIO::Job*, const QString& ) ), + this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) ); + connect( mJob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( slotDone() ) ); +} + +void LdapClient::cancelQuery() +{ + if ( mJob ) { + mJob->kill(); + mJob = 0; + } + + mActive = false; +} + +void LdapClient::slotData( KIO::Job*, const QByteArray& data ) +{ +#ifndef NDEBUG // don't create the QString +// QString str( data ); +// kdDebug(5700) << "LdapClient: Got \"" << str << "\"\n"; +#endif + parseLDIF( data ); +} + +void LdapClient::slotInfoMessage( KIO::Job*, const QString & ) +{ + //qDebug("Job said \"%s\"", info.latin1()); +} + +void LdapClient::slotDone() +{ + endParseLDIF(); + mActive = false; +#if 0 + for ( QValueList<LdapObject>::Iterator it = mObjects.begin(); it != mObjects.end(); ++it ) { + qDebug( (*it).toString().latin1() ); + } +#endif + int err = mJob->error(); + if ( err && err != KIO::ERR_USER_CANCELED ) { + emit error( KIO::buildErrorString( err, QString("%1:%2").arg( mHost ).arg( mPort ) ) ); + } + emit done(); +} + +void LdapClient::startParseLDIF() +{ + mCurrentObject.clear(); + mLastAttrName = 0; + mLastAttrValue = 0; + mIsBase64 = false; + d->ldif.startParsing(); +} + +void LdapClient::endParseLDIF() +{ +} + +void LdapClient::parseLDIF( const QByteArray& data ) +{ + if ( data.size() ) { + d->ldif.setLDIF( data ); + } else { + d->ldif.endLDIF(); + } + + LDIF::ParseVal ret; + QString name; + do { + ret = d->ldif.nextItem(); + switch ( ret ) { + case LDIF::Item: + { + name = d->ldif.attr(); + // Must make a copy! QByteArray is explicitely shared + QByteArray value = d->ldif.val().copy(); + mCurrentObject.attrs[ name ].append( value ); + break; + } + case LDIF::EndEntry: + mCurrentObject.dn = d->ldif.dn(); + mCurrentObject.client = this; + emit result( mCurrentObject ); + mCurrentObject.clear(); + break; + default: + break; + } + } while ( ret != LDIF::MoreData ); +} + +QString LdapClient::bindDN() const +{ + return d->bindDN; +} + +QString LdapClient::pwdBindDN() const +{ + return d->pwdBindDN; +} + +LdapSearch::LdapSearch() + : mActiveClients( 0 ), mNoLDAPLookup( false ) +{ + if ( !KProtocolInfo::isKnownProtocol( KURL("ldap://localhost") ) ) { + mNoLDAPLookup = true; + return; + } + + // stolen from KAddressBook + KConfig config( "kabldaprc", true ); + config.setGroup( "LDAP" ); + int numHosts = config.readUnsignedNumEntry( "NumSelectedHosts"); + if ( !numHosts ) { + mNoLDAPLookup = true; + return; + } else { + for ( int j = 0; j < numHosts; j++ ) { + LdapClient* ldapClient = new LdapClient( this ); + + QString host = config.readEntry( QString( "SelectedHost%1" ).arg( j ), "" ).stripWhiteSpace(); + if ( !host.isEmpty() ) + ldapClient->setHost( host ); + + QString port = QString::number( config.readUnsignedNumEntry( QString( "SelectedPort%1" ).arg( j ) ) ); + if ( !port.isEmpty() ) + ldapClient->setPort( port ); + + QString base = config.readEntry( QString( "SelectedBase%1" ).arg( j ), "" ).stripWhiteSpace(); + if ( !base.isEmpty() ) + ldapClient->setBase( base ); + + QString bindDN = config.readEntry( QString( "SelectedBind%1" ).arg( j ) ).stripWhiteSpace(); + if ( !bindDN.isEmpty() ) + ldapClient->setBindDN( bindDN ); + + QString pwdBindDN = config.readEntry( QString( "SelectedPwdBind%1" ).arg( j ) ); + if ( !pwdBindDN.isEmpty() ) + ldapClient->setPwdBindDN( pwdBindDN ); + + QStringList attrs; + attrs << "cn" << "mail" << "givenname" << "sn"; + ldapClient->setAttrs( attrs ); + + connect( ldapClient, SIGNAL( result( const KABC::LdapObject& ) ), + this, SLOT( slotLDAPResult( const KABC::LdapObject& ) ) ); + connect( ldapClient, SIGNAL( done() ), + this, SLOT( slotLDAPDone() ) ); + connect( ldapClient, SIGNAL( error( const QString& ) ), + this, SLOT( slotLDAPError( const QString& ) ) ); + + mClients.append( ldapClient ); + } + } + + connect( &mDataTimer, SIGNAL( timeout() ), SLOT( slotDataTimer() ) ); +} + +void LdapSearch::startSearch( const QString& txt ) +{ + if ( mNoLDAPLookup ) + return; + + cancelSearch(); + + int pos = txt.find( '\"' ); + if( pos >= 0 ) + { + ++pos; + int pos2 = txt.find( '\"', pos ); + if( pos2 >= 0 ) + mSearchText = txt.mid( pos , pos2 - pos ); + else + mSearchText = txt.mid( pos ); + } else + mSearchText = txt; + + QString filter = QString( "|(cn=%1*)(mail=%2*)(givenName=%3*)(sn=%4*)" ) + .arg( mSearchText ).arg( mSearchText ).arg( mSearchText ).arg( mSearchText ); + + QValueList< LdapClient* >::Iterator it; + for ( it = mClients.begin(); it != mClients.end(); ++it ) { + (*it)->startQuery( filter ); + ++mActiveClients; + } +} + +void LdapSearch::cancelSearch() +{ + QValueList< LdapClient* >::Iterator it; + for ( it = mClients.begin(); it != mClients.end(); ++it ) + (*it)->cancelQuery(); + + mActiveClients = 0; + mResults.clear(); +} + +void LdapSearch::slotLDAPResult( const KABC::LdapObject& obj ) +{ + mResults.append( obj ); + if ( !mDataTimer.isActive() ) + mDataTimer.start( 500, true ); +} + +void LdapSearch::slotLDAPError( const QString& ) +{ + slotLDAPDone(); +} + +void LdapSearch::slotLDAPDone() +{ + if ( --mActiveClients > 0 ) + return; + + finish(); +} + +void LdapSearch::slotDataTimer() +{ + QStringList lst; + LdapResultList reslist; + makeSearchData( lst, reslist ); + if ( !lst.isEmpty() ) + emit searchData( lst ); + if ( !reslist.isEmpty() ) + emit searchData( reslist ); +} + +void LdapSearch::finish() +{ + mDataTimer.stop(); + + slotDataTimer(); // emit final bunch of data + emit searchDone(); +} + +void LdapSearch::makeSearchData( QStringList& ret, LdapResultList& resList ) +{ + QString search_text_upper = mSearchText.upper(); + + QValueList< KABC::LdapObject >::ConstIterator it1; + for ( it1 = mResults.begin(); it1 != mResults.end(); ++it1 ) { + QString name, mail, givenname, sn; + + LdapAttrMap::ConstIterator it2; + for ( it2 = (*it1).attrs.begin(); it2 != (*it1).attrs.end(); ++it2 ) { + QString tmp = QString::fromUtf8( (*it2).first(), (*it2).first().size() ); + if ( it2.key() == "cn" ) + name = tmp; // TODO loop? + else if( it2.key() == "mail" ) + mail = tmp; + else if( it2.key() == "givenName" ) + givenname = tmp; + else if( it2.key() == "sn" ) + sn = tmp; + } + + if( mail.isEmpty()) + continue; // nothing, bad entry + else if ( name.isEmpty() ) + ret.append( mail ); + else { + kdDebug(5700) << "<" << name << "><" << mail << ">" << endl; + ret.append( QString( "%1 <%2>" ).arg( name ).arg( mail ) ); + } + + LdapResult sr; + sr.clientNumber = mClients.findIndex( (*it1).client ); + sr.name = name; + sr.email = mail; + resList.append( sr ); + } + + mResults.clear(); +} + +bool LdapSearch::isAvailable() const +{ + return !mNoLDAPLookup; +} + + + +#include "ldapclient.moc" diff --git a/kabc/ldapclient.h b/kabc/ldapclient.h new file mode 100644 index 000000000..a7bb89ddd --- /dev/null +++ b/kabc/ldapclient.h @@ -0,0 +1,248 @@ +/* kldapclient.h - LDAP access + * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * + * Author: Steffen Hansen <hansen@kde.org> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef KABC_LDAPCLIENT_H +#define KABC_LDAPCLIENT_H + + +#include <qobject.h> +#include <qstring.h> +#include <qcstring.h> +#include <qstringlist.h> +#include <qmemarray.h> +#include <qguardedptr.h> +#include <qtimer.h> + +#include <kio/job.h> + +namespace KABC { + +class LdapClient; +typedef QValueList<QByteArray> LdapAttrValue; +typedef QMap<QString,LdapAttrValue > LdapAttrMap; + +/** + * This class is internal. Binary compatibiliy might be broken any time + * without notification. Do not use it. + * + * We mean it! + * + */ +class KABC_EXPORT LdapObject +{ + public: + LdapObject() + : dn( QString::null ), client( 0 ) {} + explicit LdapObject( const QString& _dn, LdapClient* _cl ) : dn( _dn ), client( _cl ) {} + LdapObject( const LdapObject& that ) { assign( that ); } + + LdapObject& operator=( const LdapObject& that ) + { + assign( that ); + return *this; + } + + QString toString() const; + + void clear(); + + QString dn; + LdapAttrMap attrs; + LdapClient* client; + + protected: + void assign( const LdapObject& that ); + + private: + //class LdapObjectPrivate* d; +}; + +/** + * This class is internal. Binary compatibiliy might be broken any time + * without notification. Do not use it. + * + * We mean it! + * + */ +class KABC_EXPORT LdapClient : public QObject +{ + Q_OBJECT + + public: + LdapClient( QObject* parent = 0, const char* name = 0 ); + virtual ~LdapClient(); + + /*! returns true if there is a query running */ + bool isActive() const { return mActive; } + + signals: + /*! Emitted when the query is done */ + void done(); + + /*! Emitted in case of error */ + void error( const QString& ); + + /*! Emitted once for each object returned + * from the query + */ + void result( const KABC::LdapObject& ); + + public slots: + /*! + * Set the name or IP of the LDAP server + */ + void setHost( const QString& host ); + QString host() const { return mHost; } + + /*! + * Set the port of the LDAP server + * if using a nonstandard port + */ + void setPort( const QString& port ); + QString port() const { return mPort; } + + /*! + * Set the base DN + */ + void setBase( const QString& base ); + QString base() const { return mBase; } + + /*! + * Set the bind DN + */ + void setBindDN( const QString& bindDN ); + QString bindDN() const; + + /*! + * Set the bind password DN + */ + void setPwdBindDN( const QString& pwdBindDN ); + QString pwdBindDN() const; + + /*! Set the attributes that should be + * returned, or an empty list if + * all attributes are wanted + */ + void setAttrs( const QStringList& attrs ); + QStringList attrs() const { return mAttrs; } + + void setScope( const QString scope ) { mScope = scope; } + + /*! + * Start the query with filter filter + */ + void startQuery( const QString& filter ); + + /*! + * Abort a running query + */ + void cancelQuery(); + + protected slots: + void slotData( KIO::Job*, const QByteArray &data ); + void slotInfoMessage( KIO::Job*, const QString &info ); + void slotDone(); + + protected: + void startParseLDIF(); + void parseLDIF( const QByteArray& data ); + void endParseLDIF(); + + QString mHost; + QString mPort; + QString mBase; + QString mScope; + QStringList mAttrs; + + QGuardedPtr<KIO::SimpleJob> mJob; + bool mActive; + + LdapObject mCurrentObject; + QCString mBuf; + QCString mLastAttrName; + QCString mLastAttrValue; + bool mIsBase64; + + private: + class LdapClientPrivate; + LdapClientPrivate* d; +}; + +/** + * Structure describing one result returned by a LDAP query + */ +struct LdapResult { + QString name; ///< full name + QString email; ///< email + int clientNumber; ///< for sorting +}; +typedef QValueList<LdapResult> LdapResultList; + + +/** + * This class is internal. Binary compatibiliy might be broken any time + * without notification. Do not use it. + * + * We mean it! + * + */ +class KABC_EXPORT LdapSearch : public QObject +{ + Q_OBJECT + + public: + LdapSearch(); + + void startSearch( const QString& txt ); + void cancelSearch(); + bool isAvailable() const; + + signals: + /// Results, assembled as "Full Name <email>" + /// (This signal can be emitted many times) + void searchData( const QStringList& ); + /// Another form for the results, with separate fields + /// (This signal can be emitted many times) + void searchData( const KABC::LdapResultList& ); + void searchDone(); + + private slots: + void slotLDAPResult( const KABC::LdapObject& ); + void slotLDAPError( const QString& ); + void slotLDAPDone(); + void slotDataTimer(); + + private: + void finish(); + void makeSearchData( QStringList& ret, LdapResultList& resList ); + QValueList< LdapClient* > mClients; + QString mSearchText; + QTimer mDataTimer; + int mActiveClients; + bool mNoLDAPLookup; + QValueList< LdapObject > mResults; + + private: + class LdapSearchPrivate* d; +}; + +} +#endif // KABC_LDAPCLIENT_H diff --git a/kabc/ldapconfigwidget.cpp b/kabc/ldapconfigwidget.cpp new file mode 100644 index 000000000..b144b2db5 --- /dev/null +++ b/kabc/ldapconfigwidget.cpp @@ -0,0 +1,626 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 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 <qapplication.h> + +#include <qobjectlist.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qspinbox.h> +#include <qvgroupbox.h> +#include <qhbuttongroup.h> +#include <qradiobutton.h> + +#include <kmessagebox.h> +#include <kaccelmanager.h> +#include <kdialogbase.h> +#include <klocale.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <kprogress.h> + +#include <kdebug.h> + +#include "ldapconfigwidget.h" +#include "ldapconfigwidget.moc" + +using namespace KABC; + +LdapConfigWidget::LdapConfigWidget( QWidget* parent, + const char* name, WFlags fl ) : QWidget( parent, name, fl ) +{ + mProg = 0; + mFlags = 0; + mainLayout = new QGridLayout( this, 12, 4, 0, + KDialog::spacingHint() ); +} + +LdapConfigWidget::LdapConfigWidget( int flags, QWidget* parent, + const char* name, WFlags fl ) : QWidget( parent, name, fl ) +{ + mFlags = flags; + mProg = 0; + mainLayout = new QGridLayout( this, 12, 4, 0, + KDialog::spacingHint() ); + initWidget(); +} + +LdapConfigWidget::~LdapConfigWidget() +{ +} + +void LdapConfigWidget::initWidget() +{ + QLabel *label; + + mUser = mPassword = mHost = mDn = mBindDN = mRealm = mFilter = 0; + mPort = mVer = mTimeLimit = mSizeLimit = 0; + mAnonymous = mSimple = mSASL = mSecNO = mSecTLS = mSecSSL = 0; + mEditButton = mQueryMech = 0; + mMech = 0; + int row = 0; + int col; + + if ( mFlags & W_USER ) { + label = new QLabel( i18n( "User:" ), this ); + mUser = new KLineEdit( this, "kcfg_ldapuser" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mUser, row, row, 1, 3 ); + row++; + } + + if ( mFlags & W_BINDDN ) { + label = new QLabel( i18n( "Bind DN:" ), this ); + mBindDN = new KLineEdit( this, "kcfg_ldapbinddn" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mBindDN, row, row, 1, 3 ); + row++; + } + + if ( mFlags & W_REALM ) { + label = new QLabel( i18n( "Realm:" ), this ); + mRealm = new KLineEdit( this, "kcfg_ldaprealm" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mRealm, row, row, 1, 3 ); + row++; + } + + if ( mFlags & W_PASS ) { + label = new QLabel( i18n( "Password:" ), this ); + mPassword = new KLineEdit( this, "kcfg_ldappassword" ); + mPassword->setEchoMode( KLineEdit::Password ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mPassword, row, row, 1, 3 ); + row++; + } + + if ( mFlags & W_HOST ) { + label = new QLabel( i18n( "Host:" ), this ); + mHost = new KLineEdit( this, "kcfg_ldaphost" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mHost, row, row, 1, 3 ); + row++; + } + + col = 0; + if ( mFlags & W_PORT ) { + label = new QLabel( i18n( "Port:" ), this ); + mPort = new QSpinBox( 0, 65535, 1, this, "kcfg_ldapport" ); + mPort->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) ); + mPort->setValue( 389 ); + + mainLayout->addWidget( label, row, col ); + mainLayout->addWidget( mPort, row, col+1 ); + col += 2; + } + + if ( mFlags & W_VER ) { + label = new QLabel( i18n( "LDAP version:" ), this ); + mVer = new QSpinBox( 2, 3, 1, this, "kcfg_ldapver" ); + mVer->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) ); + mVer->setValue( 3 ); + mainLayout->addWidget( label, row, col ); + mainLayout->addWidget( mVer, row, col+1 ); + } + if ( mFlags & ( W_PORT | W_VER ) ) row++; + + col = 0; + if ( mFlags & W_SIZELIMIT ) { + label = new QLabel( i18n( "Size limit:" ), this ); + mSizeLimit = new QSpinBox( 0, 9999999, 1, this, "kcfg_ldapsizelimit" ); + mSizeLimit->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) ); + mSizeLimit->setValue( 0 ); + mSizeLimit->setSpecialValueText( i18n("Default") ); + mainLayout->addWidget( label, row, col ); + mainLayout->addWidget( mSizeLimit, row, col+1 ); + col += 2; + } + + if ( mFlags & W_TIMELIMIT ) { + label = new QLabel( i18n( "Time limit:" ), this ); + mTimeLimit = new QSpinBox( 0, 9999999, 1, this, "kcfg_ldaptimelimit" ); + mTimeLimit->setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) ); + mTimeLimit->setValue( 0 ); + mTimeLimit->setSuffix( i18n(" sec") ); + mTimeLimit->setSpecialValueText( i18n("Default") ); + mainLayout->addWidget( label, row, col ); + mainLayout->addWidget( mTimeLimit, row, col+1 ); + } + if ( mFlags & ( W_SIZELIMIT | W_TIMELIMIT ) ) row++; + + if ( mFlags & W_DN ) { + label = new QLabel( i18n( "Distinguished Name", "DN:" ), this ); + mDn = new KLineEdit( this, "kcfg_ldapdn" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mDn, row, row, 1, 1 ); + //without host query doesn't make sense + if ( mHost ) { + QPushButton *dnquery = new QPushButton( i18n( "Query Server" ), this ); + connect( dnquery, SIGNAL( clicked() ), SLOT( mQueryDNClicked() ) ); + mainLayout->addMultiCellWidget( dnquery, row, row, 2, 3 ); + } + row++; + } + + if ( mFlags & W_FILTER ) { + label = new QLabel( i18n( "Filter:" ), this ); + mFilter = new KLineEdit( this, "kcfg_ldapfilter" ); + + mainLayout->addWidget( label, row, 0 ); + mainLayout->addMultiCellWidget( mFilter, row, row, 1, 3 ); + row++; + } + + if ( mFlags & W_SECBOX ) { + QHButtonGroup *btgroup = new QHButtonGroup( i18n( "Security" ), this ); + mSecNO = new QRadioButton( i18n( "No" ), btgroup, "kcfg_ldapnosec" ); + mSecTLS = new QRadioButton( i18n( "TLS" ), btgroup, "kcfg_ldaptls" ); + mSecSSL = new QRadioButton( i18n( "SSL" ), btgroup, "kcfg_ldapssl" ); + mainLayout->addMultiCellWidget( btgroup, row, row, 0, 3 ); + + connect( mSecNO, SIGNAL( clicked() ), SLOT( setLDAPPort() ) ); + connect( mSecTLS, SIGNAL( clicked() ), SLOT( setLDAPPort() ) ); + connect( mSecSSL, SIGNAL( clicked() ), SLOT( setLDAPSPort( ) ) ); + + mSecNO->setChecked( true ); + row++; + } + + if ( mFlags & W_AUTHBOX ) { + + QButtonGroup *authbox = + new QButtonGroup( 3, Qt::Horizontal, i18n( "Authentication" ), this ); + + mAnonymous = new QRadioButton( i18n( "Anonymous" ), authbox, "kcfg_ldapanon" ); + mSimple = new QRadioButton( i18n( "Simple" ), authbox, "kcfg_ldapsimple" ); + mSASL = new QRadioButton( i18n( "SASL" ), authbox, "kcfg_ldapsasl" ); + + label = new QLabel( i18n( "SASL mechanism:" ), authbox ); + mMech = new KComboBox( false, authbox, "kcfg_ldapsaslmech" ); + mMech->setEditable( true ); + mMech->insertItem( "DIGEST-MD5" ); + mMech->insertItem( "GSSAPI" ); + mMech->insertItem( "PLAIN" ); + + //without host query doesn't make sense + if ( mHost ) { + mQueryMech = new QPushButton( i18n( "Query Server" ), authbox ); + connect( mQueryMech, SIGNAL( clicked() ), SLOT( mQueryMechClicked() ) ); + } + + mainLayout->addMultiCellWidget( authbox, row, row+1, 0, 3 ); + + connect( mAnonymous, SIGNAL( stateChanged(int) ), SLOT( setAnonymous(int) ) ); + connect( mSimple, SIGNAL( stateChanged(int) ), SLOT( setSimple(int) ) ); + connect( mSASL, SIGNAL( stateChanged(int) ), SLOT( setSASL(int) ) ); + + mAnonymous->setChecked( true ); + } + +} + +void LdapConfigWidget::loadData( KIO::Job*, const QByteArray& d ) +{ + LDIF::ParseVal ret; + + if ( d.size() ) { + mLdif.setLDIF( d ); + } else { + mLdif.endLDIF(); + } + do { + ret = mLdif.nextItem(); + if ( ret == LDIF::Item && mLdif.attr().lower() == mAttr ) { + mProg->progressBar()->advance( 1 ); + mQResult.push_back( QString::fromUtf8( mLdif.val(), mLdif.val().size() ) ); + } + } while ( ret != LDIF::MoreData ); +} + +void LdapConfigWidget::loadResult( KIO::Job* job) +{ + int error = job->error(); + if ( error && error != KIO::ERR_USER_CANCELED ) + mErrorMsg = job->errorString(); + else + mErrorMsg = ""; + + mCancelled = false; + mProg->close(); +} + +void LdapConfigWidget::sendQuery() +{ + LDAPUrl _url; + + mQResult.clear(); + mCancelled = true; + + _url.setProtocol( ( mSecSSL && mSecSSL->isChecked() ) ? "ldaps" : "ldap" ); + if ( mHost ) _url.setHost( mHost->text() ); + if ( mPort ) _url.setPort( mPort->value() ); + _url.setDn( "" ); + _url.setAttributes( mAttr ); + _url.setScope( LDAPUrl::Base ); + if ( mVer ) _url.setExtension( "x-ver", QString::number( mVer->value() ) ); + if ( mSecTLS && mSecTLS->isChecked() ) _url.setExtension( "x-tls", "" ); + + kdDebug(5700) << "sendQuery url: " << _url.prettyURL() << endl; + mLdif.startParsing(); + KIO::Job *job = KIO::get( _url, true, false ); + job->addMetaData("no-auth-prompt","true"); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( loadData( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( loadResult( KIO::Job* ) ) ); + + if ( mProg == NULL ) + mProg = new KProgressDialog( this, 0, i18n("LDAP Query"), _url.prettyURL(), true ); + else + mProg->setLabel( _url.prettyURL() ); + mProg->progressBar()->setValue( 0 ); + mProg->progressBar()->setTotalSteps( 1 ); + mProg->exec(); + if ( mCancelled ) { + kdDebug(5700) << "query cancelled!" << endl; + job->kill( true ); + } else { + if ( !mErrorMsg.isEmpty() ) KMessageBox::error( this, mErrorMsg ); + } +} + +void LdapConfigWidget::mQueryMechClicked() +{ + mAttr = "supportedsaslmechanisms"; + sendQuery(); + if ( !mQResult.isEmpty() ) { + mQResult.sort(); + mMech->clear(); + mMech->insertStringList( mQResult ); + } +} + +void LdapConfigWidget::mQueryDNClicked() +{ + mAttr = "namingcontexts"; + sendQuery(); + if ( !mQResult.isEmpty() ) mDn->setText( mQResult.first() ); +} + +void LdapConfigWidget::setAnonymous( int state ) +{ + if ( state == QButton::Off ) return; + if ( mUser ) mUser->setEnabled(false); + if ( mPassword ) mPassword->setEnabled(false); + if ( mBindDN ) mBindDN->setEnabled(false); + if ( mRealm ) mRealm->setEnabled(false); + if ( mMech ) mMech->setEnabled(false); + if ( mQueryMech ) mQueryMech->setEnabled(false); +} + +void LdapConfigWidget::setSimple( int state ) +{ + if ( state == QButton::Off ) return; + if ( mUser ) mUser->setEnabled(true); + if ( mPassword ) mPassword->setEnabled(true); + if ( mBindDN ) mBindDN->setEnabled(false); + if ( mRealm ) mRealm->setEnabled(false); + if ( mMech ) mMech->setEnabled(false); + if ( mQueryMech ) mQueryMech->setEnabled(false); +} + +void LdapConfigWidget::setSASL( int state ) +{ + if ( state == QButton::Off ) return; + if ( mUser ) mUser->setEnabled(true); + if ( mPassword ) mPassword->setEnabled(true); + if ( mBindDN ) mBindDN->setEnabled(true); + if ( mRealm ) mRealm->setEnabled(true); + if ( mMech ) mMech->setEnabled(true); + if ( mQueryMech ) mQueryMech->setEnabled(true); +} + +void LdapConfigWidget::setLDAPPort() +{ + mPort->setValue( 389 ); +} + +void LdapConfigWidget::setLDAPSPort() +{ + mPort->setValue( 636 ); +} + + +LDAPUrl LdapConfigWidget::url() const +{ + LDAPUrl _url; + if ( mSecSSL && mSecSSL->isChecked() ) + _url.setProtocol( "ldaps" ); + else + _url.setProtocol( "ldap" ); + + if ( mUser ) _url.setUser( mUser->text() ); + if ( mPassword ) _url.setPass( mPassword->text() ); + if ( mHost ) _url.setHost( mHost->text() ); + if ( mPort ) _url.setPort( mPort->value() ); + if ( mDn ) _url.setDn( mDn->text() ); + if ( mVer ) _url.setExtension( "x-ver", QString::number( mVer->value() ) ); + if ( mSizeLimit && mSizeLimit->value() != 0 ) + _url.setExtension( "x-sizelimit", QString::number( mSizeLimit->value() ) ); + if ( mTimeLimit && mTimeLimit->value() != 0 ) + _url.setExtension( "x-timelimit", QString::number( mTimeLimit->value() ) ); + if ( mSecTLS && mSecTLS->isChecked() ) _url.setExtension( "x-tls","" ); + if ( mFilter && !mFilter->text().isEmpty() ) + _url.setFilter( mFilter->text() ); + if ( mSASL && mSASL->isChecked() ) { + _url.setExtension( "x-sasl", "" ); + _url.setExtension( "x-mech", mMech->currentText() ); + if ( mBindDN && !mBindDN->text().isEmpty() ) + _url.setExtension( "bindname", mBindDN->text() ); + if ( mRealm && !mRealm->text().isEmpty() ) + _url.setExtension( "x-realm", mRealm->text() ); + } + return ( _url ); +} + +void LdapConfigWidget::setUser( const QString &user ) +{ + if ( mUser ) mUser->setText( user ); +} + +QString LdapConfigWidget::user() const +{ + return ( mUser ? mUser->text() : QString::null ); +} + +void LdapConfigWidget::setPassword( const QString &password ) +{ + if ( mPassword ) mPassword->setText( password ); +} + +QString LdapConfigWidget::password() const +{ + return ( mPassword ? mPassword->text() : QString::null ); +} + +void LdapConfigWidget::setBindDN( const QString &binddn ) +{ + if ( mBindDN ) mBindDN->setText( binddn ); +} + +QString LdapConfigWidget::bindDN() const +{ + return ( mBindDN ? mBindDN->text() : QString::null ); +} + +void LdapConfigWidget::setRealm( const QString &realm ) +{ + if ( mRealm ) mRealm->setText( realm ); +} + +QString LdapConfigWidget::realm() const +{ + return ( mRealm ? mRealm->text() : QString::null ); +} + +void LdapConfigWidget::setHost( const QString &host ) +{ + if ( mHost ) mHost->setText( host ); +} + +QString LdapConfigWidget::host() const +{ + return ( mHost ? mHost->text() : QString::null ); +} + +void LdapConfigWidget::setPort( int port ) +{ + if ( mPort ) mPort->setValue( port ); +} + +int LdapConfigWidget::port() const +{ + return ( mPort ? mPort->value() : 389 ); +} + +void LdapConfigWidget::setVer( int ver ) +{ + if ( mVer ) mVer->setValue( ver ); +} + +int LdapConfigWidget::ver() const +{ + return ( mVer ? mVer->value() : 3 ); +} + +void LdapConfigWidget::setDn( const QString &dn ) +{ + if ( mDn ) mDn->setText( dn ); +} + +QString LdapConfigWidget::dn() const +{ + return ( mDn ? mDn->text() : QString::null ); +} + +void LdapConfigWidget::setFilter( const QString &filter ) +{ + if ( mFilter ) mFilter->setText( filter ); +} + +QString LdapConfigWidget::filter() const +{ + return ( mFilter ? mFilter->text() : QString::null ); +} + +void LdapConfigWidget::setMech( const QString &mech ) +{ + if ( mMech == 0 ) return; + if ( !mech.isEmpty() ) { + int i = 0; + while ( i < mMech->count() ) { + if ( mMech->text( i ) == mech ) break; + i++; + } + if ( i == mMech->count() ) mMech->insertItem( mech ); + mMech->setCurrentItem( i ); + } +} + +QString LdapConfigWidget::mech() const +{ + return ( mMech ? mMech->currentText() : QString::null ); +} + +void LdapConfigWidget::setSecNO( bool b ) +{ + if ( mSecNO ) mSecNO->setChecked( b ); +} + +bool LdapConfigWidget::isSecNO() const +{ + return ( mSecNO ? mSecNO->isChecked() : true ); +} + +void LdapConfigWidget::setSecTLS( bool b ) +{ + if ( mSecTLS ) mSecTLS->setChecked( b ); +} + +bool LdapConfigWidget::isSecTLS() const +{ + return ( mSecTLS ? mSecTLS->isChecked() : false ); +} + +void LdapConfigWidget::setSecSSL( bool b ) +{ + if ( mSecSSL ) mSecSSL->setChecked( b ); +} + +bool LdapConfigWidget::isSecSSL() const +{ + return ( mSecSSL ? mSecSSL->isChecked() : false ); +} + +void LdapConfigWidget::setAuthAnon( bool b ) +{ + if ( mAnonymous ) mAnonymous->setChecked( b ); +} + +bool LdapConfigWidget::isAuthAnon() const +{ + return ( mAnonymous ? mAnonymous->isChecked() : true ); +} + +void LdapConfigWidget::setAuthSimple( bool b ) +{ + if ( mSimple ) mSimple->setChecked( b ); +} + +bool LdapConfigWidget::isAuthSimple() const +{ + return ( mSimple ? mSimple->isChecked() : false ); +} + +void LdapConfigWidget::setAuthSASL( bool b ) +{ + if ( mSASL ) mSASL->setChecked( b ); +} + +bool LdapConfigWidget::isAuthSASL() const +{ + return ( mSASL ? mSASL->isChecked() : false ); +} + +void LdapConfigWidget::setSizeLimit( int sizelimit ) +{ + if ( mSizeLimit ) mSizeLimit->setValue( sizelimit ); +} + +int LdapConfigWidget::sizeLimit() const +{ + return ( mSizeLimit ? mSizeLimit->value() : 0 ); +} + +void LdapConfigWidget::setTimeLimit( int timelimit ) +{ + if ( mTimeLimit ) mTimeLimit->setValue( timelimit ); +} + +int LdapConfigWidget::timeLimit() const +{ + return ( mTimeLimit ? mTimeLimit->value() : 0 ); +} + +int LdapConfigWidget::flags() const +{ + return mFlags; +} + +void LdapConfigWidget::setFlags( int flags ) +{ + mFlags = flags; + + // First delete all the child widgets. + // FIXME: I hope it's correct + const QObjectList *ch = children(); + QObjectList ch2 = *ch; + QObject *obj; + QWidget *widget; + + obj = ch2.first(); + while ( obj != 0 ) { + widget = dynamic_cast<QWidget*> (obj); + if ( widget && widget->parent() == this ) { + mainLayout->remove( widget ); + delete ( widget ); + } + obj = ch2.next(); + } + // Re-create child widgets according to the new flags + initWidget(); +} diff --git a/kabc/ldapconfigwidget.h b/kabc/ldapconfigwidget.h new file mode 100644 index 000000000..e48b10e53 --- /dev/null +++ b/kabc/ldapconfigwidget.h @@ -0,0 +1,297 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 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 LDAPCONFIGWIDGET_H +#define LDAPCONFIGWIDGET_H + +#include <qwidget.h> +#include <qmap.h> +#include <qstring.h> + +#include <kabc/ldapurl.h> +#include <kabc/ldif.h> +#include <kio/job.h> + +class QGridLayout; +class QSpinBox; +class QPushButton; +class QCheckBox; +class QRadioButton; +class KComboBox; +class KLineEdit; +class KProgressDialog; + +namespace KABC { + + /** + @short LDAP Configuration widget + + This class can be used to query the user for LDAP connection parameters. + It's KConfigXT compatible, using widget names starting with kcfg_ + */ + + class KABC_EXPORT LdapConfigWidget : public QWidget + { + Q_OBJECT + Q_PROPERTY( LCW_Flags flags READ flags WRITE setFlags ) + Q_PROPERTY( QString user READ user WRITE setUser ) + Q_PROPERTY( QString password READ password WRITE setPassword ) + Q_PROPERTY( QString bindDN READ bindDN WRITE setBindDN ) + Q_PROPERTY( QString realm READ realm WRITE setRealm ) + Q_PROPERTY( QString host READ host WRITE setHost ) + Q_PROPERTY( int port READ port WRITE setPort ) + Q_PROPERTY( int ver READ ver WRITE setVer ) + Q_PROPERTY( QString dn READ dn WRITE setDn ) + Q_PROPERTY( QString filter READ filter WRITE setFilter ) + Q_PROPERTY( QString mech READ mech WRITE setMech ) + Q_PROPERTY( bool secNO READ isSecNO WRITE setSecNO ) + Q_PROPERTY( bool secSSL READ isSecSSL WRITE setSecSSL ) + Q_PROPERTY( bool secTLS READ isSecSSL WRITE setSecTLS ) + Q_PROPERTY( bool authAnon READ isAuthAnon WRITE setAuthAnon ) + Q_PROPERTY( bool authSimple READ isAuthSimple WRITE setAuthSimple ) + Q_PROPERTY( bool authSASL READ isAuthSASL WRITE setAuthSASL ) + Q_PROPERTY( int sizeLimit READ sizeLimit WRITE setSizeLimit ) + Q_PROPERTY( int timeLimit READ timeLimit WRITE setTimeLimit ) + Q_SETS ( LCW_Flags ) + + public: + + enum LCW_Flags { + W_USER = 0x1, + W_PASS = 0x2, + W_BINDDN = 0x4, + W_REALM = 0x8, + W_HOST = 0x10, + W_PORT = 0x20, + W_VER = 0x40, + W_DN = 0x80, + W_FILTER = 0x100, + W_SECBOX = 0x400, + W_AUTHBOX = 0x800, + W_TIMELIMIT = 0x1000, + W_SIZELIMIT = 0x2000, + W_ALL = 0xFFFFFFF + }; + + /** Constructs an empty configuration widget. + * You need to call setFlags() after this. + */ + LdapConfigWidget( QWidget* parent = 0, + const char* name = 0, WFlags fl = 0 ); + /** Constructs a configuration widget */ + LdapConfigWidget( int flags, QWidget* parent = 0, + const char* name = 0, WFlags fl = 0 ); + /** Destructs a configuration widget */ + virtual ~LdapConfigWidget(); + + /** Sets the user name. Kconfig widget name: kcfg_ldapuser */ + void setUser( const QString &user ); + /** Gets the user name. Kconfig widget name: kcfg_ldapuser */ + QString user() const; + + /** Sets the password. Kconfig widget name: kcfg_ldappassword */ + void setPassword( const QString &password ); + /** Gets the password. Kconfig widget name: kcfg_ldappassword */ + QString password() const; + + /** + * Sets the bind dn. Useful for SASL proxy auth. + * Kconfig widget name: kcfg_ldapbinddn + */ + void setBindDN( const QString &binddn ); + /** Gets the bind dn. Kconfig widget name: kcfg_ldapbinddn*/ + QString bindDN() const; + + /** Sets the SASL realm. Kconfig widget name: kcfg_ldaprealm */ + void setRealm( const QString &realm ); + /** Gets the SASL realm. Kconfig widget name: kcfg_ldaprealm */ + QString realm() const; + + /** Sets the host name. Kconfig widget name: kcfg_ldaphost */ + void setHost( const QString &host ); + /** Gets the host name. Kconfig widget name: kcfg_ldaphost */ + QString host() const; + + /** Sets the LDAP port. Kconfig widget name: kcfg_ldapport */ + void setPort( int port ); + /** Gets the LDAP port. Kconfig widget name: kcfg_ldapport */ + int port() const; + + /** Sets the LDAP protocol version. Kconfig widget name: kcfg_ldapver */ + void setVer( int ver ); + /** Gets the LDAP protocol version. Kconfig widget name: kcfg_ldapver */ + int ver() const; + + /** Sets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn */ + void setDn( const QString &dn ); + /** Gets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn */ + QString dn() const; + + /** Sets the LDAP Filter. Kconfig widget name: kcfg_ldapfilter */ + void setFilter( const QString &filter ); + /** Gets the LDAP Filter. Kconfig widget name: kcfg_ldapfilter */ + QString filter() const; + + /** Sets the SASL Mechanism. Kconfig widget name: kcfg_ldapsaslmech */ + void setMech( const QString &mech ); + /** Gets the SASL Mechanism. Kconfig widget name: kcfg_ldapsaslmech */ + QString mech() const; + + /** + * Sets the configuration to no transport security. + * Kconfig widget name: kcfg_ldapnosec + */ + void setSecNO( bool b = true ); + /** + * Returns true if no transport security selected. + * Kconfig widget name: kcfg_ldapnosec + */ + bool isSecNO() const; + + /** + * Sets the configuration to TLS. + * Kconfig widget name: kcfg_ldaptls + */ + void setSecTLS( bool b = true ); + /** + * Returns true if TLS selected. + * Kconfig widget name: kcfg_ldaptls + */ + bool isSecTLS() const; + + /** + * Sets the configuration to SSL. + * Kconfig widget name: kcfg_ldapssl + */ + void setSecSSL( bool b = true ); + /** + * Returns true if SSL selected. + * Kconfig widget name: kcfg_ldapssl + */ + bool isSecSSL() const; + + /** + * Sets the authentication to anonymous. + * Kconfig widget name: kcfg_ldapanon + */ + void setAuthAnon( bool b = true ); + /** + * Returns true if Anonymous authentication selected. + * Kconfig widget name: kcfg_ldapanon + */ + bool isAuthAnon() const; + + /** + * Sets the authentication to simple. + * Kconfig widget name: kcfg_ldapsimple + */ + void setAuthSimple( bool b = true ); + /** + * Returns true if Simple authentication selected. + * Kconfig widget name: kcfg_ldapsimple + */ + bool isAuthSimple() const; + + /** + * Sets the authentication to SASL. + * Kconfig widget name: kcfg_ldapsasl + */ + void setAuthSASL( bool b = true ); + /** + * Returns true if SASL authentication selected. + * Kconfig widget name: kcfg_ldapsasl + */ + bool isAuthSASL() const; + + /** + * Sets the size limit. + * KConfig widget name: kcfg_ldapsizelimit + */ + void setSizeLimit( int sizelimit ); + /** + * Returns the size limit. + * KConfig widget name: kcfg_ldapsizelimit + */ + int sizeLimit() const; + + /** + * Sets the time limit. + * KConfig widget name: kcfg_ldaptimelimit + */ + void setTimeLimit( int timelimit ); + /** + * Returns the time limit. + * KConfig widget name: kcfg_ldaptimelimit + */ + int timeLimit() const; + + int flags() const; + void setFlags( int flags ); + + /** + * Returns a LDAP Url constructed from the settings given. + * Extensions are filled for use in the LDAP ioslave + */ + KABC::LDAPUrl url() const; + + private slots: + void setLDAPPort(); + void setLDAPSPort(); + void setAnonymous( int state ); + void setSimple( int state ); + void setSASL( int state ); + void mQueryDNClicked(); + void mQueryMechClicked(); + void loadData( KIO::Job*, const QByteArray& ); + void loadResult( KIO::Job* ); + private: + + int mFlags; + LDIF mLdif; + QStringList mQResult; + QString mAttr; + + KLineEdit *mUser; + KLineEdit *mPassword; + KLineEdit *mHost; + QSpinBox *mPort, *mVer, *mSizeLimit, *mTimeLimit; + KLineEdit *mDn, *mBindDN, *mRealm; + KLineEdit *mFilter; + QRadioButton *mAnonymous,*mSimple,*mSASL; + QCheckBox *mSubTree; + QPushButton *mEditButton; + QPushButton *mQueryMech; + QRadioButton *mSecNO,*mSecTLS,*mSecSSL; + KComboBox *mMech; + + QString mErrorMsg; + bool mCancelled; + KProgressDialog *mProg; + + QGridLayout *mainLayout; + class LDAPConfigWidgetPrivate; + LDAPConfigWidgetPrivate *d; + + void sendQuery(); + void initWidget(); + }; +} + +#endif diff --git a/kabc/ldapurl.cpp b/kabc/ldapurl.cpp new file mode 100644 index 000000000..b7ee2a16f --- /dev/null +++ b/kabc/ldapurl.cpp @@ -0,0 +1,201 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 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 <kdebug.h> +#include <qstringlist.h> +#include <qdir.h> + +#include "ldapurl.h" + +using namespace KABC; + +LDAPUrl::LDAPUrl() +{ + m_scope = Base; +} + +LDAPUrl::LDAPUrl(const KURL &_url) + : KURL(_url), m_extensions() +{ + m_dn = path(); + if ( !QDir::isRelativePath(m_dn) ) +#ifdef Q_WS_WIN + m_dn.remove(0,3); // e.g. "c:/" +#else + m_dn.remove(0,1); +#endif + parseQuery(); +} + +void LDAPUrl::setDn( const QString &dn) +{ + m_dn = dn; + if ( !QDir::isRelativePath(m_dn) ) +#ifdef Q_WS_WIN + m_dn.remove(0,3); // e.g. "c:/" +#else + m_dn.remove(0,1); +#endif + setPath(m_dn); +} + +bool LDAPUrl::hasExtension( const QString &key ) const +{ + return m_extensions.contains( key ); +} + +LDAPUrl::Extension LDAPUrl::extension( const QString &key ) const +{ + QMap<QString, Extension>::const_iterator it; + + it = m_extensions.find( key ); + if ( it != m_extensions.constEnd() ) + return (*it); + else { + Extension ext; + ext.value = ""; + ext.critical = false; + return ext; + } +} + +QString LDAPUrl::extension( const QString &key, bool &critical ) const +{ + Extension ext; + + ext = extension( key ); + critical = ext.critical; + return ext.value; +} + +void LDAPUrl::setExtension( const QString &key, const LDAPUrl::Extension &ext ) +{ + m_extensions[ key ] = ext; + updateQuery(); +} + +void LDAPUrl::setExtension( const QString &key, const QString &value, bool critical ) +{ + Extension ext; + ext.value = value; + ext.critical = critical; + setExtension( key, ext ); +} + +void LDAPUrl::removeExtension( const QString &key ) +{ + m_extensions.remove( key ); + updateQuery(); +} + +void LDAPUrl::updateQuery() +{ + Extension ext; + QMap<QString, Extension>::iterator it; + QString q = "?"; + + // set the attributes to query + if ( m_attributes.count() > 0 ) q += m_attributes.join(","); + + // set the scope + q += "?"; + switch( m_scope ) { + case Sub: + q += "sub"; + break; + case One: + q += "one"; + break; + case Base: + q += "base"; + break; + } + + // set the filter + q += "?"; + if ( m_filter != "(objectClass=*)" && !m_filter.isEmpty() ) + q += m_filter; + + // set the extensions + q += "?"; + for ( it = m_extensions.begin(); it != m_extensions.end(); ++it ) { + if ( it.data().critical ) q += "!"; + q += it.key(); + if ( !it.data().value.isEmpty() ) + q += "=" + it.data().value; + q += ","; + } + while ( q.endsWith("?") || q.endsWith(",") ) + q.remove( q.length() - 1, 1 ); + + setQuery(q); + kdDebug(5700) << "LDAP URL updateQuery(): " << prettyURL() << endl; +} + +void LDAPUrl::parseQuery() +{ + Extension ext; + QStringList extensions; + QString q = query(); + // remove first ? + if (q.startsWith("?")) + q.remove(0,1); + + // split into a list + QStringList url_items = QStringList::split("?", q, true); + + m_attributes.clear(); + m_scope = Base; + m_filter = "(objectClass=*)"; + m_extensions.clear(); + + int i = 0; + for ( QStringList::Iterator it = url_items.begin(); it != url_items.end(); ++it, i++ ) { + switch (i) { + case 0: + m_attributes = QStringList::split(",", (*it), false); + break; + case 1: + if ( (*it) == "sub" ) m_scope = Sub; else + if ( (*it) == "one") m_scope = One; + break; + case 2: + m_filter = decode_string( *it ); + break; + case 3: + extensions = QStringList::split(",", (*it), false); + break; + } + } + + QString name,value; + for ( QStringList::Iterator it = extensions.begin(); it != extensions.end(); ++it ) { + ext.critical = false; + name = decode_string( (*it).section('=',0,0) ).lower(); + value = decode_string( (*it).section('=',1) ); + if ( name.startsWith("!") ) { + ext.critical = true; + name.remove(0, 1); + } + kdDebug(5700) << "LDAPUrl extensions name= " << name << " value: " << value << endl; + ext.value = value.replace( "%2", "," ); + setExtension( name, ext ); + } +} diff --git a/kabc/ldapurl.h b/kabc/ldapurl.h new file mode 100644 index 000000000..6cfc9edbc --- /dev/null +++ b/kabc/ldapurl.h @@ -0,0 +1,110 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 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 _K_LDAPURL_H_ +#define _K_LDAPURL_H_ + +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> + +#include <kurl.h> + +namespace KABC { + +/** + * LDAPUrl + + * LDAPUrl implements an RFC 2255 compliant LDAP Url parser, with minimal + * differences. LDAP Urls implemented by this class has the following format: + * ldap[s]://[user[:password]@]hostname[:port]["/" [dn ["?" [attributes] + * ["?" [scope] ["?" [filter] ["?" extensions]]]]]] + */ + + + class KABC_EXPORT LDAPUrl : public KURL + { + public: + + struct Extension { + QString value; + bool critical; + }; + + typedef enum Scope { Base, One, Sub }; + + /** Constructs an empty KLDAPUrl. */ + LDAPUrl(); + /** Constructs a KLDAPUrl from a KURL. */ + LDAPUrl( const KURL &url ); + + /** + * Returns the dn part of the LDAP Url (same as path(), but slash removed + * from the beginning). + */ + const QString& dn() const { return m_dn; } + /** Sets the the dn part of the LDAP Url. */ + void setDn( const QString &dn ); + + /** Returns the attributes part of the LDAP Url */ + const QStringList &attributes() { return m_attributes; } + /** Sets the attributes part of the LDAP Url */ + void setAttributes( const QStringList &attributes ) + { m_attributes=attributes; updateQuery(); } + + /** Returns the scope part of the LDAP Url */ + Scope scope() const { return m_scope; } + /** Sets the scope part of the LDAP Url */ + void setScope(Scope scope) { m_scope = scope; updateQuery(); } + + /** Returns the filter part of the LDAP Url */ + const QString &filter() const { return m_filter; } + /** Sets the filter part of the LDAP Url */ + void setFilter( QString filter ) { m_filter = filter; updateQuery(); } + + /** Returns if the specified extension exists in the LDAP Url */ + bool hasExtension( const QString &key ) const; + /** Returns the specified extension */ + Extension extension( const QString &key ) const; + /** Returns the specified extension */ + QString extension( const QString &key, bool &critical ) const; + /** Sets the specified extension key with the value and criticality in ext */ + void setExtension( const QString &key, const Extension &ext ); + /** Sets the specified extension key with the value and criticality specified */ + void setExtension( const QString &key, const QString &value, bool critical = false ); + /** Removes the specified extension */ + void removeExtension( const QString &key ); + /** Updates the query component from the attributes, scope, filter and extensions */ + void updateQuery(); + + protected: + void parseQuery(); + + private: + + QMap<QString, Extension> m_extensions; + QString m_dn; + QStringList m_attributes; + Scope m_scope; + QString m_filter; + }; +} + +#endif diff --git a/kabc/ldif.cpp b/kabc/ldif.cpp new file mode 100644 index 000000000..6d4e033e2 --- /dev/null +++ b/kabc/ldif.cpp @@ -0,0 +1,365 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 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 <kdebug.h> +#include <kmdcodec.h> + +#include "ldif.h" + +using namespace KABC; + +LDIF::LDIF() +{ + startParsing(); +} + +LDIF::~LDIF() +{ +} + +QCString LDIF::assembleLine( const QString &fieldname, const QByteArray &value, + uint linelen, bool url ) +{ + bool safe = false; + bool isDn; + QCString result; + uint i; + + if ( url ) { + result = fieldname.utf8() + ":< " + QCString( value.data(), value.size()+1 ); + } else { + isDn = fieldname.lower() == "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 ( 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.utf8() + ": " + QCString( value.data(), value.size()+1 ); + } else { + result = fieldname.utf8() + ":: " + KCodecs::base64Encode( value, false ); + } + + if ( linelen > 0 ) { + i = (fieldname.length()+2) > linelen ? fieldname.length()+2 : linelen; + while ( i < result.length() ) { + result.insert( i, "\n " ); + i += linelen+2; + } + } + } + return result; +} + +QCString LDIF::assembleLine( const QString &fieldname, const QCString &value, + uint linelen, bool url ) +{ + QCString ret; + QByteArray tmp; + uint valuelen = value.length(); + const char *data = value.data(); + + tmp.setRawData( data, valuelen ); + ret = assembleLine( fieldname, tmp, linelen, url ); + tmp.resetRawData( data, valuelen ); + return ret; + +} + +QCString LDIF::assembleLine( const QString &fieldname, const QString &value, + uint linelen, bool url ) +{ + return assembleLine( fieldname, value.utf8(), linelen, url ); +} + +bool LDIF::splitLine( const QCString &line, QString &fieldname, QByteArray &value ) +{ + int position; + QByteArray tmp; + int linelen; + const char *data; + +// kdDebug(5700) << "splitLine line: " << QString::fromUtf8(line) << endl; + + position = line.find( ":" ); + if ( position == -1 ) { + // strange: we did not find a fieldname + fieldname = ""; + QCString str; + str = line.stripWhiteSpace(); + linelen = str.length(); + data = str.data(); + tmp.setRawData( data, linelen ); + value = tmp.copy(); + tmp.resetRawData( data, linelen ); +// kdDebug(5700) << "value : " << value[0] << endl; + return false; + } + + linelen = line.length(); + + if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) { + // String is BASE64 encoded -> decode it now. + fieldname = QString::fromUtf8( + line.left( position ).stripWhiteSpace() ); + if ( linelen <= ( position + 3 ) ) { + value.resize( 0 ); + return false; + } + data = &line.data()[ position + 3 ]; + tmp.setRawData( data, linelen - position - 3 ); + KCodecs::base64Decode( tmp, value ); + tmp.resetRawData( data, linelen - position - 3 ); + return false; + } + + if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) { + // String is an URL. + fieldname = QString::fromUtf8( + line.left( position ).stripWhiteSpace() ); + if ( linelen <= ( position + 3 ) ) { + value.resize( 0 ); + return false; + } + data = &line.data()[ position + 3]; + tmp.setRawData( data, linelen - position - 3 ); + value = tmp.copy(); + tmp.resetRawData( data, linelen - position - 3 ); + return true; + } + + fieldname = QString::fromUtf8(line.left( position ).stripWhiteSpace()); + if ( linelen <= ( position + 2 ) ) { + value.resize( 0 ); + return false; + } + data = &line.data()[ position + 2 ]; + tmp.setRawData( data, linelen - position - 2 ); + value = tmp.copy(); + tmp.resetRawData( data, linelen - position - 2 ); + return false; +} + +bool LDIF::splitControl( const QCString &line, QString &oid, bool &critical, + QByteArray &value ) +{ + QString tmp; + critical = false; + bool url = splitLine( line, tmp, value ); + + kdDebug(5700) << "splitControl: value: " << QString::fromUtf8(value, value.size()) << endl; + if ( tmp.isEmpty() ) { + tmp = QString::fromUtf8( value, value.size() ); + value.resize( 0 ); + } + if ( tmp.right( 4 ) == "true" ) { + critical = true; + tmp.truncate( tmp.length() - 5 ); + } else if ( tmp.right( 5 ) == "false" ) { + critical = false; + tmp.truncate( tmp.length() - 6 ); + } + oid = tmp; + return url; +} + +LDIF::ParseVal LDIF::processLine() +{ + + if ( mIsComment ) return None; + + ParseVal retval = None; + if ( mLastParseVal == EndEntry ) mEntryType = Entry_None; + + mUrl = splitLine( line, mAttr, mVal ); + + QString attrLower = mAttr.lower(); + + switch ( mEntryType ) { + case Entry_None: + if ( attrLower == "version" ) { + if ( !mDn.isEmpty() ) retval = Err; + } else if ( attrLower == "dn" ) { + kdDebug(5700) << "ldapentry dn: " << QString::fromUtf8( mVal, mVal.size() ) << endl; + mDn = QString::fromUtf8( mVal, mVal.size() ); + mModType = Mod_None; + retval = NewEntry; + } else if ( attrLower == "changetype" ) { + if ( mDn.isEmpty() ) + retval = Err; + else { + QString tmpval = QString::fromUtf8( mVal, mVal.size() ); + kdDebug(5700) << "changetype: " << tmpval << endl; + if ( tmpval == "add" ) mEntryType = Entry_Add; + else if ( tmpval == "delete" ) mEntryType = Entry_Del; + else if ( tmpval == "modrdn" || tmpval == "moddn" ) { + mNewRdn = ""; + mNewSuperior = ""; + mDelOldRdn = true; + mEntryType = Entry_Modrdn; + } + else if ( tmpval == "modify" ) mEntryType = Entry_Mod; + else retval = Err; + } + } else if ( attrLower == "control" ) { + mUrl = splitControl( QCString( mVal, mVal.size() + 1 ), mOid, mCritical, mVal ); + retval = Control; + } else if ( !mAttr.isEmpty() && mVal.size() > 0 ) { + mEntryType = Entry_Add; + retval = Item; + } + break; + case Entry_Add: + if ( mAttr.isEmpty() && mVal.size() == 0 ) + retval = EndEntry; + else + retval = Item; + break; + case Entry_Del: + if ( mAttr.isEmpty() && mVal.size() == 0 ) + retval = EndEntry; + else + retval = Err; + break; + case Entry_Mod: + if ( mModType == Mod_None ) { + kdDebug(5700) << "kio_ldap: new modtype " << mAttr << endl; + if ( mAttr.isEmpty() && mVal.size() == 0 ) { + retval = EndEntry; + } else if ( attrLower == "add" ) { + mModType = Mod_Add; + } else if ( attrLower == "replace" ) { + mModType = Mod_Replace; + mAttr = QString::fromUtf8( mVal, mVal.size() ); + mVal.resize( 0 ); + retval = Item; + } else if ( attrLower == "delete" ) { + mModType = Mod_Del; + mAttr = QString::fromUtf8( mVal, mVal.size() ); + mVal.resize( 0 ); + retval = Item; + } else { + retval = Err; + } + } else { + if ( mAttr.isEmpty() ) { + if ( QString::fromUtf8( mVal, mVal.size() ) == "-" ) { + mModType = Mod_None; + } else if ( mVal.size() == 0 ) { + retval = EndEntry; + } else + retval = Err; + } else + retval = Item; + } + break; + case Entry_Modrdn: + if ( mAttr.isEmpty() && mVal.size() == 0 ) + retval = EndEntry; + else if ( attrLower == "newrdn" ) + mNewRdn = QString::fromUtf8( mVal, mVal.size() ); + else if ( attrLower == "newsuperior" ) + mNewSuperior = QString::fromUtf8( mVal, mVal.size() ); + else if ( attrLower == "deleteoldrdn" ) { + if ( mVal.size() > 0 && mVal[0] == '0' ) + mDelOldRdn = false; + else if ( mVal.size() > 0 && mVal[0] == '1' ) + mDelOldRdn = true; + else + retval = Err; + } else + retval = Err; + break; + } + return retval; +} + +LDIF::ParseVal LDIF::nextItem() +{ + ParseVal retval = None; + char c=0; + + while( retval == None ) { + if ( mPos < mLdif.size() ) { + c = mLdif[mPos]; + mPos++; + if ( mIsNewLine && c == '\r' ) continue; //handle \n\r line end + if ( mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding + mIsNewLine = false; + continue; + } + if ( mIsNewLine ) { + mIsNewLine = false; + retval = processLine(); + mLastParseVal = retval; + line.resize( 0 ); + mIsComment = ( c == '#' ); + } + if ( c == '\n' || c == '\r' ) { + mLineNo++; + mIsNewLine = true; + continue; + } + } else { + retval = MoreData; + break; + } + + if ( !mIsComment ) line += c; + } + return retval; +} + +void LDIF::endLDIF() +{ + QByteArray tmp( 3 ); + tmp[ 0 ] = '\n'; + tmp[ 1 ] = '\n'; + tmp[ 2 ] = '\n'; + mLdif = tmp; + mPos = 0; +} + +void LDIF::startParsing() +{ + mPos = mLineNo = 0; + mDelOldRdn = false; + mEntryType = Entry_None; + mModType = Mod_None; + mDn = mNewRdn = mNewSuperior = ""; + line = ""; + mIsNewLine = false; + mIsComment = false; + mLastParseVal = None; +} diff --git a/kabc/ldif.h b/kabc/ldif.h new file mode 100644 index 000000000..cad227774 --- /dev/null +++ b/kabc/ldif.h @@ -0,0 +1,182 @@ +/* + This file is part of libkabc. + Copyright (c) 2004 Szombathelyi Gyorgy <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 _K_LDIF_H_ +#define _K_LDIF_H_ + +#include <qstring.h> +#include <qcstring.h> +#include <qmemarray.h> + +#include <kdelibs_export.h> + +namespace KABC { + + /** + * 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 KABC_EXPORT LDIF + { + public: + + enum ParseVal{ None, NewEntry, EndEntry, Item, Control, Err, MoreData }; + enum EntryType{ Entry_None, Entry_Add, Entry_Del, Entry_Mod, Entry_Modrdn }; + enum ModType{ Mod_None, Mod_Add, Mod_Replace, Mod_Del }; + LDIF(); + virtual ~LDIF(); + + /** + * Assembles fieldname and value into a valid LDIF line, BASE64 encodes the + * value if neccessary 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 QCString 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 QCString as the value. + */ + static QCString assembleLine( const QString &fieldname, + const QCString &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 QCString 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. + * @returns true if value is an URL, false otherwise + */ + static bool splitLine( const QCString &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 QCString &line, QString &oid, bool &critical, + QByteArray &value ); + /** + * Starts the parsing of a new LDIF + */ + void startParsing(); + /** + * Process one LDIF line + */ + ParseVal processLine(); + /** + * Process the LDIF until a complete item can be returned + * @returns 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. + */ + ParseVal nextItem(); + /** + * Sets a chunk of LDIF. Call before startParsing(), or if nextItem() returned + * MoreData. + */ + void setLDIF( const QByteArray &ldif ) { mLdif = ldif; mPos = 0; } + /** + * 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 { return mEntryType; } + /** + * Returns the LDAP modify request type if entryType() returned Entry_Mod. + */ + int modType() const { return mModType; } + /** + * Returns the Distinguished Name of the current entry. + */ + const QString& dn() const { return mDn; } + /** + * Returns the new Relative Distinguished Name if modType() returned Entry_Modrdn. + */ + const QString& newRdn() const { return mNewRdn; } + /** + * Returns the new parent of the entry if modType() returned Entry_Modrdn. + */ + const QString& newSuperior() const { return mNewSuperior; } + /** + * Returns if the delete of the old RDN is required. + */ + bool delOldRdn() const { return mDelOldRdn; } + /** + * Returns the attribute name. + */ + const QString& attr() const { return mAttr; } + /** + * Returns the attribute value. + */ + const QByteArray& val() const { return mVal; } + /** + * Returns if val() is an url + */ + bool isUrl() const { return mUrl; } + /** + * Returns the criticality level when modType() returned Control. + */ + bool critical() const { return mCritical; } + /** + * Returns the OID when modType() returned Control. + */ + const QString& oid() const { return mOid; } + /** + * Returns the line number which the parser processes. + */ + uint lineNo() const { return mLineNo; } + private: + int mModType; + bool mDelOldRdn, mUrl; + QString mDn,mAttr,mNewRdn,mNewSuperior, mOid; + QByteArray mLdif, mVal; + EntryType mEntryType; + + bool mIsNewLine, mIsComment,mCritical; + ParseVal mLastParseVal; + uint mPos,mLineNo; + QCString line; + + class LDIFPrivate; + LDIFPrivate *d; + }; +} + +#endif diff --git a/kabc/ldifconverter.cpp b/kabc/ldifconverter.cpp new file mode 100644 index 000000000..684f07bbd --- /dev/null +++ b/kabc/ldifconverter.cpp @@ -0,0 +1,573 @@ +/* + 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 <qstring.h> +#include <qstringlist.h> +#include <qregexp.h> +#include <qtextstream.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kmdcodec.h> + +#include "addressee.h" +#include "address.h" + +#include "ldif.h" +#include "ldifconverter.h" +#include "vcardconverter.h" + +using namespace KABC; + +/* generate LDIF stream */ + +bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str ) +{ + AddresseeList::ConstIterator it; + for ( it = addrList.begin(); it != addrList.end(); ++it ) { + addresseeToLDIF( *it, str ); + } + return true; +} + + + +static void ldif_out( QTextStream &t, QString formatStr, QString value ) +{ + if ( value.isEmpty() ) + return; + + QCString 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, IO_WriteOnly|IO_Append ); + t.setEncoding( QTextStream::UnicodeUTF8 ); + + const Address homeAddr = addr.address( Address::Home ); + const Address workAddr = addr.address( Address::Work ); + + ldif_out( t, "dn", QString( "cn=%1,mail=%2" ) + .arg( addr.formattedName().simplifyWhiteSpace() ) + .arg( addr.preferredEmail() ) ); + ldif_out( t, "givenname", addr.givenName() ); + ldif_out( t, "sn", addr.familyName() ); + ldif_out( t, "cn", addr.formattedName().simplifyWhiteSpace() ); + ldif_out( t, "uid", addr.uid() ); + ldif_out( t, "nickname", addr.nickName() ); + ldif_out( t, "xmozillanickname", addr.nickName() ); + + ldif_out( t, "mail", addr.preferredEmail() ); + if ( addr.emails().count() > 1 ) + ldif_out( t, "mozillasecondemail", addr.emails()[ 1 ] ); +//ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" ); + + ldif_out( t, "telephonenumber", addr.phoneNumber( PhoneNumber::Work ).number() ); + ldif_out( t, "facsimiletelephonenumber", addr.phoneNumber( PhoneNumber::Fax ).number() ); + ldif_out( t, "homephone", addr.phoneNumber( PhoneNumber::Home ).number() ); + ldif_out( t, "mobile", addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7 + ldif_out( t, "cellphone", addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x + ldif_out( t, "pager", addr.phoneNumber( PhoneNumber::Pager ).number() ); + ldif_out( t, "pagerphone", addr.phoneNumber( PhoneNumber::Pager ).number() ); + + ldif_out( t, "streethomeaddress", homeAddr.street() ); + ldif_out( t, "postalcode", workAddr.postalCode() ); + ldif_out( t, "postofficebox", workAddr.postOfficeBox() ); + + QStringList streets = QStringList::split( '\n', homeAddr.street() ); + if ( streets.count() > 0 ) + ldif_out( t, "homepostaladdress", streets[ 0 ] ); // Netscape 7 + if ( streets.count() > 1 ) + ldif_out( t, "mozillahomepostaladdress2", streets[ 1 ] ); // Netscape 7 + ldif_out( t, "mozillahomelocalityname", homeAddr.locality() ); // Netscape 7 + ldif_out( t, "mozillahomestate", homeAddr.region() ); + ldif_out( t, "mozillahomepostalcode", homeAddr.postalCode() ); + ldif_out( t, "mozillahomecountryname", Address::ISOtoCountry(homeAddr.country()) ); + ldif_out( t, "locality", workAddr.locality() ); + ldif_out( t, "streetaddress", workAddr.street() ); // Netscape 4.x + + streets = QStringList::split( '\n', workAddr.street() ); + if ( streets.count() > 0 ) + ldif_out( t, "postaladdress", streets[ 0 ] ); + if ( streets.count() > 1 ) + ldif_out( t, "mozillapostaladdress2", streets[ 1 ] ); + ldif_out( t, "countryname", Address::ISOtoCountry(workAddr.country()) ); + ldif_out( t, "l", workAddr.locality() ); + ldif_out( t, "c", Address::ISOtoCountry(workAddr.country()) ); + ldif_out( t, "st", workAddr.region() ); + + ldif_out( t, "title", addr.title() ); + ldif_out( t, "vocation", addr.prefix() ); + ldif_out( t, "ou", addr.role() ); + ldif_out( t, "o", addr.organization() ); + ldif_out( t, "organization", addr.organization() ); + ldif_out( t, "organizationname", addr.organization() ); + + // Compatibility with older kabc versions. + if ( !addr.department().isEmpty() ) + ldif_out( t, "department", addr.department() ); + else + ldif_out( t, "department", addr.custom("KADDRESSBOOK", "X-Department") ); + + ldif_out( t, "workurl", addr.url().prettyURL() ); + ldif_out( t, "homeurl", addr.url().prettyURL() ); + ldif_out( t, "description", addr.note() ); + if (addr.revision().isValid()) + ldif_out(t, "modifytimestamp", dateToVCardString( addr.revision()) ); + + 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, QDateTime dt ) +{ + if (str.isEmpty()) + return true; + + bool endldif = false, end = false; + LDIF ldif; + LDIF::ParseVal ret; + const char *latinstr = str.latin1(); + int latinstrlen = qstrlen( latinstr ); + QByteArray data; + Addressee a; + Address homeAddr, workAddr; + + data.setRawData( latinstr, latinstrlen ); + ldif.setLDIF( data ); + if (!dt.isValid()) + dt = QDateTime::currentDateTime(); + a.setRevision(dt); + homeAddr = Address( Address::Home ); + workAddr = Address( Address::Work ); + + do { + ret = ldif.nextItem(); + switch ( ret ) { + case LDIF::Item: { + QString fieldname = ldif.attr().lower(); + QString value = QString::fromUtf8( ldif.val(), ldif.val().size() ); + evaluatePair( a, homeAddr, workAddr, fieldname, value ); + break; + } + case LDIF::EndEntry: + // if the new address is not empty, append it + 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(dt); + 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 ); + + data.resetRawData( latinstr, latinstrlen ); + + return true; +} + +bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr, + Address &workAddr, + QString &fieldname, QString &value ) +{ + if ( fieldname == QString::fromLatin1( "dn" ) ) // ignore & return false! + return false; + + if ( fieldname.startsWith("#") ) { + 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() + "\n" + value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "givenname" ) ) { + a.setGivenName( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "xmozillanickname") || + fieldname == QString::fromLatin1( "nickname") ) { + a.setNickName( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "sn" ) ) { + a.setFamilyName( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "uid" ) ) { + a.setUid( value ); + return true; + } + if ( fieldname == QString::fromLatin1( "mail" ) || + fieldname == QString::fromLatin1( "mozillasecondemail" ) ) { // mozilla + if ( a.emails().findIndex( value ) == -1 ) + a.insertEmail( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "title" ) ) { + a.setTitle( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "vocation" ) ) { + a.setPrefix( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "cn" ) ) { + a.setFormattedName( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "o" ) || + fieldname == QString::fromLatin1( "organization" ) || // Exchange + fieldname == QString::fromLatin1( "organizationname" ) ) { // Exchange + a.setOrganization( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "description" ) ) { +addComment: + if ( !a.note().isEmpty() ) + a.setNote( a.note() + "\n" ); + a.setNote( a.note() + value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "custom1" ) || + fieldname == QString::fromLatin1( "custom2" ) || + fieldname == QString::fromLatin1( "custom3" ) || + fieldname == QString::fromLatin1( "custom4" ) ) { + goto addComment; + } + + if ( fieldname == QString::fromLatin1( "homeurl" ) || + fieldname == QString::fromLatin1( "workurl" ) ) { + 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 == QString::fromLatin1( "homephone" ) ) { + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "telephonenumber" ) ) { + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mobile" ) ) { // mozilla/Netscape 7 + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "cellphone" ) ) { + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "pager" ) || // mozilla + fieldname == QString::fromLatin1( "pagerphone" ) ) { // mozilla + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "facsimiletelephonenumber" ) ) { + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "xmozillaanyphone" ) ) { // mozilla + a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "street" ) || + fieldname == QString::fromLatin1( "streethomeaddress" ) ) { + homeAddr.setStreet( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "postaladdress" ) ) { // mozilla + workAddr.setStreet( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillapostaladdress2" ) ) { // mozilla + workAddr.setStreet( workAddr.street() + QString::fromLatin1( "\n" ) + value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "postalcode" ) ) { + workAddr.setPostalCode( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "postofficebox" ) ) { + workAddr.setPostOfficeBox( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "homepostaladdress" ) ) { // Netscape 7 + homeAddr.setStreet( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillahomepostaladdress2" ) ) { // mozilla + homeAddr.setStreet( homeAddr.street() + QString::fromLatin1( "\n" ) + value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillahomelocalityname" ) ) { // mozilla + homeAddr.setLocality( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillahomestate" ) ) { // mozilla + homeAddr.setRegion( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillahomepostalcode" ) ) { // mozilla + homeAddr.setPostalCode( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "mozillahomecountryname" ) ) { // mozilla + if ( value.length() <= 2 ) + value = Address::ISOtoCountry(value); + homeAddr.setCountry( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "locality" ) ) { + workAddr.setLocality( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "streetaddress" ) ) { // Netscape 4.x + workAddr.setStreet( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "countryname" ) || + fieldname == QString::fromLatin1( "c" ) ) { // mozilla + if ( value.length() <= 2 ) + value = Address::ISOtoCountry(value); + workAddr.setCountry( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "l" ) ) { // mozilla + workAddr.setLocality( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "st" ) ) { + workAddr.setRegion( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "ou" ) ) { + a.setRole( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "department" ) ) { + a.setDepartment( value ); + return true; + } + + if ( fieldname == QString::fromLatin1( "member" ) ) { + // this is a mozilla list member (cn=xxx, mail=yyy) + QStringList list( QStringList::split( ',', value ) ); + QString name, email; + + QStringList::Iterator it; + for ( it = list.begin(); it != list.end(); ++it ) { + if ( (*it).startsWith( "cn=" ) ) + name = (*it).mid( 3 ).stripWhiteSpace(); + if ( (*it).startsWith( "mail=" ) ) + email = (*it).mid( 5 ).stripWhiteSpace(); + } + if ( !name.isEmpty() && !email.isEmpty() ) + email = " <" + email + ">"; + a.insertEmail( name + email ); + a.insertCategory( i18n( "List of Emails" ) ); + return true; + } + + if ( fieldname == QString::fromLatin1( "modifytimestamp" ) ) { + if (value == QString::fromLatin1("0Z")) // ignore + return true; + QDateTime dt = VCardStringToDate( value ); + if ( dt.isValid() ) { + a.setRevision(dt); + return true; + } + } + + if ( fieldname == QString::fromLatin1( "objectclass" ) ) // ignore + return true; + + kdWarning() << QString("LDIFConverter: Unknown field for '%1': '%2=%3'\n") + .arg(a.formattedName()).arg(fieldname).arg(value); + + return true; +} + +/* The following functions are obsoleted. Similar functionality can be found + * in the LDIF class */ + +bool LDIFConverter::parseSingleLine( Addressee &a, Address &homeAddr, + Address &workAddr, QString &line ) +{ + if ( line.isEmpty() ) + return true; + + QString fieldname, value; + QByteArray val; + + LDIF::splitLine( line.latin1(), fieldname, val ); + value = QString::fromUtf8( val.data(), val.size() ); + return evaluatePair( a, homeAddr, workAddr, fieldname, value); +} + + +bool LDIFConverter::splitLine( QString &line, QString &fieldname, QString &value) +{ + QByteArray val; + bool ret = LDIF::splitLine( line.latin1(), fieldname, val ); + value = QString::fromUtf8( val.data(), val.size() ); + return ret; +} + + +QString LDIFConverter::makeLDIFfieldString( QString formatStr, QString value, bool allowEncode ) +{ + if ( value.isEmpty() ) + return QString(); + + // append format if not given + if (formatStr.find(':') == -1) + formatStr.append(": %1\n"); + + // check if base64-encoding is needed + bool printable = true; + unsigned int i, len; + len = value.length(); + for (i = 0; i<len; ++i ) { + if (!value[i].isPrint()) { + printable = false; + break; + } + } + + if (printable) // always encode if we find special chars... + printable = (value.find('\n') == -1); + + if (!printable && allowEncode) { + // encode to base64 + value = KCodecs::base64Encode( value.utf8() ); + int p = formatStr.find(':'); + if (p>=0) + formatStr.insert(p, ':'); + } + + // generate the new string and split it to 72 chars/line + QCString txt = (formatStr.arg(value)).utf8(); + + if (allowEncode) { + len = txt.length(); + if (len && txt[len-1] == '\n') + --len; + i = 72; + while (i < len) { + txt.insert(i, "\n "); + i += 72+1; + len += 2; + } + } + + return QString::fromUtf8(txt); +} + diff --git a/kabc/ldifconverter.h b/kabc/ldifconverter.h new file mode 100644 index 000000000..299a42e11 --- /dev/null +++ b/kabc/ldifconverter.h @@ -0,0 +1,100 @@ +/* + 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 <qstring.h> +#include <qdatetime.h> + +#include "addressee.h" +#include "addresseelist.h" + +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). + * @since 3.2 + */ + KABC_EXPORT bool LDIFToAddressee( const QString &str, AddresseeList &addrList, QDateTime dt = QDateTime::currentDateTime() ); + + /** + * Converts a list of addressees to a LDIF string. + * + * @param addrList The addresseelist. + * @param str The LDIF string. + * @since 3.2 + */ + 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. + * @since 3.2 + */ + KABC_EXPORT bool addresseeToLDIF( const Addressee &addr, QString &str ); + + /** + * @deprecated + * Obsoleted - please use LDIF::assembleLine() + * Returns a LDIF compatible string representing a given field/value pair. + * If necessary, the value parameter will be base64encoded and split into multiple. + * This function will return an empty string if the given value is empty. + * + * @param field The LDAP field name or a complete LDIF field string (e.g. "cn" or "cn = %1\n"). + * @param value The value for this field. + * @param allowEncode Set to false if you wish no encoding of the value. + * @since 3.2 + */ + KABC_EXPORT QString makeLDIFfieldString( QString field, QString value, bool allowEncode = true ) KDE_DEPRECATED; + + + + /* internal functions - do not use !! */ + + /** No need for this function anymore - use LDIF::splitLine() + evaluatePair() */ + KABC_EXPORT bool parseSingleLine( Addressee &a, + Address &homeAddr, Address &workAddr, QString &line ); + + /** No need for this function anymore - use LDIF::splitLine() */ + KABC_EXPORT bool splitLine( QString &line, QString &fieldname, QString &value); + + + KABC_EXPORT bool evaluatePair( Addressee &a, Address &homeAddr, Address &workAddr, + QString &fieldname, QString &value ); + + } + +} +#endif + diff --git a/kabc/lock.cpp b/kabc/lock.cpp new file mode 100644 index 000000000..a3270459d --- /dev/null +++ b/kabc/lock.cpp @@ -0,0 +1,162 @@ +/* + 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 <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#include <qfile.h> + +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +using namespace KABC; + +Lock::Lock( const QString &identifier ) + : mIdentifier( identifier ) +{ + mIdentifier.replace( "/", "_" ); +} + +Lock::~Lock() +{ + unlock(); +} + +QString Lock::locksDir() +{ + return locateLocal( "data", "kabc/lock/" ); +} + +bool Lock::readLockFile( const QString &filename, int &pid, QString &app ) +{ + QFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) return false; + + QTextStream t( &file ); + pid = t.readLine().toInt(); + app = t.readLine(); + + return true; +} + +bool Lock::writeLockFile( const QString &filename ) +{ + QFile file( filename ); + if ( !file.open( IO_WriteOnly ) ) return false; + QTextStream t( &file ); + t << ::getpid() << endl << QString( KGlobal::instance()->instanceName() ); + + return true; +} + +QString Lock::lockFileName() const +{ + return locksDir() + mIdentifier + ".lock"; +} + +bool Lock::lock() +{ + kdDebug(5700) << "Lock::lock()" << endl; + + QString lockName = lockFileName(); + kdDebug(5700) << "-- lock name: " << lockName << endl; + + if ( QFile::exists( lockName ) ) { // check if it is a stale lock file + int pid; + QString app; + + if ( !readLockFile( lockFileName(), pid, app ) ) { + 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 ); + kdWarning(5700) << "Removed stale lock file from process '" << app << "'" + << endl; + } else { + QString identifier( mIdentifier ); + identifier.replace( '_', '/' ); + + mError = i18n("The address book '%1' is locked by application '%2'.\nIf you believe this is incorrect, just remove the lock file from '%3'") + .arg( identifier ).arg( app ).arg( locateLocal( "data", "kabc/lock/*.lock" ) ); + return false; + } + } + + QString lockUniqueName; + lockUniqueName = mIdentifier + kapp->randomString( 8 ); + mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); + kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; + + // Create unique file + writeLockFile( mLockUniqueName ); + + // Create lock file + int result = ::link( QFile::encodeName( mLockUniqueName ), + QFile::encodeName( lockName ) ); + + if ( result == 0 ) { + mError = ""; + emit locked(); + return true; + } + + // TODO: check stat + + 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( mLockUniqueName ); + emit unlocked(); + } else { + mError = i18n("Unlock failed. Lock file is owned by other process: %1 (%2)") + .arg( app ).arg( QString::number( pid ) ); + kdDebug() << "Lock::unlock(): " << mError << endl; + return false; + } + } + + mError = ""; + return true; +} + +QString Lock::error() const +{ + return mError; +} + +#include "lock.moc" diff --git a/kabc/lock.h b/kabc/lock.h new file mode 100644 index 000000000..1707d0f13 --- /dev/null +++ b/kabc/lock.h @@ -0,0 +1,88 @@ +/* + 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 <qstring.h> +#include <qobject.h> + +#include <kdelibs_export.h> + +namespace KABC { + +/** + This class provides locking functionality for a file, directory or an + arbitrary string-represented resource. +*/ +class KABC_EXPORT 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(); + + virtual QString error() const; + + QString lockFileName() const; + + static bool readLockFile( const QString &filename, int &pid, QString &app ); + static bool writeLockFile( const QString &filename ); + + static QString locksDir(); + + signals: + void locked(); + void unlocked(); + + private: + QString mIdentifier; + + QString mLockUniqueName; + + QString mError; + + class Private; + Private *d; +}; + +} + +#endif diff --git a/kabc/locknull.cpp b/kabc/locknull.cpp new file mode 100644 index 000000000..1df269a24 --- /dev/null +++ b/kabc/locknull.cpp @@ -0,0 +1,63 @@ +/* + 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; + +LockNull::LockNull( bool allowAccess ) + : Lock( QString::null ), mAllowAccess( allowAccess ) +{ +} + +LockNull::~LockNull() +{ + unlock(); +} + +bool LockNull::lock() +{ + if ( !mAllowAccess ) return false; + + kdWarning() << "LockNull::lock() force success. Doesn't actually lock." + << endl; + + emit locked(); + + return true; +} + +bool LockNull::unlock() +{ + emit unlocked(); + return true; +} + +QString LockNull::error() const +{ + if ( 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 000000000..11b8c4fd5 --- /dev/null +++ b/kabc/locknull.h @@ -0,0 +1,54 @@ +/* + 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 <qstring.h> + +#include "lock.h" + +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 LockNull : public Lock +{ + public: + LockNull( bool allowAccess ); + ~LockNull(); + + bool lock(); + bool unlock(); + + QString error() const; + + private: + bool mAllowAccess; + + class Private; + Private *d; +}; + +} + +#endif diff --git a/kabc/phonenumber.cpp b/kabc/phonenumber.cpp new file mode 100644 index 000000000..31fba4a9e --- /dev/null +++ b/kabc/phonenumber.cpp @@ -0,0 +1,213 @@ +/* + 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 <kapplication.h> +#include <klocale.h> + +#include "phonenumber.h" + +using namespace KABC; + +PhoneNumber::PhoneNumber() : + mType( Home ) +{ + init(); +} + +PhoneNumber::PhoneNumber( const QString &number, int type ) : + mType( type ) +{ + init(); + + validateNumber( number ); +} + +PhoneNumber::~PhoneNumber() +{ +} + +void PhoneNumber::init() +{ + mId = KApplication::randomString( 8 ); +} + +void PhoneNumber::validateNumber( const QString &number ) +{ + mNumber = number; + + // remove line breaks + mNumber = mNumber.replace( '\n', "" ); + mNumber = mNumber.replace( '\r', "" ); +} + +bool PhoneNumber::operator==( const PhoneNumber &p ) const +{ + if ( mNumber != p.mNumber ) return false; + if ( mType != p.mType ) return false; + + return true; +} + +bool PhoneNumber::operator!=( const PhoneNumber &p ) const +{ + return !( p == *this ); +} + +void PhoneNumber::setId( const QString &id ) +{ + mId = id; +} + +QString PhoneNumber::id() const +{ + return mId; +} + +void PhoneNumber::setNumber( const QString &number ) +{ + validateNumber( number ); +} + +QString PhoneNumber::number() const +{ + return mNumber; +} + +void PhoneNumber::setType( int type ) +{ + mType = type; +} + +int PhoneNumber::type() const +{ + return mType; +} + +QString PhoneNumber::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 ) ) { + label.append( ( first ? "" : "/" ) + typeLabel( *it ) ); + if ( first ) + first = false; + } + } + + return label; +} + +QString PhoneNumber::label() 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::label( int type ) +{ + return typeLabel( type ); +} + +QString PhoneNumber::typeLabel( int type ) +{ + if ( type & Pref ) + return i18n( "Preferred phone", "Preferred" ); + + switch ( type ) { + case Home: + return i18n("Home phone", "Home"); + break; + case Work: + return i18n("Work phone", "Work"); + break; + case Msg: + return i18n("Messenger"); + break; + case Pref: + return i18n("Preferred Number"); + break; + case Voice: + return i18n("Voice"); + break; + case Fax: + return i18n("Fax"); + break; + case Cell: + return i18n("Mobile Phone", "Mobile" ); + break; + case Video: + return i18n("Video"); + break; + case Bbs: + return i18n("Mailbox"); + break; + case Modem: + return i18n("Modem"); + break; + case Car: + return i18n("Car Phone", "Car" ); + break; + case Isdn: + return i18n("ISDN"); + break; + case Pcs: + return i18n("PCS"); + break; + case Pager: + return i18n("Pager"); + break; + case Home | Fax: + return i18n("Home Fax"); + break; + case Work | Fax: + return i18n("Work Fax"); + break; + default: + return i18n("Other"); + } +} + +QDataStream &KABC::operator<<( QDataStream &s, const PhoneNumber &phone ) +{ + return s << phone.mId << phone.mType << phone.mNumber; +} + +QDataStream &KABC::operator>>( QDataStream &s, PhoneNumber &phone ) +{ + s >> phone.mId >> phone.mType >> phone.mNumber; + + return s; +} diff --git a/kabc/phonenumber.h b/kabc/phonenumber.h new file mode 100644 index 000000000..099cd2261 --- /dev/null +++ b/kabc/phonenumber.h @@ -0,0 +1,161 @@ +/* + 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 <qvaluelist.h> +#include <qstring.h> + +#include <kdelibs_export.h> + +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: + typedef QValueList<PhoneNumber> List; + typedef QValueList<int> TypeList; + + /** + @li @p Home - Home number + @li @p Work - Office number + @li @p Msg - Messaging + @li @p Pref - Preferred number + @li @p Voice - Voice + @li @p Fax - Fax machine + @li @p Cell - Cell phone + @li @p Video - Video phone + @li @p Bbs - Mailbox + @li @p Modem - Modem + @li @p Car - Car phone + @li @p Isdn - ISDN connection + @li @p Pcs - Personal Communication Service + @li @p Pager - Pager + */ + enum Types { Home = 1, Work = 2, Msg = 4, Pref = 8, Voice = 16, Fax = 32, + Cell = 64, Video = 128, Bbs = 256, Modem = 512, Car = 1024, + Isdn = 2048, Pcs = 4096, Pager = 8192 }; + + /** + Create an empty phone number object. + */ + PhoneNumber(); + + /** + Create a phonenumber 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, int type = Home ); + + /** + Destructor. + */ + ~PhoneNumber(); + + bool operator==( const PhoneNumber & ) const; + bool operator!=( const PhoneNumber & ) const; + + /** + Sets the unique identifier. + */ + void setId( const QString &id ); + + /** + Returns the unique identifier. + */ + QString id() const; + + /** + Sets the number. + */ + void setNumber( const QString & ); + + /** + Returns the number. + */ + QString number() const; + + /** + Sets the type. Multiple types can be specified by combining them by + a logical or. + */ + void setType( int ); + + /** + Returns the type. Can be a multiple types combined by a logical or. + */ + int type() const; + + /** + Returns a translated string of all types the address has. + */ + QString typeLabel() const; + + /** + Returns the translated label for phone number depending on its type. + */ + QString label() const; + + /** + Returns a list of all available types + */ + static TypeList typeList(); + + /** + Returns the translated label for phone number type. + */ + static QString typeLabel( int type ); + + /** + Returns the translated label for phone number type. + @obsolete + */ + static QString label( int type ); + + private: + void init(); + void validateNumber( const QString& ); + + QString mId; + + int mType; + QString mNumber; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const PhoneNumber & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, PhoneNumber & ); + +} + +#endif diff --git a/kabc/picture.cpp b/kabc/picture.cpp new file mode 100644 index 000000000..d0b79c89a --- /dev/null +++ b/kabc/picture.cpp @@ -0,0 +1,120 @@ +/* + 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" + +using namespace KABC; + +Picture::Picture() + : mIntern( false ) +{ +} + +Picture::Picture( const QString &url ) + : mUrl( url ), mIntern( false ) +{ +} + +Picture::Picture( const QImage &data ) + : mData( data ), mIntern( true ) +{ +} + +Picture::~Picture() +{ +} + +bool Picture::operator==( const Picture &p ) const +{ + if ( mIntern != p.mIntern ) return false; + + if ( mIntern ) { + if ( mData != p.mData ) + return false; + } else { + if ( mUrl != p.mUrl ) + return false; + } + + return true; +} + +bool Picture::operator!=( const Picture &p ) const +{ + return !( p == *this ); +} + +void Picture::setUrl( const QString &url ) +{ + mUrl = url; + mIntern = false; +} + +void Picture::setData( const QImage &data ) +{ + mData = data; + mIntern = true; +} + +void Picture::setType( const QString &type ) +{ + mType = type; +} + +bool Picture::isIntern() const +{ + return mIntern; +} + +QString Picture::url() const +{ + return mUrl; +} + +QImage Picture::data() const +{ + return mData; +} + +QString Picture::type() const +{ + return mType; +} + +QString Picture::asString() const +{ + if ( mIntern ) + return "intern picture"; + else + return mUrl; +} + +QDataStream &KABC::operator<<( QDataStream &s, const Picture &picture ) +{ + return s << picture.mIntern << picture.mUrl << picture.mType; +// return s << picture.mIntern << picture.mUrl << picture.mType << picture.mData; +} + +QDataStream &KABC::operator>>( QDataStream &s, Picture &picture ) +{ + s >> picture.mIntern >> picture.mUrl >> picture.mType; +// s >> picture.mIntern >> picture.mUrl >> picture.mType >> picture.mData; + return s; +} diff --git a/kabc/picture.h b/kabc/picture.h new file mode 100644 index 000000000..a28f3ae14 --- /dev/null +++ b/kabc/picture.h @@ -0,0 +1,128 @@ +/* + 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 <qimage.h> + +#include <kdelibs_export.h> + +namespace KABC { + +class KABC_EXPORT Picture +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Picture & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Picture & ); + +public: + + /** + * Consturctor. Creates an empty object. + */ + Picture(); + + /** + * Consturctor. + * + * @param url A URL that describes the position of the picture file. + */ + Picture( const QString &url ); + + /** + * Consturctor. + * + * @param data The raw data of the picture. + */ + Picture( const QImage &data ); + + /** + * Destructor. + */ + ~Picture(); + + + bool operator==( const Picture & ) const; + bool operator!=( const Picture & ) 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 asString() const; + +private: + QString mUrl; + QString mType; + QImage mData; + + int mIntern; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Picture & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Picture & ); + +} +#endif diff --git a/kabc/plugin.cpp b/kabc/plugin.cpp new file mode 100644 index 000000000..a00e0187f --- /dev/null +++ b/kabc/plugin.cpp @@ -0,0 +1,61 @@ +/* + 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; + +Plugin::Plugin() +{ +} + +Plugin::~Plugin() +{ +} + +void Plugin::setType( const QString& type ) +{ + mType = type; +} + +QString Plugin::type() const +{ + return mType; +} + +void Plugin::setNameLabel( const QString& label ) +{ + mNameLabel = label; +} + +QString Plugin::nameLabel() const +{ + return mNameLabel; +} + +void Plugin::setDescriptionLabel( const QString& label ) +{ + mDescriptionLabel = label; +} + +QString Plugin::descriptionLabel() const +{ + return mDescriptionLabel; +} diff --git a/kabc/plugin.h b/kabc/plugin.h new file mode 100644 index 000000000..a25b647de --- /dev/null +++ b/kabc/plugin.h @@ -0,0 +1,52 @@ +/* + 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 <qstring.h> + +#include <kdelibs_export.h> + +namespace KABC { + +class KABC_EXPORT Plugin +{ +public: + Plugin(); + virtual ~Plugin(); + + virtual void setType( const QString& type ); + virtual QString type() const; + + virtual void setNameLabel( const QString& label ); + virtual QString nameLabel() const; + + virtual void setDescriptionLabel( const QString& label ); + virtual QString descriptionLabel() const; + +private: + QString mType; + QString mNameLabel; + QString mDescriptionLabel; +}; + +} +#endif diff --git a/kabc/plugins/Makefile.am b/kabc/plugins/Makefile.am new file mode 100644 index 000000000..4024cc9f9 --- /dev/null +++ b/kabc/plugins/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = file dir ldapkio diff --git a/kabc/plugins/dir/Makefile.am b/kabc/plugins/dir/Makefile.am new file mode 100644 index 000000000..bf07e6af3 --- /dev/null +++ b/kabc/plugins/dir/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc -I$(top_builddir) $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourcedirconfig.h + +lib_LTLIBRARIES = libkabc_dir.la +libkabc_dir_la_SOURCES = resourcedir.cpp resourcedirconfig.cpp +libkabc_dir_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined +libkabc_dir_la_LIBADD = $(LIB_KABC) +libkabc_dir_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +kde_module_LTLIBRARIES = kabc_dir.la +kabc_dir_la_SOURCES = resourcedirplugin.cpp +kabc_dir_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -no-undefined +kabc_dir_la_LIBADD = libkabc_dir.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_dir.pot + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = resourcedir.h + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = dir.desktop + +resourcedirplugin.lo: ../../addressee.h diff --git a/kabc/plugins/dir/dir.desktop b/kabc/plugins/dir/dir.desktop new file mode 100644 index 000000000..faffd99d4 --- /dev/null +++ b/kabc/plugins/dir/dir.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Name=Directory +Name[af]=Gids +Name[ar]=دليل +Name[az]=CÉ™rgÉ™ +Name[be]=ТÑчка +Name[bn]=ডিরেকà§à¦Ÿà¦°à¦¿ +Name[br]=Renkell +Name[bs]=Direktorij +Name[ca]=Directori +Name[cs]=Adresář +Name[csb]=Katalog +Name[cy]=Cyfeiriadur +Name[da]=Mappe +Name[de]=Verzeichnis +Name[el]=Κατάλογος +Name[eo]=Dosierujo +Name[es]=Directorio +Name[et]=Kataloog +Name[eu]=Direktorioa +Name[fa]=Ùهرست راهنما +Name[fi]=Hakemisto +Name[fo]=FÃluskrá +Name[fr]=Dossier +Name[fy]=Map +Name[ga]=Comhadlann +Name[gl]=Directório +Name[he]=ספריה +Name[hi]=डिरेकà¥à¤Ÿà¥à¤°à¥€ +Name[hr]=Mapa +Name[hsb]=Zapisk +Name[hu]=Könyvtár +Name[id]=Direktori +Name[is]=Mappa +Name[it]=Cartella +Name[ja]=ディレクトリ +Name[ka]=დáƒáƒ¡áƒ¢áƒ +Name[kk]=Каталог +Name[km]=ážáž +Name[ko]=ìžë£Œë°© +Name[ku]=Peldank +Name[lb]=Verzeechnis +Name[lt]=Aplankas +Name[lv]=Direktorija +Name[mk]=Именик +Name[mn]=Лавлах +Name[ms]=Direktori +Name[mt]=Direttorju +Name[nb]=Katalog +Name[nds]=Orner +Name[ne]=डाइरेकà¥à¤Ÿà¤°à¥€ +Name[nl]=Map +Name[nn]=Katalog +Name[nso]=Tshupetso +Name[oc]=Directori +Name[pa]=ਡਾਇਰੈਕਟਰੀ +Name[pl]=Katalog +Name[pt]=Directoria +Name[pt_BR]=Diretório +Name[ro]=Director +Name[ru]=Каталог +Name[rw]=ububiko +Name[se]=Ohcu +Name[sk]=PrieÄinok +Name[sl]=Imenik +Name[sq]=Fioka +Name[sr]=ФаÑцикла +Name[sr@Latn]=Fascikla +Name[ss]=I-directory +Name[sv]=Katalog +Name[ta]=அடைவ௠+Name[te]=డైరకà±à°Ÿà°°à°¿ +Name[tg]=ФеҳраÑÑ‚ +Name[th]=ไดเรà¸à¸—à¸à¸£à¸µ +Name[tr]=Dizin +Name[tt]=Törgäk +Name[uk]=Каталог +Name[uz]=Jild +Name[uz@cyrillic]=Жилд +Name[ven]=Tsumbavhulwo +Name[vi]=ThÆ° mục +Name[wa]=Ridant +Name[xh]=Ulawulo +Name[zh_CN]=目录 +Name[zh_HK]=目錄 +Name[zh_TW]=目錄 +Name[zu]=Uhlu lwamafayela +X-KDE-Library=kabc_dir +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=dir diff --git a/kabc/plugins/dir/resourcedir.cpp b/kabc/plugins/dir/resourcedir.cpp new file mode 100644 index 000000000..1947e98f3 --- /dev/null +++ b/kabc/plugins/dir/resourcedir.cpp @@ -0,0 +1,310 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 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 <errno.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <qregexp.h> +#include <qtimer.h> +#include <qwidget.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kglobal.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kurlrequester.h> + +#include "addressbook.h" +#include "formatfactory.h" +#include "resourcedirconfig.h" +#include "stdaddressbook.h" +#include "lock.h" + +#include "resourcedir.h" + +using namespace KABC; + +extern "C" +{ + void *init_kabc_dir() + { + return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>(); + } +} + + +ResourceDir::ResourceDir( const KConfig *config ) + : Resource( config ), mAsynchronous( false ) +{ + if ( config ) { + init( config->readPathEntry( "FilePath", StdAddressBook::directoryName() ), + config->readEntry( "FileFormat", "vcard" ) ); + } else { + init( StdAddressBook::directoryName(), "vcard" ); + } +} + +ResourceDir::ResourceDir( const QString &path, const QString &format ) + : Resource( 0 ), mAsynchronous( false ) +{ + init( path, format ); +} + +void ResourceDir::init( const QString &path, const QString &format ) +{ + mFormatName = format; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); + + if ( !mFormat ) { + mFormatName = "vcard"; + mFormat = factory->format( mFormatName ); + } + + mLock = 0; + + connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) ); + connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) ); + connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) ); + + setPath( path ); +} + +ResourceDir::~ResourceDir() +{ + delete mFormat; + mFormat = 0; +} + +void ResourceDir::writeConfig( KConfig *config ) +{ + Resource::writeConfig( config ); + + if ( mPath == StdAddressBook::directoryName() ) + config->deleteEntry( "FilePath" ); + else + config->writePathEntry( "FilePath", mPath ); + + config->writeEntry( "FileFormat", mFormatName ); +} + +Ticket *ResourceDir::requestSaveTicket() +{ + kdDebug(5700) << "ResourceDir::requestSaveTicket()" << endl; + + if ( !addressBook() ) return 0; + + delete mLock; + mLock = new Lock( mPath ); + + if ( mLock->lock() ) { + addressBook()->emitAddressBookLocked(); + } else { + addressBook()->error( mLock->error() ); + kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock path '" + << mPath << "': " << mLock->error() << endl; + return 0; + } + + return createTicket( this ); +} + +void ResourceDir::releaseSaveTicket( Ticket *ticket ) +{ + delete ticket; + + delete mLock; + mLock = 0; +} + +bool ResourceDir::doOpen() +{ + QDir dir( mPath ); + if ( !dir.exists() ) { // no directory available + return dir.mkdir( dir.path() ); + } else { + QString testName = dir.entryList( QDir::Files )[0]; + if ( testName.isNull() || testName.isEmpty() ) // no file in directory + return true; + + QFile file( mPath + "/" + testName ); + if ( file.open( IO_ReadOnly ) ) + return true; + + if ( file.size() == 0 ) + return true; + + bool ok = mFormat->checkFormat( &file ); + file.close(); + return ok; + } +} + +void ResourceDir::doClose() +{ +} + +bool ResourceDir::load() +{ + kdDebug(5700) << "ResourceDir::load(): '" << mPath << "'" << endl; + + mAsynchronous = false; + + QDir dir( mPath ); + QStringList files = dir.entryList( QDir::Files ); + + QStringList::Iterator it; + bool ok = true; + for ( it = files.begin(); it != files.end(); ++it ) { + QFile file( mPath + "/" + (*it) ); + + if ( !file.open( IO_ReadOnly ) ) { + addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) ); + ok = false; + continue; + } + + if ( !mFormat->loadAll( addressBook(), this, &file ) ) + ok = false; + + file.close(); + } + + return ok; +} + +bool ResourceDir::asyncLoad() +{ + mAsynchronous = true; + + bool ok = load(); + if ( !ok ) + emit loadingError( this, i18n( "Loading resource '%1' failed!" ) + .arg( resourceName() ) ); + else + emit loadingFinished( this ); + + return ok; +} + +bool ResourceDir::save( Ticket * ) +{ + kdDebug(5700) << "ResourceDir::save(): '" << mPath << "'" << endl; + + Addressee::Map::Iterator it; + bool ok = true; + + mDirWatch.stopScan(); + + for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) { + if ( !it.data().changed() ) + continue; + + QFile file( mPath + "/" + (*it).uid() ); + if ( !file.open( IO_WriteOnly ) ) { + addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) ); + continue; + } + + mFormat->save( *it, &file ); + + // mark as unchanged + (*it).setChanged( false ); + + file.close(); + } + + mDirWatch.startScan(); + + return ok; +} + +bool ResourceDir::asyncSave( Ticket *ticket ) +{ + bool ok = save( ticket ); + if ( !ok ) + emit savingError( this, i18n( "Saving resource '%1' failed!" ) + .arg( resourceName() ) ); + else + emit savingFinished( this ); + + return ok; +} + +void ResourceDir::setPath( const QString &path ) +{ + mDirWatch.stopScan(); + if ( mDirWatch.contains( mPath ) ) + mDirWatch.removeDir( mPath ); + + mPath = path; + mDirWatch.addDir( mPath, true ); + mDirWatch.startScan(); +} + +QString ResourceDir::path() const +{ + return mPath; +} + +void ResourceDir::setFormat( const QString &format ) +{ + mFormatName = format; + + if ( mFormat ) + delete mFormat; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); +} + +QString ResourceDir::format() const +{ + return mFormatName; +} + +void ResourceDir::pathChanged() +{ + if ( !addressBook() ) + return; + + clear(); + if ( mAsynchronous ) + asyncLoad(); + else { + load(); + addressBook()->emitAddressBookChanged(); + } +} + +void ResourceDir::removeAddressee( const Addressee& addr ) +{ + QFile::remove( mPath + "/" + addr.uid() ); + mAddrMap.erase( addr.uid() ); +} + +#include "resourcedir.moc" diff --git a/kabc/plugins/dir/resourcedir.h b/kabc/plugins/dir/resourcedir.h new file mode 100644 index 000000000..b54f0ddda --- /dev/null +++ b/kabc/plugins/dir/resourcedir.h @@ -0,0 +1,113 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 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_RESOURCEDIR_H +#define KABC_RESOURCEDIR_H + +#include <kconfig.h> +#include <kdirwatch.h> + +#include <sys/types.h> + +#include <kabc/resource.h> + +class QTimer; + +namespace KABC { + +class FormatPlugin; +class Lock; + +/** + @internal +*/ +class KABC_EXPORT ResourceDir : public Resource +{ + Q_OBJECT + + public: + ResourceDir( const KConfig* ); + ResourceDir( const QString &path, const QString &type = "vcard" ); + ~ResourceDir(); + + virtual void writeConfig( KConfig* ); + + virtual bool doOpen(); + virtual void doClose(); + + virtual Ticket *requestSaveTicket(); + virtual void releaseSaveTicket( Ticket* ); + + virtual bool load(); + virtual bool asyncLoad(); + virtual bool save( Ticket* ticket ); + virtual bool asyncSave( Ticket* ticket ); + + /** + Set path to be used for saving. + */ + void setPath( const QString & ); + + /** + Return path used for loading and saving the address book. + */ + QString path() const; + + /** + Set the format by name. + */ + void setFormat( const QString &format ); + + /** + Returns the format name. + */ + QString format() const; + + /** + Remove a addressee from its source. + This method is mainly called by KABC::AddressBook. + */ + virtual void removeAddressee( const Addressee& addr ); + + protected slots: + void pathChanged(); + + protected: + void init( const QString &path, const QString &format ); + + private: + FormatPlugin *mFormat; + + KDirWatch mDirWatch; + + QString mPath; + QString mFormatName; + + Lock *mLock; + + bool mAsynchronous; + + class ResourceDirPrivate; + ResourceDirPrivate *d; +}; + +} + +#endif diff --git a/kabc/plugins/dir/resourcedirconfig.cpp b/kabc/plugins/dir/resourcedirconfig.cpp new file mode 100644 index 000000000..ada7c1f9d --- /dev/null +++ b/kabc/plugins/dir/resourcedirconfig.cpp @@ -0,0 +1,107 @@ +/* + 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 <qlabel.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kdialog.h> + +#include "formatfactory.h" +#include "resourcedir.h" +#include "stdaddressbook.h" + +#include "resourcedirconfig.h" + +using namespace KABC; + +ResourceDirConfig::ResourceDirConfig( QWidget* parent, const char* name ) + : KRES::ConfigWidget( parent, name ) +{ + QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0, + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "Format:" ), this ); + mFormatBox = new KComboBox( this ); + + mainLayout->addWidget( label, 0, 0 ); + mainLayout->addWidget( mFormatBox, 0, 1 ); + + label = new QLabel( i18n( "Location:" ), this ); + mFileNameEdit = new KURLRequester( this ); + mFileNameEdit->setMode( KFile::Directory ); + + mainLayout->addWidget( label, 1, 0 ); + mainLayout->addWidget( mFileNameEdit, 1, 1 ); + + FormatFactory *factory = FormatFactory::self(); + QStringList formats = factory->formats(); + QStringList::Iterator it; + for ( it = formats.begin(); it != formats.end(); ++it ) { + FormatInfo *info = factory->info( *it ); + if ( info ) { + mFormatTypes << (*it); + mFormatBox->insertItem( info->nameLabel ); + } + } + + mInEditMode = false; +} + +void ResourceDirConfig::setEditMode( bool value ) +{ + mFormatBox->setEnabled( !value ); + mInEditMode = value; +} + +void ResourceDirConfig::loadSettings( KRES::Resource *res ) +{ + ResourceDir *resource = dynamic_cast<ResourceDir*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceDirConfig::loadSettings(): cast failed" << endl; + return; + } + + mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) ); + + mFileNameEdit->setURL( resource->path() ); + if ( mFileNameEdit->url().isEmpty() ) + mFileNameEdit->setURL( KABC::StdAddressBook::directoryName() ); +} + +void ResourceDirConfig::saveSettings( KRES::Resource *res ) +{ + ResourceDir *resource = dynamic_cast<ResourceDir*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceDirConfig::loadSettings(): cast failed" << endl; + return; + } + + if ( mInEditMode ) + resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] ); + + resource->setPath( mFileNameEdit->url() ); +} + +#include "resourcedirconfig.moc" diff --git a/kabc/plugins/dir/resourcedirconfig.h b/kabc/plugins/dir/resourcedirconfig.h new file mode 100644 index 000000000..46d446b36 --- /dev/null +++ b/kabc/plugins/dir/resourcedirconfig.h @@ -0,0 +1,54 @@ +/* + 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 RESOURCEDIRCONFIG_H +#define RESOURCEDIRCONFIG_H + +#include <kcombobox.h> +#include <kurlrequester.h> + +#include <kresources/configwidget.h> + +namespace KABC { + +class KABC_EXPORT ResourceDirConfig : public KRES::ConfigWidget +{ + Q_OBJECT + +public: + ResourceDirConfig( QWidget* parent = 0, const char* name = 0 ); + + void setEditMode( bool value ); + +public slots: + void loadSettings( KRES::Resource* ); + void saveSettings( KRES::Resource* ); + +private: + KComboBox* mFormatBox; + KURLRequester* mFileNameEdit; + + QStringList mFormatTypes; + + bool mInEditMode; +}; + +} +#endif diff --git a/kabc/plugins/dir/resourcedirplugin.cpp b/kabc/plugins/dir/resourcedirplugin.cpp new file mode 100644 index 000000000..a2bd6d138 --- /dev/null +++ b/kabc/plugins/dir/resourcedirplugin.cpp @@ -0,0 +1,32 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 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 "resourcedir.h" +#include "resourcedirconfig.h" + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_dir() + { + return new KRES::PluginFactory<ResourceDir, ResourceDirConfig>(); + } +} diff --git a/kabc/plugins/evolution/Makefile.am b/kabc/plugins/evolution/Makefile.am new file mode 100644 index 000000000..ea3f950f7 --- /dev/null +++ b/kabc/plugins/evolution/Makefile.am @@ -0,0 +1,19 @@ +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourceevo.h dbwrapper.h + +kde_module_LTLIBRARIES = kabc_evo.la + +kabc_evo_la_SOURCES = dbwrapper.cpp resourceevo.cpp + +kabc_evo_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kabc_evo_la_LIBADD = ../../../kabc/libkabc.la ../../../kdeui/libkdeui.la -ldb ../../../kabc/vcardparser/libvcards.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_evolution.pot + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = evolution.desktop diff --git a/kabc/plugins/evolution/README b/kabc/plugins/evolution/README new file mode 100644 index 000000000..7dfefce00 --- /dev/null +++ b/kabc/plugins/evolution/README @@ -0,0 +1,15 @@ +A Resource using DB3 to access the evolution +addressbook make sure the wombat is not running +In future versions I may use bonobo to access it... + + +DESIGN: +The Format vs Resource idea is somehow not applyable to the +Evolution PAS + +Format would be vCard and Resource would be DB3.. +BUT +Format get's a QFile* pointer which is just not usable +with a DB3 +INSTEAD we will use the vCardImpl directly to convert +a string to Addressee
\ No newline at end of file diff --git a/kabc/plugins/evolution/dbwrapper.cpp b/kabc/plugins/evolution/dbwrapper.cpp new file mode 100644 index 000000000..cc566344c --- /dev/null +++ b/kabc/plugins/evolution/dbwrapper.cpp @@ -0,0 +1,187 @@ +#include <db.h> + +#include <qfile.h> + +#include "dbwrapper.h" + + +using namespace Evolution; + +struct DBIterator::Data { + DBWrapper *wrapper; + QString key; + QString data; + DBC* cursor; + bool atEnd; +}; + +DBIterator::DBIterator( DBWrapper* wra) { + data = new Data; + data->wrapper = wra; + data->atEnd = false; + data->cursor = 0l; +} +DBIterator::DBIterator( const DBIterator& copy ) { + data = new Data; + data->wrapper = copy.data->wrapper; + data->key = copy.data->key; + data->data = copy.data->data; + data->atEnd = copy.data->atEnd; + if (copy.data->cursor ) + copy.data->cursor->c_dup(copy.data->cursor, &data->cursor, 0 ); + else + data->cursor = 0l; +} +DBIterator::~DBIterator() { + if (data->cursor) + data->cursor->c_close(data->cursor); + delete data; +} +DBIterator& DBIterator::operator=( const DBIterator& rhs ) { + if ( *this == rhs ) + return *this; + if (data->cursor) + data->cursor->c_close(data->cursor); + delete data; + data = new Data; + data->wrapper = rhs.data->wrapper; + data->key = rhs.data->key; + data->data = rhs.data->data; + data->atEnd = rhs.data->atEnd; + if ( rhs.data->cursor ) + rhs.data->cursor->c_dup(rhs.data->cursor, &data->cursor, 0 ); + else + data->cursor = 0l; + + return *this; +} +QString DBIterator::key()const{ + return data->key; +} +QString DBIterator::value()const { + return data->data; +} +QString DBIterator::operator*() { + return data->data; +} +DBIterator& DBIterator::operator++() { + DBT key, val; + ::memset(&key, 0, sizeof(key) ); + ::memset(&val, 0, sizeof(val) ); + if ( data->cursor ) + if ( data->cursor->c_get(data->cursor, &key, &val,DB_NEXT ) != 0 ) + data->atEnd = true; + data->key = QString::fromUtf8( (char*)key.data, key.size ); + data->data = QString::fromUtf8( (char*)val.data, val.size ); + return *this; +} +DBIterator& DBIterator::operator--() { + DBT key, val; + ::memset(&key, 0, sizeof(key) ); + ::memset(&val, 0, sizeof(val) ); + if ( data->cursor ) + if ( data->cursor->c_get(data->cursor, &key, &val,DB_PREV ) != 0 ) + data->atEnd = true; + data->key = QString::fromUtf8( (char*)key.data, key.size ); + data->data = QString::fromUtf8( (char*)val.data, val.size ); + return *this; +} +bool DBIterator::operator==( const DBIterator& rhs ) { + if ( data->atEnd && data->atEnd == rhs.data->atEnd ) return true; + + return false; +} +bool DBIterator::operator!=( const DBIterator& rhs ) { + return !this->operator==(rhs ); +} +struct DBWrapper::Data { + DB* db; + bool only; +}; +DBWrapper::DBWrapper() { + data = new Data; + (void)db_create(&data->db, NULL, 0 ); + data->only = false; +} +DBWrapper::~DBWrapper() { + data->db->close(data->db, 0 ); + delete data; +} +bool DBWrapper::open( const QString& file, bool on) { + data->only = on; + return !data->db->open(data->db, QFile::encodeName( file ), NULL, DB_HASH, 0, 0666 ); +} +bool DBWrapper::save() { + return true; +} +DBIterator DBWrapper::begin() { + DBIterator it(this); + DBC* cursor; + DBT key, val; + int ret; + ret = data->db->cursor(data->db, NULL, &cursor, 0 ); + if (ret ) { + it.data->atEnd = true; + return it; + } + + ::memset(&key, 0, sizeof(key) ); + ::memset(&val, 0, sizeof(val) ); + ret = cursor->c_get(cursor, &key, &val, DB_FIRST ); + if (ret ) { + it.data->atEnd = true; + return it; + } + + it.data->cursor = cursor; + it.data->key = QString::fromUtf8((char*)key.data, key.size ); + it.data->data = QString::fromUtf8((char*)val.data, val.size ); + + return it; +} +DBIterator DBWrapper::end() { + DBIterator it(this); + it.data->atEnd = true; + + return it; +} +bool DBWrapper::find( const QString& _key, QString& _val ) { + DBT key, val; + ::memset(&key, 0, sizeof(key) ); + ::memset(&val, 0, sizeof(val) ); + + QCString db_key = _key.local8Bit(); + key.data = db_key.data(); + key.size = db_key.size(); + + int ret = data->db->get(data->db, NULL, &key, &val, 0 ); + if (!ret) { + _val = QString::fromUtf8( (char*)val.data, val.size ); + qWarning("key: %s val: %sXXX", (char*)key.data, (char*)val.data ); + return true; + } + return false; +} +bool DBWrapper::add( const QString& _key, const QString& _val ) { + QCString db_key = _key.local8Bit(); + QCString db_val = _val.local8Bit(); + DBT key, val; + ::memset(&key, 0, sizeof(key) ); + ::memset(&val, 0, sizeof(val) ); + + key.data = db_key.data(); + key.size = db_key.size(); + val.data = db_val.data(); + val.size = db_val.size(); + + return !data->db->put(data->db, NULL, &key, &val, 0 ); +} +bool DBWrapper::remove( const QString& _key ) { + QCString db_key = _key.local8Bit(); + DBT key; + memset(&key, 0, sizeof(key) ); + key.data = db_key.data(); + key.size = db_key.size(); + + return !data->db->del(data->db, NULL, &key, 0 ); +} diff --git a/kabc/plugins/evolution/dbwrapper.h b/kabc/plugins/evolution/dbwrapper.h new file mode 100644 index 000000000..484605acf --- /dev/null +++ b/kabc/plugins/evolution/dbwrapper.h @@ -0,0 +1,60 @@ +#ifndef KABC_EVOLUTION_DB_WRAPPER +#define KABC_EVOLUTION_DB_WRAPPER + +#include <db.h> + +#include <qstring.h> +#include <qpair.h> + +namespace Evolution { + + class DBWrapper; + class DBIterator { + friend class DBWrapper; + public: + DBIterator( DBWrapper* = 0l ); + ~DBIterator(); + + DBIterator( const DBIterator& ); + DBIterator &operator=( const DBIterator& ); + + QString key()const; + QString value()const; + + QString operator*(); + + DBIterator &operator++(); + DBIterator &operator--(); + + bool operator==( const DBIterator& ); + bool operator!=( const DBIterator& ); + private: + struct Data; + Data* data; + }; + class DBWrapper { + public: + DBWrapper(); + ~DBWrapper(); + + QString lastError()const; + + bool open( const QString& file, bool readOnly = false); + bool save(); + DBIterator begin(); + DBIterator end(); + + bool find( const QString& key, QString& value ); + bool add( const QString& key, const QString& val ); + bool remove( const QString& key ); + private: + // DBT element( const QString& ); + struct Data; + Data* data; + + }; + +} + + +#endif diff --git a/kabc/plugins/evolution/evolution.desktop b/kabc/plugins/evolution/evolution.desktop new file mode 100644 index 000000000..87397d92e --- /dev/null +++ b/kabc/plugins/evolution/evolution.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +Name=Evolution +Name[be]=ÐÐ²Ð°Ð»ÑŽÑ†Ñ‹Ñ +Name[bn]=ইà¦à§‹à¦²à¦¿à¦‰à¦¶à¦¨ +Name[eo]=Evoluo +Name[fa]=اوولوشن +Name[hi]=à¤à¤µà¥‰à¤²à¥à¤¯à¥‚शन +Name[ko]=ì—볼루션 +Name[mn]=Хөгжил +Name[ne]=इà¤à¥‹à¤²à¥à¤¯à¥à¤¸à¤¨ +Name[pa]=à¨à¨µà©‚ਲੇਸ਼ਨ +Name[sr]=Еволуција +Name[sr@Latn]=Evolucija +Name[ta]=படிபà¯à®ªà®Ÿà®¿à®¯à®¾à®© வளரà¯à®šà¯à®šà®¿ +Name[te]=ఎవలà±à°¯à±à°·à°¨à± +Name[th]=เà¸à¸Ÿà¹‚วลูชัน +Name[tt]=ÃœseÅŸ +Name[ven]=Tsikoni +Name[wa]=Evolucion +Name[xh]=Utshintsho lwendawo ngokwenqanawa +Name[zu]=Evolushini +X-KDE-Library=kabc_evo +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=evolution diff --git a/kabc/plugins/evolution/resourceevo.cpp b/kabc/plugins/evolution/resourceevo.cpp new file mode 100644 index 000000000..a1858bf83 --- /dev/null +++ b/kabc/plugins/evolution/resourceevo.cpp @@ -0,0 +1,132 @@ +#include <qdir.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> + +#include <stdio.h> + +#include <kabc/vcardparser/vcardtool.h> + +#include "dbwrapper.h" +#include "resourceevo.h" + +using namespace Evolution; +using namespace KABC; + +class EvolutionFactory : public KRES::PluginFactoryBase +{ + public: + KRES::Resource *resource( const KConfig *config ) + { + return new ResourceEvolution( config ); + } + + KRES::ConfigWidget *configWidget( QWidget * ) + { + return 0; + } +}; + +extern "C" +{ + KDE_EXPORT void *init_kabc_evo() + { + return ( new EvolutionFactory() ); + } +} + +ResourceEvolution::ResourceEvolution( const KConfig* conf ) + : Resource( conf ), mWrap(0l) +{ + m_isOpen = false; +} +ResourceEvolution::~ResourceEvolution() { + delete mWrap; +} +bool ResourceEvolution::doOpen() { + mWrap = new DBWrapper; + if (!mWrap->open( QDir::homeDirPath() + "/evolution/local/Contacts/addressbook.db" ) ) { + return false; + } + + QString val; + if (!mWrap->find( "PAS-DB-VERSION", val ) ) + return false; + + if (!val.startsWith("0.2") ) + return false; + + m_isOpen = true; + + return true; +} +void ResourceEvolution::doClose() { + delete mWrap; + mWrap = 0l; + m_isOpen = false; +} +Ticket* ResourceEvolution::requestSaveTicket() { + if ( !addressBook() ) return 0; + return createTicket( this ); +} +/* + * skip the first key + */ + +bool ResourceEvolution::load() { + /* doOpen never get's called :( */ + if (!doOpen()) return false; + if (!mWrap ) return false; // open first! + + DBIterator it = mWrap->begin(); + // skip the "PAS-DB-VERSION" + + for ( ; it != mWrap->end(); ++it ) { + if ( it.key().startsWith("PAS-DB-VERSION") ) + continue; + + qWarning( "val:%s", it.value().latin1() ); + VCardTool tool; + QString str = it.value().stripWhiteSpace(); + Addressee::List list = tool.parseVCards( str ); + if (!list.first().isEmpty() ) { + Addressee adr = list.first(); + adr.setResource(this); + addressBook()->insertAddressee( adr ); + } + } + return true; +} +bool ResourceEvolution::save( Ticket* ticket ) { + delete ticket; + if (!m_isOpen ) return false; + + // just delete the summary so evolution will regenerate it + // on next start up + (void)QFile::remove( QDir::homeDirPath() + "/evolution/local/Contacts/addressbook.db.summary" ); + + + AddressBook::Iterator it; + Addressee::List list; + for ( it = addressBook()->begin(); it !=addressBook()->end(); ++it ) { + if ( (*it).resource() != this || !(*it).changed() ) + continue; + + // remove, convert add set unchanged false + list.clear(); + mWrap->remove( (*it).uid() ); + VCardTool tool; + list.append( (*it) ); + mWrap->add( (*it).uid(), tool.createVCards( list, VCard::v2_1) ); + + (*it).setChanged( false ); + } + + return true; +} +void ResourceEvolution::removeAddressee( const Addressee& rem) { + if (!m_isOpen) return; + + mWrap->remove( rem.uid() ); +} diff --git a/kabc/plugins/evolution/resourceevo.h b/kabc/plugins/evolution/resourceevo.h new file mode 100644 index 000000000..0f5b3a0d2 --- /dev/null +++ b/kabc/plugins/evolution/resourceevo.h @@ -0,0 +1,23 @@ +#include "resource.h" + +namespace Evolution { + class DBWrapper; +} + +namespace KABC { + class ResourceEvolution : public Resource { + public: + ResourceEvolution( const KConfig* config ); + ~ResourceEvolution(); + + bool doOpen(); + void doClose(); + Ticket* requestSaveTicket(); + bool load(); + bool save( Ticket* ticket ); + void removeAddressee( const Addressee& ); + private: + Evolution::DBWrapper *mWrap; + bool m_isOpen : 1; + }; +} diff --git a/kabc/plugins/file/Makefile.am b/kabc/plugins/file/Makefile.am new file mode 100644 index 000000000..9e3fc8360 --- /dev/null +++ b/kabc/plugins/file/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourcefileconfig.h + +lib_LTLIBRARIES = libkabc_file.la +libkabc_file_la_SOURCES = resourcefile.cpp resourcefileconfig.cpp +libkabc_file_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined +libkabc_file_la_LIBADD = $(LIB_KABC) +libkabc_file_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + + +kde_module_LTLIBRARIES = kabc_file.la +kabc_file_la_SOURCES = resourcefileplugin.cpp +kabc_file_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -no-undefined +kabc_file_la_LIBADD = libkabc_file.la +kabc_file_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_file.pot + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = resourcefile.h + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = file.desktop diff --git a/kabc/plugins/file/file.desktop b/kabc/plugins/file/file.desktop new file mode 100644 index 000000000..559cfcf21 --- /dev/null +++ b/kabc/plugins/file/file.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Name=File +Name[af]=Lêer +Name[ar]=ملÙÙ‘ +Name[az]=Fayl +Name[be]=Файл +Name[bn]=ফাইল +Name[br]=Restr +Name[bs]=Datoteka +Name[ca]=Fitxer +Name[cs]=Soubor +Name[csb]=Lopk +Name[cy]=Ffeil +Name[da]=Fil +Name[de]=Datei +Name[el]=ΑÏχείο +Name[eo]=Dosiero +Name[es]=Archivo +Name[et]=Fail +Name[eu]=Fitxategia +Name[fa]=پرونده +Name[fi]=Tiedosto +Name[fr]=Fichier +Name[fy]=Triem +Name[ga]=Comhad +Name[gl]=Ficheiro +Name[he]=קובץ +Name[hi]=फ़ाइल +Name[hr]=Datoteka +Name[hsb]=Dataja +Name[hu]=Fájl +Name[id]=Berkas +Name[is]=Skrá +Name[ja]=ファイル +Name[ka]=ფáƒáƒ˜áƒšáƒ˜ +Name[kk]=Файл +Name[km]=ឯកសារ +Name[ko]=íŒŒì¼ +Name[lb]=Datei +Name[lt]=Byla +Name[lv]=Fails +Name[mk]=Датотека +Name[mn]=Файл +Name[ms]=Fail +Name[nb]=Fil +Name[nds]=Datei +Name[ne]=फाइल +Name[nl]=Bestand +Name[nn]=Fil +Name[pa]=ਫਾਇਲ +Name[pl]=Plik +Name[pt]=Ficheiro +Name[pt_BR]=Arquivo +Name[ro]=FiÅŸier +Name[ru]=Файл +Name[rw]=Idosiye +Name[se]=Fiila +Name[sk]=Súbor +Name[sl]=Datoteka +Name[sq]=Skedë +Name[sr]=Фајл +Name[sr@Latn]=Fajl +Name[sv]=Fil +Name[ta]=கோபà¯à®ªà¯ +Name[te]=దసà±à°¤à±à°°à°‚ +Name[tg]=Файл +Name[th]=à¹à¸Ÿà¹‰à¸¡ +Name[tr]=Dosya +Name[tt]=Birem +Name[uk]=Файл +Name[uz]=Fayl +Name[uz@cyrillic]=Файл +Name[vi]=Táºp tin +Name[wa]=Fitchî +Name[zh_CN]=文件 +Name[zh_HK]=檔案 +Name[zh_TW]=檔案 +X-KDE-Library=kabc_file +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=file diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp new file mode 100644 index 000000000..9c0f85fb8 --- /dev/null +++ b/kabc/plugins/file/resourcefile.cpp @@ -0,0 +1,395 @@ +/* + This file is part of libkabc. + + Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> + Copyright (c) 2006 Tom Abers <tomalbers@kde.nl> + + 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 <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qtimer.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kio/scheduler.h> +#include <klocale.h> +#include <ksavefile.h> +#include <kstandarddirs.h> + +#include "formatfactory.h" +#include "resourcefileconfig.h" +#include "stdaddressbook.h" +#include "lock.h" + +#include "resourcefile.h" + +using namespace KABC; + +ResourceFile::ResourceFile( const KConfig *config ) + : Resource( config ), mFormat( 0 ), + mAsynchronous( false ) +{ + QString fileName, formatName; + + if ( config ) { + fileName = config->readPathEntry( "FileName", StdAddressBook::fileName() ); + formatName = config->readEntry( "FileFormat", "vcard" ); + } else { + fileName = StdAddressBook::fileName(); + formatName = "vcard"; + } + + init( fileName, formatName ); +} + +ResourceFile::ResourceFile( const QString &fileName, + const QString &formatName ) + : Resource( 0 ), mFormat( 0 ), + mAsynchronous( false ) +{ + init( fileName, formatName ); +} + +void ResourceFile::init( const QString &fileName, const QString &formatName ) +{ + mFormatName = formatName; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); + + if ( !mFormat ) { + mFormatName = "vcard"; + mFormat = factory->format( mFormatName ); + } + + connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); + connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); + connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); + + setFileName( fileName ); + + mLock = 0; +} + +ResourceFile::~ResourceFile() +{ + delete mFormat; + mFormat = 0; +} + +void ResourceFile::writeConfig( KConfig *config ) +{ + Resource::writeConfig( config ); + + if ( mFileName == StdAddressBook::fileName() ) + config->deleteEntry( "FileName" ); + else + config->writePathEntry( "FileName", mFileName ); + + config->writeEntry( "FileFormat", mFormatName ); +} + +Ticket *ResourceFile::requestSaveTicket() +{ + kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl; + + if ( !addressBook() ) return 0; + + delete mLock; + mLock = new Lock( mFileName ); + + if ( mLock->lock() ) { + addressBook()->emitAddressBookLocked(); + } else { + addressBook()->error( mLock->error() ); + kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock file '" + << mFileName << "': " << mLock->error() << endl; + return 0; + } + + return createTicket( this ); +} + +void ResourceFile::releaseSaveTicket( Ticket *ticket ) +{ + delete ticket; + + delete mLock; + mLock = 0; + + addressBook()->emitAddressBookUnlocked(); +} + +bool ResourceFile::doOpen() +{ + QFile file( mFileName ); + + if ( !file.exists() ) { + // try to create the file + bool ok = file.open( IO_WriteOnly ); + if ( ok ) + file.close(); + + return ok; + } else { + QFileInfo fileInfo( mFileName ); + if ( readOnly() || !fileInfo.isWritable() ) { + if ( !file.open( IO_ReadOnly ) ) + return false; + } else { + if ( !file.open( IO_ReadWrite ) ) + return false; + } + + if ( file.size() == 0 ) { + file.close(); + kdDebug() << "File size is zero. Evaluating backups" << endl; + for (int i=0; i!=20; i++) + { + QFile backup( mFileName + "__" + QString::number(i) ); + kdDebug() << "Evaluating" << backup.name() << " size: " << backup.size() << endl; + if ( backup.size() != 0 ) + { + kdDebug() << "Restoring backup " << i << endl; + const QString src = mFileName + "__" + QString::number(i); + const QString dest = mFileName; + + // remove dest + QFile::remove( dest ); + + // copy src to dest + if ( backup.open( IO_ReadOnly ) ) { + const QByteArray data = backup.readAll(); + + QFile out( dest ); + if ( out.open( IO_WriteOnly ) ) { + out.writeBlock( data ); + out.close(); + } + + backup.close(); + } + return true; + } + } + return true; + } + + bool ok = mFormat->checkFormat( &file ); + file.close(); + + return ok; + } +} + +void ResourceFile::doClose() +{ +} + +bool ResourceFile::load() +{ + kdDebug(5700) << "ResourceFile::load(): '" << mFileName << "'" << endl; + + mAsynchronous = false; + + QFile file( mFileName ); + if ( !file.open( IO_ReadOnly ) ) { + addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) ); + return false; + } + + clear(); + + return mFormat->loadAll( addressBook(), this, &file ); +} + +bool ResourceFile::asyncLoad() +{ + kdDebug(5700) << "ResourceFile::asyncLoad()" << endl; + + mAsynchronous = true; + + bool ok = load(); + + if ( !ok ) + emitLoadingError(); + else + emitLoadingFinished(); + + return true; +} + +bool ResourceFile::save( Ticket * ) +{ + kdDebug(5700) << "ResourceFile::save()" << endl; + + // Only do the logrotate dance when the __0 file is not 0 bytes. + QFile file( mFileName + "__0" ); + if ( file.size() != 0 ) { + const QString last = mFileName + "__20"; + kdDebug() << "deleting " << last << endl; + + QFile::remove( last ); + + for (int i=19; i>=0; i--) + { + const QString src = mFileName + "__" + QString::number(i); + const QString dest = mFileName + "__" + QString::number(i+1); + kdDebug() << "moving " << src << " -> " << dest << endl; + + // copy src to dest + QFile in( src ); + if ( in.open( IO_ReadOnly ) ) { + const QByteArray data = in.readAll(); + + QFile out( dest ); + if ( out.open( IO_WriteOnly ) ) { + out.writeBlock( data ); + out.close(); + } + + in.close(); + } + + // remove src + QFile::remove( src ); + } + } else + kdDebug() << "Not starting logrotate __0 is 0 bytes." << endl; + + QString extension = "__0"; + (void) KSaveFile::backupFile( mFileName, QString::null /*directory*/, + extension ); + + mDirWatch.stopScan(); + + KSaveFile saveFile( mFileName ); + bool ok = false; + + if ( saveFile.status() == 0 && saveFile.file() ) { + mFormat->saveAll( addressBook(), this, saveFile.file() ); + ok = saveFile.close(); + } + + if ( !ok ) { + saveFile.abort(); + addressBook()->error( i18n( "Unable to save file '%1'." ).arg( mFileName ) ); + } + + mDirWatch.startScan(); + + return ok; +} + +bool ResourceFile::asyncSave( Ticket *ticket ) +{ + kdDebug(5700) << "ResourceFile::asyncSave()" << endl; + + bool ok = save( ticket ); + + if ( !ok ) + QTimer::singleShot( 0, this, SLOT( emitSavingError() ) ); + else + QTimer::singleShot( 0, this, SLOT( emitSavingFinished() ) ); + + return ok; +} + +void ResourceFile::setFileName( const QString &fileName ) +{ + mDirWatch.stopScan(); + if ( mDirWatch.contains( mFileName ) ) + mDirWatch.removeFile( mFileName ); + + mFileName = fileName; + + mDirWatch.addFile( mFileName ); + mDirWatch.startScan(); +} + +QString ResourceFile::fileName() const +{ + return mFileName; +} + +void ResourceFile::setFormat( const QString &format ) +{ + mFormatName = format; + delete mFormat; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); +} + +QString ResourceFile::format() const +{ + return mFormatName; +} + +void ResourceFile::fileChanged() +{ + kdDebug(5700) << "ResourceFile::fileChanged(): " << mFileName << endl; + + if ( !addressBook() ) + return; + + if ( mAsynchronous ) + asyncLoad(); + else { + load(); + kdDebug() << "addressBookChanged() " << endl; + addressBook()->emitAddressBookChanged(); + } +} + +void ResourceFile::removeAddressee( const Addressee &addr ) +{ + QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) ); + QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) ); + QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) ); + + mAddrMap.erase( addr.uid() ); +} + +void ResourceFile::emitSavingFinished() +{ + emit savingFinished( this ); +} + +void ResourceFile::emitSavingError() +{ + emit savingError( this, i18n( "Unable to save file '%1'." ).arg( mFileName ) ); +} + +void ResourceFile::emitLoadingFinished() +{ + emit loadingFinished( this ); +} + +void ResourceFile::emitLoadingError() +{ + emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mFileName ) ); +} + +#include "resourcefile.moc" diff --git a/kabc/plugins/file/resourcefile.h b/kabc/plugins/file/resourcefile.h new file mode 100644 index 000000000..84dfc7cda --- /dev/null +++ b/kabc/plugins/file/resourcefile.h @@ -0,0 +1,162 @@ +/* + 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_RESOURCEFILE_H +#define KABC_RESOURCEFILE_H + +#include <kconfig.h> +#include <kdirwatch.h> + +#include <sys/types.h> + +#include <kabc/resource.h> + +namespace KABC { + +class FormatPlugin; +class ResourceConfigWidget; +class Lock; + +/** + This resource allows access to a local file. +*/ +class KABC_EXPORT ResourceFile : public Resource +{ + Q_OBJECT + + public: + /** + Constructor. + + @param cfg The config object where custom resource settings are stored. + */ + ResourceFile( const KConfig *cfg ); + + /** + Construct file resource on file @arg fileName using format @arg formatName. + */ + ResourceFile( const QString &fileName, const QString &formatName = "vcard" ); + + /** + Destructor. + */ + ~ResourceFile(); + + /** + Writes the config back. + */ + virtual void writeConfig( KConfig *cfg ); + + /** + Tries to open the file and checks for the proper format. + This method should be called before load(). + */ + virtual bool doOpen(); + + /** + Closes the file again. + */ + virtual void doClose(); + + /** + Requests a save ticket, that is used by save() + */ + virtual Ticket *requestSaveTicket(); + + virtual void releaseSaveTicket( Ticket* ); + + /** + Loads all addressees from file to the address book. + Returns true if all addressees could be loaded otherwise false. + */ + virtual bool load(); + + virtual bool asyncLoad(); + + /** + Saves all addresses from address book to file. + Returns true if all addressees could be saved otherwise false. + + @param ticket The ticket returned by requestSaveTicket() + */ + virtual bool save( Ticket *ticket ); + + virtual bool asyncSave( Ticket *ticket ); + + /** + Set name of file to be used for saving. + */ + void setFileName( const QString & ); + + /** + Return name of file used for loading and saving the address book. + */ + QString fileName() const; + + /** + Sets a new format by name. + */ + void setFormat( const QString &name ); + + /** + Returns the format name. + */ + QString format() const; + + /** + Remove a addressee from its source. + This method is mainly called by KABC::AddressBook. + */ + virtual void removeAddressee( const Addressee& addr ); + + private slots: + void emitLoadingFinished(); + void emitLoadingError(); + void emitSavingFinished(); + void emitSavingError(); + + protected slots: + void fileChanged(); + + protected: + void init( const QString &fileName, const QString &format ); + + bool lock( const QString &fileName ); + void unlock( const QString &fileName ); + + private: + QString mFileName; + QString mFormatName; + + FormatPlugin *mFormat; + + Lock *mLock; + + KDirWatch mDirWatch; + + bool mAsynchronous; + + class ResourceFilePrivate; + ResourceFilePrivate *d; +}; + +} + +#endif diff --git a/kabc/plugins/file/resourcefileconfig.cpp b/kabc/plugins/file/resourcefileconfig.cpp new file mode 100644 index 000000000..a6d8ab4f9 --- /dev/null +++ b/kabc/plugins/file/resourcefileconfig.cpp @@ -0,0 +1,118 @@ +/* + 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 <qlabel.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kdialog.h> + +#include <unistd.h> + +#include "formatfactory.h" +#include "resourcefile.h" +#include "stdaddressbook.h" + +#include "resourcefileconfig.h" + +using namespace KABC; + +ResourceFileConfig::ResourceFileConfig( QWidget* parent, const char* name ) + : ConfigWidget( parent, name ) +{ + QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0, + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "Format:" ), this ); + mFormatBox = new KComboBox( this ); + + mainLayout->addWidget( label, 0, 0 ); + mainLayout->addWidget( mFormatBox, 0, 1 ); + + label = new QLabel( i18n( "Location:" ), this ); + mFileNameEdit = new KURLRequester( this ); + + connect( mFileNameEdit, SIGNAL( textChanged( const QString & ) ), + SLOT( checkFilePermissions( const QString & ) ) ); + + mainLayout->addWidget( label, 1, 0 ); + mainLayout->addWidget( mFileNameEdit, 1, 1 ); + + FormatFactory *factory = FormatFactory::self(); + QStringList formats = factory->formats(); + QStringList::Iterator it; + for ( it = formats.begin(); it != formats.end(); ++it ) { + FormatInfo *info = factory->info( *it ); + if ( info ) { + mFormatTypes << (*it); + mFormatBox->insertItem( info->nameLabel ); + } + } + + mInEditMode = false; +} + +void ResourceFileConfig::setEditMode( bool value ) +{ + mFormatBox->setEnabled( !value ); + mInEditMode = value; +} + +void ResourceFileConfig::loadSettings( KRES::Resource *res ) +{ + ResourceFile *resource = dynamic_cast<ResourceFile*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceFileConfig::loadSettings(): cast failed" << endl; + return; + } + + mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) ); + + mFileNameEdit->setURL( resource->fileName() ); + if ( mFileNameEdit->url().isEmpty() ) + mFileNameEdit->setURL( KABC::StdAddressBook::fileName() ); +} + +void ResourceFileConfig::saveSettings( KRES::Resource *res ) +{ + ResourceFile *resource = dynamic_cast<ResourceFile*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceFileConfig::saveSettings(): cast failed" << endl; + return; + } + + if ( !mInEditMode ) + resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] ); + + resource->setFileName( mFileNameEdit->url() ); +} + +void ResourceFileConfig::checkFilePermissions( const QString& fileName ) +{ + // If file exist but is not writeable... + if ( access( QFile::encodeName( fileName ), F_OK ) == 0 ) + emit setReadOnly( access( QFile::encodeName( fileName ), W_OK ) < 0 ); +} + +#include "resourcefileconfig.moc" diff --git a/kabc/plugins/file/resourcefileconfig.h b/kabc/plugins/file/resourcefileconfig.h new file mode 100644 index 000000000..3e92f0728 --- /dev/null +++ b/kabc/plugins/file/resourcefileconfig.h @@ -0,0 +1,57 @@ +/* + 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 RESOURCEFILECONFIG_H +#define RESOURCEFILECONFIG_H + +#include <kcombobox.h> +#include <kurlrequester.h> + +#include <kresources/configwidget.h> + +namespace KABC { + +class KABC_EXPORT ResourceFileConfig : public KRES::ConfigWidget +{ + Q_OBJECT + +public: + ResourceFileConfig( QWidget* parent = 0, const char* name = 0 ); + + void setEditMode( bool value ); + +public slots: + void loadSettings( KRES::Resource *resource ); + void saveSettings( KRES::Resource *resource ); + +protected slots: + void checkFilePermissions( const QString& fileName ); + +private: + KComboBox* mFormatBox; + KURLRequester* mFileNameEdit; + bool mInEditMode; + + QStringList mFormatTypes; +}; + +} + +#endif diff --git a/kabc/plugins/file/resourcefileplugin.cpp b/kabc/plugins/file/resourcefileplugin.cpp new file mode 100644 index 000000000..4dce19bc0 --- /dev/null +++ b/kabc/plugins/file/resourcefileplugin.cpp @@ -0,0 +1,32 @@ +/* + 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 "resourcefile.h" +#include "resourcefileconfig.h" + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_file() + { + return new KRES::PluginFactory<ResourceFile, ResourceFileConfig>(); + } +} diff --git a/kabc/plugins/ldapkio/Makefile.am b/kabc/plugins/ldapkio/Makefile.am new file mode 100644 index 000000000..64a72b8f2 --- /dev/null +++ b/kabc/plugins/ldapkio/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourceldapkioconfig.h + +lib_LTLIBRARIES = libkabc_ldapkio.la +libkabc_ldapkio_la_SOURCES = resourceldapkio.cpp resourceldapkioconfig.cpp +libkabc_ldapkio_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined +libkabc_ldapkio_la_LIBADD = $(top_builddir)/kabc/libkabc.la $(LIB_KIO) +libkabc_ldapkio_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +kde_module_LTLIBRARIES = kabc_ldapkio.la +kabc_ldapkio_la_SOURCES = resourceldapkioplugin.cpp +kabc_ldapkio_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kabc_ldapkio_la_LIBADD = libkabc_ldapkio.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_ldapkio.pot + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = resourceldapkio.h + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = ldapkio.desktop + +resourceldapkioplugin.lo: ../../addressee.h diff --git a/kabc/plugins/ldapkio/ldapkio.desktop b/kabc/plugins/ldapkio/ldapkio.desktop new file mode 100644 index 000000000..ebd8b98dd --- /dev/null +++ b/kabc/plugins/ldapkio/ldapkio.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=LDAP +Name[bn]=à¦à¦²-ডি-à¦-পি (LDAP) +Name[hi]=à¤à¤²à¤¡à¥€à¤à¤ªà¥€ (LDAP) +Name[te]=à°Žà°²à±à°¡à°¿à°à°ªà°¿ +X-KDE-Library=kabc_ldapkio +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=ldapkio diff --git a/kabc/plugins/ldapkio/resourceldapkio.cpp b/kabc/plugins/ldapkio/resourceldapkio.cpp new file mode 100644 index 000000000..30b8ba7e0 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkio.cpp @@ -0,0 +1,1041 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 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 <qapplication.h> +#include <qbuffer.h> +#include <qfile.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <klineedit.h> +#include <klocale.h> +#include <kconfig.h> +#include <kstringhandler.h> +#include <ktempfile.h> + +#include <stdlib.h> +#include <kio/netaccess.h> +#include <kabc/ldif.h> +#include <kabc/ldapurl.h> + +#include "resourceldapkio.h" +#include "resourceldapkioconfig.h" + +using namespace KABC; + +// Hack from Netaccess +void qt_enter_modal( QWidget *widget ); +void qt_leave_modal( QWidget *widget ); + +class ResourceLDAPKIO::ResourceLDAPKIOPrivate +{ + public: + LDIF mLdif; + bool mTLS,mSSL,mSubTree; + QString mResultDn; + Addressee mAddr; + Address mAd; + Resource::Iterator mSaveIt; + bool mSASL; + QString mMech; + QString mRealm, mBindDN; + LDAPUrl mLDAPUrl; + int mVer, mSizeLimit, mTimeLimit, mRDNPrefix; + int mError; + int mCachePolicy; + bool mReadOnly; + bool mAutoCache; + QString mCacheDst; + KTempFile *mTmp; +}; + +ResourceLDAPKIO::ResourceLDAPKIO( const KConfig *config ) + : Resource( config ) +{ + d = new ResourceLDAPKIOPrivate; + if ( config ) { + QMap<QString, QString> attrList; + QStringList attributes = config->readListEntry( "LdapAttributes" ); + for ( uint pos = 0; pos < attributes.count(); pos += 2 ) + mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] ); + + mUser = config->readEntry( "LdapUser" ); + mPassword = KStringHandler::obscure( config->readEntry( "LdapPassword" ) ); + mDn = config->readEntry( "LdapDn" ); + mHost = config->readEntry( "LdapHost" ); + mPort = config->readNumEntry( "LdapPort", 389 ); + mFilter = config->readEntry( "LdapFilter" ); + mAnonymous = config->readBoolEntry( "LdapAnonymous" ); + d->mTLS = config->readBoolEntry( "LdapTLS" ); + d->mSSL = config->readBoolEntry( "LdapSSL" ); + d->mSubTree = config->readBoolEntry( "LdapSubTree" ); + d->mSASL = config->readBoolEntry( "LdapSASL" ); + d->mMech = config->readEntry( "LdapMech" ); + d->mRealm = config->readEntry( "LdapRealm" ); + d->mBindDN = config->readEntry( "LdapBindDN" ); + d->mVer = config->readNumEntry( "LdapVer", 3 ); + d->mTimeLimit = config->readNumEntry( "LdapTimeLimit", 0 ); + d->mSizeLimit = config->readNumEntry( "LdapSizeLimit", 0 ); + d->mRDNPrefix = config->readNumEntry( "LdapRDNPrefix", 0 ); + d->mCachePolicy = config->readNumEntry( "LdapCachePolicy", 0 ); + d->mAutoCache = config->readBoolEntry( "LdapAutoCache", true ); + } else { + mPort = 389; + mAnonymous = true; + mUser = mPassword = mHost = mFilter = mDn = ""; + d->mMech = d->mRealm = d->mBindDN = ""; + d->mTLS = d->mSSL = d->mSubTree = d->mSASL = false; + d->mVer = 3; d->mRDNPrefix = 0; + d->mTimeLimit = d->mSizeLimit = 0; + d->mCachePolicy = Cache_No; + d->mAutoCache = true; + } + d->mCacheDst = KGlobal::dirs()->saveLocation("cache", "ldapkio") + "/" + + type() + "_" + identifier(); + init(); +} + +ResourceLDAPKIO::~ResourceLDAPKIO() +{ + delete d; +} + +void ResourceLDAPKIO::enter_loop() +{ + QWidget dummy(0,0,WType_Dialog | WShowModal); + dummy.setFocusPolicy( QWidget::NoFocus ); + qt_enter_modal(&dummy); + qApp->enter_loop(); + qt_leave_modal(&dummy); +} + +void ResourceLDAPKIO::entries( KIO::Job*, const KIO::UDSEntryList & list ) +{ + KIO::UDSEntryListConstIterator it = list.begin(); + KIO::UDSEntryListConstIterator end = list.end(); + for (; it != end; ++it) { + KIO::UDSEntry::ConstIterator it2 = (*it).begin(); + for( ; it2 != (*it).end(); it2++ ) { + if ( (*it2).m_uds == KIO::UDS_URL ) { + KURL tmpurl( (*it2).m_str ); + d->mResultDn = tmpurl.path(); + kdDebug(7125) << "findUid(): " << d->mResultDn << endl; + if ( d->mResultDn.startsWith("/") ) d->mResultDn.remove(0,1); + return; + } + } + } +} + +void ResourceLDAPKIO::listResult( KIO::Job *job) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + mErrorMsg = job->errorString(); + else + mErrorMsg = ""; + qApp->exit_loop(); +} + +QString ResourceLDAPKIO::findUid( const QString &uid ) +{ + LDAPUrl url( d->mLDAPUrl ); + KIO::UDSEntry entry; + + mErrorMsg = d->mResultDn = ""; + + url.setAttributes("dn"); + url.setFilter( "(" + mAttributes[ "uid" ] + "=" + uid + ")" + mFilter ); + url.setExtension( "x-dir", "one" ); + + kdDebug(7125) << "ResourceLDAPKIO::findUid() uid: " << uid << " url " << + url.prettyURL() << endl; + + KIO::ListJob * listJob = KIO::listDir( url, false /* no GUI */ ); + connect( listJob, + SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ), + SLOT( entries( KIO::Job*, const KIO::UDSEntryList& ) ) ); + connect( listJob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( listResult( KIO::Job* ) ) ); + + enter_loop(); + return d->mResultDn; +} + +QCString ResourceLDAPKIO::addEntry( const QString &attr, const QString &value, bool mod ) +{ + QCString tmp; + if ( !attr.isEmpty() ) { + if ( mod ) tmp += LDIF::assembleLine( "replace", attr ) + "\n"; + tmp += LDIF::assembleLine( attr, value ) + "\n"; + if ( mod ) tmp += "-\n"; + } + return ( tmp ); +} + +bool ResourceLDAPKIO::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, + const QString &olddn ) +{ + QCString tmp; + QString dn; + QByteArray data; + bool mod = false; + + if ( olddn.isEmpty() ) { + //insert new entry + switch ( d->mRDNPrefix ) { + case 1: + dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," +mDn; + break; + case 0: + default: + dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," +mDn; + break; + } + } else { + //modify existing entry + mod = true; + if ( olddn.startsWith( mAttributes[ "uid" ] ) ) { + dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," + olddn.section( ',', 1 ); + } else if ( olddn.startsWith( mAttributes[ "commonName" ] ) ) { + dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," + + olddn.section( ',', 1 ); + } else { + dn = olddn; + } + + if ( olddn.lower() != dn.lower() ) { + tmp = LDIF::assembleLine( "dn", olddn ) + "\n"; + tmp += "changetype: modrdn\n"; + tmp += LDIF::assembleLine( "newrdn", dn.section( ',', 0, 0 ) ) + "\n"; + tmp += "deleteoldrdn: 1\n\n"; + } + } + + + tmp += LDIF::assembleLine( "dn", dn ) + "\n"; + if ( mod ) tmp += "changetype: modify\n"; + if ( !mod ) { + tmp += "objectClass: top\n"; + QStringList obclass = QStringList::split( ',', mAttributes[ "objectClass" ] ); + for ( QStringList::iterator it = obclass.begin(); it != obclass.end(); it++ ) { + tmp += LDIF::assembleLine( "objectClass", *it ) + "\n"; + } + } + + tmp += addEntry( mAttributes[ "commonName" ], addr.assembledName(), mod ); + tmp += addEntry( mAttributes[ "formattedName" ], addr.formattedName(), mod ); + tmp += addEntry( mAttributes[ "givenName" ], addr.givenName(), mod ); + tmp += addEntry( mAttributes[ "familyName" ], addr.familyName(), mod ); + tmp += addEntry( mAttributes[ "uid" ], addr.uid(), mod ); + + PhoneNumber number; + number = addr.phoneNumber( PhoneNumber::Home ); + tmp += addEntry( mAttributes[ "phoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Work ); + tmp += addEntry( mAttributes[ "telephoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Fax ); + tmp += addEntry( mAttributes[ "facsimileTelephoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Cell ); + tmp += addEntry( mAttributes[ "mobile" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Pager ); + tmp += addEntry( mAttributes[ "pager" ], number.number().utf8(), mod ); + + tmp += addEntry( mAttributes[ "description" ], addr.note(), mod ); + tmp += addEntry( mAttributes[ "title" ], addr.title(), mod ); + tmp += addEntry( mAttributes[ "organization" ], addr.organization(), mod ); + + Address ad = addr.address( Address::Home ); + if ( !ad.isEmpty() ) { + tmp += addEntry( mAttributes[ "street" ], ad.street(), mod ); + tmp += addEntry( mAttributes[ "state" ], ad.region(), mod ); + tmp += addEntry( mAttributes[ "city" ], ad.locality(), mod ); + tmp += addEntry( mAttributes[ "postalcode" ], ad.postalCode(), mod ); + } + + QStringList emails = addr.emails(); + QStringList::ConstIterator mailIt = emails.begin(); + + if ( !mAttributes[ "mail" ].isEmpty() ) { + if ( mod ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "mail" ] ) + "\n"; + if ( mailIt != emails.end() ) { + tmp += LDIF::assembleLine( mAttributes[ "mail" ], *mailIt ) + "\n"; + mailIt ++; + } + if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp += "-\n"; + } + + if ( !mAttributes[ "mailAlias" ].isEmpty() ) { + if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "mailAlias" ] ) + "\n"; + for ( ; mailIt != emails.end(); ++mailIt ) { + tmp += LDIF::assembleLine( mAttributes[ "mailAlias" ], *mailIt ) + "\n" ; + } + if ( mod ) tmp += "-\n"; + } + + if ( !mAttributes[ "jpegPhoto" ].isEmpty() ) { + QByteArray pic; + QBuffer buffer( pic ); + buffer.open( IO_WriteOnly ); + addr.photo().data().save( &buffer, "JPEG" ); + + if ( mod ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "jpegPhoto" ] ) + "\n"; + tmp += LDIF::assembleLine( mAttributes[ "jpegPhoto" ], pic, 76 ) + "\n"; + if ( mod ) tmp += "-\n"; + } + + tmp += "\n"; + kdDebug(7125) << "ldif: " << QString::fromUtf8(tmp) << endl; + ldif = tmp; + return true; +} + +void ResourceLDAPKIO::setReadOnly( bool value ) +{ + //save the original readonly flag, because offline using disables writing + d->mReadOnly = true; + Resource::setReadOnly( value ); +} + +void ResourceLDAPKIO::init() +{ + if ( mPort == 0 ) mPort = 389; + + /** + If you want to add new attributes, append them here, add a + translation string in the ctor of AttributesDialog and + handle them in the load() method below. + These are the default values + */ + if ( !mAttributes.contains("objectClass") ) + mAttributes.insert( "objectClass", "inetOrgPerson" ); + if ( !mAttributes.contains("commonName") ) + mAttributes.insert( "commonName", "cn" ); + if ( !mAttributes.contains("formattedName") ) + mAttributes.insert( "formattedName", "displayName" ); + if ( !mAttributes.contains("familyName") ) + mAttributes.insert( "familyName", "sn" ); + if ( !mAttributes.contains("givenName") ) + mAttributes.insert( "givenName", "givenName" ); + if ( !mAttributes.contains("mail") ) + mAttributes.insert( "mail", "mail" ); + if ( !mAttributes.contains("mailAlias") ) + mAttributes.insert( "mailAlias", "" ); + if ( !mAttributes.contains("phoneNumber") ) + mAttributes.insert( "phoneNumber", "homePhone" ); + if ( !mAttributes.contains("telephoneNumber") ) + mAttributes.insert( "telephoneNumber", "telephoneNumber" ); + if ( !mAttributes.contains("facsimileTelephoneNumber") ) + mAttributes.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" ); + if ( !mAttributes.contains("mobile") ) + mAttributes.insert( "mobile", "mobile" ); + if ( !mAttributes.contains("pager") ) + mAttributes.insert( "pager", "pager" ); + if ( !mAttributes.contains("description") ) + mAttributes.insert( "description", "description" ); + + if ( !mAttributes.contains("title") ) + mAttributes.insert( "title", "title" ); + if ( !mAttributes.contains("street") ) + mAttributes.insert( "street", "street" ); + if ( !mAttributes.contains("state") ) + mAttributes.insert( "state", "st" ); + if ( !mAttributes.contains("city") ) + mAttributes.insert( "city", "l" ); + if ( !mAttributes.contains("organization") ) + mAttributes.insert( "organization", "o" ); + if ( !mAttributes.contains("postalcode") ) + mAttributes.insert( "postalcode", "postalCode" ); + + if ( !mAttributes.contains("uid") ) + mAttributes.insert( "uid", "uid" ); + if ( !mAttributes.contains("jpegPhoto") ) + mAttributes.insert( "jpegPhoto", "jpegPhoto" ); + + d->mLDAPUrl = KURL(); + if ( !mAnonymous ) { + d->mLDAPUrl.setUser( mUser ); + d->mLDAPUrl.setPass( mPassword ); + } + d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap"); + d->mLDAPUrl.setHost( mHost ); + d->mLDAPUrl.setPort( mPort ); + d->mLDAPUrl.setDn( mDn ); + + if (!mAttributes.empty()) { + QMap<QString,QString>::Iterator it; + QStringList attr; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { + if ( !it.data().isEmpty() && it.key() != "objectClass" ) + attr.append( it.data() ); + } + d->mLDAPUrl.setAttributes( attr ); + } + + d->mLDAPUrl.setScope( d->mSubTree ? LDAPUrl::Sub : LDAPUrl::One ); + if ( !mFilter.isEmpty() && mFilter != "(objectClass=*)" ) + d->mLDAPUrl.setFilter( mFilter ); + d->mLDAPUrl.setExtension( "x-dir", "base" ); + if ( d->mTLS ) d->mLDAPUrl.setExtension( "x-tls", "" ); + d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) ); + if ( d->mSizeLimit ) + d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) ); + if ( d->mTimeLimit ) + d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) ); + if ( d->mSASL ) { + d->mLDAPUrl.setExtension( "x-sasl", "" ); + if ( !d->mBindDN.isEmpty() ) d->mLDAPUrl.setExtension( "bindname", d->mBindDN ); + if ( !d->mMech.isEmpty() ) d->mLDAPUrl.setExtension( "x-mech", d->mMech ); + if ( !d->mRealm.isEmpty() ) d->mLDAPUrl.setExtension( "x-realm", d->mRealm ); + } + + d->mReadOnly = readOnly(); + + kdDebug(7125) << "resource_ldapkio url: " << d->mLDAPUrl.prettyURL() << endl; +} + +void ResourceLDAPKIO::writeConfig( KConfig *config ) +{ + Resource::writeConfig( config ); + + config->writeEntry( "LdapUser", mUser ); + config->writeEntry( "LdapPassword", KStringHandler::obscure( mPassword ) ); + config->writeEntry( "LdapDn", mDn ); + config->writeEntry( "LdapHost", mHost ); + config->writeEntry( "LdapPort", mPort ); + config->writeEntry( "LdapFilter", mFilter ); + config->writeEntry( "LdapAnonymous", mAnonymous ); + config->writeEntry( "LdapTLS", d->mTLS ); + config->writeEntry( "LdapSSL", d->mSSL ); + config->writeEntry( "LdapSubTree", d->mSubTree ); + config->writeEntry( "LdapSASL", d->mSASL ); + config->writeEntry( "LdapMech", d->mMech ); + config->writeEntry( "LdapVer", d->mVer ); + config->writeEntry( "LdapTimeLimit", d->mTimeLimit ); + config->writeEntry( "LdapSizeLimit", d->mSizeLimit ); + config->writeEntry( "LdapRDNPrefix", d->mRDNPrefix ); + config->writeEntry( "LdapRealm", d->mRealm ); + config->writeEntry( "LdapBindDN", d->mBindDN ); + config->writeEntry( "LdapCachePolicy", d->mCachePolicy ); + config->writeEntry( "LdapAutoCache", d->mAutoCache ); + + QStringList attributes; + QMap<QString, QString>::Iterator it; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) + attributes << it.key() << it.data(); + + config->writeEntry( "LdapAttributes", attributes ); +} + +Ticket *ResourceLDAPKIO::requestSaveTicket() +{ + if ( !addressBook() ) { + kdDebug(7125) << "no addressbook" << endl; + return 0; + } + + return createTicket( this ); +} + +void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket ) +{ + delete ticket; +} + +bool ResourceLDAPKIO::doOpen() +{ + return true; +} + +void ResourceLDAPKIO::doClose() +{ +} + +void ResourceLDAPKIO::createCache() +{ + d->mTmp = NULL; + if ( d->mCachePolicy == Cache_NoConnection && d->mAutoCache ) { + d->mTmp = new KTempFile( d->mCacheDst, "tmp" ); + d->mTmp->setAutoDelete( true ); + } +} + +void ResourceLDAPKIO::activateCache() +{ + if ( d->mTmp && d->mError == 0 ) { + d->mTmp->close(); + rename( QFile::encodeName( d->mTmp->name() ), QFile::encodeName( d->mCacheDst ) ); + } + if ( d->mTmp ) { + delete d->mTmp; + d->mTmp = 0; + } +} + +KIO::Job *ResourceLDAPKIO::loadFromCache() +{ + KIO::Job *job = NULL; + if ( d->mCachePolicy == Cache_Always || + ( d->mCachePolicy == Cache_NoConnection && + d->mError == KIO::ERR_COULD_NOT_CONNECT ) ) { + + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + Resource::setReadOnly( true ); + + KURL url( d->mCacheDst ); + job = KIO::get( url, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + } + return job; +} + +bool ResourceLDAPKIO::load() +{ + kdDebug(7125) << "ResourceLDAPKIO::load()" << endl; + KIO::Job *job; + + clear(); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + //set to original settings, offline use will disable writing + Resource::setReadOnly( d->mReadOnly ); + + createCache(); + if ( d->mCachePolicy != Cache_Always ) { + job = KIO::get( d->mLDAPUrl, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + } + + job = loadFromCache(); + if ( job ) { + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + } + if ( mErrorMsg.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO load ok!" << endl; + return true; + } else { + kdDebug(7125) << "ResourceLDAPKIO load finished with error: " << mErrorMsg << endl; + addressBook()->error( mErrorMsg ); + return false; + } +} + +bool ResourceLDAPKIO::asyncLoad() +{ + clear(); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + Resource::setReadOnly( d->mReadOnly ); + + createCache(); + if ( d->mCachePolicy != Cache_Always ) { + KIO::Job *job = KIO::get( d->mLDAPUrl, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( result( KIO::Job* ) ) ); + } else { + result( NULL ); + } + return true; +} + +void ResourceLDAPKIO::data( KIO::Job *, const QByteArray &data ) +{ + if ( data.size() ) { + d->mLdif.setLDIF( data ); + if ( d->mTmp ) { + d->mTmp->file()->writeBlock( data ); + } + } else { + d->mLdif.endLDIF(); + } + + LDIF::ParseVal ret; + QString name; + QByteArray value; + do { + ret = d->mLdif.nextItem(); + switch ( ret ) { + case LDIF::NewEntry: + kdDebug(7125) << "new entry: " << d->mLdif.dn() << endl; + break; + case LDIF::Item: + name = d->mLdif.attr().lower(); + value = d->mLdif.val(); + if ( name == mAttributes[ "commonName" ].lower() ) { + if ( !d->mAddr.formattedName().isEmpty() ) { + QString fn = d->mAddr.formattedName(); + d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); + d->mAddr.setFormattedName( fn ); + } else + d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "formattedName" ].lower() ) { + d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "givenName" ].lower() ) { + d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "mail" ].lower() ) { + d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true ); + } else if ( name == mAttributes[ "mailAlias" ].lower() ) { + d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false ); + } else if ( name == mAttributes[ "phoneNumber" ].lower() ) { + PhoneNumber phone; + phone.setNumber( QString::fromUtf8( value, value.size() ) ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "telephoneNumber" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Work ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "facsimileTelephoneNumber" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Fax ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "mobile" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Cell ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "pager" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Pager ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "description" ].lower() ) { + d->mAddr.setNote( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "title" ].lower() ) { + d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "street" ].lower() ) { + d->mAd.setStreet( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "state" ].lower() ) { + d->mAd.setRegion( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "city" ].lower() ) { + d->mAd.setLocality( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "postalcode" ].lower() ) { + d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "organization" ].lower() ) { + d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "familyName" ].lower() ) { + d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "uid" ].lower() ) { + d->mAddr.setUid( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "jpegPhoto" ].lower() ) { + KABC::Picture photo; + QImage img( value ); + if ( !img.isNull() ) { + photo.setData( img ); + photo.setType( "image/jpeg" ); + d->mAddr.setPhoto( photo ); + } + } + + break; + case LDIF::EndEntry: { + d->mAddr.setResource( this ); + d->mAddr.insertAddress( d->mAd ); + d->mAddr.setChanged( false ); + insertAddressee( d->mAddr ); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + } + break; + default: + break; + } + } while ( ret != LDIF::MoreData ); +} + +void ResourceLDAPKIO::loadCacheResult( KIO::Job *job ) +{ + mErrorMsg = ""; + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { + mErrorMsg = job->errorString(); + } + if ( !mErrorMsg.isEmpty() ) + emit loadingError( this, mErrorMsg ); + else + emit loadingFinished( this ); +} + +void ResourceLDAPKIO::result( KIO::Job *job ) +{ + mErrorMsg = ""; + if ( job ) { + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { + mErrorMsg = job->errorString(); + } + } else { + d->mError = 0; + } + activateCache(); + + KIO::Job *cjob; + cjob = loadFromCache(); + if ( cjob ) { + connect( cjob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( loadCacheResult( KIO::Job* ) ) ); + } else { + if ( !mErrorMsg.isEmpty() ) + emit loadingError( this, mErrorMsg ); + else + emit loadingFinished( this ); + } +} + +bool ResourceLDAPKIO::save( Ticket* ) +{ + kdDebug(7125) << "ResourceLDAPKIO save" << endl; + + d->mSaveIt = begin(); + KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false ); + connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), + this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + if ( mErrorMsg.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO save ok!" << endl; + return true; + } else { + kdDebug(7125) << "ResourceLDAPKIO finished with error: " << mErrorMsg << endl; + addressBook()->error( mErrorMsg ); + return false; + } +} + +bool ResourceLDAPKIO::asyncSave( Ticket* ) +{ + kdDebug(7125) << "ResourceLDAPKIO asyncSave" << endl; + d->mSaveIt = begin(); + KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false ); + connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), + this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( saveResult( KIO::Job* ) ) ); + return true; +} + +void ResourceLDAPKIO::syncLoadSaveResult( KIO::Job *job ) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + mErrorMsg = job->errorString(); + else + mErrorMsg = ""; + activateCache(); + + qApp->exit_loop(); +} + +void ResourceLDAPKIO::saveResult( KIO::Job *job ) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + emit savingError( this, job->errorString() ); + else + emit savingFinished( this ); +} + +void ResourceLDAPKIO::saveData( KIO::Job*, QByteArray& data ) +{ + while ( d->mSaveIt != end() && + !(*d->mSaveIt).changed() ) d->mSaveIt++; + + if ( d->mSaveIt == end() ) { + kdDebug(7125) << "ResourceLDAPKIO endData" << endl; + data.resize(0); + return; + } + + kdDebug(7125) << "ResourceLDAPKIO saveData: " << (*d->mSaveIt).assembledName() << endl; + + AddresseeToLDIF( data, *d->mSaveIt, findUid( (*d->mSaveIt).uid() ) ); +// kdDebug(7125) << "ResourceLDAPKIO save LDIF: " << QString::fromUtf8(data) << endl; + // mark as unchanged + (*d->mSaveIt).setChanged( false ); + + d->mSaveIt++; +} + +void ResourceLDAPKIO::removeAddressee( const Addressee& addr ) +{ + QString dn = findUid( addr.uid() ); + + kdDebug(7125) << "ResourceLDAPKIO: removeAddressee: " << dn << endl; + + if ( !mErrorMsg.isEmpty() ) { + addressBook()->error( mErrorMsg ); + return; + } + if ( !dn.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO: found uid: " << dn << endl; + LDAPUrl url( d->mLDAPUrl ); + url.setPath( "/" + dn ); + url.setExtension( "x-dir", "base" ); + url.setScope( LDAPUrl::Base ); + if ( KIO::NetAccess::del( url, NULL ) ) mAddrMap.erase( addr.uid() ); + } else { + //maybe it's not saved yet + mAddrMap.erase( addr.uid() ); + } +} + + +void ResourceLDAPKIO::setUser( const QString &user ) +{ + mUser = user; +} + +QString ResourceLDAPKIO::user() const +{ + return mUser; +} + +void ResourceLDAPKIO::setPassword( const QString &password ) +{ + mPassword = password; +} + +QString ResourceLDAPKIO::password() const +{ + return mPassword; +} + +void ResourceLDAPKIO::setDn( const QString &dn ) +{ + mDn = dn; +} + +QString ResourceLDAPKIO::dn() const +{ + return mDn; +} + +void ResourceLDAPKIO::setHost( const QString &host ) +{ + mHost = host; +} + +QString ResourceLDAPKIO::host() const +{ + return mHost; +} + +void ResourceLDAPKIO::setPort( int port ) +{ + mPort = port; +} + +int ResourceLDAPKIO::port() const +{ + return mPort; +} + +void ResourceLDAPKIO::setVer( int ver ) +{ + d->mVer = ver; +} + +int ResourceLDAPKIO::ver() const +{ + return d->mVer; +} + +void ResourceLDAPKIO::setSizeLimit( int sizelimit ) +{ + d->mSizeLimit = sizelimit; +} + +int ResourceLDAPKIO::sizeLimit() +{ + return d->mSizeLimit; +} + +void ResourceLDAPKIO::setTimeLimit( int timelimit ) +{ + d->mTimeLimit = timelimit; +} + +int ResourceLDAPKIO::timeLimit() +{ + return d->mTimeLimit; +} + +void ResourceLDAPKIO::setFilter( const QString &filter ) +{ + mFilter = filter; +} + +QString ResourceLDAPKIO::filter() const +{ + return mFilter; +} + +void ResourceLDAPKIO::setIsAnonymous( bool value ) +{ + mAnonymous = value; +} + +bool ResourceLDAPKIO::isAnonymous() const +{ + return mAnonymous; +} + +void ResourceLDAPKIO::setIsTLS( bool value ) +{ + d->mTLS = value; +} + +bool ResourceLDAPKIO::isTLS() const +{ + return d->mTLS; +} +void ResourceLDAPKIO::setIsSSL( bool value ) +{ + d->mSSL = value; +} + +bool ResourceLDAPKIO::isSSL() const +{ + return d->mSSL; +} + +void ResourceLDAPKIO::setIsSubTree( bool value ) +{ + d->mSubTree = value; +} + +bool ResourceLDAPKIO::isSubTree() const +{ + return d->mSubTree; +} + +void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes ) +{ + mAttributes = attributes; +} + +QMap<QString, QString> ResourceLDAPKIO::attributes() const +{ + return mAttributes; +} + +void ResourceLDAPKIO::setRDNPrefix( int value ) +{ + d->mRDNPrefix = value; +} + +int ResourceLDAPKIO::RDNPrefix() const +{ + return d->mRDNPrefix; +} + +void ResourceLDAPKIO::setIsSASL( bool value ) +{ + d->mSASL = value; +} + +bool ResourceLDAPKIO::isSASL() const +{ + return d->mSASL; +} + +void ResourceLDAPKIO::setMech( const QString &mech ) +{ + d->mMech = mech; +} + +QString ResourceLDAPKIO::mech() const +{ + return d->mMech; +} + +void ResourceLDAPKIO::setRealm( const QString &realm ) +{ + d->mRealm = realm; +} + +QString ResourceLDAPKIO::realm() const +{ + return d->mRealm; +} + +void ResourceLDAPKIO::setBindDN( const QString &binddn ) +{ + d->mBindDN = binddn; +} + +QString ResourceLDAPKIO::bindDN() const +{ + return d->mBindDN; +} + +void ResourceLDAPKIO::setCachePolicy( int pol ) +{ + d->mCachePolicy = pol; +} + +int ResourceLDAPKIO::cachePolicy() const +{ + return d->mCachePolicy; +} + +void ResourceLDAPKIO::setAutoCache( bool value ) +{ + d->mAutoCache = value; +} + +bool ResourceLDAPKIO::autoCache() +{ + return d->mAutoCache; +} + +QString ResourceLDAPKIO::cacheDst() const +{ + return d->mCacheDst; +} + + +#include "resourceldapkio.moc" diff --git a/kabc/plugins/ldapkio/resourceldapkio.h b/kabc/plugins/ldapkio/resourceldapkio.h new file mode 100644 index 000000000..bd72a9b11 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkio.h @@ -0,0 +1,171 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 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 KABC_RESOURCELDAP_H +#define KABC_RESOURCELDAP_H + +#include <kabc/resource.h> +#include <kabc/ldif.h> +#include <kio/job.h> + +class KConfig; + +namespace KABC { + +class KABC_EXPORT ResourceLDAPKIO : public Resource +{ + Q_OBJECT + + public: + enum CachePolicy{ Cache_No, Cache_NoConnection, Cache_Always }; + + ResourceLDAPKIO( const KConfig* ); + virtual ~ResourceLDAPKIO(); + /** + * Call this after you used one of the set... methods + */ + virtual void init(); + + virtual void writeConfig( KConfig* ); + + virtual bool doOpen(); + virtual void doClose(); + + virtual Ticket *requestSaveTicket(); + virtual void releaseSaveTicket( Ticket* ); + + virtual bool readOnly() const { return Resource::readOnly(); } + virtual void setReadOnly( bool value ); + + virtual bool load(); + virtual bool asyncLoad(); + virtual bool save( Ticket * ticket ); + virtual bool asyncSave( Ticket * ticket ); + + virtual void removeAddressee( const Addressee& addr ); + + void setUser( const QString &user ); + QString user() const; + + void setPassword( const QString &password ); + QString password() const; + + void setRealm( const QString &realm ); + QString realm() const; + + void setBindDN( const QString &binddn ); + QString bindDN() const; + + void setDn( const QString &dn ); + QString dn() const; + + void setHost( const QString &host ); + QString host() const; + + void setPort( int port ); + int port() const; + + void setVer( int ver ); + int ver() const; + + void setSizeLimit( int sizelimit ); + int sizeLimit(); + + void setTimeLimit( int timelimit ); + int timeLimit(); + + void setFilter( const QString &filter ); + QString filter() const; + + void setIsAnonymous( bool value ); + bool isAnonymous() const; + + void setAttributes( const QMap<QString, QString> &attributes ); + QMap<QString, QString> attributes() const; + + void setRDNPrefix( int value ); + int RDNPrefix() const; + + void setIsTLS( bool value ); + bool isTLS() const ; + + void setIsSSL( bool value ); + bool isSSL() const; + + void setIsSubTree( bool value ); + bool isSubTree() const ; + + void setIsSASL( bool value ); + bool isSASL() const ; + + void setMech( const QString &mech ); + QString mech() const; + + void setCachePolicy( int pol ); + int cachePolicy() const; + + void setAutoCache( bool value ); + bool autoCache(); + + QString cacheDst() const; + +protected slots: + void entries( KIO::Job*, const KIO::UDSEntryList& ); + void data( KIO::Job*, const QByteArray& ); + void result( KIO::Job* ); + void listResult( KIO::Job* ); + void syncLoadSaveResult( KIO::Job* ); + void saveResult( KIO::Job* ); + void saveData( KIO::Job*, QByteArray& ); + void loadCacheResult( KIO::Job* ); + + private: + QString mUser; + QString mPassword; + QString mDn; + QString mHost; + QString mFilter; + int mPort; + bool mAnonymous; + QMap<QString, QString> mAttributes; + + KURL mLDAPUrl; + int mGetCounter; //KDE 4: remove + bool mErrorOccured; //KDE 4: remove + QString mErrorMsg; + QMap<KIO::Job*, QByteArray> mJobMap; //KDE 4: remove + + KIO::Job *loadFromCache(); + void createCache(); + void activateCache(); + void enter_loop(); + QCString addEntry( const QString &attr, const QString &value, bool mod ); + QString findUid( const QString &uid ); + bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, + const QString &olddn ); + + class ResourceLDAPKIOPrivate; + ResourceLDAPKIOPrivate *d; +}; + +} + +#endif diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.cpp b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp new file mode 100644 index 000000000..ae54ab8c3 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp @@ -0,0 +1,388 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 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 <qapplication.h> + +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qspinbox.h> +#include <qvbox.h> +#include <qvgroupbox.h> +#include <qhbuttongroup.h> +#include <qradiobutton.h> + +#include <kaccelmanager.h> +#include <kcombobox.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klocale.h> +#include <klineedit.h> +#include <kmessagebox.h> +#include <kio/netaccess.h> + +#include "resourceldapkio.h" + +#include "resourceldapkioconfig.h" +#include "resourceldapkioconfig.moc" + +using namespace KABC; + +ResourceLDAPKIOConfig::ResourceLDAPKIOConfig( QWidget* parent, const char* name ) + : KRES::ConfigWidget( parent, name ) +{ + QBoxLayout *mainLayout = new QVBoxLayout( this ); + mainLayout->setAutoAdd( true ); + cfg = new LdapConfigWidget( LdapConfigWidget::W_ALL, this ); + + mSubTree = new QCheckBox( i18n( "Sub-tree query" ), this ); + QHBox *box = new QHBox( this ); + box->setSpacing( KDialog::spacingHint() ); + mEditButton = new QPushButton( i18n( "Edit Attributes..." ), box ); + mCacheButton = new QPushButton( i18n( "Offline Use..." ), box ); + + connect( mEditButton, SIGNAL( clicked() ), SLOT( editAttributes() ) ); + connect( mCacheButton, SIGNAL( clicked() ), SLOT( editCache() ) ); +} + +void ResourceLDAPKIOConfig::loadSettings( KRES::Resource *res ) +{ + ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceLDAPKIOConfig::loadSettings(): cast failed" << endl; + return; + } + + cfg->setUser( resource->user() ); + cfg->setPassword( resource->password() ); + cfg->setRealm( resource->realm() ); + cfg->setBindDN( resource->bindDN() ); + cfg->setHost( resource->host() ); + cfg->setPort( resource->port() ); + cfg->setVer( resource->ver() ); + cfg->setTimeLimit( resource->timeLimit() ); + cfg->setSizeLimit( resource->sizeLimit() ); + cfg->setDn( resource->dn() ); + cfg->setFilter( resource->filter() ); + cfg->setMech( resource->mech() ); + if ( resource->isTLS() ) cfg->setSecTLS(); + else if ( resource->isSSL() ) cfg->setSecSSL(); + else cfg->setSecNO(); + if ( resource->isAnonymous() ) cfg->setAuthAnon(); + else if ( resource->isSASL() ) cfg->setAuthSASL(); + else cfg->setAuthSimple(); + + mSubTree->setChecked( resource->isSubTree() ); + mAttributes = resource->attributes(); + mRDNPrefix = resource->RDNPrefix(); + mCachePolicy = resource->cachePolicy(); + mCacheDst = resource->cacheDst(); + mAutoCache = resource->autoCache(); +} + +void ResourceLDAPKIOConfig::saveSettings( KRES::Resource *res ) +{ + ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceLDAPKIOConfig::saveSettings(): cast failed" << endl; + return; + } + + resource->setUser( cfg->user() ); + resource->setPassword( cfg->password() ); + resource->setRealm( cfg->realm() ); + resource->setBindDN( cfg->bindDN() ); + resource->setHost( cfg->host() ); + resource->setPort( cfg->port() ); + resource->setVer( cfg->ver() ); + resource->setTimeLimit( cfg->timeLimit() ); + resource->setSizeLimit( cfg->sizeLimit() ); + resource->setDn( cfg->dn() ); + resource->setFilter( cfg->filter() ); + resource->setIsAnonymous( cfg->isAuthAnon() ); + resource->setIsSASL( cfg->isAuthSASL() ); + resource->setMech( cfg->mech() ); + resource->setIsTLS( cfg->isSecTLS() ); + resource->setIsSSL( cfg->isSecSSL() ); + resource->setIsSubTree( mSubTree->isChecked() ); + resource->setAttributes( mAttributes ); + resource->setRDNPrefix( mRDNPrefix ); + resource->setCachePolicy( mCachePolicy ); + resource->init(); + +} + +void ResourceLDAPKIOConfig::editAttributes() +{ + AttributesDialog dlg( mAttributes, mRDNPrefix, this ); + if ( dlg.exec() ) { + mAttributes = dlg.attributes(); + mRDNPrefix = dlg.rdnprefix(); + } +} + +void ResourceLDAPKIOConfig::editCache() +{ + LDAPUrl src; + QStringList attr; + + src = cfg->url(); + src.setScope( mSubTree->isChecked() ? LDAPUrl::Sub : LDAPUrl::One ); + if (!mAttributes.empty()) { + QMap<QString,QString>::Iterator it; + QStringList attr; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { + if ( !it.data().isEmpty() && it.key() != "objectClass" ) + attr.append( it.data() ); + } + src.setAttributes( attr ); + } + src.setExtension( "x-dir", "base" ); + OfflineDialog dlg( mAutoCache, mCachePolicy, src, mCacheDst, this ); + if ( dlg.exec() ) { + mCachePolicy = dlg.cachePolicy(); + mAutoCache = dlg.autoCache(); + } + +} + +AttributesDialog::AttributesDialog( const QMap<QString, QString> &attributes, + int rdnprefix, + QWidget *parent, const char *name ) + : KDialogBase( Plain, i18n( "Attributes Configuration" ), Ok | Cancel, + Ok, parent, name, true, true ) +{ + mNameDict.setAutoDelete( true ); + mNameDict.insert( "objectClass", new QString( i18n( "Object classes" ) ) ); + mNameDict.insert( "commonName", new QString( i18n( "Common name" ) ) ); + mNameDict.insert( "formattedName", new QString( i18n( "Formatted name" ) ) ); + mNameDict.insert( "familyName", new QString( i18n( "Family name" ) ) ); + mNameDict.insert( "givenName", new QString( i18n( "Given name" ) ) ); + mNameDict.insert( "organization", new QString( i18n( "Organization" ) ) ); + mNameDict.insert( "title", new QString( i18n( "Title" ) ) ); + mNameDict.insert( "street", new QString( i18n( "Street" ) ) ); + mNameDict.insert( "state", new QString( i18n( "State" ) ) ); + mNameDict.insert( "city", new QString( i18n( "City" ) ) ); + mNameDict.insert( "postalcode", new QString( i18n( "Postal code" ) ) ); + mNameDict.insert( "mail", new QString( i18n( "Email" ) ) ); + mNameDict.insert( "mailAlias", new QString( i18n( "Email alias" ) ) ); + mNameDict.insert( "phoneNumber", new QString( i18n( "Telephone number" ) ) ); + mNameDict.insert( "telephoneNumber", new QString( i18n( "Work telephone number" ) ) ); + mNameDict.insert( "facsimileTelephoneNumber", new QString( i18n( "Fax number" ) ) ); + mNameDict.insert( "mobile", new QString( i18n( "Cell phone number" ) ) ); + mNameDict.insert( "pager", new QString( i18n( "Pager" ) ) ); + mNameDict.insert( "description", new QString( i18n( "Note" ) ) ); + mNameDict.insert( "uid", new QString( i18n( "UID" ) ) ); + mNameDict.insert( "jpegPhoto", new QString( i18n( "Photo" ) ) ); + + // default map + mDefaultMap.insert( "objectClass", "inetOrgPerson" ); + mDefaultMap.insert( "commonName", "cn" ); + mDefaultMap.insert( "formattedName", "displayName" ); + mDefaultMap.insert( "familyName", "sn" ); + mDefaultMap.insert( "givenName", "givenName" ); + mDefaultMap.insert( "title", "title" ); + mDefaultMap.insert( "street", "street" ); + mDefaultMap.insert( "state", "st" ); + mDefaultMap.insert( "city", "l" ); + mDefaultMap.insert( "organization", "o" ); + mDefaultMap.insert( "postalcode", "postalCode" ); + mDefaultMap.insert( "mail", "mail" ); + mDefaultMap.insert( "mailAlias", "" ); + mDefaultMap.insert( "phoneNumber", "homePhone" ); + mDefaultMap.insert( "telephoneNumber", "telephoneNumber" ); + mDefaultMap.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" ); + mDefaultMap.insert( "mobile", "mobile" ); + mDefaultMap.insert( "pager", "pager" ); + mDefaultMap.insert( "description", "description" ); + mDefaultMap.insert( "uid", "uid" ); + mDefaultMap.insert( "jpegPhoto", "jpegPhoto" ); + + // overwrite the default values here + QMap<QString, QString> kolabMap, netscapeMap, evolutionMap, outlookMap; + + // kolab + kolabMap.insert( "formattedName", "display-name" ); + kolabMap.insert( "mailAlias", "mailalias" ); + + // evolution + evolutionMap.insert( "formattedName", "fileAs" ); + + mMapList.append( attributes ); + mMapList.append( kolabMap ); + mMapList.append( netscapeMap ); + mMapList.append( evolutionMap ); + mMapList.append( outlookMap ); + + QFrame *page = plainPage(); + QGridLayout *layout = new QGridLayout( page, 4, ( attributes.count() + 4 ) >> 1, + 0, spacingHint() ); + + QLabel *label = new QLabel( i18n( "Template:" ), page ); + layout->addWidget( label, 0, 0 ); + mMapCombo = new KComboBox( page ); + layout->addWidget( mMapCombo, 0, 1 ); + + mMapCombo->insertItem( i18n( "User Defined" ) ); + mMapCombo->insertItem( i18n( "Kolab" ) ); + mMapCombo->insertItem( i18n( "Netscape" ) ); + mMapCombo->insertItem( i18n( "Evolution" ) ); + mMapCombo->insertItem( i18n( "Outlook" ) ); + connect( mMapCombo, SIGNAL( activated( int ) ), SLOT( mapChanged( int ) ) ); + + label = new QLabel( i18n( "RDN prefix attribute:" ), page ); + layout->addWidget( label, 1, 0 ); + mRDNCombo = new KComboBox( page ); + layout->addWidget( mRDNCombo, 1, 1 ); + mRDNCombo->insertItem( i18n( "commonName" ) ); + mRDNCombo->insertItem( i18n( "UID" ) ); + mRDNCombo->setCurrentItem( rdnprefix ); + + QMap<QString, QString>::ConstIterator it; + int i, j = 0; + for ( i = 2, it = attributes.begin(); it != attributes.end(); ++it, ++i ) { + if ( mNameDict[ it.key() ] == 0 ) { + i--; + continue; + } + if ( (uint)(i - 2) == ( mNameDict.count() >> 1 ) ) { + i = 0; + j = 2; + } + kdDebug(7125) << "itkey: " << it.key() << " i: " << i << endl; + label = new QLabel( *mNameDict[ it.key() ] + ":", page ); + KLineEdit *lineedit = new KLineEdit( page ); + mLineEditDict.insert( it.key(), lineedit ); + lineedit->setText( it.data() ); + label->setBuddy( lineedit ); + layout->addWidget( label, i, j ); + layout->addWidget( lineedit, i, j+1 ); + } + + for ( i = 1; i < mMapCombo->count(); i++ ) { + QDictIterator<KLineEdit> it2( mLineEditDict ); + for ( ; it2.current(); ++it2 ) { + if ( mMapList[ i ].contains( it2.currentKey() ) ) { + if ( mMapList[ i ][ it2.currentKey() ] != it2.current()->text() ) break; + } else { + if ( mDefaultMap[ it2.currentKey() ] != it2.current()->text() ) break; + } + } + if ( !it2.current() ) { + mMapCombo->setCurrentItem( i ); + break; + } + } + + KAcceleratorManager::manage( this ); +} + +AttributesDialog::~AttributesDialog() +{ +} + +QMap<QString, QString> AttributesDialog::attributes() const +{ + QMap<QString, QString> map; + + QDictIterator<KLineEdit> it( mLineEditDict ); + for ( ; it.current(); ++it ) + map.insert( it.currentKey(), it.current()->text() ); + + return map; +} + +int AttributesDialog::rdnprefix() const +{ + return mRDNCombo->currentItem(); +} + +void AttributesDialog::mapChanged( int pos ) +{ + + // apply first the default and than the spezific changes + QMap<QString, QString>::Iterator it; + for ( it = mDefaultMap.begin(); it != mDefaultMap.end(); ++it ) + mLineEditDict[ it.key() ]->setText( it.data() ); + + for ( it = mMapList[ pos ].begin(); it != mMapList[ pos ].end(); ++it ) { + if ( !it.data().isEmpty() ) { + KLineEdit *le = mLineEditDict[ it.key() ]; + if ( le ) le->setText( it.data() ); + } + } +} + +OfflineDialog::OfflineDialog( bool autoCache, int cachePolicy, const KURL &src, + const QString &dst, QWidget *parent, const char *name ) + : KDialogBase( Plain, i18n( "Offline Configuration" ), Ok | Cancel, + Ok, parent, name, true, true ) +{ + QFrame *page = plainPage(); + QVBoxLayout *layout = new QVBoxLayout( page ); + layout->setAutoAdd( true ); + + mSrc = src; mDst = dst; + mCacheGroup = new QButtonGroup( 1, Qt::Horizontal, + i18n("Offline Cache Policy"), page ); + + QRadioButton *bt; + new QRadioButton( i18n("Do not use offline cache"), mCacheGroup ); + bt = new QRadioButton( i18n("Use local copy if no connection"), mCacheGroup ); + new QRadioButton( i18n("Always use local copy"), mCacheGroup ); + mCacheGroup->setButton( cachePolicy ); + + mAutoCache = new QCheckBox( i18n("Refresh offline cache automatically"), + page ); + mAutoCache->setChecked( autoCache ); + mAutoCache->setEnabled( bt->isChecked() ); + + connect( bt, SIGNAL(toggled(bool)), mAutoCache, SLOT(setEnabled(bool)) ); + + QPushButton *lcache = new QPushButton( i18n("Load into Cache"), page ); + connect( lcache, SIGNAL( clicked() ), SLOT( loadCache() ) ); +} + +OfflineDialog::~OfflineDialog() +{ +} + +bool OfflineDialog::autoCache() const +{ + return mAutoCache->isChecked(); +} + +int OfflineDialog::cachePolicy() const +{ + return mCacheGroup->selectedId(); +} + +void OfflineDialog::loadCache() +{ + if ( KIO::NetAccess::download( mSrc, mDst, this ) ) { + KMessageBox::information( this, + i18n("Successfully downloaded directory server contents!") ); + } else { + KMessageBox::error( this, + i18n("An error occurred downloading directory server contents into file %1.").arg(mDst) ); + } +} diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.h b/kabc/plugins/ldapkio/resourceldapkioconfig.h new file mode 100644 index 000000000..c261cbd06 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioconfig.h @@ -0,0 +1,118 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 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 RESOURCELDAPCONFIG_H +#define RESOURCELDAPCONFIG_H + +#include <qmap.h> +#include <qradiobutton.h> +#include <qcombobox.h> +#include <qdict.h> + +#include <kdialogbase.h> +#include <kresources/configwidget.h> +#include <kabc/ldif.h> +#include <kabc/ldapconfigwidget.h> + + +class QCheckBox; +class QPushButton; +class QSpinBox; +class QString; + +class KComboBox; +class KLineEdit; + +namespace KABC { + +class KABC_EXPORT ResourceLDAPKIOConfig : public KRES::ConfigWidget +{ + Q_OBJECT + + public: + ResourceLDAPKIOConfig( QWidget* parent = 0, const char* name = 0 ); + + public slots: + void loadSettings( KRES::Resource* ); + void saveSettings( KRES::Resource* ); + + private slots: + void editAttributes(); + void editCache(); + private: + QPushButton *mEditButton, *mCacheButton; + LdapConfigWidget *cfg; + QCheckBox *mSubTree; + QMap<QString, QString> mAttributes; + int mRDNPrefix, mCachePolicy; + bool mAutoCache; + QString mCacheDst; +}; + +class AttributesDialog : public KDialogBase +{ + Q_OBJECT + + public: + AttributesDialog( const QMap<QString, QString> &attributes, int rdnprefix, + QWidget *parent, const char *name = 0 ); + ~AttributesDialog(); + + QMap<QString, QString> attributes() const; + int rdnprefix() const; + + private slots: + void mapChanged( int pos ); + + private: + enum { UserMap, KolabMap, NetscapeMap, EvolutionMap, OutlookMap }; + + KComboBox *mMapCombo, *mRDNCombo; + QValueList< QMap<QString, QString> > mMapList; + QMap<QString, QString> mDefaultMap; + QDict<KLineEdit> mLineEditDict; + QDict<QString> mNameDict; +}; + +class OfflineDialog : public KDialogBase +{ + Q_OBJECT + + public: + OfflineDialog( bool autoCache, int cachePolicy, const KURL &src, + const QString &dst, QWidget *parent, const char *name = 0 ); + ~OfflineDialog(); + + int cachePolicy() const; + bool autoCache() const; + + private slots: + void loadCache(); + + private: + KURL mSrc; + QString mDst; + QButtonGroup *mCacheGroup; + QCheckBox *mAutoCache; +}; + +} + +#endif diff --git a/kabc/plugins/ldapkio/resourceldapkioplugin.cpp b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp new file mode 100644 index 000000000..98b21061e --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp @@ -0,0 +1,36 @@ +/* + This file is part of libkabc. + Copyright (c) 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 "resourceldapkio.h" +#include "resourceldapkioconfig.h" + +#include <kglobal.h> +#include <klocale.h> + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_ldapkio() + { + KGlobal::locale()->insertCatalogue("kabc_ldapkio"); + return new KRES::PluginFactory<ResourceLDAPKIO, ResourceLDAPKIOConfig>(); + } +} diff --git a/kabc/plugins/net/Makefile.am b/kabc/plugins/net/Makefile.am new file mode 100644 index 000000000..8e7305303 --- /dev/null +++ b/kabc/plugins/net/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourcenetconfig.h + +lib_LTLIBRARIES = libkabc_net.la +libkabc_net_la_SOURCES = resourcenet.cpp resourcenetconfig.cpp +libkabc_net_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined +libkabc_net_la_LIBADD = $(top_builddir)/kabc/libkabc.la $(LIB_KIO) +libkabc_net_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +kde_module_LTLIBRARIES = kabc_net.la +kabc_net_la_SOURCES = resourcenetplugin.cpp +kabc_net_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kabc_net_la_LIBADD = libkabc_net.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_net.pot + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = resourcenet.h + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = net.desktop + +resourcenetplugin.lo: ../../addressee.h diff --git a/kabc/plugins/net/net.desktop b/kabc/plugins/net/net.desktop new file mode 100644 index 000000000..eadc38ba8 --- /dev/null +++ b/kabc/plugins/net/net.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Name=Network +Name[af]=Netwerk +Name[ar]=الشبكة +Name[az]=ŞəbÉ™kÉ™ +Name[be]=Сетка +Name[bn]=নেটওয়ারà§à¦• +Name[br]=Rouedad +Name[bs]=Mreža +Name[ca]=Xarxa +Name[cs]=SÃÅ¥ +Name[csb]=Sec +Name[cy]=Rhydwaith +Name[da]=Netværk +Name[de]=Netzwerk +Name[el]=Δίκτυο +Name[eo]=Reto +Name[es]=Red +Name[et]=Võrk +Name[eu]=Sarea +Name[fa]=شبکه +Name[fi]=Verkko +Name[fr]=Réseau +Name[fy]=Netwurk +Name[ga]=LÃonra +Name[gl]=Rede +Name[he]=רשת +Name[hi]=नेटवरà¥à¤• +Name[hr]=Mreža +Name[hsb]=Syć +Name[hu]=Hálózat +Name[id]=Jaringan +Name[is]=Net +Name[it]=Rete +Name[ja]=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ +Name[ka]=ქსელი +Name[kk]=Желі +Name[km]=បណ្ážáž¶áž‰ +Name[ko]=ë„¤íŠ¸ì›Œí¬ +Name[ku]=Tor +Name[lb]=Netzwierk +Name[lt]=Tinklas +Name[lv]=TÄ«kls +Name[mi]=Hao +Name[mk]=Мрежа +Name[mn]=СүлжÑÑ +Name[ms]=Jaringan +Name[nds]=Nettwark +Name[ne]=सञà¥à¤œà¤¾à¤² +Name[nl]=Netwerk +Name[nn]=Nettverk +Name[nso]=Kgokagano +Name[oc]=Resèu +Name[pa]=ਨੈੱਟਵਰਕ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=ReÅ£ea +Name[ru]=Сеть +Name[rw]=Urusobe +Name[se]=Fierbmi +Name[sk]=SieÅ¥ +Name[sl]=Omrežje +Name[sq]=Rrjeta +Name[sr]=Мрежа +Name[sr@Latn]=Mreža +Name[ss]=Luchungechunge +Name[sv]=Nätverk +Name[ta]=பிணையம௠+Name[te]=కలన జాలం +Name[tg]=Шабака +Name[th]=ระบบเครืà¸à¸‚่าย +Name[tr]=AÄŸ +Name[tt]=Çeltär +Name[uk]=Мережа +Name[uz]=Tarmoq +Name[uz@cyrillic]=Tarмоқ +Name[ven]=Vhukwamani +Name[vi]=mạng +Name[wa]=Rantoele +Name[xh]=Umsebenzi womnatha +Name[zh_CN]=网络 +Name[zh_HK]=網絡 +Name[zh_TW]=網路 +Name[zu]=Umsebenzi wokuxhumana okusakazekile +X-KDE-Library=kabc_net +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=net diff --git a/kabc/plugins/net/resourcenet.cpp b/kabc/plugins/net/resourcenet.cpp new file mode 100644 index 000000000..86d2f9bdc --- /dev/null +++ b/kabc/plugins/net/resourcenet.cpp @@ -0,0 +1,390 @@ +/* + This file is part of libkabc. + Copyright (c) 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 <qfile.h> + +#include <kdebug.h> +#include <kio/netaccess.h> +#include <kio/scheduler.h> +#include <klocale.h> +#include <ksavefile.h> +#include <ktempfile.h> +#include <kurlrequester.h> + +#include "addressbook.h" +#include "formatfactory.h" +#include "resourcenetconfig.h" +#include "stdaddressbook.h" + +#include "resourcenet.h" + +using namespace KABC; + +class ResourceNet::ResourceNetPrivate +{ + public: + KIO::Job *mLoadJob; + bool mIsLoading; + + KIO::Job *mSaveJob; + bool mIsSaving; + + QString mLastErrorString; +}; + +ResourceNet::ResourceNet( const KConfig *config ) + : Resource( config ), mFormat( 0 ), + mTempFile( 0 ), + d( new ResourceNetPrivate ) +{ + if ( config ) { + init( KURL( config->readPathEntry( "NetUrl" ) ), config->readEntry( "NetFormat" ) ); + } else { + init( KURL(), "vcard" ); + } +} + +ResourceNet::ResourceNet( const KURL &url, const QString &format ) + : Resource( 0 ), mFormat( 0 ), + mTempFile( 0 ), + d( new ResourceNetPrivate ) +{ + init( url, format ); +} + +void ResourceNet::init( const KURL &url, const QString &format ) +{ + d->mLoadJob = 0; + d->mIsLoading = false; + d->mSaveJob = 0; + d->mIsSaving = false; + + mFormatName = format; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); + if ( !mFormat ) { + mFormatName = "vcard"; + mFormat = factory->format( mFormatName ); + } + + setUrl( url ); +} + +ResourceNet::~ResourceNet() +{ + if ( d->mIsLoading ) + d->mLoadJob->kill(); + if ( d->mIsSaving ) + d->mSaveJob->kill(); + + delete d; + d = 0; + + delete mFormat; + mFormat = 0; + + deleteLocalTempFile(); +} + +void ResourceNet::writeConfig( KConfig *config ) +{ + Resource::writeConfig( config ); + + config->writePathEntry( "NetUrl", mUrl.url() ); + config->writeEntry( "NetFormat", mFormatName ); +} + +Ticket *ResourceNet::requestSaveTicket() +{ + kdDebug(5700) << "ResourceNet::requestSaveTicket()" << endl; + + return createTicket( this ); +} + +void ResourceNet::releaseSaveTicket( Ticket *ticket ) +{ + delete ticket; +} + +bool ResourceNet::doOpen() +{ + return true; +} + +void ResourceNet::doClose() +{ +} + +bool ResourceNet::load() +{ + QString tempFile; + + if ( !KIO::NetAccess::download( mUrl, tempFile, 0 ) ) { + addressBook()->error( i18n( "Unable to download file '%1'." ).arg( mUrl.prettyURL() ) ); + return false; + } + + QFile file( tempFile ); + if ( !file.open( IO_ReadOnly ) ) { + addressBook()->error( i18n( "Unable to open file '%1'." ).arg( tempFile ) ); + KIO::NetAccess::removeTempFile( tempFile ); + return false; + } + + bool result = clearAndLoad( &file ); + if ( !result ) + addressBook()->error( i18n( "Problems during parsing file '%1'." ).arg( tempFile ) ); + + KIO::NetAccess::removeTempFile( tempFile ); + + return result; +} + +bool ResourceNet::clearAndLoad( QFile *file ) +{ + clear(); + return mFormat->loadAll( addressBook(), this, file ); +} + +bool ResourceNet::asyncLoad() +{ + if ( d->mIsLoading ) { + abortAsyncLoading(); + } + + if (d->mIsSaving) { + kdWarning(5700) << "Aborted asyncLoad() because we're still asyncSave()ing!" << endl; + return false; + } + + bool ok = createLocalTempFile(); + if ( ok ) + ok = mTempFile->close(); + + if ( !ok ) { + emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) ); + deleteLocalTempFile(); + return false; + } + + KURL dest; + dest.setPath( mTempFile->name() ); + + KIO::Scheduler::checkSlaveOnHold( true ); + d->mLoadJob = KIO::file_copy( mUrl, dest, -1, true, false, false ); + d->mIsLoading = true; + connect( d->mLoadJob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( downloadFinished( KIO::Job* ) ) ); + + return true; +} + +void ResourceNet::abortAsyncLoading() +{ + kdDebug(5700) << "ResourceNet::abortAsyncLoading()" << endl; + + if ( d->mLoadJob ) { + d->mLoadJob->kill(); // result not emitted + d->mLoadJob = 0; + } + + deleteLocalTempFile(); + d->mIsLoading = false; +} + +void ResourceNet::abortAsyncSaving() +{ + kdDebug(5700) << "ResourceNet::abortAsyncSaving()" << endl; + + if ( d->mSaveJob ) { + d->mSaveJob->kill(); // result not emitted + d->mSaveJob = 0; + } + + deleteLocalTempFile(); + d->mIsSaving = false; +} + +bool ResourceNet::save( Ticket* ) +{ + kdDebug(5700) << "ResourceNet::save()" << endl; + + if (d->mIsSaving) { + abortAsyncSaving(); + } + + KTempFile tempFile; + tempFile.setAutoDelete( true ); + bool ok = false; + + if ( tempFile.status() == 0 && tempFile.file() ) { + saveToFile( tempFile.file() ); + ok = tempFile.close(); + } + + if ( !ok ) { + addressBook()->error( i18n( "Unable to save file '%1'." ).arg( tempFile.name() ) ); + return false; + } + + ok = KIO::NetAccess::upload( tempFile.name(), mUrl, 0 ); + if ( !ok ) + addressBook()->error( i18n( "Unable to upload to '%1'." ).arg( mUrl.prettyURL() ) ); + + return ok; +} + +bool ResourceNet::asyncSave( Ticket* ) +{ + kdDebug(5700) << "ResourceNet::asyncSave()" << endl; + + if (d->mIsSaving) { + abortAsyncSaving(); + } + + if (d->mIsLoading) { + kdWarning(5700) << "Aborted asyncSave() because we're still asyncLoad()ing!" << endl; + return false; + } + + bool ok = createLocalTempFile(); + if ( ok ) { + saveToFile( mTempFile->file() ); + ok = mTempFile->close(); + } + + if ( !ok ) { + emit savingError( this, i18n( "Unable to save file '%1'." ).arg( mTempFile->name() ) ); + deleteLocalTempFile(); + return false; + } + + KURL src; + src.setPath( mTempFile->name() ); + + KIO::Scheduler::checkSlaveOnHold( true ); + d->mIsSaving = true; + d->mSaveJob = KIO::file_copy( src, mUrl, -1, true, false, false ); + connect( d->mSaveJob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( uploadFinished( KIO::Job* ) ) ); + + return true; +} + +bool ResourceNet::createLocalTempFile() +{ + deleteStaleTempFile(); + mTempFile = new KTempFile(); + mTempFile->setAutoDelete( true ); + return mTempFile->status() == 0; +} + +void ResourceNet::deleteStaleTempFile() +{ + if ( hasTempFile() ) { + kdDebug(5700) << "stale temp file detected " << mTempFile->name() << endl; + deleteLocalTempFile(); + } +} + +void ResourceNet::deleteLocalTempFile() +{ + delete mTempFile; + mTempFile = 0; +} + +void ResourceNet::saveToFile( QFile *file ) +{ + mFormat->saveAll( addressBook(), this, file ); +} + +void ResourceNet::setUrl( const KURL &url ) +{ + mUrl = url; +} + +KURL ResourceNet::url() const +{ + return mUrl; +} + +void ResourceNet::setFormat( const QString &name ) +{ + mFormatName = name; + if ( mFormat ) + delete mFormat; + + FormatFactory *factory = FormatFactory::self(); + mFormat = factory->format( mFormatName ); +} + +QString ResourceNet::format() const +{ + return mFormatName; +} + +void ResourceNet::downloadFinished( KIO::Job* ) +{ + kdDebug(5700) << "ResourceNet::downloadFinished()" << endl; + + d->mIsLoading = false; + + if ( !hasTempFile() || mTempFile->status() != 0 ) { + d->mLastErrorString = i18n( "Download failed in some way!" ); + QTimer::singleShot( 0, this, SLOT( signalError() ) ); + return; + } + + QFile file( mTempFile->name() ); + if ( file.open( IO_ReadOnly ) ) { + if ( clearAndLoad( &file ) ) + emit loadingFinished( this ); + else + emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mTempFile->name() ) ); + } + else { + emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) ); + } + + deleteLocalTempFile(); +} + +void ResourceNet::uploadFinished( KIO::Job *job ) +{ + kdDebug(5700) << "ResourceFile::uploadFinished()" << endl; + + d->mIsSaving = false; + + if ( job->error() ) + emit savingError( this, job->errorString() ); + else + emit savingFinished( this ); + + deleteLocalTempFile(); +} + +void ResourceNet::signalError() +{ + emit loadingError( this, d->mLastErrorString ); + d->mLastErrorString.truncate( 0 ); +} + +#include "resourcenet.moc" diff --git a/kabc/plugins/net/resourcenet.h b/kabc/plugins/net/resourcenet.h new file mode 100644 index 000000000..b315be6df --- /dev/null +++ b/kabc/plugins/net/resourcenet.h @@ -0,0 +1,117 @@ +/* + This file is part of libkabc. + Copyright (c) 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_RESOURCENET_H +#define KABC_RESOURCENET_H + +#include <kconfig.h> + +#include <sys/types.h> + +#include <kabc/resource.h> + +class QFile; +class QTimer; +class KTempFile; + +namespace KIO { +class Job; +} + +namespace KABC { + +class FormatPlugin; + +/** + @internal +*/ +class KABC_EXPORT ResourceNet : public Resource +{ + Q_OBJECT + + public: + ResourceNet( const KConfig* ); + ResourceNet( const KURL &url, const QString &format ); + ~ResourceNet(); + + virtual void writeConfig( KConfig* ); + + virtual bool doOpen(); + virtual void doClose(); + + virtual Ticket *requestSaveTicket(); + virtual void releaseSaveTicket( Ticket* ); + + virtual bool load(); + virtual bool asyncLoad(); + virtual bool save( Ticket* ticket ); + virtual bool asyncSave( Ticket* ticket ); + + /** + Set url of directory to be used for saving. + */ + void setUrl( const KURL & ); + + /** + Return url of directory used for loading and saving the address book. + */ + KURL url() const; + + /** + Sets a new format by name. + */ + void setFormat( const QString &name ); + + /** + Returns the format name. + */ + QString format() const; + + protected: + void init( const KURL &url, const QString &format ); + + private slots: + void downloadFinished( KIO::Job* ); + void uploadFinished( KIO::Job* ); + void signalError(); + + private: + bool clearAndLoad( QFile *file ); + void saveToFile( QFile *file ); + bool hasTempFile() const { return mTempFile != 0; } + void abortAsyncLoading(); + void abortAsyncSaving(); + bool createLocalTempFile(); + void deleteLocalTempFile(); + void deleteStaleTempFile(); + + FormatPlugin *mFormat; + QString mFormatName; + + KURL mUrl; + KTempFile *mTempFile; + + class ResourceNetPrivate; + ResourceNetPrivate *d; +}; + +} + +#endif diff --git a/kabc/plugins/net/resourcenetconfig.cpp b/kabc/plugins/net/resourcenetconfig.cpp new file mode 100644 index 000000000..ef5bfdcb9 --- /dev/null +++ b/kabc/plugins/net/resourcenetconfig.cpp @@ -0,0 +1,102 @@ +/* + This file is part of libkabc. + Copyright (c) 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 <qlabel.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kdialog.h> + +#include "formatfactory.h" +#include "resourcenet.h" +#include "stdaddressbook.h" + +#include "resourcenetconfig.h" + +using namespace KABC; + +ResourceNetConfig::ResourceNetConfig( QWidget* parent, const char* name ) + : ConfigWidget( parent, name ), mInEditMode( false ) +{ + QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0, + KDialog::spacingHint() ); + + QLabel *label = new QLabel( i18n( "Format:" ), this ); + mFormatBox = new KComboBox( this ); + + mainLayout->addWidget( label, 0, 0 ); + mainLayout->addWidget( mFormatBox, 0, 1 ); + + label = new QLabel( i18n( "Location:" ), this ); + mUrlEdit = new KURLRequester( this ); + mUrlEdit->setMode( KFile::File ); + + mainLayout->addWidget( label, 1, 0 ); + mainLayout->addWidget( mUrlEdit, 1, 1 ); + + FormatFactory *factory = FormatFactory::self(); + QStringList formats = factory->formats(); + QStringList::Iterator it; + for ( it = formats.begin(); it != formats.end(); ++it ) { + FormatInfo *info = factory->info( *it ); + if ( info ) { + mFormatTypes << (*it); + mFormatBox->insertItem( info->nameLabel ); + } + } +} + +void ResourceNetConfig::setEditMode( bool value ) +{ + mFormatBox->setEnabled( !value ); + mInEditMode = value; +} + +void ResourceNetConfig::loadSettings( KRES::Resource *res ) +{ + ResourceNet *resource = dynamic_cast<ResourceNet*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceNetConfig::loadSettings(): cast failed" << endl; + return; + } + + mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) ); + + mUrlEdit->setURL( resource->url().url() ); +} + +void ResourceNetConfig::saveSettings( KRES::Resource *res ) +{ + ResourceNet *resource = dynamic_cast<ResourceNet*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceNetConfig::saveSettings(): cast failed" << endl; + return; + } + + if ( !mInEditMode ) + resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] ); + + resource->setUrl( KURL( mUrlEdit->url() ) ); +} + +#include "resourcenetconfig.moc" diff --git a/kabc/plugins/net/resourcenetconfig.h b/kabc/plugins/net/resourcenetconfig.h new file mode 100644 index 000000000..e35c46c01 --- /dev/null +++ b/kabc/plugins/net/resourcenetconfig.h @@ -0,0 +1,53 @@ +/* + This file is part of libkabc. + Copyright (c) 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 RESOURCENETCONFIG_H +#define RESOURCENETCONFIG_H + +#include <kcombobox.h> +#include <kurlrequester.h> + +#include <kresources/configwidget.h> + +namespace KABC { + +class KABC_EXPORT ResourceNetConfig : public KRES::ConfigWidget +{ + Q_OBJECT + + public: + ResourceNetConfig( QWidget* parent = 0, const char* name = 0 ); + + void setEditMode( bool value ); + + public slots: + void loadSettings( KRES::Resource *resource ); + void saveSettings( KRES::Resource *resource ); + + private: + KComboBox* mFormatBox; + KURLRequester* mUrlEdit; + + QStringList mFormatTypes; + bool mInEditMode; +}; + +} +#endif diff --git a/kabc/plugins/net/resourcenetplugin.cpp b/kabc/plugins/net/resourcenetplugin.cpp new file mode 100644 index 000000000..189bab051 --- /dev/null +++ b/kabc/plugins/net/resourcenetplugin.cpp @@ -0,0 +1,32 @@ +/* + This file is part of libkabc. + Copyright (c) 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 "resourcenet.h" +#include "resourcenetconfig.h" + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_net() + { + return new KRES::PluginFactory<ResourceNet, ResourceNetConfig>(); + } +} diff --git a/kabc/plugins/sql/Makefile.am b/kabc/plugins/sql/Makefile.am new file mode 100644 index 000000000..93c86f061 --- /dev/null +++ b/kabc/plugins/sql/Makefile.am @@ -0,0 +1,20 @@ +INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourcesql.h resourcesqlconfig.h + +kde_module_LTLIBRARIES = kabc_sql.la + +kabc_sql_la_SOURCES = resourcesql.cpp resourcesqlconfig.cpp + +kabc_sql_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kabc_sql_la_LIBADD = ../../libkabc.la ../../../kdeui/libkdeui.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_sql.pot + +linkdir = $(kde_datadir)/kresources/contact +link_DATA = sql.desktop +EXTRA_DIST = $(link_DATA) diff --git a/kabc/plugins/sql/resourcesql.cpp b/kabc/plugins/sql/resourcesql.cpp new file mode 100644 index 000000000..2e6eb6902 --- /dev/null +++ b/kabc/plugins/sql/resourcesql.cpp @@ -0,0 +1,338 @@ +/* + 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 <qsqldatabase.h> +#include <qsqlcursor.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <klineedit.h> +#include <klocale.h> + +#include "resourcesql.h" +#include "resourcesqlconfig.h" + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_sql() + { + return new KRES::PluginFactory<ResourceSql,ResourceSqlConfig>(); + } +} + +ResourceSql::ResourceSql( AddressBook *ab, const KConfig *config ) + : Resource( ab ), mDb( 0 ) +{ + QString user, password, db, host; + + user = config->readEntry( "SqlUser" ); + password = cryptStr( config->readEntry( "SqlPassword " ) ); + db = config->readEntry( "SqlName" ); + host = config->readEntry( "SqlHost" ); + + init( user, password, db, host ); +} + +ResourceSql::ResourceSql( AddressBook *ab, const QString &user, + const QString &password, const QString &db, const QString &host ) + : Resource( ab ), mDb( 0 ) +{ + init( user, password, db, host ); +} + +void ResourceSql::init( const QString &user, const QString &password, + const QString &db, const QString &host ) +{ + mUser = user; + mPassword = password; + mDbName = db; + mHost = host; +} + +Ticket *ResourceSql::requestSaveTicket() +{ + if ( !addressBook() ) { + kdDebug(5700) << "no addressbook" << endl; + return 0; + } + + return createTicket( this ); +} + +bool ResourceSql::open() +{ + QStringList drivers = QSqlDatabase::drivers(); + for ( QStringList::Iterator it = drivers.begin(); it != drivers.end(); ++it ) { + kdDebug(5700) << "Driver: " << (*it) << endl; + } + + mDb = QSqlDatabase::addDatabase( "QMYSQL3" ); + + if ( !mDb ) { + kdDebug(5700) << "Error. Unable to connect to database." << endl; + return false; + } + + mDb->setDatabaseName( mDbName ); + mDb->setUserName( mUser ); + mDb->setPassword( mPassword ); + mDb->setHostName( mHost ); + + if ( !mDb->open() ) { + kdDebug(5700) << "Error. Unable to open database '" << mDbName << "'." << endl; + return false; + } + + return true; +} + +void ResourceSql::close() +{ + mDb->close(); +} + +bool ResourceSql::load() +{ + QSqlQuery query( "select addressId, name, familyName, givenName, " + "additionalName, prefix, suffix, nickname, birthday, " + "mailer, timezone, geo_latitude, geo_longitude, title, " + "role, organization, note, productId, revision, " + "sortString, url from kaddressbook_main_" + mUser ); + + while ( query.next() ) { + QString addrId = query.value(0).toString(); + + Addressee addr; + addr.setResource( this ); + addr.setUid( addrId ); + addr.setName( query.value(1).toString() ); + addr.setFamilyName( query.value(2).toString() ); + addr.setGivenName( query.value(3).toString() ); + addr.setAdditionalName( query.value(4).toString() ); + addr.setPrefix( query.value(5).toString() ); + addr.setSuffix( query.value(6).toString() ); + addr.setNickName( query.value(7).toString() ); + addr.setBirthday( query.value(8).toDateTime() ); + addr.setMailer( query.value(9).toString() ); + addr.setTimeZone( TimeZone( query.value(10).toInt() ) ); + addr.setGeo( Geo( query.value(11).toDouble(), query.value(12).toDouble() ) ); + addr.setTitle( query.value(13).toString() ); + addr.setRole( query.value(14).toString() ); + addr.setOrganization( query.value(15).toString() ); + addr.setNote( query.value(16).toString() ); + addr.setProductId( query.value(17).toString() ); + addr.setRevision( query.value(18).toDateTime() ); + addr.setSortString( query.value(19).toString() ); + addr.setUrl( query.value(20).toString() ); + + // emails + { + QSqlQuery emailsQuery( "select email, preferred from kaddressbook_emails " + "where addressId = '" + addrId + "'" ); + while ( emailsQuery.next() ) + addr.insertEmail( emailsQuery.value( 0 ).toString(), + emailsQuery.value( 1 ).toInt() ); + } + + // phones + { + QSqlQuery phonesQuery( "select number, type from kaddressbook_phones " + "where addressId = '" + addrId + "'" ); + while ( phonesQuery.next() ) + addr.insertPhoneNumber( PhoneNumber( phonesQuery.value( 0 ).toString(), + phonesQuery.value( 1 ).toInt() ) ); + } + + // addresses + { + QSqlQuery addressesQuery( "select postOfficeBox, extended, street, " + "locality, region, postalCode, country, label, type " + "from kaddressbook_addresses where addressId = '" + addrId + "'" ); + while ( addressesQuery.next() ) { + Address a; + a.setPostOfficeBox( addressesQuery.value(0).toString() ); + a.setExtended( addressesQuery.value(1).toString() ); + a.setStreet( addressesQuery.value(2).toString() ); + a.setLocality( addressesQuery.value(3).toString() ); + a.setRegion( addressesQuery.value(4).toString() ); + a.setPostalCode( addressesQuery.value(5).toString() ); + a.setCountry( addressesQuery.value(6).toString() ); + a.setLabel( addressesQuery.value(7).toString() ); + a.setType( addressesQuery.value(8).toInt() ); + + addr.insertAddress( a ); + } + } + + // categories + { + QSqlQuery categoriesQuery( "select category from kaddressbook_categories " + "where addressId = '" + addrId + "'" ); + while ( categoriesQuery.next() ) + addr.insertCategory( categoriesQuery.value( 0 ).toString() ); + } + + // customs + { + QSqlQuery customsQuery( "select app, name, value from kaddressbook_customs " + "where addressId = '" + addrId + "'" ); + while ( customsQuery.next() ) + addr.insertCustom( customsQuery.value( 0 ).toString(), + customsQuery.value( 1 ).toString(), + customsQuery.value( 2 ).toString()); + } + + addressBook()->insertAddressee( addr ); + } + + return true; +} + +bool ResourceSql::save( Ticket * ) +{ + // we have to delete all entries for this user and reinsert them + QSqlQuery query( "select addressId from kaddressbook_main_" + mUser ); + + while ( query.next() ) { + QString addrId = query.value( 0 ).toString(); + QSqlQuery q; + + q.exec( "DELETE FROM kaddressbook_emails WHERE addressId = '" + addrId + "'" ); + q.exec( "DELETE FROM kaddressbook_phones WHERE addressId = '" + addrId + "'" ); + q.exec( "DELETE FROM kaddressbook_addresses WHERE addressId = '" + addrId + "'" ); + q.exec( "DELETE FROM kaddressbook_categories WHERE addressId = '" + addrId + "'" ); + q.exec( "DELETE FROM kaddressbook_customs WHERE addressId = '" + addrId + "'" ); + + q.exec( "DELETE FROM kaddressbook_main_" + mUser + " WHERE addressId = '" + addrId + "'" ); + } + + // let's start... + AddressBook::Iterator it; + for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { + if ( (*it).resource() != this && (*it).resource() != 0 ) // save only my and new entries + continue; + + QString uid = (*it).uid(); + + query.exec( "INSERT INTO kaddressbook_main_" + mUser + " VALUES ('" + + (*it).uid() + "','" + + (*it).name() + "','" + + (*it).familyName() + "','" + + (*it).givenName() + "','" + + (*it).additionalName() + "','" + + (*it).prefix() + "','" + + (*it).suffix() + "','" + + (*it).nickName() + "','" + + (*it).birthday().toString( Qt::ISODate ) + "','" + + (*it).mailer() + "','" + + QString::number( (*it).timeZone().offset() ) + "','" + + QString::number( (*it).geo().latitude() ) + "','" + + QString::number( (*it).geo().longitude() ) + "','" + + (*it).title() + "','" + + (*it).role() + "','" + + (*it).organization() + "','" + + (*it).note() + "','" + + (*it).productId() + "','" + + (*it).revision().toString( Qt::ISODate ) + "','" + + (*it).sortString() + "','" + + (*it).url().url() + "')" + ); + + // emails + { + QStringList emails = (*it).emails(); + QStringList::ConstIterator it; + bool preferred = true; + for( it = emails.begin(); it != emails.end(); ++it ) { + query.exec("INSERT INTO kaddressbook_emails VALUES ('" + + uid + "','" + + (*it) + "','" + + QString::number(preferred) + "')"); + preferred = false; + } + } + + // phonenumbers + { + PhoneNumber::List phoneNumberList = (*it).phoneNumbers(); + PhoneNumber::List::ConstIterator it; + for( it = phoneNumberList.begin(); it != phoneNumberList.end(); ++it ) { + query.exec("INSERT INTO kaddressbook_phones VALUES ('" + + uid + "','" + + (*it).number() + "','" + + QString::number( (*it).type() ) + "')"); + } + } + + // postal addresses + { + Address::List addressList = (*it).addresses(); + Address::List::ConstIterator it; + for( it = addressList.begin(); it != addressList.end(); ++it ) { + query.exec("INSERT INTO kaddressbook_addresses VALUES ('" + + uid + "','" + + (*it).postOfficeBox() + "','" + + (*it).extended() + "','" + + (*it).street() + "','" + + (*it).locality() + "','" + + (*it).region() + "','" + + (*it).postalCode() + "','" + + (*it).country() + "','" + + (*it).label() + "','" + + QString::number( (*it).type() ) + "')"); + } + } + + // categories + { + QStringList categories = (*it).categories(); + QStringList::ConstIterator it; + for( it = categories.begin(); it != categories.end(); ++it ) + query.exec("INSERT INTO kaddressbook_categories VALUES ('" + + uid + "','" + + (*it) + "')"); + } + + // customs + { + QStringList list = (*it).customs(); + QStringList::ConstIterator it; + for( it = list.begin(); it != list.end(); ++it ) { + int dashPos = (*it).find( '-' ); + int colonPos = (*it).find( ':' ); + QString app = (*it).left( dashPos ); + QString name = (*it).mid( dashPos + 1, colonPos - dashPos - 1 ); + QString value = (*it).right( (*it).length() - colonPos - 1 ); + + query.exec("INSERT INTO kaddressbook_categories VALUES ('" + + uid + "','" + app + "','" + name + "','" + value + "')"); + } + } + } + + return true; +} + +QString ResourceSql::identifier() const +{ + return mHost + "_" + mDbName; +} diff --git a/kabc/plugins/sql/resourcesql.h b/kabc/plugins/sql/resourcesql.h new file mode 100644 index 000000000..c0b61b69b --- /dev/null +++ b/kabc/plugins/sql/resourcesql.h @@ -0,0 +1,63 @@ +/* + 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_RESOURCESQL_H +#define KABC_RESOURCESQL_H + +#include <kconfig.h> + +#include "addressbook.h" +#include "resource.h" + +class QSqlDatabase; + +namespace KABC { + +class ResourceSql : public Resource +{ +public: + ResourceSql( AddressBook *ab, const QString &user, const QString &password, + const QString &db, const QString &host ); + ResourceSql( AddressBook *ab, const KConfig * ); + + bool open(); + void close(); + + Ticket *requestSaveTicket(); + + bool load(); + bool save( Ticket * ticket ); + + QString identifier() const; + +private: + void init(const QString &user, const QString &password, + const QString &db, const QString &host ); + + QString mUser; + QString mPassword; + QString mDbName; + QString mHost; + + QSqlDatabase *mDb; +}; + +} +#endif diff --git a/kabc/plugins/sql/resourcesqlconfig.cpp b/kabc/plugins/sql/resourcesqlconfig.cpp new file mode 100644 index 000000000..d9abffa30 --- /dev/null +++ b/kabc/plugins/sql/resourcesqlconfig.cpp @@ -0,0 +1,95 @@ +/* + 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 <qlabel.h> +#include <qlayout.h> +#include <qspinbox.h> +#include <qvbox.h> + +#include <klineedit.h> +#include <klocale.h> + +#include "resource.h" +#include "resourcesqlconfig.h" + +using namespace KABC; + +ResourceSqlConfig::ResourceSqlConfig( QWidget* parent, const char* name ) + : ResourceConfigWidget( parent, name ) +{ + resize( 290, 170 ); + + QGridLayout *mainLayout = new QGridLayout( this, 4, 2 ); + + QLabel *label = new QLabel( i18n( "Username:" ), this ); + mUser = new KLineEdit( this ); + + mainLayout->addWidget( label, 0, 0 ); + mainLayout->addWidget( mUser, 0, 1 ); + + label = new QLabel( i18n( "Password:" ), this ); + mPassword = new KLineEdit( this ); + mPassword->setEchoMode( KLineEdit::Password ); + + mainLayout->addWidget( label, 1, 0 ); + mainLayout->addWidget( mPassword, 1, 1 ); + + label = new QLabel( i18n( "Host:" ), this ); + mHost = new KLineEdit( this ); + + mainLayout->addWidget( label, 2, 0 ); + mainLayout->addWidget( mHost, 2, 1 ); + + label = new QLabel( i18n( "Port:" ), this ); + QVBox *box = new QVBox(this); + mPort = new QSpinBox(0, 65535, 1, box ); + mPort->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mPort->setValue(389); + new QWidget(box, "dummy"); + + mainLayout->addWidget( label, 3, 0 ); + mainLayout->addWidget( box, 3, 1 ); + + label = new QLabel( i18n( "Database:" ), this ); + mDbName = new KLineEdit( this ); + + mainLayout->addWidget( label, 4, 0 ); + mainLayout->addWidget( mDbName, 4, 1 ); +} + +void ResourceSqlConfig::loadSettings( KConfig *config ) +{ + mUser->setText( config->readEntry( "SqlUser" ) ); + mPassword->setText( KABC::Resource::cryptStr( config->readEntry( "SqlPassword" ) ) ); + mDbName->setText( config->readEntry( "SqlName" ) ); + mHost->setText( config->readEntry( "SqlHost" ) ); + mPort->setValue( config->readNumEntry( "SqlPort" ) ); +} + +void ResourceSqlConfig::saveSettings( KConfig *config ) +{ + config->writeEntry( "SqlUser", mUser->text() ); + config->writeEntry( "SqlPassword", KABC::Resource::cryptStr( mPassword->text() ) ); + config->writeEntry( "SqlName", mDbName->text() ); + config->writeEntry( "SqlHost", mHost->text() ); + config->writeEntry( "SqlPort", mPort->value() ); +} + +#include "resourcesqlconfig.moc" diff --git a/kabc/plugins/sql/resourcesqlconfig.h b/kabc/plugins/sql/resourcesqlconfig.h new file mode 100644 index 000000000..d7230870e --- /dev/null +++ b/kabc/plugins/sql/resourcesqlconfig.h @@ -0,0 +1,51 @@ +/* + 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 RESOURCESQLCONFIG_H +#define RESOURCESQLCONFIG_H + +#include "resourceconfigwidget.h" + +class KLineEdit; +class QSpinBox; + +namespace KABC { + +class ResourceSqlConfig : public ResourceConfigWidget +{ + Q_OBJECT + +public: + ResourceSqlConfig( QWidget* parent = 0, const char* name = 0 ); + +public slots: + void loadSettings( KConfig *config ); + void saveSettings( KConfig *config ); + +private: + KLineEdit* mUser; + KLineEdit* mPassword; + KLineEdit* mDbName; + KLineEdit* mHost; + QSpinBox* mPort; +}; + +} +#endif diff --git a/kabc/plugins/sql/sql.desktop b/kabc/plugins/sql/sql.desktop new file mode 100644 index 000000000..69ca3e3a7 --- /dev/null +++ b/kabc/plugins/sql/sql.desktop @@ -0,0 +1,10 @@ +[Misc] +Name=SQL +Name[bn]=à¦à¦¸-কিউ-à¦à¦² (SQL) +Name[hi]=à¤à¤¸à¤•à¥à¤¯à¥‚à¤à¤² (SQL) +Name[ss]=I-SQL +Name[te]=à°à°¸à±à°•à±à°¯à±à°Žà°²à± + +[Plugin] +Type=sql +X-KDE-Library=kabc_sql diff --git a/kabc/resource.cpp b/kabc/resource.cpp new file mode 100644 index 000000000..fb677d9d3 --- /dev/null +++ b/kabc/resource.cpp @@ -0,0 +1,351 @@ +/* + 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 <kdebug.h> +#include <klocale.h> + +#include "resource.h" + +using namespace KABC; + +Ticket::Ticket( Resource *resource ) + : mResource( resource ) +{ +} + +Ticket::~Ticket() +{ +/* FIXME: avoid cycle deletion + if ( mResource ) + mResource->releaseSaveTicket( this ); +*/ +} + +Resource *Ticket::resource() +{ + return mResource; +} + +struct Resource::Iterator::IteratorData +{ + Addressee::Map::Iterator mIt; +}; + +struct Resource::ConstIterator::ConstIteratorData +{ + Addressee::Map::ConstIterator mIt; +}; + +Resource::Iterator::Iterator() +{ + d = new IteratorData; +} + +Resource::Iterator::Iterator( const Resource::Iterator &i ) +{ + d = new IteratorData; + d->mIt = i.d->mIt; +} + +Resource::Iterator &Resource::Iterator::operator=( const Resource::Iterator &i ) +{ + if ( this == &i ) + return *this; + delete d; + + d = new IteratorData; + d->mIt = i.d->mIt; + return *this; +} + +Resource::Iterator::~Iterator() +{ + delete d; +} + +const Addressee &Resource::Iterator::operator*() const +{ + return d->mIt.data(); +} + +Addressee &Resource::Iterator::operator*() +{ + return d->mIt.data(); +} + +Resource::Iterator &Resource::Iterator::operator++() +{ + (d->mIt)++; + return *this; +} + +Resource::Iterator &Resource::Iterator::operator++( int ) +{ + (d->mIt)++; + return *this; +} + +Resource::Iterator &Resource::Iterator::operator--() +{ + (d->mIt)--; + return *this; +} + +Resource::Iterator &Resource::Iterator::operator--( int ) +{ + (d->mIt)--; + return *this; +} + +bool Resource::Iterator::operator==( const Iterator &it ) +{ + return ( d->mIt == it.d->mIt ); +} + +bool Resource::Iterator::operator!=( const Iterator &it ) +{ + return ( d->mIt != it.d->mIt ); +} + +Resource::ConstIterator::ConstIterator() +{ + d = new ConstIteratorData; +} + +Resource::ConstIterator::ConstIterator( const Resource::ConstIterator &i ) +{ + d = new ConstIteratorData; + d->mIt = i.d->mIt; +} + +Resource::ConstIterator::ConstIterator( const Resource::Iterator &i ) +{ + d = new ConstIteratorData; + d->mIt = i.d->mIt; +} + +Resource::ConstIterator &Resource::ConstIterator::operator=( const Resource::ConstIterator &i ) +{ + if ( this == &i ) + return *this; + delete d; + + d = new ConstIteratorData; + d->mIt = i.d->mIt; + return *this; +} + +Resource::ConstIterator::~ConstIterator() +{ + delete d; +} + +const Addressee &Resource::ConstIterator::operator*() const +{ + return *(d->mIt); +} + +Resource::ConstIterator &Resource::ConstIterator::operator++() +{ + (d->mIt)++; + return *this; +} + +Resource::ConstIterator &Resource::ConstIterator::operator++( int ) +{ + (d->mIt)++; + return *this; +} + +Resource::ConstIterator &Resource::ConstIterator::operator--() +{ + (d->mIt)--; + return *this; +} + +Resource::ConstIterator &Resource::ConstIterator::operator--( int ) +{ + (d->mIt)--; + return *this; +} + +bool Resource::ConstIterator::operator==( const ConstIterator &it ) +{ + return ( d->mIt == it.d->mIt ); +} + +bool Resource::ConstIterator::operator!=( const ConstIterator &it ) +{ + return ( d->mIt != it.d->mIt ); +} + + +Resource::Resource( const KConfig *config ) + : KRES::Resource( config ), mAddressBook( 0 ) +{ +} + +Resource::~Resource() +{ +} + +Resource::Iterator Resource::begin() +{ + Iterator it; + it.d->mIt = mAddrMap.begin(); + + return it; +} + +Resource::ConstIterator Resource::begin() const +{ + ConstIterator it; + it.d->mIt = mAddrMap.constBegin(); + return it; +} + +Resource::Iterator Resource::end() +{ + Iterator it; + it.d->mIt = mAddrMap.end(); + + return it; +} + +Resource::ConstIterator Resource::end() const +{ + ConstIterator it; + it.d->mIt = mAddrMap.constEnd(); + return it; +} + +void Resource::writeConfig( KConfig *config ) +{ + KRES::Resource::writeConfig( config ); +} + +void Resource::setAddressBook( AddressBook *ab ) +{ + mAddressBook = ab; +} + +AddressBook *Resource::addressBook() +{ + return mAddressBook; +} + +Ticket *Resource::createTicket( Resource *resource ) +{ + return new Ticket( resource ); +} + +void Resource::insertAddressee( const Addressee &addr ) +{ + mAddrMap.insert( addr.uid(), addr ); +} + +void Resource::removeAddressee( const Addressee &addr ) +{ + mAddrMap.erase( addr.uid() ); +} + +Addressee Resource::findByUid( const QString &uid ) +{ + Addressee::Map::ConstIterator it = mAddrMap.find( uid ); + + if ( it != mAddrMap.end() ) + return it.data(); + + return Addressee(); +} + +Addressee::List Resource::findByName( const QString &name ) +{ + Addressee::List results; + + ConstIterator it; + for ( it = begin(); it != end(); ++it ) { + if ( name == (*it).name() ) + results.append( *it ); + } + + return results; +} + +Addressee::List Resource::findByEmail( const QString &email ) +{ + Addressee::List results; + const QString lowerEmail = email.lower(); + + ConstIterator it; + for ( it = begin(); it != end(); ++it ) { + const QStringList mailList = (*it).emails(); + for ( QStringList::ConstIterator ite = mailList.begin(); ite != mailList.end(); ++ite ) { + if ( lowerEmail == (*ite).lower() ) + results.append( *it ); + } + } + + return results; +} + +Addressee::List Resource::findByCategory( const QString &category ) +{ + Addressee::List results; + + ConstIterator it; + for ( it = begin(); it != end(); ++it ) { + if ( (*it).hasCategory( category) ) { + results.append( *it ); + } + } + + return results; +} + +void Resource::clear() +{ + mAddrMap.clear(); +} + +bool Resource::asyncLoad() +{ + bool ok = load(); + if ( !ok ) + emit loadingError( this, i18n( "Loading resource '%1' failed!" ) + .arg( resourceName() ) ); + else + emit loadingFinished( this ); + + return ok; +} + +bool Resource::asyncSave( Ticket *ticket ) { + bool ok = save( ticket ); + if ( !ok ) + emit savingError( this, i18n( "Saving resource '%1' failed!" ) + .arg( resourceName() ) ); + else + emit savingFinished( this ); + + return ok; +} + +#include "resource.moc" diff --git a/kabc/resource.h b/kabc/resource.h new file mode 100644 index 000000000..556c3beae --- /dev/null +++ b/kabc/resource.h @@ -0,0 +1,319 @@ +/* + 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_RESOURCE_H +#define KABC_RESOURCE_H + +#include <kresources/resource.h> + +#include "addressbook.h" +#include "plugin.h" + +namespace KABC { + +/** + * @short Helper class for handling coordinated save of address books. + * + * This class is used as helper class for saving address book. + * @see requestSaveTicket(), save(). + */ +class KABC_EXPORT Ticket +{ + friend class Resource; + + public: + ~Ticket(); + + Resource *resource(); + + private: + Ticket( Resource *resource ); + + Resource *mResource; +}; + +/** + * @internal + */ +class KABC_EXPORT Resource : public KRES::Resource +{ + Q_OBJECT + + public: + + /** + @short Resource Iterator + + This class provides an iterator for resource entries. + By default it points to a QValueList<Addressee>::Iterator, + but you can reimplement this class to fit your own needs. + */ + class KABC_EXPORT Iterator + { + public: + Iterator(); + Iterator( const Iterator & ); + virtual ~Iterator(); + + virtual Iterator &operator=( const Iterator & ); + virtual const Addressee &operator*() const; + virtual Addressee &operator*(); + virtual Iterator &operator++(); + virtual Iterator &operator++( int ); + virtual Iterator &operator--(); + virtual Iterator &operator--( int ); + virtual bool operator==( const Iterator &it ); + virtual bool operator!=( const Iterator &it ); + + struct IteratorData; + IteratorData *d; + }; + + /** + @short Resource Const Iterator + + This class provides a const iterator for resource entries. + */ + class KABC_EXPORT ConstIterator + { + public: + ConstIterator(); + ConstIterator( const ConstIterator & ); + ConstIterator( const Iterator & ); + virtual ~ConstIterator(); + + virtual ConstIterator &operator=( const ConstIterator & ); + virtual const Addressee &operator*() const ; + virtual ConstIterator &operator++(); + virtual ConstIterator &operator++( int ); + virtual ConstIterator &operator--(); + virtual ConstIterator &operator--( int ); + virtual bool operator==( const ConstIterator &it ); + virtual bool operator!=( const ConstIterator &it ); + + struct ConstIteratorData; + ConstIteratorData *d; + }; + + /** + Constructor. + + @param config The config object where the derived classes can + read out their settings. + */ + Resource( const KConfig *config ); + + /** + Destructor. + */ + virtual ~Resource(); + + /** + Returns an iterator pointing to the first addressee in the resource. + This iterator equals end() if the resource is empty. + */ + virtual ConstIterator begin() const; + + /** + This is an overloaded member function, provided for convenience. It + behaves essentially like the above function. + */ + virtual Iterator begin(); + + /** + Returns an iterator pointing to the last addressee in the resource. + This iterator equals begin() if the resource is empty. + */ + virtual ConstIterator end() const; + + /** + This is an overloaded member function, provided for convenience. It + behaves essentially like the above function. + */ + virtual Iterator end(); + + /** + Returns a pointer to the addressbook. + */ + AddressBook *addressBook(); + + /** + Writes the resource specific config to file. + */ + virtual void writeConfig( KConfig *config ); + + /** + Request a ticket, you have to pass through save() to + allow locking. The resource has to create its locks + in this function. + */ + virtual Ticket *requestSaveTicket() = 0; + + /** + Releases the ticket previousely requested with requestSaveTicket(). + The resource has to remove its locks in this function. + This function is also responsible for deleting the ticket. + */ + virtual void releaseSaveTicket( Ticket* ) = 0; + + /** + Loads all addressees synchronously. + + @returns Whether the loading was successfully. + */ + virtual bool load() = 0; + + /** + Loads all addressees asyncronously. You have to make sure that either + the loadingFinished() or loadingError() signal is emitted from within + this function. + + The default implementation simply calls the synchronous load. + + @return Whether the synchronous part of loading was successfully. + */ + virtual bool asyncLoad(); + + /** + Insert an addressee into the resource. + */ + virtual void insertAddressee( const Addressee& ); + + /** + Removes an addressee from resource. + */ + virtual void removeAddressee( const Addressee& addr ); + + /** + Saves all addressees synchronously. + + @param ticket You have to release the ticket later with + releaseSaveTicket() explicitely. + @return Whether the saving was successfully. + */ + virtual bool save( Ticket *ticket ) = 0; + + /** + Saves all addressees asynchronously. You have to make sure that either + the savingFinished() or savingError() signal is emitted from within + this function. + + The default implementation simply calls the synchronous save. + + @param ticket You have to release the ticket later with + releaseSaveTicket() explicitely. + @return Whether the saving was successfully. + */ + virtual bool asyncSave( Ticket *ticket ); + + /** + Searches an addressee with the specified unique identifier. + + @param uid The unique identifier you are looking for. + @return The addressee with the specified unique identifier or an + empty addressee. + */ + virtual Addressee findByUid( const QString &uid ); + + /** + Searches all addressees which match the specified name. + + @param name The name you are looking for. + @return A list of all matching addressees. + */ + virtual Addressee::List findByName( const QString &name ); + + /** + Searches all addressees which match the specified email address. + + @param email The email address you are looking for. + @return A list of all matching addressees. + */ + virtual Addressee::List findByEmail( const QString &email ); + + /** + Searches all addressees which belongs to the specified category. + + @param category The category you are looking for. + @return A list of all matching addressees. + */ + virtual Addressee::List findByCategory( const QString &category ); + + /** + Removes all addressees from the resource. + */ + virtual void clear(); + + /** + @internal + + Sets the address book of the resource. + */ + void setAddressBook( AddressBook* ); + + signals: + /** + This signal is emitted when the resource has finished the loading of all + addressees from the backend to the internal cache. + + @param resource The pointer to the resource which emitted this signal. + */ + void loadingFinished( Resource *resource ); + + /** + This signal is emitted when an error occured during loading the + addressees from the backend to the internal cache. + + @param resource The pointer to the resource which emitted this signal. + @param msg A translated error message. + */ + void loadingError( Resource *resource, const QString &msg ); + + /** + This signal is emitted when the resource has finished the saving of all + addressees from the internal cache to the backend. + + @param resource The pointer to the resource which emitted this signal. + */ + void savingFinished( Resource *resource ); + + /** + This signal is emitted when an error occured during saving the + addressees from the internal cache to the backend. + + @param resource The pointer to the resource which emitted this signal. + @param msg A translated error message. + */ + void savingError( Resource *resource, const QString &msg ); + + protected: + Ticket *createTicket( Resource * ); + Addressee::Map mAddrMap; + + private: + AddressBook *mAddressBook; + + class ResourcePrivate; + ResourcePrivate *d; +}; + +} + +#endif diff --git a/kabc/resourceselectdialog.cpp b/kabc/resourceselectdialog.cpp new file mode 100644 index 000000000..f34dcaa63 --- /dev/null +++ b/kabc/resourceselectdialog.cpp @@ -0,0 +1,111 @@ +/* + 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 <klocale.h> +#include <kbuttonbox.h> +#include <klistbox.h> +#include <kstdguiitem.h> + +#include <qgroupbox.h> +#include <qlayout.h> + +#include "resource.h" +#include "addressbook.h" + +#include "resourceselectdialog.h" + +using namespace KABC; + +ResourceSelectDialog::ResourceSelectDialog( AddressBook *ab, QWidget *parent, const char *name ) + : KDialog( parent, name, true ) +{ + setCaption( i18n( "Resource Selection" ) ); + resize( 300, 200 ); + + QVBoxLayout *mainLayout = new QVBoxLayout( this ); + mainLayout->setMargin( marginHint() ); + + QGroupBox *groupBox = new QGroupBox( 2, Qt::Horizontal, this ); + groupBox->setTitle( i18n( "Resources" ) ); + + mResourceId = new KListBox( groupBox ); + + mainLayout->addWidget( groupBox ); + + mainLayout->addSpacing( 10 ); + + KButtonBox *buttonBox = new KButtonBox( this ); + + buttonBox->addStretch(); + buttonBox->addButton( KStdGuiItem::ok(), this, SLOT( accept() ) ); + buttonBox->addButton( KStdGuiItem::cancel(), this, SLOT( reject() ) ); + buttonBox->layout(); + + mainLayout->addWidget( buttonBox ); + + // setup listbox + uint counter = 0; + QPtrList<Resource> list = ab->resources(); + for ( uint i = 0; i < list.count(); ++i ) { + Resource *resource = list.at( i ); + if ( resource && !resource->readOnly() ) { + mResourceMap.insert( counter, resource ); + mResourceId->insertItem( resource->resourceName() ); + counter++; + } + } + + mResourceId->setCurrentItem( 0 ); +} + +Resource *ResourceSelectDialog::resource() +{ + if ( mResourceId->currentItem() != -1 ) + return mResourceMap[ mResourceId->currentItem() ]; + else + return 0; +} + +Resource *ResourceSelectDialog::getResource( AddressBook *ab, QWidget *parent ) +{ + QPtrList<Resource> resources = ab->resources(); + if ( resources.count() == 1 ) return resources.first(); + + Resource *found = 0; + Resource *r = resources.first(); + while( r ) { + if ( !r->readOnly() ) { + if ( found ) { + found = 0; + break; + } else { + found = r; + } + } + r = resources.next(); + } + if ( found ) return found; + + ResourceSelectDialog dlg( ab, parent ); + if ( dlg.exec() == KDialog::Accepted ) return dlg.resource(); + else return 0; +} + +#include "resourceselectdialog.moc" diff --git a/kabc/resourceselectdialog.h b/kabc/resourceselectdialog.h new file mode 100644 index 000000000..df7e4a4bc --- /dev/null +++ b/kabc/resourceselectdialog.h @@ -0,0 +1,57 @@ +/* + 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_RESOURCESELECTDIALOG_H +#define KABC_RESOURCESELECTDIALOG_H + +#include <qmap.h> + +#include <kdialog.h> +#include <kdemacros.h> + +class KListBox; + +namespace KABC { + +class AddressBook; +class Resource; + +/** + This class is @deprecated, use KRES::SelectDialog instead. + */ +class KABC_EXPORT_DEPRECATED ResourceSelectDialog : KDialog +{ + Q_OBJECT + + public: + ResourceSelectDialog( AddressBook *ab, QWidget *parent = 0, + const char *name = 0); + Resource *resource(); + + static Resource *getResource( AddressBook *ab, QWidget *parent = 0 ); + + private: + KListBox *mResourceId; + QMap<int, Resource*> mResourceMap; +}; + +} + +#endif diff --git a/kabc/scripts/Makefile.am b/kabc/scripts/Makefile.am new file mode 100644 index 000000000..7715fba5c --- /dev/null +++ b/kabc/scripts/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = $(srcdir)/makeaddressee \ + $(srcdir)/addressee.src.cpp \ + $(srcdir)/addressee.src.h \ + $(srcdir)/entrylist \ + $(srcdir)/field.src.cpp + diff --git a/kabc/scripts/addressee.src.cpp b/kabc/scripts/addressee.src.cpp new file mode 100644 index 000000000..887290c8f --- /dev/null +++ b/kabc/scripts/addressee.src.cpp @@ -0,0 +1,1108 @@ +/* + 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 <qregexp.h> + +#include <ksharedptr.h> +#include <kdebug.h> +#include <kapplication.h> +#include <klocale.h> + +#include "addresseehelper.h" +#include "field.h" +#include "resource.h" +#include "sortmode.h" + +#include "addressee.h" + +using namespace KABC; + +static bool matchBinaryPattern( int value, int pattern ); + +template <class L> +static bool listEquals( const QValueList<L>&, const QValueList<L>& ); +static bool emailsEquals( const QStringList&, const QStringList& ); + +KABC::SortMode *Addressee::mSortMode = 0; + +struct Addressee::AddresseeData : public KShared +{ + QString uid; + --VARIABLES-- + + PhoneNumber::List phoneNumbers; + Address::List addresses; + Key::List keys; + QStringList emails; + QStringList categories; + QStringList custom; + + Resource *resource; + + bool empty :1; + bool changed :1; +}; + +Addressee::AddresseeData* Addressee::shared_null = 0; + +Addressee::AddresseeData* Addressee::makeSharedNull() +{ + Addressee::shared_null = new AddresseeData; + shared_null->_KShared_ref(); //just in case (we should add KSD) + shared_null->empty = true; + shared_null->changed = false; + shared_null->resource = 0; + return shared_null; +} + +Addressee::Addressee() +{ + mData = shared_null ? shared_null : makeSharedNull(); +} + +Addressee::~Addressee() +{ +} + +Addressee::Addressee( const Addressee &a ) +{ + mData = a.mData; +} + +Addressee &Addressee::operator=( const Addressee &a ) +{ + if ( this == &a ) + return (*this); + + mData = a.mData; + return (*this); +} + +void Addressee::detach() +{ + if ( mData.data() == shared_null ) { + mData = new AddresseeData; + mData->empty = true; + mData->changed = false; + mData->resource = 0; + mData->uid = KApplication::randomString( 10 ); + return; + } else if ( mData.count() == 1 ) return; + + AddresseeData data = *mData; + mData = new AddresseeData( data ); +} + +bool Addressee::operator==( const Addressee &a ) const +{ + if ( uid() != a.uid() ) { + kdDebug(5700) << "uid differs" << endl; + return false; + } + --EQUALSTEST-- + if ( ( mData->url.isValid() || a.mData->url.isValid() ) && + ( mData->url != a.mData->url ) ) { + kdDebug(5700) << "url differs" << endl; + return false; + } + if ( !listEquals( mData->phoneNumbers, a.mData->phoneNumbers ) ) { + kdDebug(5700) << "phoneNumbers differs" << endl; + return false; + } + if ( !listEquals( mData->addresses, a.mData->addresses ) ) { + kdDebug(5700) << "addresses differs" << endl; + return false; + } + if ( !listEquals( mData->keys, a.mData->keys ) ) { + kdDebug(5700) << "keys differs" << endl; + return false; + } + if ( !emailsEquals( mData->emails, a.mData->emails ) ) { + kdDebug(5700) << "emails differs" << endl; + return false; + } + if ( !listEquals( mData->categories, a.mData->categories ) ) { + kdDebug(5700) << "categories differs" << endl; + return false; + } + if ( !listEquals( mData->custom, a.mData->custom ) ) { + kdDebug(5700) << "custom differs" << endl; + return false; + } + + return true; +} + +bool Addressee::operator!=( const Addressee &a ) const +{ + return !( a == *this ); +} + +bool Addressee::isEmpty() const +{ + return mData->empty; +} + +void Addressee::setUid( const QString &id ) +{ + if ( id == mData->uid ) return; + detach(); + mData->empty = false; + mData->uid = id; +} + +QString Addressee::uid() const +{ + return mData->uid; +} + +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 ] == '"' && s[ s.length() - 1 ] == '"' ) + str = s.mid( 1, s.length() - 2 ); + + setFormattedName( str ); + setName( str ); + + // clear all name parts + setPrefix( QString::null ); + setGivenName( QString::null ); + setAdditionalName( QString::null ); + setFamilyName( QString::null ); + setSuffix( QString::null ); + + if ( str.isEmpty() ) + return; + + QString spaceStr = " "; + QString emptyStr = ""; + AddresseeHelper *helper = AddresseeHelper::self(); + + int i = str.find( ',' ); + if( i < 0 ) { + QStringList parts = QStringList::split( spaceStr, str ); + 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; + + QStringList inclusionList; + for ( int n = 1; (rightOffset - n >= 0) && (n < 4); ++n ) { + if ( helper->containsPrefix( parts[ rightOffset - n ].lower() ) ) { + inclusionList.prepend( parts[ rightOffset - n ] ); + } else + break; + } + + if ( !inclusionList.isEmpty() ) { + setFamilyName( inclusionList.join( " " ) + spaceStr + parts[ rightOffset ] ); + rightOffset -= inclusionList.count(); + } 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 = QStringList::split( spaceStr, part1 ); + 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 ].lower() ) ) { + 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( "" ); + setFamilyName( "" ); + setSuffix( "" ); + } + + parts = QStringList::split( spaceStr, part2 ); + + 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( "" ); + setAdditionalName( "" ); + } + } +} + +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 +{ + QString name = prefix() + " " + givenName() + " " + additionalName() + " " + + familyName() + " " + suffix(); + + return name.simplifyWhiteSpace(); +} + +QString Addressee::fullEmail( const QString &email ) const +{ + QString e; + if ( email.isNull() ) { + e = preferredEmail(); + } else { + e = email; + } + if ( e.isEmpty() ) return QString::null; + + QString text; + if ( realName().isEmpty() ) + text = e; + else { + QRegExp needQuotes( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" ); + if ( realName().find( needQuotes ) != -1 ) { + QString name = realName(); + name.replace( "\"", "\\\"" ); + text = "\"" + name + "\" <" + e + ">"; + } else + text = realName() + " <" + e + ">"; + } + + return text; +} + +void Addressee::insertEmail( const QString &email, bool preferred ) +{ + if ( email.simplifyWhiteSpace().isEmpty() ) + return; + + detach(); + mData->empty = false; + + QStringList::Iterator it = mData->emails.find( email ); + + if ( it != mData->emails.end() ) { + if ( !preferred || it == mData->emails.begin() ) return; + mData->emails.remove( it ); + mData->emails.prepend( email ); + } else { + if ( preferred ) { + mData->emails.prepend( email ); + } else { + mData->emails.append( email ); + } + } +} + +void Addressee::removeEmail( const QString &email ) +{ + detach(); + + QStringList::Iterator it = mData->emails.find( email ); + if ( it == mData->emails.end() ) return; + + mData->emails.remove( it ); +} + +QString Addressee::preferredEmail() const +{ + if ( mData->emails.count() == 0 ) return QString::null; + else return mData->emails.first(); +} + +QStringList Addressee::emails() const +{ + return mData->emails; +} +void Addressee::setEmails( const QStringList& emails ) { + detach(); + + mData->emails = emails; +} +void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber ) +{ + detach(); + mData->empty = false; + + PhoneNumber::List::Iterator it; + for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) { + if ( (*it).id() == phoneNumber.id() ) { + *it = phoneNumber; + return; + } + } + if ( !phoneNumber.number().simplifyWhiteSpace().isEmpty() ) + mData->phoneNumbers.append( phoneNumber ); +} + +void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber ) +{ + detach(); + + PhoneNumber::List::Iterator it; + for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) { + if ( (*it).id() == phoneNumber.id() ) { + mData->phoneNumbers.remove( it ); + return; + } + } +} + +PhoneNumber Addressee::phoneNumber( int type ) const +{ + PhoneNumber phoneNumber( "", type ); + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.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 mData->phoneNumbers; +} + +PhoneNumber::List Addressee::phoneNumbers( int type ) const +{ + PhoneNumber::List list; + + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + list.append( *it ); + } + } + return list; +} + +PhoneNumber Addressee::findPhoneNumber( const QString &id ) const +{ + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return PhoneNumber(); +} + +void Addressee::insertKey( const Key &key ) +{ + detach(); + mData->empty = false; + + Key::List::Iterator it; + for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) { + if ( (*it).id() == key.id() ) { + *it = key; + return; + } + } + mData->keys.append( key ); +} + +void Addressee::removeKey( const Key &key ) +{ + detach(); + + Key::List::Iterator it; + for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) { + if ( (*it).id() == key.id() ) { + mData->keys.remove( key ); + return; + } + } +} + +Key Addressee::key( int type, QString customTypeString ) const +{ + Key::List::ConstIterator it; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++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 ) +{ + detach(); + mData->keys = list; +} + +Key::List Addressee::keys() const +{ + return mData->keys; +} + +Key::List Addressee::keys( int type, QString customTypeString ) const +{ + Key::List list; + + Key::List::ConstIterator it; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++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; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return Key(); +} + +QString Addressee::asString() const +{ + return "Smith, agent Smith..."; +} + +void Addressee::dump() const +{ + kdDebug(5700) << "Addressee {" << endl; + + kdDebug(5700) << " Uid: '" << uid() << "'" << endl; + + --DEBUG-- + + kdDebug(5700) << " Emails {" << endl; + const QStringList e = emails(); + QStringList::ConstIterator it; + for( it = e.begin(); it != e.end(); ++it ) { + kdDebug(5700) << " " << (*it) << endl; + } + kdDebug(5700) << " }" << endl; + + kdDebug(5700) << " PhoneNumbers {" << endl; + const PhoneNumber::List p = phoneNumbers(); + PhoneNumber::List::ConstIterator it2; + for( it2 = p.begin(); it2 != p.end(); ++it2 ) { + kdDebug(5700) << " Type: " << int((*it2).type()) << " Number: " << (*it2).number() << endl; + } + kdDebug(5700) << " }" << endl; + + const Address::List a = addresses(); + Address::List::ConstIterator it3; + for( it3 = a.begin(); it3 != a.end(); ++it3 ) { + (*it3).dump(); + } + + kdDebug(5700) << " Keys {" << endl; + const Key::List k = keys(); + Key::List::ConstIterator it4; + for( it4 = k.begin(); it4 != k.end(); ++it4 ) { + kdDebug(5700) << " Type: " << int((*it4).type()) << + " Key: " << (*it4).textData() << + " CustomString: " << (*it4).customTypeString() << endl; + } + kdDebug(5700) << " }" << endl; + + kdDebug(5700) << "}" << endl; +} + + +void Addressee::insertAddress( const Address &address ) +{ + if ( address.isEmpty() ) + return; + + detach(); + mData->empty = false; + + Address::List::Iterator it; + for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) { + if ( (*it).id() == address.id() ) { + *it = address; + return; + } + } + + mData->addresses.append( address ); +} + +void Addressee::removeAddress( const Address &address ) +{ + detach(); + + Address::List::Iterator it; + for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) { + if ( (*it).id() == address.id() ) { + mData->addresses.remove( it ); + return; + } + } +} + +Address Addressee::address( int type ) const +{ + Address address( type ); + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++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 mData->addresses; +} + +Address::List Addressee::addresses( int type ) const +{ + Address::List list; + + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + list.append( *it ); + } + } + + return list; +} + +Address Addressee::findAddress( const QString &id ) const +{ + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return Address(); +} + +void Addressee::insertCategory( const QString &c ) +{ + detach(); + mData->empty = false; + + if ( mData->categories.findIndex( c ) != -1 ) return; + + mData->categories.append( c ); +} + +void Addressee::removeCategory( const QString &c ) +{ + detach(); + + QStringList::Iterator it = mData->categories.find( c ); + if ( it == mData->categories.end() ) return; + + mData->categories.remove( it ); +} + +bool Addressee::hasCategory( const QString &c ) const +{ + return ( mData->categories.findIndex( c ) != -1 ); +} + +void Addressee::setCategories( const QStringList &c ) +{ + detach(); + mData->empty = false; + + mData->categories = c; +} + +QStringList Addressee::categories() const +{ + return mData->categories; +} + +void Addressee::insertCustom( const QString &app, const QString &name, + const QString &value ) +{ + if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) return; + + detach(); + mData->empty = false; + + QString qualifiedName = app + "-" + name + ":"; + + QStringList::Iterator it; + for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + (*it) = qualifiedName + value; + return; + } + } + + mData->custom.append( qualifiedName + value ); +} + +void Addressee::removeCustom( const QString &app, const QString &name) +{ + detach(); + + QString qualifiedName = app + "-" + name + ":"; + + QStringList::Iterator it; + for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + mData->custom.remove( it ); + return; + } + } +} + +QString Addressee::custom( const QString &app, const QString &name ) const +{ + QString qualifiedName = app + "-" + name + ":"; + QString value; + + QStringList::ConstIterator it; + for( it = mData->custom.constBegin(); it != mData->custom.constEnd(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + value = (*it).mid( (*it).find( ":" ) + 1 ); + break; + } + } + + return value; +} + +void Addressee::setCustoms( const QStringList &l ) +{ + detach(); + mData->empty = false; + + mData->custom = l; +} + +QStringList Addressee::customs() const +{ + return mData->custom; +} + +void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName, + QString &email) +{ + // This is a simplified version of KPIM::splitAddress(). + + fullName = ""; + email = ""; + if ( rawEmail.isEmpty() ) + return; // KPIM::AddressEmpty; + + // The code works on 8-bit strings, so convert the input to UTF-8. + QCString address = rawEmail.utf8(); + + QCString displayName; + QCString addrSpec; + QCString 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.stripWhiteSpace(); + comment = comment.stripWhiteSpace(); + addrSpec = addrSpec.stripWhiteSpace(); + + 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 ] == '"' && fullName[ len - 1 ] == '"' ) + fullName = fullName.mid( 1, len - 2 ); +} + +void Addressee::setResource( Resource *resource ) +{ + detach(); + mData->resource = resource; +} + +Resource *Addressee::resource() const +{ + return mData->resource; +} + +void Addressee::setChanged( bool value ) +{ + detach(); + mData->changed = value; +} + +bool Addressee::changed() const +{ + return mData->changed; +} + +void Addressee::setSortMode( KABC::SortMode *mode ) +{ + mSortMode = mode; +} + +bool Addressee::operator< ( const Addressee &addr ) +{ + if ( !mSortMode ) + return false; + else + return mSortMode->lesser( *this, addr ); +} + +QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a ) +{ + if (!a.mData) return s; + + s << a.uid(); + + --STREAMOUT-- + s << a.mData->phoneNumbers; + s << a.mData->addresses; + s << a.mData->emails; + s << a.mData->categories; + s << a.mData->custom; + s << a.mData->keys; + return s; +} + +QDataStream &KABC::operator>>( QDataStream &s, Addressee &a ) +{ + if (!a.mData) + return s; + + a.detach(); + + s >> a.mData->uid; + + --STREAMIN-- + s >> a.mData->phoneNumbers; + s >> a.mData->addresses; + s >> a.mData->emails; + s >> a.mData->categories; + s >> a.mData->custom; + s >> a.mData->keys; + + a.mData->empty = 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 QValueList<L> &list, const QValueList<L> &pattern ) +{ + if ( list.count() != pattern.count() ) + return false; + + for ( uint i = 0; i < list.count(); ++i ) + if ( pattern.find( list[ i ] ) == pattern.end() ) + return false; + + return true; +} + +bool emailsEquals( const QStringList &list, const QStringList &pattern ) +{ + if ( list.count() != pattern.count() ) + return false; + + if ( list.first() != pattern.first() ) + return false; + + QStringList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + if ( pattern.find( *it ) == pattern.end() ) + return false; + + return true; +} diff --git a/kabc/scripts/addressee.src.h b/kabc/scripts/addressee.src.h new file mode 100644 index 000000000..abceb052a --- /dev/null +++ b/kabc/scripts/addressee.src.h @@ -0,0 +1,394 @@ +/* + 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_H +#define KABC_ADDRESSEE_H + +#include <qdatetime.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qvaluelist.h> + +#include <ksharedptr.h> +#include <kurl.h> + +#include "address.h" +#include "agent.h" +#include "geo.h" +#include "key.h" +#include "phonenumber.h" +#include "picture.h" +#include "secrecy.h" +#include "sound.h" +#include "timezone.h" + +namespace KABC { + +class Resource; +class Field; +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: + typedef QValueList<Addressee> List; + typedef QMap<QString, Addressee> Map; + + /** + Construct an empty address book entry. + */ + Addressee(); + ~Addressee(); + + Addressee( const Addressee & ); + Addressee &operator=( const Addressee & ); + + bool operator==( const Addressee & ) const; + bool operator!=( const Addressee & ) const; + + /** + Return, if the address book entry is empty. + */ + bool isEmpty() const; + + /** + Set 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::null the preferred email address is used. + */ + QString fullEmail( const QString &email=QString::null ) 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. + */ + 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. + */ + void insertPhoneNumber( const PhoneNumber &phoneNumber ); + + /** + Remove phone number. If no phone number with the given id exists for this + addresse nothing happens. + */ + void removePhoneNumber( const PhoneNumber &phoneNumber ); + + /** + Return phone number, which matches the given type. + */ + PhoneNumber phoneNumber( int type ) const; + + /** + Return list of all phone numbers. + */ + PhoneNumber::List phoneNumbers() const; + + /** + Return list of phone numbers with a special type. + */ + PhoneNumber::List phoneNumbers( int type ) const; + + /** + Return phone number with the given 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. + */ + void insertKey( const Key &key ); + + /** + Remove a key. If no key with the given id exists for this + addresse nothing happens. + */ + 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. + */ + Key key( int type, QString customTypeString = QString::null ) 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. + */ + Key::List keys( int type, QString customTypeString = QString::null ) const; + + /** + Return key with the given 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. + */ + void insertAddress( const Address &address ); + + /** + Remove address. If no address with the given id exists for this + addresse nothing happens. + */ + void removeAddress( const Address &address ); + + /** + Return address, which matches the given type. + */ + Address address( int type ) const; + + /** + Return list of all addresses. + */ + Address::List addresses() const; + + /** + Return list of addresses with a special type. + */ + Address::List addresses( int type ) const; + + /** + Return address with the given 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) + */ + void insertCustom( const QString &app, const QString &name, + const QString &value ); + + /** + Remove custom entry. + */ + void removeCustom( const QString &app, const QString &name ); + + /** + Return value of custom entry, identified by app and entry name. + */ + 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. + */ + static void parseEmailAddress( const QString &rawEmail, QString &fullName, + QString &email ); + + /** + Debug output. + */ + void dump() const; + + /** + Returns string representation of the addressee. + */ + QString asString() const; + + /** + Set resource where the addressee is from. + */ + void setResource( Resource *resource ); + + /** + Return pointer to resource. + */ + Resource *resource() const; + + /** + Mark addressee as changed. + */ + void setChanged( bool value ); + + /** + Return whether the addressee is changed. + */ + bool changed() const; + + static void setSortMode( KABC::SortMode *mode ); + + bool operator< ( const Addressee &addr ); + + private: + void detach(); + + struct AddresseeData; + mutable KSharedPtr<AddresseeData> mData; + + private: + static AddresseeData* shared_null; + static AddresseeData* makeSharedNull(); + static KABC::SortMode *mSortMode; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Addressee & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Addressee & ); + +} + +#endif diff --git a/kabc/scripts/createisomap.pl b/kabc/scripts/createisomap.pl new file mode 100755 index 000000000..2734db111 --- /dev/null +++ b/kabc/scripts/createisomap.pl @@ -0,0 +1,35 @@ +#!/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"; + } + } +} + +# add some convenience entries which aren't part of the entry.desktop files + +print "Czech Republic\tcz\n"; diff --git a/kabc/scripts/entrylist b/kabc/scripts/entrylist new file mode 100644 index 000000000..7b9b324eb --- /dev/null +++ b/kabc/scripts/entrylist @@ -0,0 +1,84 @@ +# 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,,.asString() +ALE,geographic position,,Geo,geo,,.asString() + +ALFE,title,person,QString,title,Organization +ALFE,role,person in 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,,.asString() + +ALE,logo,,Picture,logo,,.asString() +ALE,photo,,Picture,photo,,.asString() +ALE,sound,,Sound,sound,,.asString() +ALE,agent,,Agent,agent,,.asString() diff --git a/kabc/scripts/field.src.cpp b/kabc/scripts/field.src.cpp new file mode 100644 index 000000000..205ddaa06 --- /dev/null +++ b/kabc/scripts/field.src.cpp @@ -0,0 +1,530 @@ +/* + 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 "field.h" +#include "address.h" + +using namespace KABC; + +class Field::FieldImpl +{ + public: + FieldImpl( int fieldId, int category = 0, + const QString &label = QString::null, + const QString &key = QString::null, + const QString &app = QString::null ) + : 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; } + + private: + int mFieldId; + int mCategory; + + QString mLabel; + QString mKey; + QString mApp; +}; + + +Field::List Field::mAllFields; +Field::List Field::mDefaultFields; +Field::List Field::mCustomFields; + + +Field::Field( FieldImpl *impl ) +{ + mImpl = impl; +} + +Field::~Field() +{ + delete mImpl; +} + +QString Field::label() +{ + switch ( mImpl->fieldId() ) { + --CASELABEL-- + case FieldImpl::CustomField: + return mImpl->label(); + default: + return i18n("Unknown Field"); + } +} + +int Field::category() +{ + return mImpl->category(); +} + +QString Field::categoryLabel( int category ) +{ + switch ( category ) { + case All: + return i18n("All"); + case Frequent: + return i18n("Frequent"); + case Address: + return i18n("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 ( mImpl->fieldId() ) { + --CASEVALUE-- + case FieldImpl::Email: + return a.preferredEmail(); + case FieldImpl::Birthday: + if ( a.birthday().isValid() ) + return a.birthday().date().toString( Qt::ISODate ); + else + return QString::null; + case FieldImpl::Url: + return a.url().prettyURL(); + case FieldImpl::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::null; + } + case FieldImpl::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::null; + } + case FieldImpl::MobilePhone: + return a.phoneNumber( PhoneNumber::Cell ).number(); + case FieldImpl::HomeFax: + return a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ).number(); + case FieldImpl::BusinessFax: + return a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ).number(); + case FieldImpl::CarPhone: + return a.phoneNumber( PhoneNumber::Car ).number(); + case FieldImpl::Isdn: + return a.phoneNumber( PhoneNumber::Isdn ).number(); + case FieldImpl::Pager: + return a.phoneNumber( PhoneNumber::Pager ).number(); + case FieldImpl::HomeAddressStreet: + return a.address( Address::Home ).street(); + case FieldImpl::HomeAddressPostOfficeBox: + return a.address( Address::Home ).postOfficeBox(); + case FieldImpl::HomeAddressLocality: + return a.address( Address::Home ).locality(); + case FieldImpl::HomeAddressRegion: + return a.address( Address::Home ).region(); + case FieldImpl::HomeAddressPostalCode: + return a.address( Address::Home ).postalCode(); + case FieldImpl::HomeAddressCountry: + return a.address( Address::Home ).country(); + case FieldImpl::HomeAddressLabel: + return a.address( Address::Home ).label(); + case FieldImpl::BusinessAddressStreet: + return a.address( Address::Work ).street(); + case FieldImpl::BusinessAddressPostOfficeBox: + return a.address( Address::Work ).postOfficeBox(); + case FieldImpl::BusinessAddressLocality: + return a.address( Address::Work ).locality(); + case FieldImpl::BusinessAddressRegion: + return a.address( Address::Work ).region(); + case FieldImpl::BusinessAddressPostalCode: + return a.address( Address::Work ).postalCode(); + case FieldImpl::BusinessAddressCountry: + return a.address( Address::Work ).country(); + case FieldImpl::BusinessAddressLabel: + return a.address( Address::Work ).label(); + case FieldImpl::CustomField: + return a.custom( mImpl->app(), mImpl->key() ); + default: + return QString::null; + } +} + +bool Field::setValue( KABC::Addressee &a, const QString &value ) +{ + switch ( mImpl->fieldId() ) { + --CASESETVALUE-- + case FieldImpl::MobilePhone: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Cell ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::HomeFax: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::BusinessFax: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::CarPhone: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Car ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::Isdn: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Isdn ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::Pager: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Pager ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::HomeAddressStreet: + { + KABC::Address address = a.address( Address::Home ); + address.setStreet( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressPostOfficeBox: + { + KABC::Address address = a.address( Address::Home ); + address.setPostOfficeBox( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressLocality: + { + KABC::Address address = a.address( Address::Home ); + address.setLocality( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressRegion: + { + KABC::Address address = a.address( Address::Home ); + address.setRegion( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressPostalCode: + { + KABC::Address address = a.address( Address::Home ); + address.setPostalCode( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressCountry: + { + KABC::Address address = a.address( Address::Home ); + address.setCountry( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressLabel: + { + KABC::Address address = a.address( Address::Home ); + address.setLabel( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressStreet: + { + KABC::Address address = a.address( Address::Work ); + address.setStreet( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressPostOfficeBox: + { + KABC::Address address = a.address( Address::Work ); + address.setPostOfficeBox( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressLocality: + { + KABC::Address address = a.address( Address::Work ); + address.setLocality( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressRegion: + { + KABC::Address address = a.address( Address::Work ); + address.setRegion( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressPostalCode: + { + KABC::Address address = a.address( Address::Work ); + address.setPostalCode( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressCountry: + { + KABC::Address address = a.address( Address::Work ); + address.setCountry( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressLabel: + { + KABC::Address address = a.address( Address::Work ); + address.setLabel( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::Birthday: + a.setBirthday( QDate::fromString( value, Qt::ISODate ) ); + return true; + case FieldImpl::CustomField: + a.insertCustom( mImpl->app(), mImpl->key(), value ); + return true; + default: + return false; + } +} + +QString Field::sortKey( const KABC::Addressee &a ) +{ + switch ( mImpl->fieldId() ) { + --CASEVALUE-- + case FieldImpl::Birthday: + if ( a.birthday().isValid() ) { + QDate date = a.birthday().date(); + QString key; + key.sprintf( "%02d-%02d", date.month(), date.day() ); + return key; + } else + return QString( "00-00" ); + default: + return value( a ).lower(); + } +} + +bool Field::isCustom() +{ + return mImpl->fieldId() == FieldImpl::CustomField; +} + +Field::List Field::allFields() +{ + if ( mAllFields.isEmpty() ) { + --CREATEFIELDS-- + } + + return mAllFields; +} + +Field::List Field::defaultFields() +{ + if ( mDefaultFields.isEmpty() ) { + createDefaultField( FieldImpl::FormattedName ); + createDefaultField( FieldImpl::Email ); + } + + return mDefaultFields; +} + +void Field::createField( int id, int category ) +{ + mAllFields.append( new Field( new FieldImpl( id, category ) ) ); +} + +void Field::createDefaultField( int id, int category ) +{ + mDefaultFields.append( new Field( new FieldImpl( id, category ) ) ); +} + +void Field::deleteFields() +{ + Field::List::ConstIterator it; + + for ( it = mAllFields.constBegin(); it != mAllFields.constEnd(); ++it ) { + delete (*it); + } + mAllFields.clear(); + + for ( it = mDefaultFields.constBegin(); it != mDefaultFields.constEnd(); ++it ) { + delete (*it); + } + mDefaultFields.clear(); + + for ( it = mCustomFields.constBegin(); it != mCustomFields.constEnd(); ++it ) { + delete (*it); + } + mCustomFields.clear(); +} + +void Field::saveFields( const QString &identifier, + const Field::List &fields ) +{ + KConfig *cfg = KGlobal::config(); + KConfigGroupSaver( cfg, "KABCFields" ); + + saveFields( cfg, identifier, fields ); +} + +void Field::saveFields( KConfig *cfg, const QString &identifier, + const Field::List &fields ) +{ + QValueList<int> fieldIds; + + int custom = 0; + Field::List::ConstIterator it; + for( it = fields.begin(); it != fields.end(); ++it ) { + fieldIds.append( (*it)->mImpl->fieldId() ); + if( (*it)->isCustom() ) { + QStringList customEntry; + customEntry << (*it)->mImpl->label(); + customEntry << (*it)->mImpl->key(); + customEntry << (*it)->mImpl->app(); + cfg->writeEntry( "KABC_CustomEntry_" + identifier + "_" + + QString::number( custom++ ), customEntry ); + } + } + + cfg->writeEntry( identifier, fieldIds ); +} + +Field::List Field::restoreFields( const QString &identifier ) +{ + KConfig *cfg = KGlobal::config(); + KConfigGroupSaver( cfg, "KABCFields" ); + + return restoreFields( cfg, identifier ); +} + +Field::List Field::restoreFields( KConfig *cfg, const QString &identifier ) +{ + const QValueList<int> fieldIds = cfg->readIntListEntry( identifier ); + + Field::List fields; + + int custom = 0; + QValueList<int>::ConstIterator it; + for( it = fieldIds.begin(); it != fieldIds.end(); ++it ) { + FieldImpl *f = 0; + if ( (*it) == FieldImpl::CustomField ) { + QStringList customEntry = cfg->readListEntry( "KABC_CustomEntry_" + + identifier + "_" + + QString::number( custom++ ) ); + f = new FieldImpl( *it, CustomCategory, customEntry[ 0 ], + customEntry[ 1 ], customEntry[ 2 ] ); + } else { + f = new FieldImpl( *it ); + } + fields.append( new Field( f ) ); + } + + return fields; +} + +bool Field::equals( Field *field ) +{ + bool sameId = ( mImpl->fieldId() == field->mImpl->fieldId() ); + + if ( !sameId ) return false; + + if ( mImpl->fieldId() != FieldImpl::CustomField ) return true; + + return mImpl->key() == field->mImpl->key(); +} + +Field *Field::createCustomField( const QString &label, int category, + const QString &key, const QString &app ) +{ + Field *field = new Field( new FieldImpl( FieldImpl::CustomField, + category | CustomCategory, + label, key, app ) ); + mCustomFields.append( field ); + + return field; +} diff --git a/kabc/scripts/makeaddressee b/kabc/scripts/makeaddressee new file mode 100755 index 000000000..cbc69543a --- /dev/null +++ b/kabc/scripts/makeaddressee @@ -0,0 +1,215 @@ +#!/usr/bin/perl + +my $srcdir; +$srcdir = `dirname $0` || die "Can't determine \$srcdir."; +chomp $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, ">../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, ">../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] $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] == mData->$entryNames[$i] ) return;\n"; + print CPP_OUT " detach();\n mData->empty = false;\n"; + print CPP_OUT " mData->$entryNames[$i] = $entryNames[$i];\n}\n\n"; + + print CPP_OUT "$entryTypes[$i] Addressee::$entryNames[$i]() const\n{\n"; + print CPP_OUT " return mData->$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 i18n(\"$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 ( mData->$entryNames[$i] != a.mData->$entryNames[$i] &&\n"; + print CPP_OUT " !( mData->$entryNames[$i].isEmpty() && a.mData->$entryNames[$i].isEmpty() ) ) {\n"; + print CPP_OUT " kdDebug(5700) << \"$entryNames[$i] differs\" << endl;\n"; + print CPP_OUT " return false;\n"; + print CPP_OUT " }\n"; + } else { + print CPP_OUT " if ( mData->$entryNames[$i] != a.mData->$entryNames[$i] ) {\n"; + print CPP_OUT " kdDebug(5700) << \"$entryNames[$i] differs\" << endl;\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.mData->$entryNames[$i];\n"; + } + } + } elsif (/--STREAMIN--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /A/ ) { + print CPP_OUT " s >> a.mData->$entryNames[$i];\n"; + } + } + } elsif (/--DEBUG--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /A/ ) { next; } + print CPP_OUT " kdDebug(5700) << \" " . ucfirst($entryNames[$i]); + print CPP_OUT ": '\" << $entryNames[$i]()$entryDebug[$i] << \"'\" << endl;\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, ">../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 FieldImpl::" . 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 FieldImpl::" . 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 FieldImpl::" . 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( FieldImpl::" . 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 000000000..1e90d9c81 --- /dev/null +++ b/kabc/secrecy.cpp @@ -0,0 +1,100 @@ +/* + 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 <klocale.h> + +#include "secrecy.h" + +using namespace KABC; + +Secrecy::Secrecy( int type ) + : mType( type ) +{ +} + +bool Secrecy::operator==( const Secrecy &s ) const +{ + return ( mType == s.mType ); +} + +bool Secrecy::operator!=( const Secrecy &s ) const +{ + return !( *this == s ); +} + +bool Secrecy::isValid() const +{ + return mType != Invalid; +} + +void Secrecy::setType( int type ) +{ + mType = type; +} + +int Secrecy::type() const +{ + return mType; +} + +Secrecy::TypeList Secrecy::typeList() +{ + static TypeList list; + + if ( list.isEmpty() ) + list << Public << Private << Confidential; + + return list; +} + +QString Secrecy::typeLabel( int type ) +{ + switch ( type ) { + case Public: + return i18n( "Public" ); + break; + case Private: + return i18n( "Private" ); + break; + case Confidential: + return i18n( "Confidential" ); + break; + default: + return i18n( "Unknown type" ); + break; + } +} + +QString Secrecy::asString() const +{ + return typeLabel( mType ); +} + +QDataStream &KABC::operator<<( QDataStream &s, const Secrecy &secrecy ) +{ + return s << secrecy.mType; +} + +QDataStream &KABC::operator>>( QDataStream &s, Secrecy &secrecy ) +{ + s >> secrecy.mType; + + return s; +} diff --git a/kabc/secrecy.h b/kabc/secrecy.h new file mode 100644 index 000000000..e76592fa5 --- /dev/null +++ b/kabc/secrecy.h @@ -0,0 +1,100 @@ +/* + 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 <qvaluelist.h> + +#include <kdelibs_export.h> + +namespace KABC { + +class KABC_EXPORT Secrecy +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Secrecy & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Secrecy & ); + +public: + typedef QValueList<int> TypeList; + + /** + * Secrecy types + * + * @li Public - for public access + * @li Private - only private access + * @li Confidential - access for confidential persons + */ + enum Types { + Public, + Private, + Confidential, + Invalid + }; + + /** + * Constructor. + * + * @param type The secrecy type, see Types. + */ + Secrecy( int type = Invalid ); + + bool operator==( const Secrecy & ) const; + bool operator!=( const Secrecy & ) const; + + /** + Returns if the Secrecy object has a valid value. + */ + bool isValid() const; + + /** + * Sets the type, see Types. + */ + void setType( int type ); + + /** + * Returns the type, see Types. + */ + int type() const; + + /** + * Returns a list of all available secrecy types. + */ + static TypeList typeList(); + + /** + * Returns a translated label for a given secrecy type. + */ + static QString typeLabel( int type ); + + /** + * For debug. + */ + QString asString() const; + +private: + int mType; +}; + +KABC_EXPORT QDataStream& operator<<( QDataStream &s, const Secrecy &secrecy ); +KABC_EXPORT QDataStream& operator>>( QDataStream &s, Secrecy &secrecy ); + +} +#endif diff --git a/kabc/sortmode.cpp b/kabc/sortmode.cpp new file mode 100644 index 000000000..c21a871cb --- /dev/null +++ b/kabc/sortmode.cpp @@ -0,0 +1,79 @@ +/* + 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 <kabc/field.h> + +#include "sortmode.h" + +using namespace KABC; + +NameSortMode::NameSortMode() + : mNameType( FormattedName ), mAscendingOrder( true ), d( 0 ) +{ + mNameType = FormattedName; +} + +NameSortMode::NameSortMode( NameType type, bool ascending ) + : mNameType( type ), mAscendingOrder( ascending ), d( 0 ) +{ +} + +bool NameSortMode::lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const +{ + bool lesser = false; + + switch ( 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 ( !mAscendingOrder ) + lesser = !lesser; + + return lesser; +} + +FieldSortMode::FieldSortMode( KABC::Field *field, bool ascending ) + : mField( field ), mAscendingOrder( ascending ), d( 0 ) +{ +} + +bool FieldSortMode::lesser( const KABC::Addressee &first, const KABC::Addressee &second ) const +{ + if ( !mField ) + return false; + else { + bool lesser = QString::localeAwareCompare( mField->value( first ), mField->value( second ) ) < 0; + if ( !mAscendingOrder ) + lesser = !lesser; + + return lesser; + } +} diff --git a/kabc/sortmode.h b/kabc/sortmode.h new file mode 100644 index 000000000..aaec96bd4 --- /dev/null +++ b/kabc/sortmode.h @@ -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. +*/ + +#ifndef KABC_SORTMODE_H +#define KABC_SORTMODE_H + +#include <kdelibs_export.h> + +#include <kabc/addressee.h> + +namespace KABC { + +/** + @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: + /** + 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; +}; + +class KABC_EXPORT NameSortMode : public SortMode +{ + public: + enum NameType + { + FormattedName, + FamilyName, + GivenName + }; + + /** + 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 true for ascending sort, false for descending. + */ + NameSortMode( NameType type, bool ascending = true ); + + /** + Returns whether the first contact is 'smaller' then the second. + */ + virtual bool lesser( const KABC::Addressee&, const KABC::Addressee& ) const; + + private: + NameType mNameType; + bool mAscendingOrder; + + class NameSortModePrivate; + NameSortModePrivate *d; +}; + +class KABC_EXPORT FieldSortMode : public SortMode +{ + public: + /** + Constructor. + + Creates a FieldSortMethod with the specified field. + + @param field The field. + @param ascending true for ascending sort, false for descending. + */ + FieldSortMode( KABC::Field *field, bool ascending = true ); + + /** + Returns whether the first contact is 'smaller' then the second. + */ + virtual bool lesser( const KABC::Addressee&, const KABC::Addressee& ) const; + + private: + KABC::Field *mField; + bool mAscendingOrder; + + class FieldSortModePrivate; + FieldSortModePrivate *d; +}; + +} + +#endif diff --git a/kabc/sound.cpp b/kabc/sound.cpp new file mode 100644 index 000000000..48f12e4f1 --- /dev/null +++ b/kabc/sound.cpp @@ -0,0 +1,118 @@ +/* + 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 <qdatastream.h> + +using namespace KABC; + +Sound::Sound() + : mIntern( false ) +{ +} + +Sound::Sound( const QString &url ) + : mUrl( url ), mIntern( false ) +{ +} + +Sound::Sound( const QByteArray &data ) + : mData( data ), mIntern( true ) +{ +} + +Sound::~Sound() +{ +} + +bool Sound::operator==( const Sound &s ) const +{ + if ( mIntern != s.mIntern ) return false; + + if ( mIntern ) { + if ( mData != s.mData ) + return false; + } else { + if ( mUrl != s.mUrl ) + return false; + } + + return true; +} + +bool Sound::operator!=( const Sound &s ) const +{ + return !( s == *this ); +} + +void Sound::setUrl( const QString &url ) +{ + mUrl = url; + mIntern = false; +} + +void Sound::setData( const QByteArray &data ) +{ + mData = data; + mIntern = true; +} + +bool Sound::isIntern() const +{ + return mIntern; +} + +bool Sound::isEmpty() const +{ + return (!mIntern) && mUrl.isEmpty(); + +} + +QString Sound::url() const +{ + return mUrl; +} + +QByteArray Sound::data() const +{ + return mData; +} + +QString Sound::asString() const +{ + if ( mIntern ) + return "intern sound"; + else + return mUrl; +} + +QDataStream &KABC::operator<<( QDataStream &s, const Sound &sound ) +{ + return s << sound.mIntern << sound.mUrl; +// return s << sound.mIntern << sound.mUrl << sound.mData; +} + +QDataStream &KABC::operator>>( QDataStream &s, Sound &sound ) +{ + s >> sound.mIntern >> sound.mUrl; +// s >> sound.mIntern >> sound.mUrl >> sound.mData; + return s; +} diff --git a/kabc/sound.h b/kabc/sound.h new file mode 100644 index 000000000..db488530e --- /dev/null +++ b/kabc/sound.h @@ -0,0 +1,153 @@ +/* + 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 <qcstring.h> +#include <qstring.h> + +#include <kdelibs_export.h> + +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()->writeBlock( sound.data() ); + * tmp.close(); + * KAudioPlayer::play( tmp.name() ); + * } else if(!sound.url().isEmpty()) { + * QString tmpFile; + * if(!KIO::NetAccess::download(KURL(themeURL.url()), tmpFile, NULL)) + * { + * KMessageBox::error(0L, + * KIO::NetAccess::lastErrorString(), + * i18n("Failed to download sound file"), + * KMessageBox::Notify + * ); + * return; + * } + * KAudioPlayer::play( tmpFile ); + * } + * \endcode + * + * Unfortunetly 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: + + /** + * Consturctor. Creates an empty object. + */ + Sound(); + + /** + * Consturctor. + * + * @param url A URL that describes the position of the sound file. + */ + Sound( const QString &url ); + + /** + * Consturctor. + * + * @param data The raw data of the sound. + */ + Sound( const QByteArray &data ); + + /** + * Destructor. + */ + ~Sound(); + + + bool operator==( const Sound & ) const; + bool operator!=( const Sound & ) 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 ); + + /** + * Test if this sound file has been set. + * Just does: !isIntern() && url.isEmpty() + * @since 3.4 + */ + 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 asString() const; + +private: + QString mUrl; + QByteArray mData; + + int mIntern; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Sound & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Sound & ); + +} +#endif diff --git a/kabc/stdaddressbook.cpp b/kabc/stdaddressbook.cpp new file mode 100644 index 000000000..95c222bf3 --- /dev/null +++ b/kabc/stdaddressbook.cpp @@ -0,0 +1,203 @@ +/* + 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 <stdlib.h> + +#include <kapplication.h> +#include <kcrash.h> +#include <kdebug.h> +#include <klocale.h> +#include <kresources/manager.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kstaticdeleter.h> + +#include "resource.h" + +#include "stdaddressbook.h" + +using namespace KABC; + +StdAddressBook *StdAddressBook::mSelf = 0; +bool StdAddressBook::mAutomaticSave = true; + +static KStaticDeleter<StdAddressBook> addressBookDeleter; + +QString StdAddressBook::fileName() +{ + return locateLocal( "data", "kabc/std.vcf" ); +} + +QString StdAddressBook::directoryName() +{ + return locateLocal( "data", "kabc/stdvcf" ); +} + +void StdAddressBook::handleCrash() +{ +} + +StdAddressBook *StdAddressBook::self() +{ + if ( !mSelf ) + addressBookDeleter.setObject( mSelf, new StdAddressBook ); + + return mSelf; +} + +StdAddressBook *StdAddressBook::self( bool asynchronous ) +{ + if ( !mSelf ) + addressBookDeleter.setObject( mSelf, new StdAddressBook( asynchronous ) ); + + return mSelf; +} + +StdAddressBook::StdAddressBook() + : AddressBook( "" ) +{ + kdDebug(5700) << "StdAddressBook::StdAddressBook()" << endl; + + init( false ); +} + +StdAddressBook::StdAddressBook( bool asynchronous ) + : AddressBook( "" ) +{ + kdDebug(5700) << "StdAddressBook::StdAddressBook( bool )" << endl; + + init( asynchronous ); +} + +StdAddressBook::~StdAddressBook() +{ + if ( mAutomaticSave ) + saveAll(); +} + +void StdAddressBook::init( bool asynchronous ) +{ + KRES::Manager<Resource> *manager = resourceManager(); + + KRES::Manager<Resource>::ActiveIterator it; + for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) { + (*it)->setAddressBook( this ); + if ( !(*it)->open() ) { + error( QString( "Unable to open resource '%1'!" ).arg( (*it)->resourceName() ) ); + continue; + } + connect( *it, SIGNAL( loadingFinished( Resource* ) ), + this, SLOT( resourceLoadingFinished( Resource* ) ) ); + connect( *it, SIGNAL( savingFinished( Resource* ) ), + this, SLOT( resourceSavingFinished( Resource* ) ) ); + + connect( *it, SIGNAL( loadingError( Resource*, const QString& ) ), + this, SLOT( resourceLoadingError( Resource*, const QString& ) ) ); + connect( *it, SIGNAL( savingError( Resource*, const QString& ) ), + this, SLOT( resourceSavingError( Resource*, const QString& ) ) ); + } + + Resource *res = standardResource(); + if ( !res ) { + res = manager->createResource( "file" ); + if ( res ) + addResource( res ); + else + kdDebug(5700) << "No resource available!!!" << endl; + } + + setStandardResource( res ); + manager->writeConfig(); + + if ( asynchronous ) + asyncLoad(); + else + load(); +} + +bool StdAddressBook::saveAll() +{ + kdDebug(5700) << "StdAddressBook::saveAll()" << endl; + bool ok = true; + + deleteRemovedAddressees(); + + KRES::Manager<Resource>::ActiveIterator it; + KRES::Manager<Resource> *manager = resourceManager(); + for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) { + if ( !(*it)->readOnly() && (*it)->isOpen() ) { + Ticket *ticket = requestSaveTicket( *it ); + if ( !ticket ) { + error( i18n( "Unable to save to resource '%1'. It is locked." ) + .arg( (*it)->resourceName() ) ); + return false; + } + + if ( !AddressBook::save( ticket ) ) { + ok = false; + releaseSaveTicket( ticket ); + } + } + } + + return ok; +} + +bool StdAddressBook::save() +{ + kdDebug(5700) << "StdAddressBook::save()" << endl; + + if ( mSelf ) + return mSelf->saveAll(); + else + return true; +} + +void StdAddressBook::close() +{ + addressBookDeleter.destructObject(); +} + +void StdAddressBook::setAutomaticSave( bool enable ) +{ + mAutomaticSave = enable; +} + +bool StdAddressBook::automaticSave() +{ + return mAutomaticSave; +} + +// should get const for 4.X +Addressee StdAddressBook::whoAmI() +{ + KConfig config( "kabcrc" ); + config.setGroup( "General" ); + + return findByUid( config.readEntry( "WhoAmI" ) ); +} + +void StdAddressBook::setWhoAmI( const Addressee &addr ) +{ + KConfig config( "kabcrc" ); + config.setGroup( "General" ); + + config.writeEntry( "WhoAmI", addr.uid() ); +} diff --git a/kabc/stdaddressbook.h b/kabc/stdaddressbook.h new file mode 100644 index 000000000..fb4afa28b --- /dev/null +++ b/kabc/stdaddressbook.h @@ -0,0 +1,153 @@ +/* + 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_STDADDRESSBOOK_H +#define KABC_STDADDRESSBOOK_H + +#include "addressbook.h" + +namespace KABC { + +/** + Standard KDE address book + + This class provides access to the standard KDE address book shared by all + applications. + + It's implemented as a singleton. Use self() to get the address book + object. On the first self() call the address book also gets loaded. + + Example: + + \code + KABC::AddressBook *ab = KABC::StdAddressBook::self(); + + AddressBook::Ticket *ticket = ab->requestSaveTicket(); + + if ( ticket ) { + KABC::AddressBook::Iterator it; + for ( it = ab->begin(); it != ab->end(); ++it ) { + kdDebug() << "UID=" << (*it).uid() << endl; + + // do some other stuff + } + + KABC::StdAddressBook::save( ticket ); + } + \endcode +*/ +class KABC_EXPORT StdAddressBook : public AddressBook +{ + public: + + /** + Destructor. + */ + ~StdAddressBook(); + + /** + Returns the standard addressbook object. It also loads all resources of + the users standard address book synchronously. + */ + static StdAddressBook *self(); + + /** + This is the same as above, but with specified behaviour of resource loading. + + @param asynchronous When true, the resources are loaded asynchronous, that + means you have the data foremost the addressBookChanged() + signal has been emitted. So connect to this signal when + using this method! + */ + static StdAddressBook *self( bool asynchronous ); + + /** + Saves the standard address book to disk. + + @deprecated Use AddressBook::save( Ticket* ) instead + */ + static bool save() KDE_DEPRECATED; + + /** + @deprecated There is no need to call this function anymore. + */ + static void handleCrash() KDE_DEPRECATED; + + /** + Returns the default file name for vcard-based addressbook + */ + static QString fileName(); + + /** + Returns the default directory name for vcard-based addressbook + */ + static QString directoryName(); + + /** + Sets the automatic save property of the address book. + + @param state If true, the address book is saved automatically + at destruction time, otherwise you have to call + AddressBook::save( Ticket* ). + */ + static void setAutomaticSave( bool state ); + + /** + Closes the address book. Depending on automaticSave() it will + save the address book first. + */ + static void close(); + + /** + Returns whether the address book is saved at destruction time. + See also setAutomaticSave(). + */ + static bool automaticSave(); + + /** + Returns the contact, that is associated with the owner of the + address book. This contact should be used by other programs + to access user specific data. + */ + Addressee whoAmI(); + + /** + Sets the users contact. See whoAmI() for more information. + + @param addr The users contact. + */ + void setWhoAmI( const Addressee &addr ); + + protected: + StdAddressBook(); + StdAddressBook( bool asynchronous ); + + void init( bool asynchronous ); + bool saveAll(); + + private: + static StdAddressBook *mSelf; + static bool mAutomaticSave; +}; + +} + +#endif + diff --git a/kabc/tests/Makefile.am b/kabc/tests/Makefile.am new file mode 100644 index 000000000..99d410a2e --- /dev/null +++ b/kabc/tests/Makefile.am @@ -0,0 +1,55 @@ +# Make sure $(all_includes) remains last! +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc -I$(top_srcdir)/kab \ + -I$(srcdir)/../vcardparser/ -I$(srcdir)/../vcard/include \ + -I$(srcdir)/../vcard/include/generated \ + -I$(srcdir)/../vcardparser $(all_includes) +LDADD = ../libkabc.la + +METASOURCES = AUTO + +check_PROGRAMS = testlock testldapclient + +testlock_LDFLAGS = $(all_libraries) +testlock_SOURCES = testlock.cpp + +testldapclient_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testldapclient_SOURCES = testldapclient.cpp + +EXTRA_PROGRAMS = testkabc testkabcdlg testdistlist bigread bigwrite testdb \ + testaddressee testaddresseelist testaddressfmt kabcargl testaddresslineedit + +testkabc_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testkabc_SOURCES = testkabc.cpp + +testaddressee_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testaddressee_SOURCES = testaddressee.cpp + +testaddresseelist_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testaddresseelist_SOURCES = testaddresseelist.cpp + +testaddressfmt_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testaddressfmt_SOURCES = testaddressfmt.cpp + +testkabcdlg_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testkabcdlg_SOURCES = testkabcdlg.cpp + +testdistlist_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testdistlist_SOURCES = testdistlist.cpp + +testaddresslineedit_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testaddresslineedit_SOURCES = testaddresslineedit.cpp + +bigread_LDFLAGS = $(all_libraries) $(KDE_RPATH) +bigread_LDADD = ../libkabc.la $(top_builddir)/kabc/plugins/file/libkabc_file.la +bigread_SOURCES = bigread.cpp + +bigwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH) +bigwrite_LDADD = ../libkabc.la $(top_builddir)/kabc/plugins/file/libkabc_file.la +bigwrite_SOURCES = bigwrite.cpp + +testdb_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testdb_SOURCES = testdb.cpp + +kabcargl_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kabcargl_SOURCES = kabcargl.cpp + diff --git a/kabc/tests/bigread.cpp b/kabc/tests/bigread.cpp new file mode 100644 index 000000000..e64bafef8 --- /dev/null +++ b/kabc/tests/bigread.cpp @@ -0,0 +1,65 @@ +#include <sys/times.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "addressbook.h" +#include "vcardformat.h" +#include "plugins/file/resourcefile.h" +#if 0 +#include "resourcesql.h" +#endif + +using namespace KABC; + +int main(int argc,char **argv) +{ + KAboutData aboutData("bigread","BigReadKabc","0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + + KApplication app( false, false ); + + AddressBook ab; + + ResourceFile r( "my.kabc", "vcard2" ); + ab.addResource( &r ); + +#if 0 + ResourceSql rsql( &ab, "root", "kde4ever", "localhost" ); + ab.addResource( &rsql ); +#endif + + struct tms start; + + times( &start ); + +#if 0 + kdDebug() << "utime : " << int( start.tms_utime ) << endl; + kdDebug() << "stime : " << int( start.tms_stime ) << endl; + kdDebug() << "cutime: " << int( start.tms_cutime ) << endl; + kdDebug() << "cstime: " << int( start.tms_cstime ) << endl; +#endif + + kdDebug() << "Start load" << endl; + ab.load(); + kdDebug() << "Finished load" << endl; + + struct tms end; + + times( &end ); + +#if 0 + kdDebug() << "utime : " << int( end.tms_utime ) << endl; + kdDebug() << "stime : " << int( end.tms_stime ) << endl; + kdDebug() << "cutime: " << int( end.tms_cutime ) << endl; + kdDebug() << "cstime: " << int( end.tms_cstime ) << endl; +#endif + + kdDebug() << "UTime: " << int( end.tms_utime ) - int( start.tms_utime ) << endl; + kdDebug() << "STime: " << int( end.tms_stime ) - int( start.tms_stime ) << endl; + +// ab.dump(); +} diff --git a/kabc/tests/bigwrite.cpp b/kabc/tests/bigwrite.cpp new file mode 100644 index 000000000..90013a157 --- /dev/null +++ b/kabc/tests/bigwrite.cpp @@ -0,0 +1,70 @@ +#include <sys/times.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "addressbook.h" +#include "vcardformat.h" +#include "plugins/file/resourcefile.h" + +using namespace KABC; + +int main(int argc,char **argv) +{ + KAboutData aboutData("bigwrite","BigWriteKabc","0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + + KApplication app( false, false ); + + AddressBook ab; + ResourceFile r( "my.kabc", "vcard" ); + ab.addResource( &r ); + + for( int i = 0; i < 5000; ++i ) { + Addressee a; + a.setGivenName( "number" + QString::number( i ) ); + a.setFamilyName( "Name" ); + a.insertEmail( QString::number( i ) + "@domain" ); + + ab.insertAddressee( a ); + } + printf( "\n" ); + + Ticket *t = ab.requestSaveTicket( &r ); + if ( t ) { + struct tms start; + + times( &start ); + +#if 0 + kdDebug() << "utime : " << int( start.tms_utime ) << endl; + kdDebug() << "stime : " << int( start.tms_stime ) << endl; + kdDebug() << "cutime: " << int( start.tms_cutime ) << endl; + kdDebug() << "cstime: " << int( start.tms_cstime ) << endl; +#endif + + if ( !ab.save( t ) ) { + kdDebug() << "Can't save." << endl; + } + + struct tms end; + + times( &end ); + +#if 0 + kdDebug() << "utime : " << int( end.tms_utime ) << endl; + kdDebug() << "stime : " << int( end.tms_stime ) << endl; + kdDebug() << "cutime: " << int( end.tms_cutime ) << endl; + kdDebug() << "cstime: " << int( end.tms_cstime ) << endl; +#endif + + kdDebug() << "UTime: " << int( end.tms_utime ) - int( start.tms_utime ) << endl; + kdDebug() << "STime: " << int( end.tms_stime ) - int( start.tms_stime ) << endl; + + } else { + kdDebug() << "No ticket for save." << endl; + } +} diff --git a/kabc/tests/kabcargl.cpp b/kabc/tests/kabcargl.cpp new file mode 100644 index 000000000..32251303b --- /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 <qfile.h> +#include <qtextstream.h> +#include <qregexp.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kcmdlineargs.h> +#include <kglobal.h> +#include <kstandarddirs.h> + +#include "stdaddressbook.h" + +using namespace KABC; + +int main(int argc,char **argv) +{ + KAboutData aboutData("kabcargl","Fix broken pre3.0rc3 format","0.1"); + aboutData.addAuthor("Cornelius Schumacher", 0, "schumacher@kde.org"); + + KCmdLineArgs::init(argc,argv,&aboutData); + + KApplication app; + + QString filename = StdAddressBook::fileName(); + + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) { + kdDebug() << "Error opening file '" << filename << "' for reading." << endl; + return 1; + } + + QTextStream t( &f ); + t.setEncoding(QTextStream::UnicodeUTF8); + QString text = t.read(); + f.close(); + + text = QString::fromUtf8( text.local8Bit() ); + text.replace( "\n", "\r\n" ); + + if ( !f.open( IO_WriteOnly ) ) { + kdDebug() << "Error opening file '" << filename << "' for writing." << endl; + return 1; + } + + QTextStream t2( &f ); + t2.setEncoding(QTextStream::UnicodeUTF8); + t2 << text; + f.close(); +} diff --git a/kabc/tests/testaddressee.cpp b/kabc/tests/testaddressee.cpp new file mode 100644 index 000000000..d05c3af24 --- /dev/null +++ b/kabc/tests/testaddressee.cpp @@ -0,0 +1,57 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kstandarddirs.h> + +#include "addressbook.h" +#include "plugins/file/resourcefile.h" +#include "formats/binaryformat.h" +#include "vcardformat.h" +#include "phonenumber.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + { "save", "", 0 }, + { "number", "", 0 }, + KCmdLineLastOption +}; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testaddressee","TestAddressee","0.1"); + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); + + kdDebug() << "Creating a" << endl; + Addressee a; + + kdDebug() << "tick1" << endl; + a.setGivenName("Hans"); + kdDebug() << "tick2" << endl; + a.setPrefix("Dr."); + + kdDebug() << "Creating b" << endl; + Addressee b( a ); + + kdDebug() << "tack1" << endl; + a.setFamilyName("Wurst"); + kdDebug() << "tack2" << endl; + a.setNickName("hansi"); + + kdDebug() << "Creating c" << endl; + Addressee c = a; + + kdDebug() << "tock1" << endl; + c.setGivenName("Eberhard"); + + a.dump(); + b.dump(); + c.dump(); +} diff --git a/kabc/tests/testaddresseelist.cpp b/kabc/tests/testaddresseelist.cpp new file mode 100644 index 000000000..e7cc123f1 --- /dev/null +++ b/kabc/tests/testaddresseelist.cpp @@ -0,0 +1,196 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kstandarddirs.h> + +#include "addressbook.h" +#include "addresseelist.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + { "save", "", 0 }, + { "number", "", 0 }, + KCmdLineLastOption +}; + +int main(int /*argc*/,char /* **argv*/) +{ +/* KAboutData aboutData("testaddresseelist","TestAddresseeList","0.1"); + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); */ + + kdDebug() << "Creating addressees" << endl; + Addressee a, b, c, d, e, f; + a.setGivenName ("Peter"); + a.setFamilyName("Pan"); + a.setFormattedName("Pan, Peter"); + a.setUid("Asdf"); + b.setGivenName ("Phileas"); + b.setFamilyName("Fogg"); + b.setFormattedName("Fogg, Phileas"); + b.setUid("Rsdf"); + c.setGivenName ("Jim"); + c.setFamilyName("Hawkins"); + c.setFormattedName("Hawkins, Jim"); + c.setUid("Fhwn"); + d.setGivenName ("John"); + d.setFamilyName("Silver"); + d.setPrefix ("Long"); + d.setFormattedName("Long John Silver"); + d.setUid("Z2hk"); + e.setGivenName ("Alice"); + e.setFamilyName("Liddel"); + e.setFormattedName("Liddel, Alice"); + e.setUid("kk45"); + f.setGivenName ("Edmond"); + f.setFamilyName("Dantes"); + f.setFormattedName("Dantes, Edmond"); + f.setUid("78ze"); + + kdDebug() << "Adding to list" << endl; + AddresseeList list; + list.append(a); + list.append(b); + list.append(c); + list.append(d); + list.append(e); + list.append(f); + + list.sortBy(FamilyName); + if ( !( (*list.at(0)).uid()=="78ze" + && (*list.at(1)).uid()=="Rsdf" + && (*list.at(2)).uid()=="Fhwn" + && (*list.at(3)).uid()=="kk45" + && (*list.at(4)).uid()=="Asdf" + && (*list.at(5)).uid()=="Z2hk" + ) ) { + kdError() << "SORTING BY FAMILY NAME NOT CORRECT!" << endl; + kdDebug() << "list sorted by family name:" << endl; + list.dump(); + } else { + kdDebug() << "Sorting by family name correct." << endl; + } + list.setReverseSorting(true); + list.sort(); + if ( !( (*list.at(5)).uid()=="78ze" + && (*list.at(4)).uid()=="Rsdf" + && (*list.at(3)).uid()=="Fhwn" + && (*list.at(2)).uid()=="kk45" + && (*list.at(1)).uid()=="Asdf" + && (*list.at(0)).uid()=="Z2hk" + ) ) { + kdError() << "REVERSE SORTING BY FAMILY NAME NOT CORRECT!" << endl; + kdDebug() << "list reverse sorted by family name:" << endl; + list.dump(); + } else { + kdDebug() << "Reverse sorting by family name correct." << endl; + } + + list.setReverseSorting(false); + list.sortBy(FormattedName); + if ( !( (*list.at(0)).uid()=="78ze" + && (*list.at(1)).uid()=="Rsdf" + && (*list.at(2)).uid()=="Fhwn" + && (*list.at(3)).uid()=="kk45" + && (*list.at(4)).uid()=="Z2hk" + && (*list.at(5)).uid()=="Asdf" + ) ) { + kdError() << "SORTING BY FORMATTED NAME NOT CORRECT!" << endl; + kdDebug() << "list sorted by formatted name:" << endl; + list.dump(); + } else { + kdDebug() << "Sorting by formatted name correct." << endl; + } + list.setReverseSorting(true); + list.sort(); + if ( !( (*list.at(5)).uid()=="78ze" + && (*list.at(4)).uid()=="Rsdf" + && (*list.at(3)).uid()=="Fhwn" + && (*list.at(2)).uid()=="kk45" + && (*list.at(1)).uid()=="Z2hk" + && (*list.at(0)).uid()=="Asdf" + ) ) { + kdError() << "REVERSE SORTING BY FORMATTED NAME NOT CORRECT!" << endl; + kdDebug() << "list reverse sorted by formatted name:" << endl; + list.dump(); + } else { + kdDebug() << "Reverse sorting by formatted name correct." << endl; + } + + + list.setReverseSorting(false); + list.sortBy(Uid); + if ( !( (*list.at(0)).uid()=="78ze" + && (*list.at(1)).uid()=="Asdf" + && (*list.at(2)).uid()=="Fhwn" + && (*list.at(3)).uid()=="Rsdf" + && (*list.at(4)).uid()=="Z2hk" + && (*list.at(5)).uid()=="kk45" + ) ) { + kdError() << "SORTING BY UID NOT CORRECT!" << endl; + kdDebug() << "list sorted by Uid:" << endl; + list.dump(); + } else { + kdDebug() << "Sorting by Uid correct." << endl; + } + list.setReverseSorting(true); + list.sortBy(Uid); + if ( !( (*list.at(5)).uid()=="78ze" + && (*list.at(4)).uid()=="Asdf" + && (*list.at(3)).uid()=="Fhwn" + && (*list.at(2)).uid()=="Rsdf" + && (*list.at(1)).uid()=="Z2hk" + && (*list.at(0)).uid()=="kk45" + ) ) { + kdError() << "REVERSE SORTING BY UID NOT CORRECT!" << endl; + kdDebug() << "list sorted by Uid:" << endl; + list.dump(); + } else { + kdDebug() << "Reverse sorting by Uid correct." << endl; + } + + // zero, one or two entries might give errors in a poor sorting + // implementation + kdDebug() << "sorting empty list" << endl; + AddresseeList list2; + list2.sort(); + + kdDebug() << "sorting one entry list" << endl; + list2.append(a); + list2.sort(); + + kdDebug() << "sorting two entry list" << endl; + list2.append(f); + list2.setReverseSorting(false); + list2.sort(); + if ( !( (*list2.at(0)).uid()=="78ze" + && (*list2.at(1)).uid()=="Asdf" + ) ) { + kdError() << "SORTING BY FORMATTED NAME IN A TWO ENTRY LIST NOT CORRECT!" << endl; + kdDebug() << "list sorted by formatted name, two entries:" << endl; + list2.dump(); + } else { + kdDebug() << "Sorting by FormattedName in a two entry list correct." << endl; + } + list2.setReverseSorting(true); + list2.sort(); + if ( !( (*list2.at(1)).uid()=="78ze" + && (*list2.at(0)).uid()=="Asdf" + ) ) { + kdError() << "REVERSE SORTING BY FORMATTED NAME IN A TWO ENTRY LIST NOT CORRECT!" << endl; + kdDebug() << "list reverse sorted by formatted name, two entries:" << endl; + list2.dump(); + } else { + kdDebug() << "Reverse sorting by FormattedName in a two entry list correct." << endl; + } + +} + + diff --git a/kabc/tests/testaddressfmt.cpp b/kabc/tests/testaddressfmt.cpp new file mode 100644 index 000000000..f422ab692 --- /dev/null +++ b/kabc/tests/testaddressfmt.cpp @@ -0,0 +1,63 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kstandarddirs.h> + +#include "addressbook.h" +#include "address.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + { "save", "", 0 }, + { "number", "", 0 }, + KCmdLineLastOption +}; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testaddressfmt","TestAddressFormat","0.1"); + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + Address a; + a.setStreet("Lummerlandstr. 1"); + a.setPostalCode("12345"); + a.setLocality("Lummerstadt"); + a.setCountry ("Germany"); + + Address b; + b.setStreet("457 Foobar Ave"); + b.setPostalCode("1A2B3C"); + b.setLocality("Nervousbreaktown"); + b.setRegion("DC"); + b.setCountry("United States of America"); + + Address c; + c.setStreet("Lummerlandstr. 1"); + c.setPostalCode("12345"); + c.setLocality("Lummerstadt"); + c.setCountry ("Deutschland"); + + Address d; + d.setStreet("Lummerlandstr. 1"); + d.setPostalCode("12345"); + d.setLocality("Lummerstadt"); + d.setCountry (""); + + qDebug( "-------------------------------------\nShould have german address formatting, local country formatting\n" ); + qDebug( a.formattedAddress("Jim Knopf").latin1() ); + qDebug( "-------------------------------------\nShould have US address formatting, local country formatting\n" ); + qDebug( b.formattedAddress("Huck Finn").latin1() ); + qDebug( "-------------------------------------\nShould have german address formatting, local country formatting\n" ); + qDebug( c.formattedAddress("Jim Knopf").latin1() ); + qDebug( "-------------------------------------\nShould have local address formatting, local country formatting\n" ); + qDebug( d.formattedAddress("Jim Knopf").latin1() ); +} + + diff --git a/kabc/tests/testaddresslineedit.cpp b/kabc/tests/testaddresslineedit.cpp new file mode 100644 index 000000000..70c07b446 --- /dev/null +++ b/kabc/tests/testaddresslineedit.cpp @@ -0,0 +1,29 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "addresslineedit.h" + +using namespace KABC; + +int main( int argc,char **argv ) +{ + KAboutData aboutData( "testaddresslineedit", + I18N_NOOP( "Test Address LineEdit" ), "0.1" ); + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication app; + + AddressLineEdit *lineEdit = new AddressLineEdit( 0 ); + + lineEdit->show(); + app.setMainWidget( lineEdit ); + + QObject::connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); + + app.exec(); + + delete lineEdit; +} diff --git a/kabc/tests/testdb.cpp b/kabc/tests/testdb.cpp new file mode 100644 index 000000000..f94397a62 --- /dev/null +++ b/kabc/tests/testdb.cpp @@ -0,0 +1,33 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "addressbook.h" +#include "vcardformat.h" +#include "resourcesql.h" + +using namespace KABC; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testdb","TestKabcDB","0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + +// KApplication app( false, false ); + KApplication app; + + AddressBook ab; + + ResourceSql r( &ab, "root", "kde4ever", "localhost" ); + if ( ! r.open() ) { + kdDebug() << "Failed to open resource." << endl; + } + + r.load( &ab ); + + r.close(); + + ab.dump(); +} diff --git a/kabc/tests/testdistlist.cpp b/kabc/tests/testdistlist.cpp new file mode 100644 index 000000000..a81f8c0dc --- /dev/null +++ b/kabc/tests/testdistlist.cpp @@ -0,0 +1,59 @@ +#include <qwidget.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "stdaddressbook.h" + +#include "distributionlisteditor.h" +#include "distributionlist.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + {"list <listname>", I18N_NOOP("Show distribution list with name <listname>"), 0}, + KCmdLineLastOption +}; + + +int main(int argc,char **argv) +{ + KAboutData aboutData("testdistlist",I18N_NOOP("Test Distribution Lists"),"0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->isSet("list")) { + QString name = args->getOption("list"); + + DistributionListManager *manager = + new DistributionListManager( StdAddressBook::self() ); + manager->load(); + DistributionList *list = manager->list( name ); + if ( !list ) { + kdDebug() << "No list with name '" << name << "'" << endl; + return 1; + } else { + kdDebug() << "RESULT: " << list->emails().join(", ") << endl; + return 0; + } + } + + DistributionListEditor *editor = + new DistributionListEditor( StdAddressBook::self(), 0 ); + + editor->show(); + app.setMainWidget(editor); + + QObject::connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); + + app.exec(); + + delete editor; +} diff --git a/kabc/tests/testkabc.cpp b/kabc/tests/testkabc.cpp new file mode 100644 index 000000000..15fa11c44 --- /dev/null +++ b/kabc/tests/testkabc.cpp @@ -0,0 +1,62 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kstandarddirs.h> + +#include <qfile.h> +#include <qimage.h> + +#include "geo.h" +#include "secrecy.h" +#include "stdaddressbook.h" +#include "timezone.h" +#include "key.h" +#include "agent.h" +#include "vcardconverter.h" + +using namespace KABC; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testkabc",I18N_NOOP("TestKabc"),"0.1"); + KCmdLineArgs::init(argc, argv, &aboutData); + + KApplication app( false, false ); + AddressBook *ab = StdAddressBook::self(); + +#define READ + +#ifdef READ + AddressBook::Iterator it; + for ( it = ab->begin(); it != ab->end(); ++it ) { + QString vcard; + VCardConverter converter; + converter.addresseeToVCard( *it, vcard ); + kdDebug() << "card=" << vcard << endl; + } +#else + Addressee addr; + + addr.setGivenName("Tobias"); + addr.setFamilyName("Koenig"); + + + Picture pic; + QImage img; + img.load("/home/tobias/test.png"); +/* + pic.setData(img); + pic.setType(QImage::imageFormat("/home/tobias/test.png")); +*/ + pic.setUrl("http://www.mypict.de"); + addr.setLogo( pic ); + + ab->insertAddressee( addr ); + + StdAddressBook::save(); +#endif + + return 0; +} diff --git a/kabc/tests/testkabcdlg.cpp b/kabc/tests/testkabcdlg.cpp new file mode 100644 index 000000000..c497a9ead --- /dev/null +++ b/kabc/tests/testkabcdlg.cpp @@ -0,0 +1,45 @@ +#include <qwidget.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include "addresseedialog.h" + +using namespace KABC; + +static const KCmdLineOptions options[] = +{ + {"multiple", I18N_NOOP("Allow selection of multiple addressees"), 0}, + KCmdLineLastOption +}; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testkabcdlg",I18N_NOOP("TestKabc"),"0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->isSet("multiple")) { + Addressee::List al = AddresseeDialog::getAddressees( 0 ); + Addressee::List::ConstIterator it; + kdDebug() << "Selected Addressees:" << endl; + for( it = al.begin(); it != al.end(); ++it ) { + kdDebug() << " " << (*it).fullEmail() << endl; + } + } else { + Addressee a = AddresseeDialog::getAddressee( 0 ); + + if ( !a.isEmpty() ) { + kdDebug() << "Selected Addressee:" << endl; + a.dump(); + } else { + kdDebug() << "No Addressee selected." << endl; + } + } +} diff --git a/kabc/tests/testldapclient.cpp b/kabc/tests/testldapclient.cpp new file mode 100644 index 000000000..f4616d16c --- /dev/null +++ b/kabc/tests/testldapclient.cpp @@ -0,0 +1,161 @@ +/* This file is part of the KDE project + Copyright (C) 2005 David Faure <faure@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 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. +*/ + +#include "testldapclient.h" + +#include <kapplication.h> +#include <kdebug.h> +#include <kcmdlineargs.h> + +#include <qeventloop.h> + +#include <assert.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) +{ + KApplication::disableAutoDcopRegistration(); + KCmdLineArgs::init(argc,argv,"testldapclient", 0, 0, 0, 0); + KApplication app; + + TestLDAPClient test; + test.setup(); + test.runAll(); + test.cleanup(); + kdDebug() << "All tests OK." << endl; + return 0; +} + +void TestLDAPClient::setup() +{ +} + +void TestLDAPClient::runAll() +{ + testIntevation(); +} + +bool TestLDAPClient::check(const QString& txt, QString a, QString b) +{ + if (a.isEmpty()) + a = QString::null; + if (b.isEmpty()) + b = QString::null; + if (a == b) { + kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl; + } + else { + kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl; + cleanup(); + exit(1); + } + return true; +} + +void TestLDAPClient::cleanup() +{ + mClient = 0; +} + +void TestLDAPClient::testIntevation() +{ + kdDebug() << k_funcinfo << endl; + mClient = new LdapClient( this ); + + mClient->setHost( "ca.intevation.de" ); + mClient->setPort( "389" ); + mClient->setBase( "o=Intevation GmbH,c=de" ); + + // Same list as in kaddressbook's ldapsearchdialog + QStringList attrs; + attrs << "l" << "Company" << "co" << "department" << "description" << "mail" << "facsimileTelephoneNumber" << "cn" << "homePhone" << "mobile" << "o" << "pager" << "postalAddress" << "st" << "street" << "title" << "uid" << "telephoneNumber" << "postalCode" << "objectClass"; + // the list from ldapclient.cpp + //attrs << "cn" << "mail" << "givenname" << "sn" << "objectClass"; + mClient->setAttrs( attrs ); + + // Taken from LdapSearch + //QString mSearchText = QString::fromUtf8( "Till" ); + //QString filter = QString( "&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))(|(cn=%1*)(mail=%2*)(givenName=%3*)(sn=%4*))" ) + // .arg( mSearchText ).arg( mSearchText ).arg( mSearchText ).arg( mSearchText ); + + // For some reason a fromUtf8 broke the search for me (no results). + // But this certainly looks fishy, it might break on non-utf8 systems. + QString filter = "&(|(objectclass=person)(objectclass=groupofnames)(mail=*))(|(cn=*Ägypten MDK*)(sn=*Ägypten MDK*))"; + + connect( mClient, SIGNAL( result( const KABC::LdapObject& ) ), + this, SLOT( slotLDAPResult( const KABC::LdapObject& ) ) ); + connect( mClient, SIGNAL( done() ), + this, SLOT( slotLDAPDone() ) ); + connect( mClient, SIGNAL( error( const QString& ) ), + this, SLOT( slotLDAPError( const QString& ) ) ); + mClient->startQuery( filter ); + kapp->eventLoop()->enterLoop(); + delete mClient; mClient = 0; +} + +// from kaddressbook... ugly though... +static QString asUtf8( const QByteArray &val ) +{ + if ( val.isEmpty() ) + return QString::null; + + const char *data = val.data(); + + //QString::fromUtf8() bug workaround + if ( data[ val.size() - 1 ] == '\0' ) + return QString::fromUtf8( data, val.size() - 1 ); + else + return QString::fromUtf8( data, val.size() ); +} + +static QString join( const KABC::LdapAttrValue& lst, const QString& sep ) +{ + QString res; + bool already = false; + for ( KABC::LdapAttrValue::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + if ( already ) + res += sep; + already = TRUE; + res += asUtf8( *it ); + } + return res; +} + +void TestLDAPClient::slotLDAPResult( const KABC::LdapObject& obj ) +{ + QString cn = join( obj.attrs[ "cn" ], ", " ); + kdDebug() << " cn:" << cn << endl; + assert( !obj.attrs[ "mail" ].isEmpty() ); + QString mail = join( obj.attrs[ "mail" ], ", " ); + kdDebug() << " mail:" << mail << endl; + assert( mail.contains( '@' ) ); +} + +void TestLDAPClient::slotLDAPError( const QString& err ) +{ + kdDebug() << k_funcinfo << err << endl; + ::exit( 1 ); +} + +void TestLDAPClient::slotLDAPDone() +{ + kdDebug() << k_funcinfo << endl; + kapp->eventLoop()->exitLoop(); +} + +#include "testldapclient.moc" diff --git a/kabc/tests/testldapclient.h b/kabc/tests/testldapclient.h new file mode 100644 index 000000000..583ead073 --- /dev/null +++ b/kabc/tests/testldapclient.h @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2005 David Faure <faure@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 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 TESTLDAPCLIENT_H +#define TESTLDAPCLIENT_H + +#include <qobject.h> + +#include "../ldapclient.h" +typedef KABC::LdapClient LdapClient; + +class TestLDAPClient : public QObject +{ + Q_OBJECT + +public: + TestLDAPClient() {} + void setup(); + void runAll(); + void cleanup(); + + // tests + void testIntevation(); + +private slots: + void slotLDAPResult( const KABC::LdapObject& ); + void slotLDAPError( const QString& ); + void slotLDAPDone(); + +private: + bool check(const QString& txt, QString a, QString b); + + LdapClient* mClient; +}; + +#endif diff --git a/kabc/tests/testlock.cpp b/kabc/tests/testlock.cpp new file mode 100644 index 000000000..c922c7a7e --- /dev/null +++ b/kabc/tests/testlock.cpp @@ -0,0 +1,206 @@ +/* + 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 "testlock.h" + +#include "stdaddressbook.h" + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kdirwatch.h> + +#include <kmessagebox.h> +#include <kdialog.h> + +#include <qwidget.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qlistview.h> +#include <qdir.h> + +#include <iostream> + +#include <sys/types.h> +#include <unistd.h> + +using namespace KABC; + +LockWidget::LockWidget( const QString &identifier ) +{ + QVBoxLayout *topLayout = new QVBoxLayout( this ); + topLayout->setMargin( KDialog::marginHint() ); + topLayout->setSpacing( KDialog::spacingHint() ); + + if ( identifier.isEmpty() ) { + mLock = 0; + } else { + mLock = new Lock( identifier ); + + int pid = getpid(); + + QLabel *pidLabel = new QLabel( "Process ID: " + QString::number( pid ), + this ); + topLayout->addWidget( pidLabel ); + + QHBoxLayout *identifierLayout = new QHBoxLayout( topLayout ); + + QLabel *resourceLabel = new QLabel( "Identifier:", this ); + identifierLayout->addWidget( resourceLabel ); + + QLabel *resourceIdentifier = new QLabel( identifier, this ); + identifierLayout->addWidget( resourceIdentifier ); + + mStatus = new QLabel( "Status: Unlocked", this ); + topLayout->addWidget( mStatus ); + + QPushButton *button = new QPushButton( "Lock", this ); + topLayout->addWidget( button ); + connect( button, SIGNAL( clicked() ), SLOT( lock() ) ); + + button = new QPushButton( "Unlock", this ); + topLayout->addWidget( button ); + connect( button, SIGNAL( clicked() ), SLOT( unlock() ) ); + } + + mLockView = new QListView( this ); + topLayout->addWidget( mLockView ); + mLockView->addColumn( "Lock File" ); + mLockView->addColumn( "PID" ); + mLockView->addColumn( "Locking App" ); + + updateLockView(); + + QPushButton *quitButton = new QPushButton( "Quit", this ); + topLayout->addWidget( quitButton ); + connect( quitButton, SIGNAL( clicked() ), SLOT( close() ) ); + + KDirWatch *watch = KDirWatch::self(); + connect( watch, SIGNAL( dirty( const QString & ) ), + SLOT( updateLockView() ) ); + connect( watch, SIGNAL( created( const QString & ) ), + SLOT( updateLockView() ) ); + connect( watch, SIGNAL( deleted( const QString & ) ), + SLOT( updateLockView() ) ); + watch->addDir( Lock::locksDir() ); + watch->startScan(); +} + +LockWidget::~LockWidget() +{ + delete mLock; +} + +void LockWidget::updateLockView() +{ + mLockView->clear(); + + QDir dir( Lock::locksDir() ); + + QStringList files = dir.entryList( "*.lock" ); + + QStringList::ConstIterator it; + for( it = files.begin(); it != files.end(); ++it ) { + if ( *it == "." || *it == ".." ) continue; + + QString app; + int pid; + if ( !Lock::readLockFile( dir.filePath( *it ), pid, app ) ) { + kdWarning() << "Unable to open lock file '" << *it << "'" << endl; + } else { + new QListViewItem( mLockView, *it, QString::number( pid ), app ); + } + } +} + +void LockWidget::lock() +{ + if ( !mLock->lock() ) { + KMessageBox::sorry( this, mLock->error() ); + } else { + mStatus->setText( "Status: Locked" ); + } +} + +void LockWidget::unlock() +{ + if ( !mLock->unlock() ) { + KMessageBox::sorry( this, mLock->error() ); + } else { + mStatus->setText( "Status: Unlocked" ); + } +} + + +static const KCmdLineOptions options[] = +{ + { "a", 0, 0 }, + { "addressbook", "Standard address book", 0 }, + { "d", 0, 0 }, + { "diraddressbook", "Standard address book directory resource", 0 }, + { "+identifier", "Identifier of resource to be locked, e.g. filename", 0 }, + KCmdLineLastOption +}; + +int main(int argc,char **argv) +{ + KAboutData aboutData("testlock",I18N_NOOP("Test libkabc Lock"),"0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + QString identifier; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if ( args->count() == 1 ) { + identifier = args->arg( 0 ); + } else if ( args->count() != 0 ) { + std::cerr << "Usage: testlock <identifier>" << std::endl; + return 1; + } + + if ( args->isSet( "addressbook" ) ) { + if ( args->count() == 1 ) { + std::cerr << "Ignoring resource identifier" << std::endl; + } + identifier = StdAddressBook::fileName(); + } + + if ( args->isSet( "diraddressbook" ) ) { + if ( args->count() == 1 ) { + std::cerr << "Ignoring resource identifier" << std::endl; + } + identifier = StdAddressBook::directoryName(); + } + + LockWidget mainWidget( identifier ); + + kapp->setMainWidget( &mainWidget ); + mainWidget.show(); + + return app.exec(); +} + +#include "testlock.moc" diff --git a/kabc/tests/testlock.h b/kabc/tests/testlock.h new file mode 100644 index 000000000..16c128bf1 --- /dev/null +++ b/kabc/tests/testlock.h @@ -0,0 +1,51 @@ +/* + 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_TESTLOCK_H +#define KABC_TESTLOCK_H + +#include "lock.h" + +#include <qwidget.h> + +class QLabel; +class QListView; + +class KABC_EXPORT LockWidget : public QWidget +{ + Q_OBJECT + public: + LockWidget( const QString &identifier ); + ~LockWidget(); + + protected slots: + void lock(); + void unlock(); + + void updateLockView(); + + private: + KABC::Lock *mLock; + + QLabel *mStatus; + QListView *mLockView; +}; + +#endif diff --git a/kabc/timezone.cpp b/kabc/timezone.cpp new file mode 100644 index 000000000..ddb28e526 --- /dev/null +++ b/kabc/timezone.cpp @@ -0,0 +1,85 @@ +/* + 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 <qdatastream.h> + +#include "timezone.h" + +using namespace KABC; + +TimeZone::TimeZone() : + mOffset( 0 ), mValid( false ) +{ +} + +TimeZone::TimeZone( int offset ) : + mOffset( offset ), mValid( true ) +{ +} + +void TimeZone::setOffset( int offset ) +{ + mOffset = offset; + mValid = true; +} + +int TimeZone::offset() const +{ + return mOffset; +} + +bool TimeZone::isValid() const +{ + return mValid; +} + +bool TimeZone::operator==( const TimeZone &t ) const +{ + if ( !t.isValid() && !isValid() ) return true; + if ( !t.isValid() || !isValid() ) return false; + if ( t.mOffset == mOffset ) return true; + return false; +} + +bool TimeZone::operator!=( const TimeZone &t ) const +{ + if ( !t.isValid() && !isValid() ) return false; + if ( !t.isValid() || !isValid() ) return true; + if ( t.mOffset != mOffset ) return true; + return false; +} + +QString TimeZone::asString() const +{ + return QString::number( mOffset ); +} + +QDataStream &KABC::operator<<( QDataStream &s, const TimeZone &zone ) +{ + return s << zone.mOffset; +} + +QDataStream &KABC::operator>>( QDataStream &s, TimeZone &zone ) +{ + s >> zone.mOffset; + zone.mValid = true; + + return s; +} diff --git a/kabc/timezone.h b/kabc/timezone.h new file mode 100644 index 000000000..d3cc00d8e --- /dev/null +++ b/kabc/timezone.h @@ -0,0 +1,89 @@ +/* + 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_TIMEZONE_H +#define KABC_TIMEZONE_H + +#include <qstring.h> + +#include <kdelibs_export.h> + +namespace KABC { + +/** + * @short Time zone information. + * + * This class stores information about a time zone. + */ +class KABC_EXPORT TimeZone +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const TimeZone & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, TimeZone & ); + +public: + + /** + * Construct invalid time zone. + */ + TimeZone(); + + /** + * Construct time zone. + * + * @param offset Offset in minutes relative to UTC. + */ + TimeZone( int offset ); + + /** + * Set time zone offset relative to UTC. + * + * @param offset Offset in minutes. + */ + void setOffset( int offset ); + + /** + * Return offset in minutes relative to UTC. + */ + int offset() const; + + /** + * Return, if this time zone object is valid. + */ + bool isValid() const; + + bool operator==( const TimeZone & ) const; + bool operator!=( const TimeZone & ) const; + + /** + * Return string representation of time zone offset. + */ + QString asString() const; + +private: + int mOffset; // Offset in minutes + + bool mValid; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const TimeZone & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, TimeZone & ); + +} +#endif diff --git a/kabc/vcard/AdrParam.cpp b/kabc/vcard/AdrParam.cpp new file mode 100644 index 000000000..fa46499c3 --- /dev/null +++ b/kabc/vcard/AdrParam.cpp @@ -0,0 +1,126 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardRToken.h> +#include <VCardAdrParam.h> +#include <VCardParam.h> + +using namespace VCARD; + +AdrParam::AdrParam() + : Param() +{ +} + +AdrParam::AdrParam(const AdrParam & x) + : Param(x), + adrTypeList_ (x.adrTypeList_) +{ +} + +AdrParam::AdrParam(const QCString & s) + : Param(s) +{ +} + + AdrParam & +AdrParam::operator = (AdrParam & x) +{ + if (*this == x) return *this; + + adrTypeList_ = x.adrTypeList(); + textParam_ = x.textParam(); + + Param::operator = (x); + return *this; +} + + AdrParam & +AdrParam::operator = (const QCString & s) +{ + Param::operator = (s); + + adrTypeList_.clear(); + textParam_.truncate(0); + + return *this; +} + + bool +AdrParam::operator == (AdrParam & x) +{ + parse(); + + if (!x.textParam().isEmpty()) + return (x.textParam_ == textParam_); + + if (x.adrTypeList().count() != adrTypeList_.count()) + return false; + + QStrListIterator it(x.adrTypeList_); + + for (; it.current(); ++it) + if (!adrTypeList_.find(it.current())) + return false; + + return true; +} + +AdrParam::~AdrParam() +{ +} + + void +AdrParam::_parse() +{ + adrTypeList_.clear(); + + if (strRep_.left(4) != "TYPE") { + textParam_ = strRep_; + return; + } + + if (!strRep_.contains('=')) + return; + + RTokenise(strRep_, ",", adrTypeList_); +} + + void +AdrParam::_assemble() +{ + if (!textParam_.isEmpty()) { + strRep_ = textParam_; + return; + } + + QStrListIterator it(adrTypeList_); + + for (; it.current(); ++it) { + + strRep_ += it.current(); + + if (it.current() != adrTypeList_.last()) + strRep_ += ','; + } +} diff --git a/kabc/vcard/AdrValue.cpp b/kabc/vcard/AdrValue.cpp new file mode 100644 index 000000000..7ecef332a --- /dev/null +++ b/kabc/vcard/AdrValue.cpp @@ -0,0 +1,140 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardRToken.h> +#include <VCardAdrValue.h> +#include <VCardValue.h> +#include <VCardDefines.h> + +using namespace VCARD; + +AdrValue::AdrValue() + : Value() +{ +} + +AdrValue::AdrValue(const AdrValue & x) + : Value(x), + poBox_ (x.poBox_), + extAddress_ (x.extAddress_), + street_ (x.street_), + locality_ (x.locality_), + region_ (x.region_), + postCode_ (x.postCode_), + countryName_ (x.countryName_) +{ +} + +AdrValue::AdrValue(const QCString & s) + : Value(s) +{ +} + + AdrValue & +AdrValue::operator = (AdrValue & x) +{ + if (*this == x) return *this; + + poBox_ = x.poBox_; + extAddress_ = x.extAddress_; + street_ = x.street_; + locality_ = x.locality_; + region_ = x.region_; + postCode_ = x.postCode_; + countryName_ = x.countryName_; + + Value::operator = (x); + return *this; +} + + AdrValue & +AdrValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +AdrValue::operator == (AdrValue & x) +{ + parse(); + x.parse(); + + return ( + poBox_ == x.poBox_ && + extAddress_ == x.extAddress_ && + street_ == x.street_ && + locality_ == x.locality_ && + region_ == x.region_ && + postCode_ == x.postCode_ && + countryName_ == x.countryName_); +} + +AdrValue::~AdrValue() +{ +} + + AdrValue * +AdrValue::clone() +{ + return new AdrValue( *this ); +} + + void +AdrValue::_parse() +{ + vDebug("AdrValue::_parse()"); + + QStrList l; + RTokenise(strRep_, ";", l); + + for (unsigned int i = 0; i < l.count(); i++) { + + switch (i) { + + case 0: poBox_ = l.at(0); break; + case 1: extAddress_ = l.at(1); break; + case 2: street_ = l.at(2); break; + case 3: locality_ = l.at(3); break; + case 4: region_ = l.at(4); break; + case 5: postCode_ = l.at(5); break; + case 6: countryName_ = l.at(6); break; + default: break; + } + } +} + + void +AdrValue::_assemble() +{ + vDebug("AdrValue::_assemble"); + + strRep_ = poBox_; + strRep_ += ";" + extAddress_; + strRep_ += ";" + street_; + strRep_ += ";" + locality_; + strRep_ += ";" + region_; + strRep_ += ";" + postCode_; + strRep_ += ";" + countryName_; +} + diff --git a/kabc/vcard/AgentParam.cpp b/kabc/vcard/AgentParam.cpp new file mode 100644 index 000000000..5625e0071 --- /dev/null +++ b/kabc/vcard/AgentParam.cpp @@ -0,0 +1,103 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardAgentParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +AgentParam::AgentParam() + : Param() +{ +} + +AgentParam::AgentParam(const AgentParam & x) + : Param(x), + refer_ (x.refer_), + uri_ (x.uri_) +{ +} + +AgentParam::AgentParam(const QCString & s) + : Param(s) +{ +} + + AgentParam & +AgentParam::operator = (AgentParam & x) +{ + if (*this == x) return *this; + + refer_ = x.refer_; + uri_ = x.uri_; + + Param::operator = (x); + return *this; +} + + AgentParam & +AgentParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +AgentParam::operator == (AgentParam & x) +{ + parse(); + + if (refer_) + return (x.refer() && uri_ == x.uri_); + + return !x.refer(); +} + +AgentParam::~AgentParam() +{ +} + + void +AgentParam::_parse() +{ + if (strRep_.isEmpty()) { + refer_ = false; + return; + } + + refer_ = true; + uri_ = strRep_; +} + + void +AgentParam::_assemble() +{ + if (!refer_) { + strRep_.truncate(0); + return; + } + + strRep_ = uri_.asString(); + return; +} diff --git a/kabc/vcard/AgentValue.cpp b/kabc/vcard/AgentValue.cpp new file mode 100644 index 000000000..bccde80cf --- /dev/null +++ b/kabc/vcard/AgentValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardAgentValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +AgentValue::AgentValue() + : Value() +{ +} + +AgentValue::AgentValue(const AgentValue & x) + : Value(x) +{ +} + +AgentValue::AgentValue(const QCString & s) + : Value(s) +{ +} + + AgentValue & +AgentValue::operator = (AgentValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + AgentValue & +AgentValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +AgentValue::operator == (AgentValue & x) +{ + x.parse(); + return false; +} + +AgentValue::~AgentValue() +{ +} + + void +AgentValue::_parse() +{ +} + + void +AgentValue::_assemble() +{ +} + diff --git a/kabc/vcard/ClassValue.cpp b/kabc/vcard/ClassValue.cpp new file mode 100644 index 000000000..f01e5a65b --- /dev/null +++ b/kabc/vcard/ClassValue.cpp @@ -0,0 +1,120 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardClassValue.h> + +#include <VCardValue.h> + +#include <kdebug.h> + +using namespace VCARD; + +ClassValue::ClassValue() + : Value() +{ +} + +ClassValue::ClassValue(const ClassValue & x) + : Value(x), + classType_(x.classType_) +{ +} + +ClassValue::ClassValue(const QCString & s) + : Value(s) +{ +} + + ClassValue & +ClassValue::operator = (ClassValue & x) +{ + if (*this == x) return *this; + x.parse(); + + classType_ = x.classType_; + + Value::operator = (x); + return *this; +} + + ClassValue & +ClassValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +ClassValue::operator == (ClassValue & x) +{ + x.parse(); + return ( classType_ == x.classType_ ); +} + +ClassValue::~ClassValue() +{ +} + + ClassValue * +ClassValue::clone() +{ + return new ClassValue( *this ); +} + + void +ClassValue::_parse() +{ + if (qstricmp(strRep_, "PUBLIC") == 0) + classType_ = Public; + + else if (qstricmp(strRep_, "PRIVATE") == 0) + classType_ = Private; + + else if (qstricmp(strRep_, "CONFIDENTIAL") == 0) + classType_ = Confidential; + + else classType_ = Other; +} + + void +ClassValue::_assemble() +{ + switch (classType_) { + + case Public: + strRep_ = "PUBLIC"; + break; + + case Private: + strRep_ = "PRIVATE"; + break; + + case Confidential: + strRep_ = "CONFIDENTIAL"; + break; + + default: + break; + } +} + diff --git a/kabc/vcard/ContentLine.cpp b/kabc/vcard/ContentLine.cpp new file mode 100644 index 000000000..566eb6a79 --- /dev/null +++ b/kabc/vcard/ContentLine.cpp @@ -0,0 +1,302 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qcstring.h> +#include <qstrlist.h> +#include <qregexp.h> + +#include <kdebug.h> + +#include <VCardAdrParam.h> +#include <VCardAgentParam.h> +#include <VCardDateParam.h> +#include <VCardEmailParam.h> +#include <VCardImageParam.h> +#include <VCardSourceParam.h> +#include <VCardTelParam.h> +#include <VCardTextBinParam.h> +#include <VCardTextParam.h> + +#include <VCardAdrValue.h> +#include <VCardAgentValue.h> +#include <VCardDateValue.h> +#include <VCardImageValue.h> +#include <VCardTextValue.h> +#include <VCardTextBinValue.h> +#include <VCardLangValue.h> +#include <VCardNValue.h> +#include <VCardURIValue.h> +#include <VCardSoundValue.h> +#include <VCardClassValue.h> +#include <VCardFloatValue.h> +#include <VCardOrgValue.h> +#include <VCardTelValue.h> +#include <VCardTextListValue.h> +#include <VCardUTCValue.h> +#include <VCardGeoValue.h> + +#include <VCardRToken.h> +#include <VCardContentLine.h> + +#include <VCardEntity.h> +#include <VCardEnum.h> +#include <VCardDefines.h> + +using namespace VCARD; + +ContentLine::ContentLine() + : Entity(), + value_(0), + paramType_( ParamUnknown ), + valueType_( ValueUnknown ), + entityType_( EntityUnknown ) +{ +} + +ContentLine::ContentLine(const ContentLine & x) + : Entity(x), + group_ (x.group_), + name_ (x.name_), + paramList_(x.paramList_), + value_(x.value_->clone()), + paramType_( x.paramType_ ), + valueType_( x.valueType_ ), + entityType_( x.entityType_ ) +{ +} + +ContentLine::ContentLine(const QCString & s) + : Entity(s), + value_(0), + paramType_( ParamUnknown ), + valueType_( ValueUnknown ), + entityType_( EntityUnknown ) +{ +} + + ContentLine & +ContentLine::operator = (ContentLine & x) +{ + if (*this == x) return *this; + + paramList_ = x.paramList(); + value_ = x.value_->clone(); + + Entity::operator = (x); + return *this; +} + + ContentLine & +ContentLine::operator = (const QCString & s) +{ + Entity::operator = (s); + delete value_; + value_ = 0; + return *this; +} + + bool +ContentLine::operator == (ContentLine & x) +{ + x.parse(); + + QPtrListIterator<Param> it(x.paramList()); + + if (!paramList_.find(it.current())) + return false; + + return true; +} + +ContentLine::~ContentLine() +{ + delete value_; + value_ = 0; +} + + void +ContentLine::_parse() +{ + vDebug("parse"); + + // Unqote newlines + strRep_ = strRep_.replace( QRegExp( "\\\\n" ), "\n" ); + + int split = strRep_.find(':'); + + if (split == -1) { // invalid content line + vDebug("No ':'"); + return; + } + + QCString firstPart(strRep_.left(split)); + QCString valuePart(strRep_.mid(split + 1)); + + split = firstPart.find('.'); + + if (split != -1) { + group_ = firstPart.left(split); + firstPart = firstPart.mid(split + 1); + } + + vDebug("Group == " + group_); + vDebug("firstPart == " + firstPart); + vDebug("valuePart == " + valuePart); + + // Now we have the group, the name and param list together and the value. + + QStrList l; + + RTokenise(firstPart, ";", l); + + if (l.count() == 0) {// invalid - no name ! + vDebug("No name for this content line !"); + return; + } + + name_ = l.at(0); + + // Now we have the name, so the rest of 'l' is the params. + // Remove the name part. + l.remove(0u); + + entityType_ = EntityNameToEntityType(name_); + paramType_ = EntityTypeToParamType(entityType_); + + unsigned int i = 0; + + // For each parameter, create a new parameter of the correct type. + + QStrListIterator it(l); + + for (; it.current(); ++it, i++) { + + QCString str = *it; + + split = str.find("="); + if (split < 0 ) { + vDebug("No '=' in parameter."); + continue; + } + + QCString paraName = str.left(split); + QCString paraValue = str.mid(split + 1); + + QStrList paraValues; + RTokenise(paraValue, ",", paraValues); + + QStrListIterator it2( paraValues ); + + for(; it2.current(); ++it2) { + + Param *p = new Param; + p->setName( paraName ); + p->setValue( *it2 ); + + paramList_.append(p); + } + } + + // Create a new value of the correct type. + + valueType_ = EntityTypeToValueType(entityType_); + +// kdDebug(5710) << "valueType: " << valueType_ << endl; + + switch (valueType_) { + + case ValueSound: value_ = new SoundValue; break; + case ValueAgent: value_ = new AgentValue; break; + case ValueAddress: value_ = new AdrValue; break; + case ValueTel: value_ = new TelValue; break; + case ValueTextBin: value_ = new TextBinValue; break; + case ValueOrg: value_ = new OrgValue; break; + case ValueN: value_ = new NValue; break; + case ValueUTC: value_ = new UTCValue; break; + case ValueURI: value_ = new URIValue; break; + case ValueClass: value_ = new ClassValue; break; + case ValueFloat: value_ = new FloatValue; break; + case ValueImage: value_ = new ImageValue; break; + case ValueDate: value_ = new DateValue; break; + case ValueTextList: value_ = new TextListValue; break; + case ValueGeo: value_ = new GeoValue; break; + case ValueText: + case ValueUnknown: + default: value_ = new TextValue; break; + } + + *value_ = valuePart; +} + + void +ContentLine::_assemble() +{ + vDebug("Assemble (argl) - my name is \"" + name_ + "\""); + strRep_.truncate(0); + + QCString line; + + if (!group_.isEmpty()) + line += group_ + '.'; + + line += name_; + + vDebug("Adding parameters"); + ParamListIterator it(paramList_); + + for (; it.current(); ++it) + line += ";" + it.current()->asString(); + + vDebug("Adding value"); + if (value_ != 0) + line += ":" + value_->asString(); + else { + vDebug("No value"); + } + + // Quote newlines + line = line.replace( QRegExp( "\n" ), "\\n" ); + + // Fold lines longer than 72 chars + const int maxLen = 72; + uint cursor = 0; + while( line.length() > ( cursor + 1 ) * maxLen ) { + strRep_ += line.mid( cursor * maxLen, maxLen ); + strRep_ += "\r\n "; + ++cursor; + } + strRep_ += line.mid( cursor * maxLen ); +} + + void +ContentLine::clear() +{ + group_.truncate(0); + name_.truncate(0); + paramList_.clear(); + delete value_; + value_ = 0; + paramType_ = ParamUnknown; + valueType_ = ValueUnknown; + entityType_ = EntityUnknown; +} diff --git a/kabc/vcard/DateParam.cpp b/kabc/vcard/DateParam.cpp new file mode 100644 index 000000000..52af08997 --- /dev/null +++ b/kabc/vcard/DateParam.cpp @@ -0,0 +1,82 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardDateParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +DateParam::DateParam() + : Param() +{ +} + +DateParam::DateParam(const DateParam & x) + : Param(x) +{ +} + +DateParam::DateParam(const QCString & s) + : Param(s) +{ +} + + DateParam & +DateParam::operator = (DateParam & x) +{ + if (*this == x) return *this; + + Param::operator = (x); + return *this; +} + + DateParam & +DateParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +DateParam::operator == (DateParam & x) +{ + x.parse(); + + return false; +} + +DateParam::~DateParam() +{ +} + + void +DateParam::_parse() +{ +} + + void +DateParam::_assemble() +{ +} + diff --git a/kabc/vcard/DateValue.cpp b/kabc/vcard/DateValue.cpp new file mode 100644 index 000000000..c5c5c8554 --- /dev/null +++ b/kabc/vcard/DateValue.cpp @@ -0,0 +1,434 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qregexp.h> + +#include <kdebug.h> + +#include <VCardDefines.h> +#include <VCardDateValue.h> +#include <VCardValue.h> + +using namespace VCARD; + +DateValue::DateValue() + : Value() +{ + vDebug("DateValue::DateValue()"); +} + +DateValue::DateValue( + unsigned int year, + unsigned int month, + unsigned int day, + unsigned int hour, + unsigned int minute, + unsigned int second, + double secFrac, + bool zonePositive, + unsigned int zoneHour, + unsigned int zoneMinute) + : Value (), + year_ (year), + month_ (month), + day_ (day), + hour_ (hour), + minute_ (minute), + second_ (second), + zoneHour_ (zoneHour), + zoneMinute_ (zoneMinute), + secFrac_ (secFrac), + zonePositive_ (zonePositive), + hasTime_(true) +{ + parsed_ = true; + assembled_ = false; +} + +DateValue::DateValue(const QDate & d) + : Value (), + year_ (d.year()), + month_ (d.month()), + day_ (d.day()), + hasTime_(false) +{ + parsed_ = true; + assembled_ = false; +} + +DateValue::DateValue(const QDateTime & d) + : Value (), + year_ (d.date().year()), + month_ (d.date().month()), + day_ (d.date().day()), + hour_ (d.time().hour()), + minute_ (d.time().minute()), + second_ (d.time().second()), + hasTime_(true) +{ + parsed_ = true; + assembled_ = false; +} + +DateValue::DateValue(const DateValue & x) + : Value(x) +{ + year_ = x.year_; + month_ = x.month_; + day_ = x.day_; + hour_ = x.hour_; + minute_ = x.minute_; + second_ = x.second_; + zoneHour_ = x.zoneHour_; + zoneMinute_ = x.zoneMinute_; + secFrac_ = x.secFrac_; + hasTime_ = x.hasTime_; +} + +DateValue::DateValue(const QCString & s) + : Value(s) +{ +} + + DateValue & +DateValue::operator = (DateValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + DateValue & +DateValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +DateValue::operator == (DateValue & x) +{ + x.parse(); + return false; +} + +DateValue::~DateValue() +{ +} + + DateValue * +DateValue::clone() +{ + return new DateValue( *this ); +} + + void +DateValue::_parse() +{ + vDebug("DateValue::_parse()"); + + // date = date-full-year ["-"] date-month ["-"] date-mday + // time = time-hour [":"] time-minute [":"] time-second [":"] + // [time-secfrac] [time-zone] + + int timeSep = strRep_.find('T'); + + QCString dateStr; + QCString timeStr; + + if (timeSep == -1) { + + dateStr = strRep_; + vDebug("Has date string \"" + dateStr + "\""); + + } else { + + dateStr = strRep_.left(timeSep); + vDebug("Has date string \"" + dateStr + "\""); + + timeStr = strRep_.mid(timeSep + 1); + vDebug("Has time string \"" + timeStr + "\""); + } + + /////////////////////////////////////////////////////////////// DATE + + dateStr.replace(QRegExp("-"), ""); + + kdDebug(5710) << "dateStr: " << dateStr << endl; + + year_ = dateStr.left(4).toInt(); + month_ = dateStr.mid(4, 2).toInt(); + day_ = dateStr.right(2).toInt(); + + if (timeSep == -1) { + hasTime_ = false; + return; // No time, done. + } + else + hasTime_ = true; + + /////////////////////////////////////////////////////////////// TIME + + /////////////////////////////////////////////////////////////// ZONE + + int zoneSep = timeStr.find('Z'); + + if (zoneSep != -1 && timeStr.length() - zoneSep > 3) { + + QCString zoneStr(timeStr.mid(zoneSep + 1)); + vDebug("zoneStr == " + zoneStr); + + zonePositive_ = (zoneStr[0] == '+'); + zoneHour_ = zoneStr.mid(1, 2).toInt(); + zoneMinute_ = zoneStr.right(2).toInt(); + + timeStr.remove(zoneSep, timeStr.length() - zoneSep); + } + + //////////////////////////////////////////////////// SECOND FRACTION + + int secFracSep = timeStr.findRev(','); + + if (secFracSep != -1 && zoneSep != -1) { // zoneSep checked to avoid errors. + QCString quirkafleeg = "0." + timeStr.mid(secFracSep + 1, zoneSep); + secFrac_ = quirkafleeg.toDouble(); + } + + /////////////////////////////////////////////////////////////// HMS + + timeStr.replace(QRegExp(":"), ""); + + hour_ = timeStr.left(2).toInt(); + minute_ = timeStr.mid(2, 2).toInt(); + second_ = timeStr.mid(4, 2).toInt(); +} + + void +DateValue::_assemble() +{ + vDebug("DateValue::_assemble"); + + QCString year; + QCString month; + QCString day; + + year.setNum( year_ ); + month.setNum( month_ ); + day.setNum( day_ ); + + if ( month.length() < 2 ) month.prepend( "0" ); + if ( day.length() < 2 ) day.prepend( "0" ); + + strRep_ = year + '-' + month + '-' + day; + + if ( hasTime_ ) { + QCString hour; + QCString minute; + QCString second; + + hour.setNum( hour_ ); + minute.setNum( minute_ ); + second.setNum( second_ ); + + if ( hour.length() < 2 ) hour.prepend( "0" ); + if ( minute.length() < 2 ) minute.prepend( "0" ); + if ( second.length() < 2 ) second.prepend( "0" ); + + strRep_ += 'T' + hour + ':' + minute + ':' + second + 'Z'; + } +} + + unsigned int +DateValue::year() +{ + parse(); + return year_; +} + + unsigned int +DateValue::month() +{ + parse(); + return month_; +} + + unsigned int +DateValue::day() +{ + parse(); + return day_; +} + unsigned int +DateValue::hour() +{ + parse(); + return hour_; +} + + unsigned int +DateValue::minute() +{ + parse(); + return minute_; +} + + unsigned int +DateValue::second() +{ + parse(); + return second_; +} + + double +DateValue::secondFraction() +{ + parse(); + return secFrac_; +} + + bool +DateValue::zonePositive() +{ + parse(); + return zonePositive_; +} + + unsigned int +DateValue::zoneHour() +{ + parse(); + return zoneHour_; +} + + unsigned int +DateValue::zoneMinute() +{ + parse(); + return zoneMinute_; +} + + void +DateValue::setYear(unsigned int i) +{ + year_ = i; + assembled_ = false; +} + + void +DateValue::setMonth(unsigned int i) +{ + month_ = i; + assembled_ = false; +} + + void +DateValue::setDay(unsigned int i) +{ + day_ = i; + assembled_ = false; +} + + void +DateValue::setHour(unsigned int i) +{ + hour_ = i; + assembled_ = false; +} + + void +DateValue::setMinute(unsigned int i) +{ + minute_ = i; + assembled_ = false; +} + + void +DateValue::setSecond(unsigned int i) +{ + second_ = i; + assembled_ = false; +} + + void +DateValue::setSecondFraction(double d) +{ + secFrac_ = d; + assembled_ = false; +} + + void +DateValue::setZonePositive(bool b) +{ + zonePositive_ = b; + assembled_ = false; +} + + void +DateValue::setZoneHour(unsigned int i) +{ + zoneHour_ = i; + assembled_ = false; +} + + void +DateValue::setZoneMinute(unsigned int i) +{ + zoneMinute_ = i; + assembled_ = false; +} + + QDate +DateValue::qdate() +{ + parse(); + QDate d(year_, month_, day_); + return d; +} + + QTime +DateValue::qtime() +{ + parse(); + QTime t(hour_, minute_, second_); +// t.setMs(1 / secFrac_); + return t; +} + + QDateTime +DateValue::qdt() +{ + parse(); + QDateTime dt; + dt.setDate(qdate()); + dt.setTime(qtime()); + return dt; +} + + bool +DateValue::hasTime() +{ + parse(); + return hasTime_; +} + diff --git a/kabc/vcard/EmailParam.cpp b/kabc/vcard/EmailParam.cpp new file mode 100644 index 000000000..8c87477bc --- /dev/null +++ b/kabc/vcard/EmailParam.cpp @@ -0,0 +1,116 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardEmailParam.h> +#include <VCardParam.h> +#include <VCardDefines.h> + +using namespace VCARD; + +EmailParam::EmailParam() + : Param() +{ + vDebug("ctor"); +} + +EmailParam::EmailParam(const EmailParam & x) + : Param(x), + emailType_ (x.emailType_), + pref_ (x.pref_) +{ +} + +EmailParam::EmailParam(const QCString & s) + : Param(s) +{ +} + + EmailParam & +EmailParam::operator = (EmailParam & x) +{ + if (*this == x) return *this; + + emailType_ = x.emailType(); + pref_ = x.pref_; + + Param::operator = (x); + return *this; +} + + EmailParam & +EmailParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +EmailParam::operator == (EmailParam & x) +{ + parse(); + + if (pref_) + return (x.pref_ && x.emailType() == emailType_); + + return !x.pref(); +} + +EmailParam::~EmailParam() +{ +} + + void +EmailParam::_parse() +{ +#if 0 + Param::parseToList(); + + SubParamListIterator it(subParamList_); + + pref_ = true; + emailType_ = ""; + + for (; it.current(); ++it) { + + if (qstricmp(it.current()->name(), "TYPE") == 0) { + emailType_ = it.current()->value(); + continue; + } + + if (qstricmp(it.current()->name(), "PREF") == 0) { + pref_ = true; + } + } +#endif +} + + void +EmailParam::_assemble() +{ + strRep_ = "TYPE="; + strRep_ += emailType_; + + if (pref_) + strRep_ += ",PREF"; +} + diff --git a/kabc/vcard/Entity.cpp b/kabc/vcard/Entity.cpp new file mode 100644 index 000000000..b7d09e08e --- /dev/null +++ b/kabc/vcard/Entity.cpp @@ -0,0 +1,134 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardEntity.h> + +using namespace VCARD; + +Entity::Entity() + : parsed_ (false), + assembled_ (true) +{ + // empty +} + +Entity::Entity(const Entity & e) + : strRep_ (e.strRep_), + parsed_ (e.parsed_), + assembled_ (e.assembled_) +{ + // empty +} + +Entity::Entity(const QCString & s) + : strRep_ (s), + parsed_ (false), + assembled_ (true) +{ + // empty +} + + Entity & +Entity::operator = (const Entity & e) +{ + if (this == &e) return *this; + + strRep_ = e.strRep_; + parsed_ = e.parsed_; + assembled_ = e.assembled_; + + return *this; +} + + Entity & +Entity::operator = (const QCString & s) +{ + strRep_ = s; + parsed_ = false; + assembled_ = true; + + return *this; +} + + bool +Entity::operator == (Entity & e) +{ + return asString() == e.asString(); +} + + bool +Entity::operator != (Entity & e) +{ + return !(*this == e); +} + + bool +Entity::operator == (const QCString & s) +{ + return asString() == s; +} + + bool +Entity::operator != (const QCString & s) +{ + return !(*this == s); +} + +Entity::~Entity() +{ + // empty +} + + QCString +Entity::asString() +{ +// vDebug("Entity::asString()"); + assemble(); + + return strRep_; +} + + void +Entity::parse() +{ +// vDebug( "Entity::parse()" ); + + if (!parsed_) _parse(); + + parsed_ = true; + assembled_ = false; +} + + void +Entity::assemble() +{ +// vDebug( "Entity::assemble()" ); + + if (assembled_) return; + + parse(); + _assemble(); + + assembled_ = true; +} + diff --git a/kabc/vcard/Enum.cpp b/kabc/vcard/Enum.cpp new file mode 100644 index 000000000..cc48b5a57 --- /dev/null +++ b/kabc/vcard/Enum.cpp @@ -0,0 +1,482 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qcstring.h> +#include <ctype.h> + +#include <VCardEnum.h> + +using namespace VCARD; + +// There are 31 possible types, not including extensions. + const QCString +VCARD::paramNames [] = +{ + "NAME", + "PROFILE", + "SOURCE", + "FN", + "N", + "NICKNAME", + "PHOTO", + "BDAY", + "ADR", + "LABEL", + "TEL", + "EMAIL", + "MAILER", + "TZ", + "GEO", + "TITLE", + "ROLE", + "LOGO", + "AGENT", + "ORG", + "CATEGORIES", + "NOTE", + "PRODID", + "REV", + "SORT-STRING", + "SOUND", + "UID", + "URL", + "VERSION", + "CLASS", + "KEY" +}; + + const ParamType +VCARD::paramTypesTable[] = { + ParamNone, // NAME + ParamNone, // PROFILE + ParamSource, // SOURCE + ParamText, // FN + ParamText, // N + ParamText, // NICKNAME + ParamImage, // PHOTO (inline/refer) + ParamDate, // BDAY ("VALUE = "date-time/date) + ParamAddrText, // ADR (adr-param/text-param) + ParamAddrText, // LABEL (adr-param/text-param) + ParamTel, // TEL + ParamEmail, // EMAIL + ParamText, // MAILER + ParamNone, // TZ + ParamNone, // GEO + ParamText, // TITLE + ParamText, // ROLE + ParamImage, // LOGO + ParamAgent, // AGENT + ParamText, // ORG + ParamText, // CATEGORIES + ParamText, // NOTE + ParamNone, // PRODID + ParamDate, // REV + ParamText, // SORT-STRING + ParamSound, // SOUND + ParamNone, // UID + ParamNone, // URL + ParamNone, // VERSION + ParamNone, // CLASS + ParamTextBin, // KEY + ParamTextNS // X +}; + + ParamType +VCARD::EntityTypeToParamType(EntityType e) +{ + ParamType t(ParamUnknown); + + switch (e) { + + //---------------------------------------------------------------// + case EntityAgent: t = ParamAgent; break; + //---------------------------------------------------------------// + case EntitySound: t = ParamSound; break; + //---------------------------------------------------------------// + case EntitySource: t = ParamSource; break; + //---------------------------------------------------------------// + case EntityTelephone: t = ParamTel; break; + //---------------------------------------------------------------// + case EntityEmail: t = ParamEmail; break; + //---------------------------------------------------------------// + case EntityKey: t = ParamTextBin; break; + //---------------------------------------------------------------// + case EntityExtension: t = ParamTextNS; break; + //---------------------------------------------------------------// + case EntityAddress: + case EntityLabel: t = ParamAddrText; break; + //---------------------------------------------------------------// + case EntityBirthday: + case EntityRevision: t = ParamDate; break; + //---------------------------------------------------------------// + case EntityPhoto: + case EntityLogo: t = ParamImage; break; + //---------------------------------------------------------------// + case EntityOrganisation: + case EntityTitle: + case EntityRole: + case EntityFullName: + case EntityMailer: + case EntityN: + case EntitySortString: + case EntityNickname: + case EntityCategories: + case EntityNote: t = ParamText; break; + //---------------------------------------------------------------// + case EntityProductID: + case EntityTimeZone: + case EntityUID: + case EntityURL: + case EntityClass: + case EntityGeo: + case EntityName: + case EntityVersion: + case EntityProfile: + default: t = ParamNone; break; + //---------------------------------------------------------------// + + } + + return t; +} + + ValueType +VCARD::EntityTypeToValueType(EntityType e) +{ + ValueType t(ValueUnknown); + + switch (e) { + + //---------------------------------------------------------------// + case EntitySound: t = ValueSound; break; + //---------------------------------------------------------------// + case EntityAgent: t = ValueAgent; break; + //---------------------------------------------------------------// + case EntityAddress: t = ValueAddress; break; + //---------------------------------------------------------------// + case EntityTelephone: t = ValueTel; break; + //---------------------------------------------------------------// + case EntityKey: t = ValueTextBin; break; + //---------------------------------------------------------------// + case EntityOrganisation: t = ValueOrg; break; + //---------------------------------------------------------------// + case EntityN: t = ValueN; break; + //---------------------------------------------------------------// + case EntityTimeZone: t = ValueUTC; break; + //---------------------------------------------------------------// + case EntityClass: t = ValueClass; break; + //---------------------------------------------------------------// + case EntityGeo: t = ValueGeo; break; + //---------------------------------------------------------------// + case EntitySource: + case EntityURL: t = ValueURI; break; + //---------------------------------------------------------------// + case EntityPhoto: + case EntityLogo: t = ValueImage; break; + //---------------------------------------------------------------// + case EntityBirthday: + case EntityRevision: t = ValueDate; break; + //---------------------------------------------------------------// + case EntityCategories: + case EntityNickname: t = ValueTextList; break; + //---------------------------------------------------------------// + case EntityLabel: + case EntityExtension: + case EntityEmail: + case EntityTitle: + case EntityRole: + case EntityFullName: + case EntityMailer: + case EntityProductID: + case EntityName: + case EntitySortString: + case EntityVersion: + case EntityProfile: + case EntityUID: + case EntityNote: + default: t = ValueText; break; + //---------------------------------------------------------------// + + } + + return t; +} + + QCString +VCARD::EntityTypeToParamName(EntityType e) +{ + if ( e > EntityUnknown ) e = EntityUnknown; + return paramNames[ int( e ) ]; +} + + EntityType +VCARD::EntityNameToEntityType(const QCString & s) +{ + if (s.isEmpty()) return EntityUnknown; + + EntityType t(EntityUnknown); + + switch (s[0]) { + + case 'A': + if (s == "ADR") + t = EntityAddress; + else if (s == "AGENT") + t = EntityAgent; + break; + + case 'B': + if (s == "BDAY") + t = EntityBirthday; + break; + + case 'C': + if (s == "CATEGORIES") + t = EntityCategories; + else if (s == "CLASS") + t = EntityClass; + break; + + case 'E': + if (s == "EMAIL") + t = EntityEmail; + break; + + case 'F': + if (s == "FN") + t = EntityFullName; + break; + + case 'G': + if (s == "GEO") + t = EntityGeo; + break; + + case 'K': + if (s == "KEY") + t = EntityKey; + break; + + case 'L': + if (s == "LABEL") + t = EntityLabel; + else if (s == "LOGO") + t = EntityLogo; + break; + + case 'M': + if (s == "MAILER") + t = EntityMailer; + break; + + case 'N': + if (s == "N") + t = EntityN; + else if (s == "NAME") + t = EntityName; + else if (s == "NICKNAME") + t = EntityNickname; + else if (s == "NOTE") + t = EntityNote; + break; + + case 'O': + if (s == "ORG") + t = EntityOrganisation; + break; + + case 'P': + if (s == "PHOTO") + t = EntityPhoto; + else if (s == "PRODID") + t = EntityProductID; + else if (s == "PROFILE") + t = EntityProfile; + break; + + case 'R': + if (s == "REV") + t = EntityRevision; + else if (s == "ROLE") + t = EntityRole; + break; + + case 'S': + if (s == "SORT-STRING") + t = EntitySortString; + else if (s == "SOUND") + t = EntitySound; + else if (s == "SOURCE") + t = EntitySource; + break; + + case 'T': + if (s == "TEL") + t = EntityTelephone; + else if (s == "TITLE") + t = EntityTitle; + else if (s == "TZ") + t = EntityTimeZone; + break; + + case 'U': + if (s == "UID") + t = EntityUID; + else if (s == "URL") + t = EntityURL; + case 'V': + if (s == "VERSION") + t = EntityVersion; + break; + + case 'X': + if (s.left(2) == "X-") + t = EntityExtension; + break; + + default: + + t = EntityUnknown; + } + + return t; +} + +// The copyright notice below refers to the base64 codec functions used below, +// which are modified from the original sources. + +/* + * Original version Copyright 1988 by The Leland Stanford Junior University + * Copyright 1998 by the University of Washington + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that both the + * above copyright notices and this permission notice appear in supporting + * documentation, and that the name of the University of Washington or The + * Leland Stanford Junior University not be used in advertising or publicity + * pertaining to distribution of the software without specific, written prior + * permission. This software is made available "as is", and + * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY + * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF + * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +static char B64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// the mime base64 disctionary used for decoding +static signed char b64dec[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 30 + -1, -1, -1,-19, -1, -1, -1,-16, -4, -4, // 40 -19 == '+' -16 == '/' + -4, -4, -4, -4, -4, -4, -4, -4, -1, -1, // 50 -4 == '0' + -1, 0, -1, -1, -1, 65, 65, 65, 65, 65, // 60 0 == '=' 65 == 'A' + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, // 70 + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, // 80 + 65, -1, -1, -1, -1, -1, -1, 71, 71, 71, // 90 71 == 'a' + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, // 100 + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, // 110 + 71, 71, 71, -1, -1, -1, -1, -1, -1, -1, // 120 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 130 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 140 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 150 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 170 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 180 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 190 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 200 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 210 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 220 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 230 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 240 + -1, -1, -1, -1, -1, -1, -1 // 250 +}; + + char * +VCARD::decodeBase64(const char * s, unsigned long srcl, unsigned long & len) +{ + register unsigned char c; + register unsigned long e(0); + len = 0; + unsigned const char * src = (unsigned const char *)s; + char * ret = new char[srcl + (srcl / 4 + 1)]; + register char *d = ret; + while (srcl--) { // Critical loop + c = *src++; + int dec = b64dec[c]; + if (dec == -1) continue; + if (c == '=') { + switch (e++) { + case 3: e = 0; break; + case 2: if (*src == '=') break; + default: delete [] ret; ret = 0; return 0; break; + } + continue; + } + c -= dec; + if (e == 0) { *d = c << 2; ++e; continue; } + switch (e) { + case 1: *d |= c >> 4; *++d = c << 4; break; + case 2: *d |= c >> 2; *++d = c << 6; break; + case 3: *d++ |= c; e = 0; continue; break; + } + ++e; + } + len = d - (char *)ret; + return ret; +} + + + char * +VCARD::encodeBase64(const char * src, unsigned long srcl, unsigned long & destl) +{ + register const unsigned char *s = (unsigned char *)src; + register unsigned long i = ((srcl + 2) / 3) * 4; + destl = i += 2 * ((i / 60) + 1); + i = 0; + char * ret = new char[destl]; + register unsigned char *d((unsigned char *)ret); + while (srcl != 0) { // Critical loop + *d++ = B64[s[0] >> 2]; + *d++ = B64[((s[0] << 4) + (--srcl == 0 ? 0 : s[1] >> 4)) & 0x3f]; + *d++ = srcl == 0 ? '=' : + B64[((s[1] << 2) + (--srcl == 0 ? 0 : s[2] >> 6)) & 0x3f]; + *d++ = srcl == 0 ? '=' : B64[s[2] & 0x3f]; + if (srcl != 0) srcl--; + if (++i == 15) { i = 0; *d++ = '\r'; *d++ = '\n'; } + s += 3; + } + *d = '\r'; *++d = '\n'; *++d = '\0'; + return ret; +} + diff --git a/kabc/vcard/FloatValue.cpp b/kabc/vcard/FloatValue.cpp new file mode 100644 index 000000000..15bb664b0 --- /dev/null +++ b/kabc/vcard/FloatValue.cpp @@ -0,0 +1,120 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardFloatValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +FloatValue::FloatValue() + : Value() +{ +} + +FloatValue::FloatValue(float f) + : Value (), + value_ (f) +{ + parsed_ = true; +} + +FloatValue::FloatValue(const FloatValue & x) + : Value(x) +{ + value_ = x.value_; +} + +FloatValue::FloatValue(const QCString & s) + : Value(s) +{ +} + + FloatValue & +FloatValue::operator = (FloatValue & x) +{ + if (*this == x) return *this; + + x.parse(); + value_ = x.value_; + + Value::operator = (x); + return *this; +} + + FloatValue & +FloatValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +FloatValue::operator == (FloatValue & x) +{ + x.parse(); + return (value_ == x.value_); +} + +FloatValue::~FloatValue() +{ +} + + void +FloatValue::_parse() +{ + bool negative(false); + + if (strRep_[0] == '-' || strRep_[1] == '+') { + + if (strRep_[0] == '-') + negative = true; + + strRep_.remove(0, 1); + } + + value_ = strRep_.toFloat(); + if (negative) + value_ = -value_; +} + + void +FloatValue::_assemble() +{ + strRep_ = QCString().setNum(value_); +} + + float +FloatValue::value() +{ + parse(); + return value_; +} + + void +FloatValue::setValue(float f) +{ + parsed_ = true; + value_ = f; +} + diff --git a/kabc/vcard/GeoValue.cpp b/kabc/vcard/GeoValue.cpp new file mode 100644 index 000000000..848890a2c --- /dev/null +++ b/kabc/vcard/GeoValue.cpp @@ -0,0 +1,100 @@ +/* + This file is part of libvcard. + 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 <VCardGeoValue.h> + +#include <VCardValue.h> + +#include <kdebug.h> + +using namespace VCARD; + +GeoValue::GeoValue() + : Value() +{ +} + +GeoValue::GeoValue(const GeoValue & x) + : Value(x), latitude_(x.latitude_), longitude_(x.longitude_) +{ +} + +GeoValue::GeoValue(const QCString & s) + : Value(s) +{ +} + + GeoValue & +GeoValue::operator = (GeoValue & x) +{ + if (*this == x) return *this; + + latitude_ = x.latitude_; + longitude_ = x.longitude_; + + Value::operator = (x); + return *this; +} + + GeoValue & +GeoValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +GeoValue::operator == (GeoValue & x) +{ + x.parse(); + + if ( latitude_ != x.latitude_ ) return false; + if ( longitude_ != x.longitude_ ) return false; + + return true; +} + +GeoValue::~GeoValue() +{ +} + + GeoValue * +GeoValue::clone() +{ + return new GeoValue( *this ); +} + + void +GeoValue::_parse() +{ + int semiColon = strRep_.find( ";" ); + + if ( semiColon == -1 ) // invalid + return; + + latitude_ = strRep_.left( semiColon ).toFloat(); + longitude_ = strRep_.mid( semiColon + 1, strRep_.length() - semiColon ).toFloat(); +} + + void +GeoValue::_assemble() +{ + strRep_.sprintf( "%.6f;%.6f", latitude_, longitude_ ); +} diff --git a/kabc/vcard/ImageParam.cpp b/kabc/vcard/ImageParam.cpp new file mode 100644 index 000000000..c9cf6fdc7 --- /dev/null +++ b/kabc/vcard/ImageParam.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardImageParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +ImageParam::ImageParam() + : Param() +{ +} + +ImageParam::ImageParam(const ImageParam & x) + : Param(x) +{ +} + +ImageParam::ImageParam(const QCString & s) + : Param(s) +{ +} + + ImageParam & +ImageParam::operator = (ImageParam & x) +{ + if (*this == x) return *this; + + Param::operator = (x); + return *this; +} + + ImageParam & +ImageParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +ImageParam::operator == (ImageParam & x) +{ + x.parse(); + return false; +} + +ImageParam::~ImageParam() +{ +} + + void +ImageParam::_parse() +{ +} + + void +ImageParam::_assemble() +{ +} + diff --git a/kabc/vcard/ImageValue.cpp b/kabc/vcard/ImageValue.cpp new file mode 100644 index 000000000..4630fac85 --- /dev/null +++ b/kabc/vcard/ImageValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardImageValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +ImageValue::ImageValue() + : Value() +{ +} + +ImageValue::ImageValue(const ImageValue & x) + : Value(x) +{ +} + +ImageValue::ImageValue(const QCString & s) + : Value(s) +{ +} + + ImageValue & +ImageValue::operator = (ImageValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + ImageValue & +ImageValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +ImageValue::operator == (ImageValue & x) +{ + x.parse(); + return false; +} + +ImageValue::~ImageValue() +{ +} + + void +ImageValue::_parse() +{ +} + + void +ImageValue::_assemble() +{ +} + diff --git a/kabc/vcard/ImgValue.cpp b/kabc/vcard/ImgValue.cpp new file mode 100644 index 000000000..7b961f82e --- /dev/null +++ b/kabc/vcard/ImgValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardImgValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +ImgValue::ImgValue() + : Value() +{ +} + +ImgValue::ImgValue(const ImgValue & x) + : Value(x) +{ +} + +ImgValue::ImgValue(const QCString & s) + : Value(s) +{ +} + + ImgValue & +ImgValue::operator = (ImgValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + ImgValue & +ImgValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +ImgValue::operator == (ImgValue & x) +{ + x.parse(); + return false; +} + +ImgValue::~ImgValue() +{ +} + + void +ImgValue::_parse() +{ +} + + void +ImgValue::_assemble() +{ +} + diff --git a/kabc/vcard/LangValue.cpp b/kabc/vcard/LangValue.cpp new file mode 100644 index 000000000..edf180460 --- /dev/null +++ b/kabc/vcard/LangValue.cpp @@ -0,0 +1,127 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardRToken.h> + +#include <VCardLangValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +LangValue::LangValue() + : Value() +{ +} + +LangValue::LangValue(const LangValue & x) + : Value(x) +{ +} + +LangValue::LangValue(const QCString & s) + : Value(s) +{ +} + + LangValue & +LangValue::operator = (LangValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + LangValue & +LangValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +LangValue::operator == (LangValue & x) +{ + x.parse(); + return false; +} + +LangValue::~LangValue() +{ +} + + void +LangValue::_parse() +{ + QStrList l; + RTokenise(strRep_, "-", l); + + if (l.count() == 0) return; + + primary_ = l.at(0); + + l.remove(0u); + + subtags_ = l; +} + + void +LangValue::_assemble() +{ + strRep_ = primary_; + + QStrListIterator it(subtags_); + + for (; it.current(); ++it) + strRep_ += QCString('-') + it.current(); +} + + QCString +LangValue::primary() +{ + parse(); + return primary_; +} + + QStrList +LangValue::subtags() +{ + parse(); + return subtags_; +} + + void +LangValue::setPrimary(const QCString & s) +{ + parse(); + primary_ = s; +} + + void +LangValue::setSubTags(const QStrList & l) +{ + parse(); + subtags_ = l; +} + diff --git a/kabc/vcard/Makefile.am b/kabc/vcard/Makefile.am new file mode 100644 index 000000000..86306fece --- /dev/null +++ b/kabc/vcard/Makefile.am @@ -0,0 +1,21 @@ +INCLUDES = \ + -I$(srcdir)/include \ + -I$(srcdir)/include/generated \ + $(all_includes) + +### KDE 4.0: either make noinst or rename to something like libkvcard +lib_LTLIBRARIES = libvcard.la + +libvcard_la_SOURCES = vCard-all.cpp +libvcard_la_LDFLAGS = $(all_libraries) +libvcard_la_LIBADD = $(LIB_KDECORE) + +check_PROGRAMS = testwrite testread + +testwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testwrite_LDADD = libvcard.la +testwrite_SOURCES = testwrite.cpp + +testread_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testread_LDADD = libvcard.la +testread_SOURCES = testread.cpp diff --git a/kabc/vcard/NValue.cpp b/kabc/vcard/NValue.cpp new file mode 100644 index 000000000..cdec621c3 --- /dev/null +++ b/kabc/vcard/NValue.cpp @@ -0,0 +1,128 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qstrlist.h> + +#include <VCardRToken.h> +#include <VCardNValue.h> +#include <VCardValue.h> +#include <VCardDefines.h> + +using namespace VCARD; + +NValue::NValue() + : Value() +{ + vDebug("ctor"); +} + +NValue::NValue(const NValue & x) + : Value(x), + family_ (x.family_), + given_ (x.given_), + middle_ (x.middle_), + prefix_ (x.prefix_), + suffix_ (x.suffix_) +{ +} + +NValue::NValue(const QCString & s) + : Value(s) +{ + vDebug("ctor"); +} + + NValue & +NValue::operator = (NValue & x) +{ + if (*this == x) return *this; + + family_ = x.family_; + given_ = x.given_; + middle_ = x.middle_; + prefix_ = x.prefix_; + suffix_ = x.suffix_; + + Value::operator = (x); + return *this; +} + + NValue & +NValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +NValue::operator == (NValue & x) +{ + x.parse(); + + return ( + family_ == x.family_ && + given_ == x.given_ && + middle_ == x.middle_ && + prefix_ == x.prefix_ && + suffix_ == x.suffix_); +} + +NValue::~NValue() +{ +} + + NValue * +NValue::clone() +{ + return new NValue( *this ); +} + + void +NValue::_parse() +{ + QStrList l; + RTokenise(strRep_, ";", l); + + for (unsigned int i = 0; i < l.count(); i++) { + + switch (i) { + case 0: family_ = l.at(0); break; + case 1: given_ = l.at(1); break; + case 2: middle_ = l.at(2); break; + case 3: prefix_ = l.at(3); break; + case 4: suffix_ = l.at(4); break; + default: break; + } + } +} + + void +NValue::_assemble() +{ + strRep_ = family_; + strRep_ += ";" + given_; + strRep_ += ";" + middle_; + strRep_ += ";" + prefix_; + strRep_ += ";" + suffix_; +} + diff --git a/kabc/vcard/OrgValue.cpp b/kabc/vcard/OrgValue.cpp new file mode 100644 index 000000000..c3134c835 --- /dev/null +++ b/kabc/vcard/OrgValue.cpp @@ -0,0 +1,107 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardRToken.h> + +#include <VCardOrgValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +OrgValue::OrgValue() + : Value() +{ +} + +OrgValue::OrgValue(const OrgValue & x) + : Value(x) +{ +} + +OrgValue::OrgValue(const QCString & s) + : Value(s) +{ +} + + OrgValue & +OrgValue::operator = (OrgValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + OrgValue & +OrgValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +OrgValue::operator == (OrgValue & x) +{ + x.parse(); + return false; +} + +OrgValue::~OrgValue() +{ +} + + void +OrgValue::_parse() +{ + RTokenise(strRep_, ";", valueList_); +} + + void +OrgValue::_assemble() +{ + bool first(true); + + QStrListIterator it(valueList_); + + for (; it.current(); ++it) { + if (!first) strRep_ += ';'; + strRep_ += it.current(); + first = false; + } +} + + unsigned int +OrgValue::numValues() +{ + parse(); + return valueList_.count(); +} + + QCString +OrgValue::value(unsigned int i) +{ + parse(); + return valueList_.at(i); +} + diff --git a/kabc/vcard/Param.cpp b/kabc/vcard/Param.cpp new file mode 100644 index 000000000..c51361328 --- /dev/null +++ b/kabc/vcard/Param.cpp @@ -0,0 +1,129 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardParam.h> + +#include <VCardEntity.h> + +#include <VCardRToken.h> + +using namespace VCARD; + +Param::Param() + : Entity(), + name_(""), + value_("") +{ +} + +Param::Param(const Param & x) + : Entity(x), + name_(x.name_), + value_(x.value_) +{ +} + +Param::Param(const QCString & s) + : Entity(s), + name_(""), + value_("") +{ +} + + Param & +Param::operator = (Param & x) +{ + if (*this == x) return *this; + + Entity::operator = (x); + name_ = x.name_; + value_ = x.value_; + + return *this; +} + + Param & +Param::operator = (const QCString & s) +{ + Entity::operator = (s); + return *this; +} + + bool +Param::operator == (Param & x) +{ + x.parse(); + return false; +} + +Param::~Param() +{ +} + + void +Param::_parse() +{ +} + + void +Param::_assemble() +{ + strRep_ = name_ + "=" + value_; +} + +Param::Param(const QCString &name, const QCString &value) + : Entity(), + name_(name), + value_(value) +{ + parsed_ = true; + assembled_ = false; +} + + void +Param::setName(const QCString & name) +{ + name_ = name; + + assembled_ = false; +} + + void +Param::setValue(const QCString & value) +{ + value_ = value; + + assembled_ = false; +} + + QCString +Param::name() +{ + return name_; +} + + QCString +Param::value() +{ + return value_; +} diff --git a/kabc/vcard/PhoneNumberValue.cpp b/kabc/vcard/PhoneNumberValue.cpp new file mode 100644 index 000000000..17b1400d3 --- /dev/null +++ b/kabc/vcard/PhoneNumberValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardPhoneNumberValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +PhoneNumberValue::PhoneNumberValue() + : Value() +{ +} + +PhoneNumberValue::PhoneNumberValue(const PhoneNumberValue & x) + : Value(x) +{ +} + +PhoneNumberValue::PhoneNumberValue(const QCString & s) + : Value(s) +{ +} + + PhoneNumberValue & +PhoneNumberValue::operator = (PhoneNumberValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + PhoneNumberValue & +PhoneNumberValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +PhoneNumberValue::operator == (PhoneNumberValue & x) +{ + x.parse(); + return false; +} + +PhoneNumberValue::~PhoneNumberValue() +{ +} + + void +PhoneNumberValue::_parse() +{ +} + + void +PhoneNumberValue::_assemble() +{ +} + diff --git a/kabc/vcard/README b/kabc/vcard/README new file mode 100644 index 000000000..18a9daf4a --- /dev/null +++ b/kabc/vcard/README @@ -0,0 +1,15 @@ +libvcard (C) 1999 Rik Hemsley <rik@kde.org> +Written for the KDE project. + +This software is licensed under the MIT license. + +A vCard 3.0 parser based on the same principles that librmm (from Empath) uses. + +It's small and very fast due to parsing and assembly of object being lazy. + +There is a base64 codec declared in Enum.h + +Feedback welcome. + +Rik <rik@kde.org> + diff --git a/kabc/vcard/RToken.cpp b/kabc/vcard/RToken.cpp new file mode 100644 index 000000000..2a85820bd --- /dev/null +++ b/kabc/vcard/RToken.cpp @@ -0,0 +1,88 @@ +/* + + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <string.h> +#include <stddef.h> +#include <qcstring.h> +#include <qstrlist.h> + +namespace VCARD +{ + + Q_UINT32 +RTokenise(const char * str, const char * delim, QStrList & l) +{ + // FIXME no stderr ! + l.clear(); + + if (!delim || !str || strlen(delim) == 0 || strlen(str) == 0) return 0; + + char * len = (char *)(str + strlen(str)); // End of string. + + register char * rstart = new char[strlen(str) + 1]; + register char * r = rstart; + + + register const char * i = str; // Cursor. + + while (i <= len) { + + if (*i == '\\') { // Escaped chars go straight through. + *r++ = *i++; + if (i <= len) + *r++ = *i++; + continue; + } + + if (strchr(delim, *i) != 0) { + // We hit a delimiter. If we have some text, make a new token. + // This has the effect that multiple delimiters are collapsed. + // cs: We mustn't collapse multiple delimiters, otherwise we + // lose empty fields. + *r = '\0'; +// if (r != rstart) { + l.append(rstart); +// } + r = rstart; + ++i; + continue; + } + + *r++ = *i++; + } + + // Catch last token +// if (r != rstart) { + *r = '\0'; + l.append(rstart); +// } + + r = 0; + + delete [] rstart; + + return l.count(); +} + +} diff --git a/kabc/vcard/SoundValue.cpp b/kabc/vcard/SoundValue.cpp new file mode 100644 index 000000000..81040d118 --- /dev/null +++ b/kabc/vcard/SoundValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardSoundValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +SoundValue::SoundValue() + : Value() +{ +} + +SoundValue::SoundValue(const SoundValue & x) + : Value(x) +{ +} + +SoundValue::SoundValue(const QCString & s) + : Value(s) +{ +} + + SoundValue & +SoundValue::operator = (SoundValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + SoundValue & +SoundValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +SoundValue::operator == (SoundValue & x) +{ + x.parse(); + return false; +} + +SoundValue::~SoundValue() +{ +} + + void +SoundValue::_parse() +{ +} + + void +SoundValue::_assemble() +{ +} + diff --git a/kabc/vcard/SourceParam.cpp b/kabc/vcard/SourceParam.cpp new file mode 100644 index 000000000..cd51cbdaa --- /dev/null +++ b/kabc/vcard/SourceParam.cpp @@ -0,0 +1,112 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardSourceParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +SourceParam::SourceParam() + : Param(), + type_(SourceParam::TypeUnknown) +{ +} + +SourceParam::SourceParam(const SourceParam & x) + : Param(x), + type_ (x.type_), + par_ (x.par_), + val_ (x.val_) +{ +} + +SourceParam::SourceParam(const QCString & s) + : Param(s), + type_(SourceParam::TypeUnknown) +{ +} + + SourceParam & +SourceParam::operator = (SourceParam & x) +{ + if (*this == x) return *this; + type_ = x.type(); + par_ = x.par(); + val_ = x.val(); + + Param::operator = (x); + return *this; +} + + SourceParam & +SourceParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +SourceParam::operator == (SourceParam & x) +{ + x.parse(); + return false; +} + +SourceParam::~SourceParam() +{ +} + + void +SourceParam::_parse() +{ + int i = strRep_.find('='); + if (i == -1) // Invalid + return; + + par_ = strRep_.left(i); + val_ = strRep_.right(strRep_.length() - i - 1); + + if (qstricmp(par_, "VALUE") == 0 && qstricmp(val_, "uri") == 0) + type_ = TypeValue; + else if (qstricmp(par_, "CONTEXT") == 0 && qstricmp(val_, "word") == 0) + type_ = TypeContext; + else if (qstrnicmp(par_, "X-", 2) == 0) { + type_ = TypeX; + } + else type_ = TypeUnknown; + +} + + void +SourceParam::_assemble() +{ + if (type_ == TypeValue) + strRep_ = "VALUE=uri"; + else if (type_ == TypeContext) + strRep_ = "CONTEXT=word"; + else if (type_ == TypeX) + strRep_ = par_ + "=" + val_; + else strRep_ = ""; +} + diff --git a/kabc/vcard/TelParam.cpp b/kabc/vcard/TelParam.cpp new file mode 100644 index 000000000..9d9fe4d7f --- /dev/null +++ b/kabc/vcard/TelParam.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardTelParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +TelParam::TelParam() + : Param() +{ +} + +TelParam::TelParam(const TelParam & x) + : Param(x) +{ +} + +TelParam::TelParam(const QCString & s) + : Param(s) +{ +} + + TelParam & +TelParam::operator = (TelParam & x) +{ + if (*this == x) return *this; + + Param::operator = (x); + return *this; +} + + TelParam & +TelParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +TelParam::operator == (TelParam & x) +{ + x.parse(); + return false; +} + +TelParam::~TelParam() +{ +} + + void +TelParam::_parse() +{ +} + + void +TelParam::_assemble() +{ +} + diff --git a/kabc/vcard/TelValue.cpp b/kabc/vcard/TelValue.cpp new file mode 100644 index 000000000..349f99af9 --- /dev/null +++ b/kabc/vcard/TelValue.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardTelValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +TelValue::TelValue() + : Value() +{ +} + +TelValue::TelValue(const TelValue & x) + : Value(x) +{ +} + +TelValue::TelValue(const QCString & s) + : Value(s) +{ +} + + TelValue & +TelValue::operator = (TelValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + TelValue & +TelValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +TelValue::operator == (TelValue & x) +{ + x.parse(); + return false; +} + +TelValue::~TelValue() +{ +} + + void +TelValue::_parse() +{ +} + + void +TelValue::_assemble() +{ +} + diff --git a/kabc/vcard/TextBinParam.cpp b/kabc/vcard/TextBinParam.cpp new file mode 100644 index 000000000..66f29467d --- /dev/null +++ b/kabc/vcard/TextBinParam.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardTextBinParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +TextBinParam::TextBinParam() + : Param() +{ +} + +TextBinParam::TextBinParam(const TextBinParam & x) + : Param(x) +{ +} + +TextBinParam::TextBinParam(const QCString & s) + : Param(s) +{ +} + + TextBinParam & +TextBinParam::operator = (TextBinParam & x) +{ + if (*this == x) return *this; + + Param::operator = (x); + return *this; +} + + TextBinParam & +TextBinParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +TextBinParam::operator == (TextBinParam & x) +{ + x.parse(); + return false; +} + +TextBinParam::~TextBinParam() +{ +} + + void +TextBinParam::_parse() +{ +} + + void +TextBinParam::_assemble() +{ +} + diff --git a/kabc/vcard/TextBinValue.cpp b/kabc/vcard/TextBinValue.cpp new file mode 100644 index 000000000..c58400967 --- /dev/null +++ b/kabc/vcard/TextBinValue.cpp @@ -0,0 +1,104 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <kmdcodec.h> + +#include <VCardTextBinValue.h> +#include <VCardValue.h> + +using namespace VCARD; + +TextBinValue::TextBinValue() + : Value() +{ +} + +TextBinValue::TextBinValue(const TextBinValue & x) + : Value(x) +{ + mIsBinary_ = x.mIsBinary_; + mData_ = x.mData_; + mUrl_ = x.mUrl_; +} + +TextBinValue::TextBinValue(const QCString & s) + : Value(s) +{ +} + + TextBinValue & +TextBinValue::operator = (TextBinValue & x) +{ + if (*this == x) return *this; + + mIsBinary_ = x.mIsBinary_; + mData_ = x.mData_; + mUrl_ = x.mUrl_; + + Value::operator = (x); + return *this; +} + + TextBinValue & +TextBinValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +TextBinValue::operator == (TextBinValue & x) +{ + x.parse(); + + if ( mIsBinary_ != x.mIsBinary_ ) return false; + if ( mData_ != x.mData_ ) return false; + if ( mUrl_ != x.mUrl_ ) return false; + + return true; +} + +TextBinValue::~TextBinValue() +{ +} + + TextBinValue * +TextBinValue::clone() +{ + return new TextBinValue( *this ); +} + + void +TextBinValue::_parse() +{ +} + + void +TextBinValue::_assemble() +{ + if ( mIsBinary_ ) { + strRep_ = KCodecs::base64Encode( mData_ ); + } else + strRep_ = mUrl_.utf8(); +} + diff --git a/kabc/vcard/TextListValue.cpp b/kabc/vcard/TextListValue.cpp new file mode 100644 index 000000000..c4ac1e38b --- /dev/null +++ b/kabc/vcard/TextListValue.cpp @@ -0,0 +1,107 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardRToken.h> + +#include <VCardTextListValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +TextListValue::TextListValue() + : Value() +{ +} + +TextListValue::TextListValue(const TextListValue & x) + : Value(x) +{ +} + +TextListValue::TextListValue(const QCString & s) + : Value(s) +{ +} + + TextListValue & +TextListValue::operator = (TextListValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + TextListValue & +TextListValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +TextListValue::operator == (TextListValue & x) +{ + x.parse(); + return false; +} + +TextListValue::~TextListValue() +{ +} + + void +TextListValue::_parse() +{ + RTokenise(strRep_, ";", valueList_); +} + + void +TextListValue::_assemble() +{ + bool first(true); + + QStrListIterator it(valueList_); + + for (; it.current(); ++it) { + if (!first) strRep_ += ';'; + strRep_ += it.current(); + first = false; + } +} + + unsigned int +TextListValue::numValues() +{ + parse(); + return valueList_.count(); +} + + QCString +TextListValue::value(unsigned int i) +{ + parse(); + return valueList_.at(i); +} + diff --git a/kabc/vcard/TextParam.cpp b/kabc/vcard/TextParam.cpp new file mode 100644 index 000000000..7c6870093 --- /dev/null +++ b/kabc/vcard/TextParam.cpp @@ -0,0 +1,82 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardTextParam.h> + +#include <VCardParam.h> + +using namespace VCARD; + +TextParam::TextParam() + : Param() +{ +} + +TextParam::TextParam(const TextParam & x) + : Param(x) +{ +} + +TextParam::TextParam(const QCString & s) + : Param(s) +{ +} + + TextParam & +TextParam::operator = (TextParam & x) +{ + if (*this == x) return *this; + + Param::operator = (x); + return *this; +} + + TextParam & +TextParam::operator = (const QCString & s) +{ + Param::operator = (s); + return *this; +} + + bool +TextParam::operator == (TextParam & x) +{ + x.parse(); + + return false; +} + +TextParam::~TextParam() +{ +} + + void +TextParam::_parse() +{ +} + + void +TextParam::_assemble() +{ +} + diff --git a/kabc/vcard/TextValue.cpp b/kabc/vcard/TextValue.cpp new file mode 100644 index 000000000..9708398ad --- /dev/null +++ b/kabc/vcard/TextValue.cpp @@ -0,0 +1,86 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardTextValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +TextValue::TextValue() + : Value() +{ +} + +TextValue::TextValue(const TextValue & x) + : Value(x) +{ +} + +TextValue::TextValue(const QCString & s) + : Value(s) +{ +} + + TextValue & +TextValue::operator = (TextValue & x) +{ + if (*this == x) return *this; + + Value::operator = (x); + return *this; +} + + TextValue & +TextValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +TextValue::operator == (TextValue & x) +{ + return strRep_ == x.strRep_; +} + +TextValue::~TextValue() +{ +} + + TextValue * +TextValue::clone() +{ + return new TextValue( *this ); +} + + void +TextValue::_parse() +{ +} + + void +TextValue::_assemble() +{ +} + diff --git a/kabc/vcard/URIValue.cpp b/kabc/vcard/URIValue.cpp new file mode 100644 index 000000000..c1d1022e8 --- /dev/null +++ b/kabc/vcard/URIValue.cpp @@ -0,0 +1,133 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardURIValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +URIValue::URIValue() + : Value() +{ +} + +URIValue::URIValue(const QCString & scheme, const QCString & schemeSpecificPart) + : Value(), + scheme_ (scheme), + schemeSpecificPart_ (schemeSpecificPart) +{ + parsed_ = true; +} + +URIValue::URIValue(const URIValue & x) + : Value (x), + scheme_ (x.scheme_), + schemeSpecificPart_ (x.schemeSpecificPart_) +{ +} + +URIValue::URIValue(const QCString & s) + : Value(s) +{ +} + + URIValue & +URIValue::operator = (URIValue & x) +{ + if (*this == x) return *this; + + scheme_ = x.scheme_; + schemeSpecificPart_ = x.schemeSpecificPart_; + + Value::operator = (x); + return *this; +} + + URIValue & +URIValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +URIValue::operator == (URIValue & x) +{ + x.parse(); + return ( + (scheme_ == x.scheme_) && + (schemeSpecificPart_ == x.schemeSpecificPart_)); + + return false; +} + +URIValue::~URIValue() +{ +} + + void +URIValue::_parse() +{ + int split = strRep_.find(':'); + if (split == -1) + return; + + scheme_ = strRep_.left(split); + schemeSpecificPart_ = strRep_.mid(split + 1); +} + + void +URIValue::_assemble() +{ + strRep_ = scheme_ + ':' + schemeSpecificPart_; +} + + QCString +URIValue::scheme() +{ + parse(); + return scheme_; +} + + QCString +URIValue::schemeSpecificPart() +{ + parse(); + return schemeSpecificPart_; +} + + void +URIValue::setScheme(const QCString & s) +{ + parse(); + scheme_ = s; +} + + void +URIValue::setSchemeSpecificPart(const QCString & s) +{ + parse(); + schemeSpecificPart_ = s; +} + diff --git a/kabc/vcard/UTCValue.cpp b/kabc/vcard/UTCValue.cpp new file mode 100644 index 000000000..374306c5f --- /dev/null +++ b/kabc/vcard/UTCValue.cpp @@ -0,0 +1,110 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardUTCValue.h> + +#include <VCardValue.h> + +using namespace VCARD; + +UTCValue::UTCValue() + : Value() +{ +} + +UTCValue::UTCValue(const UTCValue & x) + : Value(x), positive_(x.positive_), hour_(x.hour_), minute_(x.minute_) + +{ +} + +UTCValue::UTCValue(const QCString & s) + : Value(s) +{ +} + + UTCValue & +UTCValue::operator = (UTCValue & x) +{ + if (*this == x) return *this; + + positive_ = x.positive_; + hour_ = x.hour_; + minute_ = x.minute_; + + Value::operator = (x); + return *this; +} + + UTCValue & +UTCValue::operator = (const QCString & s) +{ + Value::operator = (s); + return *this; +} + + bool +UTCValue::operator == (UTCValue & x) +{ + x.parse(); + + if (positive_ != x.positive_) return false; + if (hour_ != x.hour_) return false; + if (minute_ != x.minute_) return false; + + return true; +} + +UTCValue::~UTCValue() +{ +} + + UTCValue * +UTCValue::clone() +{ + return new UTCValue( *this ); +} + + void +UTCValue::_parse() +{ + if ( strRep_.isEmpty() ) + return; + + positive_ = ( strRep_[0] == '+' ); + + int colon = strRep_.find( ':' ); + + if ( colon == -1 ) // Not valid. + return; + + hour_ = strRep_.mid( 1, 2 ).toInt(); + minute_ = strRep_.right( 2 ).toInt(); +} + + void +UTCValue::_assemble() +{ + strRep_.sprintf( "%c%.2i:%.2i", (positive_ ? '+' : '-'), hour_, minute_ ); +} + diff --git a/kabc/vcard/VCard.cpp b/kabc/vcard/VCard.cpp new file mode 100644 index 000000000..8a65ecfd4 --- /dev/null +++ b/kabc/vcard/VCard.cpp @@ -0,0 +1,283 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qcstring.h> +#include <qstrlist.h> + +#include <VCardEntity.h> +#include <VCardVCard.h> +#include <VCardContentLine.h> +#include <VCardRToken.h> + +#include <VCardDefines.h> + +using namespace VCARD; + +VCard::VCard() + : Entity() +{ + contentLineList_.setAutoDelete( true ); +} + +VCard::VCard(const VCard & x) + : Entity(x), + group_(x.group_), + contentLineList_(x.contentLineList_) +{ +} + +VCard::VCard(const QCString & s) + : Entity(s) +{ +} + + VCard & +VCard::operator = (VCard & x) +{ + if (*this == x) return *this; + + group_ = x.group(); + contentLineList_ = x.contentLineList_; + + Entity::operator = (x); + return *this; +} + + VCard & +VCard::operator = (const QCString & s) +{ + Entity::operator = (s); + return *this; +} + + bool +VCard::operator == (VCard & x) +{ + x.parse(); + return false; +} + +VCard::~VCard() +{ +} + + void +VCard::_parse() +{ + vDebug("parse() called"); + QStrList l; + + RTokenise(strRep_, "\r\n", l); + + if (l.count() < 3) { // Invalid VCARD ! + vDebug("Invalid vcard"); + return; + } + + // Get the first line + QCString beginLine = QCString(l.at(0)).stripWhiteSpace(); + + vDebug("Begin line == \"" + beginLine + "\""); + + // Remove extra blank lines + while (QCString(l.last()).isEmpty()) + l.remove(l.last()); + + // Now we know this is the last line + QCString endLine = l.last(); + + // Trash the first and last lines as we have seen them. + l.remove(0u); + l.remove(l.last()); + + /////////////////////////////////////////////////////////////// + // FIRST LINE + + int split = beginLine.find(':'); + + if (split == -1) { // invalid, no BEGIN + vDebug("No split"); + return; + } + + QCString firstPart(beginLine.left(split)); + QCString valuePart(beginLine.mid(split + 1)); + + split = firstPart.find('.'); + + if (split != -1) { + group_ = firstPart.left(split); + firstPart = firstPart.right(firstPart.length() - split - 1); + } + + if (qstrnicmp(firstPart, "BEGIN", 5) != 0) { // No BEGIN ! + vDebug("No BEGIN"); + return; + } + + if (qstrnicmp(valuePart, "VCARD", 5) != 0) { // Not a vcard ! + vDebug("No VCARD"); + return; + } + + /////////////////////////////////////////////////////////////// + // CONTENT LINES + // + vDebug("Content lines"); + + // Handle folded lines. + + QStrList refolded; + + QStrListIterator it(l); + + QCString cur; + + for (; it.current(); ++it) { + + cur = it.current(); + + ++it; + + while ( + it.current() && + it.current()[0] == ' ' && + strlen(it.current()) != 1) + { + cur += it.current() + 1; + ++it; + } + + --it; + + refolded.append(cur); + } + + QStrListIterator it2(refolded); + + for (; it2.current(); ++it2) { + + vDebug("New contentline using \"" + QCString(it2.current()) + "\""); + ContentLine * cl = new ContentLine(it2.current()); + + cl->parse(); + + contentLineList_.append(cl); + } + + /////////////////////////////////////////////////////////////// + // LAST LINE + + split = endLine.find(':'); + + if (split == -1) // invalid, no END + return; + + firstPart = endLine.left(split); + valuePart = endLine.right(firstPart.length() - split - 1); + + split = firstPart.find('.'); + + if (split != -1) { + group_ = firstPart.left(split); + firstPart = firstPart.right(firstPart.length() - split - 1); + } + + if (qstricmp(firstPart, "END") != 0) // No END ! + return; + + if (qstricmp(valuePart, "VCARD") != 0) // Not a vcard ! + return; +} + + void +VCard::_assemble() +{ + vDebug("Assembling vcard"); + strRep_ = "BEGIN:VCARD\r\n"; + strRep_ += "VERSION:3.0\r\n"; + + QPtrListIterator<ContentLine> it(contentLineList_); + + for (; it.current(); ++it) + strRep_ += it.current()->asString() + "\r\n"; + + strRep_ += "END:VCARD\r\n"; +} + + bool +VCard::has(EntityType t) +{ + parse(); + return contentLine(t) == 0 ? false : true; +} + + bool +VCard::has(const QCString & s) +{ + parse(); + return contentLine(s) == 0 ? false : true; +} + + void +VCard::add(const ContentLine & cl) +{ + parse(); + ContentLine * c = new ContentLine(cl); + contentLineList_.append(c); +} + + void +VCard::add(const QCString & s) +{ + parse(); + ContentLine * c = new ContentLine(s); + contentLineList_.append(c); +} + + ContentLine * +VCard::contentLine(EntityType t) +{ + parse(); + QPtrListIterator<ContentLine> it(contentLineList_); + + for (; it.current(); ++it) + if (it.current()->entityType() == t) + return it.current(); + + return 0; +} + + ContentLine * +VCard::contentLine(const QCString & s) +{ + parse(); + QPtrListIterator<ContentLine> it(contentLineList_); + + for (; it.current(); ++it) + if (it.current()->entityType() == EntityNameToEntityType(s)) + return it.current(); + + return 0; +} + diff --git a/kabc/vcard/VCardEntity.cpp b/kabc/vcard/VCardEntity.cpp new file mode 100644 index 000000000..0c21e2f70 --- /dev/null +++ b/kabc/vcard/VCardEntity.cpp @@ -0,0 +1,119 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <qregexp.h> + +#include <VCardDefines.h> +#include <VCardVCardEntity.h> + +using namespace VCARD; + +VCardEntity::VCardEntity() + : Entity() +{ +} + +VCardEntity::VCardEntity(const VCardEntity & x) + : Entity(x) +{ +} + +VCardEntity::VCardEntity(const QCString & s) + : Entity(s) +{ +} + + VCardEntity & +VCardEntity::operator = (VCardEntity & x) +{ + if (*this == x) return *this; + + Entity::operator = (x); + return *this; +} + + VCardEntity & +VCardEntity::operator = (const QCString & s) +{ + Entity::operator = (s); + return *this; +} + + bool +VCardEntity::operator == (VCardEntity & x) +{ + x.parse(); + return false; +} + +VCardEntity::~VCardEntity() +{ +} + + void +VCardEntity::_parse() +{ + vDebug("parse"); + QCString s(strRep_); + + int i = s.find(QRegExp("BEGIN:VCARD", false)); + + while (i != -1) { + + i = s.find(QRegExp("BEGIN:VCARD", false), 11); + + QCString cardStr(s.left(i)); + + VCard * v = new VCard(cardStr); + + cardList_.append(v); + + v->parse(); + + s.remove(0, i); + } +} + + void +VCardEntity::_assemble() +{ + VCardListIterator it(cardList_); + + for (; it.current(); ++it) + strRep_ += it.current()->asString() + "\r\n"; // One CRLF for luck. +} + + VCardList & +VCardEntity::cardList() +{ + parse(); + return cardList_; +} + + void +VCardEntity::setCardList(const VCardList & l) +{ + parse(); + cardList_ = l; +} + diff --git a/kabc/vcard/Value.cpp b/kabc/vcard/Value.cpp new file mode 100644 index 000000000..33b7a509e --- /dev/null +++ b/kabc/vcard/Value.cpp @@ -0,0 +1,81 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <VCardEntity.h> +#include <VCardValue.h> + +using namespace VCARD; + +Value::Value() + : Entity() +{ +} + +Value::Value(const Value & x) + : Entity(x) +{ +} + +Value::Value(const QCString & s) + : Entity(s) +{ +} + + Value & +Value::operator = (Value & x) +{ + if (*this == x) return *this; + + Entity::operator = (x); + return *this; +} + + Value & +Value::operator = (const QCString & s) +{ + Entity::operator = (s); + return *this; +} + + bool +Value::operator == (Value & x) +{ + x.parse(); + return false; +} + +Value::~Value() +{ +} + + void +Value::_parse() +{ +} + + void +Value::_assemble() +{ + vDebug("Value::_assemble()"); +} + diff --git a/kabc/vcard/include/VCard.h b/kabc/vcard/include/VCard.h new file mode 100644 index 000000000..17b50e8f2 --- /dev/null +++ b/kabc/vcard/include/VCard.h @@ -0,0 +1,43 @@ +#ifndef VCARD_H +#define VCARD_H + +#include "VCardAdrParam.h" +#include "VCardAdrValue.h" +#include "VCardAgentParam.h" +#include "VCardAgentValue.h" +#include "VCardClassValue.h" +#include "VCardContentLine.h" +#include "VCardDateParam.h" +#include "VCardDateValue.h" +#include "VCardDefines.h" +#include "VCardEmailParam.h" +#include "VCardEntity.h" +#include "VCardEnum.h" +#include "VCardFloatValue.h" +#include "VCardGeoValue.h" +#include "VCardGroup.h" +#include "VCardImageParam.h" +#include "VCardImageValue.h" +#include "VCardImgValue.h" +#include "VCardLangValue.h" +#include "VCardNValue.h" +#include "VCardOrgValue.h" +#include "VCardParam.h" +#include "VCardPhoneNumberValue.h" +#include "VCardRToken.h" +#include "VCardSoundValue.h" +#include "VCardSourceParam.h" +#include "VCardTelParam.h" +#include "VCardTelValue.h" +#include "VCardTextBinParam.h" +#include "VCardTextBinValue.h" +#include "VCardTextListValue.h" +#include "VCardTextParam.h" +#include "VCardTextValue.h" +#include "VCardURIValue.h" +#include "VCardUTCValue.h" +#include "VCardVCard.h" +#include "VCardVCardEntity.h" +#include "VCardValue.h" + +#endif diff --git a/kabc/vcard/include/VCardAdrParam.h b/kabc/vcard/include/VCardAdrParam.h new file mode 100644 index 000000000..783d79129 --- /dev/null +++ b/kabc/vcard/include/VCardAdrParam.h @@ -0,0 +1,64 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ADRPARAM_H +#define ADRPARAM_H + +#include <qcstring.h> +#include <qstrlist.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT AdrParam : public Param +{ + +#include "AdrParam-generated.h" + + QStrList adrTypeList() + { parse(); return adrTypeList_; } + + QCString textParam() + { parse(); return textParam_; } + + void setAdrTypeList(const QStrList & l) + { adrTypeList_ = l; assembled_ = false; } + + void setTextParam(const QCString & s) + { textParam_ = s; assembled_ = false; } + + enum AdrType { + AdrDom, AdrIntl, AdrPostal, AdrParcel, AdrHome, AdrWork, AdrPref, + AdrIANA, AdrX + }; + + private: + + QStrList adrTypeList_; + QCString textParam_; +}; +} + +#endif diff --git a/kabc/vcard/include/VCardAdrValue.h b/kabc/vcard/include/VCardAdrValue.h new file mode 100644 index 000000000..e17ee347f --- /dev/null +++ b/kabc/vcard/include/VCardAdrValue.h @@ -0,0 +1,83 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ADRVALUE_H +#define ADRVALUE_H + +#include <qstrlist.h> +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT AdrValue : public Value +{ + +#include "AdrValue-generated.h" + + AdrValue *clone(); + + void setPOBox(const QCString & s) + { poBox_ = s; assembled_ = false; } + + void setExtAddress(const QCString & s) + { extAddress_ = s; assembled_ = false; } + + void setStreet(const QCString & s) + { street_ = s; assembled_ = false; } + + void setLocality(const QCString & s) + { locality_ = s; assembled_ = false; } + + void setRegion(const QCString & s) + { region_ = s; assembled_ = false; } + + void setPostCode(const QCString & s) + { postCode_ = s; assembled_ = false; } + + void setCountryName(const QCString & s) + { countryName_ = s; assembled_ = false; } + + QCString poBox() { parse(); return poBox_; } + QCString extAddress() { parse(); return extAddress_; } + QCString street() { parse(); return street_; } + QCString locality() { parse(); return locality_; } + QCString region() { parse(); return region_; } + QCString postCode() { parse(); return postCode_; } + QCString countryName() { parse(); return countryName_; } + + private: + + QCString poBox_; + QCString extAddress_; + QCString street_; + QCString locality_; + QCString region_; + QCString postCode_; + QCString countryName_; +}; + +} + +#endif + diff --git a/kabc/vcard/include/VCardAgentParam.h b/kabc/vcard/include/VCardAgentParam.h new file mode 100644 index 000000000..aed1ade19 --- /dev/null +++ b/kabc/vcard/include/VCardAgentParam.h @@ -0,0 +1,60 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef AGENTPARAM_H +#define AGENTPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> +#include <VCardURIValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT AgentParam : public Param +{ + +#include "AgentParam-generated.h" + + bool refer() + { parse(); return refer_; } + + URIValue uri() + { parse(); return uri_; } + + void setRefer(bool b) + { refer_ = b; assembled_ = false; } + + void setURI(const QCString & s) + { uri_ = s; assembled_ = false; } + + private: + + bool refer_; + URIValue uri_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardAgentValue.h b/kabc/vcard/include/VCardAgentValue.h new file mode 100644 index 000000000..0d103be41 --- /dev/null +++ b/kabc/vcard/include/VCardAgentValue.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef AGENTVALUE_H +#define AGENTVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT AgentValue : public Value +{ + +#include "AgentValue-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardClassValue.h b/kabc/vcard/include/VCardClassValue.h new file mode 100644 index 000000000..23e9b6d28 --- /dev/null +++ b/kabc/vcard/include/VCardClassValue.h @@ -0,0 +1,56 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef CLASSVALUE_H +#define CLASSVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +#include <kdebug.h> + +namespace VCARD +{ + +class KVCARD_EXPORT ClassValue : public Value +{ + +#include "ClassValue-generated.h" + + enum ClassType { + Public, Private, Confidential, Other + }; + + ClassValue *clone(); + + void setType( int type ) { classType_ = type; assembled_ = false; parsed_ = true; } + int type() { parse(); return classType_; } + + private: + int classType_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardContentLine.h b/kabc/vcard/include/VCardContentLine.h new file mode 100644 index 000000000..6cb26d7bd --- /dev/null +++ b/kabc/vcard/include/VCardContentLine.h @@ -0,0 +1,77 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef CONTENTLINE_H +#define CONTENTLINE_H + +#include <qptrlist.h> + +#include "VCardEnum.h" +#include "VCardEntity.h" +#include "VCardParam.h" +#include "VCardValue.h" + +namespace VCARD +{ + +class KVCARD_EXPORT ContentLine : public Entity +{ + +#include "ContentLine-generated.h" + + QCString group() { parse(); return group_; } + QCString name() { parse(); return name_; } + Value * value() { parse(); return value_; } + ParamList paramList() { parse(); return paramList_; } + ParamType paramType() { parse(); return paramType_; } + ValueType valueType() { parse(); return valueType_; } + EntityType entityType() { parse(); return entityType_; } + + void setGroup (const QCString & s) + { group_ = s; assembled_ = false; } + + void setName (const QCString & s) + { name_ = s; assembled_ = false; } + + void setValue (Value *s) + { value_ = s; assembled_ = false; } + + void setParamList (const ParamList & l) + { paramList_ = l; assembled_ = false; } + + void clear (); + + private: + + QCString group_; + QCString name_; + QPtrList<Param> paramList_; + Value * value_; + + ParamType paramType_; + ValueType valueType_; + EntityType entityType_; +}; +} + +#endif diff --git a/kabc/vcard/include/VCardDateParam.h b/kabc/vcard/include/VCardDateParam.h new file mode 100644 index 000000000..32179be43 --- /dev/null +++ b/kabc/vcard/include/VCardDateParam.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef DATEPARAM_H +#define DATEPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT DateParam : public Param +{ + +#include "DateParam-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardDateValue.h b/kabc/vcard/include/VCardDateValue.h new file mode 100644 index 000000000..f97b21113 --- /dev/null +++ b/kabc/vcard/include/VCardDateValue.h @@ -0,0 +1,99 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef DATEVALUE_H +#define DATEVALUE_H + +#include <qcstring.h> +#include <qdatetime.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT DateValue : public Value +{ +#include "DateValue-generated.h" + + DateValue( + unsigned int year, + unsigned int month, + unsigned int day, + unsigned int hour = 0, + unsigned int minute = 0, + unsigned int second = 0, + double secFrac = 0, + bool zonePositive = true, + unsigned int zoneHour = 0, + unsigned int zoneMinute = 0); + + DateValue(const QDate &); + DateValue(const QDateTime &); + + DateValue *clone(); + + bool hasTime(); + + unsigned int year(); + unsigned int month(); + unsigned int day(); + unsigned int hour(); + unsigned int minute(); + unsigned int second(); + double secondFraction(); + bool zonePositive(); + unsigned int zoneHour(); + unsigned int zoneMinute(); + + void setYear (unsigned int); + void setMonth (unsigned int); + void setDay (unsigned int); + void setHour (unsigned int); + void setMinute (unsigned int); + void setSecond (unsigned int); + void setSecondFraction (double); + void setZonePositive (bool); + void setZoneHour (unsigned int); + void setZoneMinute (unsigned int); + + QDate qdate(); + QTime qtime(); + QDateTime qdt(); + + private: + + unsigned int year_, month_, day_, + hour_, minute_, second_, + zoneHour_, zoneMinute_; + + double secFrac_; + + bool zonePositive_; + + bool hasTime_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardDefines.h b/kabc/vcard/include/VCardDefines.h new file mode 100644 index 000000000..dd38ae28b --- /dev/null +++ b/kabc/vcard/include/VCardDefines.h @@ -0,0 +1,52 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1998 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef VCARD_DEFINES_H +#define VCARD_DEFINES_H + +#include <kdebug.h> + +#ifdef VCARD_DEBUG +#define vDebug(a) kdDebug(5710) << a << endl; +#else +#define vDebug(a) +#endif + +#if 0 +#ifndef NDEBUG +# include <qcstring.h> +# include <iostream> +# ifdef __GNUG__ +# define vDebug(a) cerr << className() << ":" << __FUNCTION__ << " (" \ + << __LINE__ << "): " << QCString((a)).data() << endl; +# else +# define vDebug(a) cerr << className() << ": " \ + << QCString((a)).data() << endl; +# endif +#else +# define vDebug(a) +#endif +#endif + +#endif // Included this file + diff --git a/kabc/vcard/include/VCardEmailParam.h b/kabc/vcard/include/VCardEmailParam.h new file mode 100644 index 000000000..c879fac49 --- /dev/null +++ b/kabc/vcard/include/VCardEmailParam.h @@ -0,0 +1,56 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef EMAILPARAM_H +#define EMAILPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT EmailParam : public Param +{ + +#include "EmailParam-generated.h" + + QCString emailType() { parse(); return emailType_; } + bool pref() { parse(); return pref_; } + + void setEmailType(const QCString & s) + { emailType_ = s; assembled_ = false; } + + void setPref(bool b) + { pref_ = b; assembled_ = false; } + + private: + + QCString emailType_; + bool pref_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardEntity.h b/kabc/vcard/include/VCardEntity.h new file mode 100644 index 000000000..ed503f896 --- /dev/null +++ b/kabc/vcard/include/VCardEntity.h @@ -0,0 +1,68 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ENTITY_H +#define ENTITY_H + +#include <qcstring.h> +#include <kdelibs_export.h> + +namespace VCARD +{ + +class KVCARD_EXPORT Entity +{ + public: + + Entity(); + Entity(const Entity & e); + Entity(const QCString & s); + + virtual Entity & operator = (const Entity & e); + virtual Entity & operator = (const QCString & s); + + virtual bool operator == (Entity & e); + virtual bool operator != (Entity & e); + virtual bool operator == (const QCString & s); + virtual bool operator != (const QCString & s); + + virtual ~Entity(); + + QCString asString(); + + virtual void parse(); + virtual void assemble(); + + virtual void _parse() = 0; + virtual void _assemble() = 0; + + protected: + + QCString strRep_; + bool parsed_; + bool assembled_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardEnum.h b/kabc/vcard/include/VCardEnum.h new file mode 100644 index 000000000..485a13e16 --- /dev/null +++ b/kabc/vcard/include/VCardEnum.h @@ -0,0 +1,122 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ENUM_H +#define ENUM_H + +#include <qcstring.h> + +#include <kdelibs_export.h> + +namespace VCARD +{ + +extern const QCString paramNames []; + +enum EntityType { + EntityName, + EntityProfile, + EntitySource, + EntityFullName, + EntityN, + EntityNickname, + EntityPhoto, + EntityBirthday, + EntityAddress, + EntityLabel, + EntityTelephone, + EntityEmail, + EntityMailer, + EntityTimeZone, + EntityGeo, + EntityTitle, + EntityRole, + EntityLogo, + EntityAgent, + EntityOrganisation, + EntityCategories, + EntityNote, + EntityProductID, + EntityRevision, + EntitySortString, + EntitySound, + EntityUID, + EntityURL, + EntityVersion, + EntityClass, + EntityKey, + EntityExtension, + EntityUnknown +}; + +enum ValueType { + ValueSound, + ValueAgent, + ValueAddress, + ValueTel, + ValueTextBin, + ValueOrg, + ValueN, + ValueUTC, + ValueURI, + ValueClass, + ValueFloat, + ValueImage, + ValueDate, + ValueTextList, + ValueText, + ValueGeo, + ValueUnknown +}; + +enum ParamType { + ParamUnknown, + ParamNone, + ParamSource, + ParamText, + ParamImage, + ParamDate, + ParamAddrText, + ParamTel, + ParamEmail, + ParamMailer, + ParamAgent, + ParamTextBin, + ParamTextNS, + ParamSound +}; + +extern const ParamType paramTypesTable[]; + +KVCARD_EXPORT ParamType EntityTypeToParamType(EntityType); +KVCARD_EXPORT ValueType EntityTypeToValueType(EntityType); +KVCARD_EXPORT QCString EntityTypeToParamName(EntityType); +KVCARD_EXPORT EntityType EntityNameToEntityType(const QCString &); + +KVCARD_EXPORT char * encodeBase64(const char *, unsigned long, unsigned long &); +KVCARD_EXPORT char * decodeBase64(const char *, unsigned long, unsigned long &); + +} + +#endif + diff --git a/kabc/vcard/include/VCardFloatValue.h b/kabc/vcard/include/VCardFloatValue.h new file mode 100644 index 000000000..3e158774f --- /dev/null +++ b/kabc/vcard/include/VCardFloatValue.h @@ -0,0 +1,51 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef FLOATVALUE_H +#define FLOATVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT FloatValue : public Value +{ + +#include "FloatValue-generated.h" + + FloatValue(float); + + float value(); + void setValue(float); + + private: + + float value_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardGeoValue.h b/kabc/vcard/include/VCardGeoValue.h new file mode 100644 index 000000000..4228587a4 --- /dev/null +++ b/kabc/vcard/include/VCardGeoValue.h @@ -0,0 +1,49 @@ +/* + This file is part of libvcard. + 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 GEOVALUE_H +#define GEOVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT GeoValue : public Value +{ + +#include "GeoValue-generated.h" + + GeoValue *clone(); + + void setLatitude( float lat ) { latitude_ = lat; assembled_ = false; } + void setLongitude( float lon ) { longitude_ = lon; assembled_ = false; } + + float latitude() { parse(); return latitude_; } + float longitude() { parse(); return longitude_; } + + private: + float latitude_; + float longitude_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardGroup.h b/kabc/vcard/include/VCardGroup.h new file mode 100644 index 000000000..ce884f100 --- /dev/null +++ b/kabc/vcard/include/VCardGroup.h @@ -0,0 +1,39 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef GROUP_H +#define GROUP_H + +#include <VCardEntity.h> + +namespace VCARD +{ + +class KVCARD_EXPORT Group : public Entity +{ +#include "Group-generated.h" +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardImageParam.h b/kabc/vcard/include/VCardImageParam.h new file mode 100644 index 000000000..a78ebd4a6 --- /dev/null +++ b/kabc/vcard/include/VCardImageParam.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef IMGPARAM_H +#define IMGPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT ImageParam : public Param +{ + +#include "ImageParam-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardImageValue.h b/kabc/vcard/include/VCardImageValue.h new file mode 100644 index 000000000..7a9b29c1e --- /dev/null +++ b/kabc/vcard/include/VCardImageValue.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef IMAGEVALUE_H +#define IMAGEVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT ImageValue : public Value +{ + +#include "ImageValue-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardImgValue.h b/kabc/vcard/include/VCardImgValue.h new file mode 100644 index 000000000..7d4bbfa2d --- /dev/null +++ b/kabc/vcard/include/VCardImgValue.h @@ -0,0 +1,39 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef IMGVALUE_H +#define IMGVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT ImgValue : public Value +{ +#include "ImgValue-generated.h" +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardLangValue.h b/kabc/vcard/include/VCardLangValue.h new file mode 100644 index 000000000..22c50a9d4 --- /dev/null +++ b/kabc/vcard/include/VCardLangValue.h @@ -0,0 +1,51 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LANGVALUE_H +#define LANGVALUE_H + +#include <qcstring.h> +#include <qstrlist.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT LangValue : public Value +{ +#include "LangValue-generated.h" + + QCString primary(); + QStrList subtags(); + + void setPrimary(const QCString &); + void setSubTags(const QStrList &); + + QCString primary_; + QStrList subtags_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardNValue.h b/kabc/vcard/include/VCardNValue.h new file mode 100644 index 000000000..41a6e9b28 --- /dev/null +++ b/kabc/vcard/include/VCardNValue.h @@ -0,0 +1,56 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef NVALUE_H +#define NVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT NValue : public Value +{ +#include "NValue-generated.h" + NValue *clone(); + + QCString family() { parse(); return family_; } + QCString given() { parse(); return given_; } + QCString middle() { parse(); return middle_; } + QCString prefix() { parse(); return prefix_; } + QCString suffix() { parse(); return suffix_; } + + void setFamily (const QCString & s) { family_ = s; assembled_ = false; } + void setGiven (const QCString & s) { given_ = s; assembled_ = false; } + void setMiddle (const QCString & s) { middle_ = s; assembled_ = false; } + void setPrefix (const QCString & s) { prefix_ = s; assembled_ = false; } + void setSuffix (const QCString & s) { suffix_ = s; assembled_ = false; } + + private: + + QCString family_, given_, middle_, prefix_, suffix_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardOrgValue.h b/kabc/vcard/include/VCardOrgValue.h new file mode 100644 index 000000000..cc5633501 --- /dev/null +++ b/kabc/vcard/include/VCardOrgValue.h @@ -0,0 +1,50 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ORGVALUE_H +#define ORGVALUE_H + +#include <qcstring.h> +#include <qstrlist.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT OrgValue : public Value +{ + +#include "OrgValue-generated.h" + + unsigned int numValues(); + QCString value(unsigned int); + + private: + + QStrList valueList_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardParam.h b/kabc/vcard/include/VCardParam.h new file mode 100644 index 000000000..f805634c0 --- /dev/null +++ b/kabc/vcard/include/VCardParam.h @@ -0,0 +1,59 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PARAM_H +#define PARAM_H + +#include <qcstring.h> +#include <qptrlist.h> + +#include <VCardEntity.h> + +namespace VCARD +{ + +class KVCARD_EXPORT Param : public Entity +{ + +#include "Param-generated.h" + + Param(const QCString &name, const QCString &value); + + void setName(const QCString &); + void setValue(const QCString &); + + QCString name(); + QCString value(); + + private: + + QCString name_; + QCString value_; +}; + +typedef QPtrList<Param> ParamList; +typedef QPtrListIterator<Param> ParamListIterator; + +} + +#endif diff --git a/kabc/vcard/include/VCardPhoneNumberValue.h b/kabc/vcard/include/VCardPhoneNumberValue.h new file mode 100644 index 000000000..3f9e106ca --- /dev/null +++ b/kabc/vcard/include/VCardPhoneNumberValue.h @@ -0,0 +1,39 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PHONENUMBERVALUE_H +#define PHONENUMBERVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT PhoneNumberValue : public Value +{ +#include "PhoneNumberValue-generated.h" +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardRToken.h b/kabc/vcard/include/VCardRToken.h new file mode 100644 index 000000000..06e644b20 --- /dev/null +++ b/kabc/vcard/include/VCardRToken.h @@ -0,0 +1,40 @@ +/* + + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef RTOKEN_H +#define RTOKEN_H + +#include <qstrlist.h> + +#include <kdelibs_export.h> + +namespace VCARD +{ + +KVCARD_EXPORT Q_UINT32 RTokenise(const char * str, const char * delim, QStrList & l); + +} + +#endif + diff --git a/kabc/vcard/include/VCardSndValue.h b/kabc/vcard/include/VCardSndValue.h new file mode 100644 index 000000000..09a3a8238 --- /dev/null +++ b/kabc/vcard/include/VCardSndValue.h @@ -0,0 +1,39 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SNDVALUE_H +#define SNDVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT SndValue : public Value +{ +#include "SndValue-generated.h" +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardSoundValue.h b/kabc/vcard/include/VCardSoundValue.h new file mode 100644 index 000000000..0a7af1fbc --- /dev/null +++ b/kabc/vcard/include/VCardSoundValue.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SOUNDVALUE_H +#define SOUNDVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT SoundValue : public Value +{ + +#include "SoundValue-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardSourceParam.h b/kabc/vcard/include/VCardSourceParam.h new file mode 100644 index 000000000..bb28ffe62 --- /dev/null +++ b/kabc/vcard/include/VCardSourceParam.h @@ -0,0 +1,58 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SOURCEPARAM_H +#define SOURCEPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT SourceParam : public Param +{ + +#include "SourceParam-generated.h" + + enum SourceParamType { TypeUnknown, TypeValue, TypeContext, TypeX }; + + SourceParamType type() { parse(); return type_;} + QCString par() { parse(); return par_; } + QCString val() { parse(); return val_; } + + void setType(SourceParamType t) { type_ = t; assembled_ = false; } + void setPar(const QCString & s) { par_ = s; assembled_ = false; } + void setVal(const QCString & s) { val_ = s; assembled_ = false; } + + private: + + SourceParamType type_; + // May be "VALUE = uri" or "CONTEXT = word" or "x-name = *SAFE-CHAR" + QCString par_, val_; // Sub-parameter, value +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTelParam.h b/kabc/vcard/include/VCardTelParam.h new file mode 100644 index 000000000..0eff82390 --- /dev/null +++ b/kabc/vcard/include/VCardTelParam.h @@ -0,0 +1,51 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TELPARAM_H +#define TELPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TelParam : public Param +{ +#include "TelParam-generated.h" + + enum TelType { + TelHome, TelWork, TelPref, TelVoice, TelFex, TelMsg, TelCell, + TelPager, TelBBS, TelModem, TelCar, TelISDN, TelVideo, TelPCS, + TelIANA, TelX + }; + + private: + + QPtrList<TelType> types_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTelValue.h b/kabc/vcard/include/VCardTelValue.h new file mode 100644 index 000000000..1d3563192 --- /dev/null +++ b/kabc/vcard/include/VCardTelValue.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TELVALUE_H +#define TELVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TelValue : public Value +{ + +#include "TelValue-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTextBinParam.h b/kabc/vcard/include/VCardTextBinParam.h new file mode 100644 index 000000000..5085d5d36 --- /dev/null +++ b/kabc/vcard/include/VCardTextBinParam.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TEXTBINPARAM_H +#define TEXTBINPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TextBinParam : public Param +{ + +#include "TextBinParam-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTextBinValue.h b/kabc/vcard/include/VCardTextBinValue.h new file mode 100644 index 000000000..9835acf9b --- /dev/null +++ b/kabc/vcard/include/VCardTextBinValue.h @@ -0,0 +1,67 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TEXTBINVALUE_H +#define TEXTBINVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TextBinValue : public Value +{ + +#include "TextBinValue-generated.h" + + TextBinValue *clone(); + + bool isBinary() { parse(); return mIsBinary_; } + QByteArray data() { parse(); return mData_; } + QString url() { parse(); return mUrl_; } + + void setData( const QByteArray &data ) + { + mData_ = data; + mIsBinary_ = true; + assembled_ = false; + } + + void setUrl( const QString &url ) + { + mUrl_ = url; + mIsBinary_ = false; + assembled_ = false; + } + + private: + int mIsBinary_; + QByteArray mData_; + QString mUrl_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTextListValue.h b/kabc/vcard/include/VCardTextListValue.h new file mode 100644 index 000000000..14242312a --- /dev/null +++ b/kabc/vcard/include/VCardTextListValue.h @@ -0,0 +1,51 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TEXTLISTVALUE_H +#define TEXTLISTVALUE_H + +#include <qstrlist.h> + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TextListValue : public Value +{ + +#include "TextListValue-generated.h" + + unsigned int numValues(); + QCString value(unsigned int); + + private: + + QStrList valueList_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTextParam.h b/kabc/vcard/include/VCardTextParam.h new file mode 100644 index 000000000..d241f42d0 --- /dev/null +++ b/kabc/vcard/include/VCardTextParam.h @@ -0,0 +1,44 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TEXTPARAM_H +#define TEXTPARAM_H + +#include <qcstring.h> + +#include <VCardParam.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TextParam : public Param +{ + +#include "TextParam-generated.h" + + private: +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardTextValue.h b/kabc/vcard/include/VCardTextValue.h new file mode 100644 index 000000000..66eed32a8 --- /dev/null +++ b/kabc/vcard/include/VCardTextValue.h @@ -0,0 +1,41 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef TEXTVALUE_H +#define TEXTVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT TextValue : public Value +{ +#include "TextValue-generated.h" + + TextValue *clone(); +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardURIValue.h b/kabc/vcard/include/VCardURIValue.h new file mode 100644 index 000000000..de56d49e6 --- /dev/null +++ b/kabc/vcard/include/VCardURIValue.h @@ -0,0 +1,52 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef URIVALUE_H +#define URIVALUE_H + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT URIValue : public Value +{ +#include "URIValue-generated.h" + + URIValue(const QCString & scheme, const QCString & schemeSpecificPart); + + QCString scheme(); + QCString schemeSpecificPart(); + + void setScheme (const QCString &); + void setSchemeSpecificPart (const QCString &); + + private: + + QCString scheme_; + QCString schemeSpecificPart_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardUTCValue.h b/kabc/vcard/include/VCardUTCValue.h new file mode 100644 index 000000000..6674ff7db --- /dev/null +++ b/kabc/vcard/include/VCardUTCValue.h @@ -0,0 +1,58 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef UTCVALUE_H +#define UTCVALUE_H + +#include <qcstring.h> + +#include <VCardValue.h> + +namespace VCARD +{ + +class KVCARD_EXPORT UTCValue : public Value +{ + +#include "UTCValue-generated.h" + + UTCValue *clone(); + + void setPositive( int p ) { positive_ = p; assembled_ = false; } + void setHour( int h ) { hour_ = h; assembled_ = false; } + void setMinute( int m ) { minute_ = m; assembled_ = false; } + + bool positive() { parse(); return positive_; } + unsigned int hour() { parse(); return hour_; } + unsigned int minute() { parse(); return minute_; } + + private: + + bool positive_; + unsigned int hour_; + unsigned int minute_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardVCard.h b/kabc/vcard/include/VCardVCard.h new file mode 100644 index 000000000..120682212 --- /dev/null +++ b/kabc/vcard/include/VCardVCard.h @@ -0,0 +1,63 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef VCARD_VCARD_H +#define VCARD_VCARD_H + +#include <qstring.h> +#include <qptrlist.h> + +#include <VCardEnum.h> +#include <VCardEntity.h> +#include <VCardContentLine.h> + +namespace VCARD +{ + +class KVCARD_EXPORT VCard : public Entity +{ + +#include "VCard-generated.h" + + bool has(EntityType); + bool has(const QCString &); + + void add(const ContentLine &); + void add(const QCString &); + + ContentLine * contentLine(EntityType); + ContentLine * contentLine(const QCString &); + + QCString group() { parse(); return group_; } + + QPtrList<ContentLine> contentLineList() { parse(); return contentLineList_; } + + private: + + QCString group_; + QPtrList<ContentLine> contentLineList_; +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardVCardEntity.h b/kabc/vcard/include/VCardVCardEntity.h new file mode 100644 index 000000000..d45d43c26 --- /dev/null +++ b/kabc/vcard/include/VCardVCardEntity.h @@ -0,0 +1,56 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef VCARD_ENTITY_H +#define VCARD_ENTITY_H + +#include <qstring.h> +#include <qptrlist.h> + +#include <VCardEnum.h> +#include <VCardVCard.h> +#include <VCardEntity.h> + +namespace VCARD +{ + +typedef QPtrList<VCard> VCardList; +typedef QPtrListIterator<VCard> VCardListIterator; + +class KVCARD_EXPORT VCardEntity : public Entity +{ + +#include "VCardEntity-generated.h" + + void setCardList(const VCardList & l); + VCardList & cardList(); + + private: + + VCardList cardList_; + +}; + +} + +#endif diff --git a/kabc/vcard/include/VCardValue.h b/kabc/vcard/include/VCardValue.h new file mode 100644 index 000000000..9019f2b1a --- /dev/null +++ b/kabc/vcard/include/VCardValue.h @@ -0,0 +1,46 @@ +/* + libvcard - vCard parsing library for vCard version 3.0 + + Copyright (C) 1999 Rik Hemsley rik@kde.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef VALUE_H +#define VALUE_H + +#include <qptrlist.h> + +#include <VCardEntity.h> + +namespace VCARD +{ + +class KVCARD_EXPORT Value : public Entity +{ +#include "Value-generated.h" + + virtual Value *clone() { return new Value( *this ); } +}; + +typedef QPtrList<Value> ValueList; +typedef QPtrListIterator<Value> ValueListIterator; + +} + +#endif diff --git a/kabc/vcard/include/generated/AdrParam-generated.h b/kabc/vcard/include/generated/AdrParam-generated.h new file mode 100644 index 000000000..3e265d8a7 --- /dev/null +++ b/kabc/vcard/include/generated/AdrParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +AdrParam(); +AdrParam(const AdrParam&); +AdrParam(const QCString&); +AdrParam & operator = (AdrParam&); +AdrParam & operator = (const QCString&); +bool operator ==(AdrParam&); +bool operator !=(AdrParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {AdrParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~AdrParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "AdrParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/AdrValue-generated.h b/kabc/vcard/include/generated/AdrValue-generated.h new file mode 100644 index 000000000..e1d93e425 --- /dev/null +++ b/kabc/vcard/include/generated/AdrValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +AdrValue(); +AdrValue(const AdrValue&); +AdrValue(const QCString&); +AdrValue & operator = (AdrValue&); +AdrValue & operator = (const QCString&); +bool operator ==(AdrValue&); +bool operator !=(AdrValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {AdrValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~AdrValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "AdrValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/AgentParam-generated.h b/kabc/vcard/include/generated/AgentParam-generated.h new file mode 100644 index 000000000..6423867d9 --- /dev/null +++ b/kabc/vcard/include/generated/AgentParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +AgentParam(); +AgentParam(const AgentParam&); +AgentParam(const QCString&); +AgentParam & operator = (AgentParam&); +AgentParam & operator = (const QCString&); +bool operator ==(AgentParam&); +bool operator !=(AgentParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {AgentParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~AgentParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "AgentParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/AgentValue-generated.h b/kabc/vcard/include/generated/AgentValue-generated.h new file mode 100644 index 000000000..76bb81c53 --- /dev/null +++ b/kabc/vcard/include/generated/AgentValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +AgentValue(); +AgentValue(const AgentValue&); +AgentValue(const QCString&); +AgentValue & operator = (AgentValue&); +AgentValue & operator = (const QCString&); +bool operator ==(AgentValue&); +bool operator !=(AgentValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {AgentValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~AgentValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "AgentValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ClassValue-generated.h b/kabc/vcard/include/generated/ClassValue-generated.h new file mode 100644 index 000000000..df4ed5ff0 --- /dev/null +++ b/kabc/vcard/include/generated/ClassValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ClassValue(); +ClassValue(const ClassValue&); +ClassValue(const QCString&); +ClassValue & operator = (ClassValue&); +ClassValue & operator = (const QCString&); +bool operator ==(ClassValue&); +bool operator !=(ClassValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ClassValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ClassValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "ClassValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ContentLine-generated.h b/kabc/vcard/include/generated/ContentLine-generated.h new file mode 100644 index 000000000..9efe2731a --- /dev/null +++ b/kabc/vcard/include/generated/ContentLine-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ContentLine(); +ContentLine(const ContentLine&); +ContentLine(const QCString&); +ContentLine & operator = (ContentLine&); +ContentLine & operator = (const QCString&); +bool operator ==(ContentLine&); +bool operator !=(ContentLine& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ContentLine a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ContentLine(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "ContentLine"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/DateParam-generated.h b/kabc/vcard/include/generated/DateParam-generated.h new file mode 100644 index 000000000..ff1da58c9 --- /dev/null +++ b/kabc/vcard/include/generated/DateParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +DateParam(); +DateParam(const DateParam&); +DateParam(const QCString&); +DateParam & operator = (DateParam&); +DateParam & operator = (const QCString&); +bool operator ==(DateParam&); +bool operator !=(DateParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {DateParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~DateParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "DateParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/DateValue-generated.h b/kabc/vcard/include/generated/DateValue-generated.h new file mode 100644 index 000000000..a38282379 --- /dev/null +++ b/kabc/vcard/include/generated/DateValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +DateValue(); +DateValue(const DateValue&); +DateValue(const QCString&); +DateValue & operator = (DateValue&); +DateValue & operator = (const QCString&); +bool operator ==(DateValue&); +bool operator !=(DateValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {DateValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~DateValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "DateValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/EmailParam-generated.h b/kabc/vcard/include/generated/EmailParam-generated.h new file mode 100644 index 000000000..428a6fc20 --- /dev/null +++ b/kabc/vcard/include/generated/EmailParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +EmailParam(); +EmailParam(const EmailParam&); +EmailParam(const QCString&); +EmailParam & operator = (EmailParam&); +EmailParam & operator = (const QCString&); +bool operator ==(EmailParam&); +bool operator !=(EmailParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {EmailParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~EmailParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "EmailParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/FloatValue-generated.h b/kabc/vcard/include/generated/FloatValue-generated.h new file mode 100644 index 000000000..cac55cfef --- /dev/null +++ b/kabc/vcard/include/generated/FloatValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +FloatValue(); +FloatValue(const FloatValue&); +FloatValue(const QCString&); +FloatValue & operator = (FloatValue&); +FloatValue & operator = (const QCString&); +bool operator ==(FloatValue&); +bool operator !=(FloatValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {FloatValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~FloatValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "FloatValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/GeoValue-generated.h b/kabc/vcard/include/generated/GeoValue-generated.h new file mode 100644 index 000000000..594f3ad67 --- /dev/null +++ b/kabc/vcard/include/generated/GeoValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +GeoValue(); +GeoValue(const GeoValue&); +GeoValue(const QCString&); +GeoValue & operator = (GeoValue&); +GeoValue & operator = (const QCString&); +bool operator ==(GeoValue&); +bool operator !=(GeoValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {GeoValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~GeoValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "GeoValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/Group-generated.h b/kabc/vcard/include/generated/Group-generated.h new file mode 100644 index 000000000..f39302dd3 --- /dev/null +++ b/kabc/vcard/include/generated/Group-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +Group(); +Group(const Group&); +Group(const QCString&); +Group & operator = (Group&); +Group & operator = (const QCString&); +bool operator ==(Group&); +bool operator !=(Group& x) {return !(*this==x);} +bool operator ==(const QCString& s) {Group a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~Group(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "Group"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ImageParam-generated.h b/kabc/vcard/include/generated/ImageParam-generated.h new file mode 100644 index 000000000..81edfd29a --- /dev/null +++ b/kabc/vcard/include/generated/ImageParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ImageParam(); +ImageParam(const ImageParam&); +ImageParam(const QCString&); +ImageParam & operator = (ImageParam&); +ImageParam & operator = (const QCString&); +bool operator ==(ImageParam&); +bool operator !=(ImageParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ImageParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ImageParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "ImageParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ImageValue-generated.h b/kabc/vcard/include/generated/ImageValue-generated.h new file mode 100644 index 000000000..5a2c493ee --- /dev/null +++ b/kabc/vcard/include/generated/ImageValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ImageValue(); +ImageValue(const ImageValue&); +ImageValue(const QCString&); +ImageValue & operator = (ImageValue&); +ImageValue & operator = (const QCString&); +bool operator ==(ImageValue&); +bool operator !=(ImageValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ImageValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ImageValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "ImageValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ImgParam-generated.h b/kabc/vcard/include/generated/ImgParam-generated.h new file mode 100644 index 000000000..46a6ca031 --- /dev/null +++ b/kabc/vcard/include/generated/ImgParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ImgParam(); +ImgParam(const ImgParam&); +ImgParam(const QCString&); +ImgParam & operator = (ImgParam&); +ImgParam & operator = (const QCString&); +bool operator ==(ImgParam&); +bool operator !=(ImgParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ImgParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ImgParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +virtual const char * className() const { return "ImgParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ImgValue-generated.h b/kabc/vcard/include/generated/ImgValue-generated.h new file mode 100644 index 000000000..d75d54550 --- /dev/null +++ b/kabc/vcard/include/generated/ImgValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +ImgValue(); +ImgValue(const ImgValue&); +ImgValue(const QCString&); +ImgValue & operator = (ImgValue&); +ImgValue & operator = (const QCString&); +bool operator ==(ImgValue&); +bool operator !=(ImgValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {ImgValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~ImgValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +virtual const char * className() const { return "ImgValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/LangValue-generated.h b/kabc/vcard/include/generated/LangValue-generated.h new file mode 100644 index 000000000..23e138b2f --- /dev/null +++ b/kabc/vcard/include/generated/LangValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +LangValue(); +LangValue(const LangValue&); +LangValue(const QCString&); +LangValue & operator = (LangValue&); +LangValue & operator = (const QCString&); +bool operator ==(LangValue&); +bool operator !=(LangValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {LangValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~LangValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "LangValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/NValue-generated.h b/kabc/vcard/include/generated/NValue-generated.h new file mode 100644 index 000000000..082c2534d --- /dev/null +++ b/kabc/vcard/include/generated/NValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +NValue(); +NValue(const NValue&); +NValue(const QCString&); +NValue & operator = (NValue&); +NValue & operator = (const QCString&); +bool operator ==(NValue&); +bool operator !=(NValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {NValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~NValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "NValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/Name-generated.h b/kabc/vcard/include/generated/Name-generated.h new file mode 100644 index 000000000..0e69abd1d --- /dev/null +++ b/kabc/vcard/include/generated/Name-generated.h @@ -0,0 +1,22 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +V_Name(); +V_Name(const V_Name&); +V_Name(const QCString&); +V_Name & operator = (V_Name&); +V_Name & operator = (const QCString&); +bool operator ==(V_Name&); +bool operator !=(V_Name& x) {return !(*this==x);} +bool operator ==(const QCString& s) {V_Name a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~V_Name(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/OrgValue-generated.h b/kabc/vcard/include/generated/OrgValue-generated.h new file mode 100644 index 000000000..51eb1b738 --- /dev/null +++ b/kabc/vcard/include/generated/OrgValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +OrgValue(); +OrgValue(const OrgValue&); +OrgValue(const QCString&); +OrgValue & operator = (OrgValue&); +OrgValue & operator = (const QCString&); +bool operator ==(OrgValue&); +bool operator !=(OrgValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {OrgValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~OrgValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "OrgValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/Param-generated.h b/kabc/vcard/include/generated/Param-generated.h new file mode 100644 index 000000000..cf4666a4b --- /dev/null +++ b/kabc/vcard/include/generated/Param-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +Param(); +Param(const Param&); +Param(const QCString&); +Param & operator = (Param&); +Param & operator = (const QCString&); +bool operator ==(Param&); +bool operator !=(Param& x) {return !(*this==x);} +bool operator ==(const QCString& s) {Param a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~Param(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "Param"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ParamName-generated.h b/kabc/vcard/include/generated/ParamName-generated.h new file mode 100644 index 000000000..ef673c392 --- /dev/null +++ b/kabc/vcard/include/generated/ParamName-generated.h @@ -0,0 +1,22 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +V_ParamName(); +V_ParamName(const V_ParamName&); +V_ParamName(const QCString&); +V_ParamName & operator = (V_ParamName&); +V_ParamName & operator = (const QCString&); +bool operator ==(V_ParamName&); +bool operator !=(V_ParamName& x) {return !(*this==x);} +bool operator ==(const QCString& s) {V_ParamName a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~V_ParamName(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/ParamValue-generated.h b/kabc/vcard/include/generated/ParamValue-generated.h new file mode 100644 index 000000000..e73500f67 --- /dev/null +++ b/kabc/vcard/include/generated/ParamValue-generated.h @@ -0,0 +1,22 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +V_ParamValue(); +V_ParamValue(const V_ParamValue&); +V_ParamValue(const QCString&); +V_ParamValue & operator = (V_ParamValue&); +V_ParamValue & operator = (const QCString&); +bool operator ==(V_ParamValue&); +bool operator !=(V_ParamValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {V_ParamValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~V_ParamValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/PhoneNumberValue-generated.h b/kabc/vcard/include/generated/PhoneNumberValue-generated.h new file mode 100644 index 000000000..1320f186c --- /dev/null +++ b/kabc/vcard/include/generated/PhoneNumberValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +PhoneNumberValue(); +PhoneNumberValue(const PhoneNumberValue&); +PhoneNumberValue(const QCString&); +PhoneNumberValue & operator = (PhoneNumberValue&); +PhoneNumberValue & operator = (const QCString&); +bool operator ==(PhoneNumberValue&); +bool operator !=(PhoneNumberValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {PhoneNumberValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~PhoneNumberValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "PhoneNumberValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/SoundValue-generated.h b/kabc/vcard/include/generated/SoundValue-generated.h new file mode 100644 index 000000000..a9ab2e8c5 --- /dev/null +++ b/kabc/vcard/include/generated/SoundValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +SoundValue(); +SoundValue(const SoundValue&); +SoundValue(const QCString&); +SoundValue & operator = (SoundValue&); +SoundValue & operator = (const QCString&); +bool operator ==(SoundValue&); +bool operator !=(SoundValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {SoundValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~SoundValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "SoundValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/SourceParam-generated.h b/kabc/vcard/include/generated/SourceParam-generated.h new file mode 100644 index 000000000..75fefb862 --- /dev/null +++ b/kabc/vcard/include/generated/SourceParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +SourceParam(); +SourceParam(const SourceParam&); +SourceParam(const QCString&); +SourceParam & operator = (SourceParam&); +SourceParam & operator = (const QCString&); +bool operator ==(SourceParam&); +bool operator !=(SourceParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {SourceParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~SourceParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "SourceParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TelParam-generated.h b/kabc/vcard/include/generated/TelParam-generated.h new file mode 100644 index 000000000..3ee77cc3c --- /dev/null +++ b/kabc/vcard/include/generated/TelParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TelParam(); +TelParam(const TelParam&); +TelParam(const QCString&); +TelParam & operator = (TelParam&); +TelParam & operator = (const QCString&); +bool operator ==(TelParam&); +bool operator !=(TelParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TelParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TelParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TelParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TelValue-generated.h b/kabc/vcard/include/generated/TelValue-generated.h new file mode 100644 index 000000000..3213e1cd1 --- /dev/null +++ b/kabc/vcard/include/generated/TelValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TelValue(); +TelValue(const TelValue&); +TelValue(const QCString&); +TelValue & operator = (TelValue&); +TelValue & operator = (const QCString&); +bool operator ==(TelValue&); +bool operator !=(TelValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TelValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TelValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TelValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextBinParam-generated.h b/kabc/vcard/include/generated/TextBinParam-generated.h new file mode 100644 index 000000000..d075c102b --- /dev/null +++ b/kabc/vcard/include/generated/TextBinParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextBinParam(); +TextBinParam(const TextBinParam&); +TextBinParam(const QCString&); +TextBinParam & operator = (TextBinParam&); +TextBinParam & operator = (const QCString&); +bool operator ==(TextBinParam&); +bool operator !=(TextBinParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextBinParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextBinParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextBinParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextBinValue-generated.h b/kabc/vcard/include/generated/TextBinValue-generated.h new file mode 100644 index 000000000..e9553ac2c --- /dev/null +++ b/kabc/vcard/include/generated/TextBinValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextBinValue(); +TextBinValue(const TextBinValue&); +TextBinValue(const QCString&); +TextBinValue & operator = (TextBinValue&); +TextBinValue & operator = (const QCString&); +bool operator ==(TextBinValue&); +bool operator !=(TextBinValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextBinValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextBinValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextBinValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextListValue-generated.h b/kabc/vcard/include/generated/TextListValue-generated.h new file mode 100644 index 000000000..9f46124bf --- /dev/null +++ b/kabc/vcard/include/generated/TextListValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextListValue(); +TextListValue(const TextListValue&); +TextListValue(const QCString&); +TextListValue & operator = (TextListValue&); +TextListValue & operator = (const QCString&); +bool operator ==(TextListValue&); +bool operator !=(TextListValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextListValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextListValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextListValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextNSParam-generated.h b/kabc/vcard/include/generated/TextNSParam-generated.h new file mode 100644 index 000000000..d7f58caae --- /dev/null +++ b/kabc/vcard/include/generated/TextNSParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextNSParam(); +TextNSParam(const TextNSParam&); +TextNSParam(const QCString&); +TextNSParam & operator = (TextNSParam&); +TextNSParam & operator = (const QCString&); +bool operator ==(TextNSParam&); +bool operator !=(TextNSParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextNSParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextNSParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextNSParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextParam-generated.h b/kabc/vcard/include/generated/TextParam-generated.h new file mode 100644 index 000000000..154e1bf4c --- /dev/null +++ b/kabc/vcard/include/generated/TextParam-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextParam(); +TextParam(const TextParam&); +TextParam(const QCString&); +TextParam & operator = (TextParam&); +TextParam & operator = (const QCString&); +bool operator ==(TextParam&); +bool operator !=(TextParam& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextParam a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextParam(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextParam"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/TextValue-generated.h b/kabc/vcard/include/generated/TextValue-generated.h new file mode 100644 index 000000000..e1c4dcc09 --- /dev/null +++ b/kabc/vcard/include/generated/TextValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +TextValue(); +TextValue(const TextValue&); +TextValue(const QCString&); +TextValue & operator = (TextValue&); +TextValue & operator = (const QCString&); +bool operator ==(TextValue&); +bool operator !=(TextValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {TextValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~TextValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "TextValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/URIValue-generated.h b/kabc/vcard/include/generated/URIValue-generated.h new file mode 100644 index 000000000..dbcb5c1ed --- /dev/null +++ b/kabc/vcard/include/generated/URIValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +URIValue(); +URIValue(const URIValue&); +URIValue(const QCString&); +URIValue & operator = (URIValue&); +URIValue & operator = (const QCString&); +bool operator ==(URIValue&); +bool operator !=(URIValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {URIValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~URIValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "URIValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/UTCValue-generated.h b/kabc/vcard/include/generated/UTCValue-generated.h new file mode 100644 index 000000000..46e447b3b --- /dev/null +++ b/kabc/vcard/include/generated/UTCValue-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +UTCValue(); +UTCValue(const UTCValue&); +UTCValue(const QCString&); +UTCValue & operator = (UTCValue&); +UTCValue & operator = (const QCString&); +bool operator ==(UTCValue&); +bool operator !=(UTCValue& x) {return !(*this==x);} +bool operator ==(const QCString& s) {UTCValue a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~UTCValue(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "UTCValue"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/VCard-generated.h b/kabc/vcard/include/generated/VCard-generated.h new file mode 100644 index 000000000..4d7d96d48 --- /dev/null +++ b/kabc/vcard/include/generated/VCard-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +VCard(); +VCard(const VCard&); +VCard(const QCString&); +VCard & operator = (VCard&); +VCard & operator = (const QCString&); +bool operator ==(VCard&); +bool operator !=(VCard& x) {return !(*this==x);} +bool operator ==(const QCString& s) {VCard a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~VCard(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "VCard"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/VCardEntity-generated.h b/kabc/vcard/include/generated/VCardEntity-generated.h new file mode 100644 index 000000000..9f2dfbce8 --- /dev/null +++ b/kabc/vcard/include/generated/VCardEntity-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +VCardEntity(); +VCardEntity(const VCardEntity&); +VCardEntity(const QCString&); +VCardEntity & operator = (VCardEntity&); +VCardEntity & operator = (const QCString&); +bool operator ==(VCardEntity&); +bool operator !=(VCardEntity& x) {return !(*this==x);} +bool operator ==(const QCString& s) {VCardEntity a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~VCardEntity(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "VCardEntity"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/Value-generated.h b/kabc/vcard/include/generated/Value-generated.h new file mode 100644 index 000000000..7afac34b6 --- /dev/null +++ b/kabc/vcard/include/generated/Value-generated.h @@ -0,0 +1,23 @@ +// XXX Automatically generated. DO NOT EDIT! XXX // + +public: +Value(); +Value(const Value&); +Value(const QCString&); +Value & operator = (Value&); +Value & operator = (const QCString&); +bool operator ==(Value&); +bool operator !=(Value& x) {return !(*this==x);} +bool operator ==(const QCString& s) {Value a(s);return(*this==a);} +bool operator != (const QCString& s) {return !(*this == s);} + +virtual ~Value(); +void parse() {if(!parsed_) _parse();parsed_=true;assembled_=false;} + +void assemble() {if(assembled_) return;parse();_assemble();assembled_=true;} + +void _parse(); +void _assemble(); +const char * className() const { return "Value"; } + +// End of automatically generated code // diff --git a/kabc/vcard/include/generated/generate b/kabc/vcard/include/generated/generate new file mode 100755 index 000000000..926dbf136 --- /dev/null +++ b/kabc/vcard/include/generated/generate @@ -0,0 +1,2 @@ +#!/bin/sh +cat headerBodies | awk -f generateHeaders.awk diff --git a/kabc/vcard/include/generated/generateHeaders.awk b/kabc/vcard/include/generated/generateHeaders.awk new file mode 100755 index 000000000..471db11b4 --- /dev/null +++ b/kabc/vcard/include/generated/generateHeaders.awk @@ -0,0 +1,41 @@ +#!/bin/awk -f + +{ + outfile = $1 "-generated.h" + name = $1 + + OFS="" + + print "// XXX Automatically generated. DO NOT EDIT! XXX //\n" > outfile + print "// WARNING! All changes made in this file will be lost!\n" > outfile + + if ($2 == "v") { pre = "virtual " } else { pre = "" } + + print "public:" >> outfile + print name "();" >> outfile + print name "(const " name "&);" >> outfile + print name "(const QCString&);" >> outfile + print pre name " & operator = (" name "&);" >> outfile + print pre name " & operator = (const QCString&);" >> outfile + print pre "bool operator ==(" name "&);" >> outfile + print pre "bool operator !=(" name "& x) {return !(*this==x);}" \ + >> outfile + print pre "bool operator ==(const QCString& s) {" name " a(s);" \ + "return(*this==a);} " >> outfile + print pre "bool operator != (const QCString& s) {return !(*this == s);}\n" \ + >> outfile + print "virtual ~" name "();" >> outfile + print pre "void parse() " \ + "{if(!parsed_) _parse();parsed_=true;assembled_=false;}\n" \ + >> outfile + print pre "void assemble() " \ + "{if(assembled_) return;parse();_assemble();assembled_=true;}\n" \ + >> outfile + print pre "void _parse();" >> outfile + print pre "void _assemble();" >> outfile + print pre "const char * className() const { return \"" name "\"; }" \ + >> outfile + + print "\n// End of automatically generated code //" >> outfile +} + diff --git a/kabc/vcard/include/generated/headerBodies b/kabc/vcard/include/generated/headerBodies new file mode 100644 index 000000000..5e77b2b5e --- /dev/null +++ b/kabc/vcard/include/generated/headerBodies @@ -0,0 +1,34 @@ +AdrParam Param +AdrValue Value +AgentParam Param +ContentLine Entity +DateParam Param +DateValue Value +EmailParam Param +GeoValue Value +Group Entity +ImageParam Param +ImageValue Value +LangValue Value +NValue Value +Param Entity +PhoneNumberValue Value +SourceParam Param +TelParam Param +TextParam Param +TextNSParam Param +TextValue Value +TextBinParam Param +URIValue Value +VCard Entity +VCardEntity Entity +Value Entity +SoundValue Value +AgentValue Value +TelValue Value +TextBinValue Value +OrgValue Value +UTCValue Value +ClassValue Value +FloatValue Value +TextListValue Value diff --git a/kabc/vcard/testread.cpp b/kabc/vcard/testread.cpp new file mode 100644 index 000000000..919c6616d --- /dev/null +++ b/kabc/vcard/testread.cpp @@ -0,0 +1,129 @@ +#include <iostream> +#include <stdlib.h> +#include <assert.h> + +#include <qfile.h> +#include <qtextstream.h> + +#include <VCard.h> + +using namespace std; + +int main(int argc, char * argv[]) +{ + if (argc != 2) { + cerr << "Usage: " << argv[0] << " <filename>" << endl; + exit(1); + } + + QFile f(argv[1]); + + QCString str; + + if (!f.open(IO_ReadOnly)) { + cerr << "Couldn't open file \"" << argv[1] << endl; + exit(1); + } + + QTextStream t(&f); + + while (!t.eof()) + str += t.readLine().utf8() + '\n'; + + using namespace VCARD; + + // Iterate through all vCards in the file. + + cout << "--------- begin ----------" << endl; + cout << str.data(); + cout << "--------- end ----------" << endl; + + VCardEntity e(str); + + VCardListIterator it(e.cardList()); + + for (; it.current(); ++it) { + + cerr << "****************** VCARD ********************" << endl; + + // Create a vcard using the string representation. + VCard & v (*it.current()); + + if (v.has(EntityEmail)) { + cerr << "Email parameter found" << endl; + + QCString s = v.contentLine(EntityEmail)->value()->asString(); + + cerr << "Email value == " << s << endl; + } + + if (v.has(EntityNickname)) { + cerr << "Nickname parameter found" << endl; + + cerr << "Nickname value == " << + v.contentLine(EntityNickname)->value()->asString() << + endl; + } + + if (v.has(EntityRevision)) { + + cerr << "Revision parameter found" << endl; + + DateValue * d = + (DateValue *) + v.contentLine(EntityRevision)->value(); + + assert(d != 0); + + cerr << "Revision date: " << endl; + cerr << "Day : " << d->day() << endl; + cerr << "Month : " << d->month() << endl; + cerr << "Year : " << d->year() << endl; + + if (d->hasTime()) { + cerr << "Revision date has a time component" << endl; + cerr << "Revision time: " << endl; + cerr << "Hour : " << d->hour() << endl; + cerr << "Minute : " << d->minute() << endl; + cerr << "Second : " << d->second() << endl; + + } + else cerr << "Revision date does NOT have a time component" << endl; + } + + if (v.has(EntityURL)) { + cerr << "URL Parameter found" << endl; + + cerr << "URL Value == " << + v.contentLine(EntityURL)->value()->asString() << + endl; + + URIValue * urlVal = + (URIValue *)v.contentLine(EntityURL)->value(); + + assert(urlVal != 0); + + cerr << "URL scheme == " << + urlVal->scheme() << endl; + + cerr << "URL scheme specific part == " << + urlVal->schemeSpecificPart() << endl; + } + + if (v.has(EntityN)) { + cerr << "N Parameter found" << endl; + + NValue * n = + (NValue *)(v.contentLine(EntityN)->value()); + + cerr << "Family name == " << n->family() << endl; + cerr << "Given name == " << n->given() << endl; + cerr << "Middle name == " << n->middle() << endl; + cerr << "Prefix == " << n->prefix() << endl; + cerr << "Suffix == " << n->suffix() << endl; + } + + cerr << "***************** END VCARD ******************" << endl; + } +} + diff --git a/kabc/vcard/testwrite.cpp b/kabc/vcard/testwrite.cpp new file mode 100644 index 000000000..e4bbe7bc0 --- /dev/null +++ b/kabc/vcard/testwrite.cpp @@ -0,0 +1,41 @@ +#include <kaboutdata.h> +#include <kapplication.h> +#include <kdebug.h> +#include <klocale.h> +#include <kcmdlineargs.h> + +#include <VCard.h> + +int main(int argc,char **argv) +{ + KAboutData aboutData("testwrite",I18N_NOOP("TestWritevCard"),"0.1"); + KCmdLineArgs::init(argc,argv,&aboutData); + + KApplication app; + + kdDebug() << "Test Write VCard" << endl; + + using namespace VCARD; + + VCard v; + + ContentLine cl1; + cl1.setName(EntityTypeToParamName(EntityName)); + cl1.setValue(new TextValue("Hans Wurst")); + v.add(cl1); + + ContentLine cl2; + cl2.setName(EntityTypeToParamName(EntityTelephone)); + cl2.setValue(new TelValue("12345")); + ParamList p; + p.append( new TelParam("home") ); + p.append( new TelParam("fax") ); + cl2.setParamList( p ); + v.add(cl2); + + QCString str = v.asString(); + + kdDebug() << "--- VCard begin ---" << endl + << str + << "--- VCard end ---" << endl; +} diff --git a/kabc/vcard/vCard-all.cpp b/kabc/vcard/vCard-all.cpp new file mode 100644 index 000000000..07bbcd2bb --- /dev/null +++ b/kabc/vcard/vCard-all.cpp @@ -0,0 +1,37 @@ +#include "AdrParam.cpp" +#include "AdrValue.cpp" +#include "AgentParam.cpp" +#include "AgentValue.cpp" +#include "ClassValue.cpp" +#include "ContentLine.cpp" +#include "DateParam.cpp" +#include "DateValue.cpp" +#include "EmailParam.cpp" +#include "Entity.cpp" +#include "Enum.cpp" +#include "FloatValue.cpp" +#include "GeoValue.cpp" +#include "ImageParam.cpp" +#include "ImageValue.cpp" +#include "ImgValue.cpp" +#include "LangValue.cpp" +#include "NValue.cpp" +#include "OrgValue.cpp" +#include "Param.cpp" +#include "PhoneNumberValue.cpp" +#include "RToken.cpp" +#include "SoundValue.cpp" +#include "SourceParam.cpp" +#include "TelParam.cpp" +#include "TelValue.cpp" +#include "TextBinParam.cpp" +#include "TextBinValue.cpp" +#include "TextListValue.cpp" +#include "TextParam.cpp" +#include "TextValue.cpp" +#include "URIValue.cpp" +#include "UTCValue.cpp" +#include "VCard.cpp" +#include "VCardEntity.cpp" +#include "Value.cpp" + diff --git a/kabc/vcard21parser.cpp b/kabc/vcard21parser.cpp new file mode 100644 index 000000000..aebef680c --- /dev/null +++ b/kabc/vcard21parser.cpp @@ -0,0 +1,608 @@ +/* + This file is part of libkabc. + Copyright (c) 2001 Mark Westcott <mark@houseoffish.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 <qmap.h> +#include <qregexp.h> +#include <kmdcodec.h> + +#include "vcard21parser.h" +#include "vcardconverter.h" + +using namespace KABC; + +bool VCardLineX::isValid() const +{ + // Invalid: if it is "begin:vcard" or "end:vcard" + if ( name == VCARD_BEGIN_N || name == VCARD_END_N ) + return false; + + if ( name[0] == 'x' && name[1] == '-' ) // A custom x- line + return true; + + // This is long but it makes it a bit faster (and saves me from using + // a tree which is probably the ideal situation, but a bit memory heavy) + switch( name[0] ) { + case 'a': + if ( name == VCARD_ADR && qualified && + (qualifiers.contains(VCARD_ADR_DOM) || + qualifiers.contains(VCARD_ADR_INTL) || + qualifiers.contains(VCARD_ADR_POSTAL) || + qualifiers.contains(VCARD_ADR_HOME) || + qualifiers.contains(VCARD_ADR_WORK) || + qualifiers.contains(VCARD_ADR_PREF) + ) ) + return true; + + if ( name == VCARD_AGENT ) + return true; + break; + + case 'b': + if ( name == VCARD_BDAY ) + return true; + break; + + case 'c': + if ( name == VCARD_CATEGORIES ) + return true; + if ( name == VCARD_CLASS && qualified && + (qualifiers.contains(VCARD_CLASS_PUBLIC) || + qualifiers.contains(VCARD_CLASS_PRIVATE) || + qualifiers.contains(VCARD_CLASS_CONFIDENTIAL) + ) ) + return true; + break; + + case 'e': + if ( name == VCARD_EMAIL && qualified && + (qualifiers.contains(VCARD_EMAIL_INTERNET) || + qualifiers.contains(VCARD_EMAIL_PREF) || + qualifiers.contains(VCARD_EMAIL_X400) + ) ) + return true; + break; + + case 'f': + if ( name == VCARD_FN ) + return true; + break; + + case 'g': + if ( name == VCARD_GEO ) + return true; + break; + + case 'k': + if ( name == VCARD_KEY && qualified && + (qualifiers.contains(VCARD_KEY_X509) || + qualifiers.contains(VCARD_KEY_PGP) + ) ) + return true; + break; + + case 'l': + if ( name == VCARD_LABEL ) + return true; + if ( name == VCARD_LOGO ) + return true; + break; + + case 'm': + if ( name == VCARD_MAILER ) + return true; + break; + + case 'n': + if ( name == VCARD_N ) + return true; + if ( name == VCARD_NAME ) + return true; + if ( name == VCARD_NICKNAME ) + return true; + if ( name == VCARD_NOTE ) + return true; + break; + + case 'o': + if ( name == VCARD_ORG ) + return true; + break; + + case 'p': + if ( name == VCARD_PHOTO ) + return true; + if ( name == VCARD_PROFILE ) + return true; + if ( name == VCARD_PRODID ) + return true; + break; + + case 'r': + if ( name == VCARD_ROLE ) + return true; + if ( name == VCARD_REV ) + return true; + break; + + case 's': + if ( name == VCARD_SOURCE ) + return true; + if ( name == VCARD_SOUND ) + return true; + break; + + case 't': + if ( name == VCARD_TEL && qualified && + (qualifiers.contains(VCARD_TEL_HOME) || + qualifiers.contains(VCARD_TEL_WORK) || + qualifiers.contains(VCARD_TEL_PREF) || + qualifiers.contains(VCARD_TEL_VOICE) || + qualifiers.contains(VCARD_TEL_FAX) || + qualifiers.contains(VCARD_TEL_MSG) || + qualifiers.contains(VCARD_TEL_CELL) || + qualifiers.contains(VCARD_TEL_PAGER) || + qualifiers.contains(VCARD_TEL_BBS) || + qualifiers.contains(VCARD_TEL_MODEM) || + qualifiers.contains(VCARD_TEL_CAR) || + qualifiers.contains(VCARD_TEL_ISDN) || + qualifiers.contains(VCARD_TEL_VIDEO) || + qualifiers.contains(VCARD_TEL_PCS) + ) ) + return true; + if ( name == VCARD_TZ ) + return true; + if ( name == VCARD_TITLE ) + return true; + break; + + case 'u': + if ( name == VCARD_URL ) + return true; + if ( name == VCARD_UID ) + return true; + break; + + case 'v': + if ( name == VCARD_VERSION ) + return true; + break; + default: + break; + } + + return false; +} + + +VCard21Parser::VCard21Parser() +{ +} + +VCard21Parser::~VCard21Parser() +{ +} + +void VCard21Parser::readFromString(KABC::AddressBook *addressbook, const QString &data) +{ + KABC::Addressee mAddressee = readFromString(data); + addressbook->insertAddressee(mAddressee); +} + +KABC::Addressee VCard21Parser::readFromString( const QString &data) +{ + KABC::Addressee addressee; + VCard21ParserImpl *vCard = VCard21ParserImpl::parseVCard(data); + QString tmpStr; + + // Check if parsing failed + if (vCard == 0) + { + kdDebug() << "Parsing failed" << endl; + return addressee; + } + //set the addressees name and formated name + QStringList tmpList = vCard->getValues(VCARD_N); + QString formattedName = ""; + if (tmpList.count() > 0) + addressee.setFamilyName(tmpList[0]); + if (tmpList.count() > 1) + addressee.setGivenName(tmpList[1]); + if (tmpList.count() > 2) + addressee.setAdditionalName(tmpList[2]); + if (tmpList.count() > 3) + addressee.setPrefix(tmpList[3]); + if (tmpList.count() > 4) + addressee.setSuffix(tmpList[4]); + + tmpStr = (vCard->getValue(VCARD_FN)); + if (!tmpStr.isEmpty()) + addressee.setFormattedName(tmpStr); + + //set the addressee's nick name + tmpStr = vCard->getValue(VCARD_NICKNAME); + addressee.setNickName(tmpStr); + //set the addressee's organization + tmpStr = vCard->getValue(VCARD_ORG); + addressee.setOrganization(tmpStr); + //set the addressee's title + tmpStr = vCard->getValue(VCARD_TITLE); + addressee.setTitle(tmpStr); + //set the addressee's email - we can only deal with two. The preferenced one and one other. + tmpStr = vCard->getValue(VCARD_EMAIL, VCARD_EMAIL_INTERNET); + addressee.insertEmail(tmpStr, false); + tmpStr = vCard->getValue(VCARD_EMAIL,VCARD_EMAIL_PREF); + addressee.insertEmail(tmpStr, true); + //set the addressee's url + tmpStr = vCard->getValue(VCARD_URL); + if (tmpStr.isEmpty()) tmpStr = vCard->getValue(VCARD_URL, VCARD_ADR_WORK); + if (tmpStr.isEmpty()) tmpStr = vCard->getValue(VCARD_URL, VCARD_ADR_HOME); + if (!tmpStr.isEmpty()) { + addressee.setUrl(KURL(tmpStr)); + } + + //set the addressee's birthday + tmpStr = vCard->getValue(VCARD_BDAY); + addressee.setBirthday(VCardStringToDate(tmpStr)); + + //set the addressee's phone numbers + for ( QValueListIterator<VCardLineX> i = vCard->_vcdata->begin();i != vCard->_vcdata->end(); ++i ) { + if ( (*i).name == VCARD_TEL ) { + int type = 0; + if ( (*i).qualified ) { + if ( (*i).qualifiers.contains( VCARD_TEL_HOME ) ) + type |= PhoneNumber::Home; + if ( (*i).qualifiers.contains( VCARD_TEL_WORK ) ) + type |= PhoneNumber::Work; + if ( (*i).qualifiers.contains( VCARD_TEL_PREF ) ) + type |= PhoneNumber::Pref; + // if ( (*i).qualifiers.contains( VCARD_TEL_VOICE ) ) + // type |= PhoneNumber::Voice; + if ( (*i).qualifiers.contains( VCARD_TEL_FAX ) ) + type |= PhoneNumber::Fax; + if ( (*i).qualifiers.contains( VCARD_TEL_MSG ) ) + type |= PhoneNumber::Msg; + if ( (*i).qualifiers.contains( VCARD_TEL_CELL ) ) + type |= PhoneNumber::Cell; + if ( (*i).qualifiers.contains( VCARD_TEL_PAGER ) ) + type |= PhoneNumber::Pager; + if ( (*i).qualifiers.contains( VCARD_TEL_BBS ) ) + type |= PhoneNumber::Bbs; + if ( (*i).qualifiers.contains( VCARD_TEL_MODEM ) ) + type |= PhoneNumber::Modem; + if ( (*i).qualifiers.contains( VCARD_TEL_CAR ) ) + type |= PhoneNumber::Car; + if ( (*i).qualifiers.contains( VCARD_TEL_ISDN ) ) + type |= PhoneNumber::Isdn; + if ( (*i).qualifiers.contains( VCARD_TEL_VIDEO ) ) + type |= PhoneNumber::Video; + if ( (*i).qualifiers.contains( VCARD_TEL_PCS ) ) + type |= PhoneNumber::Pcs; + } + addressee.insertPhoneNumber( PhoneNumber( (*i).parameters[ 0 ], type ) ); + } + } + + //set the addressee's addresses + for ( QValueListIterator<VCardLineX> i = vCard->_vcdata->begin();i != vCard->_vcdata->end(); ++i ) { + if ( (*i).name == VCARD_ADR ) { + int type = 0; + if ( (*i).qualified ) { + if ( (*i).qualifiers.contains( VCARD_ADR_DOM ) ) + type |= Address::Dom; + if ( (*i).qualifiers.contains( VCARD_ADR_INTL ) ) + type |= Address::Intl; + if ( (*i).qualifiers.contains( VCARD_ADR_POSTAL ) ) + type |= Address::Postal; + if ( (*i).qualifiers.contains( VCARD_ADR_PARCEL ) ) + type |= Address::Parcel; + if ( (*i).qualifiers.contains( VCARD_ADR_HOME ) ) + type |= Address::Home; + if ( (*i).qualifiers.contains( VCARD_ADR_WORK ) ) + type |= Address::Work; + if ( (*i).qualifiers.contains( VCARD_ADR_PREF ) ) + type |= Address::Pref; + } + addressee.insertAddress( readAddressFromQStringList( (*i).parameters, type ) ); + } + } + + //set the addressee's delivery label + tmpStr = vCard->getValue(VCARD_LABEL); + if (!tmpStr.isEmpty()) { + tmpStr.replace("\r\n","\n"); + Address tmpAddress; + tmpAddress.setLabel(tmpStr); + addressee.insertAddress(tmpAddress); + } + + //set the addressee's notes + tmpStr = vCard->getValue(VCARD_NOTE); + tmpStr.replace("\r\n","\n"); + addressee.setNote(tmpStr); + + //set the addressee's timezone + tmpStr = vCard->getValue(VCARD_TZ); + TimeZone tmpZone(tmpStr.toInt()); + addressee.setTimeZone(tmpZone); + + //set the addressee's geographical position + tmpList = vCard->getValues(VCARD_GEO); + if (tmpList.count()==2) + { + tmpStr = tmpList[0]; + float glat = tmpStr.toFloat(); + tmpStr = tmpList[1]; + float glong = tmpStr.toFloat(); + Geo tmpGeo(glat,glong); + addressee.setGeo(tmpGeo); + } + + //set the last revision date + tmpStr = vCard->getValue(VCARD_REV); + addressee.setRevision(VCardStringToDate(tmpStr)); + + //set the role of the addressee + tmpStr = vCard->getValue(VCARD_ROLE); + addressee.setRole(tmpStr); + + delete vCard; + + return addressee; +} + + + +KABC::Address VCard21Parser::readAddressFromQStringList ( const QStringList &data, const int type ) +{ + KABC::Address mAddress; + mAddress.setType( type ); + + if ( data.count() > 0 ) + mAddress.setPostOfficeBox( data[0] ); + if ( data.count() > 1 ) + mAddress.setExtended( data[1] ); + if ( data.count() > 2 ) + mAddress.setStreet( data[2] ); + if ( data.count() > 3 ) + mAddress.setLocality( data[3] ); + if ( data.count() > 4 ) + mAddress.setRegion( data[4] ); + if ( data.count() > 5 ) + mAddress.setPostalCode( data[5] ); + if ( data.count() > 6 ) + mAddress.setCountry( data[6] ); + + return mAddress; +} + + +VCard21ParserImpl *VCard21ParserImpl::parseVCard( const QString& vc, int *err ) +{ + int _err = 0; + int _state = VC_STATE_BEGIN; + + QValueList<VCardLineX> *vcdata; + QValueList<QString> lines; + + vcdata = new QValueList<VCardLineX>; + + lines = QStringList::split( QRegExp( "[\x0d\x0a]" ), vc ); + + // for each line in the vCard + for ( QStringList::Iterator j = lines.begin(); j != lines.end(); ++j ) { + VCardLineX _vcl; + + // take spaces off the end - ugly but necessary hack + for ( int g = (*j).length()-1; g > 0 && (*j)[g].isSpace(); --g ) + (*j)[g] = 0; + + // first token: + // verify state, update if necessary + if ( _state & VC_STATE_BEGIN) { + if ( !qstricmp( (*j).latin1(), VCARD_BEGIN ) ) { + _state = VC_STATE_BODY; + continue; + } else { + _err = VC_ERR_NO_BEGIN; + break; + } + } else if ( _state & VC_STATE_BODY ) { + if ( !qstricmp( (*j).latin1(), VCARD_END ) ) { + _state |= VC_STATE_END; + break; + } + + // split into two tokens + int colon = (*j).find( ':' ); + if ( colon < 0 ) { + _err = VC_ERR_INVALID_LINE; + break; + } + + QString key = (*j).left( colon ); + QString value = (*j).mid( colon + 1 ); + + // check for qualifiers and + // set name, qualified, qualifier(s) + QStringList keyTokens = QStringList::split( ';', key ); + bool qp = false, first_pass = true; + bool b64 = false; + + if ( keyTokens.count() > 0 ) { + _vcl.qualified = false; + _vcl.name = keyTokens[ 0 ].lower(); + + for ( QStringList::Iterator z = keyTokens.begin(); z != keyTokens.end(); ++z ) { + QString zz = (*z).lower(); + if ( zz == VCARD_QUOTED_PRINTABLE || zz == VCARD_ENCODING_QUOTED_PRINTABLE ) { + qp = true; + } else if ( zz == VCARD_BASE64 ) { + b64 = true; + } else if ( !first_pass ) { + _vcl.qualified = true; + _vcl.qualifiers.append( zz ); + } + first_pass = false; + } + } else { + _err = VC_ERR_INVALID_LINE; + } + + if ( _err != 0 ) + break; + + if ( _vcl.name == VCARD_VERSION ) + _state |= VC_STATE_HAVE_VERSION; + + if ( _vcl.name == VCARD_N || _vcl.name == VCARD_FN ) + _state |= VC_STATE_HAVE_N; + + // second token: + // split into tokens by ; + // add to parameters vector + if ( b64 ) { + if ( value[ value.length() - 1 ] != '=' ) + do { + value += *( ++j ); + } while ( (*j)[ (*j).length() - 1 ] != '=' ); + } else { + if ( qp ) { // join any split lines + while ( value[ value.length() - 1 ] == '=' ) { + value.remove( value.length() - 1, 1 ); + value.append(*( ++j )); + } + } + _vcl.parameters = QStringList::split( ';', value, true ); + if ( qp ) { // decode the quoted printable + for ( QStringList::Iterator z = _vcl.parameters.begin(); z != _vcl.parameters.end(); ++z ) + *z = KCodecs::quotedPrintableDecode( (*z).latin1() ); + } + } + } else { + _err = VC_ERR_INTERNAL; + break; + } + + // validate VCardLineX + if ( !_vcl.isValid() ) { + _err = VC_ERR_INVALID_LINE; + break; + } + + // add to vector + vcdata->append( _vcl ); + } + + // errors to check at the last minute (exit state related) + if ( _err == 0 ) { + if ( !( _state & VC_STATE_END ) ) // we have to have an end!! + _err = VC_ERR_NO_END; + + if ( !( _state & VC_STATE_HAVE_N ) || // we have to have the mandatories! + !( _state & VC_STATE_HAVE_VERSION ) ) + _err = VC_ERR_MISSING_MANDATORY; + } + + // set the error message if we can, and only return an object + // if the vCard was valid. + if ( err ) + *err = _err; + + if ( _err != 0 ) { + delete vcdata; + return 0; + } + + return new VCard21ParserImpl( vcdata ); +} + +VCard21ParserImpl::VCard21ParserImpl() + : _vcdata( 0 ) +{ +} + +VCard21ParserImpl::VCard21ParserImpl(QValueList<VCardLineX> *_vcd) + : _vcdata(_vcd) +{ +} + +VCard21ParserImpl::~VCard21ParserImpl() +{ + delete _vcdata; + _vcdata = 0; +} + +QString VCard21ParserImpl::getValue(const QString& name, const QString& qualifier) +{ + QString failed; + const QString lowname = name.lower(); + const QString lowqualifier = qualifier.lower(); + + for (QValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { + if ((*i).name == lowname && (*i).qualified && (*i).qualifiers.contains(lowqualifier)) { + if ((*i).parameters.count() > 0) + return (*i).parameters[0]; + else return failed; + } + } + return failed; +} + + +QString VCard21ParserImpl::getValue(const QString& name) +{ + QString failed; + const QString lowname = name.lower(); + + for (QValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { + if ((*i).name == lowname && !(*i).qualified) { + if ((*i).parameters.count() > 0) + return (*i).parameters[0]; + else return failed; + } + } + return failed; +} + + +QStringList VCard21ParserImpl::getValues(const QString& name) +{ + const QString lowname = name.lower(); + for (QValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { + if ((*i).name == lowname && !(*i).qualified) + return (*i).parameters; + } + // failed. + return QStringList(); +} + +QStringList VCard21ParserImpl::getValues(const QString& name, const QString& qualifier) +{ + const QString lowname = name.lower(); + const QString lowqualifier = qualifier.lower(); + for (QValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { + if ((*i).name == lowname && (*i).qualified && (*i).qualifiers.contains(lowqualifier)) + return (*i).parameters; + } + // failed. + return QStringList(); +} + + diff --git a/kabc/vcard21parser.h b/kabc/vcard21parser.h new file mode 100644 index 000000000..0c9e3db8a --- /dev/null +++ b/kabc/vcard21parser.h @@ -0,0 +1,221 @@ +/* + This file is part of libkabc. + + Copyright (c) 2002 Mark Westcott <mark@houseoffish.org> + Copyright (c) 2000 George Staikos <staikos@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_VCARD21FORMAT_H +#define KABC_VCARD21FORMAT_H + +#include <qdatetime.h> +#include <kdebug.h> +#include <qregexp.h> +#include <qstring.h> +#include <kurl.h> +#include <qvaluelist.h> + +#include "addressee.h" +#include "addressbook.h" +#include "phonenumber.h" + + +#define VCARD_BEGIN "begin:vcard" +#define VCARD_END "end:vcard" +#define VCARD_BEGIN_N "begin" +#define VCARD_END_N "end" +#define VCARD_VERSION "version" + +#define VCARD_FN "fn" +#define VCARD_N "n" + +// optional +#define VCARD_NAME "name" +#define VCARD_NICKNAME "nickname" +#define VCARD_PHOTO "photo" +#define VCARD_BDAY "bday" +#define VCARD_ADR "adr" + +// types +#define VCARD_ADR_DOM "dom" +#define VCARD_ADR_INTL "intl" +#define VCARD_ADR_POSTAL "postal" +#define VCARD_ADR_PARCEL "parcel" +#define VCARD_ADR_HOME "home" +#define VCARD_ADR_WORK "work" +#define VCARD_ADR_PREF "pref" +// values +#define VCARD_ADR_POBOX "PO Box" +#define VCARD_ADR_EXTADR "Extended Address" +#define VCARD_ADR_STREET "Street" +#define VCARD_ADR_LOCALITY "Locality" +#define VCARD_ADR_REGION "Region" +#define VCARD_ADR_POSTCODE "Postal Code" +#define VCARD_ADR_COUNTRY "Country Name" +#define VCARD_LABEL "label" +#define VCARD_PROFILE "profile" +#define VCARD_SOURCE "source" +#define VCARD_TEL "tel" +// types +#define VCARD_TEL_HOME "home" +#define VCARD_TEL_WORK "work" +#define VCARD_TEL_PREF "pref" +#define VCARD_TEL_VOICE "voice" +#define VCARD_TEL_FAX "fax" +#define VCARD_TEL_MSG "msg" +#define VCARD_TEL_CELL "cell" +#define VCARD_TEL_PAGER "pager" +#define VCARD_TEL_BBS "bbs" +#define VCARD_TEL_MODEM "modem" +#define VCARD_TEL_CAR "car" +#define VCARD_TEL_ISDN "isdn" +#define VCARD_TEL_VIDEO "video" +#define VCARD_TEL_PCS "pcs" +#define VCARD_EMAIL "email" +// types +#define VCARD_EMAIL_PREF "pref" +#define VCARD_EMAIL_INTERNET "internet" +#define VCARD_EMAIL_X400 "x400" +#define VCARD_TZ "tz" +#define VCARD_GEO "geo" +#define VCARD_MAILER "mailer" +#define VCARD_TITLE "title" +#define VCARD_ROLE "role" +#define VCARD_LOGO "logo" +#define VCARD_AGENT "agent" +#define VCARD_ORG "org" +#define VCARD_CATEGORIES "categories" +#define VCARD_NOTE "note" +#define VCARD_PRODID "prodid" +#define VCARD_REV "rev" +#define VCARD_SOUND "sound" +#define VCARD_UID "uid" +#define VCARD_URL "url" +#define VCARD_CLASS "class" +#define VCARD_CLASS_PUBLIC "public" +#define VCARD_CLASS_PRIVATE "private" +#define VCARD_CLASS_CONFIDENTIAL "confidential" +#define VCARD_KEY "key" +// types +#define VCARD_KEY_X509 "x509" +#define VCARD_KEY_PGP "pgp" + +#define VCARD_QUOTED_PRINTABLE "quoted-printable" +// this one is a temporary hack until we support TYPE=VALUE +#define VCARD_ENCODING_QUOTED_PRINTABLE "encoding=quoted-printable" +#define VCARD_BASE64 "base64" + +#define VC_STATE_BEGIN 1 +#define VC_STATE_BODY 2 +#define VC_STATE_END 4 +#define VC_STATE_HAVE_N 8 +#define VC_STATE_HAVE_VERSION 16 + +#define VC_ERR_NO_BEGIN 1 +#define VC_ERR_NO_END 2 +#define VC_ERR_INVALID_LINE 3 +#define VC_ERR_INTERNAL 4 +#define VC_ERR_INVALID_NAME 5 +#define VC_ERR_MISSING_MANDATORY 6 + +namespace KABC { + +class AddressBook; + +/** + @deprecated use VCardConverter instead. + */ +class KABC_EXPORT_DEPRECATED VCard21Parser +{ +public: + + /** + * Constructor. + */ + VCard21Parser(); + + /** + * Destructor. + */ + virtual ~VCard21Parser(); + + /** + * Parses a string in vcard2.1 format and saves the single addressees + * to the address book. + * + * @param ab The address book. + * @param str The vcard string. + */ + void readFromString( KABC::AddressBook *ab, const QString &str ); + + /** + * FIXME: we need a writeToString method + * QString writeToString (KABC::AddressBook *); + */ + + /** + * Parses a string in vcard2.1 format and returns the inherent addressee. + */ + KABC::Addressee readFromString( const QString &data); + + /** + * Helper method to store a address. + * + * @param data A string list, that is filled with 'street', 'house number' ... + * @param type The type of the returned address. + */ + static KABC::Address readAddressFromQStringList (const QStringList &data, const int type); +}; + +} + +/** + * @short Helper class + */ +class KABC_EXPORT VCardLineX +{ +public: + QString name; + bool qualified; + QValueList<QString> qualifiers; + QValueList<QString> parameters; + bool isValid() const; +}; + +/** + * @short Helper class + */ +class KABC_EXPORT VCard21ParserImpl +{ + friend class VCardLineX; + +public: + VCard21ParserImpl(); + virtual ~VCard21ParserImpl(); + static VCard21ParserImpl *parseVCard(const QString& vc, int *err = NULL); + QString getValue(const QString& name, const QString& qualifier); + QString getValue(const QString& name); + QStringList getValues(const QString& name, const QString& qualifier); + QStringList getValues(const QString& name); + + QValueList<VCardLineX> *_vcdata; + +private: + VCard21ParserImpl (QValueList<VCardLineX> *_vcd); +}; + +#endif diff --git a/kabc/vcardconverter.cpp b/kabc/vcardconverter.cpp new file mode 100644 index 000000000..42283488a --- /dev/null +++ b/kabc/vcardconverter.cpp @@ -0,0 +1,129 @@ +/* + 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 "vcard21parser.h" +#include "vcardformatimpl.h" +#include "vcardtool.h" + +#include "vcardconverter.h" + +using namespace KABC; + +struct VCardConverter::VCardConverterData +{ + VCard21Parser vcard21parser; + VCardFormatImpl vcard30parser; +}; + +VCardConverter::VCardConverter() + : d( new VCardConverterData ) +{ +} + +VCardConverter::~VCardConverter() +{ + delete d; + d = 0; +} + +QString VCardConverter::createVCard( const Addressee &addr, Version version ) +{ + Addressee::List list; + list.append( addr ); + + return createVCards( list, version ); +} + +QString VCardConverter::createVCards( Addressee::List list, Version version ) +{ + VCardTool tool; + + return tool.createVCards( list, ( version == v3_0 ? VCard::v3_0 : VCard::v2_1 ) ); +} + +Addressee VCardConverter::parseVCard( const QString& vcard ) +{ + Addressee::List list = parseVCards( vcard ); + + return list[ 0 ]; +} + +Addressee::List VCardConverter::parseVCards( const QString& vcard ) +{ + VCardTool tool; + + return tool.parseVCards( vcard ); +} + +// ---------------------------- deprecated stuff ---------------------------- // + +bool VCardConverter::vCardToAddressee( const QString &str, Addressee &addr, Version version ) +{ + if ( version == v2_1 ) { + addr = d->vcard21parser.readFromString( str ); + return true; + } + + if ( version == v3_0 ) + return d->vcard30parser.readFromString( str, addr ); + + return false; +} + +bool VCardConverter::addresseeToVCard( const Addressee &addr, QString &str, Version version ) +{ + if ( version == v2_1 ) + return false; + + if ( version == v3_0 ) + return d->vcard30parser.writeToString( addr, str ); + + return false; +} + + +/* Helper functions */ + +QString KABC::dateToVCardString( const QDateTime &dateTime ) +{ + return dateTime.toString("yyyyMMddThhmmssZ"); +} + +QString KABC::dateToVCardString( const QDate &date ) +{ + return date.toString("yyyyMMdd"); +} + +QDateTime KABC::VCardStringToDate( const QString &dateString ) +{ + QDate date; + QTime time; + QString d( dateString ); + + d = d.remove('-').remove(':'); + + if (d.length()>=8) + date = QDate( d.mid(0,4).toUInt(), d.mid(4,2).toUInt(), d.mid(6,2).toUInt() ); + if (d.length()>9 && d[8].upper()=='T') + time = QTime( d.mid(9,2).toUInt(), d.mid(11,2).toUInt(), d.mid(13,2).toUInt() ); + + return QDateTime( date, time ); +} + diff --git a/kabc/vcardconverter.h b/kabc/vcardconverter.h new file mode 100644 index 000000000..6c427d0a9 --- /dev/null +++ b/kabc/vcardconverter.h @@ -0,0 +1,163 @@ +/* + 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_VCARDCONVERTER_H +#define KABC_VCARDCONVERTER_H + +#include <qstring.h> + +#include "addressee.h" + +namespace KABC { + +/** + @short Class to converting contact objects into vCard format and vice versa. + + This class implements reading and writing of contact using from/to the + vCard format. Currently vCard version 2.1 and 3.0 is supported. + + Example: + + \code + + QFile file( "myfile.vcf" ); + file.open( IO_ReadOnly ); + + QString data = file.readAll(); + + VCardConverter converter; + Addressee::List list = converter.parseVCards( data ); + + // print formatted name of first contact + qDebug( "name=%s", list[ 0 ].formattedName().latin1() ); + + \endcode +*/ +class KABC_EXPORT VCardConverter +{ + public: + + /** + @li v2_1 - VCard format version 2.1 + @li v3_0 - VCard format version 3.0 + */ + enum Version + { + v2_1, + v3_0 + }; + + /** + Constructor. + */ + VCardConverter(); + + /** + Destructor. + */ + ~VCardConverter(); + + /** + Creates a string in vCard format which contains the given + contact. + + @param addr The contact object + @param version The version of the generated vCard format + */ + QString createVCard( const Addressee &addr, Version version = v3_0 ); + + /** + Creates a string in vCard format which contains the given + list of contact. + + @param list The list of contact objects + @param version The version of the generated vCard format + */ + // FIXME: Add error handling + QString createVCards( Addressee::List list, Version version = v3_0 ); + + // FIXME: Add "createVCards( AddressBook * )" + + /** + Parses a string in vCard format and returns the first contact. + */ + Addressee parseVCard( const QString& vcard ); + + /** + Parses a string in vCard format and returns a list of contact objects. + */ + // FIXME: Add error handling + Addressee::List parseVCards( const QString& vcard ); + + // FIXME: Add "bool parseVCards( AddressBook *, const QString &vcard )" + + /** + @deprecated + */ + bool vCardToAddressee( const QString&, Addressee &, Version version = v3_0 ) KDE_DEPRECATED; + + /** + @deprecated + */ + bool addresseeToVCard( const Addressee&, QString&, Version version = v3_0 ) KDE_DEPRECATED; + + private: + /** + Split a string and replaces escaped separators on the fly with + unescaped ones. + */ + QStringList splitString( const QChar &sep, const QString &value ); + + struct VCardConverterData; + VCardConverterData *d; +}; + + +/** + Helper functions + */ + +/** + * Converts a QDateTime to a date string as it is used in VCard and LDIF files. + * The return value is in the form "yyyyMMddThhmmssZ" (e.g. "20031201T120000Z") + * @param dateTime date and time to be converted + * @since 3.2 + */ +KABC_EXPORT QString dateToVCardString( const QDateTime &dateTime ); + +/** + * Converts a QDate to a short date string as it is used in VCard and LDIF files. + * The return value is in the form "yyyyMMdd" (e.g. "20031201") + * @param date date to be converted + * @since 3.2 + */ +KABC_EXPORT QString dateToVCardString( const QDate &date ); + +/** + * Converts a date string as it is used in VCard and LDIF files to a QDateTime value. + * If the date string does not contain a time value, it will be returned as 00:00:00. + * (e.g. "20031201T120000" will return a QDateTime for 2003-12-01 at 12:00) + * @param dateString string representing the date and time. + * @since 3.2 + */ +KABC_EXPORT QDateTime VCardStringToDate( const QString &dateString ); + +} +#endif diff --git a/kabc/vcardformat.cpp b/kabc/vcardformat.cpp new file mode 100644 index 000000000..ec2d4806e --- /dev/null +++ b/kabc/vcardformat.cpp @@ -0,0 +1,59 @@ +/* + 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 "vcardformatimpl.h" + +#include "vcardformat.h" + +using namespace KABC; + +VCardFormat::VCardFormat() +{ + mImpl = new VCardFormatImpl; +} + +VCardFormat::~VCardFormat() +{ + delete mImpl; +} + +bool VCardFormat::load( AddressBook *addressBook, const QString &fileName ) +{ + QFile f( fileName ); + if ( !f.open( IO_ReadOnly ) ) return false; + + bool result = mImpl->loadAll( addressBook, 0, &f ); + + f.close(); + + return result; +} + +bool VCardFormat::save( AddressBook *addressBook, const QString &fileName ) +{ + QFile f( fileName ); + if ( !f.open( IO_WriteOnly ) ) return false; + + mImpl->saveAll( addressBook, 0, &f ); + + f.close(); + + return true; +} diff --git a/kabc/vcardformat.h b/kabc/vcardformat.h new file mode 100644 index 000000000..6d90c4836 --- /dev/null +++ b/kabc/vcardformat.h @@ -0,0 +1,49 @@ +/* + 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_VCARDFORMAT_H +#define KABC_VCARDFORMAT_H + +#include <qstring.h> + +#include "format.h" + +namespace KABC { + +class AddressBook; +class VCardFormatImpl; + +/** + @deprecated use VCardFormatPlugin instead. + */ +class KABC_EXPORT_DEPRECATED VCardFormat : public Format { + public: + VCardFormat(); + virtual ~VCardFormat(); + + bool load( AddressBook *, const QString &fileName ); + bool save( AddressBook *, const QString &fileName ); + + private: + VCardFormatImpl *mImpl; +}; + +} + +#endif diff --git a/kabc/vcardformatimpl.cpp b/kabc/vcardformatimpl.cpp new file mode 100644 index 000000000..cfaccd056 --- /dev/null +++ b/kabc/vcardformatimpl.cpp @@ -0,0 +1,996 @@ +/* + 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 <qfile.h> +#include <qregexp.h> + +#include <kdebug.h> +#include <kmdcodec.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#include <VCard.h> + +#include "addressbook.h" +#include "vcardformatimpl.h" + +using namespace KABC; +using namespace VCARD; + +bool VCardFormatImpl::load( Addressee &addressee, QFile *file ) +{ + kdDebug(5700) << "VCardFormat::load()" << endl; + + QByteArray fdata = file->readAll(); + QCString data(fdata.data(), fdata.size()+1); + + VCardEntity e( data ); + + VCardListIterator it( e.cardList() ); + + if ( it.current() ) { + VCARD::VCard v(*it.current()); + loadAddressee( addressee, v ); + return true; + } + + return false; +} + +bool VCardFormatImpl::loadAll( AddressBook *addressBook, Resource *resource, QFile *file ) +{ + kdDebug(5700) << "VCardFormat::loadAll()" << endl; + + QByteArray fdata = file->readAll(); + QCString data(fdata.data(), fdata.size()+1); + + VCardEntity e( data ); + + VCardListIterator it( e.cardList() ); + + for (; it.current(); ++it) { + VCARD::VCard v(*it.current()); + Addressee addressee; + loadAddressee( addressee, v ); + addressee.setResource( resource ); + addressBook->insertAddressee( addressee ); + } + + return true; +} + +void VCardFormatImpl::save( const Addressee &addressee, QFile *file ) +{ + VCardEntity vcards; + VCardList vcardlist; + vcardlist.setAutoDelete( true ); + + VCARD::VCard *v = new VCARD::VCard; + + saveAddressee( addressee, v, false ); + + vcardlist.append( v ); + vcards.setCardList( vcardlist ); + + QCString vcardData = vcards.asString(); + file->writeBlock( (const char*)vcardData, vcardData.length() ); +} + +void VCardFormatImpl::saveAll( AddressBook *ab, Resource *resource, QFile *file ) +{ + VCardEntity vcards; + VCardList vcardlist; + vcardlist.setAutoDelete( true ); + + AddressBook::Iterator it; + for ( it = ab->begin(); it != ab->end(); ++it ) { + if ( (*it).resource() == resource ) { + VCARD::VCard *v = new VCARD::VCard; + saveAddressee( (*it), v, false ); + (*it).setChanged( false ); + vcardlist.append( v ); + } + } + + vcards.setCardList( vcardlist ); + + QCString vcardData = vcards.asString(); + file->writeBlock( (const char*)vcardData, vcardData.length() ); +} + +bool VCardFormatImpl::loadAddressee( Addressee& addressee, VCARD::VCard &v ) +{ + QPtrList<ContentLine> contentLines = v.contentLineList(); + ContentLine *cl; + + for( cl = contentLines.first(); cl; cl = contentLines.next() ) { + QCString n = cl->name(); + if ( n.left( 2 ) == "X-" ) { + n = n.mid( 2 ); + int posDash = n.find( "-" ); + addressee.insertCustom( QString::fromUtf8( n.left( posDash ) ), + QString::fromUtf8( n.mid( posDash + 1 ) ), + QString::fromUtf8( cl->value()->asString() ) ); + continue; + } + + EntityType type = cl->entityType(); + switch( type ) { + + case EntityUID: + addressee.setUid( readTextValue( cl ) ); + break; + + case EntityEmail: + addressee.insertEmail( readTextValue( cl ) ); + break; + + case EntityName: + addressee.setName( readTextValue( cl ) ); + break; + + case EntityFullName: + addressee.setFormattedName( readTextValue( cl ) ); + break; + + case EntityURL: + addressee.setUrl( KURL( readTextValue( cl ) ) ); + break; + + case EntityNickname: + addressee.setNickName( readTextValue( cl ) ); + break; + + case EntityLabel: + // not yet supported by kabc + break; + + case EntityMailer: + addressee.setMailer( readTextValue( cl ) ); + break; + + case EntityTitle: + addressee.setTitle( readTextValue( cl ) ); + break; + + case EntityRole: + addressee.setRole( readTextValue( cl ) ); + break; + + case EntityOrganisation: + addressee.setOrganization( readTextValue( cl ) ); + break; + + case EntityNote: + addressee.setNote( readTextValue( cl ) ); + break; + + case EntityProductID: + addressee.setProductId( readTextValue( cl ) ); + break; + + case EntitySortString: + addressee.setSortString( readTextValue( cl ) ); + break; + + case EntityN: + readNValue( cl, addressee ); + break; + + case EntityAddress: + addressee.insertAddress( readAddressValue( cl ) ); + break; + + case EntityTelephone: + addressee.insertPhoneNumber( readTelephoneValue( cl ) ); + break; + + case EntityCategories: + addressee.setCategories( QStringList::split( ",", readTextValue( cl ) ) ); + break; + + case EntityBirthday: + addressee.setBirthday( readDateValue( cl ) ); + break; + + case EntityRevision: + addressee.setRevision( readDateTimeValue( cl ) ); + break; + + case EntityGeo: + addressee.setGeo( readGeoValue( cl ) ); + break; + + case EntityTimeZone: + addressee.setTimeZone( readUTCValue( cl ) ); + break; + + case EntityVersion: + break; + + case EntityClass: + addressee.setSecrecy( readClassValue( cl ) ); + break; + + case EntityKey: + addressee.insertKey( readKeyValue( cl ) ); + break; + + case EntityPhoto: + addressee.setPhoto( readPictureValue( cl, EntityPhoto, addressee ) ); + break; + + case EntityLogo: + addressee.setLogo( readPictureValue( cl, EntityLogo, addressee ) ); + break; + + case EntityAgent: + addressee.setAgent( readAgentValue( cl ) ); + break; + + case EntitySound: + addressee.setSound( readSoundValue( cl, addressee ) ); + break; + + default: + kdDebug(5700) << "VCardFormat::load(): Unsupported entity: " + << int( type ) << ": " << cl->asString() << endl; + break; + } + } + + for( cl = contentLines.first(); cl; cl = contentLines.next() ) { + EntityType type = cl->entityType(); + if ( type == EntityLabel ) { + int type = readAddressParam( cl ); + Address address = addressee.address( type ); + if ( address.isEmpty() ) + address.setType( type ); + + address.setLabel( QString::fromUtf8( cl->value()->asString() ) ); + addressee.insertAddress( address ); + } + } + + return true; +} + +void VCardFormatImpl::saveAddressee( const Addressee &addressee, VCARD::VCard *v, bool intern ) +{ + ContentLine cl; + QString value; + + addTextValue( v, EntityName, addressee.name() ); + addTextValue( v, EntityUID, addressee.uid() ); + addTextValue( v, EntityFullName, addressee.formattedName() ); + + QStringList emails = addressee.emails(); + QStringList::ConstIterator it4; + for( it4 = emails.begin(); it4 != emails.end(); ++it4 ) { + addTextValue( v, EntityEmail, *it4 ); + } + + QStringList customs = addressee.customs(); + QStringList::ConstIterator it5; + for( it5 = customs.begin(); it5 != customs.end(); ++it5 ) { + addCustomValue( v, *it5 ); + } + + addTextValue( v, EntityURL, addressee.url().url() ); + + addNValue( v, addressee ); + + addTextValue( v, EntityNickname, addressee.nickName() ); + addTextValue( v, EntityMailer, addressee.mailer() ); + addTextValue( v, EntityTitle, addressee.title() ); + addTextValue( v, EntityRole, addressee.role() ); + addTextValue( v, EntityOrganisation, addressee.organization() ); + addTextValue( v, EntityNote, addressee.note() ); + addTextValue( v, EntityProductID, addressee.productId() ); + addTextValue( v, EntitySortString, addressee.sortString() ); + + Address::List addresses = addressee.addresses(); + Address::List::ConstIterator it3; + for( it3 = addresses.begin(); it3 != addresses.end(); ++it3 ) { + addAddressValue( v, *it3 ); + addLabelValue( v, *it3 ); + } + + PhoneNumber::List phoneNumbers = addressee.phoneNumbers(); + PhoneNumber::List::ConstIterator it2; + for( it2 = phoneNumbers.begin(); it2 != phoneNumbers.end(); ++it2 ) { + addTelephoneValue( v, *it2 ); + } + + Key::List keys = addressee.keys(); + Key::List::ConstIterator it6; + for( it6 = keys.begin(); it6 != keys.end(); ++it6 ) { + addKeyValue( v, *it6 ); + } + + addTextValue( v, EntityCategories, addressee.categories().join(",") ); + + addDateValue( v, EntityBirthday, addressee.birthday().date() ); + addDateTimeValue( v, EntityRevision, addressee.revision() ); + addGeoValue( v, addressee.geo() ); + addUTCValue( v, addressee.timeZone() ); + + addClassValue( v, addressee.secrecy() ); + + addPictureValue( v, EntityPhoto, addressee.photo(), addressee, intern ); + addPictureValue( v, EntityLogo, addressee.logo(), addressee, intern ); + + addAgentValue( v, addressee.agent() ); + + addSoundValue( v, addressee.sound(), addressee, intern ); +} + +void VCardFormatImpl::addCustomValue( VCARD::VCard *v, const QString &txt ) +{ + if ( txt.isEmpty() ) return; + + ContentLine cl; + cl.setName( "X-" + txt.left( txt.find( ":" ) ).utf8() ); + QString value = txt.mid( txt.find( ":" ) + 1 ); + if ( value.isEmpty() ) + return; + cl.setValue( new TextValue( value.utf8() ) ); + v->add(cl); +} + +void VCardFormatImpl::addTextValue( VCARD::VCard *v, EntityType type, const QString &txt ) +{ + if ( txt.isEmpty() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( type ) ); + cl.setValue( new TextValue( txt.utf8() ) ); + v->add(cl); +} + +void VCardFormatImpl::addDateValue( VCARD::VCard *vcard, EntityType type, + const QDate &date ) +{ + if ( !date.isValid() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( type ) ); + + DateValue *v = new DateValue( date ); + cl.setValue( v ); + vcard->add(cl); +} + +void VCardFormatImpl::addDateTimeValue( VCARD::VCard *vcard, EntityType type, + const QDateTime &dateTime ) +{ + if ( !dateTime.isValid() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( type ) ); + + DateValue *v = new DateValue( dateTime ); + cl.setValue( v ); + vcard->add(cl); +} + +void VCardFormatImpl::addAddressValue( VCARD::VCard *vcard, const Address &a ) +{ + if ( a.isEmpty() ) + return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityAddress ) ); + + AdrValue *v = new AdrValue; + v->setPOBox( a.postOfficeBox().utf8() ); + v->setExtAddress( a.extended().utf8() ); + v->setStreet( a.street().utf8() ); + v->setLocality( a.locality().utf8() ); + v->setRegion( a.region().utf8() ); + v->setPostCode( a.postalCode().utf8() ); + v->setCountryName( a.country().utf8() ); + cl.setValue( v ); + + addAddressParam( &cl, a.type() ); + + vcard->add( cl ); +} + +void VCardFormatImpl::addLabelValue( VCARD::VCard *vcard, const Address &a ) +{ + if ( a.label().isEmpty() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityLabel ) ); + cl.setValue( new TextValue( a.label().utf8() ) ); + + addAddressParam( &cl, a.type() ); + + vcard->add( cl ); +} + +void VCardFormatImpl::addAddressParam( ContentLine *cl, int type ) +{ + ParamList params; + if ( type & Address::Dom ) params.append( new Param( "TYPE", "dom" ) ); + if ( type & Address::Intl ) params.append( new Param( "TYPE", "intl" ) ); + if ( type & Address::Parcel ) params.append( new Param( "TYPE", "parcel" ) ); + if ( type & Address::Postal ) params.append( new Param( "TYPE", "postal" ) ); + if ( type & Address::Work ) params.append( new Param( "TYPE", "work" ) ); + if ( type & Address::Home ) params.append( new Param( "TYPE", "home" ) ); + if ( type & Address::Pref ) params.append( new Param( "TYPE", "pref" ) ); + cl->setParamList( params ); +} + +void VCardFormatImpl::addGeoValue( VCARD::VCard *vcard, const Geo &geo ) +{ + if ( !geo.isValid() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityGeo ) ); + + GeoValue *v = new GeoValue; + v->setLatitude( geo.latitude() ); + v->setLongitude( geo.longitude() ); + + cl.setValue( v ); + vcard->add(cl); +} + +void VCardFormatImpl::addUTCValue( VCARD::VCard *vcard, const TimeZone &tz ) +{ + if ( !tz.isValid() ) return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityTimeZone ) ); + + UTCValue *v = new UTCValue; + + v->setPositive( tz.offset() >= 0 ); + v->setHour( (tz.offset() / 60) * ( tz.offset() >= 0 ? 1 : -1 ) ); + v->setMinute( (tz.offset() % 60) * ( tz.offset() >= 0 ? 1 : -1 ) ); + + cl.setValue( v ); + vcard->add(cl); +} + +void VCardFormatImpl::addClassValue( VCARD::VCard *vcard, const Secrecy &secrecy ) +{ + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityClass ) ); + + ClassValue *v = new ClassValue; + switch ( secrecy.type() ) { + case Secrecy::Public: + v->setType( (int)ClassValue::Public ); + break; + case Secrecy::Private: + v->setType( (int)ClassValue::Private ); + break; + case Secrecy::Confidential: + v->setType( (int)ClassValue::Confidential ); + break; + } + + cl.setValue( v ); + vcard->add(cl); +} + + +Address VCardFormatImpl::readAddressValue( ContentLine *cl ) +{ + Address a; + AdrValue *v = (AdrValue *)cl->value(); + a.setPostOfficeBox( QString::fromUtf8( v->poBox() ) ); + a.setExtended( QString::fromUtf8( v->extAddress() ) ); + a.setStreet( QString::fromUtf8( v->street() ) ); + a.setLocality( QString::fromUtf8( v->locality() ) ); + a.setRegion( QString::fromUtf8( v->region() ) ); + a.setPostalCode( QString::fromUtf8( v->postCode() ) ); + a.setCountry( QString::fromUtf8( v->countryName() ) ); + + a.setType( readAddressParam( cl ) ); + + return a; +} + +int VCardFormatImpl::readAddressParam( ContentLine *cl ) +{ + int type = 0; + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "TYPE" ) { + if ( (*it)->value() == "dom" ) type |= Address::Dom; + else if ( (*it)->value() == "intl" ) type |= Address::Intl; + else if ( (*it)->value() == "parcel" ) type |= Address::Parcel; + else if ( (*it)->value() == "postal" ) type |= Address::Postal; + else if ( (*it)->value() == "work" ) type |= Address::Work; + else if ( (*it)->value() == "home" ) type |= Address::Home; + else if ( (*it)->value() == "pref" ) type |= Address::Pref; + } + } + return type; +} + +void VCardFormatImpl::addNValue( VCARD::VCard *vcard, const Addressee &a ) +{ + ContentLine cl; + cl.setName(EntityTypeToParamName( EntityN ) ); + NValue *v = new NValue; + v->setFamily( a.familyName().utf8() ); + v->setGiven( a.givenName().utf8() ); + v->setMiddle( a.additionalName().utf8() ); + v->setPrefix( a.prefix().utf8() ); + v->setSuffix( a.suffix().utf8() ); + + cl.setValue( v ); + vcard->add(cl); +} + +void VCardFormatImpl::readNValue( ContentLine *cl, Addressee &a ) +{ + NValue *v = (NValue *)cl->value(); + a.setFamilyName( QString::fromUtf8( v->family() ) ); + a.setGivenName( QString::fromUtf8( v->given() ) ); + a.setAdditionalName( QString::fromUtf8( v->middle() ) ); + a.setPrefix( QString::fromUtf8( v->prefix() ) ); + a.setSuffix( QString::fromUtf8( v->suffix() ) ); +} + +void VCardFormatImpl::addTelephoneValue( VCARD::VCard *v, const PhoneNumber &p ) +{ + if ( p.number().isEmpty() ) + return; + + ContentLine cl; + cl.setName(EntityTypeToParamName(EntityTelephone)); + cl.setValue(new TelValue( p.number().utf8() )); + + ParamList params; + if( p.type() & PhoneNumber::Home ) params.append( new Param( "TYPE", "home" ) ); + if( p.type() & PhoneNumber::Work ) params.append( new Param( "TYPE", "work" ) ); + if( p.type() & PhoneNumber::Msg ) params.append( new Param( "TYPE", "msg" ) ); + if( p.type() & PhoneNumber::Pref ) params.append( new Param( "TYPE", "pref" ) ); + if( p.type() & PhoneNumber::Voice ) params.append( new Param( "TYPE", "voice" ) ); + if( p.type() & PhoneNumber::Fax ) params.append( new Param( "TYPE", "fax" ) ); + if( p.type() & PhoneNumber::Cell ) params.append( new Param( "TYPE", "cell" ) ); + if( p.type() & PhoneNumber::Video ) params.append( new Param( "TYPE", "video" ) ); + if( p.type() & PhoneNumber::Bbs ) params.append( new Param( "TYPE", "bbs" ) ); + if( p.type() & PhoneNumber::Modem ) params.append( new Param( "TYPE", "modem" ) ); + if( p.type() & PhoneNumber::Car ) params.append( new Param( "TYPE", "car" ) ); + if( p.type() & PhoneNumber::Isdn ) params.append( new Param( "TYPE", "isdn" ) ); + if( p.type() & PhoneNumber::Pcs ) params.append( new Param( "TYPE", "pcs" ) ); + if( p.type() & PhoneNumber::Pager ) params.append( new Param( "TYPE", "pager" ) ); + cl.setParamList( params ); + + v->add(cl); +} + +PhoneNumber VCardFormatImpl::readTelephoneValue( ContentLine *cl ) +{ + PhoneNumber p; + TelValue *value = (TelValue *)cl->value(); + p.setNumber( QString::fromUtf8( value->asString() ) ); + + int type = 0; + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "TYPE" ) { + if ( (*it)->value() == "home" ) type |= PhoneNumber::Home; + else if ( (*it)->value() == "work" ) type |= PhoneNumber::Work; + else if ( (*it)->value() == "msg" ) type |= PhoneNumber::Msg; + else if ( (*it)->value() == "pref" ) type |= PhoneNumber::Pref; + else if ( (*it)->value() == "voice" ) type |= PhoneNumber::Voice; + else if ( (*it)->value() == "fax" ) type |= PhoneNumber::Fax; + else if ( (*it)->value() == "cell" ) type |= PhoneNumber::Cell; + else if ( (*it)->value() == "video" ) type |= PhoneNumber::Video; + else if ( (*it)->value() == "bbs" ) type |= PhoneNumber::Bbs; + else if ( (*it)->value() == "modem" ) type |= PhoneNumber::Modem; + else if ( (*it)->value() == "car" ) type |= PhoneNumber::Car; + else if ( (*it)->value() == "isdn" ) type |= PhoneNumber::Isdn; + else if ( (*it)->value() == "pcs" ) type |= PhoneNumber::Pcs; + else if ( (*it)->value() == "pager" ) type |= PhoneNumber::Pager; + } + } + p.setType( type ); + + return p; +} + +QString VCardFormatImpl::readTextValue( ContentLine *cl ) +{ + VCARD::Value *value = cl->value(); + if ( value ) { + return QString::fromUtf8( value->asString() ); + } else { + kdDebug(5700) << "No value: " << cl->asString() << endl; + return QString::null; + } +} + +QDate VCardFormatImpl::readDateValue( ContentLine *cl ) +{ + DateValue *dateValue = (DateValue *)cl->value(); + if ( dateValue ) + return dateValue->qdate(); + else + return QDate(); +} + +QDateTime VCardFormatImpl::readDateTimeValue( ContentLine *cl ) +{ + DateValue *dateValue = (DateValue *)cl->value(); + if ( dateValue ) + return dateValue->qdt(); + else + return QDateTime(); +} + +Geo VCardFormatImpl::readGeoValue( ContentLine *cl ) +{ + GeoValue *geoValue = (GeoValue *)cl->value(); + if ( geoValue ) { + Geo geo( geoValue->latitude(), geoValue->longitude() ); + return geo; + } else + return Geo(); +} + +TimeZone VCardFormatImpl::readUTCValue( ContentLine *cl ) +{ + UTCValue *utcValue = (UTCValue *)cl->value(); + if ( utcValue ) { + TimeZone tz; + tz.setOffset(((utcValue->hour()*60)+utcValue->minute())*(utcValue->positive() ? 1 : -1)); + return tz; + } else + return TimeZone(); +} + +Secrecy VCardFormatImpl::readClassValue( ContentLine *cl ) +{ + ClassValue *classValue = (ClassValue *)cl->value(); + if ( classValue ) { + Secrecy secrecy; + switch ( classValue->type() ) { + case ClassValue::Public: + secrecy.setType( Secrecy::Public ); + break; + case ClassValue::Private: + secrecy.setType( Secrecy::Private ); + break; + case ClassValue::Confidential: + secrecy.setType( Secrecy::Confidential ); + break; + } + + return secrecy; + } else + return Secrecy(); +} + +void VCardFormatImpl::addKeyValue( VCARD::VCard *vcard, const Key &key ) +{ + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityKey ) ); + + ParamList params; + if ( key.isBinary() ) { + cl.setValue( new TextValue( KCodecs::base64Encode( key.binaryData() ) ) ); + params.append( new Param( "ENCODING", "b" ) ); + } else { + cl.setValue( new TextValue( key.textData().utf8() ) ); + } + + switch ( key.type() ) { + case Key::X509: + params.append( new Param( "TYPE", "X509" ) ); + break; + case Key::PGP: + params.append( new Param( "TYPE", "PGP" ) ); + break; + case Key::Custom: + params.append( new Param( "TYPE", key.customTypeString().utf8() ) ); + break; + } + + cl.setParamList( params ); + vcard->add( cl ); +} + +Key VCardFormatImpl::readKeyValue( VCARD::ContentLine *cl ) +{ + Key key; + bool isBinary = false; + TextValue *v = (TextValue *)cl->value(); + + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" ) + isBinary = true; + if ( (*it)->name() == "TYPE" ) { + if ( (*it)->value().isEmpty() ) + continue; + if ( (*it)->value() == "X509" ) + key.setType( Key::X509 ); + else if ( (*it)->value() == "PGP" ) + key.setType( Key::PGP ); + else { + key.setType( Key::Custom ); + key.setCustomTypeString( QString::fromUtf8( (*it)->value() ) ); + } + } + } + + + if ( isBinary ) { + QByteArray data; + KCodecs::base64Decode( v->asString().stripWhiteSpace(), data ); + key.setBinaryData( data ); + } else { + key.setTextData( QString::fromUtf8( v->asString() ) ); + } + + return key; +} + + +void VCardFormatImpl::addAgentValue( VCARD::VCard *vcard, const Agent &agent ) +{ + if ( agent.isIntern() && !agent.addressee() ) + return; + + if ( !agent.isIntern() && agent.url().isEmpty() ) + return; + + ContentLine cl; + cl.setName( EntityTypeToParamName( EntityAgent ) ); + + ParamList params; + if ( agent.isIntern() ) { + QString vstr; + Addressee *addr = agent.addressee(); + if ( addr ) { + writeToString( (*addr), vstr ); + vstr.replace( ":", "\\:" ); + vstr.replace( ",", "\\," ); + vstr.replace( ";", "\\;" ); + vstr.replace( "\r\n", "\\n" ); + cl.setValue( new TextValue( vstr.utf8() ) ); + } else + return; + } else { + cl.setValue( new TextValue( agent.url().utf8() ) ); + params.append( new Param( "VALUE", "uri" ) ); + } + + cl.setParamList( params ); + vcard->add( cl ); +} + +Agent VCardFormatImpl::readAgentValue( VCARD::ContentLine *cl ) +{ + Agent agent; + bool isIntern = true; + TextValue *v = (TextValue *)cl->value(); + + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "VALUE" && (*it)->value() == "uri" ) + isIntern = false; + } + + if ( isIntern ) { + QString vstr = QString::fromUtf8( v->asString() ); + vstr.replace( "\\n", "\r\n" ); + vstr.replace( "\\:", ":" ); + vstr.replace( "\\,", "," ); + vstr.replace( "\\;", ";" ); + Addressee *addr = new Addressee; + readFromString( vstr, *addr ); + agent.setAddressee( addr ); + } else { + agent.setUrl( QString::fromUtf8( v->asString() ) ); + } + + return agent; +} + +void VCardFormatImpl::addPictureValue( VCARD::VCard *vcard, VCARD::EntityType type, const Picture &pic, const Addressee &addr, bool intern ) +{ + ContentLine cl; + cl.setName( EntityTypeToParamName( type ) ); + + if ( pic.isIntern() && pic.data().isNull() ) + return; + + if ( !pic.isIntern() && pic.url().isEmpty() ) + return; + + ParamList params; + if ( pic.isIntern() ) { + QImage img = pic.data(); + if ( intern ) { // only for vCard export we really write the data inline + QByteArray data; + QDataStream s( data, IO_WriteOnly ); + s.setVersion( 4 ); // to produce valid png files + s << img; + cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) ); + } else { // save picture in cache + QString dir; + if ( type == EntityPhoto ) + dir = "photos"; + if ( type == EntityLogo ) + dir = "logos"; + + img.save( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ), pic.type().utf8() ); + cl.setValue( new TextValue( "<dummy>" ) ); + } + params.append( new Param( "ENCODING", "b" ) ); + if ( !pic.type().isEmpty() ) + params.append( new Param( "TYPE", pic.type().utf8() ) ); + } else { + cl.setValue( new TextValue( pic.url().utf8() ) ); + params.append( new Param( "VALUE", "uri" ) ); + } + + cl.setParamList( params ); + vcard->add( cl ); +} + +Picture VCardFormatImpl::readPictureValue( VCARD::ContentLine *cl, VCARD::EntityType type, const Addressee &addr ) +{ + Picture pic; + bool isInline = false; + QString picType; + TextValue *v = (TextValue *)cl->value(); + + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" ) + isInline = true; + if ( (*it)->name() == "TYPE" && !(*it)->value().isEmpty() ) + picType = QString::fromUtf8( (*it)->value() ); + } + + if ( isInline ) { + QImage img; + if ( v->asString() == "<dummy>" ) { // no picture inline stored => picture is in cache + QString dir; + if ( type == EntityPhoto ) + dir = "photos"; + if ( type == EntityLogo ) + dir = "logos"; + + img.load( locateLocal( "data", "kabc/" + dir + "/" + addr.uid() ) ); + } else { + QByteArray data; + KCodecs::base64Decode( v->asString(), data ); + img.loadFromData( data ); + } + pic.setData( img ); + pic.setType( picType ); + } else { + pic.setUrl( QString::fromUtf8( v->asString() ) ); + } + + return pic; +} + +void VCardFormatImpl::addSoundValue( VCARD::VCard *vcard, const Sound &sound, const Addressee &addr, bool intern ) +{ + ContentLine cl; + cl.setName( EntityTypeToParamName( EntitySound ) ); + + if ( sound.isIntern() && sound.data().isNull() ) + return; + + if ( !sound.isIntern() && sound.url().isEmpty() ) + return; + + ParamList params; + if ( sound.isIntern() ) { + QByteArray data = sound.data(); + if ( intern ) { // only for vCard export we really write the data inline + cl.setValue( new TextValue( KCodecs::base64Encode( data ) ) ); + } else { // save sound in cache + QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) ); + if ( file.open( IO_WriteOnly ) ) { + file.writeBlock( data ); + } + cl.setValue( new TextValue( "<dummy>" ) ); + } + params.append( new Param( "ENCODING", "b" ) ); + } else { + cl.setValue( new TextValue( sound.url().utf8() ) ); + params.append( new Param( "VALUE", "uri" ) ); + } + + cl.setParamList( params ); + vcard->add( cl ); +} + +Sound VCardFormatImpl::readSoundValue( VCARD::ContentLine *cl, const Addressee &addr ) +{ + Sound sound; + bool isInline = false; + TextValue *v = (TextValue *)cl->value(); + + ParamList params = cl->paramList(); + ParamListIterator it( params ); + for( ; it.current(); ++it ) { + if ( (*it)->name() == "ENCODING" && (*it)->value() == "b" ) + isInline = true; + } + + if ( isInline ) { + QByteArray data; + if ( v->asString() == "<dummy>" ) { // no sound inline stored => sound is in cache + QFile file( locateLocal( "data", "kabc/sounds/" + addr.uid() ) ); + if ( file.open( IO_ReadOnly ) ) { + data = file.readAll(); + file.close(); + } + } else { + KCodecs::base64Decode( v->asString(), data ); + } + sound.setData( data ); + } else { + sound.setUrl( QString::fromUtf8( v->asString() ) ); + } + + return sound; +} + +bool VCardFormatImpl::readFromString( const QString &vcard, Addressee &addressee ) +{ + VCardEntity e( vcard.utf8() ); + VCardListIterator it( e.cardList() ); + + if ( it.current() ) { + VCARD::VCard v(*it.current()); + loadAddressee( addressee, v ); + return true; + } + + return false; +} + +bool VCardFormatImpl::writeToString( const Addressee &addressee, QString &vcard ) +{ + VCardEntity vcards; + VCardList vcardlist; + vcardlist.setAutoDelete( true ); + + VCARD::VCard *v = new VCARD::VCard; + + saveAddressee( addressee, v, true ); + + vcardlist.append( v ); + vcards.setCardList( vcardlist ); + vcard = QString::fromUtf8( vcards.asString() ); + + return true; +} diff --git a/kabc/vcardformatimpl.h b/kabc/vcardformatimpl.h new file mode 100644 index 000000000..3a29e3a92 --- /dev/null +++ b/kabc/vcardformatimpl.h @@ -0,0 +1,106 @@ +/* + 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_VCARDFORMATIMPL_H +#define KABC_VCARDFORMATIMPL_H + +#include <qstring.h> +#include <qfile.h> + +#include "address.h" +#include "addressee.h" + +#ifdef __CYGWIN__ +#include <vcard/include/VCard.h> +#else +#include <VCard.h> +#endif + +namespace KABC { + +class AddressBook; + +/** + @deprecated use VCardFormatPlugin instead. + */ +class KABC_EXPORT_DEPRECATED VCardFormatImpl +{ + public: + bool load( Addressee &, QFile *file ); + bool loadAll( AddressBook *, Resource *, QFile *file ); + void save( const Addressee &, QFile *file ); + void saveAll( AddressBook *, Resource *, QFile *file ); + + bool readFromString( const QString &vcard, Addressee &addr ); + bool writeToString( const Addressee &addressee, QString &vcard ); + + protected: + bool loadAddressee( Addressee &, VCARD::VCard & ); + void saveAddressee( const Addressee &, VCARD::VCard *, bool intern ); + + void addTextValue (VCARD::VCard *, VCARD::EntityType, const QString & ); + QString readTextValue( VCARD::ContentLine * ); + + void addDateValue( VCARD::VCard *, VCARD::EntityType, const QDate & ); + QDate readDateValue( VCARD::ContentLine * ); + + void addDateTimeValue( VCARD::VCard *, VCARD::EntityType, const QDateTime & ); + QDateTime readDateTimeValue( VCARD::ContentLine * ); + + void addAddressValue( VCARD::VCard *, const Address & ); + Address readAddressValue( VCARD::ContentLine * ); + + void addLabelValue( VCARD::VCard *, const Address & ); + + void addTelephoneValue( VCARD::VCard *, const PhoneNumber & ); + PhoneNumber readTelephoneValue( VCARD::ContentLine * ); + + void addNValue( VCARD::VCard *, const Addressee & ); + void readNValue( VCARD::ContentLine *, Addressee & ); + + void addCustomValue( VCARD::VCard *, const QString & ); + + void addAddressParam( VCARD::ContentLine *, int ); + int readAddressParam( VCARD::ContentLine * ); + + void addGeoValue( VCARD::VCard *, const Geo & ); + Geo readGeoValue( VCARD::ContentLine * ); + + void addUTCValue( VCARD::VCard *, const TimeZone & ); + TimeZone readUTCValue( VCARD::ContentLine * ); + + void addClassValue( VCARD::VCard *, const Secrecy & ); + Secrecy readClassValue( VCARD::ContentLine * ); + + void addKeyValue( VCARD::VCard *, const Key & ); + Key readKeyValue( VCARD::ContentLine * ); + + void addPictureValue( VCARD::VCard *, VCARD::EntityType, const Picture &, const Addressee &, bool ); + Picture readPictureValue( VCARD::ContentLine *, VCARD::EntityType, const Addressee &addr ); + + void addSoundValue( VCARD::VCard *, const Sound &, const Addressee &, bool ); + Sound readSoundValue( VCARD::ContentLine *, const Addressee &addr ); + + void addAgentValue( VCARD::VCard *, const Agent & ); + Agent readAgentValue( VCARD::ContentLine * ); +}; + +} +#endif diff --git a/kabc/vcardformatplugin.cpp b/kabc/vcardformatplugin.cpp new file mode 100644 index 000000000..6725e3b65 --- /dev/null +++ b/kabc/vcardformatplugin.cpp @@ -0,0 +1,120 @@ +/* + 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 <qfile.h> + +#include "address.h" +#include "addressee.h" +#include "vcardconverter.h" + +#include "vcardformatplugin.h" + +using namespace KABC; + +VCardFormatPlugin::VCardFormatPlugin() +{ +} + +VCardFormatPlugin::~VCardFormatPlugin() +{ +} + +bool VCardFormatPlugin::load( Addressee &addressee, QFile *file ) +{ + QString data; + + QTextStream t( file ); + t.setEncoding( QTextStream::Latin1 ); + data = t.read(); + + VCardConverter converter; + Addressee::List l = converter.parseVCards( data ); + + if ( ! l.first().isEmpty() ) { + addressee = l.first(); + return true; + } + + return false; +} + +bool VCardFormatPlugin::loadAll( AddressBook*, Resource *resource, QFile *file ) +{ + QString data; + + QTextStream t( file ); + t.setEncoding( QTextStream::Latin1 ); + data = t.read(); + + VCardConverter converter; + + Addressee::List l = converter.parseVCards( data ); + + Addressee::List::iterator itr; + for ( itr = l.begin(); itr != l.end(); ++itr) { + Addressee addressee = *itr; + addressee.setResource( resource ); + addressee.setChanged( false ); + resource->insertAddressee( addressee ); + } + + return true; +} + +void VCardFormatPlugin::save( const Addressee &addressee, QFile *file ) +{ + VCardConverter converter ; + Addressee::List vcardlist; + + + vcardlist.append( addressee ); + + QTextStream t( file ); + t.setEncoding( QTextStream::UnicodeUTF8 ); + t << converter.createVCards( vcardlist ); +} + +void VCardFormatPlugin::saveAll( AddressBook*, Resource *resource, QFile *file ) +{ + VCardConverter converter; + Addressee::List vcardlist; + + Resource::Iterator it; + for ( it = resource->begin(); it != resource->end(); ++it ) { + (*it).setChanged( false ); + vcardlist.append( *it ); + } + + QTextStream t( file ); + t.setEncoding( QTextStream::UnicodeUTF8 ); + t << converter.createVCards( vcardlist ); +} + +bool VCardFormatPlugin::checkFormat( QFile *file ) const +{ + QString line; + + file->readLine( line, 1024 ); + line = line.stripWhiteSpace(); + if ( line == "BEGIN:VCARD" ) + return true; + else + return false; +} diff --git a/kabc/vcardformatplugin.h b/kabc/vcardformatplugin.h new file mode 100644 index 000000000..7733438ba --- /dev/null +++ b/kabc/vcardformatplugin.h @@ -0,0 +1,56 @@ +/* + 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_VCARDFORMATPLUGIN_H +#define KABC_VCARDFORMATPLUGIN_H + +#include "formatplugin.h" + +namespace KABC { + +class AddressBook; +class Addressee; + +/** + @short Interface of vCard backend for address book. + + This class implements the file format interface of address book entries for + the vCard format. +*/ +class KABC_EXPORT VCardFormatPlugin : public FormatPlugin +{ + public: + VCardFormatPlugin(); + virtual ~VCardFormatPlugin(); + + bool load( Addressee &, QFile *file ); + bool loadAll( AddressBook *, Resource *, QFile *file ); + void save( const Addressee &, QFile *file ); + void saveAll( AddressBook *, Resource *, QFile *file ); + + bool checkFormat( QFile *file ) const; + + private: + struct VCardFormatPrivate; + VCardFormatPrivate *d; +}; + +} +#endif diff --git a/kabc/vcardparser/Makefile.am b/kabc/vcardparser/Makefile.am new file mode 100644 index 000000000..42e55cb4b --- /dev/null +++ b/kabc/vcardparser/Makefile.am @@ -0,0 +1,31 @@ +INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes) + +noinst_LTLIBRARIES = libvcards.la +libvcards_la_SOURCES = vcard.cpp vcardline.cpp vcardparser.cpp + +vcardsincludedir = $(includedir)/kabc +vcardsinclude_HEADERS = vcard.h vcardline.h vcardparser.h + +check_PROGRAMS = testread testwrite testread2 + +testread_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testread_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testread_SOURCES = testread.cpp + +testread2_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testread2_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testread2_SOURCES = testread2.cpp testutils.cpp + +testwrite_LDFLAGS = $(all_libraries) $(KDE_RPATH) +testwrite_LDADD = libvcards.la $(top_builddir)/kabc/libkabc.la +testwrite_SOURCES = testwrite.cpp + +TESTFILES = vcard1.vcf vcard2.vcf vcard3.vcf vcard4.vcf vcard6.vcf vcard7.vcf + +check-local: testread + rm -f FAILED; \ + for i in $(TESTFILES); \ + do perl $(top_srcdir)/kabc/vcardparser/checkvcard.pl \ + $(top_srcdir)/kabc/vcardparser/tests/$$i; \ + done; \ + [ ! -e FAILED ] diff --git a/kabc/vcardparser/README.testing b/kabc/vcardparser/README.testing new file mode 100644 index 000000000..a7794931d --- /dev/null +++ b/kabc/vcardparser/README.testing @@ -0,0 +1,15 @@ +For testing the vcardparser there are some test files and a small testsuite +automatically checking for regressions. The tests directory contains some vCard +files and correpsonding reference output files (with an additional ".ref" +suffix). For running the geression test do "make check". This will compile some +test programs, parse the test files, write them out as vCard again and compare +the output to the reference file. The check fails, if there are unexpected +differences and shows which lines differed. + +For creating a new test put a vCard file to be parsed into the tests directory. +Create a reference file by running "testread" on the test file. It will put out +the parsed data as vCard again on stdout. Carefully check the output, manually +correct any errors and save the result as reference file in the tests directory. +Now add the filename to the TESTFILES variable in Makefile.am and run "make +check". If the check fails adapt the reference file or fix the bugs in the +parser, whatever is appropriate. diff --git a/kabc/vcardparser/checkvcard.pl b/kabc/vcardparser/checkvcard.pl new file mode 100755 index 000000000..67160ea4a --- /dev/null +++ b/kabc/vcardparser/checkvcard.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +if ( @ARGV != 1 ) { + print STDERR "Missing arg: filename\n"; + exit 1; +} + +$file = $ARGV[0]; + +if ( !open( IN, "$file" ) ) { + print STDERR "Unable to open '$file'\n"; + exit 1; +} + +while( <IN> ) { + if (/^VERSION:(.*)$/ ) { + $version = $1; + if ( $version eq "2.1" ) { $options = "--vcard21"; } + } +} + +close IN; + +$ref = "$file.ref"; + +if ( !open( REF, "$ref" ) ) { + print STDERR "Unable to open $ref\n"; + exit 1; +} + +while( <REF> ) { + push @ref, $_; +} + +close REF; + +if ( !open( READ, "./testread $file $options 2> /dev/null |" ) ) { + print STDERR "Unable to open testread\n"; + exit 1; +} + +print "Checking '$file':\n"; + +$gotsomething = 0; +$error = 0; +$i = 0; +while( <READ> ) { + $gotsomething = 1; + $out = $_; + $ref = @ref[$i++]; + + if ( $out ne $ref ) { + if ( $ref =~ /^UID/ && $out =~ /^UID/ ) { next; } + $error++; + print " Expected : $ref"; + print " Parser output : $out"; + } +} + +close READ; + +if ( $gotsomething == 0 ) { + print "\n FAILED: testread didn't output anything\n"; + system "touch FAILED"; + exit 1; +} +if ( $error > 0 ) { + print "\n FAILED: $error errors found.\n"; + system "touch FAILED"; + exit 1; +} else { + print " OK\n"; +} + +exit 0; diff --git a/kabc/vcardparser/testread.cpp b/kabc/vcardparser/testread.cpp new file mode 100644 index 000000000..52fe81a11 --- /dev/null +++ b/kabc/vcardparser/testread.cpp @@ -0,0 +1,89 @@ +/* + This file is part of libkabc. + + 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 <iostream> +#include <stdlib.h> + +#include <qfile.h> +#include <qtextstream.h> + +#include <kprocess.h> +#include <kdebug.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kaboutdata.h> + +#include "vcardconverter.h" +#include "vcard.h" + +static const KCmdLineOptions options[] = +{ + {"vcard21", I18N_NOOP("vCard 2.1"), 0}, + {"+inputfile", I18N_NOOP("Input file"), 0}, + KCmdLineLastOption +}; + +int main( int argc, char **argv ) +{ + KApplication::disableAutoDcopRegistration(); + + KAboutData aboutData( "testread", "vCard test reader", "0.1" ); + aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app( false, false ); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if ( args->count() != 1 ) { + std::cerr << "Missing argument" << std::endl; + return 1; + } + + QString inputFile( args->arg( 0 ) ); + + QFile file( inputFile ); + if ( !file.open( IO_ReadOnly ) ) { + qDebug( "Unable to open file '%s' for reading!", file.name().latin1() ); + return 1; + } + + QString text; + + QTextStream s( &file ); + s.setEncoding( QTextStream::Latin1 ); + text = s.read(); + file.close(); + + KABC::VCardConverter converter; + KABC::Addressee::List list = converter.parseVCards( text ); + + if ( args->isSet( "vcard21" ) ) { + text = converter.createVCards( list, KABC::VCardConverter::v2_1 ); // uses version 2.1 + } else { + text = converter.createVCards( list ); // uses version 3.0 + } + + std::cout << text.utf8(); + + return 0; +} diff --git a/kabc/vcardparser/testread2.cpp b/kabc/vcardparser/testread2.cpp new file mode 100644 index 000000000..19a02e3c9 --- /dev/null +++ b/kabc/vcardparser/testread2.cpp @@ -0,0 +1,42 @@ +#include "testutils.h" +#include <kabc/addressee.h> +#include <vcardconverter.h> +#include <kdebug.h> + +using namespace KABC; + +int +main() +{ + Addressee::List l = vCardsAsAddresseeList(); + QString vcards = vCardsAsText(); + + VCardConverter vct; + + Addressee::List parsed = vct.parseVCards( vcards ); + + if ( l.size() != parsed.size() ) { + kdDebug()<<"\tSize - FAILED : "<<l.size()<<" vs. parsed "<<parsed.size()<<endl; + } else { + kdDebug()<<"\tSize - PASSED"<<endl; + } + + Addressee::List::iterator itr1; + Addressee::List::iterator itr2; + for ( itr1 = l.begin(), itr2 = parsed.begin(); + itr1 != l.end(); ++itr1, ++itr2 ) { + if ( (*itr1).fullEmail() == (*itr2).fullEmail() && + (*itr1).organization() == (*itr2).organization() && + (*itr1).phoneNumbers() == (*itr2).phoneNumbers() && + (*itr1).emails() == (*itr2).emails() && + (*itr1).role() == (*itr2).role() ) { + kdDebug()<<"\tAddressee - PASSED"<<endl; + kdDebug()<<"\t\t"<< (*itr1).fullEmail() << " VS. " << (*itr2).fullEmail()<<endl; + } else { + kdDebug()<<"\tAddressee - FAILED"<<endl; + (*itr1).dump(); + (*itr2).dump(); + //kdDebug()<<"\t\t"<< (*itr1).fullEmail() << " VS. " << (*itr2).fullEmail()<<endl; + } + } +} diff --git a/kabc/vcardparser/tests/vcard1.vcf b/kabc/vcardparser/tests/vcard1.vcf new file mode 100644 index 000000000..2c77b094c --- /dev/null +++ b/kabc/vcardparser/tests/vcard1.vcf @@ -0,0 +1,13 @@ +BEGIN:vCard +VERSION:3.0 +FN:Frank Dawson +ORG:Lotus Development Corporation +ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive + ;Raleigh;NC;27613-3502;U.S.A. +TEL;TYPE=VOICE,MSG,WORK:+1-919-676-9515 +TEL;TYPE=FAX,WORK:+1-919-676-9564 +EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com +EMAIL;TYPE=INTERNET:fdawson@earthlink.net +URL:http://home.earthlink.net/~fdawson +END:vCard + diff --git a/kabc/vcardparser/tests/vcard1.vcf.ref b/kabc/vcardparser/tests/vcard1.vcf.ref new file mode 100644 index 000000000..073a7f31d --- /dev/null +++ b/kabc/vcardparser/tests/vcard1.vcf.ref @@ -0,0 +1,15 @@ +BEGIN:VCARD
+ADR;TYPE=parcel;TYPE=postal;TYPE=work:;;6544 Battleford Drive;Raleigh;NC;27
+ 613-3502;U.S.A.
+EMAIL;TYPE=PREF:Frank_Dawson@Lotus.com
+EMAIL:fdawson@earthlink.net
+FN:Frank Dawson
+N:;;;;
+ORG:Lotus Development Corporation
+TEL;TYPE=MSG;TYPE=VOICE;TYPE=WORK:+1-919-676-9515
+TEL;TYPE=FAX;TYPE=WORK:+1-919-676-9564
+UID:gDVbA6LY3t
+URL:http://home.earthlink.net/~fdawson
+VERSION:3.0
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard2.vcf b/kabc/vcardparser/tests/vcard2.vcf new file mode 100644 index 000000000..a4136b1b8 --- /dev/null +++ b/kabc/vcardparser/tests/vcard2.vcf @@ -0,0 +1,11 @@ +BEGIN:vCard +VERSION:3.0 +FN:Tim Howes +ORG:Netscape Communications Corp. +ADR;TYPE=WORK:;;501 E. Middlefield Rd.;Mountain View; + CA; 94043;U.S.A. +TEL;TYPE=VOICE,MSG,WORK:+1-415-937-3419 +TEL;TYPE=FAX,WORK:+1-415-528-4164 +EMAIL;TYPE=INTERNET:howes@netscape.com +END:vCard + diff --git a/kabc/vcardparser/tests/vcard2.vcf.ref b/kabc/vcardparser/tests/vcard2.vcf.ref new file mode 100644 index 000000000..55151c797 --- /dev/null +++ b/kabc/vcardparser/tests/vcard2.vcf.ref @@ -0,0 +1,12 @@ +BEGIN:VCARD
+ADR;TYPE=work:;;501 E. Middlefield Rd.;Mountain View;CA; 94043;U.S.A.
+EMAIL:howes@netscape.com
+FN:Tim Howes
+N:;;;;
+ORG:Netscape Communications Corp.
+TEL;TYPE=MSG;TYPE=VOICE;TYPE=WORK:+1-415-937-3419
+TEL;TYPE=FAX;TYPE=WORK:+1-415-528-4164
+UID:1UgvYejJMs
+VERSION:3.0
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard3.vcf b/kabc/vcardparser/tests/vcard3.vcf new file mode 100644 index 000000000..f3f649784 --- /dev/null +++ b/kabc/vcardparser/tests/vcard3.vcf @@ -0,0 +1,11 @@ +begin:vcard +n:geiser;ian +x-mozilla-html:FALSE +org:Source eXtreme +version:2.1 +email;internet:geiseri@yahoo.com +title:VP of Engineering +x-mozilla-cpt:;0 +fn:ian geiser +end:vcard + diff --git a/kabc/vcardparser/tests/vcard3.vcf.ref b/kabc/vcardparser/tests/vcard3.vcf.ref new file mode 100644 index 000000000..c91351769 --- /dev/null +++ b/kabc/vcardparser/tests/vcard3.vcf.ref @@ -0,0 +1,12 @@ +BEGIN:VCARD
+EMAIL:geiseri@yahoo.com
+FN:ian geiser
+N:geiser;ian;;;
+ORG:Source eXtreme
+TITLE:VP of Engineering
+UID:ebvq9Wo9rO
+VERSION:3.0
+X-mozilla-cpt:;0
+X-mozilla-html:FALSE
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard4.vcf b/kabc/vcardparser/tests/vcard4.vcf new file mode 100644 index 000000000..7152ceb05 --- /dev/null +++ b/kabc/vcardparser/tests/vcard4.vcf @@ -0,0 +1,14 @@ +BEGIN:VCARD +X-EVOLUTION-FILE-AS:Ximian, Inc. +FN +N: +LABEL;QUOTED-PRINTABLE;WORK:401 Park Drive 3 West=0ABoston, MA 02215=0AUSA +TEL;WORK;VOICE:(617) 236-0442 +TEL;WORK;FAX:(617) 236-8630 +EMAIL;INTERNET:hello@ximian.com +URL:www.ximian.com/ +ORG:Ximian, Inc. +NOTE:Welcome to the Ximian Addressbook. +UID:pas-id-3E136F9B00000000 +END:VCARD + diff --git a/kabc/vcardparser/tests/vcard4.vcf.ref b/kabc/vcardparser/tests/vcard4.vcf.ref new file mode 100644 index 000000000..fc3b7a500 --- /dev/null +++ b/kabc/vcardparser/tests/vcard4.vcf.ref @@ -0,0 +1,14 @@ +BEGIN:VCARD
+EMAIL:hello@ximian.com
+LABEL;TYPE=work:401 Park Drive 3 West\nBoston\, MA 02215\nUSA
+N:;;;;
+NOTE:Welcome to the Ximian Addressbook.
+ORG:Ximian\, Inc.
+TEL;TYPE=VOICE;TYPE=WORK:(617) 236-0442
+TEL;TYPE=FAX;TYPE=WORK:(617) 236-8630
+UID:pas-id-3E136F9B00000000
+URL:www.ximian.com/
+VERSION:3.0
+X-EVOLUTION-FILE-AS:Ximian\, Inc.
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard5.vcf b/kabc/vcardparser/tests/vcard5.vcf new file mode 100644 index 000000000..957a1e552 --- /dev/null +++ b/kabc/vcardparser/tests/vcard5.vcf @@ -0,0 +1,313 @@ +BEGIN:VCARD +ADR;TYPE=home;TYPE=pref:;;Buehlauer Strasse 45;Dresden;Sachsen;01327;German + y +ADR;TYPE=work:;;Prager Strasse 55;Dresden;Sachsen;01066;Germany +BDAY:1955-07-19T00:00:00Z +CATEGORIES:Friend +CLASS:CONFIDENTIAL +EMAIL;TYPE=PREF:heiko.mustermann@freenet.org +EMAIL:heiko8@tst.inf.tu-dresden.de +FN:Mustermann, Heiko +GEO:19.283333;166.616669 +LOGO;ENCODING=b;TYPE=image/png:iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVU + AAAOW0lEQVR4nO1df2hb1xX+OlyQwQEJXJAgBQlaiEwDsdqO2l1H47RjMe2gbjOoszG2dozG7aC + YMIqTjS7NYKSmbE1StsQpWxMXmsSF1WhlTeSwJlZY06gsSVXWUAkakKAGPajBDxrQ/jjnez8k27 + EjJdyU+/0jPz29X9L57jnnO+deAxYWFhYWFhYWFu3Hbe082XT2ZF3+WgAAdHZ0AgBqTg0A4H7DT + 7oAgNSdKQDAg99/sK33caPB53RqFQBA5PYIAMBdkOf6yc9+ct3P852W786irWjJMs/8+0wdACpV + sZTS50V5vSLb1UoVQMCCvnFDx0c65f3BHw4CABJ3RL19mwYfM4Y1e/+0V5h/VbbPXzwPACiVSgA + A15XnikVjAIB44Dli3TIKjL+2e0XPYxliGFZshSdzZ+r8OyKGjdl8AQCQfe84AKBaFUaUrojlRL + vEUpx5h0eGjo9EZH+kQ7Yz9/d71+vdkAYApO+W16d+/NQNZ8ye8T11ACiV5TkcR5jufCX3XyrLc + 9XmxUe6bvi5XH3OaNRnSKRL9vWsywAAstNTyz6HZYhhsD+IYbjmMPDxfz6uA0BMqQcAR96eAgBM + vSevtTkJa6tzQnVSNn2XOLSZ03ljHHQ7MLxlSIa2kg5pOrTVHHHu/hANRDrke4t2y3cy+KgEMPs + P7F/0O7EMMQzXtNxLn16qA8DUu1nvvcm3DgEAFlxxbo4jFpFYK4woXix8qxhxLYxuH6sDQG5Gvq + NSueLtcxwdNTTASemoUTi3+HdkGWIYlrTkj2clzC1ckGRv3xv7vH2VK7QAlUDuktA0f/bG+YpL5 + 4WpDDXv7TdPbjm472AdACbe9L+r4mdMHuW+42uTAIByuWwZciugY6kdER3zzn8iMkFt3pc93Kvy + d0QzvHYxI5h8Qq/BiK1YLur78nJw4mBIznj2V88ueg+HjxyrA0BEdE7EumLePp773u/e25b7jyb + kfAObh7z3SleELS40SVZ/u+2F0ToA7H99PHRtyxDD0GQZZ9RKKxUZ+/YdmAAAFD4peJ9hbF2dq7 + aHGSpn12p+dJI7PQsAcDS3YcxfmZPXnrt65F40P+pd3wsgwF69x/xHedlWNkfX+PlUep0ck0omA + ACxO+R10w82tfRch8leAJOas82ek+cho/sfkGtnT8xYhpiMJh9CiytVZayjYIgO37KCmWgrOPy3 + w3UAKKpsf/zd496+wkVhpOu5Lje0XS6X9X5lbJ49KxZIJqSSEu+Xrsj9V1Xw5OcBIPJBDoCfPw0 + 9IVn0sanpOgA8NXR9JYBILO7/rd8n/RV9SM1tPg6wDDEOTQxhFEKLYjbuBljBX9tjzyox/Q+xQO + crOf7I20cAAIVz+cCnVNJu8Alo3Nb43nEjoSfa8dIOAMDs6Zy+3wcAyM3kvCtUyZ6qXLd0WZj6z + E+fAeAX4FZbYo5Fmt9zXfeanwEsQ4xDE0Nqbi203ZhztANVZUb2PdF+imqZLgLX0OvSd7lLbPO+ + OFan1B8wGotEE3pCYfpWtX4A2L1rZ+gcHN+Pa8EtEpX3mR9tGlieKSf/dVJ9Ysl7j/fhMYTfuDa + ANMIyxDA0Z+r6Qy7MC1Mi3lge1PijTYetBNNTkjUfOjQJAMi+LzE6S7nJtX50krknE74hZQZbij + o19U7eKcfQAKuaP7lam+hRdZXl19kZX7Xe+PBG2acM7YzE9Bpi1UfeFN9G7Y6+77EfLR59UdGtV + X2G8D7IEPrf7PtZq2XdCmhiCBsUYnGxLJfxP5rzkI0Pb6wDwMypmWXHVupOk0eFEfQZIy+MAQB6 + 79OGhnSvd0yk4c5o4c7Xamlrwj7Nqck9uVf5eblGVnONqIY1W38+4h3DyJH1i6j6jFi3+B1GaPm + 8RGFsa9qrqu7zI6KfHXtHmM8KKq8ZfNZg/rMcLEMMQ5NlH/zLwVDz28SbomVRUxI0RDZJZrqici + biYmHFz8Q6cmox6bR8bsfOVwD44ylzH47dgK9lTf5dqpOzZ0V1Hnh0AIDfXMdmO7Zx0h8MaO2aT + JtQf7D16Se9a9CS0+uEofQVmV7ZjqhPmXhrIvQcnV2doeemv6UfIysAeNoVg9TMfdLqZH3ILYIl + x36Oi/v+Knp+/mwhsFfHcR0X2W3Su0Gy4ZrG3tU5GaOHtwhzXv3jqwB8ZgFiaezamFVWAMDO30u + OQAsjfvFL8QHpdFLOoPE8FQXG99UvxecMbhameOrCnB8tbh0WtjA3IZuYl6TXC1PoY/b9eRwAUL + hYDH3emXdD20EwX4p3SzS4VKWQsAwxDPYHMQxLlnDpJNlbSyEO8BvjvDKrJnZFlcxJ+biGkRT6Y + nf45VMAqHypXfMa0uY+8JM2Fpycr+QzfQ+JM0+nhPoMBHit3FFxuHT6FB8rGsYnusWZVsoBAVOH + QzrlkoqlcW1qSyQkOMmsE+c9sk2Gy+d//Xzo+Ago40RD3wsARKMrG6oIyxDDsCRDOAtodLsU44M + d3QtXKcnzLGELoXN7cos4y3jcl0QAYOFrOZ4ySLGooWqgOYBs4XVp+Qw9i2XZX1GyZtIJvQdhRi + Il23S4ntgYSNB67xcWTs2ouDmn97FRrlX6MlzUSt8jo8XQlq0AgMm3J8Ln1OfmnBBg9U2DliGGY + UmGEON7pE1lVNtWAGD2IwlPK1fF6jhziGMxE8eR54QhnWtUatY5hpS5ixfCPmexsDHRLedOeDK6 + YOARsdLxabHqVJIiozbvqQzvsZnvJ33r7dkgfuXQBWHC6NMSIrvqZ+grOTOsX+evPLlZRMlCXsv + GGsZn1osgOt7Q2rMaWIYYhmsyhAj+6tue2ybNZ59ruVfl5k614igL+90NvoNz9LT5jkJgKiVWS5 + 8CAOVSGYAv9FU0eezXaItsHHkkCQBI360RnDKBzODx7iKNGcPa1FCZk3JArZzT53FC5yB4DxGN8 + IY04d3+m+23AcDMqZmma6wWliGGYcUMCWL/G+HJJsNbhkPtPBxrGwv5pcufAgDcrzlPXayX430w + D2GMTx/CQlkqqUzokGO8MpZGUwtagqbASTAScuZ8ATOVlGa7wT6Jnnb/QacTaO4CFR0JFsXiiXj + oGrte3lUHgJ2/29ly46BliGG4LoY0YvLoZMgyjr9zXCKyTrEozuemsEfRjtEZfUq+4MvWjFxojd + ympTNqamq+iKjP8LJlln6VGQGxkj4hpS2lbJYeXC++xZuQpOxjO2hCi3f0lSxVtAOWIYahLQxpB + KXmijJjQed1R9nbptbNAhbbgRBoQYomxAobW0M5jvuWrpGQRj7MyFlsYg6RSDCS863ZnZf3EmuF + VcNPDMv9/FNKsfsPHAoxf/RFmbpWLLBtVa5JNvY90FcHWpueYRliGNrKkC/+90Ud8EucLjR7dtQ + 3qALLaCz7vsT9nO6V7vVXcqBi6jYUqHB7wyvCDWccz6kGpFU1ZqNCENWaKAWOMjZzn8RsbOTDgU + Ohz690vZJWYBliGNr6i1/6r0zM9LQqVXGZI3yqeQjfZ4ae2SCWyaY3QbhldOB7kqHHEuGaSiNe+ + a3UXlh2zeiaKYOPS7nW19uA8dekPB3TXGf0xVEAgXKv1oCok+VOCcs2DbY2oWc5WIYYhrb4kOms + tFgWL0tUlf9QNB0ygcwoXw5XzQY3D9YBIK7M4MQZwM87HM1dSmzP1KgrFgv7joUFNjlwqSF5efV + 1YUHurFj32PYx75gdL+uUhbyuf6UZeq9WFznJv6KqL33fjYRliGFoiSGc0FLUxQW8VsolmsAa4U + VCSRnng1PlqBPFNO/gKnVs76RP6WRuo35q6HHJsqkKsPZOto7v2e1dY+QF8RkDfaqIdZCVmsOo+ + swIjbX/GwnLEMPQEkPatZoomdE47QsAoHX6aDRcm+B4X/K6YbT+oYxg/ZttopzKxsmhgF8zrzR0 + 0bDjhp/l8iL508s3lbcDliGGwf4ghsGIFXWONaxHAvgrDMVUhmGLEfuA4xoiT70rgQQdrteBr6X + bktcoF94G/GY6hrO5U9pipAEAz1mttmfFipXAMsQw3BD5fbVwuJbUGl868UJMXdNEa0eIdocLUJ + wH8souSfI8eV7DYcr2lPqDgUNlPtzKSqawIMXQ+3rn418PLEMMgxE+hNirCxkDQK82SrgqBqY5K + 1eZUanK+94ahrpaUfGCyCCDm0VMpDBImb4SaHKgD/FWFVVmMGFl6Tl3Qgpok0eXXwS5HbAMMQxG + MSSIsZekXNp7v8zKymzo0T26WpHO42MjNxsmGHWx6a6/rz/0uWDBi+coFJRdnDHLiI4rTqxQCmo + HLEMMgxFR1mJgMOQ1YHO7S14b1zQhQ5iHsLXoiM6g9SbTICDPdIRbiLw5kyqpNK72djNgGWIYjG + VIPB5e+cBrauvSdh5tGWKbEHMJFrn6HxDf0bNOfE+Na7cEWaFPT+m+oNMjip9J/pE90Xrz9GphG + WIYjGUIW/zZyMysOcrGuTjXVAwXjbgST0WjKbZ70nXkC77VFy9r/jEXZteC077W0NXCMsQwGJuH + NGJsp+QlfZqXsHWHKi4n1xS0YZvToWc+lPLr+U+k2BSqgV31MnNjvgfLEMNgjGWsFFytiM3WcZW + BOUWgoj6kqv/Ii00RXBm7GljViBFXwaD/d2IZYhiMjbKWgreUhlb3OAFz4CHZz6aGWHd4hTnHFc + WWjeBAeJKpKbAMMQy3HEO45Mfecfl3qNSyuB5iRtt/XP43hK5w3nK+4rcBNa7FZQIsQwyDMdFFq + xh9UZb+6HtIlr1wF8SHFM6JPsVGueDiMzej8W21sAwxDPYHMQy3nFNfCmltrKuWRDrhv0HlUMWV + 8Rrn1JsGyxDDYLS1XA927ZZWooL+MzC29sycuHmNCq3AMsQwfGt8CFHISwEqskbDWwPlkeVgGWJ + xczH20lidTXe3AixDLCwsLCwsviX4P68/8cprSSqmAAAAAElFTkSuQmCC +N:Mustermann;Heiko;;; +NICKNAME:clown +NOTE:I'm a friendly note text,\nplease copy me to your address book... +ORG:KDE +PHOTO;ENCODING=b;TYPE=image/png:iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pV + UAAAOW0lEQVR4nO1df2hb1xX+OlyQwQEJXJAgBQlaiEwDsdqO2l1H47RjMe2gbjOoszG2dozG7a + CYMIqTjS7NYKSmbE1StsQpWxMXmsSF1WhlTeSwJlZY06gsSVXWUAkakKAGPajBDxrQ/jjnez8k2 + 7EjJdyU+/0jPz29X9L57jnnO+deAxYWFhYWFhYWFu3Hbe082XT2ZF3+WgAAdHZ0AgBqTg0A4H7D + T7oAgNSdKQDAg99/sK33caPB53RqFQBA5PYIAMBdkOf6yc9+ct3P852W786irWjJMs/8+0wdACp + VsZTS50V5vSLb1UoVQMCCvnFDx0c65f3BHw4CABJ3RL19mwYfM4Y1e/+0V5h/VbbPXzwPACiVSg + AA15XnikVjAIB44Dli3TIKjL+2e0XPYxliGFZshSdzZ+r8OyKGjdl8AQCQfe84AKBaFUaUrojlR + LvEUpx5h0eGjo9EZH+kQ7Yz9/d71+vdkAYApO+W16d+/NQNZ8ye8T11ACiV5TkcR5jufCX3XyrL + c9XmxUe6bvi5XH3OaNRnSKRL9vWsywAAstNTyz6HZYhhsD+IYbjmMPDxfz6uA0BMqQcAR96eAgB + MvSevtTkJa6tzQnVSNn2XOLSZ03ljHHQ7MLxlSIa2kg5pOrTVHHHu/hANRDrke4t2y3cy+KgEMP + sP7F/0O7EMMQzXtNxLn16qA8DUu1nvvcm3DgEAFlxxbo4jFpFYK4woXix8qxhxLYxuH6sDQG5Gv + qNSueLtcxwdNTTASemoUTi3+HdkGWIYlrTkj2clzC1ckGRv3xv7vH2VK7QAlUDuktA0f/bG+YpL + 54WpDDXv7TdPbjm472AdACbe9L+r4mdMHuW+42uTAIByuWwZciugY6kdER3zzn8iMkFt3pc93Kv + yd0QzvHYxI5h8Qq/BiK1YLur78nJw4mBIznj2V88ueg+HjxyrA0BEdE7EumLePp773u/e25b7jy + bkfAObh7z3SleELS40SVZ/u+2F0ToA7H99PHRtyxDD0GQZZ9RKKxUZ+/YdmAAAFD4peJ9hbF2dq + 7aHGSpn12p+dJI7PQsAcDS3YcxfmZPXnrt65F40P+pd3wsgwF69x/xHedlWNkfX+PlUep0ck0om + AACxO+R10w82tfRch8leAJOas82ek+cho/sfkGtnT8xYhpiMJh9CiytVZayjYIgO37KCmWgrOPy + 3w3UAKKpsf/zd496+wkVhpOu5Lje0XS6X9X5lbJ49KxZIJqSSEu+Xrsj9V1Xw5OcBIPJBDoCfPw + 09IVn0sanpOgA8NXR9JYBILO7/rd8n/RV9SM1tPg6wDDEOTQxhFEKLYjbuBljBX9tjzyox/Q+xQ + OcrOf7I20cAAIVz+cCnVNJu8Alo3Nb43nEjoSfa8dIOAMDs6Zy+3wcAyM3kvCtUyZ6qXLd0WZj6 + zE+fAeAX4FZbYo5Fmt9zXfeanwEsQ4xDE0Nqbi203ZhztANVZUb2PdF+imqZLgLX0OvSd7lLbPO + +OFan1B8wGotEE3pCYfpWtX4A2L1rZ+gcHN+Pa8EtEpX3mR9tGlieKSf/dVJ9Ysl7j/fhMYTfuD + aANMIyxDA0Z+r6Qy7MC1Mi3lge1PijTYetBNNTkjUfOjQJAMi+LzE6S7nJtX50krknE74hZQZbi + jo19U7eKcfQAKuaP7lam+hRdZXl19kZX7Xe+PBG2acM7YzE9Bpi1UfeFN9G7Y6+77EfLR59UdGt + VX2G8D7IEPrf7PtZq2XdCmhiCBsUYnGxLJfxP5rzkI0Pb6wDwMypmWXHVupOk0eFEfQZIy+MAQB + 679OGhnSvd0yk4c5o4c7Xamlrwj7Nqck9uVf5eblGVnONqIY1W38+4h3DyJH1i6j6jFi3+B1GaP + m8RGFsa9qrqu7zI6KfHXtHmM8KKq8ZfNZg/rMcLEMMQ5NlH/zLwVDz28SbomVRUxI0RDZJZrqic + ibiYmHFz8Q6cmox6bR8bsfOVwD44ylzH47dgK9lTf5dqpOzZ0V1Hnh0AIDfXMdmO7Zx0h8MaO2a + TJtQf7D16Se9a9CS0+uEofQVmV7ZjqhPmXhrIvQcnV2doeemv6UfIysAeNoVg9TMfdLqZH3ILYI + lx36Oi/v+Knp+/mwhsFfHcR0X2W3Su0Gy4ZrG3tU5GaOHtwhzXv3jqwB8ZgFiaezamFVWAMDO30 + uOQAsjfvFL8QHpdFLOoPE8FQXG99UvxecMbhameOrCnB8tbh0WtjA3IZuYl6TXC1PoY/b9eRwAU + LhYDH3emXdD20EwX4p3SzS4VKWQsAwxDPYHMQxLlnDpJNlbSyEO8BvjvDKrJnZFlcxJ+biGkRT6 + Ynf45VMAqHypXfMa0uY+8JM2Fpycr+QzfQ+JM0+nhPoMBHit3FFxuHT6FB8rGsYnusWZVsoBAVO + HQzrlkoqlcW1qSyQkOMmsE+c9sk2Gy+d//Xzo+Ago40RD3wsARKMrG6oIyxDDsCRDOAtodLsU44 + Md3QtXKcnzLGELoXN7cos4y3jcl0QAYOFrOZ4ySLGooWqgOYBs4XVp+Qw9i2XZX1GyZtIJvQdhR + iIl23S4ntgYSNB67xcWTs2ouDmn97FRrlX6MlzUSt8jo8XQlq0AgMm3J8Ln1OfmnBBg9U2DliGG + YUmGEON7pE1lVNtWAGD2IwlPK1fF6jhziGMxE8eR54QhnWtUatY5hpS5ixfCPmexsDHRLedOeDK + 6YOARsdLxabHqVJIiozbvqQzvsZnvJ33r7dkgfuXQBWHC6NMSIrvqZ+grOTOsX+evPLlZRMlCXs + vGGsZn1osgOt7Q2rMaWIYYhmsyhAj+6tue2ybNZ59ruVfl5k614igL+90NvoNz9LT5jkJgKiVWS + 58CAOVSGYAv9FU0eezXaItsHHkkCQBI360RnDKBzODx7iKNGcPa1FCZk3JArZzT53FC5yB4DxGN + 8IY04d3+m+23AcDMqZmma6wWliGGYcUMCWL/G+HJJsNbhkPtPBxrGwv5pcufAgDcrzlPXayX430 + wD2GMTx/CQlkqqUzokGO8MpZGUwtagqbASTAScuZ8ATOVlGa7wT6Jnnb/QacTaO4CFR0JFsXiiX + joGrte3lUHgJ2/29ly46BliGG4LoY0YvLoZMgyjr9zXCKyTrEozuemsEfRjtEZfUq+4MvWjFxoj + dympTNqamq+iKjP8LJlln6VGQGxkj4hpS2lbJYeXC++xZuQpOxjO2hCi3f0lSxVtAOWIYahLQxp + BKXmijJjQed1R9nbptbNAhbbgRBoQYomxAobW0M5jvuWrpGQRj7MyFlsYg6RSDCS863ZnZf3Emu + FVcNPDMv9/FNKsfsPHAoxf/RFmbpWLLBtVa5JNvY90FcHWpueYRliGNrKkC/+90Ud8EucLjR7dt + Q3qALLaCz7vsT9nO6V7vVXcqBi6jYUqHB7wyvCDWccz6kGpFU1ZqNCENWaKAWOMjZzn8RsbOTDg + UOhz690vZJWYBliGNr6i1/6r0zM9LQqVXGZI3yqeQjfZ4ae2SCWyaY3QbhldOB7kqHHEuGaSiNe + +a3UXlh2zeiaKYOPS7nW19uA8dekPB3TXGf0xVEAgXKv1oCok+VOCcs2DbY2oWc5WIYYhrb4kOm + stFgWL0tUlf9QNB0ygcwoXw5XzQY3D9YBIK7M4MQZwM87HM1dSmzP1KgrFgv7joUFNjlwqSF5ef + V1YUHurFj32PYx75gdL+uUhbyuf6UZeq9WFznJv6KqL33fjYRliGFoiSGc0FLUxQW8VsolmsAa4 + UVCSRnng1PlqBPFNO/gKnVs76RP6WRuo35q6HHJsqkKsPZOto7v2e1dY+QF8RkDfaqIdZCVmsOo + +swIjbX/GwnLEMPQEkPatZoomdE47QsAoHX6aDRcm+B4X/K6YbT+oYxg/ZttopzKxsmhgF8zrzR + 00bDjhp/l8iL508s3lbcDliGGwf4ghsGIFXWONaxHAvgrDMVUhmGLEfuA4xoiT70rgQQdrteBr6 + XbktcoF94G/GY6hrO5U9pipAEAz1mttmfFipXAMsQw3BD5fbVwuJbUGl868UJMXdNEa0eIdocLU + JwH8souSfI8eV7DYcr2lPqDgUNlPtzKSqawIMXQ+3rn418PLEMMgxE+hNirCxkDQK82SrgqBqY5 + K1eZUanK+94ahrpaUfGCyCCDm0VMpDBImb4SaHKgD/FWFVVmMGFl6Tl3Qgpok0eXXwS5HbAMMQx + GMSSIsZekXNp7v8zKymzo0T26WpHO42MjNxsmGHWx6a6/rz/0uWDBi+coFJRdnDHLiI4rTqxQCm + oHLEMMgxFR1mJgMOQ1YHO7S14b1zQhQ5iHsLXoiM6g9SbTICDPdIRbiLw5kyqpNK72djNgGWIYj + GVIPB5e+cBrauvSdh5tGWKbEHMJFrn6HxDf0bNOfE+Na7cEWaFPT+m+oNMjip9J/pE90Xrz9Gph + GWIYjGUIW/zZyMysOcrGuTjXVAwXjbgST0WjKbZ70nXkC77VFy9r/jEXZteC077W0NXCMsQwGJu + HNGJsp+QlfZqXsHWHKi4n1xS0YZvToWc+lPLr+U+k2BSqgV31MnNjvgfLEMNgjGWsFFytiM3WcZ + WBOUWgoj6kqv/Ii00RXBm7GljViBFXwaD/d2IZYhiMjbKWgreUhlb3OAFz4CHZz6aGWHd4hTnHF + cWWjeBAeJKpKbAMMQy3HEO45Mfecfl3qNSyuB5iRtt/XP43hK5w3nK+4rcBNa7FZQIsQwyDMdFF + qxh9UZb+6HtIlr1wF8SHFM6JPsVGueDiMzej8W21sAwxDPYHMQy3nFNfCmltrKuWRDrhv0HlUMW + V8Rrn1JsGyxDDYLS1XA927ZZWooL+MzC29sycuHmNCq3AMsQwfGt8CFHISwEqskbDWwPlkeVgGW + JxczH20lidTXe3AixDLCwsLCwsviX4P68/8cprSSqmAAAAAElFTkSuQmCC +ROLE:Developer +SOUND;ENCODING=b:UklGRiQgAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAgAA + B/f39/f39/f39/f39/f4B/gH+Af4CAgIGBgYGBgYGBgYGBgYGBgYGBgIGAgICBgYGBgYGBgYCAg + YGAgICAgICAgIGBgICAgYCAgICBgICAgICAgICAgIGAgICAgYCAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAf4CAgICAgICAgICAgICAgIB/f4CAgICAgICAgIB/f4B/f39/f39/f3+AgICAf4CAf3 + 9/gIB/f4CAgH9/gICAgH+AgICAgICAgICAf4CAgIB/gICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgIB/gICAf39/f39/f3+Af4CAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgH9/f39/f39/f39/f39/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgIGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYCAgICB + gICAgYGBgICAgICAgICAgIGAgICBgICBgYGBgYGBgYGAgYGBgYCBgYGBgYGBgYGBgYGBgYGBgYG + BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgICAgYGBgIGBgYGAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYGAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgH+AgICAgICAgICAgICAgICAgICAf4CAgIB/gH+Af4B/f39/f39/f + 39/f39/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYG + BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgY + GBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGAgIGBgYCAgICBgYCAgYGBgYCAgICBg + YCAgICAgICAgICAgICAgIGAgICAgICAgICAgICAgYGBgYGAgICAgIGBgYCAgICBgYGAgICAgIGA + gICAgICAgIGBgYCBgYGAgYGBgYGBgoGBgYGCgoGAgICBgYGBgYCBgYKCgYGBgYGBgYGAgYGBgH9 + /gIB/f3+AgIB/gH9/gICAf4CBgYB/f35+gIB/f4CBgX9/gYCAgYKCgYCAgYOBgICAgoGAf4GCgn + 9/gIB/gICBgH5/f4GAfX+BgYB+fn9/fn+Afn6Af39+f35+fn9+fn6AgH9/f4CAgYCAgYKCgH9/g + IKBf3+AgYJ/f4GCg4F/gIGCgoOBfoCDgYF/fH+BgYGAfn6Af4CCgn58gIN/fX+AgICBgYGAgYCB + goOCgICBgYB/fXyBhIGAgH5+f4GBgX9/f35+gIKCgXt9goN/f318f4GAf4B/fHt9fn5+fXx+fn5 + /gH9+fHx/gHx9f4CAfn18gIB9e4GBfn5+foCBfHyAgoGAfX6CgYCBgH+DgHt9gYN/fX2BhYB7en + 6AgH98foKCgH18foCAfoCAf4CAf31+fn+AgH1+goJ/fX5/gIKAgIGAfH6CgX17foCBf3+BgoB/g + YOBgIB/f4KDgoJ+e3+ChIOBfn1/gX+BfX2BgH59foCCfn1/gX99fICAgoB/f39/gISCf36AgoSB + foCBgYGAf4CCf4CCgX5/gYKDgYB/gH+BhIOBgYB/gIOEhIF9foGCg4OBgICBgoOCgICChIOBg4O + CgoSDgoKAgYKBgoODhISBf4CCg4SEgoGCg4SEgH6BhIWEgX+EhYKAgoKFhIB+gIKChYKAgYOCgo + B+gYWFhIKAg4WEg4ODhIWFhYaGhIWGhYWGh4eHhYOCgoSFg4B/gIB+fX1+fn57e3t7fHt6fH5/f + 4GDhYiMkJGQj5GVmZycmZiXlZGIfXRwcnZ4d3Nva2hoamppaWxvc3R0dXl+iJCPjZShqrCzvNHi + rFYxOmKSrJ6UmJOAbV1ZboSMjI6JfnNjW2JweYGFg4B/e3Z0c3Btc3p9fHp4fIGBf3+Dh4qLjJG + YnZuWkY6MhnpwbnN6fHlya2hlZmdmaW9ycXFzd3t/g42cpquzvMzd/sRADiBZkL6xpLa1jFpANV + iHoJ2ioJWGbEQ2VHaOm5aHhIFuYmZzgoVxZFxfdJCSgnt/kKewr7bDsopcSV6JopyRjpOQfmNXZ + HmGhYB8fXtvXExKXnyKgnJsc3t8fZC0ysfK0+vHTxEeXY6yr6rAxJRSNTdbh5+fp7KjglQ6PVx3 + ho6Ph3dmW15oa2x0hIuNkK3R18jJ0Ys8LUlxkqais8WtdlBFT2yDjpywro9mS0VVaXaBiIdyX2J + rcG5udYKKjaXT4dfV2Y82JkBpiaKkvdO2eE9GTGZ4hZu6u51yTUNOX2l9kZWKdl5PXG93dHeAip + KZut7j2tacRjJIYHCOo77XvoRdVlFYZniVuL+kfl9ST1Rcb4mTjoNxW1pqdXd5fH6CiKHN4d7k2 + 4E4N05Yaoqo1eO0emVbTU5ZdKDCuZV9b1tMSVlyiYp8dHl7cmpqdYCCgIqixNTR2OqnRTlPXFt3 + ksbnw4lzcFdKS2KMtLWZiIZwV0lPZXZ1b3uNinZqbXJ3dX2XxOPg4/zDUDRCTUhmiMXx1p+If1g + +O1J7pK+yspN3W0pGVGdugYmCen54b21rb3V9i6vZ7vD92WpAS0gzSny04tq3qp5qPDhHX3uVrs + KukXVhT0hRYnF/gnuCh31ubG9zdHeMs+Dr8P7KalFVOylJeq7QzMPIqmtIRUZOY4KovqicknhZS + 1BWXWh6gIeLiH91b21vc4GcyuXt/umTZGhGIjJfh6y+yt7LkGlfTD1GYYOipKKwnXhkXldVUFhs + dYOMjYWBem9ucoCWvNTm9+2weHdZMSpQboujvtnUrY6BZEdDUmV4jZypppeFd2dcWVFWWWh8hYS + Ii393c3Z7iJ3A1ePp3aGDfVYyOVZkfJe5zsavpJNsU1BTVmR9kpmcn5uGdGxoWU5VVGZ0fIKLh4 + F/d3Z6g4ufuc3e3depjoViPz9VWm2FqLu8tLGifmphWlJZbH+Lj5+elod+c19WU0xUZW11gISEg + nx6e3h6g4qWp7zM3NrSpZGIYkRFVVVlfZ6vsbW3qIl7b2BUWGVwe4ybn52TkIRuX2BVRVFjZmp7 + hIF9fX12cnZ6eX6LlZyousfP0c++jot6X0ZRXF9sgaCnqa6yn4eAdGZZYGlvd4mcnqCWnY91aWN + cSUtYYmJxf399f351cXFzcHF4foOIlZ+hp7CytLm8uLKNg4RtYF5oanN8j5qZnqGaioV9dGpqb3 + J1f42Rk5iZjIKAcmFcW1RXYGhwdXt+e3Z2c25tcXJxd3yChY2Tl5udn6Gho6ioq6uonoaHbWNzZ + GdxgoGPlZqdj5CJgHFzcWxwdH1/hYqOioSFfnFpaWBdX2Jqb3N5fHh4eHNxcXFxc3d7foOJjI6Q + lZOSlZOTl5eYnJucnpyZkYiEfnd1dnZ5fYKHio6QkIyHg394dHRzc3Z5fHt2enJrcG5obG9sbW9 + ucHJzdnh3eXp5eXt9foCDhoeJjI6OkJGSk5aYmZudn6Gjn5qLh4J3cnJ0dHR5g4GEi42Ih4aBfH + h4dXR1eHl4dXhuaW5rZ2ltaWttbW5vcnR1dHZ2dXV2d3d7fn+BhIeIiYuOjpCTlJWZnJueoKarr + ZuJhntvaW1ucnh+hIWJi4qFg4F7d3V1c3R3fH1/gHlvbXJnXmdpYmdtamtxcW9vbm9tamxtbG5z + dXZ5fHx7fX9+fH6AgoWHioyNj5CRlZeYmp2TiYyGenp9eXh9fX19foB/fH1/e3p8e3l5e3x7e3x + 6d3FxcnBwcG9vb29vb29wb25tbWxsbW5vb3Fyc3N1dXV1dnd4ent9fn+BgoGAgoWEhoqJiYyLi4 + yPioaLiYSEh4WDhIOCgoKAgX58fXx5eXp4eHl4dXZ1cnN0dHR1cnJycXBxcnJycW9ubGxsbW1ub + m5ub29vcXNzdHZ2dXh6enp+fn5/gYCBhIKFiYeGiomJi4qKjIuLjIyLiomKh4aKioeIiIWDgYB9 + fHx7e3l4eHh2dnd3d3l7enp6enp5ent7e3x7enl6e3t7fHx7e3p8fX5/gIKDg4GCg4KCg4OEhoe + Hh4iJiomLjIqLi4uLi46Pjo2OjouJiomHh4aDgH9/fXp5eXh3d3h4eHh4d3V2d3Z0dnd0dXd3d3 + p7fH59fX19fH5+fn+Af4CAf3+Af359f4KDgoSIiIeJjI6PkJOUk5SYmZiYmZqZmJqamJiZmJaWl + ZSTkZCQj46Ni4qHh4iFgoKBfn9+fn+AgYCAgYOCgoSEg4SFhIODg4OCgICBf35/gICAgYKCgYGD + hIOBgYOCgYGAgIGBgIGCgoKBgoSEg4KCgH9/f318fHt6e3t7enl5eHh5fH18foCAf4GDg4OFhoa + GhoeJh4aJioiIiYiIhoWGh4aGh4eHiImHh4mIiIeHh4iIiIqJioqJh4mKh4eJiYiHh4eHhoWGhY + OEhYWEhYWDg4SFhYWEg4SDgYKCgH+AgICBgoOCgYGBgYKEhoaGhoiIh4eJiYmKioqKiomKioiJi + oqJiYmJiIiIiYiHh4eHh4eGhYWFhISDgoKCgoKCgYGAf31+fXx9fn58e3x8fHx9fX19fX19fX19 + fHx9fn5/gICBgYGCgoKCg4OCgoODgoKDg4OCgoKCgoGBgYGBgYGCgYCBgIGCgoKDg4KCg4OEhIS + FhYWFhYWFhYWFhoWGhoWEhISDg4ODg4ODg4ODg4SDgoKDg4OCg4SDgoKDgoGBgoGAgIB/f35+fn + 9+fn9/f35+fn5/gICAgIGBgYKCg4ODg4SEg4OEhIODhIODhIODg4ODg4OCgoKBgoKCg4OCgoODg + 4ODg4OEhISEhIWEhIWFhISEhISEhIWEhISEhIODhISEg4ODg4ODg4ODg4ODgoKCgoKCg4KCgoKC + goKCgoKCgoOCgoKCgoKBgYKCgoKCgoGBgYGAgICAgYGBgYCAf39/f39/f3+Af39/f39/f39/gIC + AgIB/f39/f39/gICAgIB/f39/gIB/f39/gH9/f39/f39/fn5+f39/f39/fn5+fn5/f39/f39/fn + 5+fn9/f39/f35+fn5+fn9/f35/f39+fn5+fn9/fn5+fn5+fn5+f39+fn5+fn19fX5+fn5+fn5+f + X5+fn5+fn5+fn19fn5+fn5+fX19fX59fn5+fn19fX19fX1+fX19fX19fX19fX19fX19fX19fX19 + fX19fX19fX19fX19fX19fX19fX19fX19fXx9fX18fH19fXx8fXx9fXx8fHx8fHx8fH19fX19fXx + 9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX + 19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f + X19fX19fX19fX19fX19fX19fX19fX19fX1+fX5+fn19fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+ + fn5+fn5+fn5+fn5+f39/fn5/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f3 + 9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f + 39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/ + f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f39/f39/f39/f39/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3 + 9/f39/f39/f39/f39/f39/f35+fn5+f35/f39/f39/f39/f39/f39/f39/f39/f39/f39/f35+f + 39+fn5/fn5+f39/fn9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/ + f39/f39/f39/f39/f39+fn9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f4CAf39/f39/f39/gIB/f39/f39/f4B/f4CAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgIB/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAgIC + AgICAgICAgICAgICAgICAgICAgICAgIGBgYGAgYGBgICAgIGAgICBgYGAgYGBgYGBgYGBgYGBgY + GBgYGBgYGBgYGBgYGBgYGAgYCAgICAgICAgICAgICAgICAgICAgICAgICAgH+AgICAf39/gH9/f + 3+Af39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4CAgH9/gIB/f39/f4B/f3+AgICAf4CA + gICAgICAgICAgICAgH9/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgIB/f39/f39/f39/f4CAf39/f39/f39/f39/f39/f39+fn + 9/fn5+fn5+fn5+fn5+fX19fX19fX19fX19fX19fX19fn5+fn5+fn9/f39/f4CAgICAgICBgYGBg + YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICAgICAgICAgICAgICAgYGAgICA + gICAgICAgICAgICBgYGAgICAgICAgICAgICAgICAgICAgICAgIB/gICAgH9/f39/f39/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAgICAf39/f39/gH+AgI + CAgICAgIB/f39/f39/f4B/f39/f39/f39/f39/f39/f39/f39/f39/f39/fn9/f39/f39/f39+f + 39/f39/f39/f39/f39/f39/f39/f4B/f4CAgICAf39/f39/gICAf39/gICAgICAgICAgICAgICA + gICAgIGAgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICBgYGBgYGBgYCBgYGBgYCAgIG + BgICAgICAgICAgICAgICAgICAgICAgICAgICBgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAf3+AgIB/f4CAf39/f39/f3+AgICAgH+AgICAf3+AgICAgICAgH9/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3 + 9/f39/f39/gH9/gICAgICAgICAgIB/gICAgH+AgIB/f39/f39/gICAgICAgH9/f3+AgH9/f4B/f + 39/f39/f39/f39/f3+AgICAgICAf3+AgIB/f4CAgIB/f4CAgICAgICAgICAf39/f3+AgIB/f4CA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAf39/f39 + /f4CAgH9/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f39/f39/gIB/f39/f39/f39/gH9/f3 + 9/f4CAgICAgIB/gICAgICAgICAgICAgICAgICAgICAgICAgH+AgICAf4CAgICAgICAgIB/gICAf + 4CAgICAgH+Af4CAgH9/f39/f39/f39/gICAgICAgICAgICAf39/f39/f4CAgH9/gICAf3+AgICA + gICAgICAgICAgICAgICAgICAgIB/f39/gIB/f4CAgIB/f4CAgH9/gICAf39/f39/f39/f39/f39 + /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3 + 9/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAf39/gH9/f3+AgH9/f39/f39/f39/f39/f + 39/f39/f39/f39/f39/f39/f39/gICAf3+AgH9/f3+AgH9/f4CAgH9/gICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAgICAgICBgYGBgIGBgYCAgYGAgICAgYCAgICAgICAgICAgICAgICAg + ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA + gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC + AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI + CAgICAgICAgICAgICAgICAf39/f39/f4CAgIB/f4CAgICAgICAgICAgICAgICAgICAgICAgICAg + ICAf39/f3+Af39/f39/f39/f4B/f39/f4CAgICAgICAgICAgA== +TEL;TYPE=HOME:0351 223344 +TEL;TYPE=WORK:0351 443322 +TEL;TYPE=CELL:0173 223344 +UID:P9HXg34Oav +URL:http://www.mustermann.de/~heiko/ +VERSION:3.0 +X-KADDRESSBOOK-X-Anniversary:1982-07-07 +X-KADDRESSBOOK-X-AssistantsName:Mr. Smithers +X-KADDRESSBOOK-X-Department:Edutainment +X-KADDRESSBOOK-X-IMAddress:122334455 +X-KADDRESSBOOK-X-ManagersName:Mr. Burnes +X-KADDRESSBOOK-X-Office:223 2nd stage +X-KADDRESSBOOK-X-Profession:Clown +X-KADDRESSBOOK-X-SpousesName:femal clown +END:VCARD + diff --git a/kabc/vcardparser/tests/vcard5.vcf.ref b/kabc/vcardparser/tests/vcard5.vcf.ref new file mode 100644 index 000000000..712b49494 --- /dev/null +++ b/kabc/vcardparser/tests/vcard5.vcf.ref @@ -0,0 +1,313 @@ +BEGIN:VCARD
+ADR;TYPE=home;TYPE=pref:;;Buehlauer Strasse 45;Dresden;Sachsen;01327;German
+ y
+ADR;TYPE=work:;;Prager Strasse 55;Dresden;Sachsen;01066;Germany
+BDAY:1955-07-19T00:00:00Z
+CATEGORIES:Friend
+CLASS:CONFIDENTIAL
+EMAIL;TYPE=PREF:heiko.mustermann@freenet.org
+EMAIL:heiko8@tst.inf.tu-dresden.de
+FN:Mustermann, Heiko
+GEO:19.283333;166.616669
+LOGO;ENCODING=b;TYPE=image/png:iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVU
+ AAAOW0lEQVR4nO1df2hb1xX+OlyQwQEJXJAgBQlaiEwDsdqO2l1H47RjMe2gbjOoszG2dozG7aC
+ YMIqTjS7NYKSmbE1StsQpWxMXmsSF1WhlTeSwJlZY06gsSVXWUAkakKAGPajBDxrQ/jjnez8k27
+ EjJdyU+/0jPz29X9L57jnnO+deAxYWFhYWFhYWFu3Hbe082XT2ZF3+WgAAdHZ0AgBqTg0A4H7DT
+ 7oAgNSdKQDAg99/sK33caPB53RqFQBA5PYIAMBdkOf6yc9+ct3P852W786irWjJMs/8+0wdACpV
+ sZTS50V5vSLb1UoVQMCCvnFDx0c65f3BHw4CABJ3RL19mwYfM4Y1e/+0V5h/VbbPXzwPACiVSgA
+ A15XnikVjAIB44Dli3TIKjL+2e0XPYxliGFZshSdzZ+r8OyKGjdl8AQCQfe84AKBaFUaUrojlRL
+ vEUpx5h0eGjo9EZH+kQ7Yz9/d71+vdkAYApO+W16d+/NQNZ8ye8T11ACiV5TkcR5jufCX3XyrLc
+ 9XmxUe6bvi5XH3OaNRnSKRL9vWsywAAstNTyz6HZYhhsD+IYbjmMPDxfz6uA0BMqQcAR96eAgBM
+ vSevtTkJa6tzQnVSNn2XOLSZ03ljHHQ7MLxlSIa2kg5pOrTVHHHu/hANRDrke4t2y3cy+KgEMPs
+ P7F/0O7EMMQzXtNxLn16qA8DUu1nvvcm3DgEAFlxxbo4jFpFYK4woXix8qxhxLYxuH6sDQG5Gvq
+ NSueLtcxwdNTTASemoUTi3+HdkGWIYlrTkj2clzC1ckGRv3xv7vH2VK7QAlUDuktA0f/bG+YpL5
+ 4WpDDXv7TdPbjm472AdACbe9L+r4mdMHuW+42uTAIByuWwZciugY6kdER3zzn8iMkFt3pc93Kvy
+ d0QzvHYxI5h8Qq/BiK1YLur78nJw4mBIznj2V88ueg+HjxyrA0BEdE7EumLePp773u/e25b7jyb
+ kfAObh7z3SleELS40SVZ/u+2F0ToA7H99PHRtyxDD0GQZZ9RKKxUZ+/YdmAAAFD4peJ9hbF2dq7
+ aHGSpn12p+dJI7PQsAcDS3YcxfmZPXnrt65F40P+pd3wsgwF69x/xHedlWNkfX+PlUep0ck0omA
+ ACxO+R10w82tfRch8leAJOas82ek+cho/sfkGtnT8xYhpiMJh9CiytVZayjYIgO37KCmWgrOPy3
+ w3UAKKpsf/zd496+wkVhpOu5Lje0XS6X9X5lbJ49KxZIJqSSEu+Xrsj9V1Xw5OcBIPJBDoCfPw0
+ 9IVn0sanpOgA8NXR9JYBILO7/rd8n/RV9SM1tPg6wDDEOTQxhFEKLYjbuBljBX9tjzyox/Q+xQO
+ crOf7I20cAAIVz+cCnVNJu8Alo3Nb43nEjoSfa8dIOAMDs6Zy+3wcAyM3kvCtUyZ6qXLd0WZj6z
+ E+fAeAX4FZbYo5Fmt9zXfeanwEsQ4xDE0Nqbi203ZhztANVZUb2PdF+imqZLgLX0OvSd7lLbPO+
+ OFan1B8wGotEE3pCYfpWtX4A2L1rZ+gcHN+Pa8EtEpX3mR9tGlieKSf/dVJ9Ysl7j/fhMYTfuDa
+ ANMIyxDA0Z+r6Qy7MC1Mi3lge1PijTYetBNNTkjUfOjQJAMi+LzE6S7nJtX50krknE74hZQZbij
+ o19U7eKcfQAKuaP7lam+hRdZXl19kZX7Xe+PBG2acM7YzE9Bpi1UfeFN9G7Y6+77EfLR59UdGtV
+ X2G8D7IEPrf7PtZq2XdCmhiCBsUYnGxLJfxP5rzkI0Pb6wDwMypmWXHVupOk0eFEfQZIy+MAQB6
+ 79OGhnSvd0yk4c5o4c7Xamlrwj7Nqck9uVf5eblGVnONqIY1W38+4h3DyJH1i6j6jFi3+B1GaPm
+ 8RGFsa9qrqu7zI6KfHXtHmM8KKq8ZfNZg/rMcLEMMQ5NlH/zLwVDz28SbomVRUxI0RDZJZrqici
+ biYmHFz8Q6cmox6bR8bsfOVwD44ylzH47dgK9lTf5dqpOzZ0V1Hnh0AIDfXMdmO7Zx0h8MaO2aT
+ JtQf7D16Se9a9CS0+uEofQVmV7ZjqhPmXhrIvQcnV2doeemv6UfIysAeNoVg9TMfdLqZH3ILYIl
+ x36Oi/v+Knp+/mwhsFfHcR0X2W3Su0Gy4ZrG3tU5GaOHtwhzXv3jqwB8ZgFiaezamFVWAMDO30u
+ OQAsjfvFL8QHpdFLOoPE8FQXG99UvxecMbhameOrCnB8tbh0WtjA3IZuYl6TXC1PoY/b9eRwAUL
+ hYDH3emXdD20EwX4p3SzS4VKWQsAwxDPYHMQxLlnDpJNlbSyEO8BvjvDKrJnZFlcxJ+biGkRT6Y
+ nf45VMAqHypXfMa0uY+8JM2Fpycr+QzfQ+JM0+nhPoMBHit3FFxuHT6FB8rGsYnusWZVsoBAVOH
+ QzrlkoqlcW1qSyQkOMmsE+c9sk2Gy+d//Xzo+Ago40RD3wsARKMrG6oIyxDDsCRDOAtodLsU44M
+ d3QtXKcnzLGELoXN7cos4y3jcl0QAYOFrOZ4ySLGooWqgOYBs4XVp+Qw9i2XZX1GyZtIJvQdhRi
+ Il23S4ntgYSNB67xcWTs2ouDmn97FRrlX6MlzUSt8jo8XQlq0AgMm3J8Ln1OfmnBBg9U2DliGGY
+ UmGEON7pE1lVNtWAGD2IwlPK1fF6jhziGMxE8eR54QhnWtUatY5hpS5ixfCPmexsDHRLedOeDK6
+ YOARsdLxabHqVJIiozbvqQzvsZnvJ33r7dkgfuXQBWHC6NMSIrvqZ+grOTOsX+evPLlZRMlCXsv
+ GGsZn1osgOt7Q2rMaWIYYhmsyhAj+6tue2ybNZ59ruVfl5k614igL+90NvoNz9LT5jkJgKiVWS5
+ 8CAOVSGYAv9FU0eezXaItsHHkkCQBI360RnDKBzODx7iKNGcPa1FCZk3JArZzT53FC5yB4DxGN8
+ IY04d3+m+23AcDMqZmma6wWliGGYcUMCWL/G+HJJsNbhkPtPBxrGwv5pcufAgDcrzlPXayX430w
+ D2GMTx/CQlkqqUzokGO8MpZGUwtagqbASTAScuZ8ATOVlGa7wT6Jnnb/QacTaO4CFR0JFsXiiXj
+ oGrte3lUHgJ2/29ly46BliGG4LoY0YvLoZMgyjr9zXCKyTrEozuemsEfRjtEZfUq+4MvWjFxojd
+ ympTNqamq+iKjP8LJlln6VGQGxkj4hpS2lbJYeXC++xZuQpOxjO2hCi3f0lSxVtAOWIYahLQxpB
+ KXmijJjQed1R9nbptbNAhbbgRBoQYomxAobW0M5jvuWrpGQRj7MyFlsYg6RSDCS863ZnZf3EmuF
+ VcNPDMv9/FNKsfsPHAoxf/RFmbpWLLBtVa5JNvY90FcHWpueYRliGNrKkC/+90Ud8EucLjR7dtQ
+ 3qALLaCz7vsT9nO6V7vVXcqBi6jYUqHB7wyvCDWccz6kGpFU1ZqNCENWaKAWOMjZzn8RsbOTDgU
+ Ohz690vZJWYBliGNr6i1/6r0zM9LQqVXGZI3yqeQjfZ4ae2SCWyaY3QbhldOB7kqHHEuGaSiNe+
+ a3UXlh2zeiaKYOPS7nW19uA8dekPB3TXGf0xVEAgXKv1oCok+VOCcs2DbY2oWc5WIYYhrb4kOms
+ tFgWL0tUlf9QNB0ygcwoXw5XzQY3D9YBIK7M4MQZwM87HM1dSmzP1KgrFgv7joUFNjlwqSF5efV
+ 1YUHurFj32PYx75gdL+uUhbyuf6UZeq9WFznJv6KqL33fjYRliGFoiSGc0FLUxQW8VsolmsAa4U
+ VCSRnng1PlqBPFNO/gKnVs76RP6WRuo35q6HHJsqkKsPZOto7v2e1dY+QF8RkDfaqIdZCVmsOo+
+ swIjbX/GwnLEMPQEkPatZoomdE47QsAoHX6aDRcm+B4X/K6YbT+oYxg/ZttopzKxsmhgF8zrzR0
+ 0bDjhp/l8iL508s3lbcDliGGwf4ghsGIFXWONaxHAvgrDMVUhmGLEfuA4xoiT70rgQQdrteBr6X
+ bktcoF94G/GY6hrO5U9pipAEAz1mttmfFipXAMsQw3BD5fbVwuJbUGl868UJMXdNEa0eIdocLUJ
+ wH8souSfI8eV7DYcr2lPqDgUNlPtzKSqawIMXQ+3rn418PLEMMgxE+hNirCxkDQK82SrgqBqY5K
+ 1eZUanK+94ahrpaUfGCyCCDm0VMpDBImb4SaHKgD/FWFVVmMGFl6Tl3Qgpok0eXXwS5HbAMMQxG
+ MSSIsZekXNp7v8zKymzo0T26WpHO42MjNxsmGHWx6a6/rz/0uWDBi+coFJRdnDHLiI4rTqxQCmo
+ HLEMMgxFR1mJgMOQ1YHO7S14b1zQhQ5iHsLXoiM6g9SbTICDPdIRbiLw5kyqpNK72djNgGWIYjG
+ VIPB5e+cBrauvSdh5tGWKbEHMJFrn6HxDf0bNOfE+Na7cEWaFPT+m+oNMjip9J/pE90Xrz9GphG
+ WIYjGUIW/zZyMysOcrGuTjXVAwXjbgST0WjKbZ70nXkC77VFy9r/jEXZteC077W0NXCMsQwGJuH
+ NGJsp+QlfZqXsHWHKi4n1xS0YZvToWc+lPLr+U+k2BSqgV31MnNjvgfLEMNgjGWsFFytiM3WcZW
+ BOUWgoj6kqv/Ii00RXBm7GljViBFXwaD/d2IZYhiMjbKWgreUhlb3OAFz4CHZz6aGWHd4hTnHFc
+ WWjeBAeJKpKbAMMQy3HEO45Mfecfl3qNSyuB5iRtt/XP43hK5w3nK+4rcBNa7FZQIsQwyDMdFFq
+ xh9UZb+6HtIlr1wF8SHFM6JPsVGueDiMzej8W21sAwxDPYHMQy3nFNfCmltrKuWRDrhv0HlUMWV
+ 8Rrn1JsGyxDDYLS1XA927ZZWooL+MzC29sycuHmNCq3AMsQwfGt8CFHISwEqskbDWwPlkeVgGWJ
+ xczH20lidTXe3AixDLCwsLCwsviX4P68/8cprSSqmAAAAAElFTkSuQmCC
+N:Mustermann;Heiko;;;
+NICKNAME:clown
+NOTE:I'm a friendly note text,\nplease copy me to your address book...
+ORG:KDE
+PHOTO;ENCODING=b;TYPE=image/png:iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pV
+ UAAAOW0lEQVR4nO1df2hb1xX+OlyQwQEJXJAgBQlaiEwDsdqO2l1H47RjMe2gbjOoszG2dozG7a
+ CYMIqTjS7NYKSmbE1StsQpWxMXmsSF1WhlTeSwJlZY06gsSVXWUAkakKAGPajBDxrQ/jjnez8k2
+ 7EjJdyU+/0jPz29X9L57jnnO+deAxYWFhYWFhYWFu3Hbe082XT2ZF3+WgAAdHZ0AgBqTg0A4H7D
+ T7oAgNSdKQDAg99/sK33caPB53RqFQBA5PYIAMBdkOf6yc9+ct3P852W786irWjJMs/8+0wdACp
+ VsZTS50V5vSLb1UoVQMCCvnFDx0c65f3BHw4CABJ3RL19mwYfM4Y1e/+0V5h/VbbPXzwPACiVSg
+ AA15XnikVjAIB44Dli3TIKjL+2e0XPYxliGFZshSdzZ+r8OyKGjdl8AQCQfe84AKBaFUaUrojlR
+ LvEUpx5h0eGjo9EZH+kQ7Yz9/d71+vdkAYApO+W16d+/NQNZ8ye8T11ACiV5TkcR5jufCX3XyrL
+ c9XmxUe6bvi5XH3OaNRnSKRL9vWsywAAstNTyz6HZYhhsD+IYbjmMPDxfz6uA0BMqQcAR96eAgB
+ MvSevtTkJa6tzQnVSNn2XOLSZ03ljHHQ7MLxlSIa2kg5pOrTVHHHu/hANRDrke4t2y3cy+KgEMP
+ sP7F/0O7EMMQzXtNxLn16qA8DUu1nvvcm3DgEAFlxxbo4jFpFYK4woXix8qxhxLYxuH6sDQG5Gv
+ qNSueLtcxwdNTTASemoUTi3+HdkGWIYlrTkj2clzC1ckGRv3xv7vH2VK7QAlUDuktA0f/bG+YpL
+ 54WpDDXv7TdPbjm472AdACbe9L+r4mdMHuW+42uTAIByuWwZciugY6kdER3zzn8iMkFt3pc93Kv
+ yd0QzvHYxI5h8Qq/BiK1YLur78nJw4mBIznj2V88ueg+HjxyrA0BEdE7EumLePp773u/e25b7jy
+ bkfAObh7z3SleELS40SVZ/u+2F0ToA7H99PHRtyxDD0GQZZ9RKKxUZ+/YdmAAAFD4peJ9hbF2dq
+ 7aHGSpn12p+dJI7PQsAcDS3YcxfmZPXnrt65F40P+pd3wsgwF69x/xHedlWNkfX+PlUep0ck0om
+ AACxO+R10w82tfRch8leAJOas82ek+cho/sfkGtnT8xYhpiMJh9CiytVZayjYIgO37KCmWgrOPy
+ 3w3UAKKpsf/zd496+wkVhpOu5Lje0XS6X9X5lbJ49KxZIJqSSEu+Xrsj9V1Xw5OcBIPJBDoCfPw
+ 09IVn0sanpOgA8NXR9JYBILO7/rd8n/RV9SM1tPg6wDDEOTQxhFEKLYjbuBljBX9tjzyox/Q+xQ
+ OcrOf7I20cAAIVz+cCnVNJu8Alo3Nb43nEjoSfa8dIOAMDs6Zy+3wcAyM3kvCtUyZ6qXLd0WZj6
+ zE+fAeAX4FZbYo5Fmt9zXfeanwEsQ4xDE0Nqbi203ZhztANVZUb2PdF+imqZLgLX0OvSd7lLbPO
+ +OFan1B8wGotEE3pCYfpWtX4A2L1rZ+gcHN+Pa8EtEpX3mR9tGlieKSf/dVJ9Ysl7j/fhMYTfuD
+ aANMIyxDA0Z+r6Qy7MC1Mi3lge1PijTYetBNNTkjUfOjQJAMi+LzE6S7nJtX50krknE74hZQZbi
+ jo19U7eKcfQAKuaP7lam+hRdZXl19kZX7Xe+PBG2acM7YzE9Bpi1UfeFN9G7Y6+77EfLR59UdGt
+ VX2G8D7IEPrf7PtZq2XdCmhiCBsUYnGxLJfxP5rzkI0Pb6wDwMypmWXHVupOk0eFEfQZIy+MAQB
+ 679OGhnSvd0yk4c5o4c7Xamlrwj7Nqck9uVf5eblGVnONqIY1W38+4h3DyJH1i6j6jFi3+B1GaP
+ m8RGFsa9qrqu7zI6KfHXtHmM8KKq8ZfNZg/rMcLEMMQ5NlH/zLwVDz28SbomVRUxI0RDZJZrqic
+ ibiYmHFz8Q6cmox6bR8bsfOVwD44ylzH47dgK9lTf5dqpOzZ0V1Hnh0AIDfXMdmO7Zx0h8MaO2a
+ TJtQf7D16Se9a9CS0+uEofQVmV7ZjqhPmXhrIvQcnV2doeemv6UfIysAeNoVg9TMfdLqZH3ILYI
+ lx36Oi/v+Knp+/mwhsFfHcR0X2W3Su0Gy4ZrG3tU5GaOHtwhzXv3jqwB8ZgFiaezamFVWAMDO30
+ uOQAsjfvFL8QHpdFLOoPE8FQXG99UvxecMbhameOrCnB8tbh0WtjA3IZuYl6TXC1PoY/b9eRwAU
+ LhYDH3emXdD20EwX4p3SzS4VKWQsAwxDPYHMQxLlnDpJNlbSyEO8BvjvDKrJnZFlcxJ+biGkRT6
+ Ynf45VMAqHypXfMa0uY+8JM2Fpycr+QzfQ+JM0+nhPoMBHit3FFxuHT6FB8rGsYnusWZVsoBAVO
+ HQzrlkoqlcW1qSyQkOMmsE+c9sk2Gy+d//Xzo+Ago40RD3wsARKMrG6oIyxDDsCRDOAtodLsU44
+ Md3QtXKcnzLGELoXN7cos4y3jcl0QAYOFrOZ4ySLGooWqgOYBs4XVp+Qw9i2XZX1GyZtIJvQdhR
+ iIl23S4ntgYSNB67xcWTs2ouDmn97FRrlX6MlzUSt8jo8XQlq0AgMm3J8Ln1OfmnBBg9U2DliGG
+ YUmGEON7pE1lVNtWAGD2IwlPK1fF6jhziGMxE8eR54QhnWtUatY5hpS5ixfCPmexsDHRLedOeDK
+ 6YOARsdLxabHqVJIiozbvqQzvsZnvJ33r7dkgfuXQBWHC6NMSIrvqZ+grOTOsX+evPLlZRMlCXs
+ vGGsZn1osgOt7Q2rMaWIYYhmsyhAj+6tue2ybNZ59ruVfl5k614igL+90NvoNz9LT5jkJgKiVWS
+ 58CAOVSGYAv9FU0eezXaItsHHkkCQBI360RnDKBzODx7iKNGcPa1FCZk3JArZzT53FC5yB4DxGN
+ 8IY04d3+m+23AcDMqZmma6wWliGGYcUMCWL/G+HJJsNbhkPtPBxrGwv5pcufAgDcrzlPXayX430
+ wD2GMTx/CQlkqqUzokGO8MpZGUwtagqbASTAScuZ8ATOVlGa7wT6Jnnb/QacTaO4CFR0JFsXiiX
+ joGrte3lUHgJ2/29ly46BliGG4LoY0YvLoZMgyjr9zXCKyTrEozuemsEfRjtEZfUq+4MvWjFxoj
+ dympTNqamq+iKjP8LJlln6VGQGxkj4hpS2lbJYeXC++xZuQpOxjO2hCi3f0lSxVtAOWIYahLQxp
+ BKXmijJjQed1R9nbptbNAhbbgRBoQYomxAobW0M5jvuWrpGQRj7MyFlsYg6RSDCS863ZnZf3Emu
+ FVcNPDMv9/FNKsfsPHAoxf/RFmbpWLLBtVa5JNvY90FcHWpueYRliGNrKkC/+90Ud8EucLjR7dt
+ Q3qALLaCz7vsT9nO6V7vVXcqBi6jYUqHB7wyvCDWccz6kGpFU1ZqNCENWaKAWOMjZzn8RsbOTDg
+ UOhz690vZJWYBliGNr6i1/6r0zM9LQqVXGZI3yqeQjfZ4ae2SCWyaY3QbhldOB7kqHHEuGaSiNe
+ +a3UXlh2zeiaKYOPS7nW19uA8dekPB3TXGf0xVEAgXKv1oCok+VOCcs2DbY2oWc5WIYYhrb4kOm
+ stFgWL0tUlf9QNB0ygcwoXw5XzQY3D9YBIK7M4MQZwM87HM1dSmzP1KgrFgv7joUFNjlwqSF5ef
+ V1YUHurFj32PYx75gdL+uUhbyuf6UZeq9WFznJv6KqL33fjYRliGFoiSGc0FLUxQW8VsolmsAa4
+ UVCSRnng1PlqBPFNO/gKnVs76RP6WRuo35q6HHJsqkKsPZOto7v2e1dY+QF8RkDfaqIdZCVmsOo
+ +swIjbX/GwnLEMPQEkPatZoomdE47QsAoHX6aDRcm+B4X/K6YbT+oYxg/ZttopzKxsmhgF8zrzR
+ 00bDjhp/l8iL508s3lbcDliGGwf4ghsGIFXWONaxHAvgrDMVUhmGLEfuA4xoiT70rgQQdrteBr6
+ XbktcoF94G/GY6hrO5U9pipAEAz1mttmfFipXAMsQw3BD5fbVwuJbUGl868UJMXdNEa0eIdocLU
+ JwH8souSfI8eV7DYcr2lPqDgUNlPtzKSqawIMXQ+3rn418PLEMMgxE+hNirCxkDQK82SrgqBqY5
+ K1eZUanK+94ahrpaUfGCyCCDm0VMpDBImb4SaHKgD/FWFVVmMGFl6Tl3Qgpok0eXXwS5HbAMMQx
+ GMSSIsZekXNp7v8zKymzo0T26WpHO42MjNxsmGHWx6a6/rz/0uWDBi+coFJRdnDHLiI4rTqxQCm
+ oHLEMMgxFR1mJgMOQ1YHO7S14b1zQhQ5iHsLXoiM6g9SbTICDPdIRbiLw5kyqpNK72djNgGWIYj
+ GVIPB5e+cBrauvSdh5tGWKbEHMJFrn6HxDf0bNOfE+Na7cEWaFPT+m+oNMjip9J/pE90Xrz9Gph
+ GWIYjGUIW/zZyMysOcrGuTjXVAwXjbgST0WjKbZ70nXkC77VFy9r/jEXZteC077W0NXCMsQwGJu
+ HNGJsp+QlfZqXsHWHKi4n1xS0YZvToWc+lPLr+U+k2BSqgV31MnNjvgfLEMNgjGWsFFytiM3WcZ
+ WBOUWgoj6kqv/Ii00RXBm7GljViBFXwaD/d2IZYhiMjbKWgreUhlb3OAFz4CHZz6aGWHd4hTnHF
+ cWWjeBAeJKpKbAMMQy3HEO45Mfecfl3qNSyuB5iRtt/XP43hK5w3nK+4rcBNa7FZQIsQwyDMdFF
+ qxh9UZb+6HtIlr1wF8SHFM6JPsVGueDiMzej8W21sAwxDPYHMQy3nFNfCmltrKuWRDrhv0HlUMW
+ V8Rrn1JsGyxDDYLS1XA927ZZWooL+MzC29sycuHmNCq3AMsQwfGt8CFHISwEqskbDWwPlkeVgGW
+ JxczH20lidTXe3AixDLCwsLCwsviX4P68/8cprSSqmAAAAAElFTkSuQmCC
+ROLE:Developer
+SOUND;ENCODING=b:UklGRiQgAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAgAA
+ B/f39/f39/f39/f39/f4B/gH+Af4CAgIGBgYGBgYGBgYGBgYGBgYGBgIGAgICBgYGBgYGBgYCAg
+ YGAgICAgICAgIGBgICAgYCAgICBgICAgICAgICAgIGAgICAgYCAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAf4CAgICAgICAgICAgICAgIB/f4CAgICAgICAgIB/f4B/f39/f39/f3+AgICAf4CAf3
+ 9/gIB/f4CAgH9/gICAgH+AgICAgICAgICAf4CAgIB/gICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgIB/gICAf39/f39/f3+Af4CAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgH9/f39/f39/f39/f39/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgIGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYCAgICB
+ gICAgYGBgICAgICAgICAgIGAgICBgICBgYGBgYGBgYGAgYGBgYCBgYGBgYGBgYGBgYGBgYGBgYG
+ BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgICAgYGBgIGBgYGAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYGAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgH+AgICAgICAgICAgICAgICAgICAf4CAgIB/gH+Af4B/f39/f39/f
+ 39/f39/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgYG
+ BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgY
+ GBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGAgIGBgYCAgICBgYCAgYGBgYCAgICBg
+ YCAgICAgICAgICAgICAgIGAgICAgICAgICAgICAgYGBgYGAgICAgIGBgYCAgICBgYGAgICAgIGA
+ gICAgICAgIGBgYCBgYGAgYGBgYGBgoGBgYGCgoGAgICBgYGBgYCBgYKCgYGBgYGBgYGAgYGBgH9
+ /gIB/f3+AgIB/gH9/gICAf4CBgYB/f35+gIB/f4CBgX9/gYCAgYKCgYCAgYOBgICAgoGAf4GCgn
+ 9/gIB/gICBgH5/f4GAfX+BgYB+fn9/fn+Afn6Af39+f35+fn9+fn6AgH9/f4CAgYCAgYKCgH9/g
+ IKBf3+AgYJ/f4GCg4F/gIGCgoOBfoCDgYF/fH+BgYGAfn6Af4CCgn58gIN/fX+AgICBgYGAgYCB
+ goOCgICBgYB/fXyBhIGAgH5+f4GBgX9/f35+gIKCgXt9goN/f318f4GAf4B/fHt9fn5+fXx+fn5
+ /gH9+fHx/gHx9f4CAfn18gIB9e4GBfn5+foCBfHyAgoGAfX6CgYCBgH+DgHt9gYN/fX2BhYB7en
+ 6AgH98foKCgH18foCAfoCAf4CAf31+fn+AgH1+goJ/fX5/gIKAgIGAfH6CgX17foCBf3+BgoB/g
+ YOBgIB/f4KDgoJ+e3+ChIOBfn1/gX+BfX2BgH59foCCfn1/gX99fICAgoB/f39/gISCf36AgoSB
+ foCBgYGAf4CCf4CCgX5/gYKDgYB/gH+BhIOBgYB/gIOEhIF9foGCg4OBgICBgoOCgICChIOBg4O
+ CgoSDgoKAgYKBgoODhISBf4CCg4SEgoGCg4SEgH6BhIWEgX+EhYKAgoKFhIB+gIKChYKAgYOCgo
+ B+gYWFhIKAg4WEg4ODhIWFhYaGhIWGhYWGh4eHhYOCgoSFg4B/gIB+fX1+fn57e3t7fHt6fH5/f
+ 4GDhYiMkJGQj5GVmZycmZiXlZGIfXRwcnZ4d3Nva2hoamppaWxvc3R0dXl+iJCPjZShqrCzvNHi
+ rFYxOmKSrJ6UmJOAbV1ZboSMjI6JfnNjW2JweYGFg4B/e3Z0c3Btc3p9fHp4fIGBf3+Dh4qLjJG
+ YnZuWkY6MhnpwbnN6fHlya2hlZmdmaW9ycXFzd3t/g42cpquzvMzd/sRADiBZkL6xpLa1jFpANV
+ iHoJ2ioJWGbEQ2VHaOm5aHhIFuYmZzgoVxZFxfdJCSgnt/kKewr7bDsopcSV6JopyRjpOQfmNXZ
+ HmGhYB8fXtvXExKXnyKgnJsc3t8fZC0ysfK0+vHTxEeXY6yr6rAxJRSNTdbh5+fp7KjglQ6PVx3
+ ho6Ph3dmW15oa2x0hIuNkK3R18jJ0Ys8LUlxkqais8WtdlBFT2yDjpywro9mS0VVaXaBiIdyX2J
+ rcG5udYKKjaXT4dfV2Y82JkBpiaKkvdO2eE9GTGZ4hZu6u51yTUNOX2l9kZWKdl5PXG93dHeAip
+ KZut7j2tacRjJIYHCOo77XvoRdVlFYZniVuL+kfl9ST1Rcb4mTjoNxW1pqdXd5fH6CiKHN4d7k2
+ 4E4N05Yaoqo1eO0emVbTU5ZdKDCuZV9b1tMSVlyiYp8dHl7cmpqdYCCgIqixNTR2OqnRTlPXFt3
+ ksbnw4lzcFdKS2KMtLWZiIZwV0lPZXZ1b3uNinZqbXJ3dX2XxOPg4/zDUDRCTUhmiMXx1p+If1g
+ +O1J7pK+yspN3W0pGVGdugYmCen54b21rb3V9i6vZ7vD92WpAS0gzSny04tq3qp5qPDhHX3uVrs
+ KukXVhT0hRYnF/gnuCh31ubG9zdHeMs+Dr8P7KalFVOylJeq7QzMPIqmtIRUZOY4KovqicknhZS
+ 1BWXWh6gIeLiH91b21vc4GcyuXt/umTZGhGIjJfh6y+yt7LkGlfTD1GYYOipKKwnXhkXldVUFhs
+ dYOMjYWBem9ucoCWvNTm9+2weHdZMSpQboujvtnUrY6BZEdDUmV4jZypppeFd2dcWVFWWWh8hYS
+ Ii393c3Z7iJ3A1ePp3aGDfVYyOVZkfJe5zsavpJNsU1BTVmR9kpmcn5uGdGxoWU5VVGZ0fIKLh4
+ F/d3Z6g4ufuc3e3depjoViPz9VWm2FqLu8tLGifmphWlJZbH+Lj5+elod+c19WU0xUZW11gISEg
+ nx6e3h6g4qWp7zM3NrSpZGIYkRFVVVlfZ6vsbW3qIl7b2BUWGVwe4ybn52TkIRuX2BVRVFjZmp7
+ hIF9fX12cnZ6eX6LlZyousfP0c++jot6X0ZRXF9sgaCnqa6yn4eAdGZZYGlvd4mcnqCWnY91aWN
+ cSUtYYmJxf399f351cXFzcHF4foOIlZ+hp7CytLm8uLKNg4RtYF5oanN8j5qZnqGaioV9dGpqb3
+ J1f42Rk5iZjIKAcmFcW1RXYGhwdXt+e3Z2c25tcXJxd3yChY2Tl5udn6Gho6ioq6uonoaHbWNzZ
+ GdxgoGPlZqdj5CJgHFzcWxwdH1/hYqOioSFfnFpaWBdX2Jqb3N5fHh4eHNxcXFxc3d7foOJjI6Q
+ lZOSlZOTl5eYnJucnpyZkYiEfnd1dnZ5fYKHio6QkIyHg394dHRzc3Z5fHt2enJrcG5obG9sbW9
+ ucHJzdnh3eXp5eXt9foCDhoeJjI6OkJGSk5aYmZudn6Gjn5qLh4J3cnJ0dHR5g4GEi42Ih4aBfH
+ h4dXR1eHl4dXhuaW5rZ2ltaWttbW5vcnR1dHZ2dXV2d3d7fn+BhIeIiYuOjpCTlJWZnJueoKarr
+ ZuJhntvaW1ucnh+hIWJi4qFg4F7d3V1c3R3fH1/gHlvbXJnXmdpYmdtamtxcW9vbm9tamxtbG5z
+ dXZ5fHx7fX9+fH6AgoWHioyNj5CRlZeYmp2TiYyGenp9eXh9fX19foB/fH1/e3p8e3l5e3x7e3x
+ 6d3FxcnBwcG9vb29vb29wb25tbWxsbW5vb3Fyc3N1dXV1dnd4ent9fn+BgoGAgoWEhoqJiYyLi4
+ yPioaLiYSEh4WDhIOCgoKAgX58fXx5eXp4eHl4dXZ1cnN0dHR1cnJycXBxcnJycW9ubGxsbW1ub
+ m5ub29vcXNzdHZ2dXh6enp+fn5/gYCBhIKFiYeGiomJi4qKjIuLjIyLiomKh4aKioeIiIWDgYB9
+ fHx7e3l4eHh2dnd3d3l7enp6enp5ent7e3x7enl6e3t7fHx7e3p8fX5/gIKDg4GCg4KCg4OEhoe
+ Hh4iJiomLjIqLi4uLi46Pjo2OjouJiomHh4aDgH9/fXp5eXh3d3h4eHh4d3V2d3Z0dnd0dXd3d3
+ p7fH59fX19fH5+fn+Af4CAf3+Af359f4KDgoSIiIeJjI6PkJOUk5SYmZiYmZqZmJqamJiZmJaWl
+ ZSTkZCQj46Ni4qHh4iFgoKBfn9+fn+AgYCAgYOCgoSEg4SFhIODg4OCgICBf35/gICAgYKCgYGD
+ hIOBgYOCgYGAgIGBgIGCgoKBgoSEg4KCgH9/f318fHt6e3t7enl5eHh5fH18foCAf4GDg4OFhoa
+ GhoeJh4aJioiIiYiIhoWGh4aGh4eHiImHh4mIiIeHh4iIiIqJioqJh4mKh4eJiYiHh4eHhoWGhY
+ OEhYWEhYWDg4SFhYWEg4SDgYKCgH+AgICBgoOCgYGBgYKEhoaGhoiIh4eJiYmKioqKiomKioiJi
+ oqJiYmJiIiIiYiHh4eHh4eGhYWFhISDgoKCgoKCgYGAf31+fXx9fn58e3x8fHx9fX19fX19fX19
+ fHx9fn5/gICBgYGCgoKCg4OCgoODgoKDg4OCgoKCgoGBgYGBgYGCgYCBgIGCgoKDg4KCg4OEhIS
+ FhYWFhYWFhYWFhoWGhoWEhISDg4ODg4ODg4ODg4SDgoKDg4OCg4SDgoKDgoGBgoGAgIB/f35+fn
+ 9+fn9/f35+fn5/gICAgIGBgYKCg4ODg4SEg4OEhIODhIODhIODg4ODg4OCgoKBgoKCg4OCgoODg
+ 4ODg4OEhISEhIWEhIWFhISEhISEhIWEhISEhIODhISEg4ODg4ODg4ODg4ODgoKCgoKCg4KCgoKC
+ goKCgoKCgoOCgoKCgoKBgYKCgoKCgoGBgYGAgICAgYGBgYCAf39/f39/f3+Af39/f39/f39/gIC
+ AgIB/f39/f39/gICAgIB/f39/gIB/f39/gH9/f39/f39/fn5+f39/f39/fn5+fn5/f39/f39/fn
+ 5+fn9/f39/f35+fn5+fn9/f35/f39+fn5+fn9/fn5+fn5+fn5+f39+fn5+fn19fX5+fn5+fn5+f
+ X5+fn5+fn5+fn19fn5+fn5+fX19fX59fn5+fn19fX19fX1+fX19fX19fX19fX19fX19fX19fX19
+ fX19fX19fX19fX19fX19fX19fX19fX19fXx9fX18fH19fXx8fXx9fXx8fHx8fHx8fH19fX19fXx
+ 9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX
+ 19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
+ X19fX19fX19fX19fX19fX19fX19fX19fX1+fX5+fn19fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
+ fn5+fn5+fn5+fn5+f39/fn5/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f3
+ 9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f
+ 39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/
+ f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f39/f39/f39/f39/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3
+ 9/f39/f39/f39/f39/f39/f35+fn5+f35/f39/f39/f39/f39/f39/f39/f39/f39/f39/f35+f
+ 39+fn5/fn5+f39/fn9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/
+ f39/f39/f39/f39/f39+fn9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f4CAf39/f39/f39/gIB/f39/f39/f4B/f4CAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgIB/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgIGBgYGAgYGBgICAgIGAgICBgYGAgYGBgYGBgYGBgYGBgY
+ GBgYGBgYGBgYGBgYGBgYGAgYCAgICAgICAgICAgICAgICAgICAgICAgICAgH+AgICAf39/gH9/f
+ 3+Af39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f4CAgH9/gIB/f39/f4B/f3+AgICAf4CA
+ gICAgICAgICAgICAgH9/f4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgIB/f39/f39/f39/f4CAf39/f39/f39/f39/f39/f39+fn
+ 9/fn5+fn5+fn5+fn5+fX19fX19fX19fX19fX19fX19fn5+fn5+fn9/f39/f4CAgICAgICBgYGBg
+ YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICAgICAgICAgICAgICAgYGAgICA
+ gICAgICAgICAgICBgYGAgICAgICAgICAgICAgICAgICAgICAgIB/gICAgH9/f39/f39/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAgICAf39/f39/gH+AgI
+ CAgICAgIB/f39/f39/f4B/f39/f39/f39/f39/f39/f39/f39/f39/f39/fn9/f39/f39/f39+f
+ 39/f39/f39/f39/f39/f39/f39/f4B/f4CAgICAf39/f39/gICAf39/gICAgICAgICAgICAgICA
+ gICAgIGAgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYCAgICBgYGBgYGBgYCBgYGBgYCAgIG
+ BgICAgICAgICAgICAgICAgICAgICAgICAgICBgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAf3+AgIB/f4CAf39/f39/f3+AgICAgH+AgICAf3+AgICAgICAgH9/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3
+ 9/f39/f39/gH9/gICAgICAgICAgIB/gICAgH+AgIB/f39/f39/gICAgICAgH9/f3+AgH9/f4B/f
+ 39/f39/f39/f39/f3+AgICAgICAf3+AgIB/f4CAgIB/f4CAgICAgICAgICAf39/f3+AgIB/f4CA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAf39/f39
+ /f4CAgH9/f39/f39/f39/f39/f39/f39/f39/f39/f4B/f39/f39/gIB/f39/f39/f39/gH9/f3
+ 9/f4CAgICAgIB/gICAgICAgICAgICAgICAgICAgICAgICAgH+AgICAf4CAgICAgICAgIB/gICAf
+ 4CAgICAgH+Af4CAgH9/f39/f39/f39/gICAgICAgICAgICAf39/f39/f4CAgH9/gICAf3+AgICA
+ gICAgICAgICAgICAgICAgICAgIB/f39/gIB/f4CAgIB/f4CAgH9/gICAf39/f39/f39/f39/f39
+ /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3
+ 9/f39/f39/f39/f39/f39/f39/f39/f39/f39/gICAf39/gH9/f3+AgH9/f39/f39/f39/f39/f
+ 39/f39/f39/f39/f39/f39/f39/gICAf3+AgH9/f3+AgH9/f4CAgH9/gICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAgICAgICBgYGBgIGBgYCAgYGAgICAgYCAgICAgICAgICAgICAgICAg
+ ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+ gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+ AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+ CAgICAgICAgICAgICAgICAf39/f39/f4CAgIB/f4CAgICAgICAgICAgICAgICAgICAgICAgICAg
+ ICAf39/f3+Af39/f39/f39/f4B/f39/f4CAgICAgICAgICAgA==
+TEL;TYPE=HOME:0351 223344
+TEL;TYPE=WORK:0351 443322
+TEL;TYPE=CELL:0173 223344
+UID:P9HXg34Oav
+URL:http://www.mustermann.de/~heiko/
+VERSION:3.0
+X-KADDRESSBOOK-X-Anniversary:1982-07-07
+X-KADDRESSBOOK-X-AssistantsName:Mr. Smithers
+X-KADDRESSBOOK-X-Department:Edutainment
+X-KADDRESSBOOK-X-IMAddress:122334455
+X-KADDRESSBOOK-X-ManagersName:Mr. Burnes
+X-KADDRESSBOOK-X-Office:223 2nd stage
+X-KADDRESSBOOK-X-Profession:Clown
+X-KADDRESSBOOK-X-SpousesName:femal clown
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard6.vcf b/kabc/vcardparser/tests/vcard6.vcf new file mode 100644 index 000000000..92339c798 --- /dev/null +++ b/kabc/vcardparser/tests/vcard6.vcf @@ -0,0 +1,10 @@ +BEGIN:VCARD +CLASS:PUBLIC +EMAIL;TYPE=PREF:email1@abc.de +EMAIL:email2@abc.de +FN:Test User +N:User;Test;;; +UID:uJTkVqH5Qt +VERSION:3.0 +END:VCARD + diff --git a/kabc/vcardparser/tests/vcard6.vcf.ref b/kabc/vcardparser/tests/vcard6.vcf.ref new file mode 100644 index 000000000..3cfde20b9 --- /dev/null +++ b/kabc/vcardparser/tests/vcard6.vcf.ref @@ -0,0 +1,10 @@ +BEGIN:VCARD
+CLASS:PUBLIC
+EMAIL;TYPE=PREF:email1@abc.de
+EMAIL:email2@abc.de
+FN:Test User
+N:User;Test;;;
+UID:uJTkVqH5Qt
+VERSION:3.0
+END:VCARD
+
diff --git a/kabc/vcardparser/tests/vcard7.vcf b/kabc/vcardparser/tests/vcard7.vcf new file mode 100644 index 000000000..8b5be8ec7 --- /dev/null +++ b/kabc/vcardparser/tests/vcard7.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +N: +LABEL;QUOTED-PRINTABLE;WORK:401 Park Drive 3 West=0ABoston, MA 02215=0AUSA=0A= +Herecomesyetanotherline +UID:pas-id-3E136F9B00000000 +END:VCARD + diff --git a/kabc/vcardparser/tests/vcard7.vcf.ref b/kabc/vcardparser/tests/vcard7.vcf.ref new file mode 100644 index 000000000..84ed6236b --- /dev/null +++ b/kabc/vcardparser/tests/vcard7.vcf.ref @@ -0,0 +1,8 @@ +BEGIN:VCARD
+LABEL;TYPE=work:401 Park Drive 3 West\nBoston\, MA 02215\nUSA\nHerecomesye
+ tanotherline
+N:;;;;
+UID:pas-id-3E136F9B00000000
+VERSION:3.0
+END:VCARD
+
diff --git a/kabc/vcardparser/testutils.cpp b/kabc/vcardparser/testutils.cpp new file mode 100644 index 000000000..086dd297e --- /dev/null +++ b/kabc/vcardparser/testutils.cpp @@ -0,0 +1,99 @@ +#include <vcardparser.h> +#include <kabc/addressee.h> +#include <qfile.h> + +using namespace KABC; + +Addressee +vcard1() +{ + Addressee addr; + + addr.setName( "Frank Dawson" ); + addr.setOrganization( "Lotus Development Corporation" ); + addr.setUrl( KURL( "http://home.earthlink.net/~fdawson") ); + addr.insertEmail( "fdawson@earthlink.net" ); + addr.insertEmail( "Frank_Dawson@Lotus.com", true ); + addr.insertPhoneNumber( PhoneNumber("+1-919-676-9515",PhoneNumber::Voice|PhoneNumber::Msg + |PhoneNumber::Work ) ); + addr.insertPhoneNumber( PhoneNumber("+1-919-676-9564",PhoneNumber::Fax |PhoneNumber::Work )); + Address a( Address::Work | Address::Postal | Address::Parcel ); + a.setStreet( "6544 Battleford Drive" ); + a.setLocality( "Raleigh" ); + a.setRegion( "NC" ); + a.setPostalCode( "27613-3502" ); + a.setCountry( "U.S.A." ); + addr.insertAddress( a ); + return addr; +} + +Addressee +vcard2() +{ + Addressee addr; + + addr.setName( "Tim Howes" ); + addr.setOrganization( "Netscape Communications Corp." ); + addr.insertEmail( "howes@netscape.com" ); + addr.insertPhoneNumber( PhoneNumber("+1-415-937-3419",PhoneNumber::Voice|PhoneNumber::Msg + |PhoneNumber::Work) ); + addr.insertPhoneNumber( PhoneNumber("+1-415-528-4164",PhoneNumber::Fax |PhoneNumber::Work) ); + Address a( Address::Work ); + a.setStreet( "501 E. Middlefield Rd." ); + a.setLocality( "Mountain View" ); + a.setRegion( "CA" ); + a.setPostalCode( "94043" ); + a.setCountry( "U.S.A." ); + addr.insertAddress( a ); + return addr; +} + +Addressee +vcard3() +{ + Addressee addr; + + addr.setName( "ian geiser" ); + addr.setOrganization( "Source eXtreme" ); + addr.insertEmail( "geiseri@yahoo.com" ); + addr.setTitle( "VP of Engineering" ); + return addr; +} + + +QString +vcardAsText( const QString& location ) +{ + QString line; + QFile file( location ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream stream( &file ); + if ( !stream.eof() ) { + line = stream.read(); + } + file.close(); + } + return line; +} + +Addressee::List +vCardsAsAddresseeList() +{ + Addressee::List l; + + l.append( vcard1() ); + l.append( vcard2() ); + l.append( vcard3() ); + + return l; +} + +QString +vCardsAsText() +{ + QString vcards = vcardAsText( "tests/vcard1.vcf" ); + vcards += vcardAsText( "tests/vcard2.vcf" ); + vcards += vcardAsText( "tests/vcard3.vcf" ); + + return vcards; +} diff --git a/kabc/vcardparser/testutils.h b/kabc/vcardparser/testutils.h new file mode 100644 index 000000000..369912ac0 --- /dev/null +++ b/kabc/vcardparser/testutils.h @@ -0,0 +1,14 @@ +#ifndef TESTUTILS_H +#define TESTUTILS_H + +#include <kabc/addressee.h> +#include <qstring.h> + +KABC::Addressee vcard1(); +KABC::Addressee vcard2(); +KABC::Addressee vcard3(); +KABC::Addressee::List vCardsAsAddresseeList(); +QString vCardAsText( const QString& location ); +QString vCardsAsText(); + +#endif diff --git a/kabc/vcardparser/testwrite.cpp b/kabc/vcardparser/testwrite.cpp new file mode 100644 index 000000000..7d2f77c83 --- /dev/null +++ b/kabc/vcardparser/testwrite.cpp @@ -0,0 +1,134 @@ +/* + This file is part of libkabc. + + 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/addressee.h> +#include <kabc/phonenumber.h> +#include <kabc/address.h> +#include <kabc/key.h> +#include <kabc/picture.h> +#include <kabc/sound.h> +#include <kabc/secrecy.h> +#include <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> + +#include <qfile.h> +#include <qtextstream.h> + +#include "vcardconverter.h" + +int main( int argc, char **argv ) +{ + KAboutData aboutData( "testwrite", "vCard test writer", "0.1" ); + + KCmdLineArgs::init( argc, argv, &aboutData ); + + KApplication app( false, false ); + + + KABC::Addressee addressee; + + addressee.setNameFromString( "Mr. Tobias Koenig Jr." ); + addressee.setNickName( "tokoe" ); + addressee.setBirthday( QDate( 1982, 7, 19 ) ); + addressee.setMailer( "mutt1.2" ); + addressee.setTimeZone( KABC::TimeZone( +2 ) ); + + KABC::Geo geo; + geo.setLatitude( 30 ); + geo.setLongitude( 51 ); + addressee.setGeo( geo ); + + addressee.setTitle( "nerd" ); + addressee.setRole( "Maintainer" ); + addressee.setOrganization( "KDE" ); + addressee.setNote( "nerver\ntouch a running system" ); + addressee.setProductId( "testId" ); + addressee.setRevision( QDateTime::currentDateTime() ); + addressee.setSortString( "koenig" ); + addressee.setUrl( KURL( "http://wgess16.dyndns.org") ); + addressee.setSecrecy( KABC::Secrecy( KABC::Secrecy::Confidential ) ); +/* + QImage img; + img.load( "testimg.png", "PNG" ); + KABC::Picture photo; + photo.setData( img ); + addressee.setPhoto( photo ); + + QImage img2; + img2.load( "testimg.png", "PNG" ); + KABC::Picture logo; + logo.setData( img2 ); + addressee.setLogo( logo ); + + QFile soundFile( "testsound.wav" ); + soundFile.open( IO_ReadOnly ); + QByteArray data = soundFile.readAll(); + soundFile.close(); + KABC::Sound sound; + sound.setData( data ); + addressee.setSound( sound ); +*/ + addressee.insertEmail( "tokoe@kde.org", true ); + addressee.insertEmail( "tokoe82@yahoo.de", true ); + + KABC::PhoneNumber phone1( "3541523475", KABC::PhoneNumber::Pref | KABC::PhoneNumber::Home ); + KABC::PhoneNumber phone2( "+46745673475", KABC::PhoneNumber::Work ); + addressee.insertPhoneNumber( phone1 ); + addressee.insertPhoneNumber( phone2 ); + + KABC::Key key( "secret key", KABC::Key::X509 ); + addressee.insertKey( key ); + + QStringList categories; + categories << "Friends" << "School" << "KDE"; + addressee.setCategories( categories ); + + KABC::Address a( KABC::Address::Work | KABC::Address::Postal | KABC::Address::Parcel ); + a.setStreet( "6544 Battleford Drive" ); + a.setLocality( "Raleigh" ); + a.setRegion( "NC" ); + a.setPostalCode( "27613-3502" ); + a.setCountry( "U.S.A." ); + addressee.insertAddress( a ); + + addressee.insertCustom( "1hsdf", "ertuer", "iurt" ); + addressee.insertCustom( "2hsdf", "ertuer", "iurt" ); + addressee.insertCustom( "3hsdf", "ertuer", "iurt" ); + + KABC::Addressee::List list; + for ( int i = 0; i < 1000; ++i ) { + KABC::Addressee addr = addressee; + addr.setUid( QString::number( i ) ); + list.append( addr ); + } + + KABC::VCardConverter converter; + QString txt = converter.createVCards( list ); + + QFile file( "out.vcf" ); + file.open( IO_WriteOnly ); + + QTextStream s( &file ); + s.setEncoding( QTextStream::UnicodeUTF8 ); + s << txt; + file.close(); + + return 0; +} diff --git a/kabc/vcardparser/vcard.cpp b/kabc/vcardparser/vcard.cpp new file mode 100644 index 000000000..410a958d1 --- /dev/null +++ b/kabc/vcardparser/vcard.cpp @@ -0,0 +1,109 @@ +/* + This file is part of libkabc. + Copyright (c) 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 "vcard.h" + +using namespace KABC; + +VCard::VCard() +{ +} + +VCard::VCard( const VCard& vcard ) +{ + mLineMap = vcard.mLineMap; +} + +VCard::~VCard() +{ +} + +VCard& VCard::operator=( const VCard& vcard ) +{ + if ( &vcard == this ) + return *this; + + mLineMap = vcard.mLineMap; + + return *this; +} + +void VCard::clear() +{ + mLineMap.clear(); +} + +QStringList VCard::identifiers() const +{ + return mLineMap.keys(); +} + +void VCard::addLine( const VCardLine& line ) +{ + mLineMap[ line.identifier() ].append( line ); +} + +VCardLine::List VCard::lines( const QString& identifier ) const +{ + LineMap::ConstIterator it = mLineMap.find( identifier ); + if ( it == mLineMap.end() ) + return VCardLine::List(); + + return *it; +} + +VCardLine VCard::line( const QString& identifier ) const +{ + LineMap::ConstIterator it = mLineMap.find( identifier ); + if ( it == mLineMap.end() ) + return VCardLine(); + + if ( (*it).isEmpty() ) + return VCardLine(); + else + return (*it).first(); +} + +void VCard::setVersion( Version version ) +{ + mLineMap.erase( "VERSION" ); + + VCardLine line; + line.setIdentifier( "VERSION" ); + if ( version == v2_1 ) + line.setIdentifier( "2.1" ); + else if ( version == v3_0 ) + line.setIdentifier( "3.0" ); + + mLineMap[ "VERSION" ].append( line ); +} + +VCard::Version VCard::version() const +{ + LineMap::ConstIterator versionEntry = mLineMap.find( "VERSION" ); + if ( versionEntry == mLineMap.end() ) + return v3_0; + + VCardLine line = ( *versionEntry )[ 0 ]; + if ( line.value() == "2.1" ) + return v2_1; + else + return v3_0; +} diff --git a/kabc/vcardparser/vcard.h b/kabc/vcardparser/vcard.h new file mode 100644 index 000000000..73fcd1ea2 --- /dev/null +++ b/kabc/vcardparser/vcard.h @@ -0,0 +1,91 @@ +/* + This file is part of libkabc. + Copyright (c) 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 VCARDPARSER_VCARD_H +#define VCARDPARSER_VCARD_H + +#include "vcardline.h" +#include <qmap.h> +#include <qstringlist.h> +#include <qvaluelist.h> + +namespace KABC { + +class VCard +{ + public: + typedef QValueList<VCard> List; + typedef QMap< QString, VCardLine::List > LineMap; + + enum Version { v2_1, v3_0 }; + + VCard(); + VCard( const VCard& ); + + ~VCard(); + + VCard& operator=( const VCard& ); + + /** + * Removes all lines from the vCard. + */ + void clear(); + + /** + * Returns a list of all identifiers that exists in the + * vCard. + */ + QStringList identifiers() const; + + /** + * Adds a VCardLine to the VCard + */ + void addLine( const VCardLine& line ); + + /** + * Returns all lines of the vcard with a special identifier. + */ + VCardLine::List lines( const QString& identifier ) const; + + /** + * Returns only the first line of the vcard with a special identifier. + */ + VCardLine line( const QString& identifier ) const; + + /** + * Set the version of the vCard. + */ + void setVersion( Version version ); + + /** + * Returns the version of this vCard. + */ + Version version() const; + + private: + LineMap mLineMap; + + class VCardPrivate; + VCardPrivate *d; +}; + +} + +#endif diff --git a/kabc/vcardparser/vcardline.cpp b/kabc/vcardparser/vcardline.cpp new file mode 100644 index 000000000..247604ebb --- /dev/null +++ b/kabc/vcardparser/vcardline.cpp @@ -0,0 +1,151 @@ +/* + This file is part of libkabc. + Copyright (c) 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 "vcardline.h" + +using namespace KABC; + +class VCardLine::VCardLinePrivate +{ + public: + QString mGroup; +}; + +VCardLine::VCardLine() + : d( 0 ) +{ +} + +VCardLine::VCardLine( const QString &identifier ) + : d( 0 ) +{ + mIdentifier = identifier; +} + +VCardLine::VCardLine( const QString &identifier, const QVariant &value ) + : d( 0 ) +{ + mIdentifier = identifier; + mValue = value; +} + +VCardLine::VCardLine( const VCardLine& line ) + : d( 0 ) +{ + mParamMap = line.mParamMap; + mValue = line.mValue; + mIdentifier = line.mIdentifier; +} + +VCardLine::~VCardLine() +{ + delete d; + d = 0; +} + +VCardLine& VCardLine::operator=( const VCardLine& line ) +{ + if ( &line == this ) + return *this; + + mParamMap = line.mParamMap; + mValue = line.mValue; + mIdentifier = line.mIdentifier; + + return *this; +} + +void VCardLine::setIdentifier( const QString& identifier ) +{ + mIdentifier = identifier; +} + +QString VCardLine::identifier() const +{ + return mIdentifier; +} + +void VCardLine::setValue( const QVariant& value ) +{ + mValue = value; +} + +QVariant VCardLine::value() const +{ + return mValue; +} + +void VCardLine::setGroup( const QString& group ) +{ + if ( !d ) + d = new VCardLinePrivate(); + + d->mGroup = group; +} + +QString VCardLine::group() const +{ + if ( d ) + return d->mGroup; + else + return QString(); +} + +bool VCardLine::hasGroup() const +{ + if ( !d ) + return false; + else + return d->mGroup.isEmpty(); +} + +QStringList VCardLine::parameterList() const +{ + return mParamMap.keys(); +} + +void VCardLine::addParameter( const QString& param, const QString& value ) +{ + QStringList &list = mParamMap[ param ]; + if ( list.findIndex( value ) == -1 ) // not included yet + list.append( value ); +} + +QStringList VCardLine::parameters( const QString& param ) const +{ + ParamMap::ConstIterator it = mParamMap.find( param ); + if ( it == mParamMap.end() ) + return QStringList(); + else + return *it; +} + +QString VCardLine::parameter( const QString& param ) const +{ + ParamMap::ConstIterator it = mParamMap.find( param ); + if ( it == mParamMap.end() ) + return QString::null; + else { + if ( (*it).isEmpty() ) + return QString::null; + else + return (*it).first(); + } +} diff --git a/kabc/vcardparser/vcardline.h b/kabc/vcardparser/vcardline.h new file mode 100644 index 000000000..d6ad9dd77 --- /dev/null +++ b/kabc/vcardparser/vcardline.h @@ -0,0 +1,115 @@ +/* + This file is part of libkabc. + Copyright (c) 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 VCARDLINE_H +#define VCARDLINE_H + +#include <qstringlist.h> +#include <qvaluelist.h> +#include <qvariant.h> +#include <qmap.h> +#include <qstring.h> + +namespace KABC { + +class VCardLine +{ + public: + typedef QValueList<VCardLine> List; + typedef QMap<QString, QStringList> ParamMap; + + VCardLine(); + VCardLine( const QString &identifier ); + VCardLine( const QString &identifier, const QVariant &value ); + VCardLine( const VCardLine& ); + + ~VCardLine(); + + VCardLine& operator=( const VCardLine& ); + + /** + * Sets the identifier of this line e.g. UID, FN, CLASS + */ + void setIdentifier( const QString& identifier ); + + /** + * Returns the identifier of this line. + */ + QString identifier() const; + + /** + * Sets the value of of this line. + */ + void setValue( const QVariant& value ); + + /** + * Returns the value of this line. + */ + QVariant value() const; + + /** + * Sets the group the line belongs to. + */ + void setGroup( const QString& group ); + + /** + * Returns the group the line belongs to. + */ + QString group() const; + + /** + * Returns whether the line belongs to a group. + */ + bool hasGroup() const; + + /** + * Returns all parameters. + */ + QStringList parameterList() const; + + /** + * Add a new parameter to the line. + */ + void addParameter( const QString& param, const QString& value ); + + /** + * Returns the values of a special parameter. + * You can get a list of all parameters with paramList(). + */ + QStringList parameters( const QString& param ) const; + + /** + * Returns only the first value of a special parameter. + * You can get a list of all parameters with paramList(). + */ + QString parameter( const QString& param ) const; + + private: + ParamMap mParamMap; + QString mIdentifier; + QVariant mValue; + + class VCardLinePrivate; + VCardLinePrivate *d; +}; + +} + +#endif diff --git a/kabc/vcardparser/vcardparser.cpp b/kabc/vcardparser/vcardparser.cpp new file mode 100644 index 000000000..34c13c68a --- /dev/null +++ b/kabc/vcardparser/vcardparser.cpp @@ -0,0 +1,287 @@ +/* + This file is part of libkabc. + Copyright (c) 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 <qregexp.h> +#include <qtextcodec.h> + +#include <kmdcodec.h> + +#include "vcardparser.h" + +#define FOLD_WIDTH 75 + +using namespace KABC; + +static QString backslash( "\\\\" ); +static QString comma( "\\," ); +static QString newline( "\\n" ); +static QString cr( "\\r" ); + +static void addEscapes( QString &str ) +{ + str.replace( '\\', backslash ); + str.replace( ',', comma ); + str.replace( '\r', cr ); + str.replace( '\n', newline ); +} + +static void removeEscapes( QString &str ) +{ + str.replace( cr, "\\r" ); + str.replace( newline, "\n" ); + str.replace( comma, "," ); + str.replace( backslash, "\\" ); +} + +VCardParser::VCardParser() +{ +} + +VCardParser::~VCardParser() +{ +} + +VCard::List VCardParser::parseVCards( const QString& text ) +{ + static QRegExp sep( "[\x0d\x0a]" ); + + VCard currentVCard; + VCard::List vCardList; + QString currentLine; + + const QStringList lines = QStringList::split( sep, text ); + QStringList::ConstIterator it; + + bool inVCard = false; + QStringList::ConstIterator linesEnd( lines.end() ); + for ( it = lines.begin(); it != linesEnd; ++it ) { + + if ( (*it).isEmpty() ) // empty line + continue; + + if ( (*it)[ 0 ] == ' ' || (*it)[ 0 ] == '\t' ) { // folded line => append to previous + currentLine += QString( *it ).remove( 0, 1 ); + continue; + } else { + if ( inVCard && !currentLine.isEmpty() ) { // now parse the line + int colon = currentLine.find( ':' ); + if ( colon == -1 ) { // invalid line + currentLine = (*it); + continue; + } + + VCardLine vCardLine; + const QString key = currentLine.left( colon ).stripWhiteSpace(); + QString value = currentLine.mid( colon + 1 ); + + QStringList params = QStringList::split( ';', key ); + + // check for group + if ( params[0].find( '.' ) != -1 ) { + const QStringList groupList = QStringList::split( '.', params[0] ); + vCardLine.setGroup( groupList[0] ); + vCardLine.setIdentifier( groupList[1] ); + } else + vCardLine.setIdentifier( params[0] ); + + if ( params.count() > 1 ) { // find all parameters + QStringList::ConstIterator paramIt = params.begin(); + for ( ++paramIt; paramIt != params.end(); ++paramIt ) { + QStringList pair = QStringList::split( '=', *paramIt ); + if ( pair.size() == 1 ) { + // correct the fucking 2.1 'standard' + if ( pair[0].lower() == "quoted-printable" ) { + pair[0] = "encoding"; + pair[1] = "quoted-printable"; + } else if ( pair[0].lower() == "base64" ) { + pair[0] = "encoding"; + pair[1] = "base64"; + } else { + pair.prepend( "type" ); + } + } + // This is pretty much a faster pair[1].contains( ',' )... + if ( pair[1].find( ',' ) != -1 ) { // parameter in type=x,y,z format + const QStringList args = QStringList::split( ',', pair[ 1 ] ); + QStringList::ConstIterator argIt; + for ( argIt = args.begin(); argIt != args.end(); ++argIt ) + vCardLine.addParameter( pair[0].lower(), *argIt ); + } else + vCardLine.addParameter( pair[0].lower(), pair[1] ); + } + } + + removeEscapes( value ); + + QByteArray output; + bool wasBase64Encoded = false; + + params = vCardLine.parameterList(); + if ( params.findIndex( "encoding" ) != -1 ) { // have to decode the data + QByteArray input; + input = QCString(value.latin1()); + if ( vCardLine.parameter( "encoding" ).lower() == "b" || + vCardLine.parameter( "encoding" ).lower() == "base64" ) { + KCodecs::base64Decode( input, output ); + wasBase64Encoded = true; + } + else if ( vCardLine.parameter( "encoding" ).lower() == "quoted-printable" ) { + // join any qp-folded lines + while ( value.at( value.length() - 1 ) == '=' && it != linesEnd ) { + value = value.remove( value.length() - 1, 1 ) + (*it); + ++it; + } + input = QCString(value.latin1()); + KCodecs::quotedPrintableDecode( input, output ); + } + } else { + output = QCString(value.latin1()); + } + + if ( params.findIndex( "charset" ) != -1 ) { // have to convert the data + QTextCodec *codec = + QTextCodec::codecForName( vCardLine.parameter( "charset" ).latin1() ); + if ( codec ) { + vCardLine.setValue( codec->toUnicode( output ) ); + } else { + vCardLine.setValue( QString::fromUtf8( output ) ); + } + } else if ( wasBase64Encoded ) { + vCardLine.setValue( output ); + } else { // if charset not given, assume it's in UTF-8 (as used in previous KDE versions) + vCardLine.setValue( QString::fromUtf8( output ) ); + } + + currentVCard.addLine( vCardLine ); + } + + // we do not save the start and end tag as vcardline + if ( (*it).lower().startsWith( "begin:vcard" ) ) { + inVCard = true; + currentLine.setLength( 0 ); + currentVCard.clear(); // flush vcard + continue; + } + + if ( (*it).lower().startsWith( "end:vcard" ) ) { + inVCard = false; + vCardList.append( currentVCard ); + currentLine.setLength( 0 ); + currentVCard.clear(); // flush vcard + continue; + } + + currentLine = (*it); + } + } + + return vCardList; +} + +QString VCardParser::createVCards( const VCard::List& list ) +{ + QString text; + QString textLine; + QString encodingType; + QStringList idents; + QStringList params; + QStringList values; + QStringList::ConstIterator identIt; + QStringList::Iterator paramIt; + QStringList::ConstIterator valueIt; + + VCardLine::List lines; + VCardLine::List::ConstIterator lineIt; + VCard::List::ConstIterator cardIt; + + bool hasEncoding; + + text.reserve( list.size() * 300 ); // reserve memory to be more efficient + + // iterate over the cards + VCard::List::ConstIterator listEnd( list.end() ); + for ( cardIt = list.begin(); cardIt != listEnd; ++cardIt ) { + text.append( "BEGIN:VCARD\r\n" ); + + idents = (*cardIt).identifiers(); + for ( identIt = idents.constBegin(); identIt != idents.constEnd(); ++identIt ) { + lines = (*cardIt).lines( (*identIt) ); + + // iterate over the lines + for ( lineIt = lines.constBegin(); lineIt != lines.constEnd(); ++lineIt ) { + if ( !(*lineIt).value().asString().isEmpty() ) { + if ( (*lineIt).hasGroup() ) + textLine = (*lineIt).group() + "." + (*lineIt).identifier(); + else + textLine = (*lineIt).identifier(); + + params = (*lineIt).parameterList(); + hasEncoding = false; + if ( params.count() > 0 ) { // we have parameters + for ( paramIt = params.begin(); paramIt != params.end(); ++paramIt ) { + if ( (*paramIt) == "encoding" ) { + hasEncoding = true; + encodingType = (*lineIt).parameter( "encoding" ).lower(); + } + + values = (*lineIt).parameters( *paramIt ); + for ( valueIt = values.constBegin(); valueIt != values.constEnd(); ++valueIt ) { + textLine.append( ";" + (*paramIt).upper() ); + if ( !(*valueIt).isEmpty() ) + textLine.append( "=" + (*valueIt) ); + } + } + } + + if ( hasEncoding ) { // have to encode the data + QByteArray input, output; + if ( encodingType == "b" ) { + input = (*lineIt).value().toByteArray(); + KCodecs::base64Encode( input, output ); + } else if ( encodingType == "quoted-printable" ) { + input = (*lineIt).value().toString().utf8(); + input.resize( input.size() - 1 ); // strip \0 + KCodecs::quotedPrintableEncode( input, output, false ); + } + + QString value( output ); + addEscapes( value ); + textLine.append( ":" + value ); + } else { + QString value( (*lineIt).value().asString() ); + addEscapes( value ); + textLine.append( ":" + value ); + } + + if ( textLine.length() > FOLD_WIDTH ) { // we have to fold the line + for ( uint i = 0; i <= ( textLine.length() / FOLD_WIDTH ); ++i ) + text.append( ( i == 0 ? "" : " " ) + textLine.mid( i * FOLD_WIDTH, FOLD_WIDTH ) + "\r\n" ); + } else + text.append( textLine + "\r\n" ); + } + } + } + + text.append( "END:VCARD\r\n" ); + text.append( "\r\n" ); + } + + return text; +} diff --git a/kabc/vcardparser/vcardparser.h b/kabc/vcardparser/vcardparser.h new file mode 100644 index 000000000..31e13424c --- /dev/null +++ b/kabc/vcardparser/vcardparser.h @@ -0,0 +1,44 @@ +/* + This file is part of libkabc. + Copyright (c) 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 VCARDPARSER_H +#define VCARDPARSER_H + +#include "vcard.h" + +namespace KABC { + +class VCardParser +{ + public: + VCardParser(); + ~VCardParser(); + + static VCard::List parseVCards( const QString& text ); + static QString createVCards( const VCard::List& list ); + + private: + class VCardParserPrivate; + VCardParserPrivate *d; +}; + +} + +#endif diff --git a/kabc/vcardtool.cpp b/kabc/vcardtool.cpp new file mode 100644 index 000000000..d9fdd03a8 --- /dev/null +++ b/kabc/vcardtool.cpp @@ -0,0 +1,889 @@ +/* + This file is part of libkabc. + Copyright (c) 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 <qbuffer.h> +#include <qdatastream.h> +#include <qstring.h> + +#include "agent.h" +#include "key.h" +#include "picture.h" +#include "secrecy.h" +#include "sound.h" + +#include "vcardtool.h" + +using namespace KABC; + +static bool needsEncoding( const QString &value ) +{ + uint length = value.length(); + for ( uint i = 0; i < length; ++i ) { + char c = value.at( i ).latin1(); + if ( (c < 33 || c > 126) && c != ' ' && c != '=' ) + return true; + } + + return false; +} + +VCardTool::VCardTool() +{ + mAddressTypeMap.insert( "dom", Address::Dom ); + mAddressTypeMap.insert( "intl", Address::Intl ); + mAddressTypeMap.insert( "postal", Address::Postal ); + mAddressTypeMap.insert( "parcel", Address::Parcel ); + mAddressTypeMap.insert( "home", Address::Home ); + mAddressTypeMap.insert( "work", Address::Work ); + mAddressTypeMap.insert( "pref", Address::Pref ); + + mPhoneTypeMap.insert( "HOME", PhoneNumber::Home ); + mPhoneTypeMap.insert( "WORK", PhoneNumber::Work ); + mPhoneTypeMap.insert( "MSG", PhoneNumber::Msg ); + mPhoneTypeMap.insert( "PREF", PhoneNumber::Pref ); + mPhoneTypeMap.insert( "VOICE", PhoneNumber::Voice ); + mPhoneTypeMap.insert( "FAX", PhoneNumber::Fax ); + mPhoneTypeMap.insert( "CELL", PhoneNumber::Cell ); + mPhoneTypeMap.insert( "VIDEO", PhoneNumber::Video ); + mPhoneTypeMap.insert( "BBS", PhoneNumber::Bbs ); + mPhoneTypeMap.insert( "MODEM", PhoneNumber::Modem ); + mPhoneTypeMap.insert( "CAR", PhoneNumber::Car ); + mPhoneTypeMap.insert( "ISDN", PhoneNumber::Isdn ); + mPhoneTypeMap.insert( "PCS", PhoneNumber::Pcs ); + mPhoneTypeMap.insert( "PAGER", PhoneNumber::Pager ); +} + +VCardTool::~VCardTool() +{ +} + +// TODO: make list a const& +QString VCardTool::createVCards( Addressee::List list, VCard::Version version ) +{ + VCard::List vCardList; + + Addressee::List::ConstIterator addrIt; + Addressee::List::ConstIterator listEnd( list.constEnd() ); + for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) { + VCard card; + QStringList::ConstIterator strIt; + + // ADR + LABEL + const Address::List addresses = (*addrIt).addresses(); + for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) { + QStringList address; + + bool isEmpty = ( (*it).postOfficeBox().isEmpty() && + (*it).extended().isEmpty() && + (*it).street().isEmpty() && + (*it).locality().isEmpty() && + (*it).region().isEmpty() && + (*it).postalCode().isEmpty() && + (*it).country().isEmpty() ); + + address.append( (*it).postOfficeBox().replace( ';', "\\;" ) ); + address.append( (*it).extended().replace( ';', "\\;" ) ); + address.append( (*it).street().replace( ';', "\\;" ) ); + address.append( (*it).locality().replace( ';', "\\;" ) ); + address.append( (*it).region().replace( ';', "\\;" ) ); + address.append( (*it).postalCode().replace( ';', "\\;" ) ); + address.append( (*it).country().replace( ';', "\\;" ) ); + + VCardLine adrLine( "ADR", address.join( ";" ) ); + if ( version == VCard::v2_1 && needsEncoding( address.join( ";" ) ) ) { + adrLine.addParameter( "charset", "UTF-8" ); + adrLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + + VCardLine labelLine( "LABEL", (*it).label() ); + if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) { + labelLine.addParameter( "charset", "UTF-8" ); + labelLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + + bool hasLabel = !(*it).label().isEmpty(); + QMap<QString, int>::ConstIterator typeIt; + for ( typeIt = mAddressTypeMap.constBegin(); typeIt != mAddressTypeMap.constEnd(); ++typeIt ) { + if ( typeIt.data() & (*it).type() ) { + adrLine.addParameter( "TYPE", typeIt.key() ); + if ( hasLabel ) + labelLine.addParameter( "TYPE", typeIt.key() ); + } + } + + if ( !isEmpty ) + card.addLine( adrLine ); + if ( hasLabel ) + card.addLine( labelLine ); + } + + // AGENT + card.addLine( createAgent( version, (*addrIt).agent() ) ); + + // BDAY + card.addLine( VCardLine( "BDAY", createDateTime( (*addrIt).birthday() ) ) ); + + // CATEGORIES + if ( version == VCard::v3_0 ) { + QStringList categories = (*addrIt).categories(); + QStringList::Iterator catIt; + for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) + (*catIt).replace( ',', "\\," ); + + VCardLine catLine( "CATEGORIES", categories.join( "," ) ); + if ( version == VCard::v2_1 && needsEncoding( categories.join( "," ) ) ) { + catLine.addParameter( "charset", "UTF-8" ); + catLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + + card.addLine( catLine ); + } + + // CLASS + if ( version == VCard::v3_0 ) { + card.addLine( createSecrecy( (*addrIt).secrecy() ) ); + } + + // EMAIL + const QStringList emails = (*addrIt).emails(); + bool pref = true; + for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) { + VCardLine line( "EMAIL", *strIt ); + if ( pref == true && emails.count() > 1 ) { + line.addParameter( "TYPE", "PREF" ); + pref = false; + } + card.addLine( line ); + } + + // FN + VCardLine fnLine( "FN", (*addrIt).formattedName() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) { + fnLine.addParameter( "charset", "UTF-8" ); + fnLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( fnLine ); + + // GEO + Geo geo = (*addrIt).geo(); + if ( geo.isValid() ) { + QString str; + str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() ); + card.addLine( VCardLine( "GEO", str ) ); + } + + // KEY + const Key::List keys = (*addrIt).keys(); + Key::List::ConstIterator keyIt; + for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt ) + card.addLine( createKey( *keyIt ) ); + + // LOGO + card.addLine( createPicture( "LOGO", (*addrIt).logo() ) ); + + // MAILER + VCardLine mailerLine( "MAILER", (*addrIt).mailer() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) { + mailerLine.addParameter( "charset", "UTF-8" ); + mailerLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( mailerLine ); + + // N + QStringList name; + name.append( (*addrIt).familyName().replace( ';', "\\;" ) ); + name.append( (*addrIt).givenName().replace( ';', "\\;" ) ); + name.append( (*addrIt).additionalName().replace( ';', "\\;" ) ); + name.append( (*addrIt).prefix().replace( ';', "\\;" ) ); + name.append( (*addrIt).suffix().replace( ';', "\\;" ) ); + + VCardLine nLine( "N", name.join( ";" ) ); + if ( version == VCard::v2_1 && needsEncoding( name.join( ";" ) ) ) { + nLine.addParameter( "charset", "UTF-8" ); + nLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( nLine ); + + // NAME + VCardLine nameLine( "NAME", (*addrIt).name() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) { + nameLine.addParameter( "charset", "UTF-8" ); + nameLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( nameLine ); + + // NICKNAME + if ( version == VCard::v3_0 ) + card.addLine( VCardLine( "NICKNAME", (*addrIt).nickName() ) ); + + // NOTE + VCardLine noteLine( "NOTE", (*addrIt).note() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) { + noteLine.addParameter( "charset", "UTF-8" ); + noteLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( noteLine ); + + // ORG + QStringList organization; + organization.append( ( *addrIt ).organization().replace( ';', "\\;" ) ); + if ( !( *addrIt ).department().isEmpty() ) + organization.append( ( *addrIt ).department().replace( ';', "\\;" ) ); + VCardLine orgLine( "ORG", organization.join( ";" ) ); + if ( version == VCard::v2_1 && needsEncoding( organization.join( ";" ) ) ) { + orgLine.addParameter( "charset", "UTF-8" ); + orgLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( orgLine ); + + // PHOTO + card.addLine( createPicture( "PHOTO", (*addrIt).photo() ) ); + + // PROID + if ( version == VCard::v3_0 ) + card.addLine( VCardLine( "PRODID", (*addrIt).productId() ) ); + + // REV + card.addLine( VCardLine( "REV", createDateTime( (*addrIt).revision() ) ) ); + + // ROLE + VCardLine roleLine( "ROLE", (*addrIt).role() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) { + roleLine.addParameter( "charset", "UTF-8" ); + roleLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( roleLine ); + + // SORT-STRING + if ( version == VCard::v3_0 ) + card.addLine( VCardLine( "SORT-STRING", (*addrIt).sortString() ) ); + + // SOUND + card.addLine( createSound( (*addrIt).sound() ) ); + + // TEL + const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers(); + PhoneNumber::List::ConstIterator phoneIt; + for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt ) { + VCardLine line( "TEL", (*phoneIt).number() ); + + QMap<QString, int>::ConstIterator typeIt; + for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) { + if ( typeIt.data() & (*phoneIt).type() ) + line.addParameter( "TYPE", typeIt.key() ); + } + + card.addLine( line ); + } + + // TITLE + VCardLine titleLine( "TITLE", (*addrIt).title() ); + if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) { + titleLine.addParameter( "charset", "UTF-8" ); + titleLine.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( titleLine ); + + // TZ + TimeZone timeZone = (*addrIt).timeZone(); + if ( timeZone.isValid() ) { + QString str; + + int neg = 1; + if ( timeZone.offset() < 0 ) + neg = -1; + + str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ), + ( timeZone.offset() / 60 ) * neg, + ( timeZone.offset() % 60 ) * neg ); + + card.addLine( VCardLine( "TZ", str ) ); + } + + // UID + card.addLine( VCardLine( "UID", (*addrIt).uid() ) ); + + // URL + card.addLine( VCardLine( "URL", (*addrIt).url().url() ) ); + + // VERSION + if ( version == VCard::v2_1 ) + card.addLine( VCardLine( "VERSION", "2.1" ) ); + if ( version == VCard::v3_0 ) + card.addLine( VCardLine( "VERSION", "3.0" ) ); + + // X- + const QStringList customs = (*addrIt).customs(); + for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) { + QString identifier = "X-" + (*strIt).left( (*strIt).find( ":" ) ); + QString value = (*strIt).mid( (*strIt).find( ":" ) + 1 ); + if ( value.isEmpty() ) + continue; + + VCardLine line( identifier, value ); + if ( version == VCard::v2_1 && needsEncoding( value ) ) { + line.addParameter( "charset", "UTF-8" ); + line.addParameter( "encoding", "QUOTED-PRINTABLE" ); + } + card.addLine( line ); + } + + vCardList.append( card ); + } + + return VCardParser::createVCards( vCardList ); +} + +Addressee::List VCardTool::parseVCards( const QString& vcard ) +{ + static const QChar semicolonSep( ';' ); + static const QChar commaSep( ',' ); + QString identifier; + + Addressee::List addrList; + const VCard::List vCardList = VCardParser::parseVCards( vcard ); + + VCard::List::ConstIterator cardIt; + VCard::List::ConstIterator listEnd( vCardList.end() ); + for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) { + Addressee addr; + + const QStringList idents = (*cardIt).identifiers(); + QStringList::ConstIterator identIt; + QStringList::ConstIterator identEnd( idents.end() ); + for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) { + const VCardLine::List lines = (*cardIt).lines( (*identIt) ); + VCardLine::List::ConstIterator lineIt; + + // iterate over the lines + for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) { + identifier = (*lineIt).identifier().lower(); + // ADR + if ( identifier == "adr" ) { + Address address; + const QStringList addrParts = splitString( semicolonSep, (*lineIt).value().asString() ); + if ( addrParts.count() > 0 ) + address.setPostOfficeBox( addrParts[ 0 ] ); + if ( addrParts.count() > 1 ) + address.setExtended( addrParts[ 1 ] ); + if ( addrParts.count() > 2 ) + address.setStreet( addrParts[ 2 ] ); + if ( addrParts.count() > 3 ) + address.setLocality( addrParts[ 3 ] ); + if ( addrParts.count() > 4 ) + address.setRegion( addrParts[ 4 ] ); + if ( addrParts.count() > 5 ) + address.setPostalCode( addrParts[ 5 ] ); + if ( addrParts.count() > 6 ) + address.setCountry( addrParts[ 6 ] ); + + int type = 0; + + const QStringList types = (*lineIt).parameters( "type" ); + for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) + type += mAddressTypeMap[ (*it).lower() ]; + + address.setType( type ); + addr.insertAddress( address ); + } + + // AGENT + else if ( identifier == "agent" ) + addr.setAgent( parseAgent( *lineIt ) ); + + // BDAY + else if ( identifier == "bday" ) + addr.setBirthday( parseDateTime( (*lineIt).value().asString() ) ); + + // CATEGORIES + else if ( identifier == "categories" ) { + const QStringList categories = splitString( commaSep, (*lineIt).value().asString() ); + addr.setCategories( categories ); + } + + // CLASS + else if ( identifier == "class" ) + addr.setSecrecy( parseSecrecy( *lineIt ) ); + + // EMAIL + else if ( identifier == "email" ) { + const QStringList types = (*lineIt).parameters( "type" ); + addr.insertEmail( (*lineIt).value().asString(), types.findIndex( "PREF" ) != -1 ); + } + + // FN + else if ( identifier == "fn" ) + addr.setFormattedName( (*lineIt).value().asString() ); + + // GEO + else if ( identifier == "geo" ) { + Geo geo; + + const QStringList geoParts = QStringList::split( ';', (*lineIt).value().asString(), true ); + geo.setLatitude( geoParts[ 0 ].toFloat() ); + geo.setLongitude( geoParts[ 1 ].toFloat() ); + + addr.setGeo( geo ); + } + + // KEY + else if ( identifier == "key" ) + addr.insertKey( parseKey( *lineIt ) ); + + // LABEL + else if ( identifier == "label" ) { + int type = 0; + + const QStringList types = (*lineIt).parameters( "type" ); + for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) + type += mAddressTypeMap[ (*it).lower() ]; + + bool available = false; + KABC::Address::List addressList = addr.addresses(); + KABC::Address::List::Iterator it; + for ( it = addressList.begin(); it != addressList.end(); ++it ) { + if ( (*it).type() == type ) { + (*it).setLabel( (*lineIt).value().asString() ); + addr.insertAddress( *it ); + available = true; + break; + } + } + + if ( !available ) { // a standalone LABEL tag + KABC::Address address( type ); + address.setLabel( (*lineIt).value().asString() ); + addr.insertAddress( address ); + } + } + + // LOGO + else if ( identifier == "logo" ) + addr.setLogo( parsePicture( *lineIt ) ); + + // MAILER + else if ( identifier == "mailer" ) + addr.setMailer( (*lineIt).value().asString() ); + + // N + else if ( identifier == "n" ) { + const QStringList nameParts = splitString( semicolonSep, (*lineIt).value().asString() ); + if ( nameParts.count() > 0 ) + addr.setFamilyName( nameParts[ 0 ] ); + if ( nameParts.count() > 1 ) + addr.setGivenName( nameParts[ 1 ] ); + if ( nameParts.count() > 2 ) + addr.setAdditionalName( nameParts[ 2 ] ); + if ( nameParts.count() > 3 ) + addr.setPrefix( nameParts[ 3 ] ); + if ( nameParts.count() > 4 ) + addr.setSuffix( nameParts[ 4 ] ); + } + + // NAME + else if ( identifier == "name" ) + addr.setName( (*lineIt).value().asString() ); + + // NICKNAME + else if ( identifier == "nickname" ) + addr.setNickName( (*lineIt).value().asString() ); + + // NOTE + else if ( identifier == "note" ) + addr.setNote( (*lineIt).value().asString() ); + + // ORGANIZATION + else if ( identifier == "org" ) { + const QStringList orgParts = splitString( semicolonSep, (*lineIt).value().asString() ); + if ( orgParts.count() > 0 ) + addr.setOrganization( orgParts[ 0 ] ); + if ( orgParts.count() > 1 ) + addr.setDepartment( orgParts[ 1 ] ); + } + + // PHOTO + else if ( identifier == "photo" ) + addr.setPhoto( parsePicture( *lineIt ) ); + + // PROID + else if ( identifier == "prodid" ) + addr.setProductId( (*lineIt).value().asString() ); + + // REV + else if ( identifier == "rev" ) + addr.setRevision( parseDateTime( (*lineIt).value().asString() ) ); + + // ROLE + else if ( identifier == "role" ) + addr.setRole( (*lineIt).value().asString() ); + + // SORT-STRING + else if ( identifier == "sort-string" ) + addr.setSortString( (*lineIt).value().asString() ); + + // SOUND + else if ( identifier == "sound" ) + addr.setSound( parseSound( *lineIt ) ); + + // TEL + else if ( identifier == "tel" ) { + PhoneNumber phone; + phone.setNumber( (*lineIt).value().asString() ); + + int type = 0; + + const QStringList types = (*lineIt).parameters( "type" ); + for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) + type += mPhoneTypeMap[(*it).upper()]; + + phone.setType( type ); + + addr.insertPhoneNumber( phone ); + } + + // TITLE + else if ( identifier == "title" ) + addr.setTitle( (*lineIt).value().asString() ); + + // TZ + else if ( identifier == "tz" ) { + TimeZone tz; + const QString date = (*lineIt).value().asString(); + + int hours = date.mid( 1, 2).toInt(); + int minutes = date.mid( 4, 2 ).toInt(); + int offset = ( hours * 60 ) + minutes; + offset = offset * ( date[ 0 ] == '+' ? 1 : -1 ); + + tz.setOffset( offset ); + addr.setTimeZone( tz ); + } + + // UID + else if ( identifier == "uid" ) + addr.setUid( (*lineIt).value().asString() ); + + // URL + else if ( identifier == "url" ) + addr.setUrl( KURL( (*lineIt).value().asString() ) ); + + // X- + else if ( identifier.startsWith( "x-" ) ) { + const QString key = (*lineIt).identifier().mid( 2 ); + int dash = key.find( "-" ); + addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), (*lineIt).value().asString() ); + } + } + } + + addrList.append( addr ); + } + + return addrList; +} + +QDateTime VCardTool::parseDateTime( const QString &str ) +{ + QDateTime dateTime; + + if ( str.find( '-' ) == -1 ) { // is base format (yyyymmdd) + dateTime.setDate( QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(), + str.mid( 6, 2 ).toInt() ) ); + + if ( str.find( 'T' ) ) // has time information yyyymmddThh:mm:ss + dateTime.setTime( QTime( str.mid( 11, 2 ).toInt(), str.mid( 14, 2 ).toInt(), + str.mid( 17, 2 ).toInt() ) ); + + } else { // is extended format yyyy-mm-dd + dateTime.setDate( QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(), + str.mid( 8, 2 ).toInt() ) ); + + if ( str.find( 'T' ) ) // has time information yyyy-mm-ddThh:mm:ss + dateTime.setTime( QTime( str.mid( 11, 2 ).toInt(), str.mid( 14, 2 ).toInt(), + str.mid( 17, 2 ).toInt() ) ); + } + + return dateTime; +} + +QString VCardTool::createDateTime( const QDateTime &dateTime ) +{ + QString str; + + if ( dateTime.date().isValid() ) { + str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(), + dateTime.date().day() ); + if ( dateTime.time().isValid() ) { + QString tmp; + tmp.sprintf( "T%02d:%02d:%02dZ", dateTime.time().hour(), dateTime.time().minute(), + dateTime.time().second() ); + str += tmp; + } + } + + return str; +} + +Picture VCardTool::parsePicture( const VCardLine &line ) +{ + Picture pic; + + const QStringList params = line.parameterList(); + if ( params.findIndex( "encoding" ) != -1 ) { + QImage img; + img.loadFromData( line.value().asByteArray() ); + pic.setData( img ); + } else if ( params.findIndex( "value" ) != -1 ) { + if ( line.parameter( "value" ).lower() == "uri" ) + pic.setUrl( line.value().asString() ); + } + + if ( params.findIndex( "type" ) != -1 ) + pic.setType( line.parameter( "type" ) ); + + return pic; +} + +VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic ) +{ + VCardLine line( identifier ); + + if ( pic.isIntern() ) { + if ( !pic.data().isNull() ) { + QByteArray input; + QBuffer buffer( input ); + buffer.open( IO_WriteOnly ); + + QImageIO iio( &buffer, "JPEG" ); + iio.setImage( pic.data() ); + iio.setQuality( 100 ); + iio.write(); + + line.setValue( input ); + line.addParameter( "encoding", "b" ); + line.addParameter( "type", "image/jpeg" ); + } + } else if ( !pic.url().isEmpty() ) { + line.setValue( pic.url() ); + line.addParameter( "value", "URI" ); + } + + return line; +} + +Sound VCardTool::parseSound( const VCardLine &line ) +{ + Sound snd; + + const QStringList params = line.parameterList(); + if ( params.findIndex( "encoding" ) != -1 ) + snd.setData( line.value().asByteArray() ); + else if ( params.findIndex( "value" ) != -1 ) { + if ( line.parameter( "value" ).lower() == "uri" ) + snd.setUrl( line.value().asString() ); + } + +/* TODO: support sound types + if ( params.contains( "type" ) ) + snd.setType( line.parameter( "type" ) ); +*/ + + return snd; +} + +VCardLine VCardTool::createSound( const Sound &snd ) +{ + VCardLine line( "SOUND" ); + + if ( snd.isIntern() ) { + if ( !snd.data().isEmpty() ) { + line.setValue( snd.data() ); + line.addParameter( "encoding", "b" ); + // TODO: need to store sound type!!! + } + } else if ( !snd.url().isEmpty() ) { + line.setValue( snd.url() ); + line.addParameter( "value", "URI" ); + } + + return line; +} + +Key VCardTool::parseKey( const VCardLine &line ) +{ + Key key; + + const QStringList params = line.parameterList(); + if ( params.findIndex( "encoding" ) != -1 ) + key.setBinaryData( line.value().asByteArray() ); + else + key.setTextData( line.value().asString() ); + + if ( params.findIndex( "type" ) != -1 ) { + if ( line.parameter( "type" ).lower() == "x509" ) + key.setType( Key::X509 ); + else if ( line.parameter( "type" ).lower() == "pgp" ) + key.setType( Key::PGP ); + else { + key.setType( Key::Custom ); + key.setCustomTypeString( line.parameter( "type" ) ); + } + } + + return key; +} + +VCardLine VCardTool::createKey( const Key &key ) +{ + VCardLine line( "KEY" ); + + if ( key.isBinary() ) { + if ( !key.binaryData().isEmpty() ) { + line.setValue( key.binaryData() ); + line.addParameter( "encoding", "b" ); + } + } else if ( !key.textData().isEmpty() ) + line.setValue( key.textData() ); + + if ( key.type() == Key::X509 ) + line.addParameter( "type", "X509" ); + else if ( key.type() == Key::PGP ) + line.addParameter( "type", "PGP" ); + else if ( key.type() == Key::Custom ) + line.addParameter( "type", key.customTypeString() ); + + return line; +} + +Secrecy VCardTool::parseSecrecy( const VCardLine &line ) +{ + Secrecy secrecy; + + if ( line.value().asString().lower() == "public" ) + secrecy.setType( Secrecy::Public ); + if ( line.value().asString().lower() == "private" ) + secrecy.setType( Secrecy::Private ); + if ( line.value().asString().lower() == "confidential" ) + secrecy.setType( Secrecy::Confidential ); + + return secrecy; +} + +VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) +{ + VCardLine line( "CLASS" ); + + int type = secrecy.type(); + + if ( type == Secrecy::Public ) + line.setValue( "PUBLIC" ); + else if ( type == Secrecy::Private ) + line.setValue( "PRIVATE" ); + else if ( type == Secrecy::Confidential ) + line.setValue( "CONFIDENTIAL" ); + + return line; +} + +Agent VCardTool::parseAgent( const VCardLine &line ) +{ + Agent agent; + + const QStringList params = line.parameterList(); + if ( params.findIndex( "value" ) != -1 ) { + if ( line.parameter( "value" ).lower() == "uri" ) + agent.setUrl( line.value().asString() ); + } else { + QString str = line.value().asString(); + str.replace( "\\n", "\r\n" ); + str.replace( "\\N", "\r\n" ); + str.replace( "\\;", ";" ); + str.replace( "\\:", ":" ); + str.replace( "\\,", "," ); + + const Addressee::List list = parseVCards( str ); + if ( list.count() > 0 ) { + Addressee *addr = new Addressee; + *addr = list[ 0 ]; + agent.setAddressee( addr ); + } + } + + return agent; +} + +VCardLine VCardTool::createAgent( VCard::Version version, const Agent &agent ) +{ + VCardLine line( "AGENT" ); + + if ( agent.isIntern() ) { + if ( agent.addressee() != 0 ) { + Addressee::List list; + list.append( *agent.addressee() ); + + QString str = createVCards( list, version ); + str.replace( "\r\n", "\\n" ); + str.replace( ";", "\\;" ); + str.replace( ":", "\\:" ); + str.replace( ",", "\\," ); + line.setValue( str ); + } + } else if ( !agent.url().isEmpty() ) { + line.setValue( agent.url() ); + line.addParameter( "value", "URI" ); + } + + return line; +} + +QStringList VCardTool::splitString( const QChar &sep, const QString &str ) +{ + QStringList list; + QString value( str ); + + int start = 0; + int pos = value.find( sep, start ); + + while ( pos != -1 ) { + if ( value[ pos - 1 ] != '\\' ) { + if ( pos > start && pos <= (int)value.length() ) + list << value.mid( start, pos - start ); + else + list << QString::null; + + start = pos + 1; + pos = value.find( sep, start ); + } else { + if ( pos != 0 ) { + value.replace( pos - 1, 2, sep ); + pos = value.find( sep, pos ); + } else + pos = value.find( sep, pos + 1 ); + } + } + + int l = value.length() - 1; + if ( value.mid( start, l - start + 1 ).length() > 0 ) + list << value.mid( start, l - start + 1 ); + else + list << QString::null; + + return list; +} diff --git a/kabc/vcardtool.h b/kabc/vcardtool.h new file mode 100644 index 000000000..2c78e8442 --- /dev/null +++ b/kabc/vcardtool.h @@ -0,0 +1,88 @@ +/* + This file is part of libkabc. + Copyright (c) 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_VCARDTOOL_H +#define KABC_VCARDTOOL_H + +#include "addressee.h" +#include "vcardparser.h" + +class QDateTime; + +namespace KABC { + +class Agent; +class Key; +class Picture; +class Secrecy; +class Sound; + +class KABC_EXPORT VCardTool +{ + public: + VCardTool(); + ~VCardTool(); + + /** + Creates a string that contains the addressees from the list in + the vCard format. + */ + QString createVCards( Addressee::List list, VCard::Version version = VCard::v3_0 ); + + /** + Parses the string and returns a list of addressee objects. + */ + Addressee::List parseVCards( const QString& vcard ); + + private: + /** + Split a string and replaces escaped separators on the fly with + unescaped ones. + */ + QStringList splitString( const QChar &sep, const QString &value ); + + QDateTime parseDateTime( const QString &str ); + QString createDateTime( const QDateTime &dateTime ); + + Picture parsePicture( const VCardLine &line ); + VCardLine createPicture( const QString &identifier, const Picture &pic ); + + Sound parseSound( const VCardLine &line ); + VCardLine createSound( const Sound &snd ); + + Key parseKey( const VCardLine &line ); + VCardLine createKey( const Key &key ); + + Secrecy parseSecrecy( const VCardLine &line ); + VCardLine createSecrecy( const Secrecy &secrecy ); + + Agent parseAgent( const VCardLine &line ); + VCardLine createAgent( VCard::Version version, const Agent &agent ); + + QMap<QString, int> mAddressTypeMap; + QMap<QString, int> mPhoneTypeMap; + + class VCardToolPrivate; + VCardToolPrivate *d; +}; + +} + +#endif |