cfgcustomservers.cpp
1 //------------------------------------------------------------------------------
2 // cfgcustomservers.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) 2009 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "configuration/doomseekerconfig.h"
24 #include "cfgcustomservers.h"
25 #include "ui_cfgcustomservers.h"
26 #include "plugins/engineplugin.h"
27 #include "plugins/pluginloader.h"
28 #include <QHeaderView>
29 #include <QMessageBox>
30 #include <QStandardItemModel>
31 #include <QUrl>
32 
33 const // clear warnings
34 #include "unknownengine.xpm"
35 
36 DClass<CFGCustomServers> : public Ui::CFGCustomServers
37 {
38 public:
39  QStandardItemModel* model;
40 };
41 
42 DPointered(CFGCustomServers)
43 
44 CFGCustomServers::CFGCustomServers(QWidget *parent)
45 : ConfigPage(parent)
46 {
47  d->setupUi(this);
48 
49  connect(d->btnAdd, SIGNAL( clicked() ), this, SLOT( add() ));
50  connect(d->btnDisableSelected, SIGNAL( clicked() ), this, SLOT( disableSelected() ));
51  connect(d->btnEnableSelected, SIGNAL( clicked() ), this, SLOT( enableSelected() ));
52  connect(d->btnRemove, SIGNAL( clicked() ), this, SLOT( remove() ));
53  connect(d->btnSetEngine, SIGNAL( clicked() ), this, SLOT( setEngine() ));
54 
55  prepareEnginesComboBox();
56 }
57 
58 CFGCustomServers::~CFGCustomServers()
59 {
60 }
61 
62 void CFGCustomServers::add()
63 {
64  int pluginIndex = d->cboEngines->itemData(d->cboEngines->currentIndex()).toInt();
65  const EnginePlugin* plugin = gPlugins->info(pluginIndex);
66 
67  QString engineName = d->cboEngines->itemText(d->cboEngines->currentIndex());
68 
69  add(engineName, "", plugin->data()->defaultServerPort, true);
70 }
71 
72 void CFGCustomServers::add(const QString& engineName, const QString& host,
73  unsigned short port, bool enabled)
74 {
75  QList<QStandardItem* > record;
76 
77  QStandardItem* engineItem = new QStandardItem();
78  setEngineOnItem(engineItem, engineName);
79 
80  QString portString = QString::number(port);
81 
82  record.append(engineItem);
83  record.append(new QStandardItem(host));
84  record.append(new QStandardItem(portString));
85 
86  QStandardItem *enabledItem = new QStandardItem();
87  enabledItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
88  enabledItem->setCheckable(true);
89  enabledItem->setToolTip(tr("Toggle enabled state"));
90  record.append(enabledItem);
91 
92  d->model->appendRow(record);
93  d->tvServers->resizeRowsToContents();
94 }
95 
96 CFGCustomServers::CheckAndFixPorts CFGCustomServers::checkAndFixPorts(int firstRow, int lastRow)
97 {
98  CheckAndFixPorts returnValue = AllOk;
99  for (int rowIndex = firstRow; rowIndex <= lastRow; ++rowIndex)
100  {
101  if (!isPortCorrect(rowIndex))
102  {
103  returnValue = AtLeastOneFixed;
104 
105  setPortToDefault(rowIndex);
106  }
107  }
108 
109  return returnValue;
110 }
111 
112 void CFGCustomServers::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
113 {
114  const QString MESSAGE_TITLE = tr("Doomseeker - pinned servers");
115 
116  int leftmostColumn = topLeft.column();
117  int rightmostColumn = bottomRight.column();
118 
119  if ( isPortColumnWithinRange(leftmostColumn, rightmostColumn) )
120  {
121  switch ( checkAndFixPorts(topLeft.row(), bottomRight.row()) )
122  {
123  case AllOk:
124  // Ignore
125  break;
126 
127  case AtLeastOneFixed:
128  QMessageBox::warning(this, MESSAGE_TITLE, tr("Port must be within range 1 - 65535"));
129  break;
130 
131  default:
132  QMessageBox::warning(this, MESSAGE_TITLE, tr("Unimplemented behavior!"));
133  break;
134  }
135  }
136 }
137 
138 void CFGCustomServers::disableSelected()
139 {
140  setEnabledOnSelected(false);
141 }
142 
143 void CFGCustomServers::enableSelected()
144 {
145  setEnabledOnSelected(true);
146 }
147 
148 void CFGCustomServers::setEnabledOnSelected(bool enabled)
149 {
150  QItemSelectionModel* sel = d->tvServers->selectionModel();
151  QModelIndexList indexList = sel->selectedRows();
152 
153  QModelIndexList::iterator it;
154  for (it = indexList.begin(); it != indexList.end(); ++it)
155  {
156  QStandardItem* item = d->model->itemFromIndex(it->sibling(it->row(), EnabledIndex));
157  item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
158  }
159 }
160 
161 const EnginePlugin* CFGCustomServers::getPluginInfoForRow(int rowIndex)
162 {
163  QStandardItem* itemEngine = d->model->item(rowIndex, EngineColumnIndex);
164  QString engineName = itemEngine->data().toString();
165  int pluginIndex = gPlugins->pluginIndexFromName(engineName);
166  return gPlugins->info(pluginIndex);
167 }
168 
169 bool CFGCustomServers::isPortColumnWithinRange(int leftmostColumnIndex, int rightmostColumnIndex)
170 {
171  return leftmostColumnIndex <= PortColumnIndex && rightmostColumnIndex >= PortColumnIndex;
172 }
173 
174 bool CFGCustomServers::isPortCorrect(int rowIndex)
175 {
176  const int MIN_PORT = 1;
177  const int MAX_PORT = 65535;
178 
179  QStandardItem* item = d->model->item(rowIndex, PortColumnIndex);
180  bool ok;
181  int port = item->text().toInt(&ok);
182 
183  return ok && port >= MIN_PORT && port <= MAX_PORT;
184 }
185 
186 void CFGCustomServers::prepareEnginesComboBox()
187 {
188  d->cboEngines->clear();
189 
190  for (unsigned i = 0; i < gPlugins->numPlugins(); ++i)
191  {
192  const EnginePlugin* plugin = gPlugins->info(i);
193  d->cboEngines->addItem(plugin->icon(), plugin->data()->name, i);
194  }
195 
196  if (d->cboEngines->count() > 0)
197  {
198  d->cboEngines->setCurrentIndex(0);
199  }
200 }
201 
202 void CFGCustomServers::prepareTable()
203 {
204  d->model = new QStandardItemModel(this);
205 
206  connect(d->model, SIGNAL( dataChanged(const QModelIndex&, const QModelIndex&) ), this, SLOT( dataChanged(const QModelIndex&, const QModelIndex&) ) );
207 
208  QStringList labels;
209  labels << "" << tr("Host") << tr("Port") << "";
210  d->model->setHorizontalHeaderLabels(labels);
211 
212  d->tvServers->setModel(d->model);
213 
214  d->tvServers->setColumnWidth(EngineColumnIndex, 23);
215  d->tvServers->setColumnWidth(AddressColumnIndex, 180);
216  d->tvServers->setColumnWidth(PortColumnIndex, 60);
217  d->tvServers->setColumnWidth(EnabledIndex, 30);
218 
219  QList<ColumnIndices> fixedSizeColumns;
220  fixedSizeColumns << EngineColumnIndex << EnabledIndex;
221  foreach (ColumnIndices columnIdx, fixedSizeColumns)
222  {
223 #if QT_VERSION >= 0x050000
224  d->tvServers->horizontalHeader()->setSectionResizeMode(columnIdx, QHeaderView::Fixed);
225 #else
226  d->tvServers->horizontalHeader()->setResizeMode(columnIdx, QHeaderView::Fixed);
227 #endif
228  }
229  d->tvServers->horizontalHeader()->setHighlightSections(false);
230 
231  d->tvServers->verticalHeader()->hide();
232 }
233 
235 {
236  prepareTable();
237 
238  QList<CustomServerInfo> customServersList = gConfig.doomseeker.customServers.toList();
239  QList<CustomServerInfo>::iterator it;
240  for (it = customServersList.begin(); it != customServersList.end(); ++it)
241  {
242  add(it->engine, it->host, it->port, it->enabled);
243  }
244 }
245 
246 void CFGCustomServers::remove()
247 {
248  QItemSelectionModel* selModel = d->tvServers->selectionModel();
249  QModelIndexList indexList = selModel->selectedRows();
250  selModel->clear();
251 
252  QList<QStandardItem*> itemList;
253  for (int i = 0; i < indexList.count(); ++i)
254  {
255  itemList << d->model->item(indexList[i].row(), 0);
256  }
257 
258  for (int i = 0; i < itemList.count(); ++i)
259  {
260  QModelIndex index = d->model->indexFromItem(itemList[i]);
261  d->model->removeRow(index.row());
262  }
263 }
264 
266 {
267  gConfig.doomseeker.customServers = this->tableGetServers();
268 }
269 
270 void CFGCustomServers::setEngine()
271 {
272  QItemSelectionModel* sel = d->tvServers->selectionModel();
273  QModelIndexList indexList = sel->selectedRows();
274 
275  QModelIndexList::iterator it;
276  for (it = indexList.begin(); it != indexList.end(); ++it)
277  {
278  QStandardItem* item = d->model->itemFromIndex(*it);
279  QString engineName = d->cboEngines->itemText(d->cboEngines->currentIndex());
280  setEngineOnItem(item, engineName);
281  }
282 }
283 
284 void CFGCustomServers::setEngineOnItem(QStandardItem* item, const QString& engineName)
285 {
286  int engineId = gPlugins->pluginIndexFromName(engineName);
287 
288  item->setData(engineName);
289  item->setToolTip(engineName);
290  if (engineId >= 0)
291  {
292  const EnginePlugin* plugin = gPlugins->info(engineId);
293  item->setIcon(plugin->icon());
294  }
295  else
296  {
297  item->setIcon(QPixmap(unknownengine_xpm));
298  }
299 
300  item->setEditable(false);
301  item->setText("");
302 }
303 
304 void CFGCustomServers::setPortToDefault(int rowIndex)
305 {
306  const EnginePlugin* pluginInfo = getPluginInfoForRow(rowIndex);
307  QString defaultPort = QString::number(pluginInfo->data()->defaultServerPort);
308 
309  QStandardItem* itemPort = d->model->item(rowIndex, PortColumnIndex);
310  itemPort->setText(defaultPort);
311 }
312 
313 QVector<CustomServerInfo> CFGCustomServers::tableGetServers()
314 {
315  QVector<CustomServerInfo> servers;
316  for (int i = 0; i < d->model->rowCount(); ++i)
317  {
318  CustomServerInfo customServer;
319 
320  QStandardItem* item = d->model->item(i, EngineColumnIndex);
321  customServer.engine = item->data().toString();
322 
323  customServer.engineIndex = gPlugins->pluginIndexFromName(customServer.engine);
324 
325  item = d->model->item(i, AddressColumnIndex);
326  customServer.host = item->text();
327 
328  item = d->model->item(i, PortColumnIndex);
329  customServer.port = item->text().toUShort();
330 
331  item = d->model->item(i, EnabledIndex);
332  customServer.enabled = (item->checkState() == Qt::Checked);
333 
334  servers << customServer;
335  }
336 
337  return servers;
338 }
void readSettings()
Reimplement this to read settings from config into widgets.
void saveSettings()
Reimplement this to write settings to config from widgets.
Base class for configuration pages.
Definition: configpage.h:44