CppEditor: Give C++ file name settings a per-project variant

Fixes: QTCREATORBUG-22033
Change-Id: If37517bb091438e70c5af5102bf833ed46d0c951
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2023-05-31 14:29:03 +02:00
parent 6cc325f845
commit 8e75381fce
39 changed files with 431 additions and 162 deletions

View File

@@ -1,4 +1,4 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
#include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}" #include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}"
%{JS: Cpp.openNamespaces('%{Class}')} %{JS: Cpp.openNamespaces('%{Class}')}
@if '%{IncludeQSharedData}' @if '%{IncludeQSharedData}'

View File

@@ -1,12 +1,12 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
@if '%{Cpp:PragmaOnce}' @if '%{JS: Cpp.usePragmaOnce()}'
#pragma once #pragma once
@else @else
#ifndef %{GUARD} #ifndef %{GUARD}
#define %{GUARD} #define %{GUARD}
@endif @endif
%{JS: Cpp.includeStatement('%{Base}', Util.preferredSuffix('text/x-c++hdr'), ['QObject', 'QWidget', 'QMainWindow', 'QQuickItem', 'QSharedData'], '%{TargetPath}')}\ %{JS: Cpp.includeStatement('%{Base}', Cpp.cxxHeaderSuffix(), ['QObject', 'QWidget', 'QMainWindow', 'QQuickItem', 'QSharedData'], '%{TargetPath}')}\
%{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '', %{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '',
( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '', ( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '',
( '%{IncludeQMainWindow}' ) ? 'QtGui/%{IncludeQMainWindow}' : '', ( '%{IncludeQMainWindow}' ) ? 'QtGui/%{IncludeQMainWindow}' : '',
@@ -65,6 +65,6 @@ private:
@endif @endif
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
@if ! '%{Cpp:PragmaOnce}' @if ! '%{JS: Cpp.usePragmaOnce()}'
#endif // %{GUARD} #endif // %{GUARD}
@endif @endif

View File

@@ -167,14 +167,14 @@
"type": "LineEdit", "type": "LineEdit",
"trDisplayName": "Header file:", "trDisplayName": "Header file:",
"mandatory": true, "mandatory": true,
"data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Util.preferredSuffix('text/x-c++hdr'))}" } "data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Cpp.cxxHeaderSuffix())}" }
}, },
{ {
"name": "SrcFileName", "name": "SrcFileName",
"type": "LineEdit", "type": "LineEdit",
"trDisplayName": "Source file:", "trDisplayName": "Source file:",
"mandatory": true, "mandatory": true,
"data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Util.preferredSuffix('text/x-c++src'))}" } "data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Cpp.cxxSourceSuffix())}" }
}, },
{ {
"name": "Path", "name": "Path",

View File

@@ -1,4 +1,4 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
#include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}" #include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}"
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\

View File

@@ -1,5 +1,5 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
@if '%{Cpp:PragmaOnce}' @if '%{JS: Cpp.usePragmaOnce()}'
#pragma once #pragma once
@else @else
#ifndef %{GUARD} #ifndef %{GUARD}
@@ -66,6 +66,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
@if ! '%{Cpp:PragmaOnce}' @if ! '%{JS: Cpp.usePragmaOnce()}'
#endif // %{GUARD} #endif // %{GUARD}
@endif @endif

View File

@@ -1,4 +1,4 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
#include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}" #include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}"
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\

View File

@@ -1,5 +1,5 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
@if '%{Cpp:PragmaOnce}' @if '%{JS: Cpp.usePragmaOnce()}'
#pragma once #pragma once
@else @else
#ifndef %{GUARD} #ifndef %{GUARD}
@@ -59,6 +59,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
@if ! '%{Cpp:PragmaOnce}' @if ! '%{JS: Cpp.usePragmaOnce()}'
#endif // %{GUARD} #endif // %{GUARD}
@endif @endif

View File

@@ -1,4 +1,4 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
#include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}" #include "%{JS: Util.relativeFilePath('%{Path}/%{HdrFileName}', '%{Path}' + '/' + Util.path('%{SrcFileName}'))}"
%{JS: Cpp.openNamespaces('%{Class}')}\ %{JS: Cpp.openNamespaces('%{Class}')}\

View File

@@ -1,5 +1,5 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
@if '%{Cpp:PragmaOnce}' @if '%{JS: Cpp.usePragmaOnce()}'
#pragma once #pragma once
@else @else
#ifndef %{GUARD} #ifndef %{GUARD}
@@ -62,6 +62,6 @@ public:
private: private:
}; };
%{JS: Cpp.closeNamespaces('%{Class}')} %{JS: Cpp.closeNamespaces('%{Class}')}
@if ! '%{Cpp:PragmaOnce}' @if ! '%{JS: Cpp.usePragmaOnce()}'
#endif // %{GUARD} #endif // %{GUARD}
@endif @endif

View File

