diff --git a/src/plugins/clangformat/clangformatconfigwidget.cpp b/src/plugins/clangformat/clangformatconfigwidget.cpp index 9d44fe1dcc8..2a6f3f9b6b5 100644 --- a/src/plugins/clangformat/clangformatconfigwidget.cpp +++ b/src/plugins/clangformat/clangformatconfigwidget.cpp @@ -43,7 +43,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -100,19 +102,22 @@ bool ClangFormatConfigWidget::eventFilter(QObject *object, QEvent *event) return QWidget::eventFilter(object, event); } -ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *project, QWidget *parent) +ClangFormatConfigWidget::ClangFormatConfigWidget(TextEditor::ICodeStylePreferences *codeStyle, + ProjectExplorer::Project *project, + QWidget *parent) : CppCodeStyleWidget(parent) , m_project(project) , m_checks(std::make_unique()) , m_ui(std::make_unique()) { m_ui->setupUi(this); + setEnabled(!codeStyle->isReadOnly()); Utils::FilePath filePath = Core::ICore::userResourcePath(); - if (m_project) - filePath = filePath / "clang-format/" / currentProjectUniqueId(); - filePath = filePath / QLatin1String(Constants::SETTINGS_FILE_NAME); - m_config = std::make_unique(filePath); + filePath = filePath / "clang-format/" + / Utils::FileUtils::fileSystemFriendlyName(codeStyle->displayName()) + / QLatin1String(Constants::SETTINGS_FILE_NAME); + m_config = std::make_unique(filePath, codeStyle->isReadOnly()); initChecksAndPreview(); showCombobox(); @@ -329,8 +334,7 @@ void ClangFormatConfigWidget::fillTable() Utils::ExecuteOnDestruction executeOnDestruction([this]() { m_disableTableUpdate = false; }); m_disableTableUpdate = true; - const std::string configText = m_project ? currentProjectConfigText() - : currentGlobalConfigText(); + const std::string configText = readFile(m_config->filePath().path()); for (QObject *child : m_checksWidget->children()) { if (!qobject_cast(child) && !qobject_cast(child) diff --git a/src/plugins/clangformat/clangformatconfigwidget.h b/src/plugins/clangformat/clangformatconfigwidget.h index fb6ffa04e0b..9a460892501 100644 --- a/src/plugins/clangformat/clangformatconfigwidget.h +++ b/src/plugins/clangformat/clangformatconfigwidget.h @@ -48,7 +48,8 @@ class ClangFormatConfigWidget : public CppEditor::CppCodeStyleWidget Q_OBJECT public: - explicit ClangFormatConfigWidget(ProjectExplorer::Project *project = nullptr, + explicit ClangFormatConfigWidget(TextEditor::ICodeStylePreferences *codeStyle, + ProjectExplorer::Project *project = nullptr, QWidget *parent = nullptr); ~ClangFormatConfigWidget() override; void apply() override; diff --git a/src/plugins/clangformat/clangformatfile.cpp b/src/plugins/clangformat/clangformatfile.cpp index 3c64ebe1b48..b439dc5698b 100644 --- a/src/plugins/clangformat/clangformatfile.cpp +++ b/src/plugins/clangformat/clangformatfile.cpp @@ -25,6 +25,7 @@ #include "clangformatfile.h" #include "clangformatsettings.h" +#include "clangformatutils.h" #include #include #include @@ -34,11 +35,18 @@ using namespace ClangFormat; -ClangFormatFile::ClangFormatFile(Utils::FilePath filePath) +ClangFormatFile::ClangFormatFile(Utils::FilePath filePath, bool isReadOnly) : m_filePath(filePath) + , m_isReadOnly(isReadOnly) { if (!m_filePath.exists()) { - resetStyleToLLVM(); + // create file and folder + m_filePath.parentDir().createDir(); + std::fstream newStyleFile(m_filePath.path().toStdString(), std::fstream::out); + if (newStyleFile.is_open()) { + newStyleFile.close(); + } + resetStyleToQtC(); return; } @@ -46,7 +54,7 @@ ClangFormatFile::ClangFormatFile(Utils::FilePath filePath) const std::error_code error = clang::format::parseConfiguration(m_filePath.fileContents().toStdString(), &m_style); if (error.value() != static_cast(clang::format::ParseError::Success)) { - resetStyleToLLVM(); + resetStyleToQtC(); } } @@ -65,10 +73,15 @@ void ClangFormatFile::setStyle(clang::format::FormatStyle style) saveNewFormat(); } -void ClangFormatFile::resetStyleToLLVM() +bool ClangFormatFile::isReadOnly() const { - m_style = clang::format::getLLVMStyle(); - saveNewFormat(); + return m_isReadOnly; +} + +void ClangFormatFile::resetStyleToQtC() +{ + m_style = qtcStyle(); + saveStyleToFile(m_style, m_filePath); } void ClangFormatFile::setBasedOnStyle(QString styleName) @@ -107,17 +120,17 @@ QString ClangFormatFile::changeFields(QList fields) void ClangFormatFile::saveNewFormat() { - std::string style = clang::format::configurationAsText(m_style); + if (m_isReadOnly) + return; - // workaround: configurationAsText() add comment "# " before BasedOnStyle line - const int pos = style.find("# BasedOnStyle"); - if (pos != int(std::string::npos)) - style.erase(pos, 2); - m_filePath.writeFileContents(QByteArray::fromStdString(style)); + saveStyleToFile(m_style, m_filePath); } void ClangFormatFile::saveNewFormat(QByteArray style) { + if (m_isReadOnly) + return; + m_filePath.writeFileContents(style); } diff --git a/src/plugins/clangformat/clangformatfile.h b/src/plugins/clangformat/clangformatfile.h index f0dddd4ec03..da864c2a753 100644 --- a/src/plugins/clangformat/clangformatfile.h +++ b/src/plugins/clangformat/clangformatfile.h @@ -37,11 +37,11 @@ namespace ClangFormat { class ClangFormatFile { public: - explicit ClangFormatFile(Utils::FilePath file); + explicit ClangFormatFile(Utils::FilePath file, bool isReadOnly); clang::format::FormatStyle format(); Utils::FilePath filePath(); - void resetStyleToLLVM(); + void resetStyleToQtC(); void setBasedOnStyle(QString styleName); void setStyle(clang::format::FormatStyle style); QString setStyle(QString style); @@ -54,6 +54,7 @@ public: TextEditor::TabSettings toTabSettings(ProjectExplorer::Project *project) const; void fromCppCodeStyleSettings(const CppEditor::CppCodeStyleSettings &settings); void fromTabSettings(const TextEditor::TabSettings &settings); + bool isReadOnly() const; private: void saveNewFormat(); @@ -62,6 +63,7 @@ private: private: Utils::FilePath m_filePath; clang::format::FormatStyle m_style; + const bool m_isReadOnly; }; } // namespace ClangFormat diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp index 0fbc44eefe9..78204ae3696 100644 --- a/src/plugins/clangformat/clangformatplugin.cpp +++ b/src/plugins/clangformat/clangformatplugin.cpp @@ -84,11 +84,13 @@ public: return new ClangFormatIndenter(doc); } - std::pair additionalTab(QWidget *parent) const override + std::pair additionalTab( + TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const override { if (!parent) - return {new ClangFormatConfigWidget(), tr("ClangFormat")}; - return {new ClangFormatConfigWidget(SessionManager::startupProject()), tr("ClangFormat")}; + return {new ClangFormatConfigWidget(codeStyle), tr("ClangFormat")}; + return {new ClangFormatConfigWidget(codeStyle, SessionManager::startupProject()), + tr("ClangFormat")}; } }; diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp index cf32bff3545..21fab5cc931 100644 --- a/src/plugins/clangformat/clangformatutils.cpp +++ b/src/plugins/clangformat/clangformatutils.cpp @@ -200,6 +200,17 @@ QString currentProjectUniqueId() .toHex(0)); } +void saveStyleToFile(clang::format::FormatStyle style, Utils::FilePath filePath) +{ + std::string styleStr = clang::format::configurationAsText(style); + + // workaround: configurationAsText() add comment "# " before BasedOnStyle line + const int pos = styleStr.find("# BasedOnStyle"); + if (pos != int(std::string::npos)) + styleStr.erase(pos, 2); + filePath.writeFileContents(QByteArray::fromStdString(styleStr)); +} + static bool useProjectOverriddenSettings() { const Project *project = SessionManager::startupProject(); @@ -371,7 +382,7 @@ void addQtcStatementMacros(clang::format::FormatStyle &style) } } -static std::string readFile(const QString &path) +std::string readFile(const QString &path) { const std::string defaultStyle = clang::format::configurationAsText(qtcStyle()); diff --git a/src/plugins/clangformat/clangformatutils.h b/src/plugins/clangformat/clangformatutils.h index 3caf6c9d6fc..aa7a8f30cc1 100644 --- a/src/plugins/clangformat/clangformatutils.h +++ b/src/plugins/clangformat/clangformatutils.h @@ -46,10 +46,12 @@ std::string currentGlobalConfigText(); clang::format::FormatStyle currentProjectStyle(); clang::format::FormatStyle currentGlobalStyle(); +std::string readFile(const QString &path); // Is the style from the matching .clang-format file or global one if it's not found. QString configForFile(Utils::FilePath fileName); clang::format::FormatStyle styleForFile(Utils::FilePath fileName); +void saveStyleToFile(clang::format::FormatStyle style, Utils::FilePath filePath); void addQtcStatementMacros(clang::format::FormatStyle &style); clang::format::FormatStyle qtcStyle(); diff --git a/src/plugins/cppeditor/cppcodestylepreferencesfactory.cpp b/src/plugins/cppeditor/cppcodestylepreferencesfactory.cpp index c417f945c22..c3ec1b345eb 100644 --- a/src/plugins/cppeditor/cppcodestylepreferencesfactory.cpp +++ b/src/plugins/cppeditor/cppcodestylepreferencesfactory.cpp @@ -109,7 +109,7 @@ TextEditor::CodeStyleEditorWidget *CppCodeStylePreferencesFactory::createEditor( widget->layout()->setContentsMargins(0, 0, 0, 0); widget->setCodeStyle(cppPreferences); - const auto tab = additionalTab(parent); + const auto tab = additionalTab(preferences, parent); widget->addTab(tab.first, tab.second); return widget; @@ -131,8 +131,9 @@ QString CppCodeStylePreferencesFactory::previewText() const } std::pair CppCodeStylePreferencesFactory::additionalTab( - QWidget *parent) const + TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const { + Q_UNUSED(codeStyle) Q_UNUSED(parent) return {nullptr, ""}; } diff --git a/src/plugins/cppeditor/cppcodestylepreferencesfactory.h b/src/plugins/cppeditor/cppcodestylepreferencesfactory.h index 60c123a64ec..8c5848bb87a 100644 --- a/src/plugins/cppeditor/cppcodestylepreferencesfactory.h +++ b/src/plugins/cppeditor/cppcodestylepreferencesfactory.h @@ -45,7 +45,8 @@ public: TextEditor::Indenter *createIndenter(QTextDocument *doc) const override; QString snippetProviderGroupId() const override; QString previewText() const override; - virtual std::pair additionalTab(QWidget *parent) const; + virtual std::pair additionalTab( + TextEditor::ICodeStylePreferences *codeStyle, QWidget *parent) const; }; } // namespace CppEditor diff --git a/src/plugins/texteditor/codestyleselectorwidget.cpp b/src/plugins/texteditor/codestyleselectorwidget.cpp index 11cd927a34b..ca1616cb1cc 100644 --- a/src/plugins/texteditor/codestyleselectorwidget.cpp +++ b/src/plugins/texteditor/codestyleselectorwidget.cpp @@ -104,6 +104,7 @@ CodeStyleDialog::CodeStyleDialog(ICodeStylePreferencesFactory *factory, m_codeStyle->setValue(codeStyle->value()); m_codeStyle->setId(codeStyle->id()); m_codeStyle->setDisplayName(m_originalDisplayName); + m_codeStyle->setReadOnly(codeStyle->isReadOnly()); TextEditor::CodeStyleEditorWidget *editor = factory->createEditor(m_codeStyle, this); m_buttons = new QDialogButtonBox(