KCal Library
resourcelocaldir.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "resourcelocaldir.h"
00023 #include "resourcelocaldir_p.h"
00024 #include "calendarlocal.h"
00025 #include "incidence.h"
00026 #include "event.h"
00027 #include "todo.h"
00028 #include "journal.h"
00029
00030 #include "kresources/configwidget.h"
00031
00032 #include <kdebug.h>
00033 #include <klocale.h>
00034 #include <kconfig.h>
00035 #include <kstandarddirs.h>
00036 #include <kconfiggroup.h>
00037
00038 #include <QtCore/QString>
00039 #include <QtCore/QDir>
00040 #include <QtCore/QFileInfo>
00041
00042 #include <typeinfo>
00043 #include <stdlib.h>
00044
00045 #include "resourcelocaldir.moc"
00046
00047 using namespace KCal;
00048
00049 ResourceLocalDir::ResourceLocalDir()
00050 : ResourceCached(), d( new KCal::ResourceLocalDir::Private )
00051 {
00052 d->init( this );
00053 }
00054
00055 ResourceLocalDir::ResourceLocalDir( const KConfigGroup &group )
00056 : ResourceCached( group ), d( new KCal::ResourceLocalDir::Private )
00057 {
00058 readConfig( group );
00059 d->init( this );
00060 }
00061
00062 ResourceLocalDir::ResourceLocalDir( const QString &dirName )
00063 : ResourceCached(), d( new KCal::ResourceLocalDir::Private( dirName ) )
00064 {
00065 d->init( this );
00066 }
00067
00068 void ResourceLocalDir::readConfig( const KConfigGroup &group )
00069 {
00070 QString url = group.readPathEntry( "CalendarURL", QString() );
00071 d->mURL = KUrl( url );
00072 }
00073
00074 void ResourceLocalDir::writeConfig( KConfigGroup &group )
00075 {
00076 kDebug();
00077
00078 ResourceCalendar::writeConfig( group );
00079
00080 group.writePathEntry( "CalendarURL", d->mURL.prettyUrl() );
00081 }
00082
00083 void ResourceLocalDir::Private::init( ResourceLocalDir *rdir )
00084 {
00085 rdir->setType( "dir" );
00086
00087 rdir->setSavePolicy( SaveDelayed );
00088
00089 rdir->connect( &mDirWatch, SIGNAL( dirty( const QString & ) ),
00090 SLOT( reload( const QString & ) ) );
00091 rdir->connect( &mDirWatch, SIGNAL( created( const QString & ) ),
00092 SLOT( reload( const QString & ) ) );
00093 rdir->connect( &mDirWatch, SIGNAL( deleted( const QString & ) ),
00094 SLOT( reload( const QString & ) ) );
00095
00096 mLock = new KABC::Lock( mURL.path() );
00097
00098 mDirWatch.addDir( mURL.path(), KDirWatch::WatchFiles );
00099 mDirWatch.startScan();
00100 }
00101
00102 ResourceLocalDir::~ResourceLocalDir()
00103 {
00104 close();
00105
00106 delete d->mLock;
00107 delete d;
00108 }
00109
00110 bool ResourceLocalDir::doOpen()
00111 {
00112 QFileInfo dirInfo( d->mURL.path() );
00113 return dirInfo.isDir() && dirInfo.isReadable() &&
00114 ( dirInfo.isWritable() || readOnly() );
00115 }
00116
00117 bool ResourceLocalDir::doLoad( bool )
00118 {
00119 kDebug();
00120
00121 calendar()->close();
00122 QString dirName = d->mURL.path();
00123
00124 if ( !( KStandardDirs::exists( dirName ) || KStandardDirs::exists( dirName + '/' ) ) ) {
00125 kDebug() << "Directory '" << dirName << "' doesn't exist yet. Creating it.";
00126
00127
00128
00129
00130 return KStandardDirs::makeDir( dirName, 0775 );
00131 }
00132
00133
00134 kDebug() << dirName;
00135 QFileInfo dirInfo( dirName );
00136 if ( !( dirInfo.isDir() && dirInfo.isReadable() &&
00137 ( dirInfo.isWritable() || readOnly() ) ) ) {
00138 return false;
00139 }
00140
00141 QDir dir( dirName );
00142 const QStringList entries = dir.entryList( QDir::Files | QDir::Readable );
00143
00144 bool success = true;
00145 for ( int i = 0, count = entries.count(); i < count; ++i ) {
00146 if ( entries[i].contains( QRegExp( "(~|\\.new|\\.tmp)$" ) ) ||
00147 entries[i].startsWith( d->mURL.path() + "/qt_temp." ) ) {
00148 continue;
00149 }
00150
00151 const QString fileName = dirName + '/' + entries[i];
00152 kDebug() << " read '" << fileName << "'";
00153 CalendarLocal cal( calendar()->timeSpec() );
00154 if ( !doFileLoad( cal, fileName ) ) {
00155 success = false;
00156 }
00157 }
00158
00159 return success;
00160 }
00161
00162 bool ResourceLocalDir::doFileLoad( CalendarLocal &cal, const QString &fileName )
00163 {
00164 if ( !cal.load( fileName ) ) {
00165 return false;
00166 }
00167 Incidence::List incidences = cal.rawIncidences();
00168 Incidence::List::ConstIterator it;
00169 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00170 Incidence *i = *it;
00171 if ( i ) {
00172 calendar()->addIncidence( i->clone() );
00173 }
00174 }
00175 return true;
00176 }
00177
00178 bool ResourceLocalDir::doSave( bool syncCache )
00179 {
00180 Q_UNUSED( syncCache );
00181 Incidence::List list;
00182 bool success = true;
00183
00184 list = addedIncidences();
00185 list += changedIncidences();
00186
00187 for ( Incidence::List::iterator it = list.begin(); it != list.end(); ++it ) {
00188 if ( !doSave( *it ) ) {
00189 success = false;
00190 }
00191 }
00192
00193 return success;
00194 }
00195
00196 bool ResourceLocalDir::doSave( bool, Incidence *incidence )
00197 {
00198 if ( d->mDeletedIncidences.contains( incidence ) ) {
00199 d->mDeletedIncidences.removeAll( incidence );
00200 return true;
00201 }
00202
00203 d->mDirWatch.stopScan();
00204
00205 QString fileName = d->mURL.path() + '/' + incidence->uid();
00206 kDebug() << "writing '" << fileName << "'";
00207
00208 CalendarLocal cal( calendar()->timeSpec() );
00209 cal.addIncidence( incidence->clone() );
00210 const bool ret = cal.save( fileName );
00211
00212 d->mDirWatch.startScan();
00213
00214 return ret;
00215 }
00216
00217 KABC::Lock *ResourceLocalDir::lock()
00218 {
00219 return d->mLock;
00220 }
00221
00222 void ResourceLocalDir::reload( const QString &file )
00223 {
00224 kDebug();
00225
00226 if ( !isOpen() ||
00227 file.contains( QRegExp( "(~|\\.new|\\.tmp)$" ) ) ||
00228 file.startsWith( d->mURL.path() + "/qt_temp." ) ) {
00229 return;
00230 }
00231
00232 kDebug() << " File: '" << file << "'";
00233
00234 calendar()->close();
00235 load();
00236
00237 emit resourceChanged( this );
00238 }
00239
00240 bool ResourceLocalDir::deleteEvent( Event *event )
00241 {
00242 kDebug();
00243 if ( d->deleteIncidenceFile( event ) ) {
00244 if ( calendar()->deleteEvent( event ) ) {
00245 d->mDeletedIncidences.append( event );
00246 return true;
00247 } else {
00248 return false;
00249 }
00250 } else {
00251 return false;
00252 }
00253 }
00254
00255 void ResourceLocalDir::deleteAllEvents()
00256 {
00257 calendar()->deleteAllEvents();
00258 }
00259
00260 bool ResourceLocalDir::deleteTodo( Todo *todo )
00261 {
00262 if ( d->deleteIncidenceFile( todo ) ) {
00263 if ( calendar()->deleteTodo( todo ) ) {
00264 d->mDeletedIncidences.append( todo );
00265 return true;
00266 } else {
00267 return false;
00268 }
00269 } else {
00270 return false;
00271 }
00272 }
00273
00274 void ResourceLocalDir::deleteAllTodos()
00275 {
00276 calendar()->deleteAllTodos();
00277 }
00278
00279 bool ResourceLocalDir::deleteJournal( Journal *journal )
00280 {
00281 if ( d->deleteIncidenceFile( journal ) ) {
00282 if ( calendar()->deleteJournal( journal ) ) {
00283 d->mDeletedIncidences.append( journal );
00284 return true;
00285 } else {
00286 return false;
00287 }
00288 } else {
00289 return false;
00290 }
00291 }
00292
00293 void ResourceLocalDir::deleteAllJournals()
00294 {
00295 calendar()->deleteAllJournals();
00296 }
00297
00298 void ResourceLocalDir::dump() const
00299 {
00300 ResourceCalendar::dump();
00301 kDebug() << " Url:" << d->mURL.url();
00302 }
00303
00304 bool ResourceLocalDir::Private::deleteIncidenceFile( Incidence *incidence )
00305 {
00306 QFile file( mURL.path() + '/' + incidence->uid() );
00307 if ( !file.exists() ) {
00308 return true;
00309 }
00310
00311 mDirWatch.stopScan();
00312 bool removed = file.remove();
00313 mDirWatch.startScan();
00314 return removed;
00315 }