resourcefile.cpp
00001 #include <sys/types.h>
00002 #include <sys/stat.h>
00003 #include <unistd.h>
00004
00005 #include <qfile.h>
00006 #include <qregexp.h>
00007 #include <qtimer.h>
00008
00009 #include <kapplication.h>
00010 #include <kconfig.h>
00011 #include <kdebug.h>
00012 #include <klocale.h>
00013 #include <kstandarddirs.h>
00014 #include <kurlrequester.h>
00015
00016 #include "addressbook.h"
00017 #include "stdaddressbook.h"
00018
00019 #include "formatfactory.h"
00020
00021 #include "resourceconfigwidget.h"
00022 #include "resourcefile.h"
00023 #include "resourcefileconfig.h"
00024
00025 using namespace KABC;
00026
00027 ResourceFile::ResourceFile( AddressBook *addressBook, const KConfig *config )
00028 : Resource( addressBook )
00029 {
00030 QString fileName = config->readEntry( "FileName" );
00031 QString type = config->readEntry( "FileFormat" );
00032
00033 FormatFactory *factory = FormatFactory::self();
00034 FormatPlugin *format = factory->format( type );
00035
00036 init( fileName, format );
00037 }
00038
00039 ResourceFile::ResourceFile( AddressBook *addressBook, const QString &filename,
00040 FormatPlugin *format ) :
00041 Resource( addressBook )
00042 {
00043 init( filename, format );
00044 }
00045
00046 ResourceFile::~ResourceFile()
00047 {
00048 delete mFormat;
00049 }
00050
00051 void ResourceFile::init( const QString &filename, FormatPlugin *format )
00052 {
00053 if ( !format ) {
00054 FormatFactory *factory = FormatFactory::self();
00055 mFormat = factory->format( "vcard" );
00056 } else {
00057 mFormat = format;
00058 }
00059
00060 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
00061 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
00062 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
00063
00064 setFileName( filename );
00065 }
00066
00067 Ticket *ResourceFile::requestSaveTicket()
00068 {
00069 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
00070
00071 if ( !addressBook() ) return 0;
00072
00073 if ( !lock( mFileName ) ) {
00074 kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock file '"
00075 << mFileName << "'" << endl;
00076 return 0;
00077 }
00078 return createTicket( this );
00079 }
00080
00081
00082 bool ResourceFile::open()
00083 {
00084 QFile file( mFileName );
00085
00086 if ( !file.exists() )
00087 return true;
00088
00089 if ( !file.open( IO_ReadOnly ) )
00090 return true;
00091
00092 if ( file.size() == 0 )
00093 return true;
00094
00095 bool ok = mFormat->checkFormat( &file );
00096 file.close();
00097
00098 return ok;
00099 }
00100
00101 void ResourceFile::close()
00102 {
00103 }
00104
00105 bool ResourceFile::load()
00106 {
00107 kdDebug(5700) << "ResourceFile::load(): '" << mFileName << "'" << endl;
00108
00109 QFile file( mFileName );
00110 if ( !file.open( IO_ReadOnly ) ) {
00111 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) );
00112 return false;
00113 }
00114
00115 return mFormat->loadAll( addressBook(), this, &file );
00116 }
00117
00118 bool ResourceFile::save( Ticket *ticket )
00119 {
00120 kdDebug(5700) << "ResourceFile::save()" << endl;
00121
00122 QFile file( mFileName );
00123 if ( !file.open( IO_WriteOnly ) ) {
00124 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) );
00125 return false;
00126 }
00127
00128 mFormat->saveAll( addressBook(), this, &file );
00129
00130 delete ticket;
00131 unlock( mFileName );
00132
00133 return true;
00134 }
00135
00136 bool ResourceFile::lock( const QString &fileName )
00137 {
00138 kdDebug(5700) << "ResourceFile::lock()" << endl;
00139
00140 QString fn = fileName;
00141 fn.replace( QRegExp("/"), "_" );
00142
00143 QString lockName = locateLocal( "data", "kabc/lock/" + fn + ".lock" );
00144 kdDebug(5700) << "-- lock name: " << lockName << endl;
00145
00146 if (QFile::exists( lockName )) return false;
00147
00148 QString lockUniqueName;
00149 lockUniqueName = fn + kapp->randomString(8);
00150 mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
00151 kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
00152
00153
00154 QFile file( mLockUniqueName );
00155 file.open( IO_WriteOnly );
00156 file.close();
00157
00158
00159 int result = ::link( QFile::encodeName( mLockUniqueName ),
00160 QFile::encodeName( lockName ) );
00161
00162 if ( result == 0 ) {
00163 addressBook()->emitAddressBookLocked();
00164 return true;
00165 }
00166
00167
00168
00169 return false;
00170 }
00171
00172 void ResourceFile::unlock( const QString &fileName )
00173 {
00174 QString fn = fileName;
00175 fn.replace( QRegExp( "/" ), "_" );
00176
00177 QString lockName = locate( "data", "kabc/lock/" + fn + ".lock" );
00178 ::unlink( QFile::encodeName( lockName ) );
00179 QFile::remove( mLockUniqueName );
00180 addressBook()->emitAddressBookUnlocked();
00181 }
00182
00183 void ResourceFile::setFileName( const QString &fileName )
00184 {
00185 mDirWatch.stopScan();
00186 mDirWatch.removeFile( mFileName );
00187
00188 mFileName = fileName;
00189
00190 mDirWatch.addFile( mFileName );
00191 mDirWatch.startScan();
00192 }
00193
00194 QString ResourceFile::fileName() const
00195 {
00196 return mFileName;
00197 }
00198
00199 void ResourceFile::fileChanged()
00200 {
00201 load();
00202 addressBook()->emitAddressBookChanged();
00203 }
00204
00205 QString ResourceFile::identifier() const
00206 {
00207 return fileName();
00208 }
00209
00210 void ResourceFile::removeAddressee( const Addressee &addr )
00211 {
00212 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
00213 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
00214 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) );
00215 }
00216
00217 void ResourceFile::cleanUp()
00218 {
00219 unlock( mFileName );
00220 }
00221
00222 #include "resourcefile.moc"
This file is part of the documentation for kdelibs Version 3.1.0.