Commit c78ea5a7 authored by Andre Hartmann's avatar Andre Hartmann Committed by André Hartmann
Browse files

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's avatarEike Ziller <>
parent 2c518625
......@@ -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<SearchResultItem> &items,
bool preserveCase)
......@@ -405,21 +411,40 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text,
if (!renameFilesCheckBox || !renameFilesCheckBox->isChecked())
CppFileSettings settings;
const QStringList newPaths =
[&parameters, text](const Node *node) -> QString {
[&parameters, 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);
if (newName != fileName) {
newName = Utils::matchCaseReplacement(fileName, newName);
return fi.absolutePath() + "/" + newName;
const QString oldSymbolName = parameters.prettySymbolName;
const QString oldBaseName = fi.baseName();
const QString newSymbolName = text;
QString newBaseName = newSymbolName;
// 1) new symbol lowercase: new base name lowercase
if (isAllLowerCase(newSymbolName)) {
newBaseName = newSymbolName;
// 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) {
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment