00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <errno.h>
00022
#include <signal.h>
00023
#include <sys/types.h>
00024
#include <sys/stat.h>
00025
#include <unistd.h>
00026
00027
#include <qregexp.h>
00028
#include <qtimer.h>
00029
#include <qwidget.h>
00030
00031
#include <kapplication.h>
00032
#include <kconfig.h>
00033
#include <kdebug.h>
00034
#include <kgenericfactory.h>
00035
#include <kglobal.h>
00036
#include <klocale.h>
00037
#include <kstandarddirs.h>
00038
#include <kurlrequester.h>
00039
00040
#include "addressbook.h"
00041
#include "formatfactory.h"
00042
#include "resourcedirconfig.h"
00043
#include "stdaddressbook.h"
00044
#include "lock.h"
00045
00046
#include "resourcedir.h"
00047
00048
using namespace KABC;
00049
00050
extern "C"
00051 {
00052
void *init_kabc_dir()
00053 {
00054
return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>();
00055 }
00056 }
00057
00058
00059 ResourceDir::ResourceDir(
const KConfig *config )
00060 : Resource( config ), mAsynchronous( false )
00061 {
00062
if ( config ) {
00063 init( config->
readPathEntry(
"FilePath" ), config->
readEntry(
"FileFormat" ) );
00064 }
else {
00065 init( StdAddressBook::directoryName(),
"vcard" );
00066 }
00067 }
00068
00069 ResourceDir::ResourceDir(
const QString &path,
const QString &format )
00070 : Resource( 0 ), mAsynchronous( false )
00071 {
00072 init( path, format );
00073 }
00074
00075
void ResourceDir::init(
const QString &path,
const QString &format )
00076 {
00077 mFormatName = format;
00078
00079
FormatFactory *factory =
FormatFactory::self();
00080 mFormat = factory->
format( mFormatName );
00081
00082
if ( !mFormat ) {
00083 mFormatName =
"vcard";
00084 mFormat = factory->
format( mFormatName );
00085 }
00086
00087 mLock = 0;
00088
00089 connect( &mDirWatch, SIGNAL( dirty(
const QString&) ), SLOT( pathChanged() ) );
00090 connect( &mDirWatch, SIGNAL( created(
const QString&) ), SLOT( pathChanged() ) );
00091 connect( &mDirWatch, SIGNAL( deleted(
const QString&) ), SLOT( pathChanged() ) );
00092
00093 setPath( path );
00094 }
00095
00096 ResourceDir::~ResourceDir()
00097 {
00098
delete mFormat;
00099 mFormat = 0;
00100 }
00101
00102
void ResourceDir::writeConfig(
KConfig *config )
00103 {
00104 Resource::writeConfig( config );
00105
00106 config->
writePathEntry(
"FilePath", mPath );
00107 config->
writeEntry(
"FileFormat", mFormatName );
00108 }
00109
00110
Ticket *ResourceDir::requestSaveTicket()
00111 {
00112
kdDebug(5700) <<
"ResourceDir::requestSaveTicket()" <<
endl;
00113
00114
if ( !addressBook() )
return 0;
00115
00116
delete mLock;
00117 mLock =
new Lock( mPath );
00118
00119
if ( mLock->lock() ) {
00120 addressBook()->emitAddressBookLocked();
00121 }
else {
00122 addressBook()->error( mLock->error() );
00123
kdDebug(5700) <<
"ResourceFile::requestSaveTicket(): Unable to lock path '"
00124 << mPath <<
"': " << mLock->error() <<
endl;
00125
return 0;
00126 }
00127
00128
return createTicket(
this );
00129 }
00130
00131
void ResourceDir::releaseSaveTicket(
Ticket *ticket )
00132 {
00133
delete ticket;
00134
00135
delete mLock;
00136 mLock = 0;
00137 }
00138
00139
bool ResourceDir::doOpen()
00140 {
00141
QDir dir( mPath );
00142
if ( !dir.
exists() ) {
00143
return dir.
mkdir( dir.
path() );
00144 }
else {
00145
QString testName = dir.
entryList( QDir::Files )[0];
00146
if ( testName.
isNull() || testName.
isEmpty() )
00147
return true;
00148
00149
QFile file( mPath +
"/" + testName );
00150
if ( file.
open( IO_ReadOnly ) )
00151
return true;
00152
00153
if ( file.
size() == 0 )
00154
return true;
00155
00156
bool ok = mFormat->checkFormat( &file );
00157 file.
close();
00158
return ok;
00159 }
00160 }
00161
00162
void ResourceDir::doClose()
00163 {
00164 }
00165
00166
bool ResourceDir::load()
00167 {
00168
kdDebug(5700) <<
"ResourceDir::load(): '" << mPath <<
"'" <<
endl;
00169
00170 mAsynchronous =
false;
00171
00172
QDir dir( mPath );
00173
QStringList files = dir.
entryList( QDir::Files );
00174
00175 QStringList::Iterator it;
00176
bool ok =
true;
00177
for ( it = files.begin(); it != files.end(); ++it ) {
00178
QFile file( mPath +
"/" + (*it) );
00179
00180
if ( !file.
open( IO_ReadOnly ) ) {
00181 addressBook()->error( i18n(
"Unable to open file '%1' for reading" ).arg( file.
name() ) );
00182 ok =
false;
00183
continue;
00184 }
00185
00186
if ( !mFormat->loadAll( addressBook(),
this, &file ) )
00187 ok =
false;
00188
00189 file.
close();
00190 }
00191
00192
return ok;
00193 }
00194
00195
bool ResourceDir::asyncLoad()
00196 {
00197 mAsynchronous =
true;
00198
00199
bool ok = load();
00200
if ( !ok )
00201 emit loadingError(
this, i18n(
"Loading resource '%1' failed!" )
00202 .arg( resourceName() ) );
00203
else
00204 emit loadingFinished(
this );
00205
00206
return ok;
00207 }
00208
00209
bool ResourceDir::save(
Ticket * )
00210 {
00211
kdDebug(5700) <<
"ResourceDir::save(): '" << mPath <<
"'" <<
endl;
00212
00213 Addressee::Map::Iterator it;
00214
bool ok =
true;
00215
00216
for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) {
00217
if ( !it.data().changed() )
00218
continue;
00219
00220
QFile file( mPath +
"/" + (*it).uid() );
00221
if ( !file.
open( IO_WriteOnly ) ) {
00222 addressBook()->error( i18n(
"Unable to open file '%1' for writing" ).arg( file.
name() ) );
00223
continue;
00224 }
00225
00226 mFormat->save( *it, &file );
00227
00228
00229 (*it).setChanged(
false );
00230
00231 file.
close();
00232 }
00233
00234
return ok;
00235 }
00236
00237
bool ResourceDir::asyncSave(
Ticket *ticket )
00238 {
00239
bool ok =
save( ticket );
00240
if ( !ok )
00241 emit savingError(
this, i18n(
"Saving resource '%1' failed!" )
00242 .arg( resourceName() ) );
00243
else
00244 emit savingFinished(
this );
00245
00246
return ok;
00247 }
00248
00249
void ResourceDir::setPath(
const QString &path )
00250 {
00251 mDirWatch.stopScan();
00252
if ( mDirWatch.contains( mPath ) )
00253 mDirWatch.removeDir( mPath );
00254
00255 mPath = path;
00256 mDirWatch.addDir( mPath,
true );
00257 mDirWatch.startScan();
00258 }
00259
00260
QString ResourceDir::path()
const
00261
{
00262
return mPath;
00263 }
00264
00265
void ResourceDir::setFormat(
const QString &format )
00266 {
00267 mFormatName = format;
00268
00269
if ( mFormat )
00270
delete mFormat;
00271
00272
FormatFactory *factory =
FormatFactory::self();
00273 mFormat = factory->
format( mFormatName );
00274 }
00275
00276
QString ResourceDir::format()
const
00277
{
00278
return mFormatName;
00279 }
00280
00281
void ResourceDir::pathChanged()
00282 {
00283
if ( !addressBook() )
00284
return;
00285
00286
clear();
00287
if ( mAsynchronous )
00288 asyncLoad();
00289
else {
00290 load();
00291 addressBook()->emitAddressBookChanged();
00292 }
00293 }
00294
00295
void ResourceDir::removeAddressee(
const Addressee& addr )
00296 {
00297
QFile::remove( mPath +
"/" + addr.
uid() );
00298 mAddrMap.erase( addr.
uid() );
00299 }
00300
00301
#include "resourcedir.moc"