|
|
@ -99,9 +99,13 @@ QString Utils::Fs::folderName(const QString &filePath) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* This function will first remove system cache files, e.g. `Thumbs.db`, |
|
|
|
* This function will first check if there are only system cache files, e.g. `Thumbs.db`, |
|
|
|
* `.DS_Store`. Then will try to remove the whole tree if the tree consist |
|
|
|
* `.DS_Store` and/or only temp files that end with '~', e.g. `filename~`. |
|
|
|
* only of folders |
|
|
|
* If they are the only files it will try to remove them and delete the folder. |
|
|
|
|
|
|
|
* This action will be performed for each subfolder starting from the deepest folder. |
|
|
|
|
|
|
|
* There is an inherent race condition here. A file might appear after it is checked |
|
|
|
|
|
|
|
* that only the above mentioned "useless" files exist but before the whole folder is removed. |
|
|
|
|
|
|
|
* In this case, the folder will not be removed but the "useless" files will be deleted. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path) |
|
|
|
bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -110,12 +114,12 @@ bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path) |
|
|
|
|
|
|
|
|
|
|
|
const QStringList deleteFilesList = { |
|
|
|
const QStringList deleteFilesList = { |
|
|
|
// Windows
|
|
|
|
// Windows
|
|
|
|
"Thumbs.db", |
|
|
|
QLatin1String("Thumbs.db"), |
|
|
|
"desktop.ini", |
|
|
|
QLatin1String("desktop.ini"), |
|
|
|
// Linux
|
|
|
|
// Linux
|
|
|
|
".directory", |
|
|
|
QLatin1String(".directory"), |
|
|
|
// Mac OS
|
|
|
|
// Mac OS
|
|
|
|
".DS_Store" |
|
|
|
QLatin1String(".DS_Store") |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// travel from the deepest folder and remove anything unwanted on the way out.
|
|
|
|
// travel from the deepest folder and remove anything unwanted on the way out.
|
|
|
@ -128,18 +132,25 @@ bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path) |
|
|
|
, [](const QString &l, const QString &r) { return l.count('/') > r.count('/'); }); |
|
|
|
, [](const QString &l, const QString &r) { return l.count('/') > r.count('/'); }); |
|
|
|
|
|
|
|
|
|
|
|
for (const QString &p : asConst(dirList)) { |
|
|
|
for (const QString &p : asConst(dirList)) { |
|
|
|
// remove unwanted files
|
|
|
|
|
|
|
|
for (const QString &f : deleteFilesList) { |
|
|
|
|
|
|
|
forceRemove(p + f); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove temp files on linux (file ends with '~'), e.g. `filename~`
|
|
|
|
|
|
|
|
const QDir dir(p); |
|
|
|
const QDir dir(p); |
|
|
|
|
|
|
|
// A deeper folder may have not been removed in the previous iteration
|
|
|
|
|
|
|
|
// so don't remove anything from this folder either.
|
|
|
|
|
|
|
|
if (!dir.isEmpty(QDir::Dirs | QDir::NoDotAndDotDot)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
const QStringList tmpFileList = dir.entryList(QDir::Files); |
|
|
|
const QStringList tmpFileList = dir.entryList(QDir::Files); |
|
|
|
for (const QString &f : tmpFileList) { |
|
|
|
|
|
|
|
if (f.endsWith('~')) |
|
|
|
// deleteFilesList contains unwanted files, usually created by the OS
|
|
|
|
|
|
|
|
// temp files on linux usually end with '~', e.g. `filename~`
|
|
|
|
|
|
|
|
const bool hasOtherFiles = std::any_of(tmpFileList.cbegin(), tmpFileList.cend(), [&deleteFilesList](const QString &f) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return (!f.endsWith('~') && !deleteFilesList.contains(f, Qt::CaseInsensitive)); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
if (hasOtherFiles) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const QString &f : tmpFileList) |
|
|
|
forceRemove(p + f); |
|
|
|
forceRemove(p + f); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove directory if empty
|
|
|
|
// remove directory if empty
|
|
|
|
dir.rmdir(p); |
|
|
|
dir.rmdir(p); |
|
|
|