00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <signal.h>
00023
#include <sys/types.h>
00024
#include <sys/stat.h>
00025
#include <unistd.h>
00026
00027
#include <qfile.h>
00028
#include <qregexp.h>
00029
#include <qtimer.h>
00030
00031
#include <kapplication.h>
00032
#include <kconfig.h>
00033
#include <kdebug.h>
00034
#include <kio/scheduler.h>
00035
#include <klocale.h>
00036
#include <ksavefile.h>
00037
#include <kstandarddirs.h>
00038
#include <ktempfile.h>
00039
00040
#include "formatfactory.h"
00041
#include "resourcefileconfig.h"
00042
#include "stdaddressbook.h"
00043
#include "lock.h"
00044
00045
#include "resourcefile.h"
00046
00047
using namespace KABC;
00048
00049 ResourceFile::ResourceFile(
const KConfig *config )
00050 : Resource( config ), mFormat( 0 ), mLocalTempFile( 0 ),
00051 mAsynchronous( false )
00052 {
00053
QString fileName, formatName;
00054
00055
if ( config ) {
00056 fileName = config->
readPathEntry(
"FileName", StdAddressBook::fileName() );
00057 formatName = config->
readEntry(
"FileFormat",
"vcard" );
00058 }
else {
00059 fileName =
StdAddressBook::fileName();
00060 formatName =
"vcard";
00061 }
00062
00063 init( fileName, formatName );
00064 }
00065
00066 ResourceFile::ResourceFile(
const QString &fileName,
00067
const QString &formatName )
00068 : Resource( 0 ), mFormat( 0 ), mLocalTempFile( 0 ),
00069 mAsynchronous( false )
00070 {
00071 init( fileName, formatName );
00072 }
00073
00074
void ResourceFile::init(
const QString &fileName,
const QString &formatName )
00075 {
00076 mFormatName = formatName;
00077
00078
FormatFactory *factory =
FormatFactory::self();
00079 mFormat = factory->
format( mFormatName );
00080
00081
if ( !mFormat ) {
00082 mFormatName =
"vcard";
00083 mFormat = factory->
format( mFormatName );
00084 }
00085
00086 connect( &mDirWatch, SIGNAL( dirty(
const QString&) ), SLOT( fileChanged() ) );
00087 connect( &mDirWatch, SIGNAL( created(
const QString&) ), SLOT( fileChanged() ) );
00088 connect( &mDirWatch, SIGNAL( deleted(
const QString&) ), SLOT( fileChanged() ) );
00089
00090
setFileName( fileName );
00091
00092 mLock = 0;
00093 }
00094
00095 ResourceFile::~ResourceFile()
00096 {
00097
delete mFormat;
00098 mFormat = 0;
00099
delete mLocalTempFile;
00100 mLocalTempFile = 0;
00101 }
00102
00103 void ResourceFile::writeConfig(
KConfig *config )
00104 {
00105 Resource::writeConfig( config );
00106
00107
if ( mFileName ==
StdAddressBook::fileName() )
00108 config->
deleteEntry(
"FileName" );
00109
else
00110 config->
writePathEntry(
"FileName", mFileName );
00111
00112 config->
writeEntry(
"FileFormat", mFormatName );
00113 }
00114
00115 Ticket *
ResourceFile::requestSaveTicket()
00116 {
00117
kdDebug(5700) <<
"ResourceFile::requestSaveTicket()" <<
endl;
00118
00119
if ( !addressBook() )
return 0;
00120
00121
delete mLock;
00122 mLock =
new Lock( mFileName );
00123
00124
if ( mLock->
lock() ) {
00125 addressBook()->emitAddressBookLocked();
00126 }
else {
00127 addressBook()->error( mLock->
error() );
00128
kdDebug(5700) <<
"ResourceFile::requestSaveTicket(): Unable to lock file '"
00129 << mFileName <<
"': " << mLock->
error() <<
endl;
00130
return 0;
00131 }
00132
00133
return createTicket(
this );
00134 }
00135
00136
void ResourceFile::releaseSaveTicket(
Ticket *ticket )
00137 {
00138
delete ticket;
00139
00140
delete mLock;
00141 mLock = 0;
00142
00143 addressBook()->emitAddressBookUnlocked();
00144 }
00145
00146 bool ResourceFile::doOpen()
00147 {
00148
QFile file( mFileName );
00149
00150
if ( !file.exists() ) {
00151
00152
bool ok = file.open( IO_WriteOnly );
00153
if ( ok )
00154 file.close();
00155
00156
return ok;
00157 }
else {
00158
if ( !file.open( IO_ReadWrite ) )
00159
return false;
00160
00161
if ( file.size() == 0 ) {
00162 file.close();
00163
return true;
00164 }
00165
00166
bool ok = mFormat->
checkFormat( &file );
00167 file.close();
00168
00169
return ok;
00170 }
00171 }
00172
00173 void ResourceFile::doClose()
00174 {
00175 }
00176
00177 bool ResourceFile::load()
00178 {
00179
kdDebug(5700) <<
"ResourceFile::load(): '" << mFileName <<
"'" <<
endl;
00180
00181 mAsynchronous =
false;
00182
00183
QFile file( mFileName );
00184
if ( !file.open( IO_ReadOnly ) ) {
00185 addressBook()->error( i18n(
"Unable to open file '%1'." ).arg( mFileName ) );
00186
return false;
00187 }
00188
00189
return mFormat->
loadAll( addressBook(),
this, &file );
00190 }
00191
00192
bool ResourceFile::asyncLoad()
00193 {
00194 mAsynchronous =
true;
00195
00196
if ( mLocalTempFile ) {
00197
kdDebug(5700) <<
"stale temp file detected " << mLocalTempFile->
name() <<
endl;
00198
delete mLocalTempFile;
00199 }
00200
00201 mLocalTempFile =
new KTempFile();
00202 mLocalTempFile->
setAutoDelete(
true );
00203 mTempFile = mLocalTempFile->
name();
00204
00205
KURL dest, src;
00206 dest.
setPath( mTempFile );
00207 src.
setPath( mFileName );
00208
00209 KIO::Scheduler::checkSlaveOnHold(
true );
00210 KIO::Job * job = KIO::file_copy( src, dest, -1,
true,
false,
false );
00211 connect( job, SIGNAL( result( KIO::Job* ) ),
00212
this, SLOT( downloadFinished( KIO::Job* ) ) );
00213
00214
return true;
00215 }
00216
00217 bool ResourceFile::save(
Ticket * )
00218 {
00219
kdDebug(5700) <<
"ResourceFile::save()" <<
endl;
00220
00221
00222
QString extension =
"_" + QString::number( QDate::currentDate().dayOfWeek() );
00223 (
void)
KSaveFile::backupFile( mFileName, QString::null ,
00224 extension );
00225
00226 mDirWatch.stopScan();
00227
KSaveFile saveFile( mFileName );
00228
bool ok =
false;
00229
if ( saveFile.
status() == 0 && saveFile.
file() )
00230 {
00231 mFormat->
saveAll( addressBook(),
this, saveFile.
file() );
00232 ok = saveFile.
close();
00233 }
00234
00235
if ( !ok )
00236 addressBook()->error( i18n(
"Unable to save file '%1'." ).arg( mFileName ) );
00237 mDirWatch.startScan();
00238
00239
return ok;
00240 }
00241
00242
bool ResourceFile::asyncSave(
Ticket * )
00243 {
00244
QFile file( mTempFile );
00245
00246
if ( !file.open( IO_WriteOnly ) ) {
00247 emit savingError(
this, i18n(
"Unable to open file '%1'." ).arg( mTempFile ) );
00248
return false;
00249 }
00250
00251 mDirWatch.stopScan();
00252 mFormat->
saveAll( addressBook(),
this, &file );
00253 file.close();
00254
00255
KURL src, dest;
00256 src.
setPath( mTempFile );
00257 dest.
setPath( mFileName );
00258
00259 KIO::Scheduler::checkSlaveOnHold(
true );
00260 KIO::Job * job = KIO::file_copy( src, dest, -1,
true,
false,
false );
00261 connect( job, SIGNAL( result( KIO::Job* ) ),
00262
this, SLOT( uploadFinished( KIO::Job* ) ) );
00263
00264
return true;
00265 }
00266
00267 void ResourceFile::setFileName(
const QString &fileName )
00268 {
00269 mDirWatch.stopScan();
00270
if ( mDirWatch.contains( mFileName ) )
00271 mDirWatch.removeFile( mFileName );
00272
00273 mFileName = fileName;
00274
00275 mDirWatch.addFile( mFileName );
00276 mDirWatch.startScan();
00277 }
00278
00279 QString ResourceFile::fileName()
const
00280
{
00281
return mFileName;
00282 }
00283
00284 void ResourceFile::setFormat(
const QString &format )
00285 {
00286 mFormatName = format;
00287
delete mFormat;
00288
00289
FormatFactory *factory =
FormatFactory::self();
00290 mFormat = factory->
format( mFormatName );
00291 }
00292
00293 QString ResourceFile::format()
const
00294
{
00295
return mFormatName;
00296 }
00297
00298
void ResourceFile::fileChanged()
00299 {
00300
if ( !addressBook() )
00301
return;
00302
00303 clear();
00304
if ( mAsynchronous )
00305 asyncLoad();
00306
else {
00307
load();
00308
kdDebug() <<
"addressBookChanged() " <<
endl;
00309 addressBook()->emitAddressBookChanged();
00310 }
00311 }
00312
00313 void ResourceFile::removeAddressee(
const Addressee &addr )
00314 {
00315 QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/photos/" ) + addr.
uid() ) );
00316 QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/logos/" ) + addr.
uid() ) );
00317 QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/sounds/" ) + addr.
uid() ) );
00318
00319 mAddrMap.erase( addr.
uid() );
00320 }
00321
00322
void ResourceFile::downloadFinished( KIO::Job* )
00323 {
00324
if ( !mLocalTempFile )
00325 emit loadingError(
this, i18n(
"Download failed in some way!" ) );
00326
00327
QFile file( mTempFile );
00328
if ( !file.open( IO_ReadOnly ) ) {
00329 emit loadingError(
this, i18n(
"Unable to open file '%1'." ).arg( mTempFile ) );
00330
return;
00331 }
00332
00333
if ( !mFormat->
loadAll( addressBook(),
this, &file ) )
00334 emit loadingError(
this, i18n(
"Problems during parsing file '%1'." ).arg( mTempFile ) );
00335
else
00336 emit loadingFinished(
this );
00337 }
00338
00339
void ResourceFile::uploadFinished( KIO::Job *job )
00340 {
00341
if ( job->error() )
00342 emit savingError(
this, job->errorString() );
00343
else
00344 emit savingFinished(
this );
00345 mDirWatch.startScan();
00346 }
00347
00348
#include "resourcefile.moc"