Fix more broken iterations...
[kdepim.git] / kmail / kmfolderdir.cpp
blob36ef0a4ff02b6e03f20d27dc0a0b02be814ebbcd
1 // kmfolderdir.cpp
3 #include <config.h>
5 #include "kmfolderdir.h"
6 #include "kmfoldersearch.h"
7 #include "kmfoldercachedimap.h"
8 #include "kmfolder.h"
10 #include <assert.h>
11 #include <errno.h>
12 #include <klocale.h>
13 #include <kmessagebox.h>
14 #include <kdebug.h>
15 #include <kstandarddirs.h>
17 #include <QDir>
18 #include <QList>
19 #include <QByteArray>
21 //=============================================================================
22 //=============================================================================
23 KMFolderRootDir::KMFolderRootDir(KMFolderMgr* manager, const QString& path,
24 KMFolderDirType dirType)
25 : KMFolderDir( 0, 0, path, dirType ),
26 mPath( path ),
27 mManager( manager )
31 //-----------------------------------------------------------------------------
32 KMFolderRootDir::~KMFolderRootDir()
34 // WABA: We can't let KMFolderDir do this because by the time its
35 // desctructor gets called, KMFolderRootDir is already destructed
36 // Most notably the path.
37 clear();
40 //-----------------------------------------------------------------------------
41 void KMFolderRootDir::setPath(const QString& aPath)
43 mPath = aPath;
47 //-----------------------------------------------------------------------------
48 QString KMFolderRootDir::path() const
50 return mPath;
54 //-----------------------------------------------------------------------------
55 QString KMFolderRootDir::prettyUrl() const
57 if ( !mBaseURL.isEmpty() )
58 return i18n( mBaseURL.data() );
59 else
60 return QString();
64 //-----------------------------------------------------------------------------
65 void KMFolderRootDir::setBaseURL( const QByteArray &baseURL )
67 mBaseURL = baseURL;
71 //-----------------------------------------------------------------------------
72 KMFolderMgr* KMFolderRootDir::manager() const
74 return mManager;
78 //=============================================================================
79 //=============================================================================
80 KMFolderDir::KMFolderDir( KMFolder * owner, KMFolderDir* parent,
81 const QString& name, KMFolderDirType dirType )
82 : KMFolderNode( parent, name ), KMFolderNodeList(),
83 mOwner( owner ), mDirType( dirType )
87 //-----------------------------------------------------------------------------
88 KMFolderDir::~KMFolderDir()
90 clear();
91 qDeleteAll( *this );
95 //-----------------------------------------------------------------------------
96 KMFolder* KMFolderDir::createFolder(const QString& aFolderName, bool aSysFldr, KMFolderType aFolderType)
98 KMFolder* fld;
100 assert(!aFolderName.isEmpty());
101 // FIXME urgs, is this still needed
102 if (mDirType == KMImapDir)
103 fld = new KMFolder( this, aFolderName, KMFolderTypeImap );
104 else
105 fld = new KMFolder( this, aFolderName, aFolderType );
107 assert(fld != 0);
108 fld->setSystemFolder(aSysFldr);
110 bool inserted = false;
111 QListIterator<KMFolderNode*> it( *this);
112 int index = 0;
113 while ( it.hasNext() ) {
114 KMFolderNode* fNode = it.next();
115 if (fNode->name().toLower() > fld->name().toLower()) {
116 insert( index, fld );
117 inserted = true;
118 break;
120 ++index;
123 if ( !inserted )
124 append(fld);
126 fld->correctUnreadMsgsCount();
127 return fld;
131 //----------------------------------------------------------------------------
132 QString KMFolderDir::path() const
134 static QString p;
136 if (parent())
138 p = parent()->path();
139 p.append("/");
140 p.append(name());
142 else p = "";
144 return p;
148 //----------------------------------------------------------------------------
149 QString KMFolderDir::label() const
151 if ( mOwner )
152 return mOwner->label();
153 else
154 return QString();
158 //-----------------------------------------------------------------------------
159 QString KMFolderDir::prettyUrl() const
161 QString parentUrl;
162 if ( parent() )
163 parentUrl = parent()->prettyUrl();
164 if ( !parentUrl.isEmpty() )
165 return parentUrl + '/' + label();
166 else
167 return label();
171 //-----------------------------------------------------------------------------
172 bool KMFolderDir::reload(void)
174 QDir dir;
175 KMFolder* folder;
176 QFileInfo fileInfo;
177 QStringList diList;
178 QList<KMFolder*> folderList;
180 clear();
182 const QString fldPath = path();
183 dir.setFilter(QDir::Files | QDir::Dirs | QDir::Hidden);
184 dir.setNameFilters(QStringList("*"));
186 if (!dir.cd(fldPath))
188 QString msg = i18n("<qt>Cannot enter folder <b>%1</b>.</qt>", fldPath);
189 KMessageBox::information(0, msg);
190 return false;
193 const QFileInfoList fiList = dir.entryInfoList();
194 if (fiList.isEmpty())
196 QString msg = i18n("<qt>Folder <b>%1</b> is unreadable.</qt>", fldPath);
197 KMessageBox::information(0, msg);
198 return false;
201 Q_FOREACH( fileInfo, fiList )
203 const QString fname = fileInfo.fileName();
204 if( ( fname[0] == '.' ) && !fname.endsWith( ".directory" ) ) {
205 // ignore all hidden files except our subfolder containers
206 continue;
208 if( fname == ".directory" ) {
209 // ignore .directory files (not created by us)
210 continue;
212 // Collect subdirectories.
213 if ( fileInfo.isDir() &&
214 fname.startsWith( "." ) && fname.endsWith( ".directory" ) ) {
215 diList.append(fname);
216 continue;
219 if ( mDirType == KMImapDir
220 && path().startsWith( KMFolderImap::cacheLocation() ) )
222 // Is the below needed for dimap as well?
223 if ( KMFolderImap::encodeFileName(
224 KMFolderImap::decodeFileName( fname ) ) == fname )
226 folder = new KMFolder( this, KMFolderImap::decodeFileName( fname ),
227 KMFolderTypeImap );
228 append(folder);
229 folderList.append(folder);
232 else if ( mDirType == KMDImapDir
233 && path().startsWith( KMFolderCachedImap::cacheLocation() ) )
235 if (fileInfo.isDir()) // a directory
237 // For this to be a cached IMAP folder, it must be in the KMail dimap
238 // subdir and must be have a uidcache file or be a maildir folder
239 QString maildir(fname + "/new");
240 QString imapcachefile = QString::fromLatin1(".%1.uidcache").arg(fname);
241 if ( dir.exists( imapcachefile) || dir.exists( maildir ) )
243 folder = new KMFolder( this, fname, KMFolderTypeCachedImap );
244 append(folder);
245 folderList.append(folder);
249 else if ( mDirType == KMSearchDir)
251 folder = new KMFolder( this, fname, KMFolderTypeSearch );
252 append(folder);
253 folderList.append(folder);
255 else if ( mDirType == KMStandardDir )
257 // This is neither an imap, dimap nor a search folder. Can be either
258 // mbox or maildir.
259 if (fileInfo.isDir())
261 // Maildir folder
262 if( dir.exists( fname + "/new" ) )
264 folder = new KMFolder( this, fname, KMFolderTypeMaildir );
265 append(folder);
266 folderList.append(folder);
269 else
271 // all other files are folders (at the moment ;-)
272 folder = new KMFolder( this, fname, KMFolderTypeMbox );
273 append(folder);
274 folderList.append(folder);
279 QList<KMFolder*>::const_iterator jt;
280 for ( jt = folderList.constBegin(); jt != folderList.constEnd(); ++jt )
282 folder = *jt;
283 for(QStringList::const_iterator it = diList.constBegin();
284 it != diList.constEnd();
285 ++it)
286 if (*it == '.' + folder->fileName() + ".directory")
288 KMFolderDir* folderDir = new KMFolderDir( folder, this, *it, mDirType);
289 folderDir->reload();
290 append(folderDir);
291 folder->setChild(folderDir);
292 break;
295 return true;
299 //-----------------------------------------------------------------------------
300 KMFolderNode* KMFolderDir::hasNamedFolder(const QString& aName)
302 QListIterator<KMFolderNode*> it(*this);
303 while ( it.hasNext() ) {
304 KMFolderNode* node = it.next();
305 if ( node && node->name() == aName ) {
306 return node;
309 return 0;
313 //-----------------------------------------------------------------------------
314 KMFolderMgr* KMFolderDir::manager() const
316 return parent()->manager();
320 #include "kmfolderdir.moc"