00001
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
00025
#include "kmmainwin.h"
00026
#include "kmfiltermgr.h"
00027
#include "kmfoldermgr.h"
00028
#include "undostack.h"
00029
#include "kmmsgdict.h"
00030
00031
00032 KMFolderMgr::KMFolderMgr(
const QString& aBasePath, KMFolderDirType dirType):
00033 QObject(), mDir(this, QString::null, dirType)
00034 {
00035 mQuiet = 0;
00036 mChanged = FALSE;
00037 setBasePath(aBasePath);
00038 }
00039
00040
00041
00042 KMFolderMgr::~KMFolderMgr()
00043 {
00044
if (kmkernel->undoStack())
00045 kmkernel->undoStack()->clear();
00046 mBasePath = QString::null;
00047 }
00048
00049
00050
00051
void KMFolderMgr::compactAll()
00052 {
00053 compactAllAux( &mDir );
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(0);
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::compactAllAux(
KMFolderDir* dir)
00108 {
00109 DO_FOR_ALL(
00110 {
00111 compactAllAux(child);
00112 },
00113 {
00114 folder->compact();
00115 emit progress();
00116 }
00117 )
00118 }
00119
00120
00121
00122
void KMFolderMgr::setBasePath(
const QString& aBasePath)
00123 {
00124 assert(!aBasePath.isNull());
00125
00126
if (aBasePath[0] ==
'~')
00127 {
00128 mBasePath = QDir::homeDirPath();
00129 mBasePath.append(
"/");
00130 mBasePath.append(aBasePath.mid(1));
00131 }
00132
else
00133 mBasePath = aBasePath;
00134
00135 QFileInfo info( mBasePath );
00136
00137
00138
00139
if ( info.exists() ) {
00140
if ( !info.isDir() ) {
00141 KMessageBox::sorry(0, i18n(
"'%1' does not appear to be a folder.\n"
00142
"Please move the file out of the way.")
00143 .arg( mBasePath ) );
00144 ::exit(-1);
00145 }
00146
if ( !info.isReadable() || !info.isWritable() ) {
00147 KMessageBox::sorry(0, i18n(
"The permissions of the folder '%1' are "
00148
"incorrect.\n"
00149
"Please make sure that you can view and modify "
00150
"the content of this folder.")
00151 .arg( mBasePath ) );
00152 ::exit(-1);
00153 }
00154 }
else {
00155
00156
if ( ::mkdir( QFile::encodeName( mBasePath ) , S_IRWXU ) == -1 ) {
00157 KMessageBox::sorry(0, i18n(
"KMail couldn't create folder '%1'.\n"
00158
"Please make sure that you can view and "
00159
"modify the content of the folder '%2'.")
00160 .arg( mBasePath ).arg( QDir::homeDirPath() ) );
00161 ::exit(-1);
00162 }
00163 }
00164 mDir.setPath(mBasePath);
00165 mDir.reload();
00166 contentsChanged();
00167 }
00168
00169
00170
00171
KMFolder* KMFolderMgr::createFolder(
const QString& fName,
bool sysFldr,
00172 KMFolderType aFolderType,
00173
KMFolderDir *aFolderDir)
00174 {
00175
KMFolder* fld;
00176
KMFolderDir *fldDir = aFolderDir;
00177
00178
if (!aFolderDir)
00179 fldDir = &mDir;
00180 fld = fldDir->
createFolder(fName, sysFldr, aFolderType);
00181
if (fld) {
00182 contentsChanged();
00183 emit folderAdded(fld);
00184
if (kmkernel->filterMgr())
00185 kmkernel->filterMgr()->folderCreated(fld);
00186 }
00187
00188
return fld;
00189 }
00190
00191
00192
00193
KMFolder* KMFolderMgr::find(
const QString& folderName,
bool foldersOnly)
00194 {
00195 KMFolderNode* node;
00196
00197
for (node=mDir.first(); node; node=mDir.next())
00198 {
00199
if (node->isDir() && foldersOnly)
continue;
00200
if (node->name()==folderName)
return (
KMFolder*)node;
00201 }
00202
return 0;
00203 }
00204
00205
00206
KMFolder* KMFolderMgr::findIdString(
const QString& folderId,
KMFolderDir *dir)
00207 {
00208
if (!dir)
00209 dir = static_cast<KMFolderDir*>(&mDir);
00210
00211 DO_FOR_ALL(
00212 {
00213
KMFolder *folder = findIdString( folderId, child);
00214
if (folder)
00215
return folder;
00216 },
00217 {
00218
if (folder->idString() == folderId)
00219
return folder;
00220 }
00221 )
00222
00223
return 0;
00224 }
00225
00226
void KMFolderMgr::getFolderURLS( QStringList& flist,
const QString& prefix,
00227
KMFolderDir *adir )
00228 {
00229
KMFolderDir* dir = adir ? adir : &mDir;
00230
00231 DO_FOR_ALL(
00232 {
00233 getFolderURLS( flist, prefix +
"/" + folder->name(), child );
00234 },
00235 {
00236 flist << prefix +
"/" + folder->name();
00237 }
00238 )
00239 }
00240
00241
KMFolder* KMFolderMgr::getFolderByURL(
const QString& vpath,
00242
const QString& prefix,
00243
KMFolderDir *adir )
00244 {
00245
KMFolderDir* dir = adir ? adir : &mDir;
00246 DO_FOR_ALL(
00247 {
00248 QString a = prefix +
"/" + folder->name();
00249
KMFolder * mfolder = getFolderByURL( vpath, a,child );
00250
if ( mfolder )
00251
return mfolder;
00252 },
00253 {
00254 QString comp = prefix +
"/" + folder->name();
00255
if ( comp == vpath )
00256
return folder;
00257 }
00258 )
00259
return 0;
00260 }
00261
00262
00263
KMFolder* KMFolderMgr::findOrCreate(
const QString& aFolderName,
bool sysFldr)
00264 {
00265
KMFolder* folder = find(aFolderName);
00266
00267
if (!folder)
00268 {
00269
static bool know_type =
false;
00270
static KMFolderType type = KMFolderTypeMaildir;
00271
if (know_type ==
false)
00272 {
00273 know_type =
true;
00274 KConfig *config = KMKernel::config();
00275 KConfigGroupSaver saver(config,
"General");
00276
if (config->hasKey(
"default-mailbox-format"))
00277 {
00278
if (config->readNumEntry(
"default-mailbox-format", 1) == 0)
00279 type = KMFolderTypeMbox;
00280
00281 }
00282 }
00283
00284 folder =
createFolder(aFolderName, sysFldr, type);
00285
if (!folder) {
00286 KMessageBox::error(0,(i18n(
"Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(aFolderName).arg(mBasePath)));
00287 exit(-1);
00288 }
00289 }
00290
return folder;
00291 }
00292
00293
00294
00295
void KMFolderMgr::remove(
KMFolder* aFolder)
00296 {
00297 assert(aFolder != 0);
00298
00299 emit folderRemoved(aFolder);
00300 removeFolderAux(aFolder);
00301
00302 contentsChanged();
00303 }
00304
00305
void KMFolderMgr::removeFolderAux(
KMFolder* aFolder)
00306 {
00307
KMFolderDir* fdir = aFolder->parent();
00308 KMFolderNode* fN;
00309
for (fN = fdir->first(); fN != 0; fN = fdir->next())
00310
if (fN->isDir() && (fN->name() ==
"." + aFolder->
fileName() +
".directory")) {
00311 removeDirAux(static_cast<KMFolderDir*>(fN));
00312
break;
00313 }
00314 aFolder->
remove();
00315 aFolder->parent()->
remove(aFolder);
00316
00317
if (kmkernel->filterMgr()) kmkernel->filterMgr()->folderRemoved(aFolder,0);
00318 }
00319
00320
void KMFolderMgr::removeDirAux(
KMFolderDir* aFolderDir)
00321 {
00322 QDir dir;
00323 QString folderDirLocation = aFolderDir->
path();
00324 KMFolderNode* fN;
00325
for (fN = aFolderDir->first(); fN != 0; fN = aFolderDir->first()) {
00326
if (fN->isDir())
00327 removeDirAux(static_cast<KMFolderDir*>(fN));
00328
else
00329 removeFolderAux(static_cast<KMFolder*>(fN));
00330 }
00331 aFolderDir->clear();
00332 aFolderDir->parent()->remove(aFolderDir);
00333 dir.rmdir(folderDirLocation);
00334 }
00335
00336
00337 KMFolderRootDir& KMFolderMgr::dir(
void)
00338 {
00339
return mDir;
00340 }
00341
00342
00343
00344
void KMFolderMgr::contentsChanged(
void)
00345 {
00346
if (mQuiet) mChanged = TRUE;
00347
else emit changed();
00348 }
00349
00350
00351
00352
void KMFolderMgr::reload(
void)
00353 {
00354 }
00355
00356
00357
void KMFolderMgr::createFolderList(QStringList *str,
00358 QValueList<QGuardedPtr<KMFolder> > *folders)
00359 {
00360 createFolderList( str, folders, 0,
"" );
00361 }
00362
00363
00364
void KMFolderMgr::createI18nFolderList(QStringList *str,
00365 QValueList<QGuardedPtr<KMFolder> > *folders)
00366 {
00367 createFolderList( str, folders, 0, QString::null,
true );
00368 }
00369
00370
00371
void KMFolderMgr::createFolderList(QStringList *str,
00372 QValueList<QGuardedPtr<KMFolder> > *folders,
00373
KMFolderDir *adir,
00374
const QString& prefix,
00375
bool i18nized)
00376 {
00377
KMFolderDir* dir = adir ? adir : &mDir;
00378
00379 DO_FOR_ALL(
00380 {
00381 createFolderList(str, folders, child,
" " + prefix, i18nized );
00382 },
00383 {
00384
if (i18nized)
00385 str->append(prefix + folder->
label());
00386
else
00387 str->append(prefix + folder->name());
00388 folders->append( folder );
00389 }
00390 )
00391 }
00392
00393
00394
void KMFolderMgr::syncAllFolders(
KMFolderDir *adir )
00395 {
00396
KMFolderDir* dir = adir ? adir : &mDir;
00397 DO_FOR_ALL(
00398 {
00399 syncAllFolders(child);
00400 },
00401 {
00402
if (folder->
isOpened())
00403 folder->
sync();
00404 }
00405 )
00406 }
00407
00408
00409
00416
void KMFolderMgr::expireAllFolders(
KMFolderDir *adir) {
00417
KMFolderDir *dir = adir ? adir : &mDir;
00418
00419 DO_FOR_ALL(
00420 {
00421 expireAllFolders(child);
00422 },
00423 {
00424
if (folder->
isAutoExpire()) {
00425 folder->
expireOldMessages();
00426 }
00427 emit progress();
00428 }
00429 )
00430 }
00431
00432
00433
void KMFolderMgr::invalidateFolder(KMMsgDict *dict,
KMFolder *folder)
00434 {
00435 unlink(QFile::encodeName(folder->
indexLocation()) +
".sorted");
00436 unlink(QFile::encodeName(folder->
indexLocation()) +
".ids");
00437
if (dict) {
00438 folder->
fillMsgDict(dict);
00439 dict->writeFolderIds(folder);
00440 }
00441 emit folderInvalidated(folder);
00442 }
00443
00444
00445
void KMFolderMgr::readMsgDict(KMMsgDict *dict,
KMFolderDir *dir,
int pass)
00446 {
00447
bool atTop =
false;
00448
if (!dir) {
00449 dir = &mDir;
00450 atTop =
true;
00451 }
00452
00453 DO_FOR_ALL(
00454 {
00455 readMsgDict(dict, child, pass);
00456 },
00457 {
00458
if (pass == 1) {
00459 dict->readFolderIds(folder);
00460 }
else if (pass == 2) {
00461
if (!dict->hasFolderIds(folder)) {
00462 invalidateFolder(dict, folder);
00463 }
00464 }
00465 }
00466 )
00467
00468
if (pass == 1 && atTop)
00469 readMsgDict(dict, dir, pass + 1);
00470 }
00471
00472
00473
void KMFolderMgr::writeMsgDict(KMMsgDict *dict,
KMFolderDir *dir)
00474 {
00475
if (!dir)
00476 dir = &mDir;
00477
00478 DO_FOR_ALL(
00479 {
00480 writeMsgDict(dict, child);
00481 },
00482 {
00483 folder->
writeMsgDict(dict);
00484 }
00485 )
00486 }
00487
00488
00489
void KMFolderMgr::quiet(
bool beQuiet)
00490 {
00491
if (beQuiet)
00492 mQuiet++;
00493
else {
00494 mQuiet--;
00495
if (mQuiet <= 0)
00496 {
00497 mQuiet = 0;
00498
if (mChanged) emit changed();
00499 mChanged = FALSE;
00500 }
00501 }
00502 }
00503
00504
00505
#include "kmfoldermgr.moc"