File indexing completed on 2024-04-28 05:48:32
0001 /* 0002 SPDX-FileCopyrightText: 2019 Mark Nauwelaerts <mark.nauwelaerts@gmail.com> 0003 SPDX-FileCopyrightText: 2023 Akseli Lahtinen <akselmo@akselmo.dev> 0004 0005 SPDX-License-Identifier: MIT 0006 */ 0007 0008 #include "debugconfigpage.h" 0009 #include "plugin_kategdb.h" 0010 #include "ui_debugconfig.h" 0011 0012 #include <KLocalizedString> 0013 0014 #include <KSyntaxHighlighting/Definition> 0015 #include <KSyntaxHighlighting/Repository> 0016 #include <KSyntaxHighlighting/SyntaxHighlighter> 0017 #include <KSyntaxHighlighting/Theme> 0018 0019 #include <KTextEditor/Editor> 0020 0021 #include <QJsonDocument> 0022 #include <QJsonParseError> 0023 #include <QMenu> 0024 #include <QPalette> 0025 0026 DebugConfigPage::DebugConfigPage(QWidget *parent, KatePluginGDB *plugin) 0027 : KTextEditor::ConfigPage(parent) 0028 , m_plugin(plugin) 0029 { 0030 ui = new Ui::DebugConfigWidget(); 0031 ui->setupUi(this); 0032 0033 // Fix-up our two text edits to be proper JSON file editors 0034 updateHighlighters(); 0035 0036 // Ensure we update the highlighters if the repository is updated or theme is changed 0037 connect(KTextEditor::Editor::instance(), &KTextEditor::Editor::repositoryReloaded, this, &DebugConfigPage::updateHighlighters); 0038 connect(KTextEditor::Editor::instance(), &KTextEditor::Editor::configChanged, this, &DebugConfigPage::updateHighlighters); 0039 0040 // Setup default JSON settings 0041 QFile defaultConfigFile(QStringLiteral(":/debugger/dap.json")); 0042 defaultConfigFile.open(QIODevice::ReadOnly); 0043 Q_ASSERT(defaultConfigFile.isOpen()); 0044 ui->defaultConfig->setPlainText(QString::fromUtf8(defaultConfigFile.readAll())); 0045 0046 // Setup default config path as placeholder to show user where it is 0047 ui->edtConfigPath->setPlaceholderText(m_plugin->m_defaultConfigPath.toLocalFile()); 0048 0049 reset(); 0050 0051 connect(ui->edtConfigPath, &KUrlRequester::textChanged, this, &DebugConfigPage::configUrlChanged); 0052 connect(ui->edtConfigPath, &KUrlRequester::urlSelected, this, &DebugConfigPage::configUrlChanged); 0053 0054 auto cfgh = [this](int position, int added, int removed) { 0055 Q_UNUSED(position); 0056 // Discard format change 0057 // (e.g. due to syntax highlighting) 0058 if (added || removed) { 0059 configTextChanged(); 0060 } 0061 }; 0062 connect(ui->userConfig->document(), &QTextDocument::contentsChange, this, cfgh); 0063 } 0064 0065 DebugConfigPage::~DebugConfigPage() 0066 { 0067 delete ui; 0068 } 0069 0070 QString DebugConfigPage::name() const 0071 { 0072 return QString(i18n("Debugger")); 0073 } 0074 0075 QString DebugConfigPage::fullName() const 0076 { 0077 return QString(i18n("Debugger")); 0078 } 0079 0080 QIcon DebugConfigPage::icon() const 0081 { 0082 return QIcon::fromTheme(QLatin1String("debug-run")); 0083 } 0084 0085 void DebugConfigPage::apply() 0086 { 0087 m_plugin->m_configPath = ui->edtConfigPath->url(); 0088 // Own scope to ensure file is flushed before we signal below in writeConfig! 0089 { 0090 QFile configFile(m_plugin->configPath().toLocalFile()); 0091 configFile.open(QIODevice::WriteOnly); 0092 if (configFile.isOpen()) { 0093 configFile.write(ui->userConfig->toPlainText().toUtf8()); 0094 } 0095 } 0096 0097 m_plugin->writeConfig(); 0098 } 0099 0100 void DebugConfigPage::reset() 0101 { 0102 ui->edtConfigPath->setUrl(m_plugin->m_configPath); 0103 readUserConfig(m_plugin->configPath().toLocalFile()); 0104 } 0105 0106 void DebugConfigPage::defaults() 0107 { 0108 reset(); 0109 } 0110 0111 void DebugConfigPage::readUserConfig(const QString &fileName) 0112 { 0113 QFile configFile(fileName); 0114 configFile.open(QIODevice::ReadOnly); 0115 if (configFile.isOpen()) { 0116 ui->userConfig->setPlainText(QString::fromUtf8(configFile.readAll())); 0117 } else { 0118 ui->userConfig->clear(); 0119 } 0120 0121 updateConfigTextErrorState(); 0122 } 0123 0124 void DebugConfigPage::updateConfigTextErrorState() 0125 { 0126 const auto data = ui->userConfig->toPlainText().toUtf8(); 0127 if (data.isEmpty()) { 0128 ui->userConfigError->setText(i18n("No JSON data to validate.")); 0129 return; 0130 } 0131 0132 QJsonParseError error{}; 0133 auto json = QJsonDocument::fromJson(data, &error); 0134 if (error.error == QJsonParseError::NoError) { 0135 if (json.isObject()) { 0136 ui->userConfigError->setText(i18n("JSON data is valid.")); 0137 } else { 0138 ui->userConfigError->setText(i18n("JSON data is invalid: no JSON object")); 0139 } 0140 } else { 0141 ui->userConfigError->setText(i18n("JSON data is invalid: %1", error.errorString())); 0142 } 0143 } 0144 0145 void DebugConfigPage::configTextChanged() 0146 { 0147 updateConfigTextErrorState(); 0148 changed(); 0149 } 0150 0151 void DebugConfigPage::configUrlChanged() 0152 { 0153 readUserConfig(ui->edtConfigPath->url().isEmpty() ? m_plugin->m_defaultConfigPath.toLocalFile() : ui->edtConfigPath->url().toLocalFile()); 0154 changed(); 0155 } 0156 0157 void DebugConfigPage::updateHighlighters() 0158 { 0159 for (auto textEdit : {ui->userConfig, ui->defaultConfig}) { 0160 auto highlighter = new KSyntaxHighlighting::SyntaxHighlighter(textEdit->document()); 0161 highlighter->setDefinition(KTextEditor::Editor::instance()->repository().definitionForFileName(QStringLiteral("dap.json"))); 0162 0163 // Use monospace font 0164 textEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 0165 0166 // Use right color scheme 0167 const auto theme = KTextEditor::Editor::instance()->theme(); 0168 auto pal = qApp->palette(); 0169 pal.setColor(QPalette::Base, QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::BackgroundColor))); 0170 pal.setColor(QPalette::Highlight, QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TextSelection))); 0171 textEdit->setPalette(pal); 0172 highlighter->setTheme(theme); 0173 highlighter->rehighlight(); 0174 } 0175 } 0176 0177 #include "moc_debugconfigpage.cpp"