@@ -14,7 +14,7 @@
{ "key": "HdrPath", "value": "%{Path}/%{HdrFileName}" }, { "key": "HdrPath", "value": "%{Path}/%{HdrFileName}" },
{ "key": "SrcPath", "value": "%{Path}/%{SrcFileName}" }, { "key": "SrcPath", "value": "%{Path}/%{SrcFileName}" },
{ "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" },
{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.preferredSuffix('text/x-c++hdr'))}" } { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Cpp.cxxHeaderSuffix())}" }
], ],
"pages": "pages":
@@ -92,14 +92,14 @@
"type": "LineEdit", "type": "LineEdit",
"trDisplayName": "Header file:", "trDisplayName": "Header file:",
"mandatory": true, "mandatory": true,
"data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Util.preferredSuffix('text/x-c++hdr'))}" } "data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Cpp.cxxHeaderSuffix())}" }
}, },
{ {
"name": "SrcFileName", "name": "SrcFileName",
"type": "LineEdit", "type": "LineEdit",
"trDisplayName": "Source file:", "trDisplayName": "Source file:",
"mandatory": true, "mandatory": true,
"data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Util.preferredSuffix('text/x-c++src'))}" } "data": { "trText": "%{JS: Cpp.classToFileName(value('Class'), Cpp.cxxSourceSuffix())}" }
}, },
{ {
"name": "Path", "name": "Path",

View File

@@ -12,7 +12,7 @@
"options": "options":
[ [
{ "key": "ProjectFile", "value": "%{ProjectDirectory}/CMakeLists.txt" }, { "key": "ProjectFile", "value": "%{ProjectDirectory}/CMakeLists.txt" },
{ "key": "CppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }, { "key": "CppFileName", "value": "%{JS: 'main.' + Cpp.cxxSourceSuffix()}" },
{ "key": "MacOSBundleValue", "value": "%{JS: %{MacOSBundle} ? 'TRUE' : 'FALSE' }" } { "key": "MacOSBundleValue", "value": "%{JS: %{MacOSBundle} ? 'TRUE' : 'FALSE' }" }
], ],
"pages": "pages":

View File

@@ -1,5 +1,5 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\
@if '%{Cpp:PragmaOnce}' @if '%{JS: Cpp.usePragmaOnce()}'
#pragma once #pragma once
@else @else
#ifndef %{JS: Cpp.headerGuard('%{FileName}')} #ifndef %{JS: Cpp.headerGuard('%{FileName}')}

View File

@@ -10,7 +10,7 @@
"enabled": "%{JS: value('Plugins').indexOf('CppEditor') >= 0}", "enabled": "%{JS: value('Plugins').indexOf('CppEditor') >= 0}",
"options": [ "options": [
{ "key": "DefaultSuffix", "value": "%{JS: Util.preferredSuffix('text/x-c++hdr')}" }, { "key": "DefaultSuffix", "value": "%{JS: Cpp.cxxHeaderSuffix()}" },
{ "key": "FileName", "value": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}" } { "key": "FileName", "value": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}" }
], ],

View File

@@ -1 +1 @@
%{Cpp:LicenseTemplate}\ %{JS: Cpp.licenseTemplate()}\

View File

@@ -11,7 +11,7 @@
"options": [ "options": [
{ "key": "FileName", "value": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}" }, { "key": "FileName", "value": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}" },
{ "key": "DefaultSuffix", "value": "%{JS: Util.preferredSuffix('text/x-c++src')}" } { "key": "DefaultSuffix", "value": "%{JS: Cpp.cxxSourceSuffix()}" }
], ],
"pages" : "pages" :

View File

@@ -1,4 +1,4 @@
%{Cpp:LicenseTemplate} %{JS: Cpp.licenseTemplate()}
@if "%{TestFrameWork}" == "GTest" @if "%{TestFrameWork}" == "GTest"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gmock/gmock-matchers.h> #include <gmock/gmock-matchers.h>

View File

@@ -13,7 +13,7 @@
"options": [ "options": [
{ "key": "TargetPath", "value": "%{Path}" }, { "key": "TargetPath", "value": "%{Path}" },
{ "key": "QmlFileName", "value": "%{JS: Util.fileName(value('QmlSrcFile').startsWith('tst_') ? value('QmlSrcFile') : 'tst_' + value('QmlSrcFile'), '.qml')}" }, { "key": "QmlFileName", "value": "%{JS: Util.fileName(value('QmlSrcFile').startsWith('tst_') ? value('QmlSrcFile') : 'tst_' + value('QmlSrcFile'), '.qml')}" },
{ "key": "CppFileName", "value": "%{JS: Util.fileName(value('CppSrcFile'), Util.preferredSuffix('text/x-c++src'))}" } { "key": "CppFileName", "value": "%{JS: Util.fileName(value('CppSrcFile'), Cpp.cxxSourceSuffix())}" }
], ],
"pages" : "pages" :
@@ -91,7 +91,7 @@
"trDisplayName": "Source file:", "trDisplayName": "Source file:",
"mandatory": true, "mandatory": true,
"visible": "%{JS: value('TestFrameWork') !== 'QtQuickTest' }", "visible": "%{JS: value('TestFrameWork') !== 'QtQuickTest' }",
"data": { "trText": "%{JS: 'tst_' + value('TestCaseName').toLowerCase() + '.' + Util.preferredSuffix('text/x-c++src')}" } "data": { "trText": "%{JS: 'tst_' + value('TestCaseName').toLowerCase() + '.' + Cpp.cxxSourceSuffix()}" }
}, },
{ {
"name": "QmlSrcFile", "name": "QmlSrcFile",

View File

@@ -570,7 +570,8 @@ void ClangdClient::findUsages(const CppEditor::CursorInEditor &cursor,
if (useClangdForRenaming) { if (useClangdForRenaming) {
symbolSupport().renameSymbol(cursor.textDocument(), adjustedCursor, *replacement, symbolSupport().renameSymbol(cursor.textDocument(), adjustedCursor, *replacement,
renameCallback, CppEditor::preferLowerCaseFileNames()); renameCallback,
CppEditor::preferLowerCaseFileNames(project()));
return; return;
} }
} }

View File

@@ -90,7 +90,8 @@ public:
const ReplacementData &replacementData, const ReplacementData &replacementData,
const QString &newSymbolName, const QString &newSymbolName,
const SearchResultItems &checkedItems, const SearchResultItems &checkedItems,
bool preserveCase); bool preserveCase,
bool preferLowerCaseFileNames);
void handleFindUsagesResult(const QList<Location> &locations); void handleFindUsagesResult(const QList<Location> &locations);
void finishSearch(); void finishSearch();
void reportAllSearchResultsAndFinish(); void reportAllSearchResultsAndFinish();
@@ -141,13 +142,14 @@ ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *d
const auto renameFilesCheckBox = new QCheckBox; const auto renameFilesCheckBox = new QCheckBox;
renameFilesCheckBox->setVisible(false); renameFilesCheckBox->setVisible(false);
d->search->setAdditionalReplaceWidget(renameFilesCheckBox); d->search->setAdditionalReplaceWidget(renameFilesCheckBox);
const auto renameHandler = const bool preferLowerCase = CppEditor::preferLowerCaseFileNames(client->project());
[search = d->search](const QString &newSymbolName, const auto renameHandler = [search = d->search, preferLowerCase](
const SearchResultItems &checkedItems, const QString &newSymbolName,
bool preserveCase) { const SearchResultItems &checkedItems,
bool preserveCase) {
const auto replacementData = search->userData().value<ReplacementData>(); const auto replacementData = search->userData().value<ReplacementData>();
Private::handleRenameRequest(search, replacementData, newSymbolName, checkedItems, Private::handleRenameRequest(search, replacementData, newSymbolName, checkedItems,
preserveCase); preserveCase, preferLowerCase);
}; };
connect(d->search, &SearchResult::replaceButtonClicked, renameHandler); connect(d->search, &SearchResult::replaceButtonClicked, renameHandler);
} }
@@ -244,7 +246,8 @@ void ClangdFindReferences::Private::handleRenameRequest(
const ReplacementData &replacementData, const ReplacementData &replacementData,
const QString &newSymbolName, const QString &newSymbolName,
const SearchResultItems &checkedItems, const SearchResultItems &checkedItems,
bool preserveCase) bool preserveCase,
bool preferLowerCaseFileNames)
{ {
const Utils::FilePaths filePaths = BaseFileFind::replaceAll(newSymbolName, checkedItems, const Utils::FilePaths filePaths = BaseFileFind::replaceAll(newSymbolName, checkedItems,
preserveCase); preserveCase);
@@ -261,7 +264,7 @@ void ClangdFindReferences::Private::handleRenameRequest(
ProjectExplorerPlugin::renameFilesForSymbol( ProjectExplorerPlugin::renameFilesForSymbol(
replacementData.oldSymbolName, newSymbolName, replacementData.oldSymbolName, newSymbolName,
Utils::toList(replacementData.fileRenameCandidates), Utils::toList(replacementData.fileRenameCandidates),
CppEditor::preferLowerCaseFileNames()); preferLowerCaseFileNames);
} }
void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location> &locations) void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location> &locations)

View File

@@ -39,9 +39,10 @@ void AbstractEditorSupport::notifyAboutUpdatedContents() const
filePath().toString(), sourceFilePath().toString(), contents()); filePath().toString(), sourceFilePath().toString(), contents());
} }
QString AbstractEditorSupport::licenseTemplate(const FilePath &filePath, const QString &className) QString AbstractEditorSupport::licenseTemplate(ProjectExplorer::Project *project,
const FilePath &filePath, const QString &className)
{ {
const QString license = Internal::CppFileSettings::licenseTemplate(); const QString license = Internal::CppEditorPlugin::licenseTemplate(project);
Utils::MacroExpander expander; Utils::MacroExpander expander;
expander.registerVariable("Cpp:License:FileName", Tr::tr("The file name."), expander.registerVariable("Cpp:License:FileName", Tr::tr("The file name."),
[filePath] { return filePath.fileName(); }); [filePath] { return filePath.fileName(); });
@@ -51,9 +52,9 @@ QString AbstractEditorSupport::licenseTemplate(const FilePath &filePath, const Q
return Utils::TemplateEngine::processText(&expander, license, nullptr); return Utils::TemplateEngine::processText(&expander, license, nullptr);
} }
bool AbstractEditorSupport::usePragmaOnce() bool AbstractEditorSupport::usePragmaOnce(ProjectExplorer::Project *project)
{ {
return Internal::CppEditorPlugin::usePragmaOnce(); return Internal::CppEditorPlugin::usePragmaOnce(project);
} }
} // CppEditor } // CppEditor

View File

