From 18b0993d3bf22e03d667aacf1a01928d063aef34 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Fri, 30 Mar 2012 15:28:47 +0200 Subject: [PATCH] Now using FindFirstFileEx() on supported OS. Should be a bit faster, as we can request the FindExSearchLimitToDirectories search limit. --- doc/Changelog.html | 1 + src/Config.h | 4 ++-- src/Model_FileSystem.cpp | 58 +++++++++++++++++++++++++++++++++++++++--------- src/Model_FileSystem.h | 5 +++-- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/doc/Changelog.html b/doc/Changelog.html index 3af23b5e..3553b166 100644 --- a/doc/Changelog.html +++ b/doc/Changelog.html @@ -34,6 +34,7 @@ a:visited { color: #0000EE; }
  • Implemented coalescing of update signals to reduce the CPU usage of the LameXP process (details)
  • Run more than four instances in parallel on systems with more than four CPU cores (details)
  • Improved handling of different character encodings for Playlist and Cue Sheet import +
  • Tweaked directory outline on "output folder" tab for improved performance (hopefully)
  • Improved LameXP inter-process communication by adding queue support
  • Workaround for a bug that causes MediaInfo to not detect the duration of Wave files (64-Bit only)
  • Prevent LameXP from blocking a system shutdown (encoding process is aborted, if necessary) diff --git a/src/Config.h b/src/Config.h index 07c15aec..6672ae56 100644 --- a/src/Config.h +++ b/src/Config.h @@ -29,8 +29,8 @@ #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 4 #define VER_LAMEXP_TYPE Beta -#define VER_LAMEXP_PATCH 10 -#define VER_LAMEXP_BUILD 939 +#define VER_LAMEXP_PATCH 11 +#define VER_LAMEXP_BUILD 942 /////////////////////////////////////////////////////////////////////////////// // Tool versions (minimum expected versions!) diff --git a/src/Model_FileSystem.cpp b/src/Model_FileSystem.cpp index 91949728..de1b5af8 100644 --- a/src/Model_FileSystem.cpp +++ b/src/Model_FileSystem.cpp @@ -25,10 +25,13 @@ #include #include #include +#include #define IS_DIR(ATTR) (((ATTR) & FILE_ATTRIBUTE_DIRECTORY) && (!((ATTR) & FILE_ATTRIBUTE_HIDDEN))) #define NO_DOT_OR_DOTDOT(STR) (wcscmp((STR), L".") && wcscmp((STR), L"..")) +typedef HANDLE (WINAPI *FindFirstFileExFun)(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags); + /////////////////////////////////////////////////////////////////////////////// // Dummy QFileIconProvider class /////////////////////////////////////////////////////////////////////////////// @@ -157,7 +160,7 @@ bool QFileSystemModelEx::hasChildren(const QModelIndex &parent) const { if(parent.isValid()) { - return (QFileSystemModel::rowCount(parent) > 0) || hasSubfoldersCached(filePath(parent)); + return /*(QFileSystemModel::rowCount(parent) > 0) ||*/ hasSubfoldersCached(filePath(parent)); } return true; @@ -183,38 +186,71 @@ void QFileSystemModelEx::fetchMore(const QModelIndex &parent) QFileSystemModel::fetchMore(parent); } +QModelIndex QFileSystemModelEx::index(const QString &path, int column) const +{ + QFileInfo info(path); + if(info.exists() && info.isDir()) + { + QStringList parts = QDir::fromNativeSeparators(info.canonicalFilePath()).split('/', QString::SkipEmptyParts); + for(int i = 2; i <= parts.count(); i++) + { + QFileInfo currentPath(((QStringList) parts.mid(0, i)).join("/")); + if((!currentPath.exists()) || (!currentPath.isDir()) || currentPath.isHidden()) + { + return QModelIndex(); + } + } + return QFileSystemModel::index(path, column); + } + return QModelIndex(); +} /* ------------------------ */ /* STATIC FUNCTIONS BELOW */ /* ------------------------ */ -QHash QFileSystemModelEx::s_hasFolderCache; -QMutex QFileSystemModelEx::s_hasFolderMutex; +QHash QFileSystemModelEx::s_hasSubfolderCache; +QMutex QFileSystemModelEx::s_hasSubfolderMutex; bool QFileSystemModelEx::hasSubfoldersCached(const QString &path) { - QMutexLocker lock(&s_hasFolderMutex); + QMutexLocker lock(&s_hasSubfolderMutex); - if(s_hasFolderCache.contains(path)) + if(s_hasSubfolderCache.contains(path)) { - return s_hasFolderCache.value(path); + return s_hasSubfolderCache.value(path); } bool bChildren = hasSubfolders(path); - s_hasFolderCache.insert(path, bChildren); + s_hasSubfolderCache.insert(path, bChildren); return bChildren; } void QFileSystemModelEx::removeFromCache(const QString &path) { - QMutexLocker lock(&s_hasFolderMutex); - s_hasFolderCache.remove(path); + QMutexLocker lock(&s_hasSubfolderMutex); + s_hasSubfolderCache.remove(path); } bool QFileSystemModelEx::hasSubfolders(const QString &path) { - bool bChildren = false; WIN32_FIND_DATAW findData; - HANDLE h = FindFirstFileW(QWCHAR(QDir::toNativeSeparators(path + "/*")), &findData); + static bool FindFirstFileExInitialized = false; + static FindFirstFileExFun FindFirstFileExPtr = NULL; + + if(!FindFirstFileExInitialized) + { + QLibrary Kernel32Lib("kernel32.dll"); + FindFirstFileExPtr = (FindFirstFileExFun) Kernel32Lib.resolve("FindFirstFileExW"); + FindFirstFileExInitialized = true; + } + + WIN32_FIND_DATAW findData; + bool bChildren = false; + + HANDLE h = (FindFirstFileExPtr) + ? FindFirstFileExPtr(QWCHAR(QDir::toNativeSeparators(path + "/*")), FindExInfoStandard, &findData, FindExSearchLimitToDirectories, NULL, 0) + : FindFirstFileW(QWCHAR(QDir::toNativeSeparators(path + "/*")), &findData); + if(h != INVALID_HANDLE_VALUE) { if(NO_DOT_OR_DOTDOT(findData.cFileName)) diff --git a/src/Model_FileSystem.h b/src/Model_FileSystem.h index 674d68a4..65539bd5 100644 --- a/src/Model_FileSystem.h +++ b/src/Model_FileSystem.h @@ -35,12 +35,13 @@ public: virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; virtual void fetchMore(const QModelIndex &parent); + virtual QModelIndex index(const QString &path, int column = 0) const; private: QFileIconProviderEx *m_myIconProvider; - static QHash s_hasFolderCache; - static QMutex s_hasFolderMutex; + static QHash s_hasSubfolderCache; + static QMutex s_hasSubfolderMutex; static bool hasSubfolders(const QString &path); static bool hasSubfoldersCached(const QString &path); -- 2.11.4.GIT