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