engineconfigpage.cpp
1 //------------------------------------------------------------------------------
2 // engineconfigpage.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) 2010 Braden "Blzut3" Obrzut <admin@maniacsvault.net>
22 //------------------------------------------------------------------------------
23 
24 #include "engineconfigpage.h"
25 #include "ui_engineconfigpage.h"
26 #include "gui/widgets/filepickwidget.h"
27 #include "ini/ini.h"
28 #include "plugins/engineplugin.h"
29 #include "serverapi/gameexefactory.h"
30 #include "serverapi/gamefile.h"
31 #include "filefilter.h"
32 
33 #include <QFileDialog>
34 #include <QTimer>
35 
36 DClass<EngineConfigPage> : public Ui::EngineConfigPage
37 {
38  public:
39  class KnownNeighbours : public FilePickWidget::NeighbourStrategy
40  {
41  public:
43  KnownNeighbours(DPtr< ::EngineConfigPage> *wrapper)
44  {
45  this->wrapper = wrapper;
46  }
47  QStringList neighbours()
48  {
49  return (*wrapper)->parent->collectKnownGameFilePaths();
50  }
51  };
52 
53 
54  ::EngineConfigPage *parent;
55  IniSection *config;
56  EnginePlugin *plugin;
57  bool clientOnly;
58  QList<FilePickWidget*> filePickers;
59  QTimer errorTimer;
60 
61  QStringList readStoredCustomParameters() const
62  {
63  return config->value("StoredCustomParameters").toStringList();
64  }
65 
66  void saveStoredCustomParameters(const QStringList &params)
67  {
68  config->setValue("StoredCustomParameters", params);
69  }
70 
71  bool existsInStoredCustomParameters(const QString &text) const
72  {
73  return readStoredCustomParameters().contains(text);
74  }
75 };
76 
77 DPointeredNoCopy(EngineConfigPage)
78 
79 
80 EngineConfigPage::EngineConfigPage(EnginePlugin *plugin, IniSection &cfg, QWidget *parent)
81 : ConfigPage(parent)
82 {
83  d->parent = this;
84  d->plugin = plugin;
85  d->config = &cfg;
86  d->setupUi(this);
87 
88  d->lblError->hide();
89  d->errorTimer.setInterval(5000);
90  d->errorTimer.setSingleShot(true);
91  this->connect(&d->errorTimer, SIGNAL(timeout()), d->lblError, SLOT(hide()));
92 
93  // Prevent combo box stretching.
94  d->cboCustomParameters->setMinimumContentsLength(25);
95  d->cboCustomParameters->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
96 
97  makeFileBrowsers();
98 
99  if(!plugin->data()->hasMasterClient())
100  d->masterAddressBox->hide();
101 }
102 
103 EngineConfigPage::~EngineConfigPage()
104 {
105 }
106 
107 void EngineConfigPage::addWidget(QWidget *widget)
108 {
109  layout()->removeItem(d->verticalSpacer);
110  layout()->addWidget(widget);
111  layout()->addItem(d->verticalSpacer);
112 }
113 
114 void EngineConfigPage::autoFindNeighbouringPaths()
115 {
116  FilePickWidget *picker = qobject_cast<FilePickWidget*>(sender());
117  if (QFileInfo(picker->path()).isFile())
118  {
119  QStringList knownPaths = collectKnownGameFilePaths();
120  foreach (FilePickWidget *picker, d->filePickers)
121  {
122  if (picker->isEmpty())
123  {
124  picker->blockSignals(true);
125  picker->findPath();
126  picker->blockSignals(false);
127  }
128  }
129  }
130  emit validationRequested();
131 }
132 
133 QStringList EngineConfigPage::collectKnownGameFilePaths() const
134 {
135  QStringList knownPaths;
136  foreach (const FilePickWidget *picker, d->filePickers)
137  {
138  if (!picker->isEmpty())
139  {
140  knownPaths << picker->path();
141  }
142  }
143  return knownPaths;
144 }
145 
146 QString EngineConfigPage::currentCustomParameters() const
147 {
148  return d->cboCustomParameters->currentText().trimmed();
149 }
150 
152 {
153  return d->plugin->icon();
154 }
155 
156 void EngineConfigPage::makeFileBrowsers()
157 {
158  QSharedPointer<FilePickWidget::NeighbourStrategy> neighbours(
160  QList<GameFile> files = d->plugin->gameExe()->gameFiles().asQList();
161  foreach (const GameFile &file, files)
162  {
163  FilePickWidget *widget = new FilePickWidget(d->exePickArea);
164  widget->setFile(file);
165  widget->setNeighbourStrategy(neighbours);
166  this->connect(widget, SIGNAL(findFailed()), SLOT(showFindFailError()));
167  this->connect(widget, SIGNAL(pathChanged()), SLOT(autoFindNeighbouringPaths()));
168  this->connect(widget, SIGNAL(pathChanged()), SIGNAL(validationRequested()));
169 
170  d->exePickArea->layout()->addWidget(widget);
171  d->filePickers << widget;
172  }
173 }
174 
175 QString EngineConfigPage::name() const
176 {
177  return d->plugin->data()->name;
178 }
179 
181 {
182  return d->plugin;
183 }
184 
186 {
187  foreach (FilePickWidget *filePicker, d->filePickers)
188  {
189  filePicker->blockSignals(true);
190  filePicker->load(*d->config);
191  filePicker->blockSignals(false);
192  }
193 
194  d->cboCustomParameters->clear();
195  d->cboCustomParameters->addItems(d->readStoredCustomParameters());
196  d->cboCustomParameters->setEditText(d->config->value("CustomParameters").toString());
197  if(d->plugin->data()->hasMasterClient())
198  d->leMasterserverAddress->setText(d->config->value("Masterserver").toString());
199 
200  updateCustomParametersSaveState();
201 }
202 
203 void EngineConfigPage::removeCurrentCustomParametersFromStorage()
204 {
205  QString currentParams = currentCustomParameters();
206  removeStoredCustomParametersFromConfig(currentParams);
207  removeStoredCustomParametersFromWidget(currentParams);
208  updateCustomParametersSaveState();
209 }
210 
211 void EngineConfigPage::removeStoredCustomParametersFromConfig(const QString &parameters)
212 {
213  QStringList storedParameters = d->readStoredCustomParameters();
214  storedParameters.removeAll(parameters);
215  d->saveStoredCustomParameters(storedParameters);
216 }
217 
218 void EngineConfigPage::removeStoredCustomParametersFromWidget(const QString &parameters)
219 {
220  int indexInWidget = d->cboCustomParameters->findText(parameters);
221  if (indexInWidget >= 0)
222  {
223  d->cboCustomParameters->removeItem(indexInWidget);
224  d->cboCustomParameters->setEditText(parameters);
225  }
226 }
227 
228 void EngineConfigPage::saveCustomParameters()
229 {
230  if (!d->existsInStoredCustomParameters(currentCustomParameters()))
231  {
232  QStringList parameters = d->readStoredCustomParameters();
233  parameters << currentCustomParameters();
234  d->saveStoredCustomParameters(parameters);
235  d->cboCustomParameters->addItem(currentCustomParameters());
236  }
237  updateCustomParametersSaveState();
238 }
239 
241 {
242  foreach (FilePickWidget *filePicker, d->filePickers)
243  {
244  filePicker->save(*d->config);
245  }
246  d->config->setValue("CustomParameters", currentCustomParameters());
247  if (d->plugin->data()->hasMasterClient())
248  {
249  d->config->setValue("Masterserver", d->leMasterserverAddress->text());
250  }
251 }
252 
253 void EngineConfigPage::showError(const QString &error)
254 {
255  d->lblError->setText(error);
256  d->lblError->show();
257  d->errorTimer.start();
258 }
259 
260 void EngineConfigPage::showFindFailError()
261 {
262  showError(tr("Failed to automatically find file.\nYou may need to use the browse button."));
263 }
264 
265 QString EngineConfigPage::title() const
266 {
267  return tr("Game - %1").arg(name());
268 }
269 
270 void EngineConfigPage::updateCustomParametersSaveState()
271 {
272  bool paramExists = d->existsInStoredCustomParameters(currentCustomParameters());
273  bool isEmpty = currentCustomParameters().isEmpty();
274  d->btnSaveCustomParameters->setVisible(!isEmpty && !paramExists);
275  d->btnDeleteCustomParameters->setVisible(!isEmpty && paramExists);
276 }
277 
279 {
280  bool allFilesOk = true;
281  foreach (FilePickWidget *filePicker, d->filePickers)
282  {
283  bool thisFileOk = filePicker->validate();
284  allFilesOk = allFilesOk && thisFileOk;
285  }
286  return allFilesOk ? VALIDATION_OK : VALIDATION_ERROR;
287 }
void readSettings()
Reimplement this to read settings from config into widgets.
Validation
Result of validate()
Definition: configpage.h:50
virtual Validation validate()
Validate settings on this page.
QVariant value(const QString &key) const
Retrieves a variable directly; omits the IniVariable system.
Definition: inisection.cpp:164
void saveSettings()
Reimplement this to write settings to config from widgets.
QString title() const
Page title, by default returns the same string as name().
QIcon icon() const
Reimplement this to return a displayable icon for the ConfigPage.
const EnginePlugin * plugin() const
Parent plugin handled by this page.
Definition: dptr.h:31
void setValue(const QString &key, const QVariant &value)
Sets a variable directly. Omits the IniVariable system.
Definition: inisection.cpp:154
INI section representation.
Definition: inisection.h:40
Game file definition allows to browse this file in configuration box.
Definition: gamefile.h:72
void addWidget(QWidget *widget)
Add a new, custom widget below the standard ones.
Definition: dptr.h:54
Base for configuration pages for plugins; provides some default behavior.
QString name() const
Reimplement this to return a list-displayable name for this ConfigPage.
Base class for configuration pages.
Definition: configpage.h:44