resourcelocaldir.cpp
00001 /* 00002 This file is part of libkcal. 00003 00004 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include <typeinfo> 00023 #include <stdlib.h> 00024 00025 #include <tqdatetime.h> 00026 #include <tqfileinfo.h> 00027 #include <tqstring.h> 00028 #include <tqptrlist.h> 00029 00030 #include <kdebug.h> 00031 #include <tdelocale.h> 00032 #include <kurl.h> 00033 #include <tdeconfig.h> 00034 #include <kstandarddirs.h> 00035 00036 #include "vcaldrag.h" 00037 #include "vcalformat.h" 00038 #include "icalformat.h" 00039 #include "exceptions.h" 00040 #include "calendarlocal.h" 00041 #include "incidence.h" 00042 #include "event.h" 00043 #include "todo.h" 00044 #include "journal.h" 00045 #include "filestorage.h" 00046 00047 #include <tderesources/configwidget.h> 00048 00049 #include "resourcelocaldirconfig.h" 00050 00051 #include "resourcelocaldir.h" 00052 00053 using namespace KCal; 00054 00055 ResourceLocalDir::ResourceLocalDir( const TDEConfig* config ) 00056 : ResourceCached( config ), mLock( 0 ) 00057 { 00058 if ( config ) { 00059 readConfig( config ); 00060 } 00061 00062 init(); 00063 } 00064 00065 ResourceLocalDir::ResourceLocalDir( const TQString& dirName ) 00066 : ResourceCached( 0 ) 00067 { 00068 mURL = KURL( dirName ); 00069 00070 init(); 00071 } 00072 00073 00074 void ResourceLocalDir::readConfig( const TDEConfig *config ) 00075 { 00076 TQString url = config->readPathEntry( "CalendarURL" ); 00077 mURL = KURL( url ); 00078 } 00079 00080 void ResourceLocalDir::writeConfig( TDEConfig *config ) 00081 { 00082 kdDebug(5800) << "ResourceLocalDir::writeConfig()" << endl; 00083 00084 ResourceCalendar::writeConfig( config ); 00085 00086 config->writePathEntry( "CalendarURL", mURL.prettyURL() ); 00087 } 00088 00089 void ResourceLocalDir::init() 00090 { 00091 setType( "dir" ); 00092 00093 setSavePolicy( SaveDelayed ); 00094 00095 connect( &mDirWatch, TQT_SIGNAL( dirty( const TQString & ) ), 00096 TQT_SLOT( reload( const TQString & ) ) ); 00097 connect( &mDirWatch, TQT_SIGNAL( created( const TQString & ) ), 00098 TQT_SLOT( reload( const TQString & ) ) ); 00099 connect( &mDirWatch, TQT_SIGNAL( deleted( const TQString & ) ), 00100 TQT_SLOT( reload( const TQString & ) ) ); 00101 00102 mLock = new TDEABC::Lock( mURL.path() ); 00103 00104 mDirWatch.addDir( mURL.path(), true ); 00105 mDirWatch.startScan(); 00106 } 00107 00108 00109 ResourceLocalDir::~ResourceLocalDir() 00110 { 00111 close(); 00112 00113 delete mLock; 00114 } 00115 00116 bool ResourceLocalDir::doOpen() 00117 { 00118 TQFileInfo dirInfo( mURL.path() ); 00119 return dirInfo.isDir() && dirInfo.isReadable() && 00120 ( dirInfo.isWritable() || readOnly() ); 00121 } 00122 00123 bool ResourceLocalDir::doLoad() 00124 { 00125 kdDebug(5800) << "ResourceLocalDir::load()" << endl; 00126 00127 mCalendar.close(); 00128 TQString dirName = mURL.path(); 00129 00130 if ( !( TDEStandardDirs::exists( dirName ) || TDEStandardDirs::exists( dirName + "/") ) ) { 00131 kdDebug(5800) << "ResourceLocalDir::load(): Directory '" << dirName 00132 << "' doesn't exist yet. Creating it..." << endl; 00133 // Create the directory. Use 0775 to allow group-writable if the umask 00134 // allows it (permissions will be 0775 & ~umask). This is desired e.g. for 00135 // group-shared directories! 00136 return TDEStandardDirs::makeDir( dirName, 0775 ); 00137 } 00138 00139 // The directory exists. Now try to open (the files in) it. 00140 kdDebug(5800) << "ResourceLocalDir::load(): '" << dirName << "'" << endl; 00141 TQFileInfo dirInfo( dirName ); 00142 if ( !( dirInfo.isDir() && dirInfo.isReadable() && 00143 ( dirInfo.isWritable() || readOnly() ) ) ) 00144 return false; 00145 00146 TQDir dir( dirName ); 00147 TQStringList entries = dir.entryList( TQDir::Files | TQDir::Readable ); 00148 00149 bool success = true; 00150 TQStringList::ConstIterator it; 00151 for( it = entries.constBegin(); it != entries.constEnd(); ++it ) { 00152 if ( (*it).endsWith( "~" ) ) // is backup file, ignore it 00153 continue; 00154 00155 TQString fileName = dirName + "/" + *it; 00156 kdDebug(5800) << " read '" << fileName << "'" << endl; 00157 CalendarLocal cal( mCalendar.timeZoneId() ); 00158 if ( !doFileLoad( cal, fileName ) ) { 00159 success = false; 00160 } 00161 } 00162 00163 return success; 00164 } 00165 00166 bool ResourceLocalDir::doFileLoad( CalendarLocal &cal, const TQString &fileName ) 00167 { 00168 if ( !cal.load( fileName ) ) 00169 return false; 00170 Incidence::List incidences = cal.rawIncidences(); 00171 Incidence::List::ConstIterator it; 00172 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) { 00173 Incidence *i = *it; 00174 if ( i ) mCalendar.addIncidence( i->clone() ); 00175 } 00176 return true; 00177 } 00178 00179 bool ResourceLocalDir::doSave() 00180 { 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 return success; 00192 } 00193 00194 bool ResourceLocalDir::doSave( Incidence *incidence ) 00195 { 00196 if ( mDeletedIncidences.contains( incidence ) ) { 00197 mDeletedIncidences.remove( incidence ); 00198 return true; 00199 } 00200 00201 mDirWatch.stopScan(); // do prohibit the dirty() signal and a following reload() 00202 00203 TQString fileName = mURL.path() + "/" + incidence->uid(); 00204 kdDebug(5800) << "writing '" << fileName << "'" << endl; 00205 00206 CalendarLocal cal( mCalendar.timeZoneId() ); 00207 cal.addIncidence( incidence->clone() ); 00208 const bool ret = cal.save( fileName ); 00209 00210 mDirWatch.startScan(); 00211 00212 return ret; 00213 } 00214 00215 TDEABC::Lock *ResourceLocalDir::lock() 00216 { 00217 return mLock; 00218 } 00219 00220 void ResourceLocalDir::reload( const TQString &file ) 00221 { 00222 kdDebug(5800) << "ResourceLocalDir::reload()" << endl; 00223 00224 if ( !isOpen() ) 00225 return; 00226 00227 kdDebug(5800) << " File: '" << file << "'" << endl; 00228 00229 mCalendar.close(); 00230 load(); 00231 00232 emit resourceChanged( this ); 00233 } 00234 00235 00236 bool ResourceLocalDir::deleteEvent(Event *event) 00237 { 00238 kdDebug(5800) << "ResourceLocalDir::deleteEvent" << endl; 00239 if ( deleteIncidenceFile(event) ) { 00240 if ( mCalendar.deleteEvent( event ) ) { 00241 mDeletedIncidences.append( event ); 00242 return true; 00243 } else { 00244 return false; 00245 } 00246 } else { 00247 return false; 00248 } 00249 } 00250 00251 00252 bool ResourceLocalDir::deleteTodo(Todo *todo) 00253 { 00254 if ( deleteIncidenceFile(todo) ) { 00255 if ( mCalendar.deleteTodo( todo ) ) { 00256 mDeletedIncidences.append( todo ); 00257 return true; 00258 } else { 00259 return false; 00260 } 00261 } else { 00262 return false; 00263 } 00264 } 00265 00266 00267 bool ResourceLocalDir::deleteJournal( Journal *journal ) 00268 { 00269 if ( deleteIncidenceFile( journal ) ) { 00270 if ( mCalendar.deleteJournal( journal ) ) { 00271 mDeletedIncidences.append( journal ); 00272 return true; 00273 } else { 00274 return false; 00275 } 00276 } else { 00277 return false; 00278 } 00279 } 00280 00281 00282 void ResourceLocalDir::dump() const 00283 { 00284 ResourceCalendar::dump(); 00285 kdDebug(5800) << " Url: " << mURL.url() << endl; 00286 } 00287 00288 bool ResourceLocalDir::deleteIncidenceFile(Incidence *incidence) 00289 { 00290 TQFile file( mURL.path() + "/" + incidence->uid() ); 00291 if ( !file.exists() ) 00292 return true; 00293 00294 mDirWatch.stopScan(); 00295 bool removed = file.remove(); 00296 mDirWatch.startScan(); 00297 return removed; 00298 } 00299 00300 #include "resourcelocaldir.moc"