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", StdAddressBook::directoryName() ),
00064 config->
readEntry(
"FileFormat",
"vcard" ) );
00065 }
else {
00066 init( StdAddressBook::directoryName(),
"vcard" );
00067 }
00068 }
00069
00070 ResourceDir::ResourceDir(
const QString &path,
const QString &format )
00071 : Resource( 0 ), mAsynchronous( false )
00072 {
00073 init( path, format );
00074 }
00075
00076
void ResourceDir::init(
const QString &path,
const QString &format )
00077 {
00078 mFormatName = format;
00079
00080
FormatFactory *factory =
FormatFactory::self();
00081 mFormat = factory->
format( mFormatName );
00082
00083
if ( !mFormat ) {
00084 mFormatName =
"vcard";
00085 mFormat = factory->
format( mFormatName );
00086 }
00087
00088 mLock = 0;
00089
00090 connect( &mDirWatch, SIGNAL( dirty(
const QString&) ), SLOT( pathChanged() ) );
00091 connect( &mDirWatch, SIGNAL( created(
const QString&) ), SLOT( pathChanged() ) );
00092 connect( &mDirWatch, SIGNAL( deleted(
const QString&) ), SLOT( pathChanged() ) );
00093
00094 setPath( path );
00095 }
00096
00097 ResourceDir::~ResourceDir()
00098 {
00099
delete mFormat;
00100 mFormat = 0;
00101 }
00102
00103
void ResourceDir::writeConfig(
KConfig *config )
00104 {
00105 Resource::writeConfig( config );
00106
00107
if ( mPath ==
StdAddressBook::directoryName() )
00108 config->
deleteEntry(
"FilePath" );
00109
else
00110 config->
writePathEntry(
"FilePath", mPath );
00111
00112 config->
writeEntry(
"FileFormat", mFormatName );
00113 }
00114
00115
Ticket *ResourceDir::requestSaveTicket()
00116 {
00117
kdDebug(5700) <<
"ResourceDir::requestSaveTicket()" <<
endl;
00118
00119
if ( !addressBook() )
return 0;
00120
00121
delete mLock;
00122 mLock =
new Lock( mPath );
00123
00124
if ( mLock->lock() ) {
00125 addressBook()->emitAddressBookLocked();
00126 }
else {
00127 addressBook()->error( mLock->error() );
00128
kdDebug(5700) <<
"ResourceFile::requestSaveTicket(): Unable to lock path '"
00129 << mPath <<
"': " << mLock->error() <<
endl;
00130
return 0;
00131 }
00132
00133
return createTicket(
this );
00134 }
00135
00136
void ResourceDir::releaseSaveTicket(
Ticket *ticket )
00137 {
00138
delete ticket;
00139
00140
delete mLock;
00141 mLock = 0;
00142 }
00143
00144
bool ResourceDir::doOpen()
00145 {
00146
QDir dir( mPath );
00147
if ( !dir.exists() ) {
00148
return dir.mkdir( dir.path() );
00149 }
else {
00150
QString testName = dir.entryList( QDir::Files )[0];
00151
if ( testName.isNull() || testName.isEmpty() )
00152
return true;
00153
00154
QFile file( mPath +
"/" + testName );
00155
if ( file.open( IO_ReadOnly ) )
00156
return true;
00157
00158
if ( file.size() == 0 )
00159
return true;
00160
00161
bool ok = mFormat->checkFormat( &file );
00162 file.close();
00163
return ok;
00164 }
00165 }
00166
00167
void ResourceDir::doClose()
00168 {
00169 }
00170
00171
bool ResourceDir::load()
00172 {
00173
kdDebug(5700) <<
"ResourceDir::load(): '" << mPath <<
"'" <<
endl;
00174
00175 mAsynchronous =
false;
00176
00177
QDir dir( mPath );
00178
QStringList files = dir.entryList( QDir::Files );
00179
00180 QStringList::Iterator it;
00181
bool ok =
true;
00182
for ( it = files.begin(); it != files.end(); ++it ) {
00183
QFile file( mPath +
"/" + (*it) );
00184
00185
if ( !file.open( IO_ReadOnly ) ) {
00186 addressBook()->error( i18n(
"Unable to open file '%1' for reading" ).arg( file.name() ) );
00187 ok =
false;
00188
continue;
00189 }
00190
00191
if ( !mFormat->loadAll( addressBook(),
this, &file ) )
00192 ok =
false;
00193
00194 file.close();
00195 }
00196
00197
return ok;
00198 }
00199
00200
bool ResourceDir::asyncLoad()
00201 {
00202 mAsynchronous =
true;
00203
00204
bool ok = load();
00205
if ( !ok )
00206 emit loadingError(
this, i18n(
"Loading resource '%1' failed!" )
00207 .arg( resourceName() ) );
00208
else
00209 emit loadingFinished(
this );
00210
00211
return ok;
00212 }
00213
00214
bool ResourceDir::save(
Ticket * )
00215 {
00216
kdDebug(5700) <<
"ResourceDir::save(): '" << mPath <<
"'" <<
endl;
00217
00218 Addressee::Map::Iterator it;
00219
bool ok =
true;
00220
00221
for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) {
00222
if ( !it.data().changed() )
00223
continue;
00224
00225
QFile file( mPath +
"/" + (*it).uid() );
00226
if ( !file.open( IO_WriteOnly ) ) {
00227 addressBook()->error( i18n(
"Unable to open file '%1' for writing" ).arg( file.name() ) );
00228
continue;
00229 }
00230
00231 mFormat->save( *it, &file );
00232
00233
00234 (*it).setChanged(
false );
00235
00236 file.close();
00237 }
00238
00239
return ok;
00240 }
00241
00242
bool ResourceDir::asyncSave(
Ticket *ticket )
00243 {
00244
bool ok =
save( ticket );
00245
if ( !ok )
00246 emit savingError(
this, i18n(
"Saving resource '%1' failed!" )
00247 .arg( resourceName() ) );
00248
else
00249 emit savingFinished(
this );
00250
00251
return ok;
00252 }
00253
00254
void ResourceDir::setPath(
const QString &path )
00255 {
00256 mDirWatch.stopScan();
00257
if ( mDirWatch.contains( mPath ) )
00258 mDirWatch.removeDir( mPath );
00259
00260 mPath = path;
00261 mDirWatch.addDir( mPath,
true );
00262 mDirWatch.startScan();
00263 }
00264
00265
QString ResourceDir::path()
const
00266
{
00267
return mPath;
00268 }
00269
00270
void ResourceDir::setFormat(
const QString &format )
00271 {
00272 mFormatName = format;
00273
00274
if ( mFormat )
00275
delete mFormat;
00276
00277
FormatFactory *factory =
FormatFactory::self();
00278 mFormat = factory->
format( mFormatName );
00279 }
00280
00281
QString ResourceDir::format()
const
00282
{
00283
return mFormatName;
00284 }
00285
00286
void ResourceDir::pathChanged()
00287 {
00288
if ( !addressBook() )
00289
return;
00290
00291
clear();
00292
if ( mAsynchronous )
00293 asyncLoad();
00294
else {
00295 load();
00296 addressBook()->emitAddressBookChanged();
00297 }
00298 }
00299
00300
void ResourceDir::removeAddressee(
const Addressee& addr )
00301 {
00302 QFile::remove( mPath +
"/" + addr.
uid() );
00303 mAddrMap.erase( addr.
uid() );
00304 }
00305
00306
#include "resourcedir.moc"