@@ -9,6 +9,8 @@
#include <QObject> #include <QObject>
namespace ProjectExplorer { class Project; }
namespace CppEditor { namespace CppEditor {
class CppModelManager; class CppModelManager;
@@ -30,8 +32,10 @@ public:
void notifyAboutUpdatedContents() const; void notifyAboutUpdatedContents() const;
unsigned revision() const { return m_revision; } unsigned revision() const { return m_revision; }
static QString licenseTemplate(const Utils::FilePath &filePath = {}, const QString &className = {}); static QString licenseTemplate(ProjectExplorer::Project *project,
static bool usePragmaOnce(); const Utils::FilePath &filePath = {},
const QString &className = {});
static bool usePragmaOnce(ProjectExplorer::Project *project);
private: private:
CppModelManager *m_modelmanager; CppModelManager *m_modelmanager;

View File

@@ -72,6 +72,7 @@
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h> #include <projectexplorer/projectnodes.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/projectpanelfactory.h> #include <projectexplorer/projectpanelfactory.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
@@ -261,17 +262,18 @@ void CppEditorPlugin::initialize()
this, [] { CppModelManager::switchHeaderSource(true); }); this, [] { CppModelManager::switchHeaderSource(true); });
MacroExpander *expander = globalMacroExpander(); MacroExpander *expander = globalMacroExpander();
// TODO: Per-project variants of these three?
expander->registerVariable("Cpp:LicenseTemplate", expander->registerVariable("Cpp:LicenseTemplate",
Tr::tr("The license template."), Tr::tr("The license template."),
[]() { return CppEditorPlugin::licenseTemplate(); }); []() { return CppEditorPlugin::licenseTemplate(nullptr); });
expander->registerFileVariables("Cpp:LicenseTemplatePath", expander->registerFileVariables("Cpp:LicenseTemplatePath",
Tr::tr("The configured path to the license template"), Tr::tr("The configured path to the license template"),
[]() { return CppEditorPlugin::licenseTemplatePath(); }); []() { return CppEditorPlugin::licenseTemplatePath(nullptr); });
expander->registerVariable( expander->registerVariable(
"Cpp:PragmaOnce", "Cpp:PragmaOnce",
Tr::tr("Insert \"#pragma once\" instead of \"#ifndef\" include guards into header file"), Tr::tr("Insert \"#pragma once\" instead of \"#ifndef\" include guards into header file"),
[] { return usePragmaOnce() ? QString("true") : QString(); }); [] { return usePragmaOnce(nullptr) ? QString("true") : QString(); });
const auto quickFixSettingsPanelFactory = new ProjectPanelFactory; const auto quickFixSettingsPanelFactory = new ProjectPanelFactory;
quickFixSettingsPanelFactory->setPriority(100); quickFixSettingsPanelFactory->setPriority(100);
@@ -505,6 +507,14 @@ void CppEditorPlugin::extensionsInitialized()
if (!d->m_fileSettings.applySuffixesToMimeDB()) if (!d->m_fileSettings.applySuffixesToMimeDB())
qWarning("Unable to apply cpp suffixes to mime database (cpp mime types not found).\n"); qWarning("Unable to apply cpp suffixes to mime database (cpp mime types not found).\n");
const auto fileNamesPanelFactory = new ProjectPanelFactory;
fileNamesPanelFactory->setPriority(99);
fileNamesPanelFactory->setDisplayName(Tr::tr("C++ File Naming"));
fileNamesPanelFactory->setCreateWidgetFunction([](Project *project) {
return new CppFileSettingsForProjectWidget(project);
});
ProjectPanelFactory::registerFactory(fileNamesPanelFactory);
if (CppModelManager::instance()->isClangCodeModelActive()) { if (CppModelManager::instance()->isClangCodeModelActive()) {
d->m_clangdSettingsPage = new ClangdSettingsPage; d->m_clangdSettingsPage = new ClangdSettingsPage;
const auto clangdPanelFactory = new ProjectPanelFactory; const auto clangdPanelFactory = new ProjectPanelFactory;
@@ -614,39 +624,19 @@ void CppEditorPlugin::clearHeaderSourceCache()
m_headerSourceMapping.clear(); m_headerSourceMapping.clear();
} }
FilePath CppEditorPlugin::licenseTemplatePath() FilePath CppEditorPlugin::licenseTemplatePath(Project *project)
{ {
return FilePath::fromString(m_instance->d->m_fileSettings.licenseTemplatePath); return FilePath::fromString(fileSettings(project).licenseTemplatePath);
} }
QString CppEditorPlugin::licenseTemplate() QString CppEditorPlugin::licenseTemplate(Project *project)
{ {
return CppFileSettings::licenseTemplate(); return fileSettings(project).licenseTemplate();
} }
bool CppEditorPlugin::usePragmaOnce() bool CppEditorPlugin::usePragmaOnce(Project *project)
{ {
return m_instance->d->m_fileSettings.headerPragmaOnce; return fileSettings(project).headerPragmaOnce;
}
const QStringList &CppEditorPlugin::headerSearchPaths()
{
return m_instance->d->m_fileSettings.headerSearchPaths;
}
const QStringList &CppEditorPlugin::sourceSearchPaths()
{
return m_instance->d->m_fileSettings.sourceSearchPaths;
}
const QStringList &CppEditorPlugin::headerPrefixes()
{
return m_instance->d->m_fileSettings.headerPrefixes;
}
const QStringList &CppEditorPlugin::sourcePrefixes()
{
return m_instance->d->m_fileSettings.sourcePrefixes;
} }
CppCodeModelSettings *CppEditorPlugin::codeModelSettings() CppCodeModelSettings *CppEditorPlugin::codeModelSettings()
@@ -654,11 +644,20 @@ CppCodeModelSettings *CppEditorPlugin::codeModelSettings()
return &d->m_codeModelSettings; return &d->m_codeModelSettings;
} }
CppFileSettings *CppEditorPlugin::fileSettings() CppFileSettings CppEditorPlugin::fileSettings(Project *project)
{ {
return &instance()->d->m_fileSettings; if (!project)
return instance()->d->m_fileSettings;
return CppFileSettingsForProject(project).settings();
} }
#ifdef WITH_TESTS
void CppEditorPlugin::setGlobalFileSettings(const CppFileSettings &settings)
{
instance()->d->m_fileSettings = settings;
}
#endif
static QStringList findFilesInProject(const QString &name, const Project *project) static QStringList findFilesInProject(const QString &name, const Project *project)
{ {
if (debug) if (debug)
@@ -721,11 +720,12 @@ static QStringList baseNameWithAllSuffixes(const QString &baseName, const QStrin
return result; return result;
} }
static QStringList baseNamesWithAllPrefixes(const QStringList &baseNames, bool isHeader) static QStringList baseNamesWithAllPrefixes(const CppFileSettings &settings,
const QStringList &baseNames, bool isHeader)
{ {
QStringList result; QStringList result;
const QStringList &sourcePrefixes = m_instance->sourcePrefixes(); const QStringList &sourcePrefixes = settings.sourcePrefixes;
const QStringList &headerPrefixes = m_instance->headerPrefixes(); const QStringList &headerPrefixes = settings.headerPrefixes;
for (const QString &name : baseNames) { for (const QString &name : baseNames) {
for (const QString &prefix : isHeader ? headerPrefixes : sourcePrefixes) { for (const QString &prefix : isHeader ? headerPrefixes : sourcePrefixes) {
@@ -812,6 +812,9 @@ FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader,
if (m_headerSourceMapping.contains(fi.absoluteFilePath())) if (m_headerSourceMapping.contains(fi.absoluteFilePath()))
return FilePath::fromString(m_headerSourceMapping.value(fi.absoluteFilePath())); return FilePath::fromString(m_headerSourceMapping.value(fi.absoluteFilePath()));
Project * const projectForFile = ProjectManager::projectForFile(filePath);
const CppFileSettings settings = CppEditorPlugin::fileSettings(projectForFile);
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << fileName << kind; qDebug() << Q_FUNC_INFO << fileName << kind;
@@ -838,11 +841,11 @@ FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader,
const QDir absoluteDir = fi.absoluteDir(); const QDir absoluteDir = fi.absoluteDir();
QStringList candidateDirs(absoluteDir.absolutePath()); QStringList candidateDirs(absoluteDir.absolutePath());
// If directory is not root, try matching against its siblings // If directory is not root, try matching against its siblings
const QStringList searchPaths = isHeader ? m_instance->sourceSearchPaths() const QStringList searchPaths = isHeader ? settings.sourceSearchPaths
: m_instance->headerSearchPaths(); : settings.headerSearchPaths;
candidateDirs += baseDirWithAllDirectories(absoluteDir, searchPaths); candidateDirs += baseDirWithAllDirectories(absoluteDir, searchPaths);
candidateFileNames += baseNamesWithAllPrefixes(candidateFileNames, isHeader); candidateFileNames += baseNamesWithAllPrefixes(settings, candidateFileNames, isHeader);
// Try to find a file in the same or sibling directories first // Try to find a file in the same or sibling directories first
for (const QString &candidateDir : std::as_const(candidateDirs)) { for (const QString &candidateDir : std::as_const(candidateDirs)) {
@@ -862,7 +865,9 @@ FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader,
} }
// Find files in the current project // Find files in the current project
Project *currentProject = ProjectTree::currentProject(); Project *currentProject = projectForFile;
if (!projectForFile)
currentProject = ProjectTree::currentProject();
if (currentProject) { if (currentProject) {
const FilePath path = correspondingHeaderOrSourceInProject(fi, candidateFileNames, const FilePath path = correspondingHeaderOrSourceInProject(fi, candidateFileNames,
currentProject, cacheUsage); currentProject, cacheUsage);

View File

@@ -5,6 +5,7 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
namespace ProjectExplorer { class Project; }
namespace Utils { class FilePath; } namespace Utils { class FilePath; }
namespace CppEditor { namespace CppEditor {
@@ -29,14 +30,10 @@ public:
CppQuickFixAssistProvider *quickFixProvider() const; CppQuickFixAssistProvider *quickFixProvider() const;
static const QStringList &headerSearchPaths();
static const QStringList &sourceSearchPaths();
static const QStringList &headerPrefixes();
static const QStringList &sourcePrefixes();
static void clearHeaderSourceCache(); static void clearHeaderSourceCache();
static Utils::FilePath licenseTemplatePath(); static Utils::FilePath licenseTemplatePath(ProjectExplorer::Project *project);
static QString licenseTemplate(); static QString licenseTemplate(ProjectExplorer::Project *project);
static bool usePragmaOnce(); static bool usePragmaOnce(ProjectExplorer::Project *project);
void openDeclarationDefinitionInNextSplit(); void openDeclarationDefinitionInNextSplit();
void openTypeHierarchy(); void openTypeHierarchy();
@@ -46,7 +43,10 @@ public:
void switchDeclarationDefinition(); void switchDeclarationDefinition();
CppCodeModelSettings *codeModelSettings(); CppCodeModelSettings *codeModelSettings();
static CppFileSettings *fileSettings(); static CppFileSettings fileSettings(ProjectExplorer::Project *project);
#ifdef WITH_TESTS
static void setGlobalFileSettings(const CppFileSettings &settings);
#endif
signals: signals:
void typeHierarchyRequested(); void typeHierarchyRequested();

View File

@@ -7,10 +7,9 @@
#include "cppeditortr.h" #include "cppeditortr.h"
#include <app/app_version.h> #include <app/app_version.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
@@ -25,11 +24,14 @@
#include <QLocale> #include <QLocale>
#include <QSettings> #include <QSettings>
#include <QTextStream> #include <QTextStream>
#include <QVBoxLayout>
using namespace Utils; using namespace Utils;
namespace CppEditor::Internal { namespace CppEditor::Internal {
const char projectSettingsKeyC[] = "CppEditorFileNames";
const char useGlobalKeyC[] = "UseGlobal";
const char headerPrefixesKeyC[] = "HeaderPrefixes"; const char headerPrefixesKeyC[] = "HeaderPrefixes";
const char sourcePrefixesKeyC[] = "SourcePrefixes"; const char sourcePrefixesKeyC[] = "SourcePrefixes";
const char headerSuffixKeyC[] = "HeaderSuffix"; const char headerSuffixKeyC[] = "HeaderSuffix";
@@ -202,18 +204,14 @@ static void parseLicenseTemplatePlaceholders(QString *t)
} }
// Convenience that returns the formatted license template. // Convenience that returns the formatted license template.
QString CppFileSettings::licenseTemplate() QString CppFileSettings::licenseTemplate() const
{ {
const QSettings *s = Core::ICore::settings(); if (licenseTemplatePath.isEmpty())
QString key = QLatin1String(Constants::CPPEDITOR_SETTINGSGROUP);
key += QLatin1Char('/');
key += QLatin1String(licenseTemplatePathKeyC);
const QString path = s->value(key, QString()).toString();
if (path.isEmpty())
return QString(); return QString();
QFile file(path); QFile file(licenseTemplatePath);
if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) { if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
qWarning("Unable to open the license template %s: %s", qPrintable(path), qPrintable(file.errorString())); qWarning("Unable to open the license template %s: %s", qPrintable(licenseTemplatePath),
qPrintable(file.errorString()));
return QString(); return QString();
} }
@@ -235,11 +233,17 @@ QString CppFileSettings::licenseTemplate()
class CppFileSettingsWidget final : public Core::IOptionsPageWidget class CppFileSettingsWidget final : public Core::IOptionsPageWidget
{ {
Q_OBJECT
public: public:
explicit CppFileSettingsWidget(CppFileSettings *settings); explicit CppFileSettingsWidget(CppFileSettings *settings);
void apply() final; void apply() final;
void setSettings(const CppFileSettings &s); void setSettings(const CppFileSettings &s);
CppFileSettings currentSettings() const;
signals:
void userChange();
private: private:
void slotEdit(); void slotEdit();
@@ -336,6 +340,25 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
m_licenseTemplatePathChooser->addButton(Tr::tr("Edit..."), this, [this] { slotEdit(); }); m_licenseTemplatePathChooser->addButton(Tr::tr("Edit..."), this, [this] { slotEdit(); });
setSettings(*m_settings); setSettings(*m_settings);
connect(m_headerSuffixComboBox, &QComboBox::currentIndexChanged,
this, &CppFileSettingsWidget::userChange);
connect(m_sourceSuffixComboBox, &QComboBox::currentIndexChanged,
this, &CppFileSettingsWidget::userChange);
connect(m_headerSearchPathsEdit, &QLineEdit::textEdited,
this, &CppFileSettingsWidget::userChange);
connect(m_sourceSearchPathsEdit, &QLineEdit::textEdited,
this, &CppFileSettingsWidget::userChange);
connect(m_headerPrefixesEdit, &QLineEdit::textEdited,
this, &CppFileSettingsWidget::userChange);
connect(m_sourcePrefixesEdit, &QLineEdit::textEdited,
this, &CppFileSettingsWidget::userChange);
connect(m_headerPragmaOnceCheckBox, &QCheckBox::stateChanged,
this, &CppFileSettingsWidget::userChange);
connect(m_lowerCaseFileNamesCheckBox, &QCheckBox::stateChanged,
this, &CppFileSettingsWidget::userChange);
connect(m_licenseTemplatePathChooser, &PathChooser::textChanged,
this, &CppFileSettingsWidget::userChange);
} }
FilePath CppFileSettingsWidget::licenseTemplatePath() const FilePath CppFileSettingsWidget::licenseTemplatePath() const
@@ -358,17 +381,7 @@ static QStringList trimmedPaths(const QString &paths)
void CppFileSettingsWidget::apply() void CppFileSettingsWidget::apply()
{ {
CppFileSettings rc; const CppFileSettings rc = currentSettings();
rc.lowerCaseFiles = m_lowerCaseFileNamesCheckBox->isChecked();
rc.headerPragmaOnce = m_headerPragmaOnceCheckBox->isChecked();
rc.headerPrefixes = trimmedPaths(m_headerPrefixesEdit->text());
rc.sourcePrefixes = trimmedPaths(m_sourcePrefixesEdit->text());
rc.headerSuffix = m_headerSuffixComboBox->currentText();
rc.sourceSuffix = m_sourceSuffixComboBox->currentText();
rc.headerSearchPaths = trimmedPaths(m_headerSearchPathsEdit->text());
rc.sourceSearchPaths = trimmedPaths(m_sourceSearchPathsEdit->text());
rc.licenseTemplatePath = licenseTemplatePath().toString();
if (rc == *m_settings) if (rc == *m_settings)
return; return;
@@ -398,6 +411,21 @@ void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
setLicenseTemplatePath(FilePath::fromString(s.licenseTemplatePath)); setLicenseTemplatePath(FilePath::fromString(s.licenseTemplatePath));
} }
CppFileSettings CppFileSettingsWidget::currentSettings() const
{
CppFileSettings rc;
rc.lowerCaseFiles = m_lowerCaseFileNamesCheckBox->isChecked();
rc.headerPragmaOnce = m_headerPragmaOnceCheckBox->isChecked();
rc.headerPrefixes = trimmedPaths(m_headerPrefixesEdit->text());
rc.sourcePrefixes = trimmedPaths(m_sourcePrefixesEdit->text());
rc.headerSuffix = m_headerSuffixComboBox->currentText();
rc.sourceSuffix = m_sourceSuffixComboBox->currentText();
rc.headerSearchPaths = trimmedPaths(m_headerSearchPathsEdit->text());
rc.sourceSearchPaths = trimmedPaths(m_sourceSearchPathsEdit->text());
rc.licenseTemplatePath = licenseTemplatePath().toString();
return rc;
}
void CppFileSettingsWidget::slotEdit() void CppFileSettingsWidget::slotEdit()
{ {
FilePath path = licenseTemplatePath(); FilePath path = licenseTemplatePath();
@@ -426,4 +454,133 @@ CppFileSettingsPage::CppFileSettingsPage(CppFileSettings *settings)
setWidgetCreator([settings] { return new CppFileSettingsWidget(settings); }); setWidgetCreator([settings] { return new CppFileSettingsWidget(settings); });
} }
CppFileSettingsForProject::CppFileSettingsForProject(ProjectExplorer::Project *project)
: m_project(project)
{
loadSettings();
}
CppFileSettings CppFileSettingsForProject::settings() const
{
return m_useGlobalSettings ? CppEditorPlugin::fileSettings(nullptr) : m_customSettings;
}
void CppFileSettingsForProject::setSettings(const CppFileSettings &settings)
{
m_customSettings = settings;
saveSettings();
}
void CppFileSettingsForProject::setUseGlobalSettings(bool useGlobal)
{
m_useGlobalSettings = useGlobal;
saveSettings();
}
void CppFileSettingsForProject::loadSettings()
{
if (!m_project)
return;
const QVariant entry = m_project->namedSettings(projectSettingsKeyC);
if (!entry.isValid())
return;
const QVariantMap data = entry.toMap();
m_useGlobalSettings = data.value(useGlobalKeyC, true).toBool();
m_customSettings.headerPrefixes = data.value(headerPrefixesKeyC,
m_customSettings.headerPrefixes).toStringList();
m_customSettings.sourcePrefixes = data.value(sourcePrefixesKeyC,
m_customSettings.sourcePrefixes).toStringList();
m_customSettings.headerSuffix = data.value(headerSuffixKeyC, m_customSettings.headerSuffix)
.toString();
m_customSettings.sourceSuffix = data.value(sourceSuffixKeyC, m_customSettings.sourceSuffix)
.toString();
m_customSettings.headerSearchPaths
= data.value(headerSearchPathsKeyC, m_customSettings.headerSearchPaths).toStringList();
m_customSettings.sourceSearchPaths
= data.value(sourceSearchPathsKeyC, m_customSettings.sourceSearchPaths).toStringList();
m_customSettings.lowerCaseFiles = data.value(Constants::LOWERCASE_CPPFILES_KEY,
m_customSettings.lowerCaseFiles).toBool();
m_customSettings.headerPragmaOnce = data.value(headerPragmaOnceC,
m_customSettings.headerPragmaOnce).toBool();
m_customSettings.licenseTemplatePath
= data.value(licenseTemplatePathKeyC, m_customSettings.licenseTemplatePath).toString();
}
void CppFileSettingsForProject::saveSettings()
{
if (!m_project)
return;
// Optimization: Don't save anything if the user never switched away from the default.
if (m_useGlobalSettings && !m_project->namedSettings(projectSettingsKeyC).isValid())
return;
QVariantMap data;
data.insert(useGlobalKeyC, m_useGlobalSettings);
data.insert(headerPrefixesKeyC, m_customSettings.headerPrefixes);
data.insert(sourcePrefixesKeyC, m_customSettings.sourcePrefixes);
data.insert(headerSuffixKeyC, m_customSettings.headerSuffix);
data.insert(sourceSuffixKeyC, m_customSettings.sourceSuffix);
data.insert(headerSearchPathsKeyC, m_customSettings.headerSearchPaths);
data.insert(sourceSearchPathsKeyC, m_customSettings.sourceSearchPaths);
data.insert(Constants::LOWERCASE_CPPFILES_KEY, m_customSettings.lowerCaseFiles);
data.insert(headerPragmaOnceC, m_customSettings.headerPragmaOnce);
data.insert(licenseTemplatePathKeyC, m_customSettings.licenseTemplatePath);
m_project->setNamedSettings(projectSettingsKeyC, data);
}
class CppFileSettingsForProjectWidget::Private
{
public:
Private(const CppFileSettingsForProject &s) : settings(s) {}
void maybeClearHeaderSourceCache();
void updateSubWidgetState() { widget.setEnabled(!settings.useGlobalSettings()); }
CppFileSettingsForProject settings;
CppFileSettings initialSettings = settings.settings();
CppFileSettingsWidget widget{&initialSettings};
QCheckBox useGlobalSettingsCheckBox;
const bool wasGlobal = settings.useGlobalSettings();
};
CppFileSettingsForProjectWidget::CppFileSettingsForProjectWidget(
const CppFileSettingsForProject &settings) : d(new Private(settings))
{
setGlobalSettingsId(Constants::CPP_FILE_SETTINGS_ID);
const auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(&d->widget);
connect(this, &ProjectSettingsWidget::useGlobalSettingsChanged, this,
[this](bool checked) {
d->settings.setUseGlobalSettings(checked);
if (!checked)
d->settings.setSettings(d->widget.currentSettings());
d->maybeClearHeaderSourceCache();
d->updateSubWidgetState();
});
connect(&d->widget, &CppFileSettingsWidget::userChange, this, [this] {
d->settings.setSettings(d->widget.currentSettings());
d->maybeClearHeaderSourceCache();
});
d->updateSubWidgetState();
}
CppFileSettingsForProjectWidget::~CppFileSettingsForProjectWidget() { delete d; }
void CppFileSettingsForProjectWidget::Private::maybeClearHeaderSourceCache()
{
const CppFileSettings &s = settings.settings();
if (settings.useGlobalSettings() != wasGlobal
|| s.headerSearchPaths != initialSettings.headerSearchPaths
|| s.sourceSearchPaths != initialSettings.sourceSearchPaths) {
CppEditorPlugin::clearHeaderSourceCache();
}
}
} // namespace CppEditor::Internal } // namespace CppEditor::Internal
#include <cppfilesettingspage.moc>

View File

@@ -6,6 +6,7 @@
#include "cppeditorconstants.h" #include "cppeditorconstants.h"
#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/projectsettingswidget.h>
#include <QDir> #include <QDir>
@@ -13,6 +14,8 @@ QT_BEGIN_NAMESPACE
class QSettings; class QSettings;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace ProjectExplorer { class Project; }
namespace CppEditor::Internal { namespace CppEditor::Internal {
class CppFileSettings class CppFileSettings
@@ -38,18 +41,47 @@ public:
bool applySuffixesToMimeDB(); bool applySuffixesToMimeDB();
// Convenience to return a license template completely formatted. // Convenience to return a license template completely formatted.
// Currently made public in QString licenseTemplate() const;
static QString licenseTemplate();
bool equals(const CppFileSettings &rhs) const; bool equals(const CppFileSettings &rhs) const;
bool operator==(const CppFileSettings &s) const { return equals(s); } bool operator==(const CppFileSettings &s) const { return equals(s); }
bool operator!=(const CppFileSettings &s) const { return !equals(s); } bool operator!=(const CppFileSettings &s) const { return !equals(s); }
}; };
class CppFileSettingsForProject
{
public:
CppFileSettingsForProject(ProjectExplorer::Project *project);
CppFileSettings settings() const;
void setSettings(const CppFileSettings &settings);
bool useGlobalSettings() const { return m_useGlobalSettings; }
void setUseGlobalSettings(bool useGlobal);
private:
void loadSettings();
void saveSettings();
ProjectExplorer::Project * const m_project;
CppFileSettings m_customSettings;
bool m_useGlobalSettings = true;
};
class CppFileSettingsPage : public Core::IOptionsPage class CppFileSettingsPage : public Core::IOptionsPage
{ {
public: public:
explicit CppFileSettingsPage(CppFileSettings *settings); explicit CppFileSettingsPage(CppFileSettings *settings);
}; };
class CppFileSettingsForProjectWidget : public ProjectExplorer::ProjectSettingsWidget
{
public:
CppFileSettingsForProjectWidget(const CppFileSettingsForProject &settings);
~CppFileSettingsForProjectWidget();
private:
class Private;
Private * const d;
};
} // namespace CppEditor::Internal } // namespace CppEditor::Internal

View File

@@ -398,6 +398,8 @@ void CppFindReferences::findUsages(CPlusPlus::Symbol *symbol,
parameters.symbolId = fullIdForSymbol(symbol); parameters.symbolId = fullIdForSymbol(symbol);
parameters.symbolFilePath = symbol->filePath(); parameters.symbolFilePath = symbol->filePath();
parameters.categorize = codeModelSettings()->categorizeFindReferences(); parameters.categorize = codeModelSettings()->categorizeFindReferences();
parameters.preferLowerCaseFileNames = preferLowerCaseFileNames(
ProjectManager::projectForFile(symbol->filePath()));
if (symbol->asClass() || symbol->asForwardClassDeclaration()) { if (symbol->asClass() || symbol->asForwardClassDeclaration()) {
CPlusPlus::Overview overview; CPlusPlus::Overview overview;
@@ -475,7 +477,7 @@ void CppFindReferences::onReplaceButtonClicked(Core::SearchResult *search, const
ProjectExplorerPlugin::renameFilesForSymbol( ProjectExplorerPlugin::renameFilesForSymbol(
parameters.prettySymbolName, text, parameters.filesToRename, parameters.prettySymbolName, text, parameters.filesToRename,
preferLowerCaseFileNames()); parameters.preferLowerCaseFileNames);
} }
void CppFindReferences::searchAgain(SearchResult *search) void CppFindReferences::searchAgain(SearchResult *search)

View File

@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "cppeditor_global.h" #include "cppeditor_global.h"
#include "cppeditorconstants.h"
#include <coreplugin/find/searchresultwindow.h> #include <coreplugin/find/searchresultwindow.h>
#include <cplusplus/FindUsages.h> #include <cplusplus/FindUsages.h>
@@ -51,6 +52,7 @@ public:
QString prettySymbolName; QString prettySymbolName;
Utils::FilePaths filesToRename; Utils::FilePaths filesToRename;
bool categorize = false; bool categorize = false;
bool preferLowerCaseFileNames = Constants::LOWERCASE_CPPFILES_DEFAULT;
}; };
class CppFindReferences: public QObject class CppFindReferences: public QObject

View File

@@ -71,25 +71,27 @@ void HeaderSourceTest::test_data()
void HeaderSourceTest::initTestCase() void HeaderSourceTest::initTestCase()
{ {
QDir(baseTestDir()).mkpath(_(".")); QDir(baseTestDir()).mkpath(_("."));
CppFileSettings *fs = CppEditorPlugin::fileSettings(); CppFileSettings fs = CppEditorPlugin::fileSettings(nullptr);
fs->headerSearchPaths.append(QLatin1String("include")); fs.headerSearchPaths.append(QLatin1String("include"));
fs->headerSearchPaths.append(QLatin1String("../include")); fs.headerSearchPaths.append(QLatin1String("../include"));
fs->sourceSearchPaths.append(QLatin1String("src")); fs.sourceSearchPaths.append(QLatin1String("src"));
fs->sourceSearchPaths.append(QLatin1String("../src")); fs.sourceSearchPaths.append(QLatin1String("../src"));
fs->headerPrefixes.append(QLatin1String("testh_")); fs.headerPrefixes.append(QLatin1String("testh_"));
fs->sourcePrefixes.append(QLatin1String("testc_")); fs.sourcePrefixes.append(QLatin1String("testc_"));
CppEditorPlugin::setGlobalFileSettings(fs);
} }
void HeaderSourceTest::cleanupTestCase() void HeaderSourceTest::cleanupTestCase()
{ {
Utils::FilePath::fromString(baseTestDir()).removeRecursively(); Utils::FilePath::fromString(baseTestDir()).removeRecursively();
CppFileSettings *fs = CppEditorPlugin::fileSettings(); CppFileSettings fs = CppEditorPlugin::fileSettings(nullptr);
fs->headerSearchPaths.removeLast(); fs.headerSearchPaths.removeLast();
fs->headerSearchPaths.removeLast(); fs.headerSearchPaths.removeLast();
fs->sourceSearchPaths.removeLast(); fs.sourceSearchPaths.removeLast();
fs->sourceSearchPaths.removeLast(); fs.sourceSearchPaths.removeLast();
fs->headerPrefixes.removeLast(); fs.headerPrefixes.removeLast();
fs->sourcePrefixes.removeLast(); fs.sourcePrefixes.removeLast();
CppEditorPlugin::setGlobalFileSettings(fs);
} }
} // namespace CppEditor::Internal } // namespace CppEditor::Internal

View File

@@ -3,6 +3,7 @@
#include "cpptoolsjsextension.h" #include "cpptoolsjsextension.h"
#include "cppeditorplugin.h"
#include "cppfilesettingspage.h" #include "cppfilesettingspage.h"
#include "cpplocatordata.h" #include "cpplocatordata.h"
#include "cppworkingcopy.h" #include "cppworkingcopy.h"
@@ -12,6 +13,7 @@
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectmanager.h>
#include <projectexplorer/projectnodes.h> #include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <cplusplus/AST.h> #include <cplusplus/AST.h>
#include <cplusplus/ASTPath.h> #include <cplusplus/ASTPath.h>
@@ -27,6 +29,13 @@
namespace CppEditor::Internal { namespace CppEditor::Internal {
static CppFileSettings fileSettings()
{
// Note that the user can set a different project in the wizard *after* the file names
// have been determined. There's nothing we can do about that here.
return CppEditorPlugin::fileSettings(ProjectExplorer::ProjectTree::currentProject());
}
static QString fileName(const QString &path, const QString &extension) static QString fileName(const QString &path, const QString &extension)
{ {
return Utils::FilePath::fromStringWithExtension(path, extension).toString(); return Utils::FilePath::fromStringWithExtension(path, extension).toString();
@@ -37,6 +46,16 @@ QString CppToolsJsExtension::headerGuard(const QString &in) const
return Utils::headerGuard(in); return Utils::headerGuard(in);
} }
QString CppToolsJsExtension::licenseTemplate() const
{
return fileSettings().licenseTemplate();
}
bool CppToolsJsExtension::usePragmaOnce() const
{
return fileSettings().headerPragmaOnce;
}
static QStringList parts(const QString &klass) static QStringList parts(const QString &klass)
{ {
return klass.split(QStringLiteral("::")); return klass.split(QStringLiteral("::"));
@@ -63,8 +82,7 @@ QString CppToolsJsExtension::className(const QString &klass) const
QString CppToolsJsExtension::classToFileName(const QString &klass, const QString &extension) const QString CppToolsJsExtension::classToFileName(const QString &klass, const QString &extension) const
{ {
const QString raw = fileName(className(klass), extension); const QString raw = fileName(className(klass), extension);
CppFileSettings settings; const CppFileSettings &settings = fileSettings();
settings.fromSettings(Core::ICore::settings());
if (!settings.lowerCaseFiles) if (!settings.lowerCaseFiles)
return raw; return raw;
@@ -249,4 +267,14 @@ QString CppToolsJsExtension::includeStatement(
return {}; return {};
} }
QString CppToolsJsExtension::cxxHeaderSuffix() const
{
return fileSettings().headerSuffix;
}
QString CppToolsJsExtension::cxxSourceSuffix() const
{
return fileSettings().sourceSuffix;
}
} // namespace CppEditor::Internal } // namespace CppEditor::Internal

View File

@@ -26,6 +26,12 @@ public:
// Generate header guard: // Generate header guard:
Q_INVOKABLE QString headerGuard(const QString &in) const; Q_INVOKABLE QString headerGuard(const QString &in) const;
// Generate license template:
Q_INVOKABLE QString licenseTemplate() const;
// Use #pragma once:
Q_INVOKABLE bool usePragmaOnce() const;
// Work with classes: // Work with classes:
Q_INVOKABLE QStringList namespaces(const QString &klass) const; Q_INVOKABLE QStringList namespaces(const QString &klass) const;
Q_INVOKABLE bool hasNamespaces(const QString &klass) const; Q_INVOKABLE bool hasNamespaces(const QString &klass) const;
@@ -46,6 +52,10 @@ public:
const QString &pathOfIncludingFile const QString &pathOfIncludingFile
); );
// File suffixes:
Q_INVOKABLE QString cxxHeaderSuffix() const;
Q_INVOKABLE QString cxxSourceSuffix() const;
private: private:
CppLocatorData * const m_locatorData; CppLocatorData * const m_locatorData;
}; };

View File

@@ -611,9 +611,19 @@ void openEditor(const Utils::FilePath &filePath, bool inNextSplit, Utils::Id edi
: EditorManager::NoFlags); : EditorManager::NoFlags);
} }
bool preferLowerCaseFileNames() bool preferLowerCaseFileNames(ProjectExplorer::Project *project)
{ {
return Internal::CppEditorPlugin::fileSettings()->lowerCaseFiles; return Internal::CppEditorPlugin::fileSettings(project).lowerCaseFiles;
}
QString preferredCxxHeaderSuffix(ProjectExplorer::Project *project)
{
return Internal::CppEditorPlugin::fileSettings(project).headerSuffix;
}
QString preferredCxxSourceSuffix(ProjectExplorer::Project *project)
{
return Internal::CppEditorPlugin::fileSettings(project).sourceSuffix;
} }
namespace Internal { namespace Internal {

View File

@@ -67,7 +67,9 @@ void CPPEDITOR_EXPORT openEditor(const Utils::FilePath &filePath, bool inNextSpl
class CppCodeModelSettings; class CppCodeModelSettings;
CppCodeModelSettings CPPEDITOR_EXPORT *codeModelSettings(); CppCodeModelSettings CPPEDITOR_EXPORT *codeModelSettings();
bool CPPEDITOR_EXPORT preferLowerCaseFileNames(); QString CPPEDITOR_EXPORT preferredCxxHeaderSuffix(ProjectExplorer::Project *project);
QString CPPEDITOR_EXPORT preferredCxxSourceSuffix(ProjectExplorer::Project *project);
bool CPPEDITOR_EXPORT preferLowerCaseFileNames(ProjectExplorer::Project *project);
UsePrecompiledHeaders CPPEDITOR_EXPORT getPchUsage(); UsePrecompiledHeaders CPPEDITOR_EXPORT getPchUsage();

View File

@@ -6,6 +6,8 @@
#include <designer/designerconstants.h> #include <designer/designerconstants.h>
#include <designer/qtdesignerformclasscodegenerator.h> #include <designer/qtdesignerformclasscodegenerator.h>
#include <cppeditor/cppeditorconstants.h> #include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cpptoolsreuse.h>
#include <projectexplorer/projecttree.h>
#include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtsupportconstants.h>
#include <QDebug> #include <QDebug>
@@ -22,12 +24,12 @@ FormClassWizard::FormClassWizard()
QString FormClassWizard::headerSuffix() const QString FormClassWizard::headerSuffix() const
{ {
return preferredSuffix(CppEditor::Constants::CPP_HEADER_MIMETYPE); return CppEditor::preferredCxxHeaderSuffix(ProjectExplorer::ProjectTree::currentProject());
} }
QString FormClassWizard::sourceSuffix() const QString FormClassWizard::sourceSuffix() const
{ {
return preferredSuffix(CppEditor::Constants::CPP_SOURCE_MIMETYPE); return CppEditor::preferredCxxSourceSuffix(ProjectExplorer::ProjectTree::currentProject());
} }
QString FormClassWizard::formSuffix() const QString FormClassWizard::formSuffix() const

View File

@@ -9,6 +9,7 @@
#include <cppeditor/abstracteditorsupport.h> #include <cppeditor/abstracteditorsupport.h>
#include <designer/formtemplatewizardpage.h> #include <designer/formtemplatewizardpage.h>
#include <projectexplorer/projecttree.h>
#include <qtsupport/codegenerator.h> #include <qtsupport/codegenerator.h>
#include <utils/filepath.h> #include <utils/filepath.h>
@@ -68,7 +69,8 @@ FormClassWizardParameters FormClassWizardDialog::parameters() const
m_classPage->getParameters(&rc); m_classPage->getParameters(&rc);
// Name the ui class in the Ui namespace after the class specified // Name the ui class in the Ui namespace after the class specified
rc.uiTemplate = QtSupport::CodeGenerator::changeUiClassName(m_rawFormTemplate, rc.className); rc.uiTemplate = QtSupport::CodeGenerator::changeUiClassName(m_rawFormTemplate, rc.className);
rc.usePragmaOnce = CppEditor::AbstractEditorSupport::usePragmaOnce(); rc.usePragmaOnce = CppEditor::AbstractEditorSupport::usePragmaOnce(
ProjectExplorer::ProjectTree::currentProject());
return rc; return rc;
} }

View File

@@ -8,9 +8,9 @@
#include "../designertr.h" #include "../designertr.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cppeditor/cppeditorconstants.h> #include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cpptoolsreuse.h>
#include <projectexplorer/projecttree.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/wizard.h> #include <utils/wizard.h>
@@ -32,9 +32,9 @@ FormClassWizardPage::FormClassWizardPage()
m_newClassWidget = new NewClassWidget(classGroupBox); m_newClassWidget = new NewClassWidget(classGroupBox);
m_newClassWidget->setHeaderExtension( m_newClassWidget->setHeaderExtension(
Utils::mimeTypeForName(CppEditor::Constants::CPP_HEADER_MIMETYPE).preferredSuffix()); CppEditor::preferredCxxHeaderSuffix(ProjectExplorer::ProjectTree::currentProject()));
m_newClassWidget->setSourceExtension( m_newClassWidget->setSourceExtension(
Utils::mimeTypeForName(CppEditor::Constants::CPP_SOURCE_MIMETYPE).preferredSuffix()); CppEditor::preferredCxxSourceSuffix(ProjectExplorer::ProjectTree::currentProject()));
m_newClassWidget->setLowerCaseFiles(lowercaseHeaderFiles()); m_newClassWidget->setLowerCaseFiles(lowercaseHeaderFiles());
connect(m_newClassWidget, &NewClassWidget::validChanged, connect(m_newClassWidget, &NewClassWidget::validChanged,
@@ -54,11 +54,7 @@ FormClassWizardPage::~FormClassWizardPage() = default;
// Retrieve settings of CppEditor plugin. // Retrieve settings of CppEditor plugin.
bool FormClassWizardPage::lowercaseHeaderFiles() bool FormClassWizardPage::lowercaseHeaderFiles()
{ {
QString lowerCaseSettingsKey = CppEditor::Constants::CPPEDITOR_SETTINGSGROUP; return CppEditor::preferLowerCaseFileNames(ProjectExplorer::ProjectTree::currentProject());
lowerCaseSettingsKey += '/';
lowerCaseSettingsKey += CppEditor::Constants::LOWERCASE_CPPFILES_KEY;
const bool lowerCaseDefault = CppEditor::Constants::LOWERCASE_CPPFILES_DEFAULT;
return Core::ICore::settings()->value(lowerCaseSettingsKey, QVariant(lowerCaseDefault)).toBool();
} }
void FormClassWizardPage::setClassName(const QString &suggestedClassName) void FormClassWizardPage::setClassName(const QString &suggestedClassName)

View File

@@ -12,6 +12,7 @@
#include <designer/cpp/formclasswizardpage.h> #include <designer/cpp/formclasswizardpage.h>
#include <cppeditor/cppeditorconstants.h> #include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cppeditorplugin.h>
#include <cppeditor/cppeditorwidget.h> #include <cppeditor/cppeditorwidget.h>
#include <cppeditor/cppmodelmanager.h> #include <cppeditor/cppmodelmanager.h>
#include <cppeditor/cppsemanticinfo.h> #include <cppeditor/cppsemanticinfo.h>
@@ -795,6 +796,6 @@ void QtCreatorIntegration::handleSymbolRenameStage2(
void QtCreatorIntegration::slotSyncSettingsToDesigner() void QtCreatorIntegration::slotSyncSettingsToDesigner()
{ {
// Set promotion-relevant parameters on integration. // Set promotion-relevant parameters on integration.
setHeaderSuffix(Utils::mimeTypeForName(CppEditor::Constants::CPP_HEADER_MIMETYPE).preferredSuffix()); setHeaderSuffix(CppEditor::preferredCxxHeaderSuffix(ProjectTree::currentProject()));
setHeaderLowercase(FormClassWizardPage::lowercaseHeaderFiles()); setHeaderLowercase(FormClassWizardPage::lowercaseHeaderFiles());
} }

View File

@@ -5,12 +5,13 @@
#include "formtemplatewizardpage.h" #include "formtemplatewizardpage.h"
#include <designer/cpp/formclasswizardparameters.h> #include <designer/cpp/formclasswizardparameters.h>
#include <utils/codegeneration.h> #include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cppeditor/abstracteditorsupport.h> #include <cppeditor/abstracteditorsupport.h>
#include <projectexplorer/projecttree.h>
#include <qtsupport/codegenerator.h> #include <qtsupport/codegenerator.h>
#include <qtsupport/codegensettings.h> #include <qtsupport/codegensettings.h>
#include <extensionsystem/pluginmanager.h> #include <utils/codegeneration.h>
#include <QTextStream> #include <QTextStream>
#include <QSettings> #include <QSettings>
@@ -70,12 +71,11 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
const QString unqualifiedClassName = namespaceList.takeLast(); const QString unqualifiedClassName = namespaceList.takeLast();
const QString headerLicense = ProjectExplorer::Project * const project = ProjectExplorer::ProjectTree::currentProject();
CppEditor::AbstractEditorSupport::licenseTemplate( const QString headerLicense = CppEditor::AbstractEditorSupport::licenseTemplate(
FilePath::fromString(parameters.headerFile), parameters.className); project, FilePath::fromString(parameters.headerFile), parameters.className);
const QString sourceLicense = const QString sourceLicense = CppEditor::AbstractEditorSupport::licenseTemplate(
CppEditor::AbstractEditorSupport::licenseTemplate( project, FilePath::fromString(parameters.sourceFile), parameters.className);
FilePath::fromString(parameters.sourceFile), parameters.className);
// Include guards // Include guards
const QString guard = Utils::headerGuard(parameters.headerFile, namespaceList); const QString guard = Utils::headerGuard(parameters.headerFile, namespaceList);

View File

@@ -7,7 +7,7 @@
#include <coreplugin/generatedfile.h> #include <coreplugin/generatedfile.h>
#include <cppeditor/abstracteditorsupport.h> #include <cppeditor/abstracteditorsupport.h>
#include <projectexplorer/projecttree.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
@@ -82,6 +82,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
// First create the widget wrappers (plugins) and - if requested - skeletons // First create the widget wrappers (plugins) and - if requested - skeletons
// for the widgets. // for the widgets.
const int widgetCount = options.widgetOptions.size(); const int widgetCount = options.widgetOptions.size();
ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject();
for (int i = 0; i < widgetCount; i++) { for (int i = 0; i < widgetCount; i++) {
const PluginOptions::WidgetOptions &wo = options.widgetOptions.at(i); const PluginOptions::WidgetOptions &wo = options.widgetOptions.at(i);
sm.clear(); sm.clear();
@@ -95,7 +96,8 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile pluginHeader(baseDir / wo.pluginHeaderFile); Core::GeneratedFile pluginHeader(baseDir / wo.pluginHeaderFile);
pluginHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( pluginHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
FilePath::fromString(wo.pluginHeaderFile), wo.pluginClassName) project, FilePath::fromString(wo.pluginHeaderFile),
wo.pluginClassName)
+ pluginHeaderContents); + pluginHeaderContents);
rc.push_back(pluginHeader); rc.push_back(pluginHeader);
@@ -122,6 +124,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile pluginSource(baseDir / wo.pluginSourceFile); Core::GeneratedFile pluginSource(baseDir / wo.pluginSourceFile);
pluginSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( pluginSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
project,
FilePath::fromString(wo.pluginSourceFile), wo.pluginClassName) FilePath::fromString(wo.pluginSourceFile), wo.pluginClassName)
+ pluginSourceContents); + pluginSourceContents);
if (i == 0 && widgetCount == 1) // Open first widget unless collection if (i == 0 && widgetCount == 1) // Open first widget unless collection
@@ -169,6 +172,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile widgetHeader(baseDir / wo.widgetHeaderFile); Core::GeneratedFile widgetHeader(baseDir / wo.widgetHeaderFile);
widgetHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( widgetHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
project,
FilePath::fromString(wo.widgetHeaderFile), FilePath::fromString(wo.widgetHeaderFile),
wo.widgetClassName) wo.widgetClassName)
+ widgetHeaderContents); + widgetHeaderContents);
@@ -181,6 +185,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile widgetSource(baseDir / wo.widgetSourceFile); Core::GeneratedFile widgetSource(baseDir / wo.widgetSourceFile);
widgetSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( widgetSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
project,
FilePath::fromString(wo.widgetSourceFile), FilePath::fromString(wo.widgetSourceFile),
wo.widgetClassName) wo.widgetClassName)
+ widgetSourceContents); + widgetSourceContents);
@@ -218,6 +223,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile collectionHeader(baseDir / options.collectionHeaderFile); Core::GeneratedFile collectionHeader(baseDir / options.collectionHeaderFile);
collectionHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( collectionHeader.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
project,
FilePath::fromString(options.collectionHeaderFile), FilePath::fromString(options.collectionHeaderFile),
options.collectionClassName) options.collectionClassName)
+ collectionHeaderContents); + collectionHeaderContents);
@@ -235,6 +241,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara
return QList<Core::GeneratedFile>(); return QList<Core::GeneratedFile>();
Core::GeneratedFile collectionSource(baseDir / options.collectionSourceFile); Core::GeneratedFile collectionSource(baseDir / options.collectionSourceFile);
collectionSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate( collectionSource.setContents(CppEditor::AbstractEditorSupport::licenseTemplate(
project,
FilePath::fromString(options.collectionSourceFile), FilePath::fromString(options.collectionSourceFile),
options.collectionClassName) options.collectionClassName)
+ collectionSourceFileContents); + collectionSourceFileContents);

View File

@@ -10,10 +10,12 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cppeditor/cppeditorconstants.h> #include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cpptoolsreuse.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/targetsetuppage.h> #include <projectexplorer/targetsetuppage.h>
#include <projectexplorer/task.h> #include <projectexplorer/task.h>
@@ -39,12 +41,12 @@ QtWizard::QtWizard()
QString QtWizard::sourceSuffix() QString QtWizard::sourceSuffix()
{ {
return preferredSuffix(QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE)); return CppEditor::preferredCxxSourceSuffix(ProjectTree::currentProject());
} }
QString QtWizard::headerSuffix() QString QtWizard::headerSuffix()
{ {
return preferredSuffix(QLatin1String(ProjectExplorer::Constants::CPP_HEADER_MIMETYPE)); return CppEditor::preferredCxxHeaderSuffix(ProjectTree::currentProject());
} }
QString QtWizard::formSuffix() QString QtWizard::formSuffix()