kmail Library API Documentation

kmfoldermgr.cpp

00001 // kmfoldermgr.cpp 00002 00003 #ifdef HAVE_CONFIG_H 00004 #include <config.h> 00005 #endif 00006 00007 #include <sys/types.h> 00008 00009 #ifdef HAVE_SYS_STAT_H 00010 #include <sys/stat.h> 00011 #endif 00012 00013 #include <assert.h> 00014 #include <fcntl.h> 00015 #include <stdlib.h> 00016 #include <unistd.h> 00017 #include <time.h> 00018 00019 #include <qdir.h> 00020 00021 #include <klocale.h> 00022 #include <kmessagebox.h> 00023 #include <kconfig.h> 00024 #include <kdebug.h> 00025 #include <kapplication.h> 00026 00027 #include "kmmainwin.h" 00028 #include "kmfiltermgr.h" 00029 #include "kmfoldermgr.h" 00030 #include "undostack.h" 00031 #include "kmmsgdict.h" 00032 #include "folderstorage.h" 00033 00034 //----------------------------------------------------------------------------- 00035 KMFolderMgr::KMFolderMgr(const QString& aBasePath, KMFolderDirType dirType): 00036 QObject(), mDir(this, QString::null, dirType) 00037 { 00038 if ( dirType == KMStandardDir ) 00039 mDir.setBaseURL( I18N_NOOP("Local") ); 00040 mQuiet = 0; 00041 mChanged = FALSE; 00042 setBasePath(aBasePath); 00043 mRemoveOrig = 0; 00044 } 00045 00046 00047 //----------------------------------------------------------------------------- 00048 KMFolderMgr::~KMFolderMgr() 00049 { 00050 if (kmkernel->undoStack()) 00051 kmkernel->undoStack()->clear(); // Speed things up a bit. 00052 mBasePath = QString::null; 00053 } 00054 00055 00056 //----------------------------------------------------------------------------- 00057 void KMFolderMgr::expireAll() { 00058 KConfig *config = KMKernel::config(); 00059 KConfigGroupSaver saver(config, "General"); 00060 int ret = KMessageBox::Continue; 00061 00062 if (config->readBoolEntry("warn-before-expire", true)) { 00063 ret = KMessageBox::warningContinueCancel(KMainWindow::memberList->first(), 00064 i18n("Are you sure you want to expire old messages?"), 00065 i18n("Expire Old Messages?"), i18n("Expire")); 00066 } 00067 00068 if (ret == KMessageBox::Continue) { 00069 expireAllFolders( true /*immediate*/ ); 00070 } 00071 00072 } 00073 00074 #define DO_FOR_ALL(function, folder_code) \ 00075 KMFolderNode* node; \ 00076 QPtrListIterator<KMFolderNode> it(*dir); \ 00077 for ( ; (node = it.current()); ) { \ 00078 ++it; \ 00079 if (node->isDir()) continue; \ 00080 KMFolder *folder = static_cast<KMFolder*>(node); \ 00081 folder_code \ 00082 KMFolderDir *child = folder->child(); \ 00083 if (child) \ 00084 function \ 00085 } 00086 00087 int KMFolderMgr::folderCount(KMFolderDir *dir) 00088 { 00089 int count = 0; 00090 if (dir == 0) 00091 dir = &mDir; 00092 DO_FOR_ALL( 00093 { 00094 count += folderCount( child ); 00095 }, 00096 { 00097 count++; 00098 } 00099 ) 00100 00101 return count; 00102 } 00103 00104 00105 00106 //----------------------------------------------------------------------------- 00107 void KMFolderMgr::compactAllFolders(bool immediate, KMFolderDir* dir) 00108 { 00109 if (dir == 0) 00110 dir = &mDir; 00111 DO_FOR_ALL( 00112 { 00113 compactAllFolders( immediate, child ); 00114 }, 00115 { 00116 if ( folder->needsCompacting() ) 00117 folder->compact( immediate ? KMFolder::CompactNow : KMFolder::CompactLater ); 00118 } 00119 ) 00120 } 00121 00122 00123 //----------------------------------------------------------------------------- 00124 void KMFolderMgr::setBasePath(const QString& aBasePath) 00125 { 00126 assert(!aBasePath.isNull()); 00127 00128 if (aBasePath[0] == '~') 00129 { 00130 mBasePath = QDir::homeDirPath(); 00131 mBasePath.append("/"); 00132 mBasePath.append(aBasePath.mid(1)); 00133 } 00134 else 00135 mBasePath = aBasePath; 00136 00137 QFileInfo info( mBasePath ); 00138 00139 // FIXME We should ask for an alternative dir, rather than bailing out, 00140 // I guess - till 00141 if ( info.exists() ) { 00142 if ( !info.isDir() ) { 00143 KMessageBox::sorry(0, i18n("'%1' does not appear to be a folder.\n" 00144 "Please move the file out of the way.") 00145 .arg( mBasePath ) ); 00146 ::exit(-1); 00147 } 00148 if ( !info.isReadable() || !info.isWritable() ) { 00149 KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are " 00150 "incorrect;\n" 00151 "please make sure that you can view and modify " 00152 "the content of this folder.") 00153 .arg( mBasePath ) ); 00154 ::exit(-1); 00155 } 00156 } else { 00157 // ~/Mail (or whatever the user specified) doesn't exist, create it 00158 if ( ::mkdir( QFile::encodeName( mBasePath ) , S_IRWXU ) == -1 ) { 00159 KMessageBox::sorry(0, i18n("KMail could not create folder '%1';\n" 00160 "please make sure that you can view and " 00161 "modify the content of the folder '%2'.") 00162 .arg( mBasePath ).arg( QDir::homeDirPath() ) ); 00163 ::exit(-1); 00164 } 00165 } 00166 mDir.setPath(mBasePath); 00167 mDir.reload(); 00168 contentsChanged(); 00169 } 00170 00171 00172 //----------------------------------------------------------------------------- 00173 KMFolder* KMFolderMgr::createFolder(const QString& fName, bool sysFldr, 00174 KMFolderType aFolderType, 00175 KMFolderDir *aFolderDir) 00176 { 00177 KMFolder* fld; 00178 KMFolderDir *fldDir = aFolderDir; 00179 00180 if (!aFolderDir) 00181 fldDir = &mDir; 00182 fld = fldDir->createFolder(fName, sysFldr, aFolderType); 00183 if (fld) { 00184 contentsChanged(); 00185 emit folderAdded(fld); 00186 if (kmkernel->filterMgr()) 00187 kmkernel->filterMgr()->folderCreated(fld); 00188 } 00189 00190 return fld; 00191 } 00192 00193 00194 //----------------------------------------------------------------------------- 00195 KMFolder* KMFolderMgr::find(const QString& folderName, bool foldersOnly) 00196 { 00197 KMFolderNode* node; 00198 00199 for (node=mDir.first(); node; node=mDir.next()) 00200 { 00201 if (node->isDir() && foldersOnly) continue; 00202 if (node->name()==folderName) return (KMFolder*)node; 00203 } 00204 return 0; 00205 } 00206 00207 //----------------------------------------------------------------------------- 00208 KMFolder* KMFolderMgr::findById(const uint id) 00209 { 00210 return findIdString( QString::null, id ); 00211 } 00212 00213 //----------------------------------------------------------------------------- 00214 KMFolder* KMFolderMgr::findIdString( const QString& folderId, 00215 const uint id, 00216 KMFolderDir *dir ) 00217 { 00218 if (!dir) 00219 dir = &mDir; 00220 00221 DO_FOR_ALL( 00222 { 00223 KMFolder *folder = findIdString( folderId, id, child ); 00224 if ( folder ) 00225 return folder; 00226 }, 00227 { 00228 if ( ( !folderId.isEmpty() && folder->idString() == folderId ) || 00229 ( id != 0 && folder->id() == id ) ) 00230 return folder; 00231 } 00232 ) 00233 00234 return 0; 00235 } 00236 00237 void KMFolderMgr::getFolderURLS( QStringList& flist, const QString& prefix, 00238 KMFolderDir *adir ) 00239 { 00240 KMFolderDir* dir = adir ? adir : &mDir; 00241 00242 DO_FOR_ALL( 00243 { 00244 getFolderURLS( flist, prefix + "/" + folder->name(), child ); 00245 }, 00246 { 00247 flist << prefix + "/" + folder->name(); 00248 } 00249 ) 00250 } 00251 00252 KMFolder* KMFolderMgr::getFolderByURL( const QString& vpath, 00253 const QString& prefix, 00254 KMFolderDir *adir ) 00255 { 00256 KMFolderDir* dir = adir ? adir : &mDir; 00257 DO_FOR_ALL( 00258 { 00259 QString a = prefix + "/" + folder->name(); 00260 KMFolder * mfolder = getFolderByURL( vpath, a,child ); 00261 if ( mfolder ) 00262 return mfolder; 00263 }, 00264 { 00265 QString comp = prefix + "/" + folder->name(); 00266 if ( comp == vpath ) 00267 return folder; 00268 } 00269 ) 00270 return 0; 00271 } 00272 00273 //----------------------------------------------------------------------------- 00274 KMFolder* KMFolderMgr::findOrCreate(const QString& aFolderName, bool sysFldr, 00275 const uint id) 00276 { 00277 KMFolder* folder = 0; 00278 if ( id == 0 ) 00279 folder = find(aFolderName); 00280 else 00281 folder = findById(id); 00282 00283 if (!folder) 00284 { 00285 static bool know_type = false; 00286 static KMFolderType type = KMFolderTypeMaildir; 00287 if (know_type == false) 00288 { 00289 know_type = true; 00290 KConfig *config = KMKernel::config(); 00291 KConfigGroupSaver saver(config, "General"); 00292 if (config->hasKey("default-mailbox-format")) 00293 { 00294 if (config->readNumEntry("default-mailbox-format", 1) == 0) 00295 type = KMFolderTypeMbox; 00296 00297 } 00298 } 00299 00300 folder = createFolder(aFolderName, sysFldr, type); 00301 if (!folder) { 00302 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(aFolderName).arg(mBasePath))); 00303 exit(-1); 00304 } 00305 if ( id > 0 ) 00306 folder->setId( id ); 00307 } 00308 return folder; 00309 } 00310 00311 00312 //----------------------------------------------------------------------------- 00313 void KMFolderMgr::remove(KMFolder* aFolder) 00314 { 00315 if (!aFolder) return; 00316 // remember the original folder to trigger contentsChanged later 00317 if (!mRemoveOrig) mRemoveOrig = aFolder; 00318 if (aFolder->child()) 00319 { 00320 // call remove for every child 00321 KMFolderNode* node; 00322 QPtrListIterator<KMFolderNode> it(*aFolder->child()); 00323 for ( ; (node = it.current()); ) 00324 { 00325 ++it; 00326 if (node->isDir()) continue; 00327 KMFolder *folder = static_cast<KMFolder*>(node); 00328 remove(folder); 00329 } 00330 } 00331 emit folderRemoved(aFolder); 00332 removeFolder(aFolder); 00333 } 00334 00335 void KMFolderMgr::removeFolder(KMFolder* aFolder) 00336 { 00337 connect(aFolder, SIGNAL(removed(KMFolder*, bool)), 00338 this, SLOT(removeFolderAux(KMFolder*, bool))); 00339 aFolder->remove(); 00340 } 00341 00342 void KMFolderMgr::removeFolderAux(KMFolder* aFolder, bool success) 00343 { 00344 if (!success) { 00345 mRemoveOrig = 0; 00346 return; 00347 } 00348 00349 KMFolderDir* fdir = aFolder->parent(); 00350 KMFolderNode* fN; 00351 for (fN = fdir->first(); fN != 0; fN = fdir->next()) { 00352 if (fN->isDir() && (fN->name() == "." + aFolder->fileName() + ".directory")) { 00353 removeDirAux(static_cast<KMFolderDir*>(fN)); 00354 break; 00355 } 00356 } 00357 aFolder->parent()->remove(aFolder); 00358 // find the parent folder by stripping "." and ".directory" from the name 00359 QString parentName = fdir->name(); 00360 parentName = parentName.mid( 1, parentName.length()-11 ); 00361 KMFolderNode* parent = fdir->hasNamedFolder( parentName ); 00362 if ( !parent && fdir->parent() ) // dimap obviously has a different structure 00363 parent = fdir->parent()->hasNamedFolder( parentName ); 00364 // update the children state 00365 if ( parent ) 00366 static_cast<KMFolder*>(parent)->storage()->updateChildrenState(); 00367 else 00368 kdWarning(5006) << "Can not find parent folder" << endl; 00369 00370 if (aFolder == mRemoveOrig) { 00371 // call only if we're removing the original parent folder 00372 contentsChanged(); 00373 mRemoveOrig = 0; 00374 } 00375 } 00376 00377 void KMFolderMgr::removeDirAux(KMFolderDir* aFolderDir) 00378 { 00379 QDir dir; 00380 QString folderDirLocation = aFolderDir->path(); 00381 aFolderDir->clear(); 00382 aFolderDir->parent()->remove(aFolderDir); 00383 dir.rmdir(folderDirLocation); 00384 } 00385 00386 //----------------------------------------------------------------------------- 00387 KMFolderRootDir& KMFolderMgr::dir(void) 00388 { 00389 return mDir; 00390 } 00391 00392 00393 //----------------------------------------------------------------------------- 00394 void KMFolderMgr::contentsChanged(void) 00395 { 00396 if (mQuiet) mChanged = TRUE; 00397 else emit changed(); 00398 } 00399 00400 00401 //----------------------------------------------------------------------------- 00402 void KMFolderMgr::reload(void) 00403 { 00404 } 00405 00406 //----------------------------------------------------------------------------- 00407 void KMFolderMgr::createFolderList(QStringList *str, 00408 QValueList<QGuardedPtr<KMFolder> > *folders) 00409 { 00410 createFolderList( str, folders, 0, "" ); 00411 } 00412 00413 //----------------------------------------------------------------------------- 00414 void KMFolderMgr::createI18nFolderList(QStringList *str, 00415 QValueList<QGuardedPtr<KMFolder> > *folders) 00416 { 00417 createFolderList( str, folders, 0, QString::null, true ); 00418 } 00419 00420 //----------------------------------------------------------------------------- 00421 void KMFolderMgr::createFolderList(QStringList *str, 00422 QValueList<QGuardedPtr<KMFolder> > *folders, 00423 KMFolderDir *adir, 00424 const QString& prefix, 00425 bool i18nized) 00426 { 00427 KMFolderDir* dir = adir ? adir : &mDir; 00428 00429 DO_FOR_ALL( 00430 { 00431 createFolderList(str, folders, child, " " + prefix, i18nized ); 00432 }, 00433 { 00434 if (i18nized) 00435 str->append(prefix + folder->label()); 00436 else 00437 str->append(prefix + folder->name()); 00438 folders->append( folder ); 00439 } 00440 ) 00441 } 00442 00443 //----------------------------------------------------------------------------- 00444 void KMFolderMgr::syncAllFolders( KMFolderDir *adir ) 00445 { 00446 KMFolderDir* dir = adir ? adir : &mDir; 00447 DO_FOR_ALL( 00448 { 00449 syncAllFolders(child); 00450 }, 00451 { 00452 if (folder->isOpened()) 00453 folder->sync(); 00454 } 00455 ) 00456 } 00457 00458 00459 //----------------------------------------------------------------------------- 00466 void KMFolderMgr::expireAllFolders(bool immediate, KMFolderDir *adir) { 00467 KMFolderDir *dir = adir ? adir : &mDir; 00468 00469 DO_FOR_ALL( 00470 { 00471 expireAllFolders(immediate, child); 00472 }, 00473 { 00474 if (folder->isAutoExpire()) { 00475 folder->expireOldMessages( immediate ); 00476 } 00477 } 00478 ) 00479 } 00480 00481 //----------------------------------------------------------------------------- 00482 void KMFolderMgr::invalidateFolder(KMMsgDict *dict, KMFolder *folder) 00483 { 00484 unlink(QFile::encodeName(folder->indexLocation()) + ".sorted"); 00485 unlink(QFile::encodeName(folder->indexLocation()) + ".ids"); 00486 if (dict) { 00487 folder->fillMsgDict(dict); 00488 dict->writeFolderIds(folder); 00489 } 00490 emit folderInvalidated(folder); 00491 } 00492 00493 //----------------------------------------------------------------------------- 00494 void KMFolderMgr::readMsgDict(KMMsgDict *dict, KMFolderDir *dir, int pass) 00495 { 00496 bool atTop = false; 00497 if (!dir) { 00498 dir = &mDir; 00499 atTop = true; 00500 } 00501 00502 DO_FOR_ALL( 00503 { 00504 readMsgDict(dict, child, pass); 00505 }, 00506 { 00507 if (pass == 1) { 00508 dict->readFolderIds(folder); 00509 } else if (pass == 2) { 00510 if (!dict->hasFolderIds(folder)) { 00511 invalidateFolder(dict, folder); 00512 } 00513 } 00514 } 00515 ) 00516 00517 if (pass == 1 && atTop) 00518 readMsgDict(dict, dir, pass + 1); 00519 } 00520 00521 //----------------------------------------------------------------------------- 00522 void KMFolderMgr::writeMsgDict(KMMsgDict *dict, KMFolderDir *dir) 00523 { 00524 if (!dir) 00525 dir = &mDir; 00526 00527 DO_FOR_ALL( 00528 { 00529 writeMsgDict(dict, child); 00530 }, 00531 { 00532 folder->writeMsgDict(dict); 00533 } 00534 ) 00535 } 00536 00537 //----------------------------------------------------------------------------- 00538 void KMFolderMgr::quiet(bool beQuiet) 00539 { 00540 if (beQuiet) 00541 mQuiet++; 00542 else { 00543 mQuiet--; 00544 if (mQuiet <= 0) 00545 { 00546 mQuiet = 0; 00547 if (mChanged) emit changed(); 00548 mChanged = FALSE; 00549 } 00550 } 00551 } 00552 00553 //----------------------------------------------------------------------------- 00554 void KMFolderMgr::tryReleasingFolder(KMFolder* f, KMFolderDir* adir) 00555 { 00556 KMFolderDir* dir = adir ? adir : &mDir; 00557 DO_FOR_ALL( 00558 { 00559 tryReleasingFolder(f, child); 00560 }, 00561 { 00562 if (folder->isOpened()) 00563 folder->storage()->tryReleasingFolder(f); 00564 } 00565 ) 00566 } 00567 00568 //----------------------------------------------------------------------------- 00569 uint KMFolderMgr::createId() 00570 { 00571 int newId; 00572 do 00573 { 00574 newId = kapp->random(); 00575 } while ( findById( newId ) != 0 ); 00576 00577 return newId; 00578 } 00579 00580 #include "kmfoldermgr.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:52:35 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003