30 #include "gldraw.h" |
30 #include "gldraw.h" |
31 |
31 |
32 PartDownloader g_PartDownloader; |
32 PartDownloader g_PartDownloader; |
33 |
33 |
34 cfg (str, net_downloadpath, ""); |
34 cfg (str, net_downloadpath, ""); |
|
35 cfg (bool, net_guesspaths, true); |
|
36 cfg (bool, net_autoclose, false); |
35 |
37 |
36 constexpr const char* PartDownloader::k_OfficialURL, |
38 constexpr const char* PartDownloader::k_OfficialURL, |
37 *PartDownloader::k_UnofficialURL; |
39 *PartDownloader::k_UnofficialURL; |
38 |
40 |
39 // ============================================================================= |
41 // ============================================================================= |
102 // ============================================================================= |
104 // ============================================================================= |
103 // ----------------------------------------------------------------------------- |
105 // ----------------------------------------------------------------------------- |
104 void PartDownloadPrompt::modifyDest (str& dest) const { |
106 void PartDownloadPrompt::modifyDest (str& dest) const { |
105 dest = dest.simplified(); |
107 dest = dest.simplified(); |
106 |
108 |
107 if (getSource() == CustomURL) |
109 // If the user doesn't want us to guess, stop right here. |
108 dest = basename (dest); |
110 if (net_guesspaths == false) |
|
111 return; |
109 |
112 |
110 // Ensure .dat extension |
113 // Ensure .dat extension |
111 if (dest.right (4) != ".dat") { |
114 if (dest.right (4) != ".dat") { |
112 // Remove the existing extension, if any. It may be we're here over a |
115 // Remove the existing extension, if any. It may be we're here over a |
113 // typo in the .dat extension. |
116 // typo in the .dat extension. |
172 } |
175 } |
173 |
176 |
174 // ============================================================================= |
177 // ============================================================================= |
175 // ----------------------------------------------------------------------------- |
178 // ----------------------------------------------------------------------------- |
176 void PartDownloadPrompt::startDownload() { |
179 void PartDownloadPrompt::startDownload() { |
|
180 str dest = ui->fname->text(); |
|
181 setPrimaryFile (null); |
|
182 |
|
183 if (getSource() == CustomURL) |
|
184 dest = basename (getURL()); |
|
185 |
|
186 modifyDest (dest); |
|
187 |
|
188 if (QFile::exists (PartDownloader::getDownloadPath() + dest)) { |
|
189 const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest); |
|
190 |
|
191 if (!confirm (tr ("Overwrite?"), overwritemsg)) |
|
192 return; |
|
193 } |
|
194 |
177 ui->progress->setEnabled (true); |
195 ui->progress->setEnabled (true); |
178 ui->buttonBox->setEnabled (false); |
196 ui->buttonBox->setEnabled (false); |
179 ui->fname->setEnabled (false); |
197 ui->fname->setEnabled (false); |
180 ui->source->setEnabled (false); |
198 ui->source->setEnabled (false); |
181 |
|
182 str dest = ui->fname->text(); |
|
183 modifyDest (dest); |
|
184 downloadFile (dest, getURL(), true); |
199 downloadFile (dest, getURL(), true); |
185 } |
200 } |
186 |
201 |
187 // ============================================================================= |
202 // ============================================================================= |
188 // ----------------------------------------------------------------------------- |
203 // ----------------------------------------------------------------------------- |
205 } |
220 } |
206 |
221 |
207 // ============================================================================= |
222 // ============================================================================= |
208 // ----------------------------------------------------------------------------- |
223 // ----------------------------------------------------------------------------- |
209 void PartDownloadPrompt::checkIfFinished() { |
224 void PartDownloadPrompt::checkIfFinished() { |
|
225 bool failed = false; |
|
226 |
210 // If there is some download still working, we're not finished. |
227 // If there is some download still working, we're not finished. |
211 for (PartDownloadRequest* req : m_requests) |
228 for (PartDownloadRequest* req : m_requests) { |
212 if (!req->isFinished()) |
229 if (!req->isFinished()) |
213 return; |
230 return; |
|
231 |
|
232 if (req->state() == PartDownloadRequest::Failed) |
|
233 failed = true; |
|
234 } |
|
235 |
|
236 for (PartDownloadRequest* req : m_requests) |
|
237 delete req; |
214 |
238 |
215 // Update everything now |
239 // Update everything now |
216 reloadAllSubfiles(); |
240 if (primaryFile()) { |
217 g_win->fullRefresh(); |
241 LDFile::setCurrent (primaryFile()); |
218 g_win->R()->resetAngles(); |
242 reloadAllSubfiles(); |
219 |
243 g_win->fullRefresh(); |
220 // Allow the prompt be closed now. |
244 g_win->R()->resetAngles(); |
221 ui->buttonBox->disconnect (SIGNAL (accepted())); |
245 m_requests.clear(); |
222 connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept())); |
246 |
223 ui->buttonBox->setEnabled (true); |
247 if (net_autoclose && !failed) { |
224 ui->progress->setEnabled (false); |
248 // Close automatically if desired. |
225 |
249 accept(); |
226 // accept(); |
250 } else { |
|
251 // Allow the prompt be closed now. |
|
252 ui->buttonBox->disconnect (SIGNAL (accepted())); |
|
253 connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept())); |
|
254 ui->buttonBox->setEnabled (true); |
|
255 ui->progress->setEnabled (false); |
|
256 } |
|
257 } |
227 } |
258 } |
228 |
259 |
229 // ============================================================================= |
260 // ============================================================================= |
230 // ----------------------------------------------------------------------------- |
261 // ----------------------------------------------------------------------------- |
231 PartDownloadRequest::PartDownloadRequest (str url, str dest, bool primary, PartDownloadPrompt* parent) : |
262 PartDownloadRequest::PartDownloadRequest (str url, str dest, bool primary, PartDownloadPrompt* parent) : |
235 m_dest (dest), |
266 m_dest (dest), |
236 m_fpath (PartDownloader::getDownloadPath() + dest), |
267 m_fpath (PartDownloader::getDownloadPath() + dest), |
237 m_nam (new QNetworkAccessManager), |
268 m_nam (new QNetworkAccessManager), |
238 m_firstUpdate (true), |
269 m_firstUpdate (true), |
239 m_state (Requesting), |
270 m_state (Requesting), |
240 m_primary (primary) |
271 m_primary (primary), |
|
272 m_fp (null) |
241 { |
273 { |
242 m_fpath.replace ("\\", "/"); |
|
243 QFile::remove (m_fpath); |
|
244 |
|
245 // Make sure that we have a valid destination. |
274 // Make sure that we have a valid destination. |
246 str dirpath = dirname (m_fpath); |
275 str dirpath = dirname (m_fpath); |
247 |
276 |
248 QDir dir (dirpath); |
277 QDir dir (dirpath); |
249 if (!dir.exists()) { |
278 if (!dir.exists()) { |
283 prog->setValue (m_bytesRead); |
312 prog->setValue (m_bytesRead); |
284 break; |
313 break; |
285 |
314 |
286 case Finished: |
315 case Finished: |
287 case Failed: |
316 case Failed: |
288 case Aborted: |
|
289 { |
317 { |
290 QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : |
318 QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : |
291 "<b><span style=\"color: #800\">FAILED</span></b>"); |
319 "<b><span style=\"color: #800\">FAILED</span></b>"); |
292 lb->setAlignment (Qt::AlignCenter); |
320 lb->setAlignment (Qt::AlignCenter); |
293 table->setCellWidget (tableRow(), ProgressColumn, lb); |
321 table->setCellWidget (tableRow(), ProgressColumn, lb); |
309 } |
337 } |
310 |
338 |
311 // ============================================================================= |
339 // ============================================================================= |
312 // ----------------------------------------------------------------------------- |
340 // ----------------------------------------------------------------------------- |
313 void PartDownloadRequest::downloadFinished() { |
341 void PartDownloadRequest::downloadFinished() { |
314 m_state = m_reply->error() == QNetworkReply::NoError ? Finished : Failed; |
342 if (m_reply->error() != QNetworkReply::NoError) |
|
343 m_state = Failed; |
|
344 elif (state() != Failed) |
|
345 m_state = Finished; |
|
346 |
315 m_bytesRead = m_bytesTotal; |
347 m_bytesRead = m_bytesTotal; |
316 updateToTable(); |
348 updateToTable(); |
317 |
349 |
|
350 if (m_fp) { |
|
351 m_fp->close(); |
|
352 delete m_fp; |
|
353 m_fp = null; |
|
354 } |
|
355 |
318 if (m_state != Finished) { |
356 if (m_state != Finished) { |
319 m_prompt->checkIfFinished(); |
357 m_prompt->checkIfFinished(); |
320 return; |
358 return; |
321 } |
359 } |
|
360 |
|
361 print ("state: %1\n", (int) m_state); |
322 |
362 |
323 // Try to load this file now. |
363 // Try to load this file now. |
324 LDFile* f = openDATFile (m_fpath, false); |
364 LDFile* f = openDATFile (m_fpath, false); |
325 if (!f) |
365 if (!f) |
326 return; |
366 return; |
343 m_prompt->modifyDest (dest); |
383 m_prompt->modifyDest (dest); |
344 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); |
384 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); |
345 } |
385 } |
346 |
386 |
347 if (m_primary) |
387 if (m_primary) |
348 LDFile::setCurrent (f); |
388 m_prompt->setPrimaryFile (f); |
349 |
389 |
350 m_prompt->checkIfFinished(); |
390 m_prompt->checkIfFinished(); |
351 } |
391 } |
352 |
392 |
353 // ============================================================================= |
393 // ============================================================================= |
360 } |
400 } |
361 |
401 |
362 // ============================================================================= |
402 // ============================================================================= |
363 // ----------------------------------------------------------------------------- |
403 // ----------------------------------------------------------------------------- |
364 void PartDownloadRequest::readyRead() { |
404 void PartDownloadRequest::readyRead() { |
365 QFile f (m_fpath); |
405 if (state() == Failed) |
366 if (!f.open (QIODevice::Append)) |
406 return; |
367 return; |
407 |
368 |
408 if (m_fp == null) { |
369 f.write (m_reply->readAll()); |
409 m_fpath.replace ("\\", "/"); |
370 f.close(); |
410 |
|
411 // We have already asked the user whether we can overwrite so we're good |
|
412 // to go here. |
|
413 m_fp = new QFile (m_fpath); |
|
414 if (!m_fp->open (QIODevice::WriteOnly)) { |
|
415 critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno))); |
|
416 m_state = Failed; |
|
417 m_reply->abort(); |
|
418 updateToTable(); |
|
419 m_prompt->checkIfFinished(); |
|
420 return; |
|
421 } |
|
422 } |
|
423 |
|
424 m_fp->write (m_reply->readAll()); |
371 } |
425 } |
372 |
426 |
373 // ============================================================================= |
427 // ============================================================================= |
374 // ----------------------------------------------------------------------------- |
428 // ----------------------------------------------------------------------------- |
375 void PartDownloadRequest::downloadError() { |
429 void PartDownloadRequest::downloadError() { |
382 } |
436 } |
383 |
437 |
384 // ============================================================================= |
438 // ============================================================================= |
385 // ----------------------------------------------------------------------------- |
439 // ----------------------------------------------------------------------------- |
386 bool PartDownloadRequest::isFinished() const { |
440 bool PartDownloadRequest::isFinished() const { |
387 return m_state == Finished || m_state == Failed || m_state == Aborted; |
441 return m_state == Finished || m_state == Failed; |
|
442 } |
|
443 |
|
444 // ============================================================================= |
|
445 // ----------------------------------------------------------------------------- |
|
446 const PartDownloadRequest::State& PartDownloadRequest::state() const { |
|
447 return m_state; |
388 } |
448 } |
389 |
449 |
390 // ============================================================================= |
450 // ============================================================================= |
391 // ----------------------------------------------------------------------------- |
451 // ----------------------------------------------------------------------------- |
392 DEFINE_ACTION (DownloadFrom, 0) { |
452 DEFINE_ACTION (DownloadFrom, 0) { |