/* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Enhanced Version of the file for platform independent KDE tools. Copyright (c) 2004 Ulf Schenk $Id$ */ #include #include #include #include #include #include #include //US #include #include #include #include #include //US #include #include #include #include #include "resourceqtopiaconfig.h" #include "stdaddressbook.h" #include "qtopiaconverter.h" #include "syncprefwidget.h" #include "resourceqtopia.h" #include #include using namespace KABC; extern "C" { void *init_microkabc_qtopia() { return new KRES::PluginFactory(); } } ResourceQtopia::ResourceQtopia( const KConfig *config, bool syncable ) : Resource( config, syncable ), mConverter (0) { // we can not choose the filename. Therefore use the default to display QString fileName = QDir::homeDirPath() + "/Applications/addressbook/addressbook.xml"; init( fileName ); } ResourceQtopia::ResourceQtopia( const QString &fileName, bool syncable ) : Resource( 0, syncable ) { init( fileName ); } void ResourceQtopia::init( const QString &fileName ) { 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 ); } ResourceQtopia::~ResourceQtopia() { if (mConverter != 0) delete mConverter; if(mAccess != 0) delete mAccess; } void ResourceQtopia::writeConfig( KConfig *config ) { Resource::writeConfig( config ); } Ticket *ResourceQtopia::requestSaveTicket() { kdDebug(5700) << "ResourceQtopia::requestSaveTicket()" << endl; qDebug("ResourceQtopia::requestSaveTicket: %s", fileName().latin1()); if ( !addressBook() ) return 0; if ( !lock( fileName() ) ) { kdDebug(5700) << "ResourceQtopia::requestSaveTicket(): Unable to lock file '" << fileName() << "'" << endl; return 0; } return createTicket( this ); } 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) { mConverter = new QtopiaConverter(); bool res = mConverter->init(); if ( !res ) { QString msg("Unable to initialize qtopia converter. Most likely a problem with the category file"); qDebug(msg); delete mAccess; mAccess = 0; return false; } } return true; } 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; return; } bool ResourceQtopia::load() { qDebug("ResourceQtopia::load: %s", fileName().latin1()); AddressBookIterator it(*mAccess); const PimContact* contact; bool res; for (contact=it.toFirst(); it.current(); ++it) { contact = it.current(); KABC::Addressee addressee; res = mConverter->qtopiaToAddressee( (*contact), addressee ); if ( !addressee.isEmpty() && res ) { addressee.setResource( this ); addressBook()->insertAddressee( addressee ); } } return true; } bool ResourceQtopia::save( Ticket *ticket ) { qDebug("ResourceQtopia::save: %s", fileName().latin1()); mDirWatch.stopScan(); KABC::AddressBook::Iterator it; bool res; KABC::Addressee::List changedAddressees; QStringList addedUID; for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) { //KABC::Addressee addressee = (*it); // qDebug("AAAfor uid %s ", (*it).originalExternalUID().latin1() ); if ( (*it).tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { QUuid uid( (*it).originalExternalUID() ); bool ok; PimContact c = mAccess->contactForId( uid, &ok ); qDebug("ResourceQtopia::save:Found %d for uid %s ", ok,(*it).originalExternalUID().latin1() ); res = mConverter->addresseeToQtopia( *it, c ); if (res == true) { if ( (*it).tempSyncStat() == SYNC_TEMPSTATE_ADDED_EXTERNAL ) { qDebug("skipping adding of contact "); continue; PimContact e; AddressBookAccess Access2; Access2.addContact(e); const PimContact* contact; bool res; QString uid2, Ouid; AddressBookIterator itt(Access2); for (contact=itt.toFirst(); itt.current(); ++itt) { contact = itt.current(); QString exuid = contact->uid().toString(); Ouid =exuid; int ente = exuid.find( "-0000"); if ( exuid.left(1) == "{" ) exuid = exuid.mid(1); if ( ente > -1 ) exuid = exuid.left( ente-1 ); uid2 = exuid; qDebug("trying find uid "); if ( !addressBook()->containsExternalUid( uid2 ) ) { qDebug("ab not contains "); if ( !addedUID.contains( uid2 )) { qDebug("list not contains "); break; } } } if ( !itt.current()) { qDebug("ERROR uid "); continue; } else qDebug("ADD uid detected "); QUuid uid3( Ouid); PimContact d = Access2.contactForId( uid3, &ok ); if ( ! ok ) { qDebug("ADD: Error getting new uid "); } else { qDebug("NEW UID found "); PimContact g = mAccess->contactForId( c.uid(), &ok ); KABC::Addressee addressee; mConverter->qtopiaToAddressee( g, addressee ); addressee.setUid((*it).uid() ); addressee.setTempSyncStat( SYNC_TEMPSTATE_NEW_ID ); changedAddressees.append( addressee ); addedUID.append( uid2 ); } } else if ( (*it).tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { qDebug("Remove contact "); if ( ok ) mAccess->removeContact(c); else qDebug("Error remove contact from qtopia "); } else if ( (*it).tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { if ( ok ) { qDebug("Update contact "); mAccess->updateContact(c); PimContact g = mAccess->contactForId( c.uid(), &ok ); KABC::Addressee addressee; mConverter->qtopiaToAddressee( g, addressee ); addressee.setUid((*it).uid() ); addressee.setTempSyncStat( SYNC_TEMPSTATE_NEW_CSUM ); changedAddressees.append( addressee ); } else qDebug("Error update contact from qtopia "); } } else { qDebug("Unable to convert Addressee %s", (*it).formattedName().latin1()); } } } KABC::Addressee::List::Iterator it2; for ( it2 = changedAddressees.begin(); it2 != changedAddressees.end(); ++it2 ) addressBook()->insertAddressee((*it2)); mDirWatch.startScan(); delete ticket; unlock( fileName() ); return true; } bool ResourceQtopia::lock( const QString &lockfileName ) { qDebug("ResourceQtopia::lock: %s", fileName().latin1()); kdDebug(5700) << "ResourceQtopia::lock()" << endl; QString fn = lockfileName; KURL url(fn); QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); kdDebug(5700) << "-- lock name: " << lockName << endl; if (QFile::exists( lockName )) { qDebug("ResourceOpie::lock: lockfile %s already exists. (Delete it before continuing if nobody else is accessing the resourcefile %s)", lockName.latin1(), fileName().latin1()); return false; } QString lockUniqueName; lockUniqueName = fn + KApplication::randomString( 8 ); url = lockUniqueName; //US mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName ); mLockUniqueName = locateLocal( "data", "kabc/lock/" + url.fileName() ); kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl; // Create unique file QFile file( mLockUniqueName ); file.open( IO_WriteOnly ); file.close(); // Create lock file int result = 0; #ifndef _WIN32_ result = ::link( QFile::encodeName( mLockUniqueName ), QFile::encodeName( lockName ) ); #endif if ( result == 0 ) { addressBook()->emitAddressBookLocked(); return true; } // TODO: check stat return false; } void ResourceQtopia::unlock( const QString &fileName ) { qDebug("ResourceQtopia::unlock() %s", fileName.latin1()); QString fn = fileName; KURL url(fn); QString lockName = locateLocal( "data", "kabc/lock/" + url.fileName() + ".lock" ); QFile::remove( lockName ); QFile::remove( mLockUniqueName ); addressBook()->emitAddressBookUnlocked(); } void ResourceQtopia::setFileName( const QString &newFileName ) { mDirWatch.stopScan(); mDirWatch.removeFile( fileName() ); Resource::setFileName( newFileName ); mDirWatch.addFile( fileName() ); mDirWatch.startScan(); } void ResourceQtopia::fileChanged() { // There is a small theoretical chance that KDirWatch calls us before // we are fully constructed if (!addressBook()) return; QString text( i18n( "Qtopia resource '%1'
has been changed by third party.
Do you want to reload?").arg( fileName() ) ); if ( readOnly() || KMessageBox::questionYesNo( 0, text ) == KMessageBox::Yes ) { load(); addressBook()->emitAddressBookChanged(); } } void ResourceQtopia::removeAddressee( const Addressee &addr ) { } void ResourceQtopia::cleanUp() { unlock( fileName() ); } //US #include "resourceqtopia.moc"