From c78ea5a7ea7bd7f451d5d3c5fcca4920e942e233 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Thu, 20 Jul 2017 20:40:19 +0200 Subject: [PATCH] CppFindReferences: Fix file name case sensitivity on class renaming Utils::matchCaseReplacement searches for common prefix and suffix between old and new file name und leaves them unchanged. This leads to unexpected new file names. E.g. when renaming MainWindow to MyMainWindow, this function computes the prefix "m", the suffix "ainwindow.h" and only considers "yM" as the middle part that is actually renamed. Use a better algorithm to determine the new base name, and for unclear cases fall back to the "Lower case file names" option from Tools -> Options -> C++ -> File Naming. Task-number: QTCREATORBUG-18592 Change-Id: I818f7d372102eb6e266123b2b4b6355f6fa28d64 Reviewed-by: Eike Ziller --- src/plugins/cpptools/cppfindreferences.cpp | 41 +++++++++++++++++----- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 32cace3e149..c069b3514e7 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -25,6 +25,7 @@ #include "cppfindreferences.h" +#include "cppfilesettingspage.h" #include "cpptoolsconstants.h" #include "cppmodelmanager.h" #include "cppworkingcopy.h" @@ -384,6 +385,11 @@ void CppFindReferences::findAll_helper(SearchResult *search, Symbol *symbol, connect(progress, &FutureProgress::clicked, search, &SearchResult::popup); } +static bool isAllLowerCase(const QString &text) +{ + return text.toLower() == text; +} + void CppFindReferences::onReplaceButtonClicked(const QString &text, const QList &items, bool preserveCase) @@ -405,21 +411,40 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text, if (!renameFilesCheckBox || !renameFilesCheckBox->isChecked()) return; + CppFileSettings settings; + settings.fromSettings(Core::ICore::settings()); + const QStringList newPaths = Utils::transform(parameters.filesToRename, - [¶meters, text](const Node *node) -> QString { + [¶meters, text, &settings](const Node *node) -> QString { const QFileInfo fi = node->filePath().toFileInfo(); - const QString fileName = fi.fileName(); - QString newName = fileName; - newName.replace(parameters.prettySymbolName, text, Qt::CaseInsensitive); + const QString oldSymbolName = parameters.prettySymbolName; + const QString oldBaseName = fi.baseName(); + const QString newSymbolName = text; + QString newBaseName = newSymbolName; - if (newName != fileName) { - newName = Utils::matchCaseReplacement(fileName, newName); + // 1) new symbol lowercase: new base name lowercase + if (isAllLowerCase(newSymbolName)) { + newBaseName = newSymbolName; - return fi.absolutePath() + "/" + newName; + // 2) old base name mixed case: new base name is verbatim symbol name + } else if (!isAllLowerCase(oldBaseName)) { + newBaseName = newSymbolName; + + // 3) old base name lowercase, old symbol mixed case: new base name lowercase + } else if (!isAllLowerCase(oldSymbolName)) { + newBaseName = newSymbolName.toLower(); + + // 4) old base name lowercase, old symbol lowercase, new symbol mixed case: + // use the preferences setting for new base name case + } else if (settings.lowerCaseFiles) { + newBaseName = newSymbolName.toLower(); } - return QString(); + if (newBaseName == oldBaseName) + return QString(); + + return fi.absolutePath() + "/" + newBaseName + '.' + fi.completeSuffix(); }); for (int i = 0; i < parameters.filesToRename.size(); ++i) {