forked from qt-creator/qt-creator
ProjectExplorer: Support bulk removal of files in project tree
Find files with the same base name and offer the user to remove these as well, like we already do for the renaming action. Fixes: QTCREATORBUG-23869 Change-Id: Ibaa068e6e4d21b884e14c4ad1e95ec14b6e5e036 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
@@ -156,6 +156,7 @@
|
|||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPair>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
@@ -3604,38 +3605,54 @@ void ProjectExplorerPluginPrivate::removeFile()
|
|||||||
QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
|
QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
|
||||||
|
|
||||||
const Utils::FilePath filePath = currentNode->filePath();
|
const Utils::FilePath filePath = currentNode->filePath();
|
||||||
|
using NodeAndPath = QPair<const Node *, Utils::FilePath>;
|
||||||
|
QList<NodeAndPath> filesToRemove{qMakePair(currentNode, currentNode->filePath())};
|
||||||
|
QList<NodeAndPath> siblings;
|
||||||
|
for (const Node * const n : ProjectTree::siblingsWithSameBaseName(currentNode))
|
||||||
|
siblings << qMakePair(n, n->filePath());
|
||||||
|
|
||||||
Utils::RemoveFileDialog removeFileDialog(filePath.toString(), ICore::mainWindow());
|
Utils::RemoveFileDialog removeFileDialog(filePath.toString(), ICore::mainWindow());
|
||||||
|
if (removeFileDialog.exec() != QDialog::Accepted)
|
||||||
|
return;
|
||||||
|
|
||||||
if (removeFileDialog.exec() == QDialog::Accepted) {
|
const bool deleteFile = removeFileDialog.isDeleteFileChecked();
|
||||||
const bool deleteFile = removeFileDialog.isDeleteFileChecked();
|
|
||||||
|
|
||||||
// Re-read the current node, in case the project is re-parsed while the dialog is open
|
const QMessageBox::StandardButton reply = QMessageBox::question(
|
||||||
if (!ProjectTree::hasNode(currentNode)) {
|
Core::ICore::mainWindow(), tr("Remove More Files?"),
|
||||||
|
tr("Would you like to remove these files as well?\n %1")
|
||||||
|
.arg(Utils::transform<QStringList>(siblings, [](const NodeAndPath &np) {
|
||||||
|
return np.second.toFileInfo().fileName();
|
||||||
|
}).join("\n ")));
|
||||||
|
if (reply == QMessageBox::Yes)
|
||||||
|
filesToRemove << siblings;
|
||||||
|
|
||||||
|
for (const NodeAndPath &file : filesToRemove) {
|
||||||
|
// Nodes can become invalid if the project was re-parsed while the dialog was open
|
||||||
|
if (!ProjectTree::hasNode(file.first)) {
|
||||||
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
|
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
|
||||||
tr("File %1 was not removed, because the project has changed "
|
tr("File \"%1\" was not removed, because the project has changed "
|
||||||
"in the meantime.\nPlease try again.")
|
"in the meantime.\nPlease try again.")
|
||||||
.arg(filePath.toUserOutput()));
|
.arg(file.second.toUserOutput()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove from project
|
// remove from project
|
||||||
FolderNode *folderNode = currentNode->asFileNode()->parentFolderNode();
|
FolderNode *folderNode = file.first->asFileNode()->parentFolderNode();
|
||||||
QTC_ASSERT(folderNode, return);
|
QTC_ASSERT(folderNode, return);
|
||||||
|
|
||||||
const RemovedFilesFromProject status
|
const RemovedFilesFromProject status
|
||||||
= folderNode->removeFiles(QStringList(filePath.toString()));
|
= folderNode->removeFiles(QStringList(file.second.toString()));
|
||||||
const bool success = status == RemovedFilesFromProject::Ok
|
const bool success = status == RemovedFilesFromProject::Ok
|
||||||
|| (status == RemovedFilesFromProject::Wildcard
|
|| (status == RemovedFilesFromProject::Wildcard
|
||||||
&& removeFileDialog.isDeleteFileChecked());
|
&& removeFileDialog.isDeleteFileChecked());
|
||||||
if (!success) {
|
if (!success) {
|
||||||
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
|
TaskHub::addTask(BuildSystemTask(Task::Error,
|
||||||
tr("Could not remove file %1 from project %2.")
|
tr("Could not remove file \"%1\" from project \"%2\".")
|
||||||
.arg(filePath.toUserOutput())
|
.arg(filePath.toUserOutput(), folderNode->managingProject()->displayName()),
|
||||||
.arg(folderNode->managingProject()->displayName()));
|
folderNode->managingProject()->filePath()));
|
||||||
if (!deleteFile)
|
if (!deleteFile)
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileChangeBlocker changeGuard(filePath.toString());
|
FileChangeBlocker changeGuard(filePath.toString());
|
||||||
FileUtils::removeFile(filePath.toString(), deleteFile);
|
FileUtils::removeFile(filePath.toString(), deleteFile);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user