Correct dir entries caching in QFileDialog

Using QFileSystemWatcher to update cache when directory is changed. It is
needed to correctly filter files created after the dialog opening.

Task-number: QTBUG-30604

Change-Id: I5479f9a54095de59ca2ba36b2bd4906de0907ac8
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Cyril Oblikov 2013-04-10 16:18:52 +03:00 committed by The Qt Project
parent c77f7229d5
commit 9557cc6536

View File

@ -61,6 +61,8 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include "qcocoaautoreleasepool.h"
#include <QFileSystemWatcher>
#include <QDir>
#include <qpa/qplatformnativeinterface.h>
@ -72,6 +74,30 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo)
QT_FORWARD_DECLARE_CLASS(QWindow)
QT_USE_NAMESPACE
class CachedEntries: public QObject {
public:
CachedEntries(QDir::Filters filters) : mFilters(filters) {
QObject::connect(&mFSWatcher, &QFileSystemWatcher::directoryChanged, this, &CachedEntries::updateDirCache);
}
QString directory() const {
const QStringList &dirs = mFSWatcher.directories();
return (dirs.count() ? dirs[0] : QString());
}
QStringList entries() const {
return mQDirFilterEntryList;
}
void updateDirCache(const QString &path) {
mFSWatcher.removePaths(mFSWatcher.directories());
mFSWatcher.addPath(path);
mQDirFilterEntryList = QDir(path).entryList(mFilters);
}
private:
QFileSystemWatcher mFSWatcher;
QStringList mQDirFilterEntryList;
QDir::Filters mFilters;
};
typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
@ -91,9 +117,8 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
int mReturnCode;
SharedPointerFileDialogOptions mOptions;
QString *mLastFilterCheckPath;
CachedEntries *mCachedEntries;
QString *mCurrentSelection;
QStringList *mQDirFilterEntryList;
QStringList *mNameFilterDropDownList;
QStringList *mSelectedNameFilter;
}
@ -137,8 +162,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
[mSavePanel setDelegate:self];
mReturnCode = -1;
mHelper = helper;
mLastFilterCheckPath = new QString;
mQDirFilterEntryList = new QStringList;
mCachedEntries = new CachedEntries(mOptions->filter());
mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
QString selectedVisualNameFilter = mOptions->initiallySelectedNameFilter();
mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]);
@ -171,8 +195,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
- (void)dealloc
{
delete mLastFilterCheckPath;
delete mQDirFilterEntryList;
delete mCachedEntries;
delete mNameFilterDropDownList;
delete mSelectedNameFilter;
delete mCurrentSelection;
@ -303,12 +326,11 @@ static QString strippedText(QString s)
QString qtFileName = QT_PREPEND_NAMESPACE(QCFString::toQString)(filename);
QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
QString path = info.absolutePath();
if (path != *mLastFilterCheckPath){
*mLastFilterCheckPath = path;
*mQDirFilterEntryList = info.dir().entryList(mOptions->filter());
if (mCachedEntries->directory() != path) {
mCachedEntries->updateDirCache(path);
}
// Check if the QDir filter accepts the file:
if (!mQDirFilterEntryList->contains(info.fileName()))
if (!mCachedEntries->entries().contains(info.fileName()))
return NO;
// No filter means accept everything