1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3 
4     SPDX-FileCopyrightText: 2004 Peter Simonsson <psn@linux.se>
5 */
6 
7 #include "servergroupdialog.h"
8 #include "identity.h"
9 #include "application.h"
10 #include "viewcontainer.h"
11 #include "preferences.h"
12 #include "serversettings.h"
13 #include "identitydialog.h"
14 #include "ui_servergroupdialogui.h"
15 #include "ui_serverdialogui.h"
16 #include "ui_channeldialogui.h"
17 
18 #include <KAuthorized>
19 
20 #include <QPushButton>
21 #include <QCheckBox>
22 
23 #include <KMessageBox>
24 #include <QDialogButtonBox>
25 #include <QVBoxLayout>
26 
27 
28 namespace Konversation
29 {
30 
ServerGroupDialog(const QString & title,QWidget * parent)31     ServerGroupDialog::ServerGroupDialog(const QString& title, QWidget *parent)
32         : QDialog(parent)
33     {
34         setWindowTitle(title);
35         auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
36         auto *mainWidget = new QWidget(this);
37         auto *mainLayout = new QVBoxLayout;
38         setLayout(mainLayout);
39         mainLayout->addWidget(mainWidget);
40         QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
41         okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
42         connect(buttonBox, &QDialogButtonBox::accepted, this, &ServerGroupDialog::accept);
43         connect(buttonBox, &QDialogButtonBox::rejected, this, &ServerGroupDialog::reject);
44         //PORTING SCRIPT: WARNING mainLayout->addWidget(buttonBox) must be last item in layout. Please move it.
45         mainLayout->addWidget(buttonBox);
46 
47         m_id = -1;
48         m_identitiesNeedsUpdate = false;
49         m_editedServer = false;
50 
51         m_mainWidget = new Ui::ServerGroupDialogUI();
52         m_mainWidget->setupUi(mainWidget);
53 
54         connect(m_mainWidget->m_editIdentityButton, &QPushButton::clicked, this, &ServerGroupDialog::editIdentity);
55 
56         const IdentityList identities = Preferences::identityList();
57 
58         for (const auto& identity : identities) {
59             m_mainWidget->m_identityCBox->addItem(identity->getName());
60         }
61 
62         m_mainWidget->m_removeServerButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
63         m_mainWidget->m_upServerBtn->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
64         m_mainWidget->m_downServerBtn->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
65 
66         connect(m_mainWidget->m_addServerButton, &QPushButton::clicked, this, &ServerGroupDialog::addServer);
67         connect(m_mainWidget->m_changeServerButton, &QPushButton::clicked, this, QOverload<>::of(&ServerGroupDialog::editServer));
68         connect(m_mainWidget->m_removeServerButton, &QToolButton::clicked, this, &ServerGroupDialog::deleteServer);
69         connect(m_mainWidget->m_serverLBox, &QListWidget::itemSelectionChanged, this, &ServerGroupDialog::updateServerArrows);
70         connect(m_mainWidget->m_upServerBtn, &QToolButton::clicked, this, &ServerGroupDialog::moveServerUp);
71         connect(m_mainWidget->m_downServerBtn, &QToolButton::clicked, this, &ServerGroupDialog::moveServerDown);
72 
73         m_mainWidget->m_removeChannelButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
74         m_mainWidget->m_upChannelBtn->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
75         m_mainWidget->m_downChannelBtn->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
76 
77         connect(m_mainWidget->m_addChannelButton, &QPushButton::clicked, this, &ServerGroupDialog::addChannel);
78         connect(m_mainWidget->m_changeChannelButton, &QPushButton::clicked, this, &ServerGroupDialog::editChannel);
79         connect(m_mainWidget->m_removeChannelButton, &QToolButton::clicked, this, &ServerGroupDialog::deleteChannel);
80         connect(m_mainWidget->m_channelLBox, &QListWidget::itemSelectionChanged, this, &ServerGroupDialog::updateChannelArrows);
81         connect(m_mainWidget->m_upChannelBtn, &QToolButton::clicked, this, &ServerGroupDialog::moveChannelUp);
82         connect(m_mainWidget->m_downChannelBtn, &QToolButton::clicked, this, &ServerGroupDialog::moveChannelDown);
83 
84         okButton->setToolTip(i18n("Change network information"));
85         buttonBox->button(QDialogButtonBox::Cancel)->setToolTip(i18n("Discards all changes made"));
86 
87         m_mainWidget->m_nameEdit->setFocus();
88 
89         resize(QSize(320, 400));
90     }
91 
~ServerGroupDialog()92     ServerGroupDialog::~ServerGroupDialog()
93     {
94         delete m_mainWidget;
95     }
96 
setServerGroupSettings(ServerGroupSettingsPtr settings)97     void ServerGroupDialog::setServerGroupSettings(ServerGroupSettingsPtr settings)
98     {
99         m_id = settings->id();
100         m_sortIndex = settings->sortIndex();
101         m_expanded = settings->expanded();
102         m_enableNotifications = settings->enableNotifications();
103         m_mainWidget->m_nameEdit->setText(settings->name());
104 
105         const int i = m_mainWidget->m_identityCBox->findText(settings->identity()->getName());
106         if (i != -1)
107             m_mainWidget->m_identityCBox->setCurrentIndex(i);
108         else
109             m_mainWidget->m_identityCBox->setItemText(m_mainWidget->m_identityCBox->currentIndex(), settings->identity()->getName());
110 
111         m_mainWidget->m_commandEdit->setText(settings->connectCommands());
112         m_mainWidget->m_autoConnectCBox->setChecked(settings->autoConnectEnabled());
113         m_serverList = settings->serverList();
114         m_channelHistory = settings->channelHistory();
115         m_mainWidget->m_serverLBox->clear();
116 
117         for (const auto& server : qAsConst(m_serverList)) {
118             m_mainWidget->m_serverLBox->addItem(server.host());
119         }
120 
121         m_channelList = settings->channelList();
122 
123         for (const auto& channel : qAsConst(m_channelList)) {
124             m_mainWidget->m_channelLBox->addItem(channel.name());
125         }
126     }
127 
serverGroupSettings()128     ServerGroupSettingsPtr ServerGroupDialog::serverGroupSettings()
129     {
130         ServerGroupSettingsPtr settings(new ServerGroupSettings(m_id));
131         settings->setSortIndex(m_sortIndex);
132         settings->setName(m_mainWidget->m_nameEdit->text());
133         IdentityList identities = Preferences::identityList();
134         settings->setIdentityId(identities[m_mainWidget->m_identityCBox->currentIndex()]->id());
135         settings->setConnectCommands(m_mainWidget->m_commandEdit->text());
136         settings->setAutoConnectEnabled(m_mainWidget->m_autoConnectCBox->isChecked());
137         settings->setServerList(m_serverList);
138         settings->setChannelList(m_channelList);
139         settings->setChannelHistory(m_channelHistory);
140         settings->setNotificationsEnabled(m_enableNotifications);
141         settings->setExpanded(m_expanded);
142 
143         return settings;
144     }
145 
editedServer() const146     ServerSettings ServerGroupDialog::editedServer() const
147     {
148         if (m_editedServer && m_editedServerIndex < m_serverList.count())
149         {
150             return m_serverList[m_editedServerIndex];
151         }
152 
153         return ServerSettings(QString());
154     }
155 
execAndEditServer(const ServerSettings & server)156     int ServerGroupDialog::execAndEditServer(const ServerSettings &server)
157     {
158         show();
159         editServer(server);
160         return exec();
161     }
162 
addServer()163     void ServerGroupDialog::addServer()
164     {
165         QPointer<ServerDialog> dlg = new ServerDialog(i18n("Add Server"), this);
166 
167         if(dlg->exec() == QDialog::Accepted)
168         {
169             ServerSettings server = dlg->serverSettings();
170             m_mainWidget->m_serverLBox->addItem(server.host());
171             m_mainWidget->m_serverLBox->setCurrentItem(m_mainWidget->m_serverLBox->item(m_mainWidget->m_serverLBox->count() - 1));
172             m_serverList.append(server);
173         }
174         delete dlg;
175     }
176 
editServer()177     void ServerGroupDialog::editServer()
178     {
179         int current = m_mainWidget->m_serverLBox->currentRow();
180 
181         if(current < m_serverList.count())
182         {
183             QPointer <ServerDialog> dlg = new ServerDialog(i18n("Edit Server"), this);
184             dlg->setServerSettings(m_serverList[current]);
185 
186             if(dlg->exec() == QDialog::Accepted)
187             {
188                 ServerSettings server = dlg->serverSettings();
189                 m_mainWidget->m_serverLBox->item(current)->setText(server.host());
190                 m_serverList[current] = server;
191             }
192             delete dlg;
193         }
194     }
195 
editServer(const ServerSettings & server)196     void ServerGroupDialog::editServer(const ServerSettings &server)
197     {
198         // Track the server the Server List dialog told us to edit
199         // and find out which server to select in the listbox
200         m_editedServer = true;
201         m_editedServerIndex = m_serverList.indexOf(server);
202         m_mainWidget->m_serverLBox->setCurrentRow(m_editedServerIndex);
203 
204         editServer();
205     }
206 
deleteServer()207     void ServerGroupDialog::deleteServer()
208     {
209         int current = m_mainWidget->m_serverLBox->currentRow();
210 
211         if (current < m_serverList.count())
212         {
213             m_serverList.removeAt(current);
214             delete m_mainWidget->m_serverLBox->takeItem(current);
215 
216             // Track the server the Server List dialog told us to edit
217             if (m_editedServer && m_editedServerIndex==current)
218                 m_editedServer = false;
219         }
220 
221         updateServerArrows();
222     }
223 
updateServerArrows()224     void ServerGroupDialog::updateServerArrows()
225     {
226         QList<QListWidgetItem*> serverBoxSelection = m_mainWidget->m_serverLBox->selectedItems();
227 
228         const bool hasServerSelected = !serverBoxSelection.isEmpty();
229         if (m_mainWidget->m_serverLBox->count() && hasServerSelected) {
230             QListWidgetItem* selectedServer = serverBoxSelection.first();
231             int selectedServerRow = m_mainWidget->m_serverLBox->row(selectedServer);
232 
233             m_mainWidget->m_upServerBtn->setEnabled(selectedServerRow > 0);
234             m_mainWidget->m_downServerBtn->setEnabled(selectedServerRow < m_mainWidget->m_serverLBox->count() - 1);
235         }
236         else
237         {
238             m_mainWidget->m_upServerBtn->setEnabled(false);
239             m_mainWidget->m_downServerBtn->setEnabled(false);
240         }
241 
242         m_mainWidget->m_removeServerButton->setEnabled(hasServerSelected);
243         m_mainWidget->m_changeServerButton->setEnabled(hasServerSelected);
244     }
245 
moveServerUp()246     void ServerGroupDialog::moveServerUp()
247     {
248         int current = m_mainWidget->m_serverLBox->currentRow();
249 
250         if (current > 0)
251         {
252             ServerSettings server = m_serverList[current];
253             delete m_mainWidget->m_serverLBox->takeItem(current);
254             m_mainWidget->m_serverLBox->insertItem(current - 1, server.host());
255             m_mainWidget->m_serverLBox->setCurrentRow(current - 1);
256             m_serverList.move(current, current - 1);
257 
258             // Track the server the Server List dialog told us to edit
259             if (m_editedServer && m_editedServerIndex==current)
260                 m_editedServerIndex = current - 1;
261         }
262 
263         updateServerArrows();
264     }
265 
moveServerDown()266     void ServerGroupDialog::moveServerDown()
267     {
268         int current = m_mainWidget->m_serverLBox->currentRow();
269 
270         if (current < (m_serverList.count() - 1))
271         {
272             ServerSettings server = m_serverList[current];
273             delete m_mainWidget->m_serverLBox->takeItem(current);
274             m_mainWidget->m_serverLBox->insertItem(current + 1, server.host());
275             m_mainWidget->m_serverLBox->setCurrentRow(current + 1);
276             m_serverList.move(current, current + 1);
277 
278             // Track the server the Server List dialog told us to edit
279             if (m_editedServer && m_editedServerIndex==current)
280                 m_editedServerIndex = current + 1;
281         }
282 
283         updateServerArrows();
284     }
285 
addChannel()286     void ServerGroupDialog::addChannel()
287     {
288         QPointer<ChannelDialog> dlg = new ChannelDialog(i18n("Add Channel"), this);
289 
290         if(dlg->exec() == QDialog::Accepted)
291         {
292             ChannelSettings channel = dlg->channelSettings();
293             m_mainWidget->m_channelLBox->addItem(channel.name());
294             m_mainWidget->m_channelLBox->setCurrentItem(m_mainWidget->m_channelLBox->item(m_mainWidget->m_channelLBox->count() - 1));
295             m_channelList.append(channel);
296         }
297         delete dlg;
298     }
299 
editChannel()300     void ServerGroupDialog::editChannel()
301     {
302         int current = m_mainWidget->m_channelLBox->currentRow();
303 
304         if(current < m_channelList.count())
305         {
306             QPointer<ChannelDialog> dlg = new ChannelDialog(i18n("Edit Channel"), this);
307             dlg->setChannelSettings(m_channelList[current]);
308 
309             if(dlg->exec() == QDialog::Accepted)
310             {
311                 ChannelSettings channel = dlg->channelSettings();
312                 m_mainWidget->m_channelLBox->item(current)->setText(channel.name());
313                 m_channelList[current] = channel;
314             }
315             delete dlg;
316         }
317     }
318 
deleteChannel()319     void ServerGroupDialog::deleteChannel()
320     {
321         int current = m_mainWidget->m_channelLBox->currentRow();
322 
323         if(current < m_channelList.count())
324         {
325             m_channelList.removeOne(m_channelList.at(current));
326             delete m_mainWidget->m_channelLBox->takeItem(current);
327             updateChannelArrows();
328         }
329     }
330 
updateChannelArrows()331     void ServerGroupDialog::updateChannelArrows()
332     {
333         QList<QListWidgetItem*> channelBoxSelection = m_mainWidget->m_channelLBox->selectedItems();
334 
335         const bool hasChannelSelected = !channelBoxSelection.isEmpty();
336         if (m_mainWidget->m_channelLBox->count() && hasChannelSelected) {
337             QListWidgetItem* selectedChannel = channelBoxSelection.first();
338             int selectedChannelRow = m_mainWidget->m_channelLBox->row(selectedChannel);
339 
340             m_mainWidget->m_upChannelBtn->setEnabled(selectedChannelRow > 0);
341             m_mainWidget->m_downChannelBtn->setEnabled(selectedChannelRow < m_mainWidget->m_channelLBox->count() - 1);
342         }
343         else
344         {
345             m_mainWidget->m_upChannelBtn->setEnabled(false);
346             m_mainWidget->m_downChannelBtn->setEnabled(false);
347         }
348 
349         m_mainWidget->m_removeChannelButton->setEnabled(hasChannelSelected);
350         m_mainWidget->m_changeChannelButton->setEnabled(hasChannelSelected);
351     }
352 
moveChannelUp()353     void ServerGroupDialog::moveChannelUp()
354     {
355         int current = m_mainWidget->m_channelLBox->currentRow();
356 
357         if(current > 0)
358         {
359             ChannelSettings channel = m_channelList[current];
360             delete m_mainWidget->m_channelLBox->takeItem(current);
361             m_mainWidget->m_channelLBox->insertItem(current - 1, channel.name());
362             m_mainWidget->m_channelLBox->setCurrentRow(current - 1);
363             m_channelList.move(current, current - 1);
364         }
365 
366         updateChannelArrows();
367     }
368 
moveChannelDown()369     void ServerGroupDialog::moveChannelDown()
370     {
371         int current = m_mainWidget->m_channelLBox->currentRow();
372 
373         if(current < (m_channelList.count() - 1))
374         {
375             ChannelSettings channel = m_channelList[current];
376             delete m_mainWidget->m_channelLBox->takeItem(current);
377             m_mainWidget->m_channelLBox->insertItem(current + 1, channel.name());
378             m_mainWidget->m_channelLBox->setCurrentRow(current + 1);
379             m_channelList.move(current, current + 1);
380         }
381 
382         updateChannelArrows();
383     }
384 
editIdentity()385     void ServerGroupDialog::editIdentity()
386     {
387         QPointer<IdentityDialog> dlg = new IdentityDialog(this);
388         dlg->setCurrentIdentity(m_mainWidget->m_identityCBox->currentIndex());
389 
390         if(dlg->exec() == QDialog::Accepted)
391         {
392             const IdentityList identities = Preferences::identityList();
393             m_mainWidget->m_identityCBox->clear();
394 
395             for (const auto& identity : identities) {
396                 m_mainWidget->m_identityCBox->addItem(identity->getName());
397             }
398 
399             const int i = m_mainWidget->m_identityCBox->findText(dlg->currentIdentity()->getName());
400             if (i != -1)
401             {
402                 m_mainWidget->m_identityCBox->setCurrentIndex(i);
403             }
404             else
405             {
406                 m_mainWidget->m_identityCBox->setItemText(m_mainWidget->m_identityCBox->currentIndex(), dlg->currentIdentity()->getName());
407             }
408 
409             m_identitiesNeedsUpdate = true; // and what's this for?
410             ViewContainer* vc = Application::instance()->getMainWindow()->getViewContainer();
411             vc->updateViewEncoding(vc->getFrontView());
412         }
413         delete dlg;
414     }
415 
accept()416     void ServerGroupDialog::accept()
417     {
418         if (m_mainWidget->m_nameEdit->text().isEmpty())
419         {
420             KMessageBox::error(this, i18n("The network name is required."));
421         }
422         else if (m_serverList.isEmpty())
423         {
424             KMessageBox::error(this, i18n("You need to add at least one server to the network."));
425         }
426         else
427         {
428             QDialog::accept();
429         }
430     }
431 
ServerDialog(const QString & title,QWidget * parent)432     ServerDialog::ServerDialog(const QString& title, QWidget *parent)
433     : QDialog(parent)
434     {
435         setWindowTitle(title);
436         auto *mainWidget = new QWidget(this);
437         auto *mainLayout = new QVBoxLayout;
438         setLayout(mainLayout);
439         mainLayout->addWidget(mainWidget);
440 
441         auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
442         m_okButton = buttonBox->button(QDialogButtonBox::Ok);
443         m_okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
444         connect(buttonBox, &QDialogButtonBox::rejected, this, &ServerDialog::reject);
445         mainLayout->addWidget(buttonBox);
446 
447         m_mainWidget = new Ui::ServerDialogUI();
448         m_mainWidget->setupUi(mainWidget);
449         m_mainWidget->m_passwordEdit->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
450 
451         m_mainWidget->m_serverEdit->setFocus();
452 
453         connect(m_okButton, &QPushButton::clicked, this, &ServerDialog::slotOk);
454         connect(m_mainWidget->m_serverEdit, &KLineEdit::textChanged, this, &ServerDialog::slotServerNameChanged);
455         slotServerNameChanged( m_mainWidget->m_serverEdit->text() );
456     }
457 
~ServerDialog()458     ServerDialog::~ServerDialog()
459     {
460         delete m_mainWidget;
461     }
462 
slotServerNameChanged(const QString & text)463     void ServerDialog::slotServerNameChanged( const QString &text )
464     {
465         m_okButton->setEnabled( !text.isEmpty() );
466     }
467 
setServerSettings(const ServerSettings & server)468     void ServerDialog::setServerSettings(const ServerSettings& server)
469     {
470         m_mainWidget->m_serverEdit->setText(server.host());
471         m_mainWidget->m_portSBox->setValue(server.port());
472         m_mainWidget->m_passwordEdit->setPassword(server.password());
473         m_mainWidget->m_sslChBox->setChecked(server.SSLEnabled());
474         m_mainWidget->m_proxyChBox->setChecked(!server.bypassProxy());
475     }
476 
serverSettings() const477     ServerSettings ServerDialog::serverSettings() const
478     {
479         ServerSettings server;
480         server.setHost(m_mainWidget->m_serverEdit->text());
481         server.setPort(m_mainWidget->m_portSBox->value());
482         server.setPassword(m_mainWidget->m_passwordEdit->password());
483         server.setSSLEnabled(m_mainWidget->m_sslChBox->isChecked());
484         server.setBypassProxy(!m_mainWidget->m_proxyChBox->isChecked());
485 
486         return server;
487     }
488 
slotOk()489     void ServerDialog::slotOk()
490     {
491         if (m_mainWidget->m_serverEdit->text().isEmpty())
492         {
493             KMessageBox::error(this, i18n("The server address is required."));
494         }
495         else
496         {
497             accept();
498         }
499     }
500 
ChannelDialog(const QString & title,QWidget * parent)501     ChannelDialog::ChannelDialog(const QString& title, QWidget *parent)
502     : QDialog(parent)
503     {
504         setWindowTitle(title);
505         auto *mainWidget = new QWidget(this);
506         auto *mainLayout = new QVBoxLayout;
507         setLayout(mainLayout);
508         mainLayout->addWidget(mainWidget);
509         auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
510         m_okButton = buttonBox->button(QDialogButtonBox::Ok);
511         m_okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
512         connect(buttonBox, &QDialogButtonBox::rejected, this, &ChannelDialog::reject);
513         mainLayout->addWidget(buttonBox);
514 
515         m_mainWidget = new Ui::ChannelDialogUI();
516         m_mainWidget->setupUi(mainWidget);
517         m_mainWidget->m_passwordEdit->setRevealPasswordAvailable(KAuthorized::authorize(QStringLiteral("lineedit_reveal_password")));
518 
519         m_mainWidget->m_channelEdit->setFocus();
520         connect(m_okButton, &QPushButton::clicked, this, &ChannelDialog::slotOk);
521         connect(m_mainWidget->m_channelEdit, &KLineEdit::textChanged, this, &ChannelDialog::slotServerNameChanged);
522         slotServerNameChanged( m_mainWidget->m_channelEdit->text() );
523     }
524 
~ChannelDialog()525     ChannelDialog::~ChannelDialog()
526     {
527         delete m_mainWidget;
528     }
529 
slotServerNameChanged(const QString & text)530     void ChannelDialog::slotServerNameChanged( const QString &text )
531     {
532         m_okButton->setEnabled( !text.isEmpty() );
533     }
534 
setChannelSettings(const ChannelSettings & channel)535     void ChannelDialog::setChannelSettings(const ChannelSettings& channel)
536     {
537         m_mainWidget->m_channelEdit->setText(channel.name());
538         m_mainWidget->m_passwordEdit->setPassword(channel.password());
539     }
540 
channelSettings() const541     ChannelSettings ChannelDialog::channelSettings() const
542     {
543         ChannelSettings channel;
544         channel.setName(m_mainWidget->m_channelEdit->text());
545         channel.setPassword(m_mainWidget->m_passwordEdit->password());
546 
547         return channel;
548     }
549 
slotOk()550     void ChannelDialog::slotOk()
551     {
552         if (m_mainWidget->m_channelEdit->text().isEmpty())
553         {
554             KMessageBox::error(this, i18n("The channel name is required."));
555         }
556         else
557         {
558             accept();
559         }
560     }
561 
562 }
563 
564 
565