cfgircdefinenetworkdialog.cpp
1 //------------------------------------------------------------------------------
2 // cfgircdefinenetworkdialog.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program 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
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; 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/configuration/chatnetworkscfg.h"
27 #include "irc/entities/ircnetworkentity.h"
28 #include "irc/chatnetworknamer.h"
29 #include <QMessageBox>
30 #include <cassert>
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  {
67  return;
68  }
69  QStringList offenders = validateAutojoinCommands();
70  if (!offenders.isEmpty())
71  {
72  if (!askToAcceptAnywayWhenCommandsBad(offenders))
73  {
74  return;
75  }
76  }
77  QDialog::accept();
78 }
79 
80 bool CFGIRCDefineNetworkDialog::askToAcceptAnywayWhenCommandsBad(const QStringList& offenders)
81 {
82  assert(!offenders.isEmpty() && "no offenders");
83  QString header = tr("Following commands have violated the IRC maximum byte "
85  QString footer = tr("\n\nIf saved, the script may not run properly.\n\n"
86  "Do you wish to save the script anyway?");
87  QStringList formattedOffenders = formatOffenders(offenders.mid(0, 10));
88  QString body = formattedOffenders.join("\n\n");
89  if (formattedOffenders.size() < offenders.size())
90  {
91  body += tr("\n\n... and %n more ...", "", offenders.size() - formattedOffenders.size());
92  }
93  QString msg = header + body + footer;
94  QMessageBox::StandardButton result = QMessageBox::warning(
95  this, tr("Doomseeker - IRC Commands Problem"), msg,
96  QMessageBox::Yes | QMessageBox::Cancel);
97  return result == QMessageBox::Yes;
98 }
99 
100 QStringList CFGIRCDefineNetworkDialog::autojoinCommands() const
101 {
102  return d->teAutojoinCommands->toPlainText().split("\n");
103 }
104 
105 void CFGIRCDefineNetworkDialog::buttonClicked(QAbstractButton* button)
106 {
107  QPushButton* pButton = (QPushButton*)button;
108  if (pButton == d->buttonBox->button(QDialogButtonBox::Ok))
109  {
110  this->accept();
111  }
112  else
113  {
114  this->reject();
115  }
116 }
117 
118 void CFGIRCDefineNetworkDialog::construct()
119 {
120  d->setupUi(this);
121 
122  connect(d->buttonBox, SIGNAL( clicked(QAbstractButton*) ), SLOT( buttonClicked(QAbstractButton*) ) );
123 }
124 
125 QStringList CFGIRCDefineNetworkDialog::formatOffenders(const QStringList& offenders) const
126 {
127  QStringList offendersFormatted;
128  foreach (const QString& offender, offenders)
129  {
130  offendersFormatted << tr("\t%1 (...)").arg(offender.left(40));
131  }
132  return offendersFormatted;
133 }
134 
135 IRCNetworkEntity CFGIRCDefineNetworkDialog::getNetworkEntity() const
136 {
137  IRCNetworkEntity entity;
138 
139  QString autojoinChannels = d->teAutojoinChannels->toPlainText();
140  autojoinChannels.remove('\r').replace('\n', ' ');
141 
142  entity.setAddress(d->leAddress->text().trimmed());
143  entity.setAutojoinChannels(autojoinChannels.split(" ", QString::SkipEmptyParts));
144  entity.setAutojoinCommands(autojoinCommands());
145  entity.setDescription(d->leDescription->text().trimmed());
146  entity.setNickservCommand(d->leNickservCommand->text().trimmed());
147  entity.setNickservPassword(d->leNickservPassword->text());
148  entity.setPassword(d->leServerPassword->text());
149  entity.setPort(d->spinPort->value());
150 
151  return entity;
152 }
153 
154 void CFGIRCDefineNetworkDialog::initFrom(const IRCNetworkEntity& networkEntity)
155 {
156  d->originalDescription = networkEntity.description();
157  d->leAddress->setText(networkEntity.address());
158  d->teAutojoinChannels->setPlainText(networkEntity.autojoinChannels().join(" "));
159  d->teAutojoinCommands->setPlainText(networkEntity.autojoinCommands().join("\n"));
160  d->leDescription->setText(networkEntity.description());
161  d->leNickservCommand->setText(networkEntity.nickservCommand());
162  d->leNickservPassword->setText(networkEntity.nickservPassword());
163  d->leServerPassword->setText(networkEntity.password());
164  d->spinPort->setValue(networkEntity.port());
165 }
166 
167 bool CFGIRCDefineNetworkDialog::isDescriptionUnique() const
168 {
169  QString current = d->leDescription->text().trimmed().toLower();
170  if (d->originalDescription.trimmed().toLower() == current)
171  {
172  // Network is being edited and its name hasn't been changed.
173  return true;
174  }
175  foreach (const IRCNetworkEntity &network, listExistingNetworks())
176  {
177  if (network.description().trimmed().toLower() == current)
178  {
179  return false;
180  }
181  }
182  return true;
183 }
184 
185 bool CFGIRCDefineNetworkDialog::isValidDescription() const
186 {
187  return ChatNetworkNamer::isValidName(d->leDescription->text());
188 }
189 
190 QList<IRCNetworkEntity> CFGIRCDefineNetworkDialog::listExistingNetworks() const
191 {
192  if (!d->existingNetworks.isEmpty())
193  {
194  return d->existingNetworks;
195  }
196  else
197  {
198  return ChatNetworksCfg().networks();
199  }
200 }
201 
202 QStringList CFGIRCDefineNetworkDialog::validateAutojoinCommands() const
203 {
204  QStringList offenders;
205  foreach (const QString& command, autojoinCommands())
206  {
207  if (command.toUtf8().length() > PrivData<CFGIRCDefineNetworkDialog>::MAX_IRC_COMMAND_LENGTH)
208  {
209  offenders << command;
210  }
211  }
212  return offenders;
213 }
214 
215 void CFGIRCDefineNetworkDialog::setExistingNetworks(const QList<IRCNetworkEntity> &networks)
216 {
217  d->existingNetworks = networks;
218 }
219 
220 bool CFGIRCDefineNetworkDialog::validateDescription()
221 {
222  if (d->leDescription->text().trimmed().isEmpty())
223  {
224  QMessageBox::critical(this, tr("Invalid network description"),
225  tr("Network description cannot be empty."));
226  return false;
227  }
228  if (!isDescriptionUnique())
229  {
230  QMessageBox::critical(this, tr("Invalid network description"),
231  tr("There already is a network with such description."));
232  return false;
233  }
234  if (!isValidDescription())
235  {
236  QString msg = tr("Network description is invalid.\n\n"
237  "Only letters, digits, spaces and \"%1\" are allowed.")
238  .arg(ChatNetworkNamer::additionalAllowedChars());
239  QMessageBox::critical(this, tr("Invalid network description"), msg);
240  return false;
241  }
242  return true;
243 }
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).
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.