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 "irc/chatnetworknamer.h"
27 #include "irc/configuration/chatnetworkscfg.h"
28 #include "irc/entities/ircnetworkentity.h"
29 #include "strings.hpp"
30 #include <cassert>
31 #include <QMessageBox>
32 
33 
34 DClass<CFGIRCDefineNetworkDialog> : public Ui::CFGIRCDefineNetworkDialog
35 {
36 public:
37  static const int MAX_IRC_COMMAND_LENGTH = 512;
38 
39  QList<IRCNetworkEntity> existingNetworks;
40  QString originalDescription;
41 };
42 
43 DPointered(CFGIRCDefineNetworkDialog)
44 
45 
46 CFGIRCDefineNetworkDialog::CFGIRCDefineNetworkDialog(const IRCNetworkEntity &initValuesEntity, QWidget *parent)
47  : QDialog(parent)
48 {
49  construct();
50 
51  initFrom(initValuesEntity);
52 }
53 
54 CFGIRCDefineNetworkDialog::CFGIRCDefineNetworkDialog(QWidget *parent)
55  : QDialog(parent)
56 {
57  construct();
58 }
59 
60 CFGIRCDefineNetworkDialog::~CFGIRCDefineNetworkDialog()
61 {
62 }
63 
64 void CFGIRCDefineNetworkDialog::accept()
65 {
66  if (!validateDescription())
67  return;
68  QStringList offenders = validateAutojoinCommands();
69  if (!offenders.isEmpty())
70  {
71  if (!askToAcceptAnywayWhenCommandsBad(offenders))
72  return;
73  }
74  QDialog::accept();
75 }
76 
77 bool CFGIRCDefineNetworkDialog::askToAcceptAnywayWhenCommandsBad(const QStringList &offenders)
78 {
79  assert(!offenders.isEmpty() && "no offenders");
80  QString header = tr("These commands have violated the IRC maximum byte "
82  QString footer = tr("\n\nIf saved, the script may not run properly.\n\n"
83  "Do you wish to save the script anyway?");
84  QStringList formattedOffenders = formatOffenders(offenders.mid(0, 10));
85  QString body = formattedOffenders.join("\n\n");
86  if (formattedOffenders.size() < offenders.size())
87  body += tr("\n\n... and %n more ...", "", offenders.size() - formattedOffenders.size());
88  QString msg = header + body + footer;
89  QMessageBox::StandardButton result = QMessageBox::warning(
90  this, tr("Doomseeker - IRC Commands Problem"), msg,
91  QMessageBox::Yes | QMessageBox::Cancel);
92  return result == QMessageBox::Yes;
93 }
94 
95 QStringList CFGIRCDefineNetworkDialog::autojoinCommands() const
96 {
97  return d->teAutojoinCommands->toPlainText().split("\n");
98 }
99 
100 void CFGIRCDefineNetworkDialog::buttonClicked(QAbstractButton *button)
101 {
102  auto pButton = (QPushButton *)button;
103  if (pButton == d->buttonBox->button(QDialogButtonBox::Ok))
104  this->accept();
105  else
106  this->reject();
107 }
108 
109 void CFGIRCDefineNetworkDialog::construct()
110 {
111  d->setupUi(this);
112 
113  connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(buttonClicked(QAbstractButton*)));
114 }
115 
116 QStringList CFGIRCDefineNetworkDialog::formatOffenders(const QStringList &offenders) const
117 {
118  QStringList offendersFormatted;
119  for (const QString &offender : offenders)
120  {
121  offendersFormatted << tr("\t%1 (...)").arg(offender.left(40));
122  }
123  return offendersFormatted;
124 }
125 
126 IRCNetworkEntity CFGIRCDefineNetworkDialog::getNetworkEntity() const
127 {
128  IRCNetworkEntity entity;
129 
130  QString autojoinChannels = d->teAutojoinChannels->toPlainText();
131  autojoinChannels.remove('\r').replace('\n', ' ');
132 
133  entity.setAddress(d->leAddress->text().trimmed());
134  entity.setAutojoinChannels(autojoinChannels.split(" ", Qt::SkipEmptyParts));
135  entity.setAutojoinCommands(autojoinCommands());
136  entity.setDescription(d->leDescription->text().trimmed());
137  entity.setNickservCommand(d->leNickservCommand->text().trimmed());
138  entity.setNickservPassword(d->leNickservPassword->text());
139  entity.setPassword(d->leServerPassword->text());
140  entity.setPort(d->spinPort->value());
141 
142  return entity;
143 }
144 
145 void CFGIRCDefineNetworkDialog::initFrom(const IRCNetworkEntity &networkEntity)
146 {
147  d->originalDescription = networkEntity.description();
148  d->leAddress->setText(networkEntity.address());
149  d->teAutojoinChannels->setPlainText(networkEntity.autojoinChannels().join(" "));
150  d->teAutojoinCommands->setPlainText(networkEntity.autojoinCommands().join("\n"));
151  d->leDescription->setText(networkEntity.description());
152  d->leNickservCommand->setText(networkEntity.nickservCommand());
153  d->leNickservPassword->setText(networkEntity.nickservPassword());
154  d->leServerPassword->setText(networkEntity.password());
155  d->spinPort->setValue(networkEntity.port());
156 }
157 
158 bool CFGIRCDefineNetworkDialog::isDescriptionUnique() const
159 {
160  QString current = d->leDescription->text().trimmed().toLower();
161  if (d->originalDescription.trimmed().toLower() == current)
162  {
163  // Network is being edited and its name hasn't been changed.
164  return true;
165  }
166  for (const IRCNetworkEntity &network : listExistingNetworks())
167  {
168  if (network.description().trimmed().toLower() == current)
169  return false;
170  }
171  return true;
172 }
173 
174 bool CFGIRCDefineNetworkDialog::isValidDescription() const
175 {
176  return ChatNetworkNamer::isValidName(d->leDescription->text());
177 }
178 
179 QList<IRCNetworkEntity> CFGIRCDefineNetworkDialog::listExistingNetworks() const
180 {
181  if (!d->existingNetworks.isEmpty())
182  return d->existingNetworks;
183  else
184  return ChatNetworksCfg().networks();
185 }
186 
187 QStringList CFGIRCDefineNetworkDialog::validateAutojoinCommands() const
188 {
189  QStringList offenders;
190  for (const QString &command : autojoinCommands())
191  {
192  if (command.toUtf8().length() > PrivData<CFGIRCDefineNetworkDialog>::MAX_IRC_COMMAND_LENGTH)
193  offenders << command;
194  }
195  return offenders;
196 }
197 
198 void CFGIRCDefineNetworkDialog::setExistingNetworks(const QList<IRCNetworkEntity> &networks)
199 {
200  d->existingNetworks = networks;
201 }
202 
203 bool CFGIRCDefineNetworkDialog::validateDescription()
204 {
205  if (d->leDescription->text().trimmed().isEmpty())
206  {
207  QMessageBox::critical(this, tr("Invalid IRC network description"),
208  tr("Network description cannot be empty."));
209  return false;
210  }
211  if (!isDescriptionUnique())
212  {
213  QMessageBox::critical(this, tr("Invalid IRC network description"),
214  tr("There already is a network with such description."));
215  return false;
216  }
217  if (!isValidDescription())
218  {
219  QString msg = tr("Network description is invalid.\n\n"
220  "Only letters, digits, spaces and \"%1\" are allowed.")
221  .arg(ChatNetworkNamer::additionalAllowedChars());
222  QMessageBox::critical(this, tr("Invalid IRC network description"), msg);
223  return false;
224  }
225  return true;
226 }