File indexing completed on 2024-05-19 15:46:03
0001 /* 0002 SPDX-FileCopyrightText: 2019 Daniel Mensinger <daniel@mensinger-ka.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "mesonoptionbaseview.h" 0008 0009 #include "mesonlisteditor.h" 0010 #include "ui_mesonoptionbaseview.h" 0011 #include <debug.h> 0012 0013 #include <KColorScheme> 0014 0015 #include <QCheckBox> 0016 #include <QComboBox> 0017 #include <QLineEdit> 0018 #include <QPalette> 0019 #include <QPushButton> 0020 #include <QSpinBox> 0021 #include <QtGlobal> 0022 0023 using namespace std; 0024 0025 // Helper class for RAII signal blocking 0026 class SignalBlocker 0027 { 0028 public: 0029 SignalBlocker(QWidget* widget) 0030 : m_widget(widget) 0031 { 0032 if (m_widget) { 0033 m_widget->blockSignals(true); 0034 } 0035 } 0036 0037 ~SignalBlocker() 0038 { 0039 if (m_widget) { 0040 m_widget->blockSignals(false); 0041 } 0042 } 0043 0044 private: 0045 QWidget* m_widget = nullptr; 0046 }; 0047 0048 MesonOptionBaseView::MesonOptionBaseView(MesonOptionPtr option, QWidget* parent) 0049 : QWidget(parent) 0050 { 0051 Q_ASSERT(option); 0052 0053 m_ui = new Ui::MesonOptionBaseView; 0054 m_ui->setupUi(this); 0055 0056 m_ui->l_name->setText(option->name() + QStringLiteral(":")); 0057 m_ui->l_name->setToolTip(option->description()); 0058 setToolTip(option->description()); 0059 } 0060 0061 MesonOptionBaseView::~MesonOptionBaseView() 0062 { 0063 if (m_ui) { 0064 delete m_ui; 0065 } 0066 } 0067 0068 // Base class functions 0069 0070 int MesonOptionBaseView::nameWidth() 0071 { 0072 // Make the name a bit (by 25) wider than it actually is to create a margin. Maybe do 0073 // something smarter in the future (TODO) 0074 return m_ui->l_name->fontMetrics().boundingRect(m_ui->l_name->text()).width() + 25; 0075 } 0076 0077 void MesonOptionBaseView::setMinNameWidth(int width) 0078 { 0079 m_ui->l_name->setMinimumWidth(width); 0080 } 0081 0082 void MesonOptionBaseView::setInputWidget(QWidget* input) 0083 { 0084 QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 0085 sizePolicy.setHorizontalStretch(0); 0086 sizePolicy.setVerticalStretch(0); 0087 sizePolicy.setHeightForWidth(input->sizePolicy().hasHeightForWidth()); 0088 input->setSizePolicy(sizePolicy); 0089 input->setToolTip(option()->description()); 0090 m_ui->layout->insertWidget(1, input); 0091 updateInput(); 0092 setChanged(false); 0093 } 0094 0095 void MesonOptionBaseView::reset() 0096 { 0097 option()->reset(); 0098 updateInput(); 0099 setChanged(false); 0100 } 0101 0102 void MesonOptionBaseView::setChanged(bool changed) 0103 { 0104 KColorScheme scheme(QPalette::Normal); 0105 KColorScheme::ForegroundRole role; 0106 0107 if (changed) { 0108 m_ui->l_name->setStyleSheet(QStringLiteral("font-weight: bold")); 0109 m_ui->b_reset->setDisabled(false); 0110 role = KColorScheme::NeutralText; 0111 } else { 0112 m_ui->l_name->setStyleSheet(QString()); 0113 m_ui->b_reset->setDisabled(true); 0114 role = KColorScheme::NormalText; 0115 } 0116 0117 QPalette pal = m_ui->l_name->palette(); 0118 pal.setColor(QPalette::WindowText, scheme.foreground(role).color()); 0119 m_ui->l_name->setPalette(pal); 0120 emit configChanged(); 0121 } 0122 0123 std::shared_ptr<MesonOptionBaseView> MesonOptionBaseView::fromOption(MesonOptionPtr option, QWidget* parent) 0124 { 0125 std::shared_ptr<MesonOptionBaseView> opt = nullptr; 0126 switch (option->type()) { 0127 case MesonOptionBase::ARRAY: 0128 opt = make_shared<MesonOptionArrayView>(option, parent); 0129 break; 0130 case MesonOptionBase::BOOLEAN: 0131 opt = make_shared<MesonOptionBoolView>(option, parent); 0132 break; 0133 case MesonOptionBase::COMBO: 0134 opt = make_shared<MesonOptionComboView>(option, parent); 0135 break; 0136 case MesonOptionBase::INTEGER: 0137 opt = make_shared<MesonOptionIntegerView>(option, parent); 0138 break; 0139 case MesonOptionBase::STRING: 0140 opt = make_shared<MesonOptionStringView>(option, parent); 0141 break; 0142 } 0143 0144 return opt; 0145 } 0146 0147 // Derived class constructors 0148 0149 MesonOptionArrayView::MesonOptionArrayView(MesonOptionPtr option, QWidget* parent) 0150 : MesonOptionBaseView(option, parent) 0151 , m_option(dynamic_pointer_cast<MesonOptionArray>(option)) 0152 { 0153 Q_ASSERT(m_option); 0154 0155 m_input = new QPushButton(this); 0156 connect(m_input, &QPushButton::clicked, this, [this]() { 0157 MesonListEditor editor(m_option->rawValue(), this); 0158 if (editor.exec() == QDialog::Accepted) { 0159 m_option->setValue(editor.content()); 0160 m_input->setText(m_option->value()); 0161 setChanged(m_option->isUpdated()); 0162 } 0163 }); 0164 setInputWidget(m_input); 0165 } 0166 0167 MesonOptionBoolView::MesonOptionBoolView(MesonOptionPtr option, QWidget* parent) 0168 : MesonOptionBaseView(option, parent) 0169 , m_option(dynamic_pointer_cast<MesonOptionBool>(option)) 0170 { 0171 Q_ASSERT(m_option); 0172 0173 m_input = new QCheckBox(this); 0174 connect(m_input, &QCheckBox::stateChanged, this, &MesonOptionBoolView::updated); 0175 setInputWidget(m_input); 0176 } 0177 0178 MesonOptionComboView::MesonOptionComboView(MesonOptionPtr option, QWidget* parent) 0179 : MesonOptionBaseView(option, parent) 0180 , m_option(dynamic_pointer_cast<MesonOptionCombo>(option)) 0181 { 0182 Q_ASSERT(m_option); 0183 0184 m_input = new QComboBox(this); 0185 m_input->clear(); 0186 m_input->addItems(m_option->choices()); 0187 m_input->setEditable(false); 0188 connect(m_input, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MesonOptionComboView::updated); 0189 setInputWidget(m_input); 0190 } 0191 0192 MesonOptionIntegerView::MesonOptionIntegerView(MesonOptionPtr option, QWidget* parent) 0193 : MesonOptionBaseView(option, parent) 0194 , m_option(dynamic_pointer_cast<MesonOptionInteger>(option)) 0195 { 0196 Q_ASSERT(m_option); 0197 0198 m_input = new QSpinBox(this); 0199 m_input->setMinimum(INT32_MIN); 0200 m_input->setMaximum(INT32_MAX); 0201 connect(m_input, QOverload<int>::of(&QSpinBox::valueChanged), this, &MesonOptionIntegerView::updated); 0202 setInputWidget(m_input); 0203 } 0204 0205 MesonOptionStringView::MesonOptionStringView(MesonOptionPtr option, QWidget* parent) 0206 : MesonOptionBaseView(option, parent) 0207 , m_option(dynamic_pointer_cast<MesonOptionString>(option)) 0208 { 0209 Q_ASSERT(m_option); 0210 0211 m_input = new QLineEdit(this); 0212 connect(m_input, &QLineEdit::textChanged, this, &MesonOptionStringView::updated); 0213 setInputWidget(m_input); 0214 } 0215 0216 // Option getters 0217 0218 MesonOptionBase* MesonOptionArrayView::option() 0219 { 0220 return m_option.get(); 0221 } 0222 0223 MesonOptionBase* MesonOptionBoolView::option() 0224 { 0225 return m_option.get(); 0226 } 0227 0228 MesonOptionBase* MesonOptionComboView::option() 0229 { 0230 return m_option.get(); 0231 } 0232 0233 MesonOptionBase* MesonOptionIntegerView::option() 0234 { 0235 return m_option.get(); 0236 } 0237 0238 MesonOptionBase* MesonOptionStringView::option() 0239 { 0240 return m_option.get(); 0241 } 0242 0243 // Updaters for the input widget 0244 0245 void MesonOptionArrayView::updateInput() 0246 { 0247 SignalBlocker block(m_input); 0248 m_input->setText(m_option->value()); 0249 } 0250 0251 void MesonOptionBoolView::updateInput() 0252 { 0253 SignalBlocker block(m_input); 0254 m_input->setCheckState(m_option->rawValue() ? Qt::Checked : Qt::Unchecked); 0255 } 0256 0257 void MesonOptionComboView::updateInput() 0258 { 0259 SignalBlocker block(m_input); 0260 m_input->setCurrentText(m_option->rawValue()); 0261 } 0262 0263 void MesonOptionIntegerView::updateInput() 0264 { 0265 SignalBlocker block(m_input); 0266 m_input->setValue(m_option->rawValue()); 0267 } 0268 0269 void MesonOptionStringView::updateInput() 0270 { 0271 SignalBlocker block(m_input); 0272 m_input->setText(m_option->rawValue()); 0273 } 0274 0275 // Slots to update the option value 0276 0277 void MesonOptionBoolView::updated() 0278 { 0279 m_option->setValue(m_input->isChecked()); 0280 setChanged(m_option->isUpdated()); 0281 } 0282 0283 void MesonOptionComboView::updated() 0284 { 0285 m_option->setValue(m_input->currentText()); 0286 setChanged(m_option->isUpdated()); 0287 } 0288 0289 void MesonOptionIntegerView::updated() 0290 { 0291 m_option->setValue(m_input->value()); 0292 setChanged(m_option->isUpdated()); 0293 } 0294 0295 void MesonOptionStringView::updated() 0296 { 0297 m_option->setValue(m_input->text()); 0298 setChanged(m_option->isUpdated()); 0299 } 0300 0301 #include "moc_mesonoptionbaseview.cpp"