File patch-r890057.diff of Package kdelibs4
Subject: fixes for toggling hidden files
From: wstephenson@suse.de
Bug: kde#174788
Patch-upstream: 890057
--- kio/kio/kdirlister_p.h (revision 890056)
+++ kio/kio/kdirlister_p.h (revision 890057)
@@ -47,8 +47,6 @@ public:
complete = false;
autoUpdate = false;
- isShowingDotFiles = false;
- dirOnlyMode = false;
autoErrorHandling = false;
errorParent = 0;
@@ -63,8 +61,7 @@ public:
lstRemoveItems = 0;
refreshItemWasFiltered = false;
-
- changes = NONE;
+ hasPendingChanges = false;
window = 0;
m_cachedItemsJob = 0;
@@ -91,6 +88,21 @@ public:
void emitItemsDeleted(const KFileItemList &items);
void redirect( const KUrl& oldUrl, const KUrl& newUrl );
+ /**
+ * Should this item be visible according to the current filter settings?
+ */
+ bool isItemVisible(const KFileItem& item) const;
+
+ void prepareForSettingsChange() {
+ if (!hasPendingChanges) {
+ hasPendingChanges = true;
+ oldSettings = settings;
+ }
+ }
+
+ void emitChanges();
+
+
KDirLister *m_parent;
/**
@@ -105,12 +117,11 @@ public:
bool complete:1;
bool autoUpdate:1;
- bool isShowingDotFiles:1;
- bool dirOnlyMode:1;
bool delayedMimeTypes:1;
bool refreshItemWasFiltered:1;
+ bool hasPendingChanges:1; // i.e. settings != oldSettings
bool autoErrorHandling:2;
QWidget *errorParent;
@@ -129,16 +140,24 @@ public:
QList<QPair<KFileItem,KFileItem> > *lstRefreshItems;
KFileItemList *lstMimeFilteredItems, *lstRemoveItems;
- int changes;
-
QWidget *window; // Main window this lister is associated with
class CachedItemsJob;
CachedItemsJob* m_cachedItemsJob;
- QString nameFilter;
- QList<QRegExp> lstFilters, oldFilters;
- QStringList mimeFilter, oldMimeFilter;
- QStringList mimeExcludeFilter, oldMimeExcludeFilter;
+ QString nameFilter; // parsed into lstFilters
+
+ struct FilterSettings {
+ FilterSettings() : isShowingDotFiles(false), dirOnlyMode(false) {}
+ bool isShowingDotFiles;
+ bool dirOnlyMode;
+ QList<QRegExp> lstFilters;
+ QStringList mimeFilter;
+ QStringList mimeExcludeFilter;
+ };
+ FilterSettings settings;
+ FilterSettings oldSettings;
+
+ friend class KDirListerCache;
};
/**
--- kio/kio/kdirlister.h (revision 890056)
+++ kio/kio/kdirlister.h (revision 890057)
@@ -579,10 +579,6 @@ Q_SIGNALS:
void speed( int bytes_per_second );
protected:
- enum Changes {
- NONE=0, NAME_FILTER=1, MIME_FILTER=2, DOT_FILES=4, DIR_ONLY_MODE=8
- };
-
/**
* Called for every new item before emitting newItems().
* You may reimplement this method in a subclass to implement your own
--- kio/kio/kdirlister.cpp (revision 890056)
+++ kio/kio/kdirlister.cpp (revision 890057)
@@ -524,8 +524,8 @@ void KDirListerCache::forgetDirs( KDirLi
// Look for a manually-mounted directory inside
// If there's one, we can't keep a watch either, FAM would prevent unmounting the CDROM
// I hope this isn't too slow
- KFileItemList::const_iterator kit = item->lstItems.begin();
- const KFileItemList::const_iterator kend = item->lstItems.end();
+ KFileItemList::const_iterator kit = item->lstItems.constBegin();
+ KFileItemList::const_iterator kend = item->lstItems.constEnd();
for ( ; kit != kend && !containsManuallyMounted; ++kit )
if ( (*kit).isDir() && manually_mounted((*kit).url().path(), possibleMountPoints) )
containsManuallyMounted = true;
@@ -771,12 +771,12 @@ void KDirListerCache::slotFilesRemoved(
}
}
- QMap<QString, KFileItemList>::const_iterator rit = removedItemsByDir.begin();
- for(; rit != removedItemsByDir.end(); ++rit) {
+ QMap<QString, KFileItemList>::const_iterator rit = removedItemsByDir.constBegin();
+ for(; rit != removedItemsByDir.constEnd(); ++rit) {
// Tell the views about it before calling deleteDir.
// They might need the subdirs' file items (see the dirtree).
- DirectoryDataHash::const_iterator dit = directoryData.find(rit.key());
- if (dit != directoryData.end()) {
+ DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
+ if (dit != directoryData.constEnd()) {
itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
}
}
@@ -816,8 +816,8 @@ void KDirListerCache::slotFilesChanged(
}
}
- KUrl::List::const_iterator itdir = dirsToUpdate.begin();
- for (; itdir != dirsToUpdate.end() ; ++itdir)
+ KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
+ for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
updateDirectory( *itdir );
// ## TODO problems with current jobs listing/updating that dir
// ( see kde-2.2.2's kdirlister )
@@ -1481,8 +1481,8 @@ void KDirListerCache::slotUpdateResult(
}
KIO::UDSEntryList buf = jobs.value( job );
- KIO::UDSEntryList::const_iterator it = buf.begin();
- const KIO::UDSEntryList::const_iterator end = buf.end();
+ KIO::UDSEntryList::const_iterator it = buf.constBegin();
+ const KIO::UDSEntryList::const_iterator end = buf.constEnd();
for ( ; it != end; ++it )
{
// Form the complete url
@@ -1574,11 +1574,10 @@ void KDirListerCache::slotUpdateResult(
KIO::ListJob *KDirListerCache::jobForUrl( const QString& url, KIO::ListJob *not_job )
{
- KIO::ListJob *job;
- QMap< KIO::ListJob *, KIO::UDSEntryList >::const_iterator it = jobs.begin();
- while ( it != jobs.end() )
+ QMap< KIO::ListJob *, KIO::UDSEntryList >::const_iterator it = jobs.constBegin();
+ while ( it != jobs.constEnd() )
{
- job = it.key();
+ KIO::ListJob *job = it.key();
if ( joburl( job ).url(KUrl::RemoveTrailingSlash) == url && job != not_job )
return job;
++it;
@@ -1724,8 +1723,8 @@ void KDirListerCache::processPendingUpda
void KDirListerCache::printDebug()
{
kDebug(7004) << "Items in use:";
- QHash<QString, DirItem *>::const_iterator itu = itemsInUse.begin();
- const QHash<QString, DirItem *>::const_iterator ituend = itemsInUse.end();
+ QHash<QString, DirItem *>::const_iterator itu = itemsInUse.constBegin();
+ const QHash<QString, DirItem *>::const_iterator ituend = itemsInUse.constEnd();
for ( ; itu != ituend ; ++itu ) {
kDebug(7004) << " " << itu.key() << "URL:" << itu.value()->url
<< "rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() : KUrl() )
@@ -1735,8 +1734,8 @@ void KDirListerCache::printDebug()
}
kDebug(7004) << "Directory data:";
- DirectoryDataHash::const_iterator dit = directoryData.begin();
- for ( ; dit != directoryData.end(); ++dit )
+ DirectoryDataHash::const_iterator dit = directoryData.constBegin();
+ for ( ; dit != directoryData.constEnd(); ++dit )
{
QString list;
foreach ( KDirLister* listit, (*dit).listersCurrentlyListing )
@@ -1803,10 +1802,10 @@ KDirLister::~KDirLister()
bool KDirLister::openUrl( const KUrl& _url, OpenUrlFlags _flags )
{
// emit the current changes made to avoid an inconsistent treeview
- if ( d->changes != NONE && ( _flags & Keep ) )
+ if (d->hasPendingChanges && (_flags & Keep))
emitChanges();
- d->changes = NONE;
+ d->hasPendingChanges = false;
return kDirListerCache->listDir( this, _url, _flags & Keep, _flags & Reload );
}
@@ -1837,30 +1836,30 @@ void KDirLister::setAutoUpdate( bool _en
bool KDirLister::showingDotFiles() const
{
- return d->isShowingDotFiles;
+ return d->settings.isShowingDotFiles;
}
void KDirLister::setShowingDotFiles( bool _showDotFiles )
{
- if ( d->isShowingDotFiles == _showDotFiles )
+ if ( d->settings.isShowingDotFiles == _showDotFiles )
return;
- d->isShowingDotFiles = _showDotFiles;
- d->changes ^= DOT_FILES;
+ d->prepareForSettingsChange();
+ d->settings.isShowingDotFiles = _showDotFiles;
}
bool KDirLister::dirOnlyMode() const
{
- return d->dirOnlyMode;
+ return d->settings.dirOnlyMode;
}
void KDirLister::setDirOnlyMode( bool _dirsOnly )
{
- if ( d->dirOnlyMode == _dirsOnly )
+ if ( d->settings.dirOnlyMode == _dirsOnly )
return;
- d->dirOnlyMode = _dirsOnly;
- d->changes ^= DIR_ONLY_MODE;
+ d->prepareForSettingsChange();
+ d->settings.dirOnlyMode = _dirsOnly;
}
bool KDirLister::autoErrorHandlingEnabled() const
@@ -1886,97 +1885,62 @@ KUrl::List KDirLister::directories() con
void KDirLister::emitChanges()
{
- if ( d->changes == NONE )
- return;
-
- const int changes = d->changes;
- d->changes = NONE; // in case of recursion (testcase: enabling recursive scan in ktorrent, #174920)
-
- Q_FOREACH(const KUrl& dir, d->lstDirs) {
- KFileItemList deletedItems;
-
- const KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
- KFileItemList::const_iterator kit = itemList->begin();
- const KFileItemList::const_iterator kend = itemList->end();
- for ( ; kit != kend; ++kit )
- {
- if ( (*kit).text() == "." || (*kit).text() == ".." )
- continue;
-
- bool oldMime = true, newMime = true;
-
- if (changes & MIME_FILTER) {
- const QString mimetype = (*kit).mimetype();
- oldMime = doMimeFilter( mimetype, d->oldMimeFilter )
- && d->doMimeExcludeFilter( mimetype, d->oldMimeExcludeFilter );
- newMime = doMimeFilter( mimetype, d->mimeFilter )
- && d->doMimeExcludeFilter( mimetype, d->mimeExcludeFilter );
+ d->emitChanges();
+}
- if ( oldMime && !newMime )
- {
- deletedItems.append(*kit);
- continue;
- }
- }
+void KDirLister::Private::emitChanges()
+{
+ if (!hasPendingChanges)
+ return;
- if (changes & DIR_ONLY_MODE) {
- // the lister switched to dirOnlyMode
- if ( d->dirOnlyMode )
- {
- if ( !(*kit).isDir() )
- {
- deletedItems.append(*kit);
- }
+ // reset 'hasPendingChanges' now, in case of recursion
+ // (testcase: enabling recursive scan in ktorrent, #174920)
+ hasPendingChanges = false;
+
+ const Private::FilterSettings newSettings = settings;
+ settings = oldSettings; // temporarily
+
+ // Mark all items that are currently visible
+ Q_FOREACH(const KUrl& dir, lstDirs) {
+ KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
+ KFileItemList::iterator kit = itemList->begin();
+ const KFileItemList::iterator kend = itemList->end();
+ for (; kit != kend; ++kit) {
+ if (isItemVisible(*kit) && m_parent->matchesMimeFilter(*kit))
+ (*kit).mark();
+ else
+ (*kit).unmark();
}
- else if ( !(*kit).isDir() )
- d->addNewItem( *kit );
+ }
- continue;
- }
+ settings = newSettings;
- if ( (*kit).isHidden() )
- {
- if (changes & DOT_FILES) {
- // the lister switched to dot files mode
- if ( d->isShowingDotFiles )
- d->addNewItem( *kit );
- else
- {
- deletedItems.append(*kit);
- }
+ Q_FOREACH(const KUrl& dir, lstDirs) {
+ KFileItemList deletedItems;
- continue;
+ KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
+ KFileItemList::iterator kit = itemList->begin();
+ const KFileItemList::iterator kend = itemList->end();
+ for (; kit != kend; ++kit) {
+ KFileItem& item = *kit;
+ const QString text = item.text();
+ if (text == "." || text == "..")
+ continue;
+ const bool nowVisible = isItemVisible(item) && m_parent->matchesMimeFilter(item);
+ if (nowVisible && !item.isMarked())
+ addNewItem(item); // takes care of emitting newItem or itemsFilteredByMime
+ else if (!nowVisible && item.isMarked())
+ deletedItems.append(*kit);
}
- } else if (changes & NAME_FILTER) {
- bool oldName = (*kit).isDir() ||
- d->oldFilters.isEmpty() ||
- doNameFilter( (*kit).text(), d->oldFilters );
-
- bool newName = (*kit).isDir() ||
- d->lstFilters.isEmpty() ||
- doNameFilter( (*kit).text(), d->lstFilters );
-
- if ( oldName && !newName )
- {
- deletedItems.append(*kit);
- continue;
+ if (!deletedItems.isEmpty()) {
+ emit m_parent->itemsDeleted(deletedItems);
+ // for compat
+ Q_FOREACH(const KFileItem& item, deletedItems)
+ emit m_parent->deleteItem(item);
}
- else if ( !oldName && newName )
- d->addNewItem( *kit );
- }
-
- if ((changes & MIME_FILTER) && !oldMime && newMime)
- d->addNewItem( *kit );
+ emitItems();
}
-
- if (!deletedItems.isEmpty()) {
- emit itemsDeleted(deletedItems);
- // for compat
- Q_FOREACH(const KFileItem& item, deletedItems)
- emit deleteItem(item);
- }
- d->emitItems();
- }
+ oldSettings = settings;
}
void KDirLister::updateDirectory( const KUrl& _u )
@@ -2014,21 +1978,17 @@ KFileItem KDirLister::findByName( const
void KDirLister::setNameFilter( const QString& nameFilter )
{
- if ( !(d->changes & NAME_FILTER) )
- {
- d->oldFilters = d->lstFilters;
- }
-
- d->lstFilters.clear();
-
- d->nameFilter = nameFilter;
+ if (d->nameFilter == nameFilter)
+ return;
- // Split on white space
- const QStringList list = nameFilter.split( ' ', QString::SkipEmptyParts );
- for ( QStringList::const_iterator it = list.begin(); it != list.end(); ++it )
- d->lstFilters.append( QRegExp(*it, Qt::CaseInsensitive, QRegExp::Wildcard ) );
+ d->prepareForSettingsChange();
- d->changes |= NAME_FILTER;
+ d->settings.lstFilters.clear();
+ d->nameFilter = nameFilter;
+ // Split on white space
+ const QStringList list = nameFilter.split( ' ', QString::SkipEmptyParts );
+ for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
+ d->settings.lstFilters.append(QRegExp(*it, Qt::CaseInsensitive, QRegExp::Wildcard));
}
QString KDirLister::nameFilter() const
@@ -2038,52 +1998,47 @@ QString KDirLister::nameFilter() const
void KDirLister::setMimeFilter( const QStringList& mimeFilter )
{
- if ( !(d->changes & MIME_FILTER) )
- d->oldMimeFilter = d->mimeFilter;
-
- if ( mimeFilter.contains("application/octet-stream") ) // all files
- d->mimeFilter.clear();
- else
- d->mimeFilter = mimeFilter;
+ if (d->settings.mimeFilter == mimeFilter)
+ return;
- d->changes |= MIME_FILTER;
+ d->prepareForSettingsChange();
+ if (mimeFilter.contains("application/octet-stream")) // all files
+ d->settings.mimeFilter.clear();
+ else
+ d->settings.mimeFilter = mimeFilter;
}
void KDirLister::setMimeExcludeFilter( const QStringList& mimeExcludeFilter )
{
- if ( !(d->changes & MIME_FILTER) )
- d->oldMimeExcludeFilter = d->mimeExcludeFilter;
+ if (d->settings.mimeExcludeFilter == mimeExcludeFilter)
+ return;
- d->mimeExcludeFilter = mimeExcludeFilter;
- d->changes |= MIME_FILTER;
+ d->prepareForSettingsChange();
+ d->settings.mimeExcludeFilter = mimeExcludeFilter;
}
void KDirLister::clearMimeFilter()
{
- if ( !(d->changes & MIME_FILTER) )
- {
- d->oldMimeFilter = d->mimeFilter;
- d->oldMimeExcludeFilter = d->mimeExcludeFilter;
- }
- d->mimeFilter.clear();
- d->mimeExcludeFilter.clear();
- d->changes |= MIME_FILTER;
+ d->prepareForSettingsChange();
+ d->settings.mimeFilter.clear();
+ d->settings.mimeExcludeFilter.clear();
}
QStringList KDirLister::mimeFilters() const
{
- return d->mimeFilter;
+ return d->settings.mimeFilter;
}
bool KDirLister::matchesFilter( const QString& name ) const
{
- return doNameFilter( name, d->lstFilters );
+ return doNameFilter(name, d->settings.lstFilters);
}
bool KDirLister::matchesMimeFilter( const QString& mime ) const
{
- return doMimeFilter( mime, d->mimeFilter ) && d->doMimeExcludeFilter(mime,d->mimeExcludeFilter);
+ return doMimeFilter(mime, d->settings.mimeFilter) &&
+ d->doMimeExcludeFilter(mime, d->settings.mimeExcludeFilter);
}
// ================ protected methods ================ //
@@ -2095,10 +2050,10 @@ bool KDirLister::matchesFilter( const KF
if ( item.text() == ".." )
return false;
- if ( !d->isShowingDotFiles && item.isHidden() )
+ if ( !d->settings.isShowingDotFiles && item.isHidden() )
return false;
- if ( item.isDir() || d->lstFilters.isEmpty() )
+ if ( item.isDir() || d->settings.lstFilters.isEmpty() )
return true;
return matchesFilter( item.text() );
@@ -2106,11 +2061,11 @@ bool KDirLister::matchesFilter( const KF
bool KDirLister::matchesMimeFilter( const KFileItem& item ) const
{
- Q_ASSERT( !item.isNull() );
- // Don't lose time determining the mimetype if there is no filter
- if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() )
- return true;
- return matchesMimeFilter( item.mimetype() );
+ Q_ASSERT(!item.isNull());
+ // Don't lose time determining the mimetype if there is no filter
+ if (d->settings.mimeFilter.isEmpty() && d->settings.mimeExcludeFilter.isEmpty())
+ return true;
+ return matchesMimeFilter(item.mimetype());
}
bool KDirLister::doNameFilter( const QString& name, const QList<QRegExp>& filters ) const
@@ -2165,8 +2120,8 @@ void KDirLister::handleError( KIO::Job *
void KDirLister::Private::addNewItem( const KFileItem &item )
{
- if ( ( dirOnlyMode && !item.isDir() ) || !m_parent->matchesFilter( item ) )
- return; // No reason to continue... bailing out here prevents a mimetype scan.
+ if (!isItemVisible(item))
+ return; // No reason to continue... bailing out here prevents a mimetype scan.
if ( m_parent->matchesMimeFilter( item ) )
{
@@ -2202,21 +2157,12 @@ void KDirLister::Private::addNewItems( c
void KDirLister::Private::aboutToRefreshItem( const KFileItem &item )
{
- // The code here follows the logic in addNewItem
- if ( ( dirOnlyMode && !item.isDir() ) || !m_parent->matchesFilter( item ) )
- refreshItemWasFiltered = true;
- else if ( !m_parent->matchesMimeFilter( item ) )
- refreshItemWasFiltered = true;
- else
- refreshItemWasFiltered = false;
+ refreshItemWasFiltered = !isItemVisible(item) || !m_parent->matchesMimeFilter(item);
}
void KDirLister::Private::addRefreshItem( const KFileItem& oldItem, const KFileItem& item )
{
- bool isExcluded = (dirOnlyMode && !item.isDir()) || !m_parent->matchesFilter( item );
-
- if ( !isExcluded && m_parent->matchesMimeFilter( item ) )
- {
+ if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
if ( refreshItemWasFiltered )
{
if ( !lstNewItems ) {
@@ -2291,12 +2237,18 @@ void KDirLister::Private::emitItems()
void KDirLister::Private::emitDeleteItem( const KFileItem &item )
{
- if ( ( dirOnlyMode && !item.isDir() ) || !m_parent->matchesFilter( item ) )
- return; // No reason to continue... bailing out here prevents a mimetype scan.
- if ( m_parent->matchesMimeFilter( item ) )
- {
- emit m_parent->deleteItem( item );
- }
+ if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
+ emit m_parent->deleteItem(item);
+ }
+}
+
+bool KDirLister::Private::isItemVisible(const KFileItem& item) const
+{
+ // Note that this doesn't include mime filters, because
+ // of the itemsFilteredByMime signal. Filtered-by-mime items are
+ // considered "visible", they are just visible via a different signal...
+ return (!settings.dirOnlyMode || item.isDir())
+ && m_parent->matchesFilter(item);
}
void KDirLister::Private::emitItemsDeleted(const KFileItemList &_items)
@@ -2305,13 +2257,11 @@ void KDirLister::Private::emitItemsDelet
QMutableListIterator<KFileItem> it(items);
while (it.hasNext()) {
const KFileItem& item = it.next();
- if ((dirOnlyMode && !item.isDir())
- || !m_parent->matchesFilter(item)
- || !m_parent->matchesMimeFilter(item) ) { // do this one last
- it.remove();
- } else {
+ if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
// for compat
emit m_parent->deleteItem(item);
+ } else {
+ it.remove();
}
}
if (!items.isEmpty())
@@ -2466,14 +2416,14 @@ KFileItemList KDirLister::itemsForDir( c
else // only items passing the filters
{
KFileItemList result;
- KFileItemList::const_iterator kit = allItems->begin();
- const KFileItemList::const_iterator kend = allItems->end();
+ KFileItemList::const_iterator kit = allItems->constBegin();
+ const KFileItemList::const_iterator kend = allItems->constEnd();
for ( ; kit != kend; ++kit )
{
- KFileItem item = *kit;
- bool isExcluded = (d->dirOnlyMode && !item.isDir()) || !matchesFilter( item );
- if ( !isExcluded && matchesMimeFilter( item ) )
- result.append( item );
+ const KFileItem& item = *kit;
+ if (d->isItemVisible(item) && matchesMimeFilter(item)) {
+ result.append(item);
+ }
}
return result;
}
@@ -2497,7 +2447,13 @@ void KDirLister::Private::redirect( cons
url = newUrl;
}
- lstDirs[ lstDirs.indexOf( oldUrl ) ] = newUrl;
+ const int idx = lstDirs.indexOf( oldUrl );
+ if (idx == -1) {
+ kWarning(7004) << "Unexpected redirection from" << oldUrl << "to" << newUrl
+ << "but this dirlister is currently listing" << lstDirs;
+ } else {
+ lstDirs[ idx ] = newUrl;
+ }
if ( lstDirs.count() == 1 ) {
emit m_parent->clear();
--- kio/tests/kdirmodeltest.cpp (revision 890056)
+++ kio/tests/kdirmodeltest.cpp (revision 890057)
@@ -40,15 +40,20 @@
QTEST_KDEMAIN( KDirModelTest, NoGUI )
#ifndef Q_WS_WIN
-#define SPECIALCHARS "specialchars%:"
+#define SPECIALCHARS "specialchars%:.pdf"
#else
-#define SPECIALCHARS "specialchars%"
+#define SPECIALCHARS "specialchars%.pdf"
#endif
+Q_DECLARE_METATYPE(KFileItemList)
+
void KDirModelTest::initTestCase()
{
qRegisterMetaType<QModelIndex>("QModelIndex"); // beats me why Qt doesn't do that
+ qRegisterMetaType<KFileItemList>("KFileItemList");
+
+ m_dirModelForExpand = 0;
s_referenceTimeStamp = QDateTime::currentDateTime().addSecs( -30 ); // 30 seconds ago
m_tempDir = 0;
m_topLevelFileNames << "toplevelfile_1"
@@ -70,7 +75,9 @@ void KDirModelTest::recreateTestData()
* PATH/toplevelfile_1
* PATH/toplevelfile_2
* PATH/toplevelfile_3
- * PATH/specialchars%:
+ * PATH/specialchars%:.pdf
+ * PATH/.hidden
+ * PATH/.hidden2
* PATH/subdir
* PATH/subdir/testfile
* PATH/subdir/subsubdir
@@ -80,6 +87,8 @@ void KDirModelTest::recreateTestData()
foreach(const QString &f, m_topLevelFileNames) {
createTestFile(path+f);
}
+ createTestFile(path+".hidden");
+ createTestFile(path+".hidden2");
createTestDirectory(path+"subdir");
createTestDirectory(path+"subdir/subsubdir", NoSymlink);
@@ -112,6 +121,9 @@ void KDirModelTest::cleanup()
{
disconnect(&m_dirModel, 0, &m_eventLoop, 0);
disconnect(m_dirModel.dirLister(), 0, this, 0);
+ m_dirModel.dirLister()->setNameFilter(QString());
+ m_dirModel.dirLister()->setMimeFilter(QStringList());
+ m_dirModel.dirLister()->emitChanges();
}
void KDirModelTest::collectKnownIndexes()
@@ -534,26 +546,25 @@ void KDirModelTest::testFilter()
QVERIFY(m_dirIndex.isValid());
const int oldTopLevelRowCount = m_dirModel.rowCount();
const int oldSubdirRowCount = m_dirModel.rowCount(m_dirIndex);
+ QSignalSpy spyItemsFilteredByMime(m_dirModel.dirLister(), SIGNAL(itemsFilteredByMime(KFileItemList)));
+ QSignalSpy spyItemsDeleted(m_dirModel.dirLister(), SIGNAL(itemsDeleted(KFileItemList)));
QSignalSpy spyRowsRemoved(&m_dirModel, SIGNAL(rowsRemoved(QModelIndex,int,int)));
m_dirModel.dirLister()->setNameFilter("toplevel*");
QCOMPARE(m_dirModel.rowCount(), oldTopLevelRowCount); // no change yet
QCOMPARE(m_dirModel.rowCount(m_dirIndex), oldSubdirRowCount); // no change yet
m_dirModel.dirLister()->emitChanges();
- const int expectedTopLevelRowCount = 4; // 3 toplevel* files, one subdir
- const int expectedSubdirRowCount = 1; // the files get filtered out, the subdir remains
+ QCOMPARE(m_dirModel.rowCount(), 4); // 3 toplevel* files, one subdir
+ QCOMPARE(m_dirModel.rowCount(m_dirIndex), 1); // the files get filtered out, the subdir remains
- //while (m_dirModel.rowCount() > expectedTopLevelRowCount) {
- // QTest::qWait(20);
- // kDebug() << "rowCount=" << m_dirModel.rowCount();
- //}
- QCOMPARE(m_dirModel.rowCount(), expectedTopLevelRowCount);
-
- //while (m_dirModel.rowCount(m_dirIndex) > expectedSubdirRowCount) {
- // QTest::qWait(20);
- // kDebug() << "rowCount in subdir=" << m_dirModel.rowCount(m_dirIndex);
- //}
- QCOMPARE(m_dirModel.rowCount(m_dirIndex), expectedSubdirRowCount);
+ QCOMPARE(spyRowsRemoved.count(), 3); // once for every dir
+ QCOMPARE(spyItemsDeleted.count(), 3); // once for every dir
+ QCOMPARE(spyItemsDeleted[0][0].value<KFileItemList>().count(), 1); // one from toplevel ('specialchars')
+ QCOMPARE(spyItemsDeleted[1][0].value<KFileItemList>().count(), 2); // two from subdir
+ QCOMPARE(spyItemsDeleted[2][0].value<KFileItemList>().count(), 1); // one from subsubdir
+ QCOMPARE(spyItemsFilteredByMime.count(), 0);
+ spyItemsDeleted.clear();
+ spyItemsFilteredByMime.clear();
// Reset the filter
kDebug() << "reset to no filter";
@@ -562,12 +573,78 @@ void KDirModelTest::testFilter()
QCOMPARE(m_dirModel.rowCount(), oldTopLevelRowCount);
QCOMPARE(m_dirModel.rowCount(m_dirIndex), oldSubdirRowCount);
+ QCOMPARE(spyItemsDeleted.count(), 0);
+ QCOMPARE(spyItemsFilteredByMime.count(), 0);
+
+ // The order of things changed because of filtering.
+ // Fill again, so that m_fileIndex etc. are correct again.
+ fillModel(true);
+}
+
+void KDirModelTest::testMimeFilter()
+{
+ QVERIFY(m_dirIndex.isValid());
+ const int oldTopLevelRowCount = m_dirModel.rowCount();
+ const int oldSubdirRowCount = m_dirModel.rowCount(m_dirIndex);
+ QSignalSpy spyItemsFilteredByMime(m_dirModel.dirLister(), SIGNAL(itemsFilteredByMime(KFileItemList)));
+ QSignalSpy spyItemsDeleted(m_dirModel.dirLister(), SIGNAL(itemsDeleted(KFileItemList)));
+ QSignalSpy spyRowsRemoved(&m_dirModel, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ m_dirModel.dirLister()->setMimeFilter(QStringList() << "application/pdf");
+ QCOMPARE(m_dirModel.rowCount(), oldTopLevelRowCount); // no change yet
+ QCOMPARE(m_dirModel.rowCount(m_dirIndex), oldSubdirRowCount); // no change yet
+ m_dirModel.dirLister()->emitChanges();
+
+ QCOMPARE(m_dirModel.rowCount(), 1); // 1 pdf files, no subdir anymore
+
+ QVERIFY(spyRowsRemoved.count() >= 1); // depends on contiguity...
+ QVERIFY(spyItemsDeleted.count() >= 1); // once for every dir
+ // Maybe it would make sense to have those items in itemsFilteredByMime,
+ // but well, for the only existing use of that signal (mime filter plugin),
+ // it's not really necessary, the plugin has seen those files before anyway.
+ // The signal is mostly useful for the case of listing a dir with a mime filter set.
+ //QCOMPARE(spyItemsFilteredByMime.count(), 1);
+ //QCOMPARE(spyItemsFilteredByMime[0][0].value<KFileItemList>().count(), 4);
+ spyItemsDeleted.clear();
+ spyItemsFilteredByMime.clear();
+
+ // Reset the filter
+ kDebug() << "reset to no filter";
+ m_dirModel.dirLister()->setMimeFilter(QStringList());
+ m_dirModel.dirLister()->emitChanges();
+
+ QCOMPARE(m_dirModel.rowCount(), oldTopLevelRowCount);
+ QCOMPARE(spyItemsDeleted.count(), 0);
+ QCOMPARE(spyItemsFilteredByMime.count(), 0);
// The order of things changed because of filtering.
// Fill again, so that m_fileIndex etc. are correct again.
fillModel(true);
}
+void KDirModelTest::testShowHiddenFiles() // #174788
+{
+ KDirLister* dirLister = m_dirModel.dirLister();
+
+ QSignalSpy spyRowsRemoved(&m_dirModel, SIGNAL(rowsRemoved(QModelIndex, int, int)));
+ QSignalSpy spyNewItems(dirLister, SIGNAL(newItems(KFileItemList)));
+ QSignalSpy spyRowsInserted(&m_dirModel, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ dirLister->setShowingDotFiles(true);
+ dirLister->emitChanges();
+ const int numberOfDotFiles = 2;
+ QCOMPARE(spyNewItems.count(), 1);
+ QCOMPARE(spyNewItems[0][0].value<KFileItemList>().count(), numberOfDotFiles);
+ QCOMPARE(spyRowsInserted.count(), 1);
+ QCOMPARE(spyRowsRemoved.count(), 0);
+ spyNewItems.clear();
+ spyRowsInserted.clear();
+
+ dirLister->setShowingDotFiles(false);
+ dirLister->emitChanges();
+ QCOMPARE(spyNewItems.count(), 0);
+ QCOMPARE(spyRowsInserted.count(), 0);
+ QCOMPARE(spyRowsRemoved.count(), 1);
+}
+
void KDirModelTest::testMultipleSlashes()
{
const QString path = m_tempDir->name();
--- kio/tests/kdirmodeltest.h (revision 890056)
+++ kio/tests/kdirmodeltest.h (revision 890057)
@@ -46,6 +46,8 @@ private Q_SLOTS:
void testExpandToUrl_data();
void testExpandToUrl();
void testFilter();
+ void testMimeFilter();
+ void testShowHiddenFiles();
void testMultipleSlashes();
void testUrlWithRef();
void testUrlWithHost();
Index: kio/kio/kdirlister_p.h
===================================================================
Index: kio/kio/kdirlister.h
===================================================================
Index: kio/kio/kdirlister.cpp
===================================================================
Index: kio/tests/kdirmodeltest.cpp
===================================================================
Index: kio/tests/kdirmodeltest.h
===================================================================