void ClangDiagnosticConfigsWidget::syncConfigChooserToModel(const Core::Id &configToSelect)
{
    disconnectConfigChooserCurrentIndex();

    const int previousCurrentIndex = m_ui->configChooserComboBox->currentIndex();
    m_ui->configChooserComboBox->clear();
    int configToSelectIndex = -1;

    const int size = m_diagnosticConfigsModel.size();
    for (int i = 0; i < size; ++i) {
        const ClangDiagnosticConfig &config = m_diagnosticConfigsModel.at(i);
        const QString displayName
                = displayNameWithBuiltinIndication(config, m_configWithUndecoratedDisplayName);
        m_ui->configChooserComboBox->addItem(displayName, config.id().toSetting());

        if (configToSelect == config.id())
            configToSelectIndex = i;
    }

    connectConfigChooserCurrentIndex();

    if (configToSelectIndex != -1) {
        m_ui->configChooserComboBox->setCurrentIndex(configToSelectIndex);
    } else if (previousCurrentIndex != m_ui->configChooserComboBox->currentIndex()) {
        syncOtherWidgetsToComboBox();
        emit currentConfigChanged(currentConfigId());
    }
}
void ClangDiagnosticConfigsWidget::onRemoveButtonClicked()
{
    m_diagnosticConfigsModel.removeConfigWithId(currentConfigId());
    emit customConfigsChanged(customConfigs());

    syncConfigChooserToModel();
}
void ClangDiagnosticConfigsSelectionWidget::refresh(Core::Id id)
{
    disconnectFromCurrentIndexChanged();

    int configToSelectIndex = -1;
    m_selectionComboBox->clear();
    m_diagnosticConfigsModel = ClangDiagnosticConfigsModel(
                codeModelSettings()->clangCustomDiagnosticConfigs());
    const int size = m_diagnosticConfigsModel.size();
    for (int i = 0; i < size; ++i) {
        const ClangDiagnosticConfig &config = m_diagnosticConfigsModel.at(i);
        const QString displayName
                = ClangDiagnosticConfigsModel::displayNameWithBuiltinIndication(config);
        m_selectionComboBox->addItem(displayName, config.id().toSetting());

        if (id == config.id())
            configToSelectIndex = i;
    }

    if (configToSelectIndex != -1)
        m_selectionComboBox->setCurrentIndex(configToSelectIndex);
    else
        emit currentConfigChanged(currentConfigId());

    connectToCurrentIndexChanged();
}
void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialog(QPushButton *button)
{
    connect(button, &QPushButton::clicked, [this]() {
        ClangDiagnosticConfigsWidget *widget = new ClangDiagnosticConfigsWidget(currentConfigId());
        widget->layout()->setMargin(0);
        QDialog dialog;
        dialog.setWindowTitle(ClangDiagnosticConfigsWidget::tr("Diagnostic Configurations"));
        dialog.setLayout(new QVBoxLayout);
        dialog.layout()->addWidget(widget);
        auto *buttonsBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
        dialog.layout()->addWidget(buttonsBox);
        connect(buttonsBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
        connect(buttonsBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

        const bool previousEnableLowerClazyLevels = codeModelSettings()->enableLowerClazyLevels();
        connect(&dialog, &QDialog::accepted, [widget, previousEnableLowerClazyLevels]() {
            QSharedPointer<CppCodeModelSettings> settings = codeModelSettings();
            const ClangDiagnosticConfigs oldDiagnosticConfigs
                    = settings->clangCustomDiagnosticConfigs();
            const ClangDiagnosticConfigs currentDiagnosticConfigs = widget->customConfigs();
            if (oldDiagnosticConfigs != currentDiagnosticConfigs
                 || previousEnableLowerClazyLevels != codeModelSettings()->enableLowerClazyLevels()) {
                const ClangDiagnosticConfigsModel configsModel(currentDiagnosticConfigs);
                if (!configsModel.hasConfigWithId(settings->clangDiagnosticConfigId()))
                    settings->resetClangDiagnosticConfigId();
                settings->setClangCustomDiagnosticConfigs(currentDiagnosticConfigs);
                settings->toSettings(Core::ICore::settings());
            }
        });
        dialog.exec();
    });
}
void ClangDiagnosticConfigsSelectionWidget::connectToCurrentIndexChanged()
{
    m_currentIndexChangedConnection
            = connect(m_selectionComboBox,
                      static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
                      this,
                      [this]() { emit currentConfigChanged(currentConfigId()); });
}
void ClangDiagnosticConfigsWidget::onDiagnosticOptionsEdited()
{
    // Clean up input
    const QString diagnosticOptions = m_clangBaseChecks->diagnosticOptionsTextEdit->document()
                                          ->toPlainText();
    const QStringList normalizedOptions = normalizeDiagnosticInputOptions(diagnosticOptions);

    // Validate
    const QString errorMessage = validateDiagnosticOptions(normalizedOptions);
    updateValidityWidgets(errorMessage);
    if (!errorMessage.isEmpty()) {
        // Remember the entered options in case the user will switch back.
        m_notAcceptedOptions.insert(currentConfigId(), diagnosticOptions);
        return;
    }
    m_notAcceptedOptions.remove(currentConfigId());

    // Commit valid changes
    ClangDiagnosticConfig updatedConfig = currentConfig();
    updatedConfig.setClangOptions(normalizedOptions);
    updateConfig(updatedConfig);
}
void ClangDiagnosticConfigsWidget::onCurrentConfigChanged(int)
{
    syncOtherWidgetsToComboBox();

    emit currentConfigChanged(currentConfigId());
}
const ClangDiagnosticConfig &ClangDiagnosticConfigsWidget::currentConfig() const
{
    return m_diagnosticConfigsModel.configWithId(currentConfigId());
}