23 #include "gui/wadseekerinterface.h"
24 #include "ui_wadseekerinterface.h"
25 #include "configuration/doomseekerconfig.h"
26 #include "serverapi/server.h"
27 #include "application.h"
28 #include "mainwindow.h"
31 #include <QMessageBox>
33 const int WadseekerInterface::UPDATE_INTERVAL_MS = 500;
36 DClass<WadseekerInterface> :
public Ui::WadseekerInterface
39 bool bCompletedSuccessfully;
51 WadseekerInterface::WadseekerInterface(ServerPtr server, QWidget* parent)
56 d->lblTop->setText(tr(
"Downloading WADs for server \"%1\"").arg(server->name()));
57 d->btnDownload->hide();
59 setCustomSite(server->webSite());
62 WadseekerInterface::~WadseekerInterface()
64 currentInstance = NULL;
67 void WadseekerInterface::accept()
71 if (d->bCompletedSuccessfully)
73 done(QDialog::Accepted);
78 if (d->leWadName->text().isEmpty())
83 startSeeking(d->leWadName->text().split(
',', QString::SkipEmptyParts));
87 void WadseekerInterface::allDone(
bool bSuccess)
90 d->bCompletedSuccessfully = bSuccess;
91 QApplication::alert(
this);
94 displayMessage(tr(
"All done. Success."), WadseekerLib::NoticeImportant,
false);
100 done(QDialog::Accepted);
104 d->btnStartGame->show();
110 QStringList failures = unsuccessfulWads();
112 foreach (
const QString& failure, failures)
114 d->twWads->setFileFailed(failure);
117 displayMessage(tr(
"All done. Fail."), WadseekerLib::CriticalError,
false);
121 void WadseekerInterface::connectWadseekerObject()
124 this->connect(&wadseeker, SIGNAL( allDone(
bool) ),
125 SLOT( allDone(
bool) ) );
126 this->connect(&wadseeker, SIGNAL( message(
const QString&, WadseekerLib::MessageType) ),
127 SLOT( message(
const QString&, WadseekerLib::MessageType) ) );
128 this->connect(&wadseeker, SIGNAL( seekStarted(
const QStringList&) ),
129 SLOT( seekStarted(
const QStringList&) ) );
130 this->connect(&wadseeker, SIGNAL( fileInstalled(
const QString&) ),
131 SLOT( fileDownloadSuccessful(
const QString&) ) );
132 this->connect(&wadseeker, SIGNAL( siteFinished(
const QUrl&) ),
133 SLOT( siteFinished(
const QUrl&) ) );
134 this->connect(&wadseeker, SIGNAL( siteProgress(
const QUrl&, qint64, qint64) ),
135 SLOT( siteProgress(
const QUrl&, qint64, qint64) ) );
136 this->connect(&wadseeker, SIGNAL( siteRedirect(
const QUrl&,
const QUrl&) ),
137 SLOT( siteRedirect(
const QUrl&,
const QUrl&) ) );
138 this->connect(&wadseeker, SIGNAL( siteStarted(
const QUrl&) ),
139 SLOT( siteStarted(
const QUrl&) ) );
142 d->twWads->connect(&wadseeker, SIGNAL( fileDownloadFinished(
const QString&) ),
143 SLOT( setFileDownloadFinished(
const QString&) ) );
144 d->twWads->connect(&wadseeker, SIGNAL( fileDownloadProgress(
const QString&, qint64, qint64) ),
145 SLOT( setFileProgress(
const QString&, qint64, qint64) ) );
146 d->twWads->connect(&wadseeker, SIGNAL( fileDownloadStarted(
const QString&,
const QUrl&) ),
147 SLOT( setFileUrl(
const QString&,
const QUrl&) ) );
150 void WadseekerInterface::construct()
153 d->bCompletedSuccessfully =
false;
158 this->setWindowIcon(QIcon(
":/icon.png"));
159 d->btnStartGame->hide();
160 this->connect(&updateTimer, SIGNAL(timeout()), SLOT(registerUpdateRequest()));
162 connectWadseekerObject();
165 this->connect(d->twWads, SIGNAL( rightMouseClick(
const QModelIndex&,
const QPoint&) ),
166 SLOT( wadsTableRightClicked(
const QModelIndex&,
const QPoint&) ) );
171 const QStringList& urlList = gConfig.wadseeker.searchURLs;
173 if (!urlList.isEmpty())
175 wadseeker.setPrimarySites(urlList);
179 wadseeker.setPrimarySitesToDefault();
182 updateTimer.setSingleShot(
false);
183 updateTimer.start(UPDATE_INTERVAL_MS);
188 if (!isInstantiated())
191 return currentInstance;
198 if (!isInstantiated())
201 return currentInstance;
206 void WadseekerInterface::displayMessage(
const QString& message, WadseekerLib::MessageType type,
bool bPrependErrorsWithMessageType)
208 QString strProcessedMessage;
210 bool bPrependWithNewline =
false;
211 QString wrapHtmlLeft =
"<div style=\"%1\">";
212 QString wrapHtmlRight =
"</div>";
217 case WadseekerLib::CriticalError:
218 htmlStyle = QString(
"color: %1; font-weight: bold;").arg(colorHtmlMessageFatalError);
219 bPrependWithNewline =
true;
221 if (bPrependErrorsWithMessageType)
223 strProcessedMessage = tr(
"CRITICAL ERROR: %1").arg(message);
227 strProcessedMessage = message;
233 case WadseekerLib::Error:
234 htmlStyle = QString(
"color: %1;").arg(colorHtmlMessageError);
236 if (bPrependErrorsWithMessageType)
238 strProcessedMessage = tr(
"Error: %1").arg(message);
242 strProcessedMessage = message;
246 case WadseekerLib::Notice:
247 htmlStyle = QString(
"color: %1;").arg(colorHtmlMessageNotice);
249 strProcessedMessage = message;
252 case WadseekerLib::NoticeImportant:
253 htmlStyle = QString(
"color: %1; font-weight: bold;").arg(colorHtmlMessageNotice);
254 bPrependWithNewline =
true;
256 strProcessedMessage = message;
260 if (bPrependWithNewline && !d->teWadseekerOutput->toPlainText().isEmpty())
262 strProcessedMessage =
"<br>" + strProcessedMessage;
265 wrapHtmlLeft = wrapHtmlLeft.arg(htmlStyle);
267 strProcessedMessage = wrapHtmlLeft + strProcessedMessage + wrapHtmlRight;
269 d->teWadseekerOutput->append(strProcessedMessage);
272 void WadseekerInterface::fileDownloadSuccessful(
const QString& filename)
274 successfulWads << filename;
275 d->twWads->setFileSuccessful(filename);
278 void WadseekerInterface::initMessageColors()
280 colorHtmlMessageNotice = gConfig.wadseeker.colorMessageNotice;
281 colorHtmlMessageError = gConfig.wadseeker.colorMessageError;
282 colorHtmlMessageFatalError = gConfig.wadseeker.colorMessageCriticalError;
285 bool WadseekerInterface::isInstantiated()
287 return currentInstance != NULL;
290 void WadseekerInterface::message(
const QString& message, WadseekerLib::MessageType type)
292 displayMessage(message, type,
true);
295 void WadseekerInterface::registerUpdateRequest()
301 void WadseekerInterface::reject()
310 this->done(Rejected);
315 void WadseekerInterface::resetTitleToDefault()
317 setWindowTitle(tr(
"Wadseeker"));
320 void WadseekerInterface::seekStarted(
const QStringList& filenames)
322 d->teWadseekerOutput->clear();
323 d->pbOverallProgress->setValue(0);
324 displayMessage(
"Seek started on filenames: " + filenames.join(
", "), WadseekerLib::Notice,
false);
326 seekedWads = filenames;
327 successfulWads.clear();
328 d->twSites->setRowCount(0);
329 d->twWads->setRowCount(0);
330 setStateDownloading();
332 foreach (
const QString& name, filenames)
334 d->twWads->addFile(name);
338 void WadseekerInterface::setStateDownloading()
340 d->btnClose->setText(tr(
"Abort"));
341 d->btnDownload->setEnabled(
false);
345 void WadseekerInterface::setStateWaiting()
347 d->btnClose->setText(tr(
"Close"));
348 d->btnDownload->setEnabled(
true);
360 d->leWadName->setText(wads.join(
", "));
364 void WadseekerInterface::setupIdgames()
366 QString idgamesUrl = Wadseeker::defaultIdgamesUrl();
367 bool useIdgames =
true;
368 bool idgamesHasHighPriority =
false;
370 useIdgames = gConfig.wadseeker.bSearchInIdgames;
371 idgamesUrl = gConfig.wadseeker.idgamesURL;
373 wadseeker.setIdgamesEnabled(useIdgames);
374 wadseeker.setIdgamesUrl(idgamesUrl);
375 wadseeker.setWadArchiveEnabled(gConfig.wadseeker.bSearchInWadArchive);
378 void WadseekerInterface::showEvent(QShowEvent* event)
386 startSeeking(seekedWads);
391 void WadseekerInterface::siteFinished(
const QUrl& site)
393 d->twSites->removeUrl(site);
394 displayMessage(
"Site finished: " + site.toEncoded(), WadseekerLib::Notice,
false);
397 void WadseekerInterface::siteProgress(
const QUrl& site, qint64 bytes, qint64 total)
399 d->twSites->setUrlProgress(site, bytes, total);
402 void WadseekerInterface::siteRedirect(
const QUrl& oldUrl,
const QUrl& newUrl)
404 d->twSites->removeUrl(oldUrl);
405 d->twSites->addUrl(newUrl);
406 displayMessage(
"Site redirect: " + oldUrl.toEncoded() +
" -> " + newUrl.toEncoded(), WadseekerLib::Notice,
false);
409 void WadseekerInterface::siteStarted(
const QUrl& site)
411 d->twSites->addUrl(site);
412 displayMessage(
"Site started: " + site.toEncoded(), WadseekerLib::Notice,
false);
415 void WadseekerInterface::startSeeking(
const QStringList& seekedFilesList)
417 if (seekedFilesList.isEmpty())
421 d->bCompletedSuccessfully =
false;
425 QStringList seekedFilesListFormatted;
426 foreach (QString filenameFormatted, seekedFilesList)
428 filenameFormatted = filenameFormatted.trimmed();
430 seekedFilesListFormatted << filenameFormatted;
435 wadseeker.setTargetDirectory(gConfig.wadseeker.targetDirectory);
436 wadseeker.setCustomSite(customSite);
437 wadseeker.setMaximumConcurrentSeeks(gConfig.wadseeker.maxConcurrentSiteDownloads);
438 wadseeker.setMaximumConcurrentDownloads(gConfig.wadseeker.maxConcurrentWadDownloads);
439 wadseeker.startSeek(seekedFilesListFormatted);
442 void WadseekerInterface::updateProgressBar()
444 double totalPercentage = d->twWads->totalDonePercentage();
445 unsigned progressBarValue = (unsigned)(totalPercentage * 100.0);
447 d->pbOverallProgress->setValue(progressBarValue);
450 void WadseekerInterface::updateTitle()
456 double totalPercentage = d->twWads->totalDonePercentage();
457 if (totalPercentage < 0.0)
459 totalPercentage = 0.0;
462 setWindowTitle(tr(
"[%1%] Wadseeker").arg(totalPercentage, 6,
'f', 2));
468 resetTitleToDefault();
473 QStringList WadseekerInterface::unsuccessfulWads()
const
475 QStringList allWads = seekedWads;
477 foreach (
const QString& success, successfulWads)
479 allWads.removeAll(success);
485 void WadseekerInterface::wadsTableRightClicked(
const QModelIndex& index,
const QPoint& cursorPosition)
490 QString fileName = d->twWads->fileNameAtRow(index.row());
491 if (!wadseeker.isDownloadingFile(fileName))
493 menu->actionSkipCurrentSite->setEnabled(
false);
496 QAction* pResult = menu->exec();
498 if (pResult == menu->actionSkipCurrentSite)
500 QString wadName = d->twWads->fileNameAtRow(index.row());
501 d->twWads->setFileUrl(fileName, QUrl());
503 wadseeker.skipFileCurrentUrl(wadName);
505 else if (pResult != NULL)
507 QMessageBox::warning(
this, tr(
"Context menu error"), tr(
"Unknown action selected."));
void setWads(const QStringList &wads)
Sets WADs to seek.
Wadseeker dialog box, only one instance is allowed.