diff --git a/src/blackmisc/fileutils.cpp b/src/blackmisc/fileutils.cpp index 098e52b16..bcb30bae3 100644 --- a/src/blackmisc/fileutils.cpp +++ b/src/blackmisc/fileutils.cpp @@ -123,6 +123,7 @@ namespace BlackMisc QStringList CFileUtils::makeDirectoriesRelative(const QStringList &directories, const QString &rootDirectory, Qt::CaseSensitivity cs) { + // not using QDir::relativePath because I do not want "../xyz" paths if (rootDirectory.isEmpty() || rootDirectory == "/") { return directories; } const QString rd(rootDirectory.endsWith('/') ? rootDirectory.left(rootDirectory.length() - 1) : rootDirectory); const int p = rd.length(); @@ -146,10 +147,10 @@ namespace BlackMisc return CBuildConfig::isRunningOnWindowsNtPlatform() ? Qt::CaseInsensitive : Qt::CaseSensitive; } - bool CFileUtils::matchesExcludeDirectory(const QString &directoryPath, const QString &excludeDirectory, Qt::CaseSensitivity cs) + bool CFileUtils::matchesExcludeDirectory(const QString &directoryPath, const QString &excludePattern, Qt::CaseSensitivity cs) { - if (directoryPath.isEmpty() || excludeDirectory.isEmpty()) { return false; } - const QString ed(normalizeFilePathToQtStandard(excludeDirectory)); + if (directoryPath.isEmpty() || excludePattern.isEmpty()) { return false; } + const QString ed(normalizeFilePathToQtStandard(excludePattern)); return directoryPath.contains(ed, cs); } @@ -179,6 +180,28 @@ namespace BlackMisc return false; } + QStringList CFileUtils::removeSubDirectories(const QStringList &directories, Qt::CaseSensitivity cs) + { + if (directories.size() < 2) { return directories; } + QStringList dirs(directories); + dirs.removeDuplicates(); + dirs.sort(cs); + if (dirs.size() < 2) { return dirs; } + + QString last; + QStringList result; + for (const QString &path : dirs) + { + if (path.isEmpty()) { continue; } + if (last.isEmpty() || !path.startsWith(last, cs)) + { + result.append(path); + } + last = path; + } + return result; + } + QString CFileUtils::findFirstExisting(const QStringList &filesOrDirectory) { if (filesOrDirectory.isEmpty()) { return ""; } diff --git a/src/blackmisc/fileutils.h b/src/blackmisc/fileutils.h index d517d1680..01ad13919 100644 --- a/src/blackmisc/fileutils.h +++ b/src/blackmisc/fileutils.h @@ -62,13 +62,14 @@ namespace BlackMisc static QString normalizeFilePathToQtStandard(const QString &filePath); //! Make directory paths relative to root directory + //! \remark unlike QDir::relativePath here reltive paths are only created when a directory is a subdir of rootDirectory static QStringList makeDirectoriesRelative(const QStringList &directories, const QString &rootDirectory, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); //! Case sensitivity for current OS static Qt::CaseSensitivity osFileNameCaseSensitivity(); //! Is directory path matching the exclude path? - static bool matchesExcludeDirectory(const QString &directoryPath, const QString &excludeDirectory, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); + static bool matchesExcludeDirectory(const QString &directoryPath, const QString &excludePattern, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); //! Directory to be excluded? static bool isExcludedDirectory(const QDir &directory, const QStringList &excludeDirectories, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); @@ -79,7 +80,10 @@ namespace BlackMisc //! Directory to be excluded? static bool isExcludedDirectory(const QString &directoryPath, const QStringList &excludeDirectories, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); - //! Find first existing file or directory + //! Removes sub directories in list: A/B A/B/C B B/D -> A/B B returned + static QStringList removeSubDirectories(const QStringList &directories, Qt::CaseSensitivity cs = osFileNameCaseSensitivity()); + + //! Find first existing file or directory (means exists on file system) static QString findFirstExisting(const QStringList &filesOrDirectory); //! Returns path to first file in dir which matches the optional wildcard and predicate, or empty string.