File indexing completed on 2025-01-26 04:52:15

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "ldapconfigurewidget.h"
0008 #include <QLabel>
0009 #include <QListWidget>
0010 #include <QListWidgetItem>
0011 #include <QPushButton>
0012 #include <QToolButton>
0013 #include <QVBoxLayout>
0014 
0015 #include <KConfig>
0016 #include <KConfigGroup>
0017 #include <KLocalizedString>
0018 #include <KMessageBox>
0019 #include <QDialogButtonBox>
0020 #include <QHBoxLayout>
0021 
0022 #include "kldapcore/ldapserver.h"
0023 #include "ldapclientsearchconfig.h"
0024 #include "ldapclientsearchconfigwriteconfigjob.h"
0025 #include "ldapwidgetitem_p.h"
0026 #include "ldapwidgetitemreadconfigserverjob.h"
0027 
0028 #include "addhostdialog.h"
0029 
0030 using namespace KLDAPWidgets;
0031 
0032 LdapConfigureWidget::LdapConfigureWidget(QWidget *parent)
0033     : QWidget(parent)
0034     , mClientSearchConfig(new KLDAPWidgets::LdapClientSearchConfig)
0035 {
0036     initGUI();
0037 
0038     connect(mHostListView, &QListWidget::currentItemChanged, this, &LdapConfigureWidget::slotSelectionChanged);
0039     connect(mHostListView, &QListWidget::itemDoubleClicked, this, &LdapConfigureWidget::slotEditHost);
0040     connect(mHostListView, &QListWidget::itemClicked, this, &LdapConfigureWidget::slotItemClicked);
0041 
0042     connect(mUpButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveUp);
0043     connect(mDownButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveDown);
0044 }
0045 
0046 LdapConfigureWidget::~LdapConfigureWidget()
0047 {
0048     delete mClientSearchConfig;
0049 }
0050 
0051 void LdapConfigureWidget::slotSelectionChanged(QListWidgetItem *item)
0052 {
0053     bool state = (item != nullptr);
0054     mEditButton->setEnabled(state);
0055     mRemoveButton->setEnabled(state);
0056     mDownButton->setEnabled(item && (mHostListView->row(item) != (mHostListView->count() - 1)));
0057     mUpButton->setEnabled(item && (mHostListView->row(item) != 0));
0058 }
0059 
0060 void LdapConfigureWidget::slotItemClicked(QListWidgetItem *item)
0061 {
0062     auto ldapItem = dynamic_cast<LdapWidgetItem *>(item);
0063     if (!ldapItem) {
0064         return;
0065     }
0066 
0067     if ((ldapItem->checkState() == Qt::Checked) != ldapItem->isActive()) {
0068         Q_EMIT changed(true);
0069         ldapItem->setIsActive(ldapItem->checkState() == Qt::Checked);
0070     }
0071 }
0072 
0073 void LdapConfigureWidget::slotAddHost()
0074 {
0075     KLDAPCore::LdapServer server;
0076     KLDAPWidgets::AddHostDialog dlg(&server, this);
0077 
0078     if (dlg.exec() && !server.host().trimmed().isEmpty()) { // krazy:exclude=crashy
0079         auto item = new LdapWidgetItem(mHostListView);
0080         item->setServer(server);
0081 
0082         Q_EMIT changed(true);
0083     }
0084 }
0085 
0086 void LdapConfigureWidget::slotEditHost()
0087 {
0088     auto item = dynamic_cast<LdapWidgetItem *>(mHostListView->currentItem());
0089     if (!item) {
0090         return;
0091     }
0092 
0093     KLDAPCore::LdapServer server = item->server();
0094     KLDAPWidgets::AddHostDialog dlg(&server, this);
0095     dlg.setWindowTitle(i18nc("@title:window", "Edit Host"));
0096 
0097     if (dlg.exec() && !server.host().isEmpty()) { // krazy:exclude=crashy
0098         item->setServer(server);
0099 
0100         Q_EMIT changed(true);
0101     }
0102 }
0103 
0104 void LdapConfigureWidget::slotRemoveHost()
0105 {
0106     QListWidgetItem *item = mHostListView->currentItem();
0107     if (!item) {
0108         return;
0109     }
0110     auto ldapItem = dynamic_cast<LdapWidgetItem *>(item);
0111     const int answer = KMessageBox::questionTwoActions(this,
0112                                                        i18n("Do you want to remove setting for host \"%1\"?", ldapItem->server().host()),
0113                                                        i18n("Remove Host"),
0114                                                        KStandardGuiItem::remove(),
0115                                                        KStandardGuiItem::cancel());
0116     if (answer == KMessageBox::SecondaryAction) {
0117         return;
0118     }
0119 
0120     delete mHostListView->takeItem(mHostListView->currentRow());
0121 
0122     slotSelectionChanged(mHostListView->currentItem());
0123 
0124     Q_EMIT changed(true);
0125 }
0126 
0127 static void swapItems(LdapWidgetItem *item, LdapWidgetItem *other)
0128 {
0129     KLDAPCore::LdapServer server = item->server();
0130     bool isActive = item->isActive();
0131     item->setServer(other->server());
0132     item->setIsActive(other->isActive());
0133     item->setCheckState(other->isActive() ? Qt::Checked : Qt::Unchecked);
0134     other->setServer(server);
0135     other->setIsActive(isActive);
0136     other->setCheckState(isActive ? Qt::Checked : Qt::Unchecked);
0137 }
0138 
0139 void LdapConfigureWidget::slotMoveUp()
0140 {
0141     const QList<QListWidgetItem *> selectedItems = mHostListView->selectedItems();
0142     if (selectedItems.isEmpty()) {
0143         return;
0144     }
0145 
0146     LdapWidgetItem *item = static_cast<LdapWidgetItem *>(mHostListView->selectedItems().first());
0147     if (!item) {
0148         return;
0149     }
0150 
0151     auto above = static_cast<LdapWidgetItem *>(mHostListView->item(mHostListView->row(item) - 1));
0152     if (!above) {
0153         return;
0154     }
0155 
0156     swapItems(item, above);
0157 
0158     mHostListView->setCurrentItem(above);
0159     above->setSelected(true);
0160 
0161     Q_EMIT changed(true);
0162 }
0163 
0164 void LdapConfigureWidget::slotMoveDown()
0165 {
0166     const QList<QListWidgetItem *> selectedItems = mHostListView->selectedItems();
0167     if (selectedItems.isEmpty()) {
0168         return;
0169     }
0170 
0171     LdapWidgetItem *item = static_cast<LdapWidgetItem *>(mHostListView->selectedItems().first());
0172     if (!item) {
0173         return;
0174     }
0175 
0176     auto below = static_cast<LdapWidgetItem *>(mHostListView->item(mHostListView->row(item) + 1));
0177     if (!below) {
0178         return;
0179     }
0180 
0181     swapItems(item, below);
0182 
0183     mHostListView->setCurrentItem(below);
0184     below->setSelected(true);
0185 
0186     Q_EMIT changed(true);
0187 }
0188 
0189 void LdapConfigureWidget::load()
0190 {
0191     mHostListView->clear();
0192     KConfig *config = KLDAPWidgets::LdapClientSearchConfig::config();
0193     KConfigGroup group(config, QStringLiteral("LDAP"));
0194 
0195     int count = group.readEntry("NumSelectedHosts", 0);
0196     for (int i = 0; i < count; ++i) {
0197         auto item = new LdapWidgetItem(mHostListView, true);
0198         item->setCheckState(Qt::Checked);
0199         auto job = new LdapWidgetItemReadConfigServerJob(this);
0200         job->setCurrentIndex(i);
0201         job->setActive(true);
0202         job->setConfig(group);
0203         job->setLdapWidgetItem(item);
0204         job->start();
0205     }
0206 
0207     count = group.readEntry("NumHosts", 0);
0208     for (int i = 0; i < count; ++i) {
0209         auto item = new LdapWidgetItem(mHostListView);
0210         auto job = new LdapWidgetItemReadConfigServerJob(this);
0211         job->setCurrentIndex(i);
0212         job->setActive(false);
0213         job->setConfig(group);
0214         job->setLdapWidgetItem(item);
0215         job->start();
0216     }
0217 
0218     Q_EMIT changed(false);
0219 }
0220 
0221 void LdapConfigureWidget::save()
0222 {
0223     // mClientSearchConfig->clearWalletPassword();
0224     KConfig *config = KLDAPWidgets::LdapClientSearchConfig::config();
0225     config->deleteGroup(QStringLiteral("LDAP"));
0226 
0227     KConfigGroup group(config, QStringLiteral("LDAP"));
0228 
0229     int selected = 0;
0230     int unselected = 0;
0231     for (int i = 0; i < mHostListView->count(); ++i) {
0232         auto item = dynamic_cast<LdapWidgetItem *>(mHostListView->item(i));
0233         if (!item) {
0234             continue;
0235         }
0236 
0237         KLDAPCore::LdapServer server = item->server();
0238         if (item->checkState() == Qt::Checked) {
0239             auto job = new LdapClientSearchConfigWriteConfigJob;
0240             job->setActive(true);
0241             job->setConfig(group);
0242             job->setServerIndex(selected);
0243             job->setServer(server);
0244             job->start();
0245             selected++;
0246         } else {
0247             auto job = new LdapClientSearchConfigWriteConfigJob;
0248             job->setActive(false);
0249             job->setConfig(group);
0250             job->setServerIndex(unselected);
0251             job->setServer(server);
0252             job->start();
0253             unselected++;
0254         }
0255     }
0256 
0257     group.writeEntry("NumSelectedHosts", selected);
0258     group.writeEntry("NumHosts", unselected);
0259     config->sync();
0260 
0261     Q_EMIT changed(false);
0262 }
0263 
0264 void LdapConfigureWidget::initGUI()
0265 {
0266     auto mainLayout = new QVBoxLayout(this);
0267     mainLayout->setObjectName(QLatin1StringView("layout"));
0268 
0269     // Contents of the QVGroupBox: label and hbox
0270     auto label = new QLabel(i18n("Check all servers that should be used:"));
0271     mainLayout->addWidget(label);
0272 
0273     auto hBox = new QWidget(this);
0274     mainLayout->addWidget(hBox);
0275 
0276     auto hBoxHBoxLayout = new QHBoxLayout(hBox);
0277     hBoxHBoxLayout->setContentsMargins(0, 0, 0, 0);
0278     hBoxHBoxLayout->setSpacing(6);
0279     // Contents of the hbox: listview and up/down buttons on the right (vbox)
0280     mHostListView = new QListWidget(hBox);
0281     hBoxHBoxLayout->addWidget(mHostListView);
0282     mHostListView->setSortingEnabled(false);
0283 
0284     auto upDownBox = new QWidget(hBox);
0285     auto upDownBoxVBoxLayout = new QVBoxLayout(upDownBox);
0286     upDownBoxVBoxLayout->setContentsMargins(0, 0, 0, 0);
0287     hBoxHBoxLayout->addWidget(upDownBox);
0288     upDownBoxVBoxLayout->setSpacing(6);
0289     mUpButton = new QToolButton(upDownBox);
0290     upDownBoxVBoxLayout->addWidget(mUpButton);
0291     mUpButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
0292     mUpButton->setEnabled(false); // b/c no item is selected yet
0293 
0294     mDownButton = new QToolButton(upDownBox);
0295     upDownBoxVBoxLayout->addWidget(mDownButton);
0296     mDownButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
0297     mDownButton->setEnabled(false); // b/c no item is selected yet
0298 
0299     auto spacer = new QWidget(upDownBox);
0300     upDownBoxVBoxLayout->addWidget(spacer);
0301     upDownBoxVBoxLayout->setStretchFactor(spacer, 100);
0302 
0303     auto buttons = new QDialogButtonBox(this);
0304     QPushButton *add = buttons->addButton(i18n("&Add Host..."), QDialogButtonBox::ActionRole);
0305     connect(add, &QPushButton::clicked, this, &LdapConfigureWidget::slotAddHost);
0306     mEditButton = buttons->addButton(i18n("&Edit Host..."), QDialogButtonBox::ActionRole);
0307     connect(mEditButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotEditHost);
0308     mEditButton->setEnabled(false);
0309     mRemoveButton = buttons->addButton(i18n("&Remove Host"), QDialogButtonBox::ActionRole);
0310     connect(mRemoveButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotRemoveHost);
0311     mRemoveButton->setEnabled(false);
0312 
0313     mainLayout->addWidget(buttons);
0314 }
0315 
0316 #include "moc_ldapconfigurewidget.cpp"