KLdap

ldapconfigurewidget.cpp
1/*
2 * SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "ldapconfigurewidget.h"
8
9#include <QLabel>
10#include <QListWidget>
11#include <QListWidgetItem>
12#include <QPushButton>
13#include <QToolButton>
14#include <QVBoxLayout>
15
16#include <KConfig>
17#include <KConfigGroup>
18#include <KLocalizedString>
19#include <KMessageBox>
20#include <QDialogButtonBox>
21#include <QHBoxLayout>
22
23#include "kldapcore/ldapclientsearchconfig.h"
24#include "kldapcore/ldapserver.h"
25#include "ldapclientsearchconfigwriteconfigjob.h"
26#include "ldapwidgetitem_p.h"
27#include "ldapwidgetitemreadconfigserverjob.h"
28
29#include "addhostdialog.h"
30
31using namespace KLDAPWidgets;
32using namespace Qt::Literals::StringLiterals;
33
34LdapConfigureWidget::LdapConfigureWidget(QWidget *parent)
35 : QWidget(parent)
36 , mClientSearchConfig(new KLDAPCore::LdapClientSearchConfig)
37{
38 initGUI();
39
40 connect(mHostListView, &QListWidget::currentItemChanged, this, &LdapConfigureWidget::slotSelectionChanged);
41 connect(mHostListView, &QListWidget::itemDoubleClicked, this, &LdapConfigureWidget::slotEditHost);
42 connect(mHostListView, &QListWidget::itemClicked, this, &LdapConfigureWidget::slotItemClicked);
43
44 connect(mUpButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveUp);
45 connect(mDownButton, &QToolButton::clicked, this, &LdapConfigureWidget::slotMoveDown);
46}
47
48LdapConfigureWidget::~LdapConfigureWidget()
49{
50 delete mClientSearchConfig;
51}
52
53void LdapConfigureWidget::slotSelectionChanged(QListWidgetItem *item)
54{
55 bool state = (item != nullptr);
56 mEditButton->setEnabled(state);
57 mRemoveButton->setEnabled(state);
58 mDownButton->setEnabled(item && (mHostListView->row(item) != (mHostListView->count() - 1)));
59 mUpButton->setEnabled(item && (mHostListView->row(item) != 0));
60}
61
62void LdapConfigureWidget::slotItemClicked(QListWidgetItem *item)
63{
64 auto ldapItem = dynamic_cast<LdapWidgetItem *>(item);
65 if (!ldapItem) {
66 return;
67 }
68
69 if ((ldapItem->checkState() == Qt::Checked) != ldapItem->isActive()) {
70 Q_EMIT changed(true);
71 ldapItem->setIsActive(ldapItem->checkState() == Qt::Checked);
72 }
73}
74
75void LdapConfigureWidget::slotAddHost()
76{
78 KLDAPWidgets::AddHostDialog dlg(&server, this);
79
80 if (dlg.exec() && !server.host().trimmed().isEmpty()) { // krazy:exclude=crashy
81 auto item = new LdapWidgetItem(mHostListView);
82 item->setServer(server);
83
84 Q_EMIT changed(true);
85 }
86}
87
88void LdapConfigureWidget::slotEditHost()
89{
90 auto item = dynamic_cast<LdapWidgetItem *>(mHostListView->currentItem());
91 if (!item) {
92 return;
93 }
94
95 KLDAPCore::LdapServer server = item->server();
96 KLDAPWidgets::AddHostDialog dlg(&server, this);
97 dlg.setWindowTitle(i18nc("@title:window", "Edit Host"));
98
99 if (dlg.exec() && !server.host().isEmpty()) { // krazy:exclude=crashy
100 item->setServer(server);
101
102 Q_EMIT changed(true);
103 }
104}
105
106void LdapConfigureWidget::slotRemoveHost()
107{
108 QListWidgetItem *item = mHostListView->currentItem();
109 if (!item) {
110 return;
111 }
112 auto ldapItem = static_cast<LdapWidgetItem *>(item);
113 const int answer = KMessageBox::questionTwoActions(this,
114 i18n("Do you want to remove setting for host \"%1\"?", ldapItem->server().host()),
115 i18nc("@title:window", "Remove Host"),
118 if (answer == KMessageBox::SecondaryAction) {
119 return;
120 }
121
122 delete mHostListView->takeItem(mHostListView->currentRow());
123
124 slotSelectionChanged(mHostListView->currentItem());
125
126 Q_EMIT changed(true);
127}
128
129static void swapItems(LdapWidgetItem *item, LdapWidgetItem *other)
130{
131 KLDAPCore::LdapServer server = item->server();
132 bool isActive = item->isActive();
133 item->setServer(other->server());
134 item->setIsActive(other->isActive());
135 item->setCheckState(other->isActive() ? Qt::Checked : Qt::Unchecked);
136 other->setServer(server);
137 other->setIsActive(isActive);
138 other->setCheckState(isActive ? Qt::Checked : Qt::Unchecked);
139}
140
141void LdapConfigureWidget::slotMoveUp()
142{
143 const QList<QListWidgetItem *> selectedItems = mHostListView->selectedItems();
144 if (selectedItems.isEmpty()) {
145 return;
146 }
147
148 LdapWidgetItem *item = static_cast<LdapWidgetItem *>(mHostListView->selectedItems().first());
149 if (!item) {
150 return;
151 }
152
153 auto above = static_cast<LdapWidgetItem *>(mHostListView->item(mHostListView->row(item) - 1));
154 if (!above) {
155 return;
156 }
157
158 swapItems(item, above);
159
160 mHostListView->setCurrentItem(above);
161 above->setSelected(true);
162
163 Q_EMIT changed(true);
164}
165
166void LdapConfigureWidget::slotMoveDown()
167{
168 const QList<QListWidgetItem *> selectedItems = mHostListView->selectedItems();
169 if (selectedItems.isEmpty()) {
170 return;
171 }
172
173 LdapWidgetItem *item = static_cast<LdapWidgetItem *>(mHostListView->selectedItems().first());
174 if (!item) {
175 return;
176 }
177
178 auto below = static_cast<LdapWidgetItem *>(mHostListView->item(mHostListView->row(item) + 1));
179 if (!below) {
180 return;
181 }
182
183 swapItems(item, below);
184
185 mHostListView->setCurrentItem(below);
186 below->setSelected(true);
187
188 Q_EMIT changed(true);
189}
190
191void LdapConfigureWidget::load()
192{
193 mHostListView->clear();
194 KConfig *config = KLDAPCore::LdapClientSearchConfig::config();
195 KConfigGroup group(config, QStringLiteral("LDAP"));
196
197 int count = group.readEntry("NumSelectedHosts", 0);
198 for (int i = 0; i < count; ++i) {
199 auto item = new LdapWidgetItem(mHostListView, true);
200 item->setCheckState(Qt::Checked);
201 auto job = new LdapWidgetItemReadConfigServerJob(this);
202 job->setCurrentIndex(i);
203 job->setActive(true);
204 job->setConfig(group);
205 job->setLdapWidgetItem(item);
206 job->start();
207 }
208
209 count = group.readEntry("NumHosts", 0);
210 for (int i = 0; i < count; ++i) {
211 auto item = new LdapWidgetItem(mHostListView);
212 auto job = new LdapWidgetItemReadConfigServerJob(this);
213 job->setCurrentIndex(i);
214 job->setActive(false);
215 job->setConfig(group);
216 job->setLdapWidgetItem(item);
217 job->start();
218 }
219
220 Q_EMIT changed(false);
221}
222
223void LdapConfigureWidget::save()
224{
225 KConfig *config = KLDAPCore::LdapClientSearchConfig::config();
226 config->deleteGroup(QStringLiteral("LDAP"));
227
228 KConfigGroup group(config, QStringLiteral("LDAP"));
229
230 int selected = 0;
231 int unselected = 0;
232 for (int i = 0; i < mHostListView->count(); ++i) {
233 auto item = dynamic_cast<LdapWidgetItem *>(mHostListView->item(i));
234 if (!item) {
235 continue;
236 }
237
238 KLDAPCore::LdapServer server = item->server();
239 if (item->checkState() == Qt::Checked) {
240 auto job = new KLDAPCore::LdapClientSearchConfigWriteConfigJob;
241 job->setActive(true);
242 job->setConfig(group);
243 job->setServerIndex(selected);
244 job->setServer(server);
245 job->start();
246 selected++;
247 } else {
248 auto job = new KLDAPCore::LdapClientSearchConfigWriteConfigJob;
249 job->setActive(false);
250 job->setConfig(group);
251 job->setServerIndex(unselected);
252 job->setServer(server);
253 job->start();
254 unselected++;
255 }
256 }
257
258 group.writeEntry("NumSelectedHosts", selected);
259 group.writeEntry("NumHosts", unselected);
260 config->sync();
261
262 Q_EMIT changed(false);
263}
264
265void LdapConfigureWidget::initGUI()
266{
267 auto mainLayout = new QVBoxLayout(this);
268 mainLayout->setObjectName("layout"_L1);
269
270 // Contents of the QVGroupBox: label and hbox
271 auto label = new QLabel(i18nc("@label:textbox", "Check all servers that should be used:"), this);
272 mainLayout->addWidget(label);
273
274 auto hBox = new QWidget(this);
275 mainLayout->addWidget(hBox);
276
277 auto hBoxHBoxLayout = new QHBoxLayout(hBox);
278 hBoxHBoxLayout->setContentsMargins({});
279 hBoxHBoxLayout->setSpacing(6);
280 // Contents of the hbox: listview and up/down buttons on the right (vbox)
281 mHostListView = new QListWidget(hBox);
282 hBoxHBoxLayout->addWidget(mHostListView);
283 mHostListView->setSortingEnabled(false);
284
285 auto upDownBox = new QWidget(hBox);
286 auto upDownBoxVBoxLayout = new QVBoxLayout(upDownBox);
287 upDownBoxVBoxLayout->setContentsMargins({});
288 hBoxHBoxLayout->addWidget(upDownBox);
289 upDownBoxVBoxLayout->setSpacing(6);
290 mUpButton = new QToolButton(upDownBox);
291 upDownBoxVBoxLayout->addWidget(mUpButton);
292 mUpButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
293 mUpButton->setEnabled(false); // b/c no item is selected yet
294
295 mDownButton = new QToolButton(upDownBox);
296 upDownBoxVBoxLayout->addWidget(mDownButton);
297 mDownButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
298 mDownButton->setEnabled(false); // b/c no item is selected yet
299
300 auto spacer = new QWidget(upDownBox);
301 upDownBoxVBoxLayout->addWidget(spacer);
302 upDownBoxVBoxLayout->setStretchFactor(spacer, 100);
303
304 auto buttons = new QDialogButtonBox(this);
305 QPushButton *add = buttons->addButton(i18nc("@action:button", "&Add Host…"), QDialogButtonBox::ActionRole);
306 connect(add, &QPushButton::clicked, this, &LdapConfigureWidget::slotAddHost);
307 mEditButton = buttons->addButton(i18nc("@action:button", "&Edit Host…"), QDialogButtonBox::ActionRole);
308 connect(mEditButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotEditHost);
309 mEditButton->setEnabled(false);
310 mRemoveButton = buttons->addButton(i18nc("@action:button", "&Remove Host"), QDialogButtonBox::ActionRole);
311 connect(mRemoveButton, &QPushButton::clicked, this, &LdapConfigureWidget::slotRemoveHost);
312 mRemoveButton->setEnabled(false);
313
314 mainLayout->addWidget(buttons);
315}
316
317#include "moc_ldapconfigurewidget.cpp"
void deleteGroup(const QString &group, WriteConfigFlags flags=Normal)
bool sync() override
A class that contains LDAP server connection settings.
Definition ldapserver.h:27
QString host() const
Returns the host of the LDAP connection.
The AddHostDialog class.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
KGuiItem add()
KGuiItem remove()
KGuiItem cancel()
QString label(StandardShortcut id)
void clicked(bool checked)
void setIcon(const QIcon &icon)
QIcon fromTheme(const QString &name)
bool isEmpty() const const
void clear()
QListWidgetItem * currentItem() const const
void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
QListWidgetItem * item(int row) const const
void itemClicked(QListWidgetItem *item)
void itemDoubleClicked(QListWidgetItem *item)
int row(const QListWidgetItem *item) const const
QList< QListWidgetItem * > selectedItems() const const
void setCurrentItem(QListWidgetItem *item)
void setSortingEnabled(bool enable)
QListWidgetItem * takeItem(int row)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const
QString trimmed() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QWidget(QWidget *parent, Qt::WindowFlags f)
void setEnabled(bool)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:14:23 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.