Warning, file /kdevelop/kdevelop/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "compilerswidget.h" 0008 0009 #include <QAction> 0010 #include <KLocalizedString> 0011 #include <QKeySequence> 0012 #include <QMenu> 0013 #include <QSignalBlocker> 0014 0015 #include "ui_compilerswidget.h" 0016 #include "compilersmodel.h" 0017 #include "../compilerprovider/settingsmanager.h" 0018 #include "../compilerprovider/compilerprovider.h" 0019 #include <debug.h> 0020 0021 using namespace KDevelop; 0022 0023 CompilersWidget::CompilersWidget(QWidget* parent) 0024 : ConfigPage(nullptr, nullptr, parent) 0025 , m_ui(new Ui::CompilersWidget) 0026 , m_compilersModel(new CompilersModel(this)) 0027 { 0028 m_ui->setupUi(this); 0029 m_ui->compilers->setModel(m_compilersModel); 0030 m_ui->compilers->header()->setSectionResizeMode(QHeaderView::Stretch); 0031 0032 m_addMenu = new QMenu(m_ui->addButton); 0033 0034 m_addMenu->clear(); 0035 0036 auto settings = SettingsManager::globalInstance(); 0037 auto provider = settings->provider(); 0038 const auto compilerFactories = provider->compilerFactories(); 0039 for (const auto& factory : compilerFactories) { 0040 auto* action = new QAction(m_addMenu); 0041 const QString fname = factory->name(); 0042 action->setText(fname); 0043 connect(action, &QAction::triggered, this, [this, fname]() { addCompiler(fname); }); 0044 m_addMenu->addAction(action); 0045 } 0046 m_ui->addButton->setMenu(m_addMenu); 0047 0048 connect(m_ui->removeButton, &QPushButton::clicked, this, &CompilersWidget::deleteCompiler); 0049 0050 auto delAction = new QAction(i18nc("@action", "Delete Compiler"), this); 0051 delAction->setShortcut( QKeySequence( QStringLiteral("Del") ) ); 0052 delAction->setShortcutContext( Qt::WidgetWithChildrenShortcut ); 0053 m_ui->compilers->addAction( delAction ); 0054 connect( delAction, &QAction::triggered, this, &CompilersWidget::deleteCompiler ); 0055 0056 connect(m_ui->compilers->selectionModel(), &QItemSelectionModel::currentChanged, this, &CompilersWidget::compilerSelected); 0057 0058 connect(m_ui->compilerName, &QLineEdit::textEdited, this, &CompilersWidget::compilerEdited); 0059 0060 connect(m_ui->compilerPath, &KUrlRequester::textEdited, this, &CompilersWidget::compilerEdited); 0061 0062 connect(m_compilersModel, &CompilersModel::compilerChanged, this, &CompilersWidget::compilerChanged); 0063 0064 enableItems(false); 0065 } 0066 0067 CompilersWidget::~CompilersWidget() 0068 { 0069 } 0070 0071 void CompilersWidget::setCompilers(const QVector< CompilerPointer >& compilers) 0072 { 0073 m_compilersModel->setCompilers(compilers); 0074 m_ui->compilers->expandAll(); 0075 } 0076 0077 void CompilersWidget::clear() 0078 { 0079 m_compilersModel->setCompilers({}); 0080 } 0081 0082 void CompilersWidget::deleteCompiler() 0083 { 0084 qCDebug(DEFINESANDINCLUDES) << "Deleting compiler"; 0085 auto selectionModel = m_ui->compilers->selectionModel(); 0086 const auto selectedRowsBefore = selectionModel->selectedIndexes(); 0087 for (const QModelIndex& row : selectedRowsBefore) { 0088 if (row.column() == 1) { 0089 //Don't remove the same compiler twice 0090 continue; 0091 } 0092 0093 if(m_compilersModel->removeRows(row.row(), 1, row.parent())) { 0094 auto selectedCompiler = selectionModel->selectedIndexes(); 0095 compilerSelected(selectedCompiler.isEmpty() ? QModelIndex() : selectedCompiler.first()); 0096 } 0097 } 0098 0099 emit changed(); 0100 } 0101 0102 void CompilersWidget::addCompiler(const QString& factoryName) 0103 { 0104 auto settings = SettingsManager::globalInstance(); 0105 auto provider = settings->provider(); 0106 const auto compilerFactories = provider->compilerFactories(); 0107 for (const auto& factory : compilerFactories) { 0108 if (factoryName == factory->name()) { 0109 //add compiler without any information, the user will fill the data in later 0110 auto compilerIndex = m_compilersModel->addCompiler(factory->createCompiler(QString(), QString())); 0111 0112 m_ui->compilers->selectionModel()->select(compilerIndex, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 0113 compilerSelected(compilerIndex); 0114 m_ui->compilers->scrollTo(compilerIndex); 0115 m_ui->compilerName->setFocus(Qt::OtherFocusReason); 0116 break; 0117 } 0118 } 0119 0120 emit changed(); 0121 } 0122 0123 QVector< CompilerPointer > CompilersWidget::compilers() const 0124 { 0125 return m_compilersModel->compilers(); 0126 } 0127 0128 void CompilersWidget::compilerSelected(const QModelIndex& index) 0129 { 0130 auto compiler = index.data(CompilersModel::CompilerDataRole); 0131 if (compiler.value<CompilerPointer>()) { 0132 m_ui->compilerName->setText(compiler.value<CompilerPointer>()->name()); 0133 0134 //NOTE: there is a bug in kLineEdit, which causes textEdited signal to be 0135 // spuriously emitted on calling setText(). See bug report here: 0136 // https://bugs.kde.org/show_bug.cgi?id=388798 0137 // The resulting spurious call of compilerEdited then fails with an assert. 0138 //Work around this bug until it is fixed upstream by disabling signals here 0139 const QSignalBlocker blocker(m_ui->compilerPath); 0140 m_ui->compilerPath->setText(compiler.value<CompilerPointer>()->path()); 0141 0142 enableItems(true); 0143 } else { 0144 enableItems(false); 0145 } 0146 } 0147 0148 void CompilersWidget::compilerEdited() 0149 { 0150 auto indexes = m_ui->compilers->selectionModel()->selectedIndexes(); 0151 Q_ASSERT(!indexes.isEmpty()); 0152 0153 auto compiler = indexes.first().data(CompilersModel::CompilerDataRole); 0154 if (!compiler.value<CompilerPointer>()) { 0155 return; 0156 } 0157 0158 compiler.value<CompilerPointer>()->setName(m_ui->compilerName->text()); 0159 compiler.value<CompilerPointer>()->setPath(m_ui->compilerPath->text()); 0160 0161 m_compilersModel->updateCompiler(m_ui->compilers->selectionModel()->selection()); 0162 0163 emit changed(); 0164 } 0165 0166 void CompilersWidget::enableItems(bool enable) 0167 { 0168 m_ui->compilerName->setEnabled(enable); 0169 m_ui->compilerPath->setEnabled(enable); 0170 0171 if(!enable) { 0172 m_ui->compilerName->clear(); 0173 0174 //NOTE: this is to work around the 0175 //spurious signal bug in kLineEdit 0176 const QSignalBlocker blocker(m_ui->compilerPath); 0177 m_ui->compilerPath->clear(); 0178 } 0179 } 0180 0181 void CompilersWidget::reset() 0182 { 0183 auto settings = SettingsManager::globalInstance(); 0184 setCompilers(settings->provider()->compilers()); 0185 } 0186 0187 void CompilersWidget::apply() 0188 { 0189 auto settings = SettingsManager::globalInstance(); 0190 auto provider = settings->provider(); 0191 0192 settings->writeUserDefinedCompilers(compilers()); 0193 0194 const auto& providerCompilers = provider->compilers(); 0195 const auto& widgetCompilers = compilers(); 0196 for (auto& compiler: providerCompilers) { 0197 if (!widgetCompilers.contains(compiler)) { 0198 provider->unregisterCompiler(compiler); 0199 } 0200 } 0201 0202 for (auto& compiler: widgetCompilers) { 0203 if (!providerCompilers.contains(compiler)) { 0204 provider->registerCompiler(compiler); 0205 } 0206 } 0207 } 0208 0209 void CompilersWidget::defaults() 0210 { 0211 } 0212 0213 QString CompilersWidget::name() const 0214 { 0215 return i18nc("@title:tab", "C/C++ Compilers"); 0216 } 0217 0218 QString CompilersWidget::fullName() const 0219 { 0220 return i18nc("@title:tab", "Configure C/C++ Compilers"); 0221 } 0222 0223 QIcon CompilersWidget::icon() const 0224 { 0225 return QIcon::fromTheme(QStringLiteral("kdevelop")); 0226 } 0227 0228 KDevelop::ConfigPage::ConfigPageType CompilersWidget::configPageType() const 0229 { 0230 return ConfigPage::LanguageConfigPage; 0231 } 0232 0233 #include "moc_compilerswidget.cpp"