-rw-r--r-- | kabc/plugins/qtopia/qtopiaE.pro | 1 | ||||
-rw-r--r-- | kabc/plugins/qtopia/qtopiaconverter.cpp | 791 | ||||
-rw-r--r-- | kabc/plugins/qtopia/qtopiaconverter.h | 66 | ||||
-rw-r--r-- | kabc/plugins/qtopia/resourceqtopia.cpp | 101 | ||||
-rw-r--r-- | kabc/plugins/qtopia/resourceqtopia.h | 1 |
5 files changed, 683 insertions, 277 deletions
diff --git a/kabc/plugins/qtopia/qtopiaE.pro b/kabc/plugins/qtopia/qtopiaE.pro index a15e9ba..d66c719 100644 --- a/kabc/plugins/qtopia/qtopiaE.pro +++ b/kabc/plugins/qtopia/qtopiaE.pro @@ -11,7 +11,6 @@ DESTDIR = $(QPEDIR)/lib LIBS += -lmicrokde LIBS += -lkamicrokabc LIBS += -L$(QPEDIR)/lib -LIBS += -lqpepim LIBS += -lqpe INTERFACES = \ diff --git a/kabc/plugins/qtopia/qtopiaconverter.cpp b/kabc/plugins/qtopia/qtopiaconverter.cpp index 5eab1be..040226c 100644 --- a/kabc/plugins/qtopia/qtopiaconverter.cpp +++ b/kabc/plugins/qtopia/qtopiaconverter.cpp @@ -27,19 +27,26 @@ $Id$ //US #include "kglobal.h" +#include "klocale.h" #include "qtopiaconverter.h" -#include <qpe/categories.h> +#include <qfile.h> +#include <qdir.h> +#include <qtextstream.h> +//#include <.h> + +//#include <qpe/categories.h> #include <libkdepim/ksyncprofile.h> //US #include <qpe/categoryselect.h> using namespace KABC; -QtopiaConverter::QtopiaConverter() : catDB(0) +QtopiaConverter::QtopiaConverter() { + m_edit = 0; } QtopiaConverter::~QtopiaConverter() @@ -49,328 +56,616 @@ QtopiaConverter::~QtopiaConverter() bool QtopiaConverter::init() { - catDB = new Categories(); - - if (!catDB) - return false; - - catDB->load( categoryFileName() ); + QString fn = QDir::homeDirPath() +"/Settings/Categories.xml"; + m_edit = new CategoryEdit( fn); return true; } void QtopiaConverter::deinit() { - if (catDB) + if (m_edit) { - delete catDB; - catDB = 0; + delete m_edit; + m_edit = 0; } } - -bool QtopiaConverter::qtopiaToAddressee( const PimContact &contact, Addressee &addr ) -{ - // name - addr.setFormattedName(contact.fileAs()); - addr.setFamilyName( contact.lastName() ); - addr.setGivenName( contact.firstName() ); - addr.setAdditionalName( contact.middleName() ); - addr.setPrefix( contact.nameTitle() ); - addr.setSuffix( contact.suffix() ); - - addr.setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL ); - QString exuid = contact.uid().toString(); - addr.setOriginalExternalUID( exuid ); - int ente = exuid.find( "-0000"); - if ( exuid.left(1) == "{" ) - exuid = exuid.mid(1); - if ( ente > -1 ) - exuid = exuid.left( ente-1 ); - addr.setExternalUID( exuid ); - // qDebug("QtopiaConverter:set %s uid %s ",addr.originalExternalUID().latin1(),addr.externalUID().latin1() ); - - // email - QStringList emails = contact.emailList(); - for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { - addr.insertEmail( *it, ((*it) == contact.defaultEmail()) ); - } - - if (!contact.defaultEmail().isEmpty()) - addr.insertEmail(contact.defaultEmail(), true); - - // home - if ((!contact.homeStreet().isEmpty()) || - (!contact.homeCity().isEmpty()) || - (!contact.homeState().isEmpty()) || - (!contact.homeZip().isEmpty()) || - (!contact.homeCountry().isEmpty())) +QString QtopiaConverter::categoriesToNumber( const QStringList &list, const QString &app ) { - Address homeaddress; - homeaddress.setType(Address::Home); -//US homeaddress.setPostOfficeBox( "" ); -//US homeaddress.setExtended( "" ); - homeaddress.setStreet( contact.homeStreet() ); - homeaddress.setLocality( contact.homeCity() ); - homeaddress.setRegion( contact.homeState() ); - homeaddress.setPostalCode( contact.homeZip() ); - homeaddress.setCountry( contact.homeCountry() ); - - addr.insertAddress( homeaddress ); + startover: + QStringList dummy; + QValueList<OpieCategories>::ConstIterator catIt; + QValueList<OpieCategories> categories = m_edit->categories(); + bool found = false; + for ( QStringList::ConstIterator listIt = list.begin(); listIt != list.end(); ++listIt ) { + /* skip empty category name */ + if ( (*listIt).isEmpty() ) continue; + + found = false; + for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) { + /* + * We currently do not take app into account + * if name matches and the id isn't already in dummy we'll add it + */ + if ( (*catIt).name() == (*listIt) && !dummy.contains(( *catIt).id() ) ) { // the same name + found= true; + dummy << (*catIt).id(); } - - if (!contact.homePhone().isEmpty()) - { - PhoneNumber homephone; - homephone.setType( PhoneNumber::Home ); - homephone.setNumber( contact.homePhone() ); - addr.insertPhoneNumber( homephone ); } + /* if not found and the category is not empty + * + * generate a new category and start over again + * ugly goto to reiterate + */ - if (!contact.homeFax().isEmpty()) - { - PhoneNumber homefax; - homefax.setType( PhoneNumber::Home | PhoneNumber::Fax ); - homefax.setNumber( contact.homeFax() ); - addr.insertPhoneNumber( homefax ); + if ( !found && !(*listIt).isEmpty() ){ + m_edit->addCategory( app, (*listIt) ); // generate a new category + goto startover; } - - if (!contact.homeMobile().isEmpty()) - { - PhoneNumber homemobile; - homemobile.setType( PhoneNumber::Home | PhoneNumber::Cell ); - homemobile.setNumber( contact.homeMobile() ); - addr.insertPhoneNumber( homemobile ); } - addr.setUrl( contact.homeWebpage() ); + return dummy.join(";"); +} - // business - if ((!contact.businessStreet().isEmpty()) || - (!contact.businessCity().isEmpty()) || - (!contact.businessState().isEmpty()) || - (!contact.businessZip().isEmpty()) || - (!contact.businessCountry().isEmpty())) +// FROM TT timeconversion.cpp GPLed +QDate QtopiaConverter::fromString( const QString &datestr ) { - Address businessaddress; - businessaddress.setType(Address::Work); -//US businessaddress.setPostOfficeBox( "" ); -//US businessaddress.setExtended( "" ); - businessaddress.setStreet( contact.businessStreet() ); - businessaddress.setLocality( contact.businessCity() ); - businessaddress.setRegion( contact.businessState() ); - businessaddress.setPostalCode( contact.businessZip() ); - businessaddress.setCountry( contact.businessCountry() ); + if (datestr.isEmpty() ) + return QDate(); - addr.insertAddress( businessaddress ); + int monthPos = datestr.find('.'); + int yearPos = datestr.find('.', monthPos+1 ); + if ( monthPos == -1 || yearPos == -1 ) { + return QDate(); } + int d = datestr.left( monthPos ).toInt(); + int m = datestr.mid( monthPos+1, yearPos - monthPos - 1 ).toInt(); + int y = datestr.mid( yearPos+1 ).toInt(); + QDate date ( y,m,d ); - if (!contact.businessPhone().isEmpty()) - { - PhoneNumber businessphone; - businessphone.setType( PhoneNumber::Work ); - businessphone.setNumber( contact.businessPhone() ); - addr.insertPhoneNumber( businessphone ); + return date; } - if (!contact.businessFax().isEmpty()) +QDate QtopiaConverter::dateFromString( const QString& s ) { - PhoneNumber businessfax; - businessfax.setType( PhoneNumber::Work | PhoneNumber::Fax ); - businessfax.setNumber( contact.businessFax() ); - addr.insertPhoneNumber( businessfax ); - } + QDate date; + + if ( s.isEmpty() ) + return date; + + // Be backward compatible to old Opie format: + // Try to load old format. If it fails, try new ISO-Format! + date = fromString ( s ); + if ( date.isValid() ) + return date; + + // Read ISO-Format (YYYYMMDD) + int year = s.mid(0, 4).toInt(); + int month = s.mid(4,2).toInt(); + int day = s.mid(6,2).toInt(); + + // do some quick sanity checking + if ( year < 1900 || year > 3000 ) + return date; + + if ( month < 0 || month > 12 ) + return date; + + if ( day < 0 || day > 31 ) + return date; + + + date.setYMD( year, month, day ); + + if ( !date.isValid() ) + return QDate(); - if (!contact.businessMobile().isEmpty()) + + return date; +} +QString QtopiaConverter::dateToString( const QDate &d ) { - PhoneNumber businessmobile; - businessmobile.setType( PhoneNumber::Work | PhoneNumber::Cell ); - businessmobile.setNumber( contact.businessMobile() ); - addr.insertPhoneNumber( businessmobile ); + if ( d.isNull() || !d.isValid() ) + return QString::null; + + // ISO format in year, month, day (YYYYMMDD); e.g. 20021231 + QString year = QString::number( d.year() ); + QString month = QString::number( d.month() ); + month = month.rightJustify( 2, '0' ); + QString day = QString::number( d.day() ); + day = day.rightJustify( 2, '0' ); + + QString str = year + month + day; + + return str; } - if (!contact.businessPager().isEmpty()) +bool QtopiaConverter::qtopiaToAddressee( const QDomElement& el, Addressee &adr ) { - PhoneNumber businesspager; - businesspager.setType( PhoneNumber::Work | PhoneNumber::Pager ); - businesspager.setNumber( contact.businessPager() ); - addr.insertPhoneNumber( businesspager ); - } - - addr.setRole( contact.jobTitle() ); //? - addr.setOrganization( contact.company() ); - addr.insertCustom( "KADDRESSBOOK", "X-Profession", contact.profession() ); - addr.insertCustom( "KADDRESSBOOK", "X-AssistantsName", contact.assistant() ); - addr.insertCustom( "KADDRESSBOOK", "X-Department", contact.department() ); - addr.insertCustom( "KADDRESSBOOK", "X-ManagersName", contact.manager() ); - addr.insertCustom( "KADDRESSBOOK", "X-Office", contact.office() ); - - //personal - addr.insertCustom( "KADDRESSBOOK", "X-SpousesName", contact.spouse() ); - // qtopia uses this categorization: - // enum GenderType { UnspecifiedGender=0, Male, Female }; - if (contact.gender() == PimContact::Male) - addr.insertCustom( "KADDRESSBOOK", "X-Gender", "male"); - else if (contact.gender() == PimContact::Female) - addr.insertCustom( "KADDRESSBOOK", "X-Gender", "female"); - - if (contact.anniversary().isValid()) { - QString dt = KGlobal::locale()->formatDate(contact.anniversary(), true, KLocale::ISODate); -//US -// qDebug("QtopiaConverter::qtopiaToAddressee found:%s", dt.latin1()); - addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt); + { //LR + + adr.setUid( el.attribute("Uid" ) ); + adr.setFamilyName( el.attribute( "LastName" ) ); + adr.setGivenName( el.attribute( "FirstName" ) ); + adr.setAdditionalName( el.attribute( "MiddleName" ) ); + adr.setSuffix( el.attribute( "Suffix" ) ); + adr.setNickName( el.attribute( "Nickname" ) ); + + QDate date = dateFromString( el.attribute( "Birthday" ) ); + if ( date.isValid() ) + adr.setBirthday( date ); + + adr.setRole( el.attribute( "JobTitle" ) ); + if ( !el.attribute( "FileAs" ).isEmpty() ) + adr.setFormattedName( el.attribute( "FileAs" ) ); + + adr.setOrganization( el.attribute( "Company" ) ); + + KABC::PhoneNumber businessPhoneNum( el.attribute( "BusinessPhone" ), + KABC::PhoneNumber::Work ); + KABC::PhoneNumber businessFaxNum( el.attribute( "BusinessFax" ), + KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax ); + KABC::PhoneNumber businessMobile( el.attribute( "BusinessMobile" ), + KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell ); + KABC::PhoneNumber businessPager( el.attribute( "BusinessPager" ), + KABC::PhoneNumber::Work | KABC::PhoneNumber::Pager ); + if ( !businessPhoneNum.number().isEmpty() ) + adr.insertPhoneNumber( businessPhoneNum ); + if ( !businessFaxNum.number().isEmpty() ) + adr.insertPhoneNumber( businessFaxNum ); + if ( !businessMobile.number().isEmpty() ) + adr.insertPhoneNumber( businessMobile ); + if ( !businessPager.number().isEmpty() ) + adr.insertPhoneNumber( businessPager ); + + // Handle multiple mail addresses + QString DefaultEmail = el.attribute( "DefaultEmail" ); + if ( !DefaultEmail.isEmpty() ) + adr.insertEmail( DefaultEmail, true ); // preferred + + QStringList Emails = QStringList::split(" ",el.attribute("Emails")); + int i; + for (i = 0;i < Emails.count();++i) { + if ( Emails[i] != DefaultEmail ) + adr.insertEmail( Emails[i], false ); } - addr.insertCustom( "KADDRESSBOOK", "X-Children", contact.children() ); - if (contact.birthday().isValid()) - addr.setBirthday( contact.birthday() ); + KABC::PhoneNumber homePhoneNum( el.attribute( "HomePhone" ), + KABC::PhoneNumber::Home ); + KABC::PhoneNumber homeFax( el.attribute( "HomeFax" ), + KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax ); - addr.setNickName( contact.nickname() ); + KABC::PhoneNumber homeMobile( el.attribute( "HomeMobile" ), + KABC::PhoneNumber::Cell ); - // others - //US I put opies BusinessWebPage into Ka/Pi's notes block, because no other native field is available. - QString notes = contact.notes(); - notes += "\nBusinessWebPage: " + contact.businessWebpage() + "\n"; + if ( !homePhoneNum.number().isEmpty() ) + adr.insertPhoneNumber( homePhoneNum ); + if ( !homeFax.number().isEmpty() ) + adr.insertPhoneNumber( homeFax ); + if ( !homeMobile.number().isEmpty() ) + adr.insertPhoneNumber( homeMobile ); - addr.setNote( contact.notes() ); + KABC::Address business( KABC::Address::Work ); + business.setStreet( el.attribute( "BusinessStreet" ) ); + business.setLocality( el.attribute( "BusinessCity" ) ); + business.setRegion( el.attribute( "BusinessState" ) ); + business.setPostalCode( el.attribute( "BusinessZip" ) ); + business.setCountry( el.attribute( "BusinessCountry" ) ); + if ( !business.isEmpty() ) + adr.insertAddress( business ); + KABC::Address home( KABC::Address::Home ); + home.setStreet( el.attribute( "HomeStreet" ) ); + home.setLocality( el.attribute( "HomeCity" ) ); + home.setRegion( el.attribute( "HomeState" ) ); + home.setPostalCode( el.attribute( "HomeZip" ) ); + home.setCountry( el.attribute( "HomeCountry" ) ); -//US QString groups() const { return find( Qtopia::Groups ); } -//US QStringList groupList() const; + if ( !home.isEmpty() ) + adr.insertAddress( home ); - QArray<int> catArray = contact.categories(); - QString cat; + adr.setNickName( el.attribute( "Nickname" ) ); + adr.setNote( el.attribute( "Notes" ) ); - for ( unsigned int i=0; i < catArray.size(); i++ ) { - cat = catDB->label("contact", catArray[i]); - if ( cat.isEmpty() ) - addr.insertCategory(QString::number(catArray[i])); - else - addr.insertCategory( cat ); + { + QStringList categories = QStringList::split(";", el.attribute("Categories" ) ); + QString cat; + QStringList added; + for ( uint i = 0; i < categories.count(); i++ ) { + cat = m_edit->categoryById( categories[ i ], "Contacts" ); + + // if name is not empty and we did not add the + // cat try to repair broken files + if ( !cat.isEmpty() && !added.contains( cat ) ) { + adr.insertCategory( cat ); + added << cat; + } + } } - return true; + if ( !el.attribute( "Department" ).isEmpty() ) + adr.insertCustom( "KADDRESSBOOK", "X-Department", el.attribute( "Department" ) ); + if ( !el.attribute( "HomeWebPage" ).isEmpty() ) + adr.insertCustom( "opie", "HomeWebPage", el.attribute( "HomeWebPage" ) ); + if ( !el.attribute( "Spouse" ).isEmpty() ) + adr.insertCustom( "KADDRESSBOOK", "X-SpousesName", el.attribute( "Spouse" ) ); + if ( !el.attribute( "Gender" ).isEmpty() ) + adr.insertCustom( "opie", "Gender", el.attribute( "Gender" ) ); + + QDate ann = dateFromString( el.attribute( "Anniversary" ) ); + if ( ann.isValid() ) { + QString dt = KGlobal::locale()->formatDate(ann, true, KLocale::ISODate); + adr.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt ); } -bool QtopiaConverter::addresseeToQtopia( const Addressee &addr, PimContact &contact ) -{ + if ( !el.attribute( "Children" ).isEmpty() ) + adr.insertCustom("opie", "Children", el.attribute("Children") ); + if ( !el.attribute( "Office" ).isEmpty() ) + adr.insertCustom("KADDRESSBOOK", "X-Office", el.attribute("Office") ); + if ( !el.attribute( "Profession" ).isEmpty() ) + adr.insertCustom("KADDRESSBOOK", "X-Profession", el.attribute("Profession") ); + if ( !el.attribute( "Assistant" ).isEmpty() ) + adr.insertCustom("KADDRESSBOOK", "X-AssistantsName", el.attribute("Assistant") ); + if ( !el.attribute( "Manager" ).isEmpty() ) + adr.insertCustom("KADDRESSBOOK", "X-ManagersName", el.attribute("Manager") ); + } + return true; +} - // name - contact.setLastName(addr.familyName()); - contact.setFirstName(addr.givenName()); - contact.setMiddleName(addr.additionalName()); - contact.setNameTitle(addr.prefix()); - contact.setSuffix(addr.suffix()); - contact.setFileAs(); +bool QtopiaConverter::addresseeToQtopia( const Addressee &ab, QTextStream *stream ) +{ + *stream << "<Contact "; + *stream << "FirstName=\"" << escape(ab.givenName()) << "\" "; + *stream << "MiddleName=\"" << escape(ab.additionalName()) << "\" "; + *stream << "LastName=\"" << escape(ab.familyName()) << "\" "; + *stream << "Suffix=\"" << escape(ab.suffix()) << "\" "; + + QString sortStr; + sortStr = ab.formattedName(); + /* is formattedName is empty we use the assembled name as fallback */ + if (sortStr.isEmpty() ) + sortStr = ab.assembledName(); + *stream << "FileAs=\"" << escape(sortStr) << "\" "; + + *stream << "JobTitle=\"" << escape(ab.role()) << "\" "; + *stream << "Department=\"" << escape(ab.custom( "KADDRESSBOOK", "X-Department" )) << "\" "; + *stream << "Company=\"" << escape(ab.organization()) << "\" "; + + KABC::PhoneNumber businessPhoneNum = ab.phoneNumber(KABC::PhoneNumber::Work ); + *stream << "BusinessPhone=\"" << escape( businessPhoneNum.number() ) << "\" "; + + KABC::PhoneNumber businessFaxNum = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax ); + *stream << "BusinessFax=\"" << escape( businessFaxNum.number() )<< "\" "; + + KABC::PhoneNumber businessMobile = ab.phoneNumber(KABC::PhoneNumber::Work | KABC::PhoneNumber::Cell ); + *stream << "BusinessMobile=\"" << escape( businessMobile.number() ) << "\" "; + + *stream << "DefaultEmail=\"" << escape( ab.preferredEmail() ) << "\" "; + QStringList list = ab.emails(); + if ( list.count() > 0 ) { + QStringList::Iterator it = list.begin(); + *stream << "Emails=\"" << escape( *it ); + while (++it != list.end()) + *stream << ' ' << escape( *it ); + *stream << "\" "; + } + KABC::PhoneNumber homePhoneNum = ab.phoneNumber(KABC::PhoneNumber::Home ); + *stream << "HomePhone=\"" << escape( homePhoneNum.number() ) << "\" "; + + KABC::PhoneNumber homeFax = ab.phoneNumber( KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax ); + *stream << "HomeFax=\"" << escape( homeFax.number() ) << "\" "; + + KABC::PhoneNumber homeMobile = ab.phoneNumber( KABC::PhoneNumber::Cell ); + *stream << "HomeMobile=\"" << escape( homeMobile.number() ) << "\" "; + + KABC::Address business = ab.address(KABC::Address::Work ); + *stream << "BusinessStreet=\"" << escape( business.street() ) << "\" "; + *stream << "BusinessCity=\"" << escape( business.locality() ) << "\" "; + *stream << "BusinessZip=\"" << escape( business.postalCode() ) << "\" "; + *stream << "BusinessCountry=\"" << escape( business.country() ) << "\" "; + *stream << "BusinessState=\"" << escape( business.region() ) << "\" "; + //stream << "BusinessPager=\"" << << "\" "; + *stream << "Office=\"" << escape( ab.custom( "KADDRESSBOOK", "X-Office" ) ) << "\" "; + *stream << "Profession=\"" << escape( ab.custom( "KADDRESSBOOK", "X-Profession" ) ) << "\" "; + *stream << "Assistant=\"" << escape( ab.custom( "KADDRESSBOOK", "X-AssistantsName") ) << "\" "; + *stream << "Manager=\"" << escape( ab.custom( "KADDRESSBOOK", "X-ManagersName" ) ) << "\" "; + + KABC::Address home = ab.address( KABC::Address::Home ); + *stream << "HomeStreet=\"" << escape( home.street() ) << "\" "; + *stream << "HomeCity=\"" << escape( home.locality() ) << "\" "; + *stream << "HomeState=\"" << escape( home.region() ) << "\" "; + *stream << "HomeZip=\"" << escape( home.postalCode() ) << "\" "; + *stream << "HomeCountry=\"" << escape( home.country() ) << "\" "; + + *stream << "HomeWebPage=\"" << escape( ab.custom( "opie", "HomeWebPage" ) ) << "\" "; + *stream << "Spouse=\"" << escape( ab.custom( "KADDRESSBOOK", "X-SpousesName") ) << "\" "; + *stream << "Gender=\"" << escape( ab.custom( "opie", "Gender") ) << "\" "; + + if ( ab.birthday().date().isValid() ) + *stream << "Birthday=\"" << escape( dateToString(ab.birthday().date() ) ) << "\" "; - // email - QStringList emails = addr.emails(); - for ( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { - contact.insertEmail(*it); + /* + * Anniversary block again + * Go from ISO -> QDate -> toString and then escape + */ + { + QDate ann = KGlobal::locale()->readDate( ab.custom("KADDRESSBOOK", "X-Anniversary" ), + "%Y-%m-%d"); + if (ann.isValid() ) { + *stream << "Anniversary=\"" << escape( dateToString( ann ) ) << "\" "; + } } - contact.setDefaultEmail( addr.preferredEmail() ); + *stream << "Nickname=\"" << escape( ab.nickName() ) << "\" "; + *stream << "Children=\"" << escape( ab.custom("opie", "Children" ) ) << "\" "; + *stream << "Notes=\"" << escape( ab.note() ) << "\" "; + *stream << "Categories=\"" << categoriesToNumber( ab.categories(), "Contacts") << "\" "; + QString uid = ab.uid(); + *stream << "Uid=\"" << uid << "\" "; + //*stream << map.toString( "addressbook", uid ); + *stream << " />" << "\n"; - // home - const Address homeaddress = addr.address(Address::Home); - if (!homeaddress.isEmpty()) { - contact.setHomeStreet(homeaddress.street()); - contact.setHomeCity(homeaddress.locality()); - contact.setHomeState(homeaddress.region()); - contact.setHomeZip(homeaddress.postalCode()); - contact.setHomeCountry(homeaddress.country()); + return true; } - PhoneNumber homephone = addr.phoneNumber( PhoneNumber::Home ); - if (!homephone.number().isEmpty()) - contact.setHomePhone(homephone.number()); - - PhoneNumber homefax = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ); - if (!homefax.number().isEmpty()) - contact.setHomeFax(homefax.number()); - PhoneNumber homemobile = addr.phoneNumber( PhoneNumber::Home | PhoneNumber::Cell ); - if (!homemobile.number().isEmpty()) - contact.setHomeMobile(homemobile.number()); +#if 0 - contact.setHomeWebpage(addr.url().url()); +KTempFile* AddressBook::fromKDE( KSync::AddressBookSyncee *syncee, ExtraMap& map ) +{ +} - // business - const Address businessaddress = addr.address(Address::Work); - if (!businessaddress.isEmpty()) { - contact.setBusinessStreet(businessaddress.street()); - contact.setBusinessCity(businessaddress.locality()); - contact.setBusinessState(businessaddress.region()); - contact.setBusinessZip(businessaddress.postalCode()); - contact.setBusinessCountry(businessaddress.country()); +QStringList AddressBook::attributes()const { + QStringList lst; + lst << "FirstName"; + lst << "MiddleName"; + lst << "LastName"; + lst << "Suffix"; + lst << "FileAs"; + lst << "JobTitle"; + lst << "Department"; + lst << "Company"; + lst << "BusinessPhone"; + lst << "BusinessFax"; + lst << "BusinessMobile"; + lst << "DefaultEmail"; + lst << "Emails"; + lst << "HomePhone"; + lst << "HomeFax"; + lst << "HomeMobile"; + lst << "BusinessStreet"; + lst << "BusinessCity"; + lst << "BusinessZip"; + lst << "BusinessCountry"; + lst << "BusinessState"; + lst << "Office"; + lst << "Profession"; + lst << "Assistant"; + lst << "Manager"; + lst << "HomeStreet"; + lst << "HomeCity"; + lst << "HomeState"; + lst << "HomeZip"; + lst << "HomeCountry"; + lst << "HomeWebPage"; + lst << "Spouse"; + lst << "Gender"; + lst << "Anniversary"; + lst << "Nickname"; + lst << "Children"; + lst << "Notes"; + lst << "Categories"; + lst << "Uid"; + lst << "Birthday"; + + return lst; } - PhoneNumber businessphone = addr.phoneNumber( PhoneNumber::Work ); - if (!businessphone.number().isEmpty()) - contact.setBusinessPhone(businessphone.number()); - PhoneNumber businessfax = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ); - if (!businessfax.number().isEmpty()) - contact.setBusinessFax(businessfax.number()); - PhoneNumber businessmobile = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Cell ); - if (!businessmobile.number().isEmpty()) - contact.setBusinessMobile(businessmobile.number()); +#endif - PhoneNumber businesspager = addr.phoneNumber( PhoneNumber::Work | PhoneNumber::Pager ); - if (!businesspager.number().isEmpty()) - contact.setBusinessPager(businesspager.number()); - contact.setJobTitle(addr.role()); - contact.setCompany(addr.organization()); +CategoryEdit::CategoryEdit(){ +} +CategoryEdit::CategoryEdit(const QString &fileName){ + parse( fileName ); +} +CategoryEdit::~CategoryEdit(){ +} +void CategoryEdit::save(const QString& fileName)const{ + QFile file( fileName ); + QString endl = "\n"; + if ( file.open( IO_WriteOnly ) ) { + QTextStream stream( &file ); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl; + stream << "<!DOCTYPE CategoryList>" << endl; + stream << "<Categories>" << endl; + for ( QValueList<OpieCategories>::ConstIterator it = m_categories.begin(); + it != m_categories.end(); ++it ) + { + stream << "<Category id=\""<< ( (*it).id() ) << "\" "; - contact.setProfession(addr.custom( "KADDRESSBOOK", "X-Profession" )); - contact.setAssistant(addr.custom( "KADDRESSBOOK", "X-AssistantsName" )); - contact.setDepartment(addr.custom( "KADDRESSBOOK", "X-Department" )); - contact.setManager(addr.custom( "KADDRESSBOOK", "X-ManagersName" )); - contact.setOffice(addr.custom( "KADDRESSBOOK", "X-Office" )); + if ( !(*it).app().isEmpty() ) + stream << " app=\""<< ( (*it).app() ) << "\" "; - //personal - contact.setSpouse(addr.custom( "KADDRESSBOOK", "X-Spouse" )); - // qtopia uses this categorization: - // enum GenderType { UnspecifiedGender=0, Male, Female }; - QString gt = addr.custom( "KADDRESSBOOK", "X-Gender" ); - if (gt = "male") - contact.setGender(PimContact::Male); - else if (gt = "female") - contact.setGender(PimContact::Female); - else - contact.setGender(PimContact::UnspecifiedGender); + stream << "name=\"" << ( (*it).name() ) << "\" "; + stream << " />" << endl; + } + stream << "</Categories>" << endl; + file.close(); + } +} +int CategoryEdit::addCategory( const QString &name, int id ){ + return addCategory( QString::null, name, id ); +} +int CategoryEdit::addCategory( const QString &appName, const QString &name, int id ){ + if ( id == 0 ) { + // code from tt + //generate uid + QDateTime dt = QDateTime::currentDateTime(); + id = -1 * (int) dt.secsTo( QDateTime(QDate( 2000,1,1)) ); + while ( ids.contains( id ) ){ + id += -1; + if ( id > 0 ) + id = -1; + } + } + ids.insert( id, TRUE ); + OpieCategories categories(QString::number(id), name, appName); + //pending FIXME LR m_categories.remove( categories); + m_categories.append( categories); + return id; +} +/* + * we parse the simple Category File here + * We also keep track of global Cats + * and Of Organizer and Contact cats and then + * we will add them to the kde side... + */ +void CategoryEdit::parse( const QString &tempFile ){ + clear(); + QDomDocument doc( "mydocument" ); + QFile f( tempFile ); + if ( !f.open( IO_ReadOnly ) ) + return; - QDate dt = KGlobal::locale()->readDate( - addr.custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); // = Qt::ISODate - contact.setAnniversary( dt ); + if ( !doc.setContent( &f ) ) { + f.close(); + return; + } + f.close(); + + QStringList global, contact, organizer; + + // print out the element names of all elements that are a direct child + // of the outermost element. + QDomElement docElem = doc.documentElement(); + QDomNode n = docElem.firstChild(); + if( docElem.nodeName() == QString::fromLatin1("Categories") ){ + while( !n.isNull() ) { + QDomElement e = n.toElement(); // try to convert the node to an element. + if( !e.isNull() ) { // the node was really an element. + QString id = e.attribute("id" ); + QString app = e.attribute("app" ); + QString name = e.attribute("name"); - contact.setChildren(addr.custom( "KADDRESSBOOK", "X-Children" )); + /* + * see where it belongs default to global + */ + if (app == QString::fromLatin1("Calendar") || app == QString::fromLatin1("Todo List") ) + organizer.append( name ); + else if ( app == QString::fromLatin1("Contacts") ) + contact.append( name ); + else + global.append( name ); - contact.setBirthday(addr.birthday().date()); - contact.setNickname(addr.nickName()); + OpieCategories category( id, name, app ); + m_categories.append( category ); // cheater + } + n = n.nextSibling(); + } + } + updateKDE( "kaddressbookrc", global + contact ); + updateKDE( "korganizerrc", global + organizer ); + +} +void CategoryEdit::clear() +{ + ids.clear(); + m_categories.clear(); +} +QString CategoryEdit::categoryById( const QString &id, const QString &app )const +{ + QValueList<OpieCategories>::ConstIterator it; + QString category; + QString fallback; + for( it = m_categories.begin(); it != m_categories.end(); ++it ){ + if( id.stripWhiteSpace() == (*it).id().stripWhiteSpace() ){ + if( app == (*it).app() ){ + category = (*it).name(); + break; + }else{ + fallback = (*it).name(); + } + } + } + return category.isEmpty() ? fallback : category; +} +QStringList CategoryEdit::categoriesByIds( const QStringList& ids, + const QString& app) { + + QStringList list; + QStringList::ConstIterator it; + QString temp; + for ( it = ids.begin(); it != ids.end(); ++it ) { + temp = categoryById( (*it), app ); + if (!temp.isEmpty() ) + list << temp; + } - // other - contact.setNotes(addr.note()); + return list; +} +void CategoryEdit::updateKDE( const QString& configFile, const QStringList& cats ) { + KConfig conf(configFile); + conf.setGroup("General"); + QStringList avail = conf.readListEntry("Custom Categories"); + for (QStringList::ConstIterator it = cats.begin(); it != cats.end(); ++it ) { + if (!avail.contains( (*it) ) ) + avail << (*it); + } + conf.writeEntry("Custom Categories", avail ); +} -//US QString groups() const { return find( Qtopia::Groups ); } -//US QStringList groupList() const; - QStringList cats = addr.categories(); +OpieCategories::OpieCategories() +{ - QArray<int> iar; - if ( !cats.isEmpty() ) { - QArray<int> iar = catDB->ids("contact", cats); - contact.setCategories(iar); } +OpieCategories::OpieCategories(const QString &id, const QString &name, const QString &app ) +{ + m_name = name; + m_id = id; + m_app = app; +} +OpieCategories::OpieCategories(const OpieCategories &op ) +{ + (*this) = op; +} +QString OpieCategories::id() const +{ + return m_id; +} +QString OpieCategories::name() const +{ + return m_name; +} +QString OpieCategories::app() const +{ + return m_app; +} +OpieCategories &OpieCategories::operator=(const OpieCategories &op ) +{ + m_name = op.m_name; + m_app = op.m_app; + m_id = op.m_id; + return (*this); +} + +bool operator== (const OpieCategories& a, const OpieCategories &b ) +{ + if ( a.id() == b.id() && a.name() == b.name() && a.app() == b.app() ) return true; + return false; } + diff --git a/kabc/plugins/qtopia/qtopiaconverter.h b/kabc/plugins/qtopia/qtopiaconverter.h index 012a6e2..d318ded 100644 --- a/kabc/plugins/qtopia/qtopiaconverter.h +++ b/kabc/plugins/qtopia/qtopiaconverter.h @@ -30,13 +30,62 @@ $Id$ #include <qstring.h> #include "addressee.h" -#include <qpe/pim/contact.h> -#include <qpe/quuid.h> +//#include <qpe/pim/contact.h> +//#include <qpe/quuid.h> +#include <xml/qdom.h> class Categories; namespace KABC { + + +class OpieCategories { + public: + //friend class KSync::OpieSocket; + friend bool operator== ( const OpieCategories &a, const OpieCategories &b ); + OpieCategories(); + OpieCategories(const QString &id, const QString &name, const QString &app ); + OpieCategories(const OpieCategories & ); + ~OpieCategories() {}; + OpieCategories &operator=(const OpieCategories & ); + QString id()const; + QString name()const; + QString app()const; + + private: + QString m_name; + QString m_app; + QString m_id; +}; + + + class CategoryEdit { + public: + CategoryEdit(); + CategoryEdit(const QString &fileName); + ~CategoryEdit(); + + void save(const QString&) const; + int addCategory( const QString &name, int id = 0 ); + int addCategory(const QString &appName, const QString &name, int id = 0); + void parse( const QString &fileName ); + + QString categoryById(const QString &id, const QString &app )const; + QStringList categoriesByIds( const QStringList& ids, const QString& app ); + + void clear(); + QValueList<OpieCategories> categories()const { return m_categories; }; + private: + /** + * this function will be used internally to update the kde categories... + */ + void updateKDE( const QString& app, const QStringList& categories ); + QMap<int, bool> ids; // from tt Qtopia::UidGen + QValueList<OpieCategories> m_categories; + }; + + class QtopiaConverter { public: @@ -60,21 +109,24 @@ public: * @param contact The qtopia contact. * @param addr The addressee. */ - bool qtopiaToAddressee( const PimContact &contact, Addressee &addr ); - + bool qtopiaToAddressee( const QDomElement& el, Addressee &adr ); /** * Converts an addressee to a vcard string. * * @param addr The addressee. * @param contact The qtopia contact. */ - bool addresseeToQtopia( const Addressee &addr, PimContact &contact ); + bool addresseeToQtopia( const Addressee &ab, QTextStream *stream ); private: - Categories* catDB; + QString categoriesToNumber( const QStringList &list, const QString &app ); + QString escape( const QString& s){ return s;}; + CategoryEdit *m_edit; + QDate fromString( const QString& ); + QDate dateFromString( const QString& ); + QString dateToString( const QDate& ); }; - } #endif diff --git a/kabc/plugins/qtopia/resourceqtopia.cpp b/kabc/plugins/qtopia/resourceqtopia.cpp index deb218b..b7263bb 100644 --- a/kabc/plugins/qtopia/resourceqtopia.cpp +++ b/kabc/plugins/qtopia/resourceqtopia.cpp @@ -30,6 +30,7 @@ $Id$ #include <qdir.h> #include <qfile.h> +#include <qtextstream.h> #include <qfileinfo.h> #include <qregexp.h> //US #include <qtimer.h> @@ -90,8 +91,6 @@ ResourceQtopia::~ResourceQtopia() if (mConverter != 0) delete mConverter; - if(mAccess != 0) - delete mAccess; } void ResourceQtopia::writeConfig( KConfig *config ) @@ -120,13 +119,6 @@ bool ResourceQtopia::doOpen() { qDebug("ResourceQtopia::doOpen(): %s", fileName().latin1()); - mAccess = new AddressBookAccess(); - - if ( !mAccess ) { - qDebug("Unable to load file() %s", fileName().latin1()); - return false; - } - if (mConverter == 0) { @@ -136,8 +128,6 @@ bool ResourceQtopia::doOpen() { QString msg("Unable to initialize qtopia converter. Most likely a problem with the category file"); qDebug(msg); - delete mAccess; - mAccess = 0; return false; } } @@ -149,11 +139,7 @@ void ResourceQtopia::doClose() { qDebug("ResourceQtopia::doClose: %s", fileName().latin1()); - if(mAccess) - { - delete mAccess; - mAccess = 0; - } + // it seems so, that deletion of access deletes backend as well //delete backend; @@ -162,6 +148,47 @@ void ResourceQtopia::doClose() bool ResourceQtopia::load() { + + QFile file( fileName() ); + if ( !file.open(IO_ReadOnly ) ) { + return false; + } + + QDomDocument doc("mydocument" ); + if ( !doc.setContent( &file ) ) { + file.close(); + return false; + } + bool res; + QDomElement docElem = doc.documentElement( ); + QDomNode n = docElem.firstChild(); + while ( !n.isNull() ) { + QDomElement e = n.toElement(); + if ( !e.isNull() ) { + if ( e.tagName() == QString::fromLatin1( "Contacts" ) ) { // we're looking for them + QDomNode no = e.firstChild(); + while ( !no.isNull() ) { + QDomElement el = no.toElement(); + if ( !el.isNull() ) { + KABC::Addressee addressee; + res = mConverter->qtopiaToAddressee( el, addressee ); + if ( !addressee.isEmpty() && res ) + { + addressee.setResource( this ); + addressBook()->insertAddressee( addressee ); + } + } + + no = no.nextSibling(); + } + } + } + + n = n.nextSibling(); + } + +#if 0 +/ old code qDebug("ResourceQtopia::load: %s", fileName().latin1()); AddressBookIterator it(*mAccess); @@ -174,7 +201,7 @@ bool ResourceQtopia::load() KABC::Addressee addressee; - res = mConverter->qtopiaToAddressee( (*contact), addressee ); + //LRres = mConverter->qtopiaToAddressee( (*contact), addressee ); if ( !addressee.isEmpty() && res ) { @@ -182,12 +209,46 @@ bool ResourceQtopia::load() addressBook()->insertAddressee( addressee ); } } - +#endif return true; } bool ResourceQtopia::save( Ticket *ticket ) { + + mDirWatch.stopScan(); + KABC::AddressBook::Iterator it; + bool res; + //pending open file for stream + QTextStream *stream;// = tempFile->textStream(); + stream->setEncoding( QTextStream::UnicodeUTF8 ); + *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>" << endl; + *stream << " <Groups>" << endl; + *stream << " </Groups>" << endl; + *stream << " <Contacts> " << endl; + // for all entries + KABC::Addressee ab; + for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { + KABC::Addressee addressee = (*it); + res = mConverter->addresseeToQtopia( addressee, stream ); + if (!res == true) + { + qDebug("Unable to convert Addressee %s", addressee.formattedName().latin1()); + } + } + + + *stream << "</Contacts>" << endl; + *stream << "</AddressBook>" << endl; + //pending close file + mDirWatch.startScan(); + + delete ticket; + unlock( fileName() ); + + +#if 0 + //old code qDebug("ResourceQtopia::save: %s", fileName().latin1()); mDirWatch.stopScan(); @@ -199,7 +260,7 @@ bool ResourceQtopia::save( Ticket *ticket ) PimContact c; KABC::Addressee addressee = (*it); - res = mConverter->addresseeToQtopia( *it, c ); + //res = mConverter->addresseeToQtopia( *it, c ); if (res == true) { mAccess->addContact(c); @@ -218,7 +279,7 @@ bool ResourceQtopia::save( Ticket *ticket ) delete ticket; unlock( fileName() ); - +#endif return true; } diff --git a/kabc/plugins/qtopia/resourceqtopia.h b/kabc/plugins/qtopia/resourceqtopia.h index ff6350d..31b95f2 100644 --- a/kabc/plugins/qtopia/resourceqtopia.h +++ b/kabc/plugins/qtopia/resourceqtopia.h @@ -132,7 +132,6 @@ protected: void unlock( const QString &fileName ); private: - AddressBookAccess* mAccess; QtopiaConverter* mConverter; QString mLockUniqueName; |