diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2023-05-31 14:29:03 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2023-06-08 08:23:01 +0000 |
commit | 8e75381fce29504cd3f278f90cfcda22b9e47b4d (patch) | |
tree | 2d5f97c186e1ec6635b792f810284fb6141860bd /src/plugins/cppeditor | |
parent | 6cc325f845b1ed2df3d28271146919c158f003d3 (diff) |
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>
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r-- | src/plugins/cppeditor/abstracteditorsupport.cpp | 9 | ||||
-rw-r--r-- | src/plugins/cppeditor/abstracteditorsupport.h | 8 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.cpp | 81 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.h | 16 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfilesettingspage.cpp | 201 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfilesettingspage.h | 36 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfindreferences.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfindreferences.h | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppheadersource_test.cpp | 30 | ||||
-rw-r--r-- | src/plugins/cppeditor/cpptoolsjsextension.cpp | 32 | ||||
-rw-r--r-- | src/plugins/cppeditor/cpptoolsjsextension.h | 10 | ||||
-rw-r--r-- | src/plugins/cppeditor/cpptoolsreuse.cpp | 14 | ||||
-rw-r--r-- | src/plugins/cppeditor/cpptoolsreuse.h | 4 |
13 files changed, 351 insertions, 96 deletions
diff --git a/src/plugins/cppeditor/abstracteditorsupport.cpp b/src/plugins/cppeditor/abstracteditorsupport.cpp index a47fb412f3..a275ed6b57 100644 --- a/src/plugins/cppeditor/abstracteditorsupport.cpp +++ b/src/plugins/cppeditor/abstracteditorsupport.cpp @@ -39,9 +39,10 @@ void AbstractEditorSupport::notifyAboutUpdatedContents() const 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; expander.registerVariable("Cpp:License:FileName", Tr::tr("The file name."), [filePath] { return filePath.fileName(); }); @@ -51,9 +52,9 @@ QString AbstractEditorSupport::licenseTemplate(const FilePath &filePath, const Q 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 diff --git a/src/plugins/cppeditor/abstracteditorsupport.h b/src/plugins/cppeditor/abstracteditorsupport.h index 2b18873238..277001e043 100644 --- a/src/plugins/cppeditor/abstracteditorsupport.h +++ b/src/plugins/cppeditor/abstracteditorsupport.h @@ -9,6 +9,8 @@ #include <QObject> +namespace ProjectExplorer { class Project; } + namespace CppEditor { class CppModelManager; @@ -30,8 +32,10 @@ public: void notifyAboutUpdatedContents() const; unsigned revision() const { return m_revision; } - static QString licenseTemplate(const Utils::FilePath &filePath = {}, const QString &className = {}); - static bool usePragmaOnce(); + static QString licenseTemplate(ProjectExplorer::Project *project, + const Utils::FilePath &filePath = {}, + const QString &className = {}); + static bool usePragmaOnce(ProjectExplorer::Project *project); private: CppModelManager *m_modelmanager; diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 5791a5cb62..223ec0e09f 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -72,6 +72,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectpanelfactory.h> #include <projectexplorer/projecttree.h> @@ -261,17 +262,18 @@ void CppEditorPlugin::initialize() this, [] { CppModelManager::switchHeaderSource(true); }); MacroExpander *expander = globalMacroExpander(); + + // TODO: Per-project variants of these three? expander->registerVariable("Cpp:LicenseTemplate", Tr::tr("The license template."), - []() { return CppEditorPlugin::licenseTemplate(); }); + []() { return CppEditorPlugin::licenseTemplate(nullptr); }); expander->registerFileVariables("Cpp:LicenseTemplatePath", Tr::tr("The configured path to the license template"), - []() { return CppEditorPlugin::licenseTemplatePath(); }); - + []() { return CppEditorPlugin::licenseTemplatePath(nullptr); }); expander->registerVariable( "Cpp:PragmaOnce", 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; quickFixSettingsPanelFactory->setPriority(100); @@ -505,6 +507,14 @@ void CppEditorPlugin::extensionsInitialized() if (!d->m_fileSettings.applySuffixesToMimeDB()) 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()) { d->m_clangdSettingsPage = new ClangdSettingsPage; const auto clangdPanelFactory = new ProjectPanelFactory; @@ -614,50 +624,39 @@ void CppEditorPlugin::clearHeaderSourceCache() 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() +CppCodeModelSettings *CppEditorPlugin::codeModelSettings() { - return m_instance->d->m_fileSettings.sourcePrefixes; + return &d->m_codeModelSettings; } -CppCodeModelSettings *CppEditorPlugin::codeModelSettings() +CppFileSettings CppEditorPlugin::fileSettings(Project *project) { - return &d->m_codeModelSettings; + if (!project) + return instance()->d->m_fileSettings; + return CppFileSettingsForProject(project).settings(); } -CppFileSettings *CppEditorPlugin::fileSettings() +#ifdef WITH_TESTS +void CppEditorPlugin::setGlobalFileSettings(const CppFileSettings &settings) { - return &instance()->d->m_fileSettings; + instance()->d->m_fileSettings = settings; } +#endif static QStringList findFilesInProject(const QString &name, const Project *project) { @@ -721,11 +720,12 @@ static QStringList baseNameWithAllSuffixes(const QString &baseName, const QStrin return result; } -static QStringList baseNamesWithAllPrefixes(const QStringList &baseNames, bool isHeader) +static QStringList baseNamesWithAllPrefixes(const CppFileSettings &settings, + const QStringList &baseNames, bool isHeader) { QStringList result; - const QStringList &sourcePrefixes = m_instance->sourcePrefixes(); - const QStringList &headerPrefixes = m_instance->headerPrefixes(); + const QStringList &sourcePrefixes = settings.sourcePrefixes; + const QStringList &headerPrefixes = settings.headerPrefixes; for (const QString &name : baseNames) { for (const QString &prefix : isHeader ? headerPrefixes : sourcePrefixes) { @@ -812,6 +812,9 @@ FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader, if (m_headerSourceMapping.contains(fi.absoluteFilePath())) return FilePath::fromString(m_headerSourceMapping.value(fi.absoluteFilePath())); + Project * const projectForFile = ProjectManager::projectForFile(filePath); + const CppFileSettings settings = CppEditorPlugin::fileSettings(projectForFile); + if (debug) qDebug() << Q_FUNC_INFO << fileName << kind; @@ -838,11 +841,11 @@ FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader, const QDir absoluteDir = fi.absoluteDir(); QStringList candidateDirs(absoluteDir.absolutePath()); // If directory is not root, try matching against its siblings - const QStringList searchPaths = isHeader ? m_instance->sourceSearchPaths() - : m_instance->headerSearchPaths(); + const QStringList searchPaths = isHeader ? settings.sourceSearchPaths + : settings.headerSearchPaths; 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 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 - Project *currentProject = ProjectTree::currentProject(); + Project *currentProject = projectForFile; + if (!projectForFile) + currentProject = ProjectTree::currentProject(); if (currentProject) { const FilePath path = correspondingHeaderOrSourceInProject(fi, candidateFileNames, currentProject, cacheUsage); diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index c28ee16b1e..d5b5b75f72 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -5,6 +5,7 @@ #include <extensionsystem/iplugin.h> +namespace ProjectExplorer { class Project; } namespace Utils { class FilePath; } namespace CppEditor { @@ -29,14 +30,10 @@ public: CppQuickFixAssistProvider *quickFixProvider() const; - static const QStringList &headerSearchPaths(); - static const QStringList &sourceSearchPaths(); - static const QStringList &headerPrefixes(); - static const QStringList &sourcePrefixes(); static void clearHeaderSourceCache(); - static Utils::FilePath licenseTemplatePath(); - static QString licenseTemplate(); - static bool usePragmaOnce(); + static Utils::FilePath licenseTemplatePath(ProjectExplorer::Project *project); + static QString licenseTemplate(ProjectExplorer::Project *project); + static bool usePragmaOnce(ProjectExplorer::Project *project); void openDeclarationDefinitionInNextSplit(); void openTypeHierarchy(); @@ -46,7 +43,10 @@ public: void switchDeclarationDefinition(); CppCodeModelSettings *codeModelSettings(); - static CppFileSettings *fileSettings(); + static CppFileSettings fileSettings(ProjectExplorer::Project *project); +#ifdef WITH_TESTS + static void setGlobalFileSettings(const CppFileSettings &settings); +#endif signals: void typeHierarchyRequested(); diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index 447d608369..21411577d3 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -7,10 +7,9 @@ #include "cppeditortr.h" #include <app/app_version.h> - #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> - +#include <projectexplorer/project.h> #include <utils/fileutils.h> #include <utils/hostosinfo.h> #include <utils/layoutbuilder.h> @@ -25,11 +24,14 @@ #include <QLocale> #include <QSettings> #include <QTextStream> +#include <QVBoxLayout> using namespace Utils; namespace CppEditor::Internal { +const char projectSettingsKeyC[] = "CppEditorFileNames"; +const char useGlobalKeyC[] = "UseGlobal"; const char headerPrefixesKeyC[] = "HeaderPrefixes"; const char sourcePrefixesKeyC[] = "SourcePrefixes"; const char headerSuffixKeyC[] = "HeaderSuffix"; @@ -202,18 +204,14 @@ static void parseLicenseTemplatePlaceholders(QString *t) } // Convenience that returns the formatted license template. -QString CppFileSettings::licenseTemplate() +QString CppFileSettings::licenseTemplate() const { - const QSettings *s = Core::ICore::settings(); - QString key = QLatin1String(Constants::CPPEDITOR_SETTINGSGROUP); - key += QLatin1Char('/'); - key += QLatin1String(licenseTemplatePathKeyC); - const QString path = s->value(key, QString()).toString(); - if (path.isEmpty()) + if (licenseTemplatePath.isEmpty()) return QString(); - QFile file(path); + QFile file(licenseTemplatePath); 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(); } @@ -235,11 +233,17 @@ QString CppFileSettings::licenseTemplate() class CppFileSettingsWidget final : public Core::IOptionsPageWidget { + Q_OBJECT + public: explicit CppFileSettingsWidget(CppFileSettings *settings); void apply() final; void setSettings(const CppFileSettings &s); + CppFileSettings currentSettings() const; + +signals: + void userChange(); private: void slotEdit(); @@ -336,6 +340,25 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings) m_licenseTemplatePathChooser->addButton(Tr::tr("Edit..."), this, [this] { slotEdit(); }); 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 @@ -358,17 +381,7 @@ static QStringList trimmedPaths(const QString &paths) void CppFileSettingsWidget::apply() { - 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(); - + const CppFileSettings rc = currentSettings(); if (rc == *m_settings) return; @@ -398,6 +411,21 @@ void CppFileSettingsWidget::setSettings(const CppFileSettings &s) 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() { FilePath path = licenseTemplatePath(); @@ -426,4 +454,133 @@ CppFileSettingsPage::CppFileSettingsPage(CppFileSettings *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 + +#include <cppfilesettingspage.moc> diff --git a/src/plugins/cppeditor/cppfilesettingspage.h b/src/plugins/cppeditor/cppfilesettingspage.h index 50cc38133a..f4c65fbbc5 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.h +++ b/src/plugins/cppeditor/cppfilesettingspage.h @@ -6,6 +6,7 @@ #include "cppeditorconstants.h" #include <coreplugin/dialogs/ioptionspage.h> +#include <projectexplorer/projectsettingswidget.h> #include <QDir> @@ -13,6 +14,8 @@ QT_BEGIN_NAMESPACE class QSettings; QT_END_NAMESPACE +namespace ProjectExplorer { class Project; } + namespace CppEditor::Internal { class CppFileSettings @@ -38,18 +41,47 @@ public: bool applySuffixesToMimeDB(); // Convenience to return a license template completely formatted. - // Currently made public in - static QString licenseTemplate(); + QString licenseTemplate() 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); } }; +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 { public: explicit CppFileSettingsPage(CppFileSettings *settings); }; +class CppFileSettingsForProjectWidget : public ProjectExplorer::ProjectSettingsWidget +{ +public: + CppFileSettingsForProjectWidget(const CppFileSettingsForProject &settings); + ~CppFileSettingsForProjectWidget(); + +private: + class Private; + Private * const d; +}; + } // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cppfindreferences.cpp b/src/plugins/cppeditor/cppfindreferences.cpp index 5da2285438..460ad7d0b2 100644 --- a/src/plugins/cppeditor/cppfindreferences.cpp +++ b/src/plugins/cppeditor/cppfindreferences.cpp @@ -398,6 +398,8 @@ void CppFindReferences::findUsages(CPlusPlus::Symbol *symbol, parameters.symbolId = fullIdForSymbol(symbol); parameters.symbolFilePath = symbol->filePath(); parameters.categorize = codeModelSettings()->categorizeFindReferences(); + parameters.preferLowerCaseFileNames = preferLowerCaseFileNames( + ProjectManager::projectForFile(symbol->filePath())); if (symbol->asClass() || symbol->asForwardClassDeclaration()) { CPlusPlus::Overview overview; @@ -475,7 +477,7 @@ void CppFindReferences::onReplaceButtonClicked(Core::SearchResult *search, const ProjectExplorerPlugin::renameFilesForSymbol( parameters.prettySymbolName, text, parameters.filesToRename, - preferLowerCaseFileNames()); + parameters.preferLowerCaseFileNames); } void CppFindReferences::searchAgain(SearchResult *search) diff --git a/src/plugins/cppeditor/cppfindreferences.h b/src/plugins/cppeditor/cppfindreferences.h index b05ce723c4..37e105ab36 100644 --- a/src/plugins/cppeditor/cppfindreferences.h +++ b/src/plugins/cppeditor/cppfindreferences.h @@ -4,6 +4,7 @@ #pragma once #include "cppeditor_global.h" +#include "cppeditorconstants.h" #include <coreplugin/find/searchresultwindow.h> #include <cplusplus/FindUsages.h> @@ -51,6 +52,7 @@ public: QString prettySymbolName; Utils::FilePaths filesToRename; bool categorize = false; + bool preferLowerCaseFileNames = Constants::LOWERCASE_CPPFILES_DEFAULT; }; class CppFindReferences: public QObject diff --git a/src/plugins/cppeditor/cppheadersource_test.cpp b/src/plugins/cppeditor/cppheadersource_test.cpp index d94920a329..28f5a8b6fb 100644 --- a/src/plugins/cppeditor/cppheadersource_test.cpp +++ b/src/plugins/cppeditor/cppheadersource_test.cpp @@ -71,25 +71,27 @@ void HeaderSourceTest::test_data() void HeaderSourceTest::initTestCase() { QDir(baseTestDir()).mkpath(_(".")); - CppFileSettings *fs = CppEditorPlugin::fileSettings(); - fs->headerSearchPaths.append(QLatin1String("include")); - fs->headerSearchPaths.append(QLatin1String("../include")); - fs->sourceSearchPaths.append(QLatin1String("src")); - fs->sourceSearchPaths.append(QLatin1String("../src")); - fs->headerPrefixes.append(QLatin1String("testh_")); - fs->sourcePrefixes.append(QLatin1String("testc_")); + CppFileSettings fs = CppEditorPlugin::fileSettings(nullptr); + fs.headerSearchPaths.append(QLatin1String("include")); + fs.headerSearchPaths.append(QLatin1String("../include")); + fs.sourceSearchPaths.append(QLatin1String("src")); + fs.sourceSearchPaths.append(QLatin1String("../src")); + fs.headerPrefixes.append(QLatin1String("testh_")); + fs.sourcePrefixes.append(QLatin1String("testc_")); + CppEditorPlugin::setGlobalFileSettings(fs); } void HeaderSourceTest::cleanupTestCase() { Utils::FilePath::fromString(baseTestDir()).removeRecursively(); - CppFileSettings *fs = CppEditorPlugin::fileSettings(); - fs->headerSearchPaths.removeLast(); - fs->headerSearchPaths.removeLast(); - fs->sourceSearchPaths.removeLast(); - fs->sourceSearchPaths.removeLast(); - fs->headerPrefixes.removeLast(); - fs->sourcePrefixes.removeLast(); + CppFileSettings fs = CppEditorPlugin::fileSettings(nullptr); + fs.headerSearchPaths.removeLast(); + fs.headerSearchPaths.removeLast(); + fs.sourceSearchPaths.removeLast(); + fs.sourceSearchPaths.removeLast(); + fs.headerPrefixes.removeLast(); + fs.sourcePrefixes.removeLast(); + CppEditorPlugin::setGlobalFileSettings(fs); } } // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cpptoolsjsextension.cpp b/src/plugins/cppeditor/cpptoolsjsextension.cpp index 73a846593c..0818af0acb 100644 --- a/src/plugins/cppeditor/cpptoolsjsextension.cpp +++ b/src/plugins/cppeditor/cpptoolsjsextension.cpp @@ -3,6 +3,7 @@ #include "cpptoolsjsextension.h" +#include "cppeditorplugin.h" #include "cppfilesettingspage.h" #include "cpplocatordata.h" #include "cppworkingcopy.h" @@ -12,6 +13,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectmanager.h> #include <projectexplorer/projectnodes.h> +#include <projectexplorer/projecttree.h> #include <cplusplus/AST.h> #include <cplusplus/ASTPath.h> @@ -27,6 +29,13 @@ 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) { return Utils::FilePath::fromStringWithExtension(path, extension).toString(); @@ -37,6 +46,16 @@ QString CppToolsJsExtension::headerGuard(const QString &in) const return Utils::headerGuard(in); } +QString CppToolsJsExtension::licenseTemplate() const +{ + return fileSettings().licenseTemplate(); +} + +bool CppToolsJsExtension::usePragmaOnce() const +{ + return fileSettings().headerPragmaOnce; +} + static QStringList parts(const QString &klass) { 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 { const QString raw = fileName(className(klass), extension); - CppFileSettings settings; - settings.fromSettings(Core::ICore::settings()); + const CppFileSettings &settings = fileSettings(); if (!settings.lowerCaseFiles) return raw; @@ -249,4 +267,14 @@ QString CppToolsJsExtension::includeStatement( return {}; } +QString CppToolsJsExtension::cxxHeaderSuffix() const +{ + return fileSettings().headerSuffix; +} + +QString CppToolsJsExtension::cxxSourceSuffix() const +{ + return fileSettings().sourceSuffix; +} + } // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cpptoolsjsextension.h b/src/plugins/cppeditor/cpptoolsjsextension.h index cdb7e56c81..593f953641 100644 --- a/src/plugins/cppeditor/cpptoolsjsextension.h +++ b/src/plugins/cppeditor/cpptoolsjsextension.h @@ -26,6 +26,12 @@ public: // Generate header guard: 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: Q_INVOKABLE QStringList namespaces(const QString &klass) const; Q_INVOKABLE bool hasNamespaces(const QString &klass) const; @@ -46,6 +52,10 @@ public: const QString &pathOfIncludingFile ); + // File suffixes: + Q_INVOKABLE QString cxxHeaderSuffix() const; + Q_INVOKABLE QString cxxSourceSuffix() const; + private: CppLocatorData * const m_locatorData; }; diff --git a/src/plugins/cppeditor/cpptoolsreuse.cpp b/src/plugins/cppeditor/cpptoolsreuse.cpp index 8f68ed3ec9..325aa8bb24 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.cpp +++ b/src/plugins/cppeditor/cpptoolsreuse.cpp @@ -611,9 +611,19 @@ void openEditor(const Utils::FilePath &filePath, bool inNextSplit, Utils::Id edi : 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 { diff --git a/src/plugins/cppeditor/cpptoolsreuse.h b/src/plugins/cppeditor/cpptoolsreuse.h index 9948ab6de7..78d158b576 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.h +++ b/src/plugins/cppeditor/cpptoolsreuse.h @@ -67,7 +67,9 @@ void CPPEDITOR_EXPORT openEditor(const Utils::FilePath &filePath, bool inNextSpl class CppCodeModelSettings; 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(); |