cfgserverpasswords.cpp
1 //------------------------------------------------------------------------------
2 // cfgserverpasswords.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) 2013 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "cfgserverpasswords.h"
24 #include "ui_cfgserverpasswords.h"
25 
26 #include "configuration/passwordscfg.h"
27 #include "configuration/serverpassword.h"
28 #include "gui/commongui.h"
29 #include "gui/helpers/datetablewidgetitem.h"
30 #include <QMap>
31 
32 static const int COL_PASS_PASSWORD = 0;
33 static const int COL_PASS_LAST_GAME = 1;
34 static const int COL_PASS_LAST_SERVER = 2;
35 static const int COL_PASS_LAST_TIME = 3;
36 
37 static const int COL_SERV_GAME = 0;
38 static const int COL_SERV_NAME = 1;
39 static const int COL_SERV_ADDRESS = 2;
40 static const int COL_SERV_LAST_TIME = 3;
41 
42 static const QString HIDDEN_PASS = "***";
43 
44 DClass<CFGServerPasswords> : public Ui::CFGServerPasswords
45 {
46 public:
47 };
48 
49 DPointered(CFGServerPasswords)
50 
51 CFGServerPasswords::CFGServerPasswords(QWidget *parent)
52  : ConfigPage(parent)
53 {
54  d->setupUi(this);
55  hidePasswords();
56 
57  d->tablePasswords->sortItems(COL_PASS_LAST_TIME, Qt::DescendingOrder);
58  d->tablePasswords->setColumnWidth(COL_PASS_PASSWORD, 90);
59  d->tablePasswords->setColumnWidth(COL_PASS_LAST_TIME, 130);
60  QHeaderView *headerPasswords = d->tablePasswords->horizontalHeader();
61  headerPasswords->setSectionResizeMode(COL_PASS_LAST_SERVER, QHeaderView::Stretch);
62 
63  d->tableServers->sortItems(COL_SERV_GAME, Qt::AscendingOrder);
64  d->tableServers->setColumnWidth(COL_SERV_GAME, 90);
65  d->tableServers->setColumnWidth(COL_SERV_ADDRESS, 120);
66  d->tableServers->setColumnWidth(COL_PASS_LAST_TIME, 130);
67  QHeaderView *headerServers = d->tableServers->horizontalHeader();
68  headerServers->setSectionResizeMode(COL_SERV_NAME, QHeaderView::Stretch);
69 
70  d->selectedPasswordPanel->setEnabled(false);
71  d->lblServerLossWarning->setVisible(false);
72 }
73 
74 CFGServerPasswords::~CFGServerPasswords()
75 {
76 }
77 
78 void CFGServerPasswords::addPasswordFromLineEdit()
79 {
80  QString phrase = d->lePassword->text();
81  d->lePassword->clear();
82  if (!phrase.isEmpty() && !isPassphraseInTable(phrase))
83  {
84  ServerPassword password;
85  password.setPhrase(phrase);
86  addServerPasswordToTable(password);
87  }
88 }
89 
90 void CFGServerPasswords::addServerPasswordToTable(const ServerPassword &password)
91 {
92  int rowIndex = d->tablePasswords->rowCount();
93  d->tablePasswords->insertRow(rowIndex);
94  setPasswordInRow(rowIndex, password);
95 }
96 
97 void CFGServerPasswords::clearTable(QTableWidget *table)
98 {
99  while (table->rowCount() > 0)
100  {
101  table->removeRow(0);
102  }
103 }
104 
105 int CFGServerPasswords::findPassphraseInTable(const QString &phrase)
106 {
107  for (int i = 0; i < d->tablePasswords->rowCount(); ++i)
108  {
109  ServerPassword password = serverPasswordFromRow(i);
110  if (password.phrase() == phrase)
111  return i;
112  }
113  return -1;
114 }
115 
116 void CFGServerPasswords::hidePasswords()
117 {
118  d->cbHide->setChecked(true);
119  d->lePassword->setEchoMode(QLineEdit::Password);
120  for (int i = 0; i < d->tablePasswords->rowCount(); ++i)
121  {
122  QTableWidgetItem *item = d->tablePasswords->item(i, COL_PASS_PASSWORD);
123  item->setText(HIDDEN_PASS);
124  item->setToolTip(HIDDEN_PASS);
125  }
126 }
127 
128 bool CFGServerPasswords::isPassphraseInTable(const QString &phrase)
129 {
130  return findPassphraseInTable(phrase) >= 0;
131 }
132 
133 void CFGServerPasswords::onPasswordTableCellChange(int currentRow, int currentColumn,
134  int previousRow, int previousColumn)
135 {
136  Q_UNUSED(currentColumn);
137  Q_UNUSED(previousColumn);
138  if (currentRow != previousRow)
139  {
140  // Setting an invalid password will clear the table which is
141  // what we want.
142  setServersInTable(serverPasswordFromRow(currentRow));
143  }
144 }
145 
147 {
148  PasswordsCfg cfg;
149  QList<ServerPassword> passwords;
150  for (int i = 0; i < d->tablePasswords->rowCount(); ++i)
151  passwords << serverPasswordFromRow(i);
152  cfg.setServerPasswords(passwords);
153  cfg.setMaxNumberOfServersPerPassword(d->spinMaxPasswords->value());
154 }
155 
156 ServerPassword CFGServerPasswords::serverPasswordFromRow(int row)
157 {
158  if (row < 0 || row >= d->tablePasswords->rowCount())
159  return ServerPassword();
160  return ServerPassword::deserializeQVariant(
161  d->tablePasswords->item(row, COL_PASS_PASSWORD)->data(Qt::UserRole));
162 }
163 
164 void CFGServerPasswords::setPasswordInRow(int row, const ServerPassword &password)
165 {
166  // Disable sorting or bad things may happen.
167  bool wasSortingEnabled = d->tablePasswords->isSortingEnabled();
168  d->tablePasswords->setSortingEnabled(false);
169 
170  QString phrase;
171  if (d->cbHide->isChecked())
172  phrase = HIDDEN_PASS;
173  else
174  phrase = password.phrase();
175 
176  QTableWidgetItem *phraseItem = toolTipItem(phrase);
177  phraseItem->setData(Qt::UserRole, password.serializeQVariant());
178  d->tablePasswords->setItem(row, COL_PASS_PASSWORD, phraseItem);
179 
180  d->tablePasswords->setItem(row, COL_PASS_LAST_GAME, toolTipItem(password.lastGame()));
181  d->tablePasswords->setItem(row, COL_PASS_LAST_SERVER, toolTipItem(password.lastServerName()));
182 
183  DateTableWidgetItem *dateItem = new DateTableWidgetItem(password.lastTime());
184  dateItem->setToolTip(dateItem->displayedText());
185  d->tablePasswords->setItem(row, COL_PASS_LAST_TIME, dateItem);
186 
187  // Re-enable sorting if was enabled before.
188  d->tablePasswords->setSortingEnabled(wasSortingEnabled);
189  d->tablePasswords->resizeRowsToContents();
190 }
191 
192 void CFGServerPasswords::setServersInTable(const ServerPassword &password)
193 {
194  clearTable(d->tableServers);
195  d->selectedPasswordPanel->setEnabled(password.isValid());
196  if (!password.isValid())
197  return;
198 
199  // Disable sorting or bad things may happen.
200  d->tableServers->setSortingEnabled(false);
201  for (const ServerPasswordSummary &server : password.servers())
202  {
203  int rowIndex = d->tableServers->rowCount();
204  d->tableServers->insertRow(rowIndex);
205 
206  QTableWidgetItem *gameItem = toolTipItem(server.game());
207  gameItem->setData(Qt::UserRole, server.serializeQVariant());
208  d->tableServers->setItem(rowIndex, COL_SERV_GAME, gameItem);
209 
210  d->tableServers->setItem(rowIndex, COL_SERV_NAME, toolTipItem(server.name()));
211  QString address = QString("%1:%2").arg(server.address()).arg(server.port());
212  d->tableServers->setItem(rowIndex, COL_SERV_ADDRESS, toolTipItem(address));
213 
214  DateTableWidgetItem *dateItem = new DateTableWidgetItem(server.time());
215  dateItem->setToolTip(dateItem->displayedText());
216  d->tableServers->setItem(rowIndex, COL_SERV_LAST_TIME, dateItem);
217  }
218  // Re-enable sorting.
219  d->tableServers->setSortingEnabled(true);
220  d->tableServers->resizeRowsToContents();
221 }
222 
223 void CFGServerPasswords::showServerLossWarningIfNecessary()
224 {
225  PasswordsCfg cfg;
226  d->lblServerLossWarning->setVisible(d->spinMaxPasswords->value() <
227  cfg.maxNumberOfServersPerPassword());
228 }
229 
231 {
232  clearTable(d->tablePasswords);
233  clearTable(d->tableServers);
234 
235  PasswordsCfg cfg;
236  for (const ServerPassword &pass : cfg.serverPasswords())
237  {
238  addServerPasswordToTable(pass);
239  }
240  d->spinMaxPasswords->setValue(cfg.maxNumberOfServersPerPassword());
241 }
242 
243 void CFGServerPasswords::removeSelectedPasswords()
244 {
245  CommonGUI::removeSelectedRowsFromQTableWidget(d->tablePasswords);
246 }
247 
248 void CFGServerPasswords::removeSelectedServers()
249 {
250  QList<ServerPasswordSummary> servers;
251  for (QTableWidgetItem *item : d->tableServers->selectedItems())
252  {
253  if (item->column() == COL_SERV_GAME)
254  servers << ServerPasswordSummary::deserializeQVariant(item->data(Qt::UserRole));
255  }
256  ServerPassword currentPassword = serverPasswordFromRow(d->tablePasswords->currentRow());
257  for (const ServerPasswordSummary &server : servers)
258  {
259  currentPassword.removeServer(server.game(), server.address(), server.port());
260  }
261  updatePassword(currentPassword);
262  CommonGUI::removeSelectedRowsFromQTableWidget(d->tableServers);
263 }
264 
265 void CFGServerPasswords::revealPasswords()
266 {
267  d->cbHide->setChecked(false);
268  d->lePassword->setEchoMode(QLineEdit::Normal);
269  for (int i = 0; i < d->tablePasswords->rowCount(); ++i)
270  {
271  QTableWidgetItem *item = d->tablePasswords->item(i, COL_PASS_PASSWORD);
272  ServerPassword password = serverPasswordFromRow(i);
273  item->setText(password.phrase());
274  item->setToolTip(password.phrase());
275  }
276 }
277 
278 void CFGServerPasswords::setPasswordsHidden(bool hidden)
279 {
280  if (hidden)
281  hidePasswords();
282  else
283  revealPasswords();
284 }
285 
286 QTableWidgetItem *CFGServerPasswords::toolTipItem(const QString &contents)
287 {
288  auto item = new QTableWidgetItem(contents);
289  item->setToolTip(contents);
290  return item;
291 }
292 
293 void CFGServerPasswords::updatePassword(const ServerPassword &password)
294 {
295  int row = findPassphraseInTable(password.phrase());
296  if (row >= 0)
297  setPasswordInRow(row, password);
298  else
299  addServerPasswordToTable(password);
300 }