4 #include "kmfolderdir.h"
5 #include "kmfoldersearch.h"
6 #include "kmfoldercachedimap.h"
8 #include "kmfoldermgr.h"
13 #include <kmessagebox.h>
15 #include <kstandarddirs.h>
21 //=============================================================================
22 //=============================================================================
23 KMFolderRootDir::KMFolderRootDir(KMFolderMgr
* manager
, const QString
& path
,
24 KMFolderDirType dirType
)
25 : KMFolderDir( 0, 0, path
, dirType
),
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 qDeleteAll( begin(), end() ); // we own the pointers to our folders
41 //-----------------------------------------------------------------------------
42 void KMFolderRootDir::setPath(const QString
& aPath
)
48 //-----------------------------------------------------------------------------
49 QString
KMFolderRootDir::path() const
55 //-----------------------------------------------------------------------------
56 QString
KMFolderRootDir::prettyUrl() const
58 if ( !mBaseURL
.isEmpty() )
59 return i18n( mBaseURL
.data() );
65 //-----------------------------------------------------------------------------
66 void KMFolderRootDir::setBaseURL( const QByteArray
&baseURL
)
72 //-----------------------------------------------------------------------------
73 KMFolderMgr
* KMFolderRootDir::manager() const
79 //=============================================================================
80 //=============================================================================
81 KMFolderDir::KMFolderDir( KMFolder
* owner
, KMFolderDir
* parent
,
82 const QString
& name
, KMFolderDirType dirType
)
83 : KMFolderNode( parent
, name
), KMFolderNodeList(),
84 mOwner( owner
), mDirType( dirType
)
88 //-----------------------------------------------------------------------------
89 KMFolderDir::~KMFolderDir()
91 qDeleteAll( begin(), end() ); // we own the pointers to our folders
96 //-----------------------------------------------------------------------------
97 KMFolder
* KMFolderDir::createFolder(const QString
& aFolderName
, bool aSysFldr
, KMFolderType aFolderType
)
101 assert(!aFolderName
.isEmpty());
102 // FIXME urgs, is this still needed
103 if (mDirType
== KMImapDir
)
104 fld
= new KMFolder( this, aFolderName
, KMFolderTypeImap
);
106 fld
= new KMFolder( this, aFolderName
, aFolderType
);
109 fld
->setSystemFolder(aSysFldr
);
111 bool inserted
= false;
112 QListIterator
<KMFolderNode
*> it( *this);
114 while ( it
.hasNext() ) {
115 KMFolderNode
* fNode
= it
.next();
116 if (fNode
->name().toLower() > fld
->name().toLower()) {
117 insert( index
, fld
);
127 fld
->correctUnreadMsgsCount();
132 //----------------------------------------------------------------------------
133 QString
KMFolderDir::path() const
139 p
= parent()->path();
149 //----------------------------------------------------------------------------
150 QString
KMFolderDir::label() const
153 return mOwner
->label();
159 //-----------------------------------------------------------------------------
160 QString
KMFolderDir::prettyUrl() const
164 parentUrl
= parent()->prettyUrl();
165 if ( !parentUrl
.isEmpty() )
166 return parentUrl
+ '/' + label();
171 //-----------------------------------------------------------------------------
172 void KMFolderDir::addDirToParent( const QString
&dirName
, KMFolder
*parentFolder
)
174 KMFolderDir
* folderDir
= new KMFolderDir( parentFolder
, this, dirName
, mDirType
);
177 parentFolder
->setChild( folderDir
);
180 // Get the default folder type of the given dir type. This function should only be used when
181 // needing to find out what the folder type of a missing folder is.
182 KMFolderType
dirTypeToFolderType( KMFolderDirType dirType
)
186 // Use maildir for normal folder dirs, as this function is only called when finding a dir
187 // without a parent folder, which can only happen with maildir-like folders
188 case KMStandardDir
: return KMFolderTypeMaildir
;
190 case KMImapDir
: return KMFolderTypeImap
;
191 case KMDImapDir
: return KMFolderTypeCachedImap
;
192 case KMSearchDir
: return KMFolderTypeSearch
;
193 default: Q_ASSERT( false ); return KMFolderTypeMaildir
;
197 //-----------------------------------------------------------------------------
198 bool KMFolderDir::reload(void)
200 qDeleteAll( begin(), end() ); // we own the pointers to our folders
203 const QString fldPath
= path();
205 dir
.setFilter(QDir::Files
| QDir::Dirs
| QDir::Hidden
| QDir::NoDotAndDotDot
);
206 dir
.setNameFilters(QStringList("*"));
208 if ( !dir
.cd(fldPath
) )
210 QString msg
= i18n("<qt>Cannot enter folder <b>%1</b>.</qt>", fldPath
);
211 KMessageBox::information(0, msg
);
215 if ( !dir
.isReadable() )
217 QString msg
= i18n("<qt>Folder <b>%1</b> is unreadable.</qt>", fldPath
);
218 KMessageBox::information(0, msg
);
223 QList
<KMFolder
*> folderList
;
224 const QFileInfoList
fiList( dir
.entryInfoList() );
225 Q_FOREACH( const QFileInfo
& fileInfo
, fiList
)
227 const QString fname
= fileInfo
.fileName();
228 const bool fileIsHidden
= fname
.startsWith('.');
229 if ( fileIsHidden
&& !fname
.endsWith( QLatin1String(".directory") ) ) {
230 // ignore all hidden files except our subfolder containers
233 if ( fname
== ".directory"
234 #ifdef KMAIL_SQLITE_INDEX
235 || fname
.endsWith( QLatin1String(".index.db") )
238 // ignore .directory and *.index.db files (not created by us)
241 // Collect subdirectories.
242 if ( fileInfo
.isDir() &&
243 fileIsHidden
&& fname
.endsWith( QLatin1String(".directory") ) )
249 // define folder parameters
251 KMFolderType folderType
= KMFolderTypeMaildir
;
252 bool withIndex
= true;
253 bool exportedSernums
= true;
255 if ( mDirType
== KMImapDir
256 && path().startsWith( KMFolderImap::cacheLocation() ) )
258 // Is the below needed for dimap as well?
259 if ( KMFolderImap::encodeFileName(
260 KMFolderImap::decodeFileName( fname
) ) == fname
)
262 folderName
= KMFolderImap::decodeFileName( fname
);
263 folderType
= KMFolderTypeImap
;
266 else if ( mDirType
== KMDImapDir
267 && path().startsWith( KMFolderCachedImap::cacheLocation() ) )
269 if (fileInfo
.isDir()) // a directory
271 // For this to be a cached IMAP folder, it must be in the KMail dimap
272 // subdir and must be have a uidcache file or be a maildir folder
273 QString
maildir(fname
+ "/new");
274 QString imapcachefile
= QString::fromLatin1(".%1.uidcache").arg(fname
);
275 if ( dir
.exists( imapcachefile
) || dir
.exists( maildir
) )
278 folderType
= KMFolderTypeCachedImap
;
282 else if ( mDirType
== KMSearchDir
)
285 folderType
= KMFolderTypeSearch
;
287 else if ( mDirType
== KMStandardDir
)
289 // This is neither an imap, dimap nor a search folder. Can be either
291 if (fileInfo
.isDir())
294 if( dir
.exists( fname
+ "/new" ) )
297 folderType
= KMFolderTypeMaildir
;
302 // all other files are folders (at the moment ;-)
304 folderType
= KMFolderTypeMbox
;
308 //TODO if ( &manager()->dir() == this && folderName == QLatin1String( "outbox" ) )
309 //TODO withIndex = false;
312 if ( !folderName
.isEmpty() ) {
313 KMFolder
* newFolder
= new KMFolder( this, folderName
, folderType
, withIndex
, exportedSernums
);
315 folderList
.append( newFolder
);
319 QSet
<QString
> dirsWithoutFolder
= dirs
;
320 foreach ( KMFolder
* folder
, folderList
)
322 const QString dirName
= '.' + folder
->fileName() + ".directory";
323 if ( dirs
.contains( dirName
) )
325 dirsWithoutFolder
.remove( dirName
);
326 addDirToParent( dirName
, folder
);
330 // Check if the are any dirs without an associated folder. This can happen if the user messes
331 // with the on-disk folder structure, see kolab issue 2972. In that case, we don't want to loose
332 // the subfolders as well, so we recreate the folder so the folder/dir hierachy is OK again.
333 if ( type() == KMDImapDir
) {
334 foreach ( const QString
&dirName
, dirsWithoutFolder
) {
336 // .foo.directory => foo
337 QString folderName
= dirName
;
338 int right
= folderName
.indexOf( ".directory" );
339 int left
= folderName
.indexOf( "." );
340 Q_ASSERT( left
!= -1 && right
!= -1 );
341 folderName
= folderName
.mid( left
+ 1, right
- 1 );
343 kWarning() << "Found dir without associated folder:" << dirName
<< ", recreating the folder"
346 // Recreate the missing folder
347 KMFolder
*folder
= new KMFolder( this, folderName
, KMFolderTypeCachedImap
);
349 folderList
.append( folder
);
351 addDirToParent( dirName
, folder
);
357 //-----------------------------------------------------------------------------
358 KMFolderNode
* KMFolderDir::hasNamedFolder(const QString
& aName
)
360 QListIterator
<KMFolderNode
*> it(*this);
361 while ( it
.hasNext() ) {
362 KMFolderNode
* node
= it
.next();
363 if ( node
&& node
->name() == aName
) {
371 //-----------------------------------------------------------------------------
372 KMFolderMgr
* KMFolderDir::manager() const
374 return parent()->manager();
378 #include "kmfolderdir.moc"