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:
parent
c77f7229d5
commit
9557cc6536
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user