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 }
00100
00101 void ResourceFile::writeConfig(
KConfig *config )
00102 {
00103 Resource::writeConfig( config );
00104
00105 config->
writePathEntry(
"FileName", mFileName );
00106 config->
writeEntry(
"FileFormat", mFormatName );
00107 }
00108
00109 Ticket *
ResourceFile::requestSaveTicket()
00110 {
00111
kdDebug(5700) <<
"ResourceFile::requestSaveTicket()" <<
endl;
00112
00113
if ( !addressBook() )
return 0;
00114
00115
delete mLock;
00116 mLock =
new Lock( mFileName );
00117
00118
if ( mLock->
lock() ) {
00119 addressBook()->emitAddressBookLocked();
00120 }
else {
00121 addressBook()->error( mLock->
error() );
00122
kdDebug(5700) <<
"ResourceFile::requestSaveTicket(): Unable to lock file '"
00123 << mFileName <<
"': " << mLock->
error() <<
endl;
00124
return 0;
00125 }
00126
00127
return createTicket(
this );
00128 }
00129
00130
void ResourceFile::releaseSaveTicket(
Ticket *ticket )
00131 {
00132
delete ticket;
00133
00134
delete mLock;
00135 mLock = 0;
00136
00137 addressBook()->emitAddressBookUnlocked();
00138 }
00139
00140 bool ResourceFile::doOpen()
00141 {
00142
QFile file( mFileName );
00143
00144
if ( !file.
exists() ) {
00145
00146
bool ok = file.
open( IO_WriteOnly );
00147
if ( ok )
00148 file.
close();
00149
00150
return ok;
00151 }
else {
00152
if ( !file.
open( IO_ReadWrite ) )
00153
return false;
00154
00155
if ( file.
size() == 0 ) {
00156 file.
close();
00157
return true;
00158 }
00159
00160
bool ok = mFormat->
checkFormat( &file );
00161 file.
close();
00162
00163
return ok;
00164 }
00165 }
00166
00167 void ResourceFile::doClose()
00168 {
00169 }
00170
00171 bool ResourceFile::load()
00172 {
00173
kdDebug(5700) <<
"ResourceFile::load(): '" << mFileName <<
"'" <<
endl;
00174
00175 mAsynchronous =
false;
00176
00177
QFile file( mFileName );
00178
if ( !file.
open( IO_ReadOnly ) ) {
00179 addressBook()->error( i18n(
"Unable to open file '%1'." ).arg( mFileName ) );
00180
return false;
00181 }
00182
00183
return mFormat->
loadAll( addressBook(),
this, &file );
00184 }
00185
00186
bool ResourceFile::asyncLoad()
00187 {
00188 mAsynchronous =
true;
00189
00190
if ( mLocalTempFile ) {
00191
kdDebug(5700) <<
"stale temp file dedected " << mLocalTempFile->
name() <<
endl;
00192 mLocalTempFile->
setAutoDelete(
true );
00193
delete mLocalTempFile;
00194 }
00195
00196 mLocalTempFile =
new KTempFile();
00197 mTempFile = mLocalTempFile->
name();
00198
00199
KURL dest, src;
00200 dest.
setPath( mTempFile );
00201 src.
setPath( mFileName );
00202
00203 KIO::Scheduler::checkSlaveOnHold(
true );
00204 KIO::Job * job = KIO::file_copy( src, dest, -1,
true,
false,
false );
00205 connect( job, SIGNAL( result( KIO::Job* ) ),
00206
this, SLOT( downloadFinished( KIO::Job* ) ) );
00207
00208
return true;
00209 }
00210
00211 bool ResourceFile::save(
Ticket * )
00212 {
00213
kdDebug(5700) <<
"ResourceFile::save()" <<
endl;
00214
00215
00216
QString extension =
"_" + QString::number( QDate::currentDate().dayOfWeek() );
00217 (
void) KSaveFile::backupFile( mFileName, QString::null ,
00218 extension );
00219
00220
KSaveFile saveFile( mFileName );
00221
bool ok =
false;
00222
if ( saveFile.
status() == 0 && saveFile.
file() )
00223 {
00224 mFormat->
saveAll( addressBook(),
this, saveFile.
file() );
00225 ok = saveFile.
close();
00226 }
00227
00228
if ( !ok )
00229 addressBook()->error( i18n(
"Unable to save file '%1'." ).arg( mFileName ) );
00230
00231
return ok;
00232 }
00233
00234
bool ResourceFile::asyncSave(
Ticket * )
00235 {
00236
QFile file( mTempFile );
00237
00238
if ( !file.
open( IO_WriteOnly ) ) {
00239 emit savingError(
this, i18n(
"Unable to open file '%1'." ).arg( mTempFile ) );
00240
return false;
00241 }
00242
00243 mFormat->
saveAll( addressBook(),
this, &file );
00244 file.
close();
00245
00246
KURL src, dest;
00247 src.
setPath( mTempFile );
00248 dest.
setPath( mFileName );
00249
00250 KIO::Scheduler::checkSlaveOnHold(
true );
00251 KIO::Job * job = KIO::file_copy( src, dest, -1,
true,
false,
false );
00252 connect( job, SIGNAL( result( KIO::Job* ) ),
00253
this, SLOT( uploadFinished( KIO::Job* ) ) );
00254
00255
return true;
00256 }
00257
00258 void ResourceFile::setFileName(
const QString &fileName )
00259 {
00260 mDirWatch.stopScan();
00261
if ( mDirWatch.contains( mFileName ) )
00262 mDirWatch.removeFile( mFileName );
00263
00264 mFileName = fileName;
00265
00266 mDirWatch.addFile( mFileName );
00267 mDirWatch.startScan();
00268 }
00269
00270 QString ResourceFile::fileName()
const
00271
{
00272
return mFileName;
00273 }
00274
00275 void ResourceFile::setFormat(
const QString &format )
00276 {
00277 mFormatName = format;
00278
delete mFormat;
00279
00280
FormatFactory *factory =
FormatFactory::self();
00281 mFormat = factory->
format( mFormatName );
00282 }
00283
00284 QString ResourceFile::format()
const
00285
{
00286
return mFormatName;
00287 }
00288
00289
void ResourceFile::fileChanged()
00290 {
00291
if ( !addressBook() )
00292
return;
00293
00294 clear();
00295
if ( mAsynchronous )
00296 asyncLoad();
00297
else {
00298
load();
00299 addressBook()->emitAddressBookChanged();
00300 }
00301 }
00302
00303 void ResourceFile::removeAddressee(
const Addressee &addr )
00304 {
00305
QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/photos/" ) + addr.
uid() ) );
00306
QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/logos/" ) + addr.
uid() ) );
00307
QFile::remove( QFile::encodeName(
locateLocal(
"data",
"kabc/sounds/" ) + addr.
uid() ) );
00308
00309 mAddrMap.erase( addr.
uid() );
00310 }
00311
00312
void ResourceFile::downloadFinished( KIO::Job* )
00313 {
00314
if ( !mLocalTempFile )
00315 emit loadingError(
this, i18n(
"Download failed in some way!" ) );
00316
00317
QFile file( mTempFile );
00318
if ( !file.
open( IO_ReadOnly ) ) {
00319 emit loadingError(
this, i18n(
"Unable to open file '%1'." ).arg( mTempFile ) );
00320
return;
00321 }
00322
00323
if ( !mFormat->
loadAll( addressBook(),
this, &file ) )
00324 emit loadingError(
this, i18n(
"Problems during parsing file '%1'." ).arg( mTempFile ) );
00325
else
00326 emit loadingFinished(
this );
00327 }
00328
00329
void ResourceFile::uploadFinished( KIO::Job *job )
00330 {
00331
if ( job->error() )
00332 emit savingError(
this, job->errorString() );
00333
else
00334 emit savingFinished(
this );
00335 }
00336
00337
#include "resourcefile.moc"