generalgamesetuppanel.cpp
1 //------------------------------------------------------------------------------
2 // generalgamesetuppanel.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) 2014 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "generalgamesetuppanel.h"
24 #include "ui_generalgamesetuppanel.h"
25 
26 #include "configuration/doomseekerconfig.h"
27 #include "gui/createserver/maplistpanel.h"
28 #include "gui/createserverdialog.h"
29 #include "ini/ini.h"
30 #include "plugins/engineplugin.h"
31 #include "serverapi/gamecreateparams.h"
32 #include "serverapi/gameexefactory.h"
33 #include "serverapi/gamefile.h"
34 #include "filefilter.h"
35 #include <QFileDialog>
36 #include <QFileInfo>
37 #include <QMessageBox>
38 #include <QTimer>
39 #include <cassert>
40 
41 DClass<GeneralGameSetupPanel> : public Ui::GeneralGameSetupPanel
42 {
43 public:
44  EnginePlugin *currentEngine;
45  bool iwadSetExplicitly;
46  CreateServerDialog *parentDialog;
47  bool remoteGameSetup;
48 };
49 
50 DPointered(GeneralGameSetupPanel)
51 
52 
54 : QWidget(parent)
55 {
56  d->setupUi(this);
57  d->iwadSetExplicitly = false;
58  d->remoteGameSetup = false;
59  d->parentDialog = NULL;
60 
61  d->executableInput->setAllowedExecutables(GameFile::CreateGame);
62 
63  this->connect(d->cboEngine, SIGNAL(currentPluginChanged(EnginePlugin*)),
64  SIGNAL(pluginChanged(EnginePlugin*)));
65 }
66 
67 GeneralGameSetupPanel::~GeneralGameSetupPanel()
68 {
69 }
70 
71 void GeneralGameSetupPanel::fillInParams(GameCreateParams &params)
72 {
73  params.setExecutablePath(pathToExe());
74  params.setIwadPath(d->iwadPicker->currentIwad());
75  params.setPwadsPaths(d->wadsPicker->filePaths());
76  params.setPwadsOptional(d->wadsPicker->fileOptional());
77  params.setBroadcastToLan(d->cbBroadcastToLAN->isChecked());
78  params.setBroadcastToMaster(d->cbBroadcastToMaster->isChecked());
79  params.setMap(d->leMap->text());
80  params.setName(d->leServername->text());
81  params.setPort(d->spinPort->isEnabled() ? d->spinPort->value() : 0);
82  params.setGameMode(currentGameMode());
83  params.setSkill(d->cboDifficulty->itemData(d->cboDifficulty->currentIndex()).toInt());
84  params.setUpnp(d->cbUpnp->isChecked());
85  params.setUpnpPort(d->spinUpnpPort->value());
86 }
87 
88 void GeneralGameSetupPanel::loadConfig(Ini &config, bool loadingPrevious)
89 {
90  IniSection general = config.section("General");
91 
92  // General
93  if (!d->remoteGameSetup)
94  {
95  QString currentExecutable = d->executableInput->path();
96  QString engineName = general["engine"];
97  const EnginePlugin* prevEngine = d->currentEngine;
98  if(!setEngine(engineName))
99  return;
100 
101  bool bChangeExecutable = (prevEngine != d->currentEngine || !d->cbLockExecutable->isChecked());
102  QString executablePath = *general["executable"];
103  QFileInfo fileInfo(executablePath);
104  if (!executablePath.isEmpty() && fileInfo.isFile() && bChangeExecutable)
105  {
106  d->executableInput->setPath(executablePath);
107  }
108  else if (!bChangeExecutable)
109  {
110  d->executableInput->setPath(currentExecutable);
111  }
112  }
113 
114  d->leServername->setText(general["name"]);
115  d->spinPort->setValue(general["port"]);
116 
117  int gameModeIndex = d->cboGamemode->findData(static_cast<gamemode_id>(general["gamemode"]));
118  if (gameModeIndex >= 0)
119  d->cboGamemode->setCurrentIndex(gameModeIndex);
120 
121  int difficultyIndex = d->cboDifficulty->findData(static_cast<int>(general["difficulty"]));
122  d->cboDifficulty->setCurrentIndex(qMax(0, difficultyIndex));
123 
124 
125  d->leMap->setText(general["map"]);
126 
127  if (!(loadingPrevious && d->iwadSetExplicitly))
128  {
129  d->iwadPicker->addIwad(general["iwad"]);
130  }
131 
132  QList<bool> optionalWads;
133  foreach(QString value, general["pwadsOptional"].valueString().split(";"))
134  {
135  optionalWads << (value != "0");
136  }
137  d->wadsPicker->setFilePaths(general["pwads"].valueString().split(";"), optionalWads);
138 
139  d->cbBroadcastToLAN->setChecked(general["broadcastToLAN"]);
140  d->cbBroadcastToMaster->setChecked(general["broadcastToMaster"]);
141  d->cbUpnp->setChecked(general["upnp"]);
142  d->spinUpnpPort->setValue(general["upnpPort"]);
143 
144  // Timer triggers slot after config is fully loaded.
145  QTimer::singleShot(0, this, SLOT(updateMapWarningVisibility()));
146 }
147 
148 void GeneralGameSetupPanel::saveConfig(Ini &config)
149 {
150  IniSection general = config.section("General");
151  general["engine"] = d->cboEngine->currentText();
152  general["executable"] = pathToExe();
153  general["name"] = d->leServername->text();
154  general["port"] = d->spinPort->value();
155  general["gamemode"] = d->cboGamemode->itemData(d->cboGamemode->currentIndex()).toInt();
156  general["map"] = d->leMap->text();
157  general["difficulty"] = d->cboDifficulty->itemData(d->cboDifficulty->currentIndex()).toInt();
158  general["iwad"] = d->iwadPicker->currentIwad();
159 
160  general["pwads"] = d->wadsPicker->filePaths().join(";");
161  QList<bool> optionalWads = d->wadsPicker->fileOptional();
162  QStringList optionalList;
163  foreach(bool optional, optionalWads)
164  optionalList << (optional ? "1" : "0");
165  general["pwadsOptional"] = optionalList.join(";");
166 
167  general["broadcastToLAN"] = d->cbBroadcastToLAN->isChecked();
168  general["broadcastToMaster"] = d->cbBroadcastToMaster->isChecked();
169  general["upnp"] = d->cbUpnp->isChecked();
170  general["upnpPort"] = d->spinUpnpPort->value();
171 }
172 
173 void GeneralGameSetupPanel::reloadAppConfig()
174 {
175  d->executableInput->reloadExecutables();
176  d->iwadPicker->loadIwads();
177 }
178 
179 void GeneralGameSetupPanel::setupDifficulty(const EnginePlugin *engine)
180 {
181  QVariant oldDifficulty = d->cboDifficulty->itemData(d->cboDifficulty->currentIndex());
182  d->cboDifficulty->clear();
183 
184  QList<GameCVar> levels = engine->data()->difficulty->get(QVariant());
185  d->labelDifficulty->setVisible(!levels.isEmpty());
186  d->cboDifficulty->setVisible(!levels.isEmpty());
187  d->cboDifficulty->addItem(tr("< NONE >"), Skill::UNDEFINED);
188  foreach(const GameCVar &level, levels)
189  {
190  d->cboDifficulty->addItem(level.name(), level.value());
191  }
192  int memorizedIndex = d->cboDifficulty->findData(oldDifficulty);
193  if (memorizedIndex >= 0)
194  d->cboDifficulty->setCurrentIndex(memorizedIndex);
195 }
196 
197 void GeneralGameSetupPanel::setupForEngine(EnginePlugin *engine)
198 {
199  d->currentEngine = engine;
200 
201  d->labelIwad->setVisible(engine->data()->hasIwad);
202  d->iwadPicker->setVisible(engine->data()->hasIwad);
203  d->upnpArea->setVisible(engine->data()->allowsUpnp);
204  d->spinUpnpPort->setVisible(engine->data()->allowsUpnpPort);
205 
206  d->executableInput->setPlugin(engine);
207 
208  d->spinPort->setValue(d->currentEngine->data()->defaultServerPort);
209 
210  d->cboGamemode->clear();
211  d->cboGamemode->addItem(tr("< NONE >"), GameMode::SGM_Unknown);
212 
213  QList<GameMode> gameModes = d->currentEngine->gameModes();
214  for (int i = 0; i < gameModes.count(); ++i)
215  {
216  d->cboGamemode->addItem(gameModes[i].name(), gameModes[i].index());
217  }
218  setupDifficulty(engine);
219 }
220 
221 void GeneralGameSetupPanel::setupForRemoteGame()
222 {
223  d->remoteGameSetup = true;
224  d->cbAllowTheGameToChoosePort->hide();
225  QWidget *disableControls[] =
226  {
227  d->cboEngine, d->leServername, d->spinPort,
228  d->cbBroadcastToLAN, d->cbBroadcastToMaster,
229  d->upnpArea,
230 
231  NULL
232  };
233  for(int i = 0;disableControls[i] != NULL;++i)
234  disableControls[i]->setDisabled(true);
235 }
236 
237 void GeneralGameSetupPanel::setCreateServerDialog(CreateServerDialog *dialog)
238 {
239  d->parentDialog = dialog;
240 }
241 
242 void GeneralGameSetupPanel::setIwadByName(const QString &iwad)
243 {
244  d->iwadSetExplicitly = true;
245  d->iwadPicker->setIwadByName(iwad);
246 }
247 
248 void GeneralGameSetupPanel::showEvent(QShowEvent *event)
249 {
250  updateMapWarningVisibility();
251 }
252 
253 QString GeneralGameSetupPanel::mapName() const
254 {
255  return d->leMap->text();
256 }
257 
258 QString GeneralGameSetupPanel::pathToExe()
259 {
260  return d->executableInput->path();
261 }
262 
263 void GeneralGameSetupPanel::onGameModeChanged(int index)
264 {
265  if (index >= 0)
266  {
267  emit gameModeChanged(currentGameMode());
268  }
269 }
270 
271 GameMode GeneralGameSetupPanel::currentGameMode() const
272 {
273  QList<GameMode> gameModes = d->currentEngine->gameModes();
274  foreach (const GameMode& mode, gameModes)
275  {
276  if (mode.index() == d->cboGamemode->itemData(d->cboGamemode->currentIndex()).toInt())
277  {
278  return mode;
279  }
280  }
281  return GameMode::mkUnknown();
282 }
283 
284 EnginePlugin *GeneralGameSetupPanel::currentPlugin() const
285 {
286  return d->cboEngine->currentPlugin();
287 }
288 
289 bool GeneralGameSetupPanel::setEngine(const QString &engineName)
290 {
291  if (!d->cboEngine->setPluginByName(engineName))
292  {
293  QMessageBox::critical(this, tr("Doomseeker - load server config"),
294  tr("Plugin for engine \"%1\" is not present!").arg(engineName));
295  return false;
296  }
297  return true;
298 }
299 
300 void GeneralGameSetupPanel::updateMapWarningVisibility()
301 {
302  assert(d->parentDialog != NULL);
303  MapListPanel *mapList = d->parentDialog->mapListPanel();
304  d->lblMapWarning->setVisible(mapList->hasMaps() && !mapList->isMapOnList(mapName()));
305 }
const QString & name() const
Nice name to display to user in Create Game dialog and in other widgets.
Impossible to determine the game mode.
Game parametrization data used when creating new games.
static const unsigned char UNDEFINED
const QVariant & value() const
Passed as the second argument, following command().
QSharedPointer< GameCVarProvider > difficulty
Difficulty levels provider for this game.
Definition: engineplugin.h:327
Dialog window allowing user to create a game.
Game mode representation.
Configuration handler.
Definition: ini.h:69
INI section representation.
Definition: inisection.h:40
IniSection section(const QString &name)
Access configuration file section.
Definition: ini.cpp:95
gamemode_id index() const
Index, either a StandardGameMode or custom defined by plugin.
A general game setting or variable (like fraglimit).