forked from qt-creator/qt-creator
ClangFormat: Fix UI issues
- 'Default' values remain so after save/load - the language is fixed to C++ - the project settings are shown correctly - fix parsing configuration file - do not trigger slots when we fill the table Change-Id: I91b477721b5084803324cd38d0cfeb9d5650dd9f Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
@@ -38,7 +38,7 @@ def full_ui_content(checks):
|
|||||||
<widget class="QWidget" name="ClangFormat::ClangFormatChecksWidget">
|
<widget class="QWidget" name="ClangFormat::ClangFormatChecksWidget">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>450</width>
|
<width>480</width>
|
||||||
<height>16777215</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@@ -199,6 +199,11 @@ def createItem(key, value, index):
|
|||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
<enum>Qt::StrongFocus</enum>
|
<enum>Qt::StrongFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
|
'''
|
||||||
|
if key == 'Language':
|
||||||
|
value_item += ''' <property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
'''
|
'''
|
||||||
if index > 0:
|
if index > 0:
|
||||||
value_item += ''' <item>
|
value_item += ''' <item>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<widget class="QWidget" name="ClangFormat::ClangFormatChecksWidget">
|
<widget class="QWidget" name="ClangFormat::ClangFormatChecksWidget">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>450</width>
|
<width>480</width>
|
||||||
<height>16777215</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@@ -2045,6 +2045,9 @@
|
|||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
<enum>Qt::StrongFocus</enum>
|
<enum>Qt::StrongFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">Default</string>
|
<string notr="true">Default</string>
|
||||||
|
|||||||
@@ -43,11 +43,11 @@
|
|||||||
#include <texteditor/snippets/snippeteditor.h>
|
#include <texteditor/snippets/snippeteditor.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
#include <utils/executeondestruction.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QScrollArea>
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -72,32 +72,8 @@ ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *proje
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
QScrollArea *scrollArea = new QScrollArea();
|
initChecksAndPreview();
|
||||||
m_checksWidget = new QWidget();
|
|
||||||
m_checks->setupUi(m_checksWidget);
|
|
||||||
scrollArea->setWidget(m_checksWidget);
|
|
||||||
scrollArea->setMaximumWidth(470);
|
|
||||||
|
|
||||||
m_ui->horizontalLayout_2->addWidget(scrollArea);
|
|
||||||
|
|
||||||
for (QObject *child : m_checksWidget->children()) {
|
|
||||||
auto comboBox = qobject_cast<QComboBox *>(child);
|
|
||||||
if (comboBox != nullptr) {
|
|
||||||
connect(comboBox,
|
|
||||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
||||||
this,
|
|
||||||
&ClangFormatConfigWidget::onTableChanged);
|
|
||||||
comboBox->installEventFilter(this);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto button = qobject_cast<QPushButton *>(child);
|
|
||||||
if (button != nullptr)
|
|
||||||
connect(button, &QPushButton::clicked, this, &ClangFormatConfigWidget::onTableChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_preview = new TextEditor::SnippetEditorWidget(this);
|
|
||||||
m_ui->horizontalLayout_2->addWidget(m_preview);
|
|
||||||
if (m_project) {
|
if (m_project) {
|
||||||
m_ui->applyButton->show();
|
m_ui->applyButton->show();
|
||||||
hideGlobalCheckboxes();
|
hideGlobalCheckboxes();
|
||||||
@@ -118,15 +94,53 @@ ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *proje
|
|||||||
initialize();
|
initialize();
|
||||||
});
|
});
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
|
connectChecks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangFormatConfigWidget::initChecksAndPreview()
|
||||||
|
{
|
||||||
|
m_checksScrollArea = new QScrollArea();
|
||||||
|
m_checksWidget = new QWidget;
|
||||||
|
m_checks->setupUi(m_checksWidget);
|
||||||
|
m_checksScrollArea->setWidget(m_checksWidget);
|
||||||
|
m_checksScrollArea->setMaximumWidth(500);
|
||||||
|
|
||||||
|
m_ui->horizontalLayout_2->addWidget(m_checksScrollArea);
|
||||||
|
|
||||||
|
m_preview = new TextEditor::SnippetEditorWidget(this);
|
||||||
|
m_ui->horizontalLayout_2->addWidget(m_preview);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangFormatConfigWidget::connectChecks()
|
||||||
|
{
|
||||||
|
for (QObject *child : m_checksWidget->children()) {
|
||||||
|
auto comboBox = qobject_cast<QComboBox *>(child);
|
||||||
|
if (comboBox != nullptr) {
|
||||||
|
connect(comboBox,
|
||||||
|
qOverload<int>(&QComboBox::currentIndexChanged),
|
||||||
|
this,
|
||||||
|
&ClangFormatConfigWidget::onTableChanged);
|
||||||
|
comboBox->installEventFilter(this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto button = qobject_cast<QPushButton *>(child);
|
||||||
|
if (button != nullptr)
|
||||||
|
connect(button, &QPushButton::clicked, this, &ClangFormatConfigWidget::onTableChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangFormatConfigWidget::onTableChanged()
|
void ClangFormatConfigWidget::onTableChanged()
|
||||||
{
|
{
|
||||||
|
if (m_disableTableUpdate)
|
||||||
|
return;
|
||||||
|
|
||||||
const std::string newConfig = tableToString(sender());
|
const std::string newConfig = tableToString(sender());
|
||||||
if (newConfig.empty())
|
if (newConfig.empty())
|
||||||
return;
|
return;
|
||||||
clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
|
const std::string oldConfig = m_project ? currentProjectConfigText()
|
||||||
const std::string oldConfig = clang::format::configurationAsText(style);
|
: currentGlobalConfigText();
|
||||||
saveConfig(newConfig);
|
saveConfig(newConfig);
|
||||||
fillTable();
|
fillTable();
|
||||||
updatePreview();
|
updatePreview();
|
||||||
@@ -180,13 +194,13 @@ void ClangFormatConfigWidget::initialize()
|
|||||||
|
|
||||||
if (!m_ui->overrideDefault->isChecked() && m_project) {
|
if (!m_ui->overrideDefault->isChecked() && m_project) {
|
||||||
// Show the fallback configuration only globally.
|
// Show the fallback configuration only globally.
|
||||||
m_checksWidget->hide();
|
m_checksScrollArea->hide();
|
||||||
m_preview->hide();
|
m_preview->hide();
|
||||||
m_ui->verticalLayout->addStretch(1);
|
m_ui->verticalLayout->addStretch(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_checksWidget->show();
|
m_checksScrollArea->show();
|
||||||
m_preview->show();
|
m_preview->show();
|
||||||
|
|
||||||
Utils::FileName fileName;
|
Utils::FileName fileName;
|
||||||
@@ -238,12 +252,61 @@ static inline void trim(std::string &s)
|
|||||||
rtrim(s);
|
rtrim(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fillPlainText(QPlainTextEdit *plainText, const std::string &text, size_t index)
|
||||||
|
{
|
||||||
|
if (index == std::string::npos) {
|
||||||
|
plainText->setPlainText("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t valueStart = text.find('\n', index + 1);
|
||||||
|
size_t valueEnd;
|
||||||
|
std::string value;
|
||||||
|
QTC_ASSERT(valueStart != std::string::npos, return;);
|
||||||
|
do {
|
||||||
|
valueEnd = text.find('\n', valueStart + 1);
|
||||||
|
if (valueEnd == std::string::npos)
|
||||||
|
break;
|
||||||
|
// Skip also 2 spaces - start with valueStart + 1 + 2.
|
||||||
|
std::string line = text.substr(valueStart + 3, valueEnd - valueStart - 3);
|
||||||
|
rtrim(line);
|
||||||
|
value += value.empty() ? line : '\n' + line;
|
||||||
|
valueStart = valueEnd;
|
||||||
|
} while (valueEnd < text.size() - 1 && text.at(valueEnd + 1) == ' ');
|
||||||
|
plainText->setPlainText(QString::fromStdString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fillComboBoxOrLineEdit(QObject *object, const std::string &text, size_t index)
|
||||||
|
{
|
||||||
|
auto *comboBox = qobject_cast<QComboBox *>(object);
|
||||||
|
auto *lineEdit = qobject_cast<QLineEdit *>(object);
|
||||||
|
if (index == std::string::npos) {
|
||||||
|
if (comboBox)
|
||||||
|
comboBox->setCurrentIndex(0);
|
||||||
|
else
|
||||||
|
lineEdit->setText("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t valueStart = text.find(':', index + 1);
|
||||||
|
QTC_ASSERT(valueStart != std::string::npos, return;);
|
||||||
|
const size_t valueEnd = text.find('\n', valueStart + 1);
|
||||||
|
QTC_ASSERT(valueEnd != std::string::npos, return;);
|
||||||
|
std::string value = text.substr(valueStart + 1, valueEnd - valueStart - 1);
|
||||||
|
trim(value);
|
||||||
|
|
||||||
|
if (comboBox)
|
||||||
|
comboBox->setCurrentText(QString::fromStdString(value));
|
||||||
|
else
|
||||||
|
lineEdit->setText(QString::fromStdString(value));
|
||||||
|
}
|
||||||
|
|
||||||
void ClangFormatConfigWidget::fillTable()
|
void ClangFormatConfigWidget::fillTable()
|
||||||
{
|
{
|
||||||
clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
|
Utils::ExecuteOnDestruction executeOnDestruction([this]() { m_disableTableUpdate = false; });
|
||||||
|
m_disableTableUpdate = true;
|
||||||
|
|
||||||
using namespace std;
|
const std::string configText = m_project ? currentProjectConfigText()
|
||||||
const string configText = clang::format::configurationAsText(style);
|
: currentGlobalConfigText();
|
||||||
|
|
||||||
for (QObject *child : m_checksWidget->children()) {
|
for (QObject *child : m_checksWidget->children()) {
|
||||||
if (!qobject_cast<QComboBox *>(child) && !qobject_cast<QLineEdit *>(child)
|
if (!qobject_cast<QComboBox *>(child) && !qobject_cast<QLineEdit *>(child)
|
||||||
@@ -251,52 +314,14 @@ void ClangFormatConfigWidget::fillTable()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t index = configText.find(child->objectName().toStdString());
|
size_t index = configText.find('\n' + child->objectName().toStdString());
|
||||||
|
if (index == std::string::npos)
|
||||||
|
index = configText.find("\n " + child->objectName().toStdString());
|
||||||
|
|
||||||
auto *plainText = qobject_cast<QPlainTextEdit *>(child);
|
if (qobject_cast<QPlainTextEdit *>(child))
|
||||||
if (plainText) {
|
fillPlainText(qobject_cast<QPlainTextEdit *>(child), configText, index);
|
||||||
if (index == string::npos) {
|
else
|
||||||
plainText->setPlainText("");
|
fillComboBoxOrLineEdit(child, configText, index);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
size_t valueStart = configText.find('\n', index);
|
|
||||||
size_t valueEnd;
|
|
||||||
string value;
|
|
||||||
QTC_ASSERT(valueStart != string::npos, continue;);
|
|
||||||
do {
|
|
||||||
valueEnd = configText.find('\n', valueStart + 1);
|
|
||||||
if (valueEnd == string::npos)
|
|
||||||
break;
|
|
||||||
// Skip also 2 spaces - start with valueStart + 1 + 2.
|
|
||||||
string line = configText.substr(valueStart + 3, valueEnd - valueStart - 3);
|
|
||||||
rtrim(line);
|
|
||||||
value += value.empty() ? line : '\n' + line;
|
|
||||||
valueStart = valueEnd;
|
|
||||||
} while (valueEnd < configText.size() - 1 && configText.at(valueEnd + 1) == ' ');
|
|
||||||
plainText->setPlainText(QString::fromStdString(value));
|
|
||||||
} else {
|
|
||||||
auto *comboBox = qobject_cast<QComboBox *>(child);
|
|
||||||
auto *lineEdit = qobject_cast<QLineEdit *>(child);
|
|
||||||
if (index == string::npos) {
|
|
||||||
if (comboBox)
|
|
||||||
comboBox->setCurrentIndex(0);
|
|
||||||
else
|
|
||||||
lineEdit->setText("");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t valueStart = configText.find(':', index);
|
|
||||||
QTC_ASSERT(valueStart != string::npos, continue;);
|
|
||||||
const size_t valueEnd = configText.find('\n', valueStart + 1);
|
|
||||||
QTC_ASSERT(valueEnd != string::npos, continue;);
|
|
||||||
string value = configText.substr(valueStart + 1, valueEnd - valueStart - 1);
|
|
||||||
trim(value);
|
|
||||||
|
|
||||||
if (comboBox)
|
|
||||||
comboBox->setCurrentText(QString::fromStdString(value));
|
|
||||||
else
|
|
||||||
lineEdit->setText(QString::fromStdString(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <texteditor/icodestylepreferencesfactory.h>
|
#include <texteditor/icodestylepreferencesfactory.h>
|
||||||
|
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -59,6 +61,9 @@ private:
|
|||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void initChecksAndPreview();
|
||||||
|
void connectChecks();
|
||||||
|
|
||||||
void fillTable();
|
void fillTable();
|
||||||
std::string tableToString(QObject *sender);
|
std::string tableToString(QObject *sender);
|
||||||
|
|
||||||
@@ -70,9 +75,11 @@ private:
|
|||||||
|
|
||||||
ProjectExplorer::Project *m_project;
|
ProjectExplorer::Project *m_project;
|
||||||
QWidget *m_checksWidget;
|
QWidget *m_checksWidget;
|
||||||
|
QScrollArea *m_checksScrollArea;
|
||||||
TextEditor::SnippetEditorWidget *m_preview;
|
TextEditor::SnippetEditorWidget *m_preview;
|
||||||
std::unique_ptr<Ui::ClangFormatChecksWidget> m_checks;
|
std::unique_ptr<Ui::ClangFormatChecksWidget> m_checks;
|
||||||
std::unique_ptr<Ui::ClangFormatConfigWidget> m_ui;
|
std::unique_ptr<Ui::ClangFormatConfigWidget> m_ui;
|
||||||
|
bool m_disableTableUpdate = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangFormat
|
} // namespace ClangFormat
|
||||||
|
|||||||
@@ -318,6 +318,32 @@ clang::format::FormatStyle styleForFile(Utils::FileName fileName)
|
|||||||
return styleForFile(fileName, true);
|
return styleForFile(fileName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string readFile(const QString &path)
|
||||||
|
{
|
||||||
|
QFile file(path);
|
||||||
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
|
clang::format::FormatStyle defaultStyle = qtcStyle();
|
||||||
|
return clang::format::configurationAsText(defaultStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray content = file.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return content.toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string currentProjectConfigText()
|
||||||
|
{
|
||||||
|
const QString configPath = projectPath().appendPath(Constants::SETTINGS_FILE_NAME).toString();
|
||||||
|
return readFile(configPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string currentGlobalConfigText()
|
||||||
|
{
|
||||||
|
const QString configPath = globalPath().appendPath(Constants::SETTINGS_FILE_NAME).toString();
|
||||||
|
return readFile(configPath);
|
||||||
|
}
|
||||||
|
|
||||||
clang::format::FormatStyle currentProjectStyle()
|
clang::format::FormatStyle currentProjectStyle()
|
||||||
{
|
{
|
||||||
return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
|
return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ void createStyleFileIfNeeded(bool isGlobal);
|
|||||||
|
|
||||||
QString currentProjectUniqueId();
|
QString currentProjectUniqueId();
|
||||||
|
|
||||||
|
std::string currentProjectConfigText();
|
||||||
|
std::string currentGlobalConfigText();
|
||||||
|
|
||||||
clang::format::FormatStyle currentProjectStyle();
|
clang::format::FormatStyle currentProjectStyle();
|
||||||
clang::format::FormatStyle currentGlobalStyle();
|
clang::format::FormatStyle currentGlobalStyle();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user