cfgircdefinenetworkdialog.cpp
1 //------------------------------------------------------------------------------
2 // cfgircdefinenetworkdialog.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2010 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "cfgircdefinenetworkdialog.h"
24 #include "ui_cfgircdefinenetworkdialog.h"
25 
26 #include "configuration/passwordscfg.h"
27 #include "gui/commongui.h"
28 #include "irc/chatnetworknamer.h"
29 #include "irc/configuration/chatnetworkscfg.h"
30 #include "irc/entities/ircnetworkentity.h"
31 #include "strings.hpp"
32 #include <cassert>
33 #include <QMessageBox>
34 
35 
36 DClass<CFGIRCDefineNetworkDialog> : public Ui::CFGIRCDefineNetworkDialog
37 {
38 public:
39  static const int MAX_IRC_COMMAND_LENGTH = 512;
40 
41  QList<IRCNetworkEntity> existingNetworks;
42  QString originalDescription;
43 };
44 
45 DPointered(CFGIRCDefineNetworkDialog)
46 
47 
48 CFGIRCDefineNetworkDialog::CFGIRCDefineNetworkDialog(const IRCNetworkEntity &initValuesEntity, QWidget *parent)
49  : QDialog(parent)
50 {
51  construct();
52 
53  initFrom(initValuesEntity);
54 }
55 
56 CFGIRCDefineNetworkDialog::CFGIRCDefineNetworkDialog(QWidget *parent)
57  : QDialog(parent)
58 {
59  construct();
60 }
61 
62 CFGIRCDefineNetworkDialog::~CFGIRCDefineNetworkDialog()
63 {
64 }
65 
66 void CFGIRCDefineNetworkDialog::accept()
67 {
68  if (!validateDescription())
69  return;
70  QStringList offenders = validateAutojoinCommands();
71  if (!offenders.isEmpty())
72  {
73  if (!askToAcceptAnywayWhenCommandsBad(offenders))
74  return;
75  }
76  QDialog::accept();
77 }
78 
79 bool CFGIRCDefineNetworkDialog::askToAcceptAnywayWhenCommandsBad(const QStringList &offenders)
80 {
81  assert(!offenders.isEmpty() && "no offenders");
82  QString header = tr("These commands have violated the IRC maximum byte "
84  QString footer = tr("\n\nIf saved, the script may not run properly.\n\n"
85  "Do you wish to save the script anyway?");
86  QStringList formattedOffenders = formatOffenders(offenders.mid(0, 10));
87  QString body = formattedOffenders.join("\n\n");
88  if (formattedOffenders.size() < offenders.size())
89  body += tr("\n\n... and %n more ...", "", offenders.size() - formattedOffenders.size());
90  QString msg = header + body + footer;
91  QMessageBox::StandardButton result = QMessageBox::warning(
92  this, tr("Doomseeker - IRC Commands Problem"), msg,
93  QMessageBox::Yes | QMessageBox::Cancel);
94  return result == QMessageBox::Yes;
95 }
96 
97 QStringList CFGIRCDefineNetworkDialog::autojoinCommands() const
98 {
99  return d->teAutojoinCommands->toPlainText().split("\n");
100 }
101 
102 void CFGIRCDefineNetworkDialog::construct()
103 {
104  d->setupUi(this);
105  CommonGUI::setupDialog(*this);
106 
107  PasswordsCfg passCfg;
108  setHideNickservPassword(passCfg.isHidingPasswords());
109  setHideServerPassword(passCfg.isHidingPasswords());
110 }
111 
112 QStringList CFGIRCDefineNetworkDialog::formatOffenders(const QStringList &offenders) const
113 {
114  QStringList offendersFormatted;
115  for (const QString &offender : offenders)
116  {
117  offendersFormatted << tr("\t%1 (...)").arg(offender.left(40));
118  }
119  return offendersFormatted;
120 }
121 
122 IRCNetworkEntity CFGIRCDefineNetworkDialog::getNetworkEntity() const
123 {
124  IRCNetworkEntity entity;
125 
126  QString autojoinChannels = d->teAutojoinChannels->toPlainText();
127  autojoinChannels.remove('\r').replace('\n', ' ');
128 
129  entity.setAddress(d->leAddress->text().trimmed());
130  entity.setAutojoinChannels(autojoinChannels.split(" ", Qt::SkipEmptyParts));
131  entity.setAutojoinCommands(autojoinCommands());
132  entity.setDescription(d->leDescription->text().trimmed());
133  entity.setNickservCommand(d->leNickservCommand->text().trimmed());
134  entity.setNickservPassword(d->leNickservPassword->text());
135  entity.setPassword(d->leServerPassword->text());
136  entity.setPort(d->spinPort->value());
137 
138  return entity;
139 }
140 
141 void CFGIRCDefineNetworkDialog::initFrom(const IRCNetworkEntity &networkEntity)
142 {
143  d->originalDescription = networkEntity.description();
144  d->leAddress->setText(networkEntity.address());
145  d->teAutojoinChannels->setPlainText(networkEntity.autojoinChannels().join(" "));
146  d->teAutojoinCommands->setPlainText(networkEntity.autojoinCommands().join("\n"));
147  d->leDescription->setText(networkEntity.description());
148  d->leNickservCommand->setText(networkEntity.nickservCommand());
149  d->leNickservPassword->setText(networkEntity.nickservPassword());
150  d->leServerPassword->setText(networkEntity.password());
151  d->spinPort->setValue(networkEntity.port());
152 }
153 
154 bool CFGIRCDefineNetworkDialog::isDescriptionUnique() const
155 {
156  QString current = d->leDescription->text().trimmed().toLower();
157  if (d->originalDescription.trimmed().toLower() == current)
158  {
159  // Network is being edited and its name hasn't been changed.
160  return true;
161  }
162  for (const IRCNetworkEntity &network : listExistingNetworks())
163  {
164  if (network.description().trimmed().toLower() == current)
165  return false;
166  }
167  return true;
168 }
169 
170 bool CFGIRCDefineNetworkDialog::isValidDescription() const
171 {
172  return ChatNetworkNamer::isValidName(d->leDescription->text());
173 }
174 
175 QList<IRCNetworkEntity> CFGIRCDefineNetworkDialog::listExistingNetworks() const
176 {
177  if (!d->existingNetworks.isEmpty())
178  return d->existingNetworks;
179  else
180  return ChatNetworksCfg().networks();
181 }
182 
183 QStringList CFGIRCDefineNetworkDialog::validateAutojoinCommands() const
184 {
185  QStringList offenders;
186  for (const QString &command : autojoinCommands())
187  {
188  if (command.toUtf8().length() > PrivData<CFGIRCDefineNetworkDialog>::MAX_IRC_COMMAND_LENGTH)
189  offenders << command;
190  }
191  return offenders;
192 }
193 
194 void CFGIRCDefineNetworkDialog::setExistingNetworks(const QList<IRCNetworkEntity> &networks)
195 {
196  d->existingNetworks = networks;
197 }
198 
199 void CFGIRCDefineNetworkDialog::setHideNickservPassword(bool hide)
200 {
201  d->cbHideNickservPassword->blockSignals(true);
202  d->cbHideNickservPassword->setChecked(hide);
203  d->cbHideNickservPassword->blockSignals(false);
204  d->leNickservPassword->setEchoMode(hide ? QLineEdit::Password : QLineEdit::Normal);
205 }
206 
207 void CFGIRCDefineNetworkDialog::setHideServerPassword(bool hide)
208 {
209  d->cbHideServerPassword->blockSignals(true);
210  d->cbHideServerPassword->setChecked(hide);
211  d->cbHideServerPassword->blockSignals(false);
212  d->leServerPassword->setEchoMode(hide ? QLineEdit::Password : QLineEdit::Normal);
213 }
214 
215 bool CFGIRCDefineNetworkDialog::validateDescription()
216 {
217  if (d->leDescription->text().trimmed().isEmpty())
218  {
219  QMessageBox::critical(this, tr("Invalid IRC network description"),
220  tr("Network description cannot be empty."));
221  return false;
222  }
223  if (!isDescriptionUnique())
224  {
225  QMessageBox::critical(this, tr("Invalid IRC network description"),
226  tr("There already is a network with such description."));
227  return false;
228  }
229  if (!isValidDescription())
230  {
231  QString msg = tr("Network description is invalid.\n\n"
232  "Only letters, digits, spaces and \"%1\" are allowed.")
233  .arg(ChatNetworkNamer::additionalAllowedChars());
234  QMessageBox::critical(this, tr("Invalid IRC network description"), msg);
235  return false;
236  }
237  return true;
238 }