forked from qt-creator/qt-creator
ProjectExplorer: Check if the project can rename a specific file
before renaming the file. This adds a new api: FolderNode::canRename(oldFileName, newFileName) that asks the project manager if a specific file renaming could be applied to the project file. Change-Id: I77bae56db06d81fd03e590285d6079abea2c514b Task-number: QTCREATORBUG-14521 Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
@@ -3264,11 +3264,28 @@ void ProjectExplorerPluginPrivate::handleRenameFile()
|
|||||||
void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
QString orgFilePath = node->path().toFileInfo().absoluteFilePath();
|
QString orgFilePath = node->path().toFileInfo().absoluteFilePath();
|
||||||
|
FolderNode *folderNode = node->parentFolderNode();
|
||||||
|
QString projectFileName = folderNode->projectNode()->path().fileName();
|
||||||
|
|
||||||
|
|
||||||
|
if (!folderNode->canRenameFile(orgFilePath, newFilePath)) {
|
||||||
|
QTimer::singleShot(0, [orgFilePath, newFilePath, projectFileName] {
|
||||||
|
int res = QMessageBox::question(ICore::mainWindow(),
|
||||||
|
tr("Project Editing Failed"),
|
||||||
|
tr("The project file %1 cannot be automatically changed\n\n"
|
||||||
|
"Rename %2 to %3 anyway?")
|
||||||
|
.arg(projectFileName)
|
||||||
|
.arg(orgFilePath)
|
||||||
|
.arg(newFilePath));
|
||||||
|
if (res == QMessageBox::Yes)
|
||||||
|
FileUtils::renameFile(orgFilePath, newFilePath);
|
||||||
|
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (FileUtils::renameFile(orgFilePath, newFilePath)) {
|
if (FileUtils::renameFile(orgFilePath, newFilePath)) {
|
||||||
// Tell the project plugin about rename
|
// Tell the project plugin about rename
|
||||||
FolderNode *folderNode = node->parentFolderNode();
|
|
||||||
QString projectFileName = folderNode->projectNode()->path().fileName();
|
|
||||||
if (!folderNode->renameFile(orgFilePath, newFilePath)) {
|
if (!folderNode->renameFile(orgFilePath, newFilePath)) {
|
||||||
QString renameFileError = tr("The file %1 was renamed to %2, but the project file %3 could not be automatically changed.")
|
QString renameFileError = tr("The file %1 was renamed to %2, but the project file %3 could not be automatically changed.")
|
||||||
.arg(orgFilePath)
|
.arg(orgFilePath)
|
||||||
|
|||||||
@@ -357,6 +357,13 @@ bool FolderNode::deleteFiles(const QStringList &filePaths)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FolderNode::canRenameFile(const QString &filePath, const QString &newFilePath)
|
||||||
|
{
|
||||||
|
if (projectNode())
|
||||||
|
return projectNode()->canRenameFile(filePath, newFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool FolderNode::renameFile(const QString &filePath, const QString &newFilePath)
|
bool FolderNode::renameFile(const QString &filePath, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
if (projectNode())
|
if (projectNode())
|
||||||
@@ -629,6 +636,13 @@ bool ProjectNode::deleteFiles(const QStringList &filePaths)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProjectNode::canRenameFile(const QString &filePath, const QString &newFilePath)
|
||||||
|
{
|
||||||
|
Q_UNUSED(filePath);
|
||||||
|
Q_UNUSED(newFilePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
|
bool ProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
Q_UNUSED(filePath)
|
Q_UNUSED(filePath)
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ public:
|
|||||||
virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
|
virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
|
||||||
virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
|
virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
|
||||||
virtual bool deleteFiles(const QStringList &filePaths);
|
virtual bool deleteFiles(const QStringList &filePaths);
|
||||||
|
virtual bool canRenameFile(const QString &filePath, const QString &newFilePath);
|
||||||
virtual bool renameFile(const QString &filePath, const QString &newFilePath);
|
virtual bool renameFile(const QString &filePath, const QString &newFilePath);
|
||||||
|
|
||||||
class AddNewInformation
|
class AddNewInformation
|
||||||
@@ -252,6 +253,7 @@ public:
|
|||||||
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0) override;
|
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0) override;
|
||||||
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0) override;
|
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0) override;
|
||||||
bool deleteFiles(const QStringList &filePaths) override;
|
bool deleteFiles(const QStringList &filePaths) override;
|
||||||
|
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
|
||||||
bool renameFile(const QString &filePath, const QString &newFilePath) override;
|
bool renameFile(const QString &filePath, const QString &newFilePath) override;
|
||||||
|
|
||||||
// by default returns false
|
// by default returns false
|
||||||
|
|||||||
@@ -1108,6 +1108,20 @@ bool QmakePriFileNode::deleteFiles(const QStringList &filePaths)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmakePriFileNode::canRenameFile(const QString &filePath, const QString &newFilePath)
|
||||||
|
{
|
||||||
|
if (newFilePath.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool changeProFileOptional = deploysFolder(QFileInfo(filePath).absolutePath());
|
||||||
|
if (changeProFileOptional)
|
||||||
|
return true;
|
||||||
|
Utils::MimeDatabase mdb;
|
||||||
|
const Utils::MimeType mt = mdb.mimeTypeForFile(newFilePath);
|
||||||
|
|
||||||
|
return renameFile(filePath, newFilePath, mt.name(), Change::TestOnly);
|
||||||
|
}
|
||||||
|
|
||||||
bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFilePath)
|
bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFilePath)
|
||||||
{
|
{
|
||||||
if (newFilePath.isEmpty())
|
if (newFilePath.isEmpty())
|
||||||
@@ -1116,15 +1130,10 @@ bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFil
|
|||||||
bool changeProFileOptional = deploysFolder(QFileInfo(filePath).absolutePath());
|
bool changeProFileOptional = deploysFolder(QFileInfo(filePath).absolutePath());
|
||||||
Utils::MimeDatabase mdb;
|
Utils::MimeDatabase mdb;
|
||||||
const Utils::MimeType mt = mdb.mimeTypeForFile(newFilePath);
|
const Utils::MimeType mt = mdb.mimeTypeForFile(newFilePath);
|
||||||
QStringList dummy;
|
|
||||||
|
|
||||||
changeFiles(mt.name(), QStringList() << filePath, &dummy, RemoveFromProFile);
|
if (renameFile(filePath, newFilePath, mt.name()))
|
||||||
if (!dummy.isEmpty() && !changeProFileOptional)
|
|
||||||
return false;
|
|
||||||
changeFiles(mt.name(), QStringList() << newFilePath, &dummy, AddToProFile);
|
|
||||||
if (!dummy.isEmpty() && !changeProFileOptional)
|
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
|
return changeProFileOptional;
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringList &files, Node *context) const
|
FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringList &files, Node *context) const
|
||||||
@@ -1235,10 +1244,47 @@ QPair<ProFile *, QStringList> QmakePriFileNode::readProFile(const QString &file)
|
|||||||
return qMakePair(includeFile, lines);
|
return qMakePair(includeFile, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmakePriFileNode::prepareForChange()
|
||||||
|
{
|
||||||
|
return saveModifiedEditors() && ensureWriteableProFile(m_projectFilePath.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmakePriFileNode::renameFile(const QString &oldName,
|
||||||
|
const QString &newName,
|
||||||
|
const QString &mimeType,
|
||||||
|
Change mode)
|
||||||
|
{
|
||||||
|
if (!prepareForChange())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QPair<ProFile *, QStringList> pair = readProFile(m_projectFilePath.toString());
|
||||||
|
ProFile *includeFile = pair.first;
|
||||||
|
QStringList lines = pair.second;
|
||||||
|
|
||||||
|
if (!includeFile)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QDir priFileDir = QDir(m_qmakeProFileNode->m_projectDir);
|
||||||
|
QStringList notChanged = ProWriter::removeFiles(includeFile, &lines, priFileDir,
|
||||||
|
QStringList(oldName), varNamesForRemoving());
|
||||||
|
if (!notChanged.isEmpty()) {
|
||||||
|
includeFile->deref();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProWriter::addFiles(includeFile, &lines,
|
||||||
|
QStringList(newName),
|
||||||
|
varNameForAdding(mimeType));
|
||||||
|
if (mode == Change::Save)
|
||||||
|
save(lines);
|
||||||
|
includeFile->deref();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void QmakePriFileNode::changeFiles(const QString &mimeType,
|
void QmakePriFileNode::changeFiles(const QString &mimeType,
|
||||||
const QStringList &filePaths,
|
const QStringList &filePaths,
|
||||||
QStringList *notChanged,
|
QStringList *notChanged,
|
||||||
ChangeType change)
|
ChangeType change, Change mode)
|
||||||
{
|
{
|
||||||
if (filePaths.isEmpty())
|
if (filePaths.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -1246,11 +1292,9 @@ void QmakePriFileNode::changeFiles(const QString &mimeType,
|
|||||||
*notChanged = filePaths;
|
*notChanged = filePaths;
|
||||||
|
|
||||||
// Check for modified editors
|
// Check for modified editors
|
||||||
if (!saveModifiedEditors())
|
if (!prepareForChange())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ensureWriteableProFile(m_projectFilePath.toString()))
|
|
||||||
return;
|
|
||||||
QPair<ProFile *, QStringList> pair = readProFile(m_projectFilePath.toString());
|
QPair<ProFile *, QStringList> pair = readProFile(m_projectFilePath.toString());
|
||||||
ProFile *includeFile = pair.first;
|
ProFile *includeFile = pair.first;
|
||||||
QStringList lines = pair.second;
|
QStringList lines = pair.second;
|
||||||
@@ -1258,7 +1302,6 @@ void QmakePriFileNode::changeFiles(const QString &mimeType,
|
|||||||
if (!includeFile)
|
if (!includeFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
if (change == AddToProFile) {
|
if (change == AddToProFile) {
|
||||||
// Use the first variable for adding.
|
// Use the first variable for adding.
|
||||||
ProWriter::addFiles(includeFile, &lines, filePaths, varNameForAdding(mimeType));
|
ProWriter::addFiles(includeFile, &lines, filePaths, varNameForAdding(mimeType));
|
||||||
@@ -1269,13 +1312,14 @@ void QmakePriFileNode::changeFiles(const QString &mimeType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// save file
|
// save file
|
||||||
|
if (mode == Change::Save)
|
||||||
save(lines);
|
save(lines);
|
||||||
includeFile->deref();
|
includeFile->deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QmakePriFileNode::setProVariable(const QString &var, const QStringList &values, const QString &scope, int flags)
|
bool QmakePriFileNode::setProVariable(const QString &var, const QStringList &values, const QString &scope, int flags)
|
||||||
{
|
{
|
||||||
if (!ensureWriteableProFile(m_projectFilePath.toString()))
|
if (!prepareForChange())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QPair<ProFile *, QStringList> pair = readProFile(m_projectFilePath.toString());
|
QPair<ProFile *, QStringList> pair = readProFile(m_projectFilePath.toString());
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ public:
|
|||||||
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
|
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
|
||||||
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
|
bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
|
||||||
bool deleteFiles(const QStringList &filePaths);
|
bool deleteFiles(const QStringList &filePaths);
|
||||||
|
bool canRenameFile(const QString &filePath, const QString &newFilePath);
|
||||||
bool renameFile(const QString &filePath, const QString &newFilePath);
|
bool renameFile(const QString &filePath, const QString &newFilePath);
|
||||||
AddNewInformation addNewInformation(const QStringList &files, Node *context) const;
|
AddNewInformation addNewInformation(const QStringList &files, Node *context) const;
|
||||||
|
|
||||||
@@ -175,6 +176,7 @@ public:
|
|||||||
bool includedInExactParse() const;
|
bool includedInExactParse() const;
|
||||||
|
|
||||||
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder);
|
static QSet<Utils::FileName> recursiveEnumerate(const QString &folder);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setIncludedInExactParse(bool b);
|
void setIncludedInExactParse(bool b);
|
||||||
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
|
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
|
||||||
@@ -189,14 +191,21 @@ protected:
|
|||||||
RemoveFromProFile
|
RemoveFromProFile
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Change { Save, TestOnly };
|
||||||
|
bool renameFile(const QString &oldName,
|
||||||
|
const QString &newName,
|
||||||
|
const QString &mimeType,
|
||||||
|
Change mode = Change::Save);
|
||||||
void changeFiles(const QString &mimeType,
|
void changeFiles(const QString &mimeType,
|
||||||
const QStringList &filePaths,
|
const QStringList &filePaths,
|
||||||
QStringList *notChanged,
|
QStringList *notChanged,
|
||||||
ChangeType change);
|
ChangeType change,
|
||||||
|
Change mode = Change::Save);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void scheduleUpdate();
|
void scheduleUpdate();
|
||||||
|
|
||||||
|
bool prepareForChange();
|
||||||
static bool ensureWriteableProFile(const QString &file);
|
static bool ensureWriteableProFile(const QString &file);
|
||||||
static QPair<ProFile *, QStringList> readProFile(const QString &file);
|
static QPair<ProFile *, QStringList> readProFile(const QString &file);
|
||||||
static QPair<ProFile *, QStringList> readProFileFromContents(const QString &contents);
|
static QPair<ProFile *, QStringList> readProFileFromContents(const QString &contents);
|
||||||
|
|||||||
Reference in New Issue
Block a user