cfgcustomservers.cpp
1 //------------------------------------------------------------------------------
2 // cfgcustomservers.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) 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 };
39 
40 DPointered(CFGCustomServers)
41 
42 CFGCustomServers::CFGCustomServers(QWidget *parent)
43 : ConfigurationBaseBox(parent)
44 {
45  d->setupUi(this);
46 
47  connect(d->btnAdd, SIGNAL( clicked() ), this, SLOT( add() ));
48  connect(d->btnRemove, SIGNAL( clicked() ), this, SLOT( remove() ));
49  connect(d->btnSetEngine, SIGNAL( clicked() ), this, SLOT( setEngine() ));
50 
51  prepareEnginesComboBox();
52 }
53 
54 CFGCustomServers::~CFGCustomServers()
55 {
56 }
57 
58 void CFGCustomServers::add()
59 {
60  int pluginIndex = d->cboEngines->itemData(d->cboEngines->currentIndex()).toInt();
61  const EnginePlugin* plugin = gPlugins->info(pluginIndex);
62 
63  QString engineName = d->cboEngines->itemText(d->cboEngines->currentIndex());
64 
65  add(engineName, "", plugin->data()->defaultServerPort);
66 }
67 
68 void CFGCustomServers::add(const QString& engineName, const QString& host, unsigned short port)
69 {
70  QList<QStandardItem* > record;
71 
72  QStandardItem* engineItem = new QStandardItem();
73  setEngineOnItem(engineItem, engineName);
74 
75  QString portString = QString::number(port);
76 
77  record.append(engineItem);
78  record.append(new QStandardItem(host));
79  record.append(new QStandardItem(portString));
80 
81  model->appendRow(record);
82  d->tvServers->resizeRowsToContents();
83 }
84 
85 CFGCustomServers::CheckAndFixPorts CFGCustomServers::checkAndFixPorts(int firstRow, int lastRow)
86 {
87  CheckAndFixPorts returnValue = AllOk;
88  for (int rowIndex = firstRow; rowIndex <= lastRow; ++rowIndex)
89  {
90  if (!isPortCorrect(rowIndex))
91  {
92  returnValue = AtLeastOneFixed;
93 
94  setPortToDefault(rowIndex);
95  }
96  }
97 
98  return returnValue;
99 }
100 
101 void CFGCustomServers::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
102 {
103  const QString MESSAGE_TITLE = tr("Doomseeker - custom servers");
104 
105  int leftmostColumn = topLeft.column();
106  int rightmostColumn = bottomRight.column();
107 
108  if ( isPortColumnWithingRange(leftmostColumn, rightmostColumn) )
109  {
110  switch ( checkAndFixPorts(topLeft.row(), bottomRight.row()) )
111  {
112  case AllOk:
113  // Ignore
114  break;
115 
116  case AtLeastOneFixed:
117  QMessageBox::warning(this, MESSAGE_TITLE, tr("Port must be within range 1 - 65535"));
118  break;
119 
120  default:
121  QMessageBox::warning(this, MESSAGE_TITLE, tr("Unimplemented behavior!"));
122  break;
123  }
124  }
125 }
126 
127 const EnginePlugin* CFGCustomServers::getPluginInfoForRow(int rowIndex)
128 {
129  QStandardItem* itemEngine = model->item(rowIndex, EngineColumnIndex);
130  QString engineName = itemEngine->data().toString();
131  int pluginIndex = gPlugins->pluginIndexFromName(engineName);
132  return gPlugins->info(pluginIndex);
133 }
134 
135 bool CFGCustomServers::isPortColumnWithingRange(int leftmostColumnIndex, int rightmostColumnIndex)
136 {
137  return leftmostColumnIndex <= PortColumnIndex && rightmostColumnIndex >= PortColumnIndex;
138 }
139 
140 bool CFGCustomServers::isPortCorrect(int rowIndex)
141 {
142  const int MIN_PORT = 1;
143  const int MAX_PORT = 65535;
144 
145  QStandardItem* item = model->item(rowIndex, PortColumnIndex);
146  bool ok;
147  int port = item->text().toInt(&ok);
148 
149  return ok && port >= MIN_PORT && port <= MAX_PORT;
150 }
151 
152 void CFGCustomServers::prepareEnginesComboBox()
153 {
154  d->cboEngines->clear();
155 
156  for (unsigned i = 0; i < gPlugins->numPlugins(); ++i)
157  {
158  const EnginePlugin* plugin = gPlugins->info(i);
159  d->cboEngines->addItem(plugin->icon(), plugin->data()->name, i);
160  }
161 
162  if (d->cboEngines->count() > 0)
163  {
164  d->cboEngines->setCurrentIndex(0);
165  }
166 }
167 
168 void CFGCustomServers::prepareTable()
169 {
170  model = new QStandardItemModel(this);
171 
172  connect(model, SIGNAL( dataChanged(const QModelIndex&, const QModelIndex&) ), this, SLOT( dataChanged(const QModelIndex&, const QModelIndex&) ) );
173 
174  QStringList labels;
175  labels << "" << tr("Host") << tr("Port");
176  model->setHorizontalHeaderLabels(labels);
177 
178  d->tvServers->setModel(model);
179 
180  d->tvServers->setColumnWidth(0, 23);
181  d->tvServers->setColumnWidth(1, 180);
182  d->tvServers->setColumnWidth(2, 60);
183 
184  d->tvServers->horizontalHeader()->setHighlightSections(false);
185  d->tvServers->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
186 
187  d->tvServers->verticalHeader()->hide();
188 }
189 
191 {
192  prepareTable();
193 
194  QList<CustomServerInfo> customServersList = gConfig.doomseeker.customServers.toList();
195  QList<CustomServerInfo>::iterator it;
196  for (it = customServersList.begin(); it != customServersList.end(); ++it)
197  {
198  add(it->engine, it->host, it->port);
199  }
200 }
201 
202 void CFGCustomServers::remove()
203 {
204  QItemSelectionModel* selModel = d->tvServers->selectionModel();
205  QModelIndexList indexList = selModel->selectedRows();
206  selModel->clear();
207 
208  QList<QStandardItem*> itemList;
209  for (int i = 0; i < indexList.count(); ++i)
210  {
211  itemList << model->item(indexList[i].row(), 0);
212  }
213 
214  for (int i = 0; i < itemList.count(); ++i)
215  {
216  QModelIndex index = model->indexFromItem(itemList[i]);
217  model->removeRow(index.row());
218  }
219 }
220 
222 {
223  gConfig.doomseeker.customServers = this->tableGetServers();
224 }
225 
226 void CFGCustomServers::setEngine()
227 {
228  QItemSelectionModel* sel = d->tvServers->selectionModel();
229  QModelIndexList indexList = sel->selectedRows();
230 
231  QModelIndexList::iterator it;
232  for (it = indexList.begin(); it != indexList.end(); ++it)
233  {
234  QStandardItem* item = model->itemFromIndex(*it);
235  QString engineName = d->cboEngines->itemText(d->cboEngines->currentIndex());
236  setEngineOnItem(item, engineName);
237  }
238 }
239 
240 void CFGCustomServers::setEngineOnItem(QStandardItem* item, const QString& engineName)
241 {
242  int engineId = gPlugins->pluginIndexFromName(engineName);
243 
244  item->setData(engineName);
245  item->setToolTip(engineName);
246  if (engineId >= 0)
247  {
248  const EnginePlugin* plugin = gPlugins->info(engineId);
249  item->setIcon(plugin->icon());
250  }
251  else
252  {
253  item->setIcon(QPixmap(unknownengine_xpm));
254  }
255 
256  item->setEditable(false);
257  item->setText("");
258 }
259 
260 void CFGCustomServers::setPortToDefault(int rowIndex)
261 {
262  const EnginePlugin* pluginInfo = getPluginInfoForRow(rowIndex);
263  QString defaultPort = QString::number(pluginInfo->data()->defaultServerPort);
264 
265  QStandardItem* itemPort = model->item(rowIndex, PortColumnIndex);
266  itemPort->setText(defaultPort);
267 }
268 
269 QVector<CustomServerInfo> CFGCustomServers::tableGetServers()
270 {
271  QVector<CustomServerInfo> servers;
272  for (int i = 0; i < model->rowCount(); ++i)
273  {
274  CustomServerInfo customServer;
275 
276  QStandardItem* item = model->item(i, EngineColumnIndex);
277  customServer.engine = item->data().toString();
278 
279  customServer.engineIndex = gPlugins->pluginIndexFromName(customServer.engine);
280 
281  item = model->item(i, AddressColumnIndex);
282  customServer.host = item->text();
283 
284  item = model->item(i, PortColumnIndex);
285  customServer.port = item->text().toUShort();
286 
287  servers << customServer;
288  }
289 
290  return servers;
291 }
void readSettings()
Reimplement this to read settings from config into widgets.
CheckAndFixPorts checkAndFixPorts(int firstRow, int lastRow)
Moves through rows and checks if network port information is correct.
void saveSettings()
Reimplement this to write settings to config from widgets.
Base class for configuration pages.