missingwadsdialog.cpp
1 //------------------------------------------------------------------------------
2 // missingwadsdialog.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) 2015 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "missingwadsdialog.h"
24 
25 #include "application.h"
26 #include "gui/mainwindow.h"
27 #include "gui/wadseekerinterface.h"
29 #include "ui_missingwadsdialog.h"
30 #include <QListWidgetItem>
31 #include <wadseeker/entities/modfile.h>
32 #include <wadseeker/freedoom.h>
33 #include <wadseeker/wadseeker.h>
34 
35 DClass<MissingWadsDialog> : public Ui::MissingWadsDialog
36 {
37 public:
38  ::MissingWadsDialog::MissingWadsProceed decision;
39  QList<PWad> missingWads;
40  QList<PWad> incompatibleWads;
41 };
42 DPointeredNoCopy(MissingWadsDialog)
43 
44 MissingWadsDialog::MissingWadsDialog(const QList<PWad> &missingWads, const QList<PWad> &incompatibleWads, QWidget *parent)
45  : QDialog(parent)
46 {
47  d->setupUi(this);
48  d->decision = Cancel;
49  d->missingWads = missingWads;
50  d->incompatibleWads = incompatibleWads;
51 
52  setup();
53  adjustSize();
54 }
55 
56 MissingWadsDialog::~MissingWadsDialog()
57 {
58 }
59 
60 void MissingWadsDialog::setAllowIgnore(bool allow)
61 {
62  d->btnIgnore->setVisible(allow);
63  d->lblUseIgnore->setVisible(allow);
64  d->lblUseIgnoreCantRun->setVisible(allow);
65 }
66 
67 void MissingWadsDialog::setup()
68 {
69  d->btnInstallFreedoom->hide();
70  if (WadseekerInterface::isInstantiated())
71  setupWadseekerIsRunning();
72  else
73  setupWadseekerNotRunning();
74 }
75 
76 void MissingWadsDialog::setupWadseekerIsRunning()
77 {
78  d->areaWadseekerAlreadyRunning->show();
79  d->areaWadseekerCanBeRun->hide();
80  d->btnInstall->hide();
81 }
82 
83 void MissingWadsDialog::setupWadseekerNotRunning()
84 {
85  d->areaWadseekerAlreadyRunning->hide();
86  d->areaWadseekerCanBeRun->show();
87 
88  setupForbiddenFilesArea();
89  setupDownloadableFilesArea();
90  setupOptionalFilesArea();
91  setupIncompatibleFilesArea();
92 
93  d->btnInstall->setVisible(hasAnyAllowedFile());
94 }
95 
96 void MissingWadsDialog::setupForbiddenFilesArea()
97 {
98  QList<PWad> files = forbiddenFiles();
99  if (!files.isEmpty())
100  {
101  d->areaCantBeDownloaded->show();
102  QStringList names;
103  for (PWad file : files)
104  {
105  names << file.name();
106  }
107  d->lblCantBeDownloadedFiles->setText(names.join(", "));
108 
109  bool installFreedoom = isFreedoomReplaceableOnList(names);
110  d->lblInstallFreedoom->setVisible(installFreedoom);
111  d->btnInstallFreedoom->setVisible(installFreedoom);
112  }
113  else
114  d->areaCantBeDownloaded->hide();
115 }
116 
117 void MissingWadsDialog::setupDownloadableFilesArea()
118 {
119  QList<PWad> files = downloadableFiles();
120  if (!files.isEmpty())
121  {
122  d->areaCanBeDownloadedFiles->show();
123  QStringList names;
124  for (PWad file : files)
125  {
126  names << file.name();
127  }
128  d->lblCanBeDownloadedFiles->setText(names.join(", "));
129  }
130  else
131  d->areaCanBeDownloadedFiles->hide();
132 }
133 
134 void MissingWadsDialog::setupOptionalFilesArea()
135 {
136  QList<PWad> files = optionalFiles();
137  if (!files.isEmpty())
138  {
139  d->areaOptionalFiles->show();
140  for (const PWad &file : files)
141  {
142  auto item = new QListWidgetItem(file.name(), d->optionalFilesList);
143  item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
144  item->setCheckState(Qt::Checked);
145  }
146  }
147  else
148  d->areaOptionalFiles->hide();
149 }
150 
151 void MissingWadsDialog::setupIncompatibleFilesArea()
152 {
153  QList<PWad> files = incompatibleFiles();
154  if (!files.isEmpty())
155  {
156  d->areaIncompatibleFiles->show();
157  for (const PWad &file : files)
158  {
159  auto item = new QListWidgetItem(file.name(), d->incompatibleFilesList);
160  item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
161  item->setCheckState(Qt::Checked);
162  }
163  }
164  else
165  d->areaIncompatibleFiles->hide();
166 }
167 
168 bool MissingWadsDialog::isFreedoomReplaceableOnList(const QStringList &files) const
169 {
170  for (const QString &file : files)
171  {
172  if (Freedoom::hasFreedoomReplacement(file))
173  return true;
174  }
175  return false;
176 }
177 
178 void MissingWadsDialog::updateStateAccordingToFileSelection()
179 {
180  d->btnInstall->setEnabled(!filesToDownload().isEmpty());
181 }
182 
183 void MissingWadsDialog::ignoreMissingFiles()
184 {
185  d->decision = Ignore;
186  accept();
187 }
188 
189 void MissingWadsDialog::installFreedoom()
190 {
191  QTimer::singleShot(0, gApp->mainWindow(), SLOT(showInstallFreedoomDialog()));
192  accept();
193 }
194 
195 void MissingWadsDialog::installMissingFiles()
196 {
197  d->decision = Install;
198  accept();
199 }
200 
201 QList<PWad> MissingWadsDialog::downloadableFiles() const
202 {
203  QList<PWad> result;
204  for (PWad file : d->missingWads)
205  {
206  if (!Wadseeker::isForbiddenWad(file) && !file.isOptional())
207  result << file;
208  }
209  return result;
210 }
211 
212 QList<PWad> MissingWadsDialog::forbiddenFiles() const
213 {
214  QList<PWad> result;
215  QList<PWad> wads;
216  wads << d->missingWads << d->incompatibleWads;
217  for (const PWad &file : wads)
218  {
219  if (Wadseeker::isForbiddenWad(file.name()))
220  result << file;
221  }
222  return result;
223 }
224 
225 QList<PWad> MissingWadsDialog::optionalFiles() const
226 {
227  QList<PWad> result;
228  for (const PWad &file : d->missingWads)
229  {
230  if (!Wadseeker::isForbiddenWad(file.name()) && file.isOptional())
231  result << file;
232  }
233  return result;
234 }
235 
236 QList<PWad> MissingWadsDialog::incompatibleFiles() const
237 {
238  QList<PWad> result;
239  for (const PWad &file : d->incompatibleWads)
240  {
241  if (!Wadseeker::isForbiddenWad(file.name()))
242  result << file;
243  }
244  return result;
245 }
246 
247 QList<PWad> MissingWadsDialog::filesToDownload() const
248 {
249  QList<PWad> result = downloadableFiles();
250  result << selectedOptionalFiles();
251  result << selectedIncompatibleFiles();
252  return result;
253 }
254 
255 QList<PWad> MissingWadsDialog::selectedOptionalFiles() const
256 {
257  QStringList result;
258  for (int i = 0; i < d->optionalFilesList->count(); ++i)
259  {
260  QListWidgetItem *item = d->optionalFilesList->item(i);
261  if (item->checkState() == Qt::Checked)
262  result << item->text();
263  }
264  return filenamesToPwads(result, optionalFiles());
265 }
266 
267 QList<PWad> MissingWadsDialog::selectedIncompatibleFiles() const
268 {
269  QStringList result;
270  for (int i = 0; i < d->incompatibleFilesList->count(); ++i)
271  {
272  QListWidgetItem *item = d->incompatibleFilesList->item(i);
273  if (item->checkState() == Qt::Checked)
274  result << item->text();
275  }
276  return filenamesToPwads(result, incompatibleFiles());
277 }
278 
279 QList<PWad> MissingWadsDialog::filenamesToPwads(const QStringList &names, QList<PWad> files) const
280 {
281  QList<PWad> result;
282  for (QString name : names)
283  {
284  for (int i = 0; i < files.size(); ++i)
285  {
286  if (files[i].name() == name)
287  {
288  result << files[i];
289  files.removeAt(i);
290  break;
291  }
292  }
293  }
294  return result;
295 }
296 
297 bool MissingWadsDialog::hasAnyAllowedFile() const
298 {
299  return !downloadableFiles().isEmpty() ||
300  !optionalFiles().isEmpty() ||
301  !incompatibleFiles().isEmpty();
302 }
303 
304 MissingWadsDialog::MissingWadsProceed MissingWadsDialog::decision() const
305 {
306  return d->decision;
307 }
PWAD hosted on a server.
bool isOptional() const
Is this WAD required to join the server?
const QString & name() const
File name of the WAD.