File indexing completed on 2024-12-01 04:36:35

0001 /*
0002    SPDX-FileCopyrightText: 2022-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "settingswidgetbase.h"
0008 #include "connection.h"
0009 #include "dialogs/confirmpassworddialog.h"
0010 #include "rocketchataccount.h"
0011 #include "ruqolawidgets_debug.h"
0012 
0013 #include <KLocalizedString>
0014 
0015 #include <KPasswordLineEdit>
0016 #include <QCheckBox>
0017 #include <QComboBox>
0018 #include <QFormLayout>
0019 #include <QHBoxLayout>
0020 #include <QLabel>
0021 #include <QLineEdit>
0022 #include <QPlainTextEdit>
0023 #include <QPushButton>
0024 #include <QSpinBox>
0025 #include <QToolButton>
0026 
0027 namespace
0028 {
0029 const char s_property[] = "settings_name";
0030 const char s_property_default_value[] = "default_value";
0031 }
0032 
0033 SettingsWidgetBase::SettingsWidgetBase(RocketChatAccount *account, QWidget *parent)
0034     : QScrollArea{parent}
0035     , mCurrentWidget(new QWidget(parent))
0036     , mAccount(account)
0037 {
0038     mCurrentWidget->setObjectName(QStringLiteral("mCurrentWidget"));
0039     setWidgetResizable(true);
0040     setWidget(mCurrentWidget);
0041 
0042     mMainLayout = new QFormLayout(mCurrentWidget);
0043     mMainLayout->setObjectName(QStringLiteral("mainLayout"));
0044 }
0045 
0046 SettingsWidgetBase::~SettingsWidgetBase() = default;
0047 
0048 void SettingsWidgetBase::connectCheckBox(QCheckBox *checkBox, const QString &variable)
0049 {
0050     checkBox->setProperty(s_property, variable);
0051     connect(checkBox, &QCheckBox::clicked, this, [this, variable, checkBox](bool checked) {
0052         if (!updateSettings(variable, checked, RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::Boolean)) {
0053             checkBox->setChecked(!checked);
0054         }
0055     });
0056 }
0057 
0058 bool SettingsWidgetBase::updateSettings(const QString &settingName,
0059                                         const QVariant &value,
0060                                         RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::ValueType typeValue,
0061                                         const QString &buttonObjectName)
0062 {
0063     bool status = false;
0064     if (mAccount) {
0065         QString password;
0066         QPointer<ConfirmPasswordDialog> dialog(new ConfirmPasswordDialog(this));
0067         if (dialog->exec()) {
0068             password = dialog->password();
0069             auto job = new RocketChatRestApi::UpdateAdminSettingsJob(this);
0070             RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo info;
0071             info.settingsValue = value;
0072             info.settingName = settingName;
0073             info.valueType = typeValue;
0074             job->setUpdateAdminSettingsInfo(info);
0075             job->setAuthMethod(QStringLiteral("password"));
0076             job->setAuthCode(QString::fromLatin1(Utils::convertSha256Password(password)));
0077             mAccount->restApi()->initializeRestApiJob(job);
0078             connect(job, &RocketChatRestApi::UpdateAdminSettingsJob::updateAdminSettingsDone, this, [this, buttonObjectName](const QJsonObject &obj) {
0079                 slotAdminSettingsDone(obj, buttonObjectName);
0080             });
0081             if (!job->start()) {
0082                 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start UpdateAdminSettingsJob job";
0083                 status = false;
0084             } else {
0085                 status = true;
0086             }
0087         } else {
0088             status = false;
0089         }
0090         delete dialog;
0091     }
0092     return status;
0093 }
0094 
0095 void SettingsWidgetBase::slotAdminSettingsDone(const QJsonObject &obj, const QString &buttonObjectName)
0096 {
0097     qDebug() << "AccountSettingsWidget::slotAdminSettingsDone " << obj;
0098     if (obj[QLatin1String("success")].toBool()) {
0099         // Disable apply button
0100         if (!buttonObjectName.isEmpty()) {
0101             Q_EMIT changedDone(buttonObjectName);
0102         }
0103     } else {
0104         // Failed
0105     }
0106 }
0107 
0108 void SettingsWidgetBase::addSpinbox(const QString &labelStr, QSpinBox *spinBox, const QString &variable)
0109 {
0110     auto layout = new QHBoxLayout;
0111     auto label = new QLabel(labelStr, this);
0112     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0113     layout->addWidget(label);
0114     layout->addWidget(spinBox);
0115     auto toolButton = new QToolButton(this);
0116     toolButton->setObjectName(QStringLiteral("toolbutton_%1").arg(variable));
0117     toolButton->setText(i18n("Apply"));
0118     toolButton->setProperty(s_property, variable);
0119     spinBox->setProperty(s_property, variable);
0120     layout->addWidget(toolButton);
0121     toolButton->setEnabled(false);
0122     connect(toolButton, &QToolButton::clicked, this, [this, variable, spinBox, toolButton]() {
0123         if (!updateSettings(variable,
0124                             spinBox->value(),
0125                             RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::Integer,
0126                             toolButton->objectName())) {
0127             spinBox->setValue(spinBox->property(s_property_default_value).toInt());
0128         }
0129     });
0130     connect(this, &SettingsWidgetBase::changedDone, this, [toolButton, spinBox](const QString &buttonName) {
0131         if (toolButton->objectName() == buttonName) {
0132             toolButton->setEnabled(false);
0133             spinBox->setProperty(s_property_default_value, spinBox->value());
0134         }
0135     });
0136     connect(spinBox, &QSpinBox::valueChanged, this, [toolButton, spinBox](int value) {
0137         if (spinBox->property(s_property_default_value).toInt() == value) {
0138             toolButton->setEnabled(false);
0139         } else {
0140             toolButton->setEnabled(true);
0141         }
0142     });
0143 
0144     mMainLayout->addRow(layout);
0145 }
0146 
0147 void SettingsWidgetBase::addLineEdit(const QString &labelStr, QLineEdit *lineEdit, const QString &variable, bool readOnly)
0148 {
0149     auto layout = new QHBoxLayout;
0150     auto label = new QLabel(labelStr, this);
0151     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0152     layout->addWidget(label);
0153     layout->addWidget(lineEdit);
0154     auto toolButton = new QToolButton(this);
0155     toolButton->setObjectName(QStringLiteral("toolbutton_%1").arg(variable));
0156     toolButton->setText(i18n("Apply"));
0157     toolButton->setProperty(s_property, variable);
0158     lineEdit->setProperty(s_property, variable);
0159     lineEdit->setReadOnly(readOnly);
0160     layout->addWidget(toolButton);
0161     toolButton->setEnabled(false);
0162     toolButton->setVisible(!readOnly);
0163     connect(this, &SettingsWidgetBase::changedDone, this, [toolButton, lineEdit](const QString &buttonName) {
0164         if (toolButton->objectName() == buttonName) {
0165             toolButton->setEnabled(false);
0166             lineEdit->setProperty(s_property_default_value, lineEdit->text());
0167         }
0168     });
0169     if (!readOnly) {
0170         connect(toolButton, &QToolButton::clicked, this, [this, variable, lineEdit, toolButton]() {
0171             if (!updateSettings(variable,
0172                                 lineEdit->text(),
0173                                 RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::String,
0174                                 toolButton->objectName())) {
0175                 lineEdit->setText(lineEdit->property(s_property_default_value).toString());
0176             }
0177         });
0178         connect(lineEdit, &QLineEdit::textChanged, this, [toolButton, lineEdit](const QString &str) {
0179             if (lineEdit->property(s_property_default_value).toString() == str) {
0180                 toolButton->setEnabled(false);
0181             } else {
0182                 toolButton->setEnabled(true);
0183             }
0184         });
0185     }
0186 
0187     mMainLayout->addRow(layout);
0188 }
0189 
0190 void SettingsWidgetBase::addLabel(const QString &labelStr, QLabel *labelElement, const QString &variable)
0191 {
0192     auto layout = new QHBoxLayout;
0193     auto label = new QLabel(labelStr, this);
0194     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0195     layout->addWidget(label);
0196     layout->addWidget(labelElement);
0197     labelElement->setProperty(s_property, variable);
0198     mMainLayout->addRow(layout);
0199 }
0200 
0201 void SettingsWidgetBase::addPlainTextEdit(const QString &labelStr, QPlainTextEdit *plainTextEdit, const QString &variable)
0202 {
0203     auto layout = new QHBoxLayout;
0204     auto label = new QLabel(labelStr, this);
0205     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0206     layout->addWidget(label, 0, Qt::AlignTop);
0207     layout->addWidget(plainTextEdit);
0208     auto toolButton = new QToolButton(this);
0209     toolButton->setObjectName(QStringLiteral("toolbutton_%1").arg(variable));
0210     toolButton->setText(i18n("Apply"));
0211     toolButton->setProperty(s_property, variable);
0212     plainTextEdit->setProperty(s_property, variable);
0213     layout->addWidget(toolButton, 0, Qt::AlignTop);
0214     toolButton->setEnabled(false);
0215     connect(toolButton, &QToolButton::clicked, this, [this, variable, plainTextEdit, toolButton]() {
0216         if (!updateSettings(variable,
0217                             plainTextEdit->toPlainText(),
0218                             RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::String,
0219                             toolButton->objectName())) {
0220             plainTextEdit->setPlainText(plainTextEdit->property(s_property_default_value).toString());
0221         }
0222     });
0223     connect(plainTextEdit, &QPlainTextEdit::textChanged, this, [toolButton, plainTextEdit]() {
0224         if (plainTextEdit->toPlainText() != plainTextEdit->property(s_property_default_value).toString()) {
0225             toolButton->setEnabled(false);
0226         } else {
0227             toolButton->setEnabled(true);
0228         }
0229     });
0230     connect(this, &SettingsWidgetBase::changedDone, this, [toolButton, plainTextEdit](const QString &buttonName) {
0231         if (toolButton->objectName() == buttonName) {
0232             plainTextEdit->setProperty(s_property_default_value, plainTextEdit->toPlainText());
0233             toolButton->setEnabled(false);
0234         }
0235     });
0236 
0237     mMainLayout->addRow(layout);
0238 }
0239 
0240 void SettingsWidgetBase::addPasswordEdit(const QString &labelStr, KPasswordLineEdit *lineEdit, const QString &variable)
0241 {
0242     auto layout = new QHBoxLayout;
0243     auto label = new QLabel(labelStr, this);
0244     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0245     layout->addWidget(label);
0246     layout->addWidget(lineEdit);
0247     auto toolButton = new QToolButton(this);
0248     toolButton->setObjectName(QStringLiteral("toolbutton_%1").arg(variable));
0249     toolButton->setText(i18n("Apply"));
0250     toolButton->setProperty(s_property, variable);
0251     lineEdit->setProperty(s_property, variable);
0252     layout->addWidget(toolButton);
0253     toolButton->setEnabled(false);
0254     connect(toolButton, &QToolButton::clicked, this, [this, variable, lineEdit, toolButton]() {
0255         updateSettings(variable, lineEdit->password(), RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::String, toolButton->objectName());
0256     });
0257     connect(lineEdit, &KPasswordLineEdit::passwordChanged, this, [toolButton]() {
0258         toolButton->setEnabled(true);
0259     });
0260     connect(this, &SettingsWidgetBase::changedDone, this, [toolButton](const QString &buttonName) {
0261         if (toolButton->objectName() == buttonName) {
0262             toolButton->setEnabled(false);
0263         }
0264     });
0265 
0266     mMainLayout->addRow(layout);
0267 }
0268 
0269 void SettingsWidgetBase::fillComboBox(QComboBox *comboBox, const QMap<QString, QString> &items)
0270 {
0271     QMapIterator<QString, QString> i(items);
0272     while (i.hasNext()) {
0273         i.next();
0274         comboBox->addItem(i.value(), i.key());
0275     }
0276 }
0277 
0278 void SettingsWidgetBase::addComboBox(const QString &labelStr, const QMap<QString, QString> &items, QComboBox *comboBox, const QString &variable)
0279 {
0280     auto layout = new QHBoxLayout;
0281     auto label = new QLabel(labelStr, this);
0282     label->setObjectName(QStringLiteral("label_%1").arg(variable));
0283     layout->addWidget(label);
0284     layout->addWidget(comboBox);
0285     fillComboBox(comboBox, items);
0286     auto toolButton = new QToolButton(this);
0287     toolButton->setObjectName(QStringLiteral("toolbutton_%1").arg(variable));
0288     toolButton->setText(i18n("Apply"));
0289     toolButton->setProperty(s_property, variable);
0290     comboBox->setProperty(s_property, variable);
0291     layout->addWidget(toolButton);
0292     toolButton->setEnabled(false);
0293     connect(toolButton, &QToolButton::clicked, this, [this, variable, comboBox, toolButton]() {
0294         if (!updateSettings(variable,
0295                             comboBox->currentData().toString(),
0296                             RocketChatRestApi::UpdateAdminSettingsJob::UpdateAdminSettingsInfo::String,
0297                             toolButton->objectName())) {
0298             comboBox->setCurrentIndex(comboBox->findData(comboBox->property(s_property_default_value).toString()));
0299         }
0300     });
0301     connect(this, &SettingsWidgetBase::changedDone, this, [toolButton, comboBox](const QString &buttonName) {
0302         if (toolButton->objectName() == buttonName) {
0303             toolButton->setEnabled(false);
0304             comboBox->setProperty(s_property_default_value, comboBox->currentText());
0305         }
0306     });
0307     connect(comboBox, &QComboBox::currentIndexChanged, this, [toolButton, comboBox]() {
0308         if (comboBox->currentIndex() == comboBox->findData(comboBox->property(s_property_default_value).toString())) {
0309             toolButton->setEnabled(false);
0310         } else {
0311             toolButton->setEnabled(true);
0312         }
0313     });
0314 
0315     mMainLayout->addRow(layout);
0316 }
0317 
0318 void SettingsWidgetBase::initializeWidget(QLineEdit *lineEdit, const QMap<QString, QVariant> &mapSettings, const QString &defaultValue)
0319 {
0320     const QString variableName = lineEdit->property(s_property).toString();
0321     QString value = defaultValue;
0322     if (mapSettings.contains(variableName)) {
0323         value = mapSettings.value(variableName).toString();
0324     }
0325     lineEdit->setText(value);
0326     lineEdit->setProperty(s_property_default_value, value);
0327     disableTooButton(variableName);
0328 }
0329 
0330 void SettingsWidgetBase::initializeWidget(KPasswordLineEdit *lineEdit, const QMap<QString, QVariant> &mapSettings)
0331 {
0332     const QString variableName = lineEdit->property(s_property).toString();
0333     if (mapSettings.contains(variableName)) {
0334         const auto value = mapSettings.value(variableName);
0335         lineEdit->setPassword(value.toString());
0336         disableTooButton(variableName);
0337     }
0338 }
0339 
0340 void SettingsWidgetBase::initializeWidget(QCheckBox *checkbox, const QMap<QString, QVariant> &mapSettings, bool defaultValue)
0341 {
0342     const QString variableName = checkbox->property(s_property).toString();
0343     if (mapSettings.contains(variableName)) {
0344         const auto value = mapSettings.value(variableName);
0345         checkbox->setChecked(value.toBool());
0346     } else {
0347         checkbox->setChecked(defaultValue);
0348     }
0349 }
0350 
0351 void SettingsWidgetBase::initializeWidget(QLabel *label, const QMap<QString, QVariant> &mapSettings, const QString &defaultValue)
0352 {
0353     const QString variableName = label->property(s_property).toString();
0354     QString value = defaultValue;
0355     if (mapSettings.contains(variableName)) {
0356         value = mapSettings.value(variableName).toString();
0357     }
0358     label->setText(value);
0359 }
0360 
0361 void SettingsWidgetBase::initializeWidget(QSpinBox *spinbox, const QMap<QString, QVariant> &mapSettings, int defaultValue)
0362 {
0363     const QString variableName = spinbox->property(s_property).toString();
0364     const bool hasValue = mapSettings.contains(variableName);
0365     int spinboxValue = defaultValue;
0366     if (hasValue) {
0367         spinboxValue = mapSettings.value(variableName).toInt();
0368     }
0369     spinbox->setValue(spinboxValue);
0370     spinbox->setProperty(s_property_default_value, spinboxValue);
0371 
0372     disableTooButton(variableName);
0373 }
0374 
0375 void SettingsWidgetBase::initializeWidget(QComboBox *comboBox, const QMap<QString, QVariant> &mapSettings, const QString &defaultValue)
0376 {
0377     const QString variableName = comboBox->property(s_property).toString();
0378     QString value = defaultValue;
0379     if (mapSettings.contains(variableName)) {
0380         value = mapSettings.value(variableName).toString();
0381     }
0382     comboBox->setCurrentIndex(comboBox->findData(value));
0383     comboBox->setProperty(s_property_default_value, value);
0384     disableTooButton(variableName);
0385 }
0386 
0387 void SettingsWidgetBase::initializeWidget(QPlainTextEdit *plainTextEdit, const QMap<QString, QVariant> &mapSettings, const QString &defaultValue)
0388 {
0389     const QString variableName = plainTextEdit->property(s_property).toString();
0390     QString value = defaultValue;
0391     if (mapSettings.contains(variableName)) {
0392         value = mapSettings.value(variableName).toString();
0393     }
0394     plainTextEdit->setPlainText(value);
0395     plainTextEdit->setProperty(s_property_default_value, value);
0396     disableTooButton(variableName);
0397 }
0398 
0399 void SettingsWidgetBase::disableTooButton(const QString &variableName)
0400 {
0401     auto toolButton = findChild<QToolButton *>(QStringLiteral("toolbutton_%1").arg(variableName));
0402     if (toolButton) {
0403         toolButton->setEnabled(false);
0404     }
0405 }
0406 
0407 QLabel *SettingsWidgetBase::createBoldLabel(const QString &text)
0408 {
0409     auto label = new QLabel(text, this);
0410     QFont apiRateLimiterLabelFont = label->font();
0411     apiRateLimiterLabelFont.setBold(true);
0412     label->setFont(apiRateLimiterLabelFont);
0413     return label;
0414 }
0415 
0416 QString SettingsWidgetBase::urlFromRelativePath(const QString &relativePath)
0417 {
0418     if (mAccount) {
0419         return mAccount->serverUrl() + QLatin1Char('/') + relativePath;
0420     }
0421     return {};
0422 }
0423 
0424 #include "moc_settingswidgetbase.cpp"