From cca7611e260c8ba86da3b01a83e70447c1c362bc Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 23 May 2011 15:38:53 +1000 Subject: [PATCH] Ensure that showDirs is respected in FolderListModel Calling index() on a QDirModel can modify the filters applied. This patch to FolderListModel ensures that filtering is reset if required, so that programmatically selecting a subfolder in a folder does not cause that subfolder to become visible if showDirs is set to false. Task-number: QTBUG-17837 Reviewed-by: Martin Jones Change-Id: I449321d5170ecedf2a0cb36483d50020305a26dd --- .../qdeclarativefolderlistmodel.cpp | 64 ++++++++++++++++++---- .../folderlistmodel/qdeclarativefolderlistmodel.h | 1 + .../data/resetFiltering.qml | 5 ++ .../data/resetfiltering/innerdir/test2.txt | 1 + .../data/resetfiltering/test.txt | 1 + .../tst_qdeclarativefolderlistmodel.cpp | 36 +++++++++++- 6 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativefolderlistmodel/data/resetFiltering.qml create mode 100644 tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/innerdir/test2.txt create mode 100644 tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/test.txt diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp index 9fe01bf..8a91667 100644 --- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp @@ -53,7 +53,7 @@ class QDeclarativeFolderListModelPrivate { public: QDeclarativeFolderListModelPrivate() - : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0) { + : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0), showDirs(true), showDots(false), showOnlyReadable(false), insideRefresh(false) { nameFilters << QLatin1String("*"); } @@ -90,6 +90,10 @@ public: QDeclarativeFolderListModel::SortField sortField; bool sortReversed; int count; + bool showDirs; + bool showDots; + bool showOnlyReadable; + bool insideRefresh; }; /*! @@ -222,15 +226,39 @@ void QDeclarativeFolderListModel::setFolder(const QUrl &folder) { if (folder == d->folder) return; - QModelIndex index = d->model.index(folder.toLocalFile()); - if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) { + QModelIndex index = d->model.index(folder.toLocalFile()); // This can modify the filtering rules. + if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) { d->folder = folder; - QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "resetFiltering", Qt::QueuedConnection); // resetFiltering will invoke refresh(). emit folderChanged(); } } +void QDeclarativeFolderListModel::resetFiltering() +{ + // ensure that we reset the filtering rules, because the QDirModel::index() + // function isn't quite as const as it claims to be. + QDir::Filters filt = d->model.filter(); + + if (d->showDirs) + filt |= (QDir::AllDirs | QDir::Drives); + else + filt &= ~(QDir::AllDirs | QDir::Drives); + + if (d->showDots) + filt &= ~QDir::NoDotAndDotDot; + else + filt |= QDir::NoDotAndDotDot; + + if (d->showOnlyReadable) + filt |= QDir::Readable; + else + filt &= ~QDir::Readable; + + d->model.setFilter(filt); // this causes a refresh(). +} + /*! \qmlproperty url FolderListModel::parentFolder @@ -363,12 +391,17 @@ bool QDeclarativeFolderListModel::isFolder(int index) const void QDeclarativeFolderListModel::refresh() { + if (d->insideRefresh) + return; + d->insideRefresh = true; + d->folderIndex = QModelIndex(); if (d->count) { emit beginRemoveRows(QModelIndex(), 0, d->count-1); d->count = 0; emit endRemoveRows(); } + d->folderIndex = d->model.index(d->folder.toLocalFile()); int newcount = d->model.rowCount(d->folderIndex); if (newcount) { @@ -376,6 +409,8 @@ void QDeclarativeFolderListModel::refresh() d->count = newcount; emit endInsertRows(); } + + d->insideRefresh = false; // finished refreshing. } void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end) @@ -423,10 +458,13 @@ void QDeclarativeFolderListModel::setShowDirs(bool on) { if (!(d->model.filter() & QDir::AllDirs) == !on) return; - if (on) + if (on) { + d->showDirs = true; d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives); - else + } else { + d->showDirs = false; d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives)); + } } /*! @@ -448,10 +486,13 @@ void QDeclarativeFolderListModel::setShowDotAndDotDot(bool on) { if (!(d->model.filter() & QDir::NoDotAndDotDot) == on) return; - if (on) + if (on) { + d->showDots = true; d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot); - else + } else { + d->showDots = false; d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot); + } } /*! @@ -473,10 +514,13 @@ void QDeclarativeFolderListModel::setShowOnlyReadable(bool on) { if (!(d->model.filter() & QDir::Readable) == !on) return; - if (on) + if (on) { + d->showOnlyReadable = true; d->model.setFilter(d->model.filter() | QDir::Readable); - else + } else { + d->showOnlyReadable = false; d->model.setFilter(d->model.filter() & ~QDir::Readable); + } } //![code] diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h index 17dc84c..b0d91e4 100644 --- a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.h @@ -136,6 +136,7 @@ Q_SIGNALS: //![class end] private Q_SLOTS: void refresh(); + void resetFiltering(); void inserted(const QModelIndex &index, int start, int end); void removed(const QModelIndex &index, int start, int end); void handleDataChanged(const QModelIndex &start, const QModelIndex &end); diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetFiltering.qml b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetFiltering.qml new file mode 100644 index 0000000..d9a8ec4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetFiltering.qml @@ -0,0 +1,5 @@ +import Qt.labs.folderlistmodel 1.0 + +FolderListModel { + showDirs: false +} diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/innerdir/test2.txt b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/innerdir/test2.txt new file mode 100644 index 0000000..97e64bb --- /dev/null +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/innerdir/test2.txt @@ -0,0 +1 @@ +This file contains some text. diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/test.txt b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/test.txt new file mode 100644 index 0000000..97e64bb --- /dev/null +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/data/resetfiltering/test.txt @@ -0,0 +1 @@ +This file contains some text. diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp index ffd5d38..0594cbe 100644 --- a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp @@ -72,6 +72,7 @@ public slots: private slots: void basicProperties(); + void resetFiltering(); void refresh(); private: @@ -109,7 +110,7 @@ void tst_qdeclarativefolderlistmodel::basicProperties() QVERIFY(flm != 0); flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data")); - QTRY_COMPARE(flm->property("count").toInt(),2); // wait for refresh + QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(SRCDIR "/data")); QCOMPARE(flm->property("parentFolder").toUrl(), QUrl::fromLocalFile(SRCDIR)); QCOMPARE(flm->property("sortField").toInt(), int(Name)); @@ -125,6 +126,37 @@ void tst_qdeclarativefolderlistmodel::basicProperties() QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile("")); } +void tst_qdeclarativefolderlistmodel::resetFiltering() +{ + // see QTBUG-17837 + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/resetFiltering.qml")); + checkNoErrors(component); + + QAbstractListModel *flm = qobject_cast(component.create()); + QVERIFY(flm != 0); + + connect(flm, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), + this, SLOT(removed(const QModelIndex&,int,int))); + + flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering")); + QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test.txt" visible + int count = flm->rowCount(); + QCOMPARE(removeStart, 0); + QCOMPARE(removeEnd, count-1); + + flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering/innerdir")); + QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test2.txt" visible + count = flm->rowCount(); + QCOMPARE(removeStart, 0); + QCOMPARE(removeEnd, count-1); + + flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering")); + QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test.txt" visible + count = flm->rowCount(); + QCOMPARE(removeStart, 0); + QCOMPARE(removeEnd, count-1); +} + void tst_qdeclarativefolderlistmodel::refresh() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml")); @@ -134,7 +166,7 @@ void tst_qdeclarativefolderlistmodel::refresh() QVERIFY(flm != 0); flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data")); - QTRY_COMPARE(flm->property("count").toInt(),2); // wait for refresh + QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh int count = flm->rowCount(); -- 2.7.4