src/download.cpp

changeset 493
16766ac1bbd9
parent 491
7d1b5ecd76c0
child 503
bebe09014dd6
equal deleted inserted replaced
492:e964085e6913 493:16766ac1bbd9
27 #include "types.h" 27 #include "types.h"
28 #include "gui.h" 28 #include "gui.h"
29 #include "file.h" 29 #include "file.h"
30 #include "gldraw.h" 30 #include "gldraw.h"
31 #include "configDialog.h" 31 #include "configDialog.h"
32 #include "moc_download.cpp"
32 33
33 cfg (String, net_downloadpath, ""); 34 cfg (String, net_downloadpath, "");
34 cfg (Bool, net_guesspaths, true); 35 cfg (Bool, net_guesspaths, true);
35 cfg (Bool, net_autoclose, false); 36 cfg (Bool, net_autoclose, false);
36 37
37 constexpr const char* PartDownloader::k_OfficialURL, 38 constexpr const char *PartDownloader::k_UnofficialURL;
38 *PartDownloader::k_UnofficialURL; 39
39 40 // =============================================================================
40 // ============================================================================= 41 // -----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------- 42 void PartDownloader::k_download()
42 void PartDownloader::k_download() { 43 { str path = getDownloadPath();
43 str path = getDownloadPath(); 44
44 if (path == "" || QDir (path).exists() == false) { 45 if (path == "" || QDir (path).exists() == false)
45 critical (PartDownloader::tr ("You need to specify a valid path for " 46 { critical (PartDownloader::tr ("You need to specify a valid path for "
46 "downloaded files in the configuration to download paths.")); 47 "downloaded files in the configuration to download paths."));
47 48
48 (new ConfigDialog (ConfigDialog::DownloadTab, null))->exec(); 49 (new ConfigDialog (ConfigDialog::DownloadTab, null))->exec();
49 return; 50 return;
50 } 51 }
51 52
52 PartDownloader* dlg = new PartDownloader; 53 PartDownloader* dlg = new PartDownloader;
53 dlg->exec(); 54 dlg->exec();
54 } 55 }
55 56
56 // ============================================================================= 57 // =============================================================================
57 // ----------------------------------------------------------------------------- 58 // -----------------------------------------------------------------------------
58 str PartDownloader::getDownloadPath() { 59 str PartDownloader::getDownloadPath()
59 str path = net_downloadpath; 60 { str path = net_downloadpath;
60 61
61 #if DIRSLASH_CHAR != '/' 62 #if DIRSLASH_CHAR != '/'
62 path.replace (DIRSLASH, "/"); 63 path.replace (DIRSLASH, "/");
63 #endif 64 #endif
64 65
65 return path; 66 return path;
66 } 67 }
67 68
68 // ============================================================================= 69 // =============================================================================
69 // ----------------------------------------------------------------------------- 70 // -----------------------------------------------------------------------------
70 PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent) { 71 PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent)
71 ui = new Ui_DownloadFrom; 72 { ui = new Ui_DownloadFrom;
72 ui->setupUi (this); 73 ui->setupUi (this);
73 ui->fname->setFocus(); 74 ui->fname->setFocus();
74 ui->progress->horizontalHeader()->setResizeMode (PartLabelColumn, QHeaderView::Stretch); 75 ui->progress->horizontalHeader()->setResizeMode (PartLabelColumn, QHeaderView::Stretch);
75 76
76 m_downloadButton = new QPushButton (tr ("Download")); 77 m_downloadButton = new QPushButton (tr ("Download"));
77 ui->buttonBox->addButton (m_downloadButton, QDialogButtonBox::ActionRole); 78 ui->buttonBox->addButton (m_downloadButton, QDialogButtonBox::ActionRole);
78 getButton (Abort)->setEnabled (false); 79 getButton (Abort)->setEnabled (false);
79 80
80 connect (ui->source, SIGNAL (currentIndexChanged (int)), this, SLOT (sourceChanged (int))); 81 connect (ui->source, SIGNAL (currentIndexChanged (int)), this, SLOT (sourceChanged (int)));
81 connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), this, SLOT (buttonClicked (QAbstractButton*))); 82 connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), this, SLOT (buttonClicked (QAbstractButton*)));
82 } 83 }
83 84
84 // ============================================================================= 85 // =============================================================================
85 // ----------------------------------------------------------------------------- 86 // -----------------------------------------------------------------------------
86 PartDownloader::~PartDownloader() { 87 PartDownloader::~PartDownloader()
87 delete ui; 88 { delete ui;
88 } 89 }
89 90
90 // ============================================================================= 91 // =============================================================================
91 // ----------------------------------------------------------------------------- 92 // -----------------------------------------------------------------------------
92 str PartDownloader::getURL() const { 93 str PartDownloader::getURL() const
93 const Source src = getSource(); 94 { const Source src = getSource();
94 str dest; 95 str dest;
95 96
96 switch (src) { 97 switch (src)
97 case PartsTracker: 98 { case PartsTracker:
98 dest = ui->fname->text(); 99 dest = ui->fname->text();
99 modifyDest (dest); 100 modifyDest (dest);
100 return str (k_UnofficialURL) + dest; 101 return str (k_UnofficialURL) + dest;
101 102
102 case CustomURL: 103 case CustomURL:
103 return ui->fname->text(); 104 return ui->fname->text();
104 } 105 }
105 106
106 // Shouldn't happen 107 // Shouldn't happen
107 return ""; 108 return "";
108 } 109 }
109 110
110 // ============================================================================= 111 // =============================================================================
111 // ----------------------------------------------------------------------------- 112 // -----------------------------------------------------------------------------
112 void PartDownloader::modifyDest (str& dest) const { 113 void PartDownloader::modifyDest (str& dest) const
113 dest = dest.simplified(); 114 { dest = dest.simplified();
114 115
115 // If the user doesn't want us to guess, stop right here. 116 // If the user doesn't want us to guess, stop right here.
116 if (net_guesspaths == false) 117 if (net_guesspaths == false)
117 return; 118 return;
118 119
119 // Ensure .dat extension 120 // Ensure .dat extension
120 if (dest.right (4) != ".dat") { 121 if (dest.right (4) != ".dat")
121 /* Remove the existing extension, if any. It may be we're here over a 122 { // Remove the existing extension, if any. It may be we're here over a
122 typo in the .dat extension. */ 123 // typo in the .dat extension.
123 const int dotpos = dest.lastIndexOf ("."); 124 const int dotpos = dest.lastIndexOf (".");
125
124 if (dotpos != -1 && dotpos >= dest.length() - 4) 126 if (dotpos != -1 && dotpos >= dest.length() - 4)
125 dest.chop (dest.length() - dotpos); 127 dest.chop (dest.length() - dotpos);
126 128
127 dest += ".dat"; 129 dest += ".dat";
128 } 130 }
129 131
130 /* If the part starts with s\ or s/, then use parts/s/. Same goes with 132 // If the part starts with s\ or s/, then use parts/s/. Same goes with
131 48\ and p/48/. */ 133 // 48\ and p/48/.
132 if (dest.left (2) == "s\\" || dest.left (2) == "s/") { 134 if (dest.left (2) == "s\\" || dest.left (2) == "s/")
133 dest.remove (0, 2); 135 { dest.remove (0, 2);
134 dest.prepend ("parts/s/"); 136 dest.prepend ("parts/s/");
135 } elif (dest.left (3) == "48\\" || dest.left (3) == "48/") { 137 } elif (dest.left (3) == "48\\" || dest.left (3) == "48/")
136 dest.remove (0, 3); 138
139 { dest.remove (0, 3);
137 dest.prepend ("p/48/"); 140 dest.prepend ("p/48/");
138 } 141 }
139 142
140 /* Try determine where to put this part. We have four directories: 143 /* Try determine where to put this part. We have four directories:
141 parts/, parts/s/, p/, and p/48/. If we haven't already specified 144 parts/, parts/s/, p/, and p/48/. If we haven't already specified
142 either parts/ or p/, we need to add it automatically. Part files 145 either parts/ or p/, we need to add it automatically. Part files
143 are numbers wit a possible u prefix for parts with unknown number 146 are numbers wit a possible u prefix for parts with unknown number
144 which can be followed by any of: 147 which can be followed by any of:
145 - c** (composites) 148 - c** (composites)
146 - d** (formed stickers) 149 - d** (formed stickers)
147 - p** (patterns) 150 - p** (patterns)
148 - a lowercase alphabetic letter for variants 151 - a lowercase alphabetic letter for variants
149 152
150 Subfiles (usually) have an s** prefix, in which case we use parts/s/. 153 Subfiles (usually) have an s** prefix, in which case we use parts/s/.
151 Note that the regex starts with a '^' so it won't catch already fully 154 Note that the regex starts with a '^' so it won't catch already fully
152 given part file names. */ 155 given part file names. */
153 str partRegex = "^u?[0-9]+(c[0-9][0-9]+)*(d[0-9][0-9]+)*[a-z]?(p[0-9a-z][0-9a-z]+)*"; 156 str partRegex = "^u?[0-9]+(c[0-9][0-9]+)*(d[0-9][0-9]+)*[a-z]?(p[0-9a-z][0-9a-z]+)*";
154 str subpartRegex = partRegex + "s[0-9][0-9]+"; 157 str subpartRegex = partRegex + "s[0-9][0-9]+";
155 158
156 partRegex += "\\.dat$"; 159 partRegex += "\\.dat$";
157 subpartRegex += "\\.dat$"; 160 subpartRegex += "\\.dat$";
158 161
159 if (QRegExp (subpartRegex).exactMatch (dest)) 162 if (QRegExp (subpartRegex).exactMatch (dest))
160 dest.prepend ("parts/s/"); 163 dest.prepend ("parts/s/");
164
161 elif (QRegExp (partRegex).exactMatch (dest)) 165 elif (QRegExp (partRegex).exactMatch (dest))
162 dest.prepend ("parts/"); 166 dest.prepend ("parts/");
163 elif (dest.left (6) != "parts/" && dest.left (2) != "p/") 167 elif (dest.left (6) != "parts/" && dest.left (2) != "p/")
164 dest.prepend ("p/"); 168 dest.prepend ("p/");
165 } 169 }
166 170
167 // ============================================================================= 171 // =============================================================================
168 // ----------------------------------------------------------------------------- 172 // -----------------------------------------------------------------------------
169 PartDownloader::Source PartDownloader::getSource() const { 173 PartDownloader::Source PartDownloader::getSource() const
170 return (Source) ui->source->currentIndex(); 174 { return (Source) ui->source->currentIndex();
171 } 175 }
172 176
173 // ============================================================================= 177 // =============================================================================
174 // ----------------------------------------------------------------------------- 178 // -----------------------------------------------------------------------------
175 void PartDownloader::sourceChanged (int i) { 179 void PartDownloader::sourceChanged (int i)
176 if (i == CustomURL) 180 { if (i == CustomURL)
177 ui->fileNameLabel->setText (tr ("URL:")); 181 ui->fileNameLabel->setText (tr ("URL:"));
178 else 182 else
179 ui->fileNameLabel->setText (tr ("File name:")); 183 ui->fileNameLabel->setText (tr ("File name:"));
180 } 184 }
181 185
182 // ============================================================================= 186 // =============================================================================
183 // ----------------------------------------------------------------------------- 187 // -----------------------------------------------------------------------------
184 void PartDownloader::buttonClicked (QAbstractButton* btn) { 188 void PartDownloader::buttonClicked (QAbstractButton* btn)
185 if (btn == getButton (Close)) { 189 { if (btn == getButton (Close))
186 reject(); 190 { reject();
187 } elif (btn == getButton (Abort)) { 191 } elif (btn == getButton (Abort))
188 setAborted (true); 192
189 193 { setAborted (true);
190 for (PartDownloadRequest* req : m_requests) 194
195 for (PartDownloadRequest * req : m_requests)
191 req->abort(); 196 req->abort();
192 } elif (btn == getButton (Download)) { 197 } elif (btn == getButton (Download))
193 str dest = ui->fname->text(); 198 { str dest = ui->fname->text();
194 setPrimaryFile (null); 199 setPrimaryFile (null);
195 setAborted (false); 200 setAborted (false);
196 201
197 if (getSource() == CustomURL) 202 if (getSource() == CustomURL)
198 dest = basename (getURL()); 203 dest = basename (getURL());
199 204
200 modifyDest (dest); 205 modifyDest (dest);
201 206
202 if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest)) { 207 if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest))
203 const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest); 208 { const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest);
204
205 if (!confirm (tr ("Overwrite?"), overwritemsg)) 209 if (!confirm (tr ("Overwrite?"), overwritemsg))
206 return; 210 return;
207 } 211 }
208 212
209 m_downloadButton->setEnabled (false); 213 m_downloadButton->setEnabled (false);
210 ui->progress->setEnabled (true); 214 ui->progress->setEnabled (true);
211 ui->fname->setEnabled (false); 215 ui->fname->setEnabled (false);
212 ui->source->setEnabled (false); 216 ui->source->setEnabled (false);
213 downloadFile (dest, getURL(), true); 217 downloadFile (dest, getURL(), true);
217 } 221 }
218 } 222 }
219 223
220 // ============================================================================= 224 // =============================================================================
221 // ----------------------------------------------------------------------------- 225 // -----------------------------------------------------------------------------
222 void PartDownloader::downloadFile (str dest, str url, bool primary) { 226 void PartDownloader::downloadFile (str dest, str url, bool primary)
223 const int row = ui->progress->rowCount(); 227 { const int row = ui->progress->rowCount();
224 228
225 // Don't download files repeadetly. 229 // Don't download files repeadetly.
226 if (m_filesToDownload.find (dest) != -1u) 230 if (m_filesToDownload.find (dest) != -1u)
227 return; 231 return;
228 232
229 modifyDest (dest); 233 modifyDest (dest);
230 print ("DOWNLOAD: %1 -> %2\n", url, PartDownloader::getDownloadPath() + DIRSLASH + dest); 234 print ("DOWNLOAD: %1 -> %2\n", url, PartDownloader::getDownloadPath() + DIRSLASH + dest);
231 PartDownloadRequest* req = new PartDownloadRequest (url, dest, primary, this); 235 PartDownloadRequest* req = new PartDownloadRequest (url, dest, primary, this);
232 236
233 m_filesToDownload << dest; 237 m_filesToDownload << dest;
234 m_requests << req; 238 m_requests << req;
235 ui->progress->insertRow (row); 239 ui->progress->insertRow (row);
236 req->setTableRow (row); 240 req->setTableRow (row);
237 req->updateToTable(); 241 req->updateToTable();
238 } 242 }
239 243
240 // ============================================================================= 244 // =============================================================================
241 // ----------------------------------------------------------------------------- 245 // -----------------------------------------------------------------------------
242 void PartDownloader::checkIfFinished() { 246 void PartDownloader::checkIfFinished()
243 bool failed = aborted(); 247 { bool failed = aborted();
244 248
245 // If there is some download still working, we're not finished. 249 // If there is some download still working, we're not finished.
246 for (PartDownloadRequest* req : m_requests) { 250 for (PartDownloadRequest* req : m_requests)
247 if (!req->isFinished()) 251 { if (!req->isFinished())
248 return; 252 return;
249 253
250 if (req->state() == PartDownloadRequest::Failed) 254 if (req->state() == PartDownloadRequest::Failed)
251 failed = true; 255 failed = true;
252 } 256 }
253 257
254 for (PartDownloadRequest* req : m_requests) 258 for (PartDownloadRequest* req : m_requests)
255 delete req; 259 delete req;
256 260
257 m_requests.clear(); 261 m_requests.clear();
258 262
259 // Update everything now 263 // Update everything now
260 if (primaryFile()) { 264 if (primaryFile())
261 LDFile::setCurrent (primaryFile()); 265 { LDFile::setCurrent (primaryFile());
262 reloadAllSubfiles(); 266 reloadAllSubfiles();
263 g_win->fullRefresh(); 267 g_win->fullRefresh();
264 g_win->R()->resetAngles(); 268 g_win->R()->resetAngles();
265 } 269 }
266 270
267 if (net_autoclose && !failed) { 271 if (net_autoclose && !failed)
268 // Close automatically if desired. 272 { // Close automatically if desired.
269 accept(); 273 accept();
270 } else { 274 }
271 // Allow the prompt be closed now. 275 else
276 { // Allow the prompt be closed now.
272 getButton (Abort)->setEnabled (false); 277 getButton (Abort)->setEnabled (false);
273 getButton (Close)->setEnabled (true); 278 getButton (Close)->setEnabled (true);
274 } 279 }
275 } 280 }
276 281
277 // ============================================================================= 282 // =============================================================================
278 // ----------------------------------------------------------------------------- 283 // -----------------------------------------------------------------------------
279 QPushButton* PartDownloader::getButton (PartDownloader::Button i) { 284 QPushButton* PartDownloader::getButton (PartDownloader::Button i)
280 typedef QDialogButtonBox QDBB; 285 { typedef QDialogButtonBox QDBB;
281 alias btnbox = ui->buttonBox; 286 alias btnbox = ui->buttonBox;
282 287
283 switch (i) { 288 switch (i)
284 case Download: 289 { case Download:
285 return m_downloadButton; 290 return m_downloadButton;
286 291
287 case Abort: 292 case Abort:
288 return qobject_cast<QPushButton*> (btnbox->button (QDBB::Abort)); 293 return qobject_cast<QPushButton*> (btnbox->button (QDBB::Abort));
289 294
290 case Close: 295 case Close:
291 return qobject_cast<QPushButton*> (btnbox->button (QDBB::Close)); 296 return qobject_cast<QPushButton*> (btnbox->button (QDBB::Close));
292 } 297 }
293 298
294 return null; 299 return null;
295 } 300 }
296 301
297 // ============================================================================= 302 // =============================================================================
298 // ----------------------------------------------------------------------------- 303 // -----------------------------------------------------------------------------
308 m_primary (primary), 313 m_primary (primary),
309 m_fp (null) 314 m_fp (null)
310 { 315 {
311 // Make sure that we have a valid destination. 316 // Make sure that we have a valid destination.
312 str dirpath = dirname (m_fpath); 317 str dirpath = dirname (m_fpath);
313 318
314 QDir dir (dirpath); 319 QDir dir (dirpath);
315 if (!dir.exists()) { 320
316 print ("Creating %1...\n", dirpath); 321 if (!dir.exists())
322 { print ("Creating %1...\n", dirpath);
323
317 if (!dir.mkpath (dirpath)) 324 if (!dir.mkpath (dirpath))
318 critical (fmt (tr ("Couldn't create the directory %1!"), dirpath)); 325 critical (fmt (tr ("Couldn't create the directory %1!"), dirpath));
319 } 326 }
320 327
321 m_reply = m_nam->get (QNetworkRequest (QUrl (url))); 328 m_reply = m_nam->get (QNetworkRequest (QUrl (url)));
322 connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished())); 329 connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished()));
323 connect (m_reply, SIGNAL (readyRead()), this, SLOT (readyRead())); 330 connect (m_reply, SIGNAL (readyRead()), this, SLOT (readyRead()));
324 connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)), this, SLOT (downloadProgress (qint64, qint64))); 331 connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)), this, SLOT (downloadProgress (qint64, qint64)));
325 } 332 }
328 // ----------------------------------------------------------------------------- 335 // -----------------------------------------------------------------------------
329 PartDownloadRequest::~PartDownloadRequest() {} 336 PartDownloadRequest::~PartDownloadRequest() {}
330 337
331 // ============================================================================= 338 // =============================================================================
332 // ----------------------------------------------------------------------------- 339 // -----------------------------------------------------------------------------
333 void PartDownloadRequest::updateToTable() { 340 void PartDownloadRequest::updateToTable()
334 const int labelcol = PartDownloader::PartLabelColumn, 341 { const int labelcol = PartDownloader::PartLabelColumn,
335 progcol = PartDownloader::ProgressColumn; 342 progcol = PartDownloader::ProgressColumn;
336 QTableWidget* table = m_prompt->ui->progress; 343 QTableWidget* table = m_prompt->ui->progress;
337 QProgressBar* prog; 344 QProgressBar* prog;
338 345
339 switch (m_state) { 346 switch (m_state)
340 case Requesting: 347 { case Requesting:
341 case Downloading: 348 case Downloading:
342 prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol)); 349 prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol));
343 350
344 if (!prog) { 351 if (!prog)
345 prog = new QProgressBar; 352 { prog = new QProgressBar;
346 table->setCellWidget (tableRow(), progcol, prog); 353 table->setCellWidget (tableRow(), progcol, prog);
347 } 354 }
348 355
349 prog->setRange (0, m_bytesTotal); 356 prog->setRange (0, m_bytesTotal);
350 prog->setValue (m_bytesRead); 357 prog->setValue (m_bytesRead);
351 break; 358 break;
352 359
353 case Finished: 360 case Finished:
354 case Failed: 361 case Failed:
355 { 362 { QLabel* lb = new QLabel ( (m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" :
356 QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : 363 "<b><span style=\"color: #800\">FAILED</span></b>");
357 "<b><span style=\"color: #800\">FAILED</span></b>");
358 lb->setAlignment (Qt::AlignCenter); 364 lb->setAlignment (Qt::AlignCenter);
359 table->setCellWidget (tableRow(), progcol, lb); 365 table->setCellWidget (tableRow(), progcol, lb);
360 } 366 }
361 break; 367 break;
362 } 368 }
363 369
364 QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), labelcol)); 370 QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), labelcol));
365 if (m_firstUpdate) { 371
366 lb = new QLabel (fmt ("<b>%1</b>", m_dest), table); 372 if (m_firstUpdate)
373 { lb = new QLabel (fmt ("<b>%1</b>", m_dest), table);
367 table->setCellWidget (tableRow(), labelcol, lb); 374 table->setCellWidget (tableRow(), labelcol, lb);
368 } 375 }
369 376
370 // Make sure that the cell is big enough to contain the label 377 // Make sure that the cell is big enough to contain the label
371 if (table->columnWidth (labelcol) < lb->width()) 378 if (table->columnWidth (labelcol) < lb->width())
372 table->setColumnWidth (labelcol, lb->width()); 379 table->setColumnWidth (labelcol, lb->width());
373 380
374 m_firstUpdate = false; 381 m_firstUpdate = false;
375 } 382 }
376 383
377 // ============================================================================= 384 // =============================================================================
378 // ----------------------------------------------------------------------------- 385 // -----------------------------------------------------------------------------
379 void PartDownloadRequest::downloadFinished() { 386 void PartDownloadRequest::downloadFinished()
380 if (m_reply->error() != QNetworkReply::NoError) { 387 { if (m_reply->error() != QNetworkReply::NoError)
381 if (m_primary && !m_prompt->aborted()) 388 { if (m_primary && !m_prompt->aborted())
382 critical (m_reply->errorString()); 389 critical (m_reply->errorString());
383 390
384 m_state = Failed; 391 m_state = Failed;
385 } elif (state() != Failed) 392 } elif (state() != Failed)
386 m_state = Finished; 393
387 394 m_state = Finished;
395
388 m_bytesRead = m_bytesTotal; 396 m_bytesRead = m_bytesTotal;
389 updateToTable(); 397 updateToTable();
390 398
391 if (m_fp) { 399 if (m_fp)
392 m_fp->close(); 400 { m_fp->close();
393 delete m_fp; 401 delete m_fp;
394 m_fp = null; 402 m_fp = null;
395 403
396 if (m_state == Failed) 404 if (m_state == Failed)
397 QFile::remove (m_fpath); 405 QFile::remove (m_fpath);
398 } 406 }
399 407
400 if (m_state != Finished) { 408 if (m_state != Finished)
401 m_prompt->checkIfFinished(); 409 { m_prompt->checkIfFinished();
402 return; 410 return;
403 } 411 }
404 412
405 // Try to load this file now. 413 // Try to load this file now.
406 LDFile* f = openDATFile (m_fpath, false); 414 LDFile* f = openDATFile (m_fpath, false);
415
407 if (!f) 416 if (!f)
408 return; 417 return;
409 418
410 f->setImplicit (!m_primary); 419 f->setImplicit (!m_primary);
411 420
412 // Iterate through this file and check for errors. If there's any that stems 421 // Iterate through this file and check for errors. If there's any that stems
413 // from unknown file references, try resolve that by downloading the reference. 422 // from unknown file references, try resolve that by downloading the reference.
414 // This is why downloading a part may end up downloading multiple files, as 423 // This is why downloading a part may end up downloading multiple files, as
415 // it resolves dependencies. 424 // it resolves dependencies.
416 for (LDObject* obj : f->objects()) { 425 for (LDObject* obj : f->objects())
417 LDError* err = dynamic_cast<LDError*> (obj); 426 { LDError* err = dynamic_cast<LDError*> (obj);
427
418 if (!err || err->fileRef().isEmpty()) 428 if (!err || err->fileRef().isEmpty())
419 continue; 429 continue;
420 430
421 str dest = err->fileRef(); 431 str dest = err->fileRef();
422 m_prompt->modifyDest (dest); 432 m_prompt->modifyDest (dest);
423 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); 433 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false);
424 } 434 }
425 435
426 if (m_primary) { 436 if (m_primary)
427 addRecentFile (m_fpath); 437 { addRecentFile (m_fpath);
428 m_prompt->setPrimaryFile (f); 438 m_prompt->setPrimaryFile (f);
429 } 439 }
430 440
431 m_prompt->checkIfFinished(); 441 m_prompt->checkIfFinished();
432 } 442 }
433 443
434 // ============================================================================= 444 // =============================================================================
435 // ----------------------------------------------------------------------------- 445 // -----------------------------------------------------------------------------
436 void PartDownloadRequest::downloadProgress (int64 recv, int64 total) { 446 void PartDownloadRequest::downloadProgress (int64 recv, int64 total)
437 m_bytesRead = recv; 447 { m_bytesRead = recv;
438 m_bytesTotal = total; 448 m_bytesTotal = total;
439 m_state = Downloading; 449 m_state = Downloading;
440 updateToTable(); 450 updateToTable();
441 } 451 }
442 452
443 // ============================================================================= 453 // =============================================================================
444 // ----------------------------------------------------------------------------- 454 // -----------------------------------------------------------------------------
445 void PartDownloadRequest::readyRead() { 455 void PartDownloadRequest::readyRead()
446 if (state() == Failed) 456 { if (state() == Failed)
447 return; 457 return;
448 458
449 if (m_fp == null) { 459 if (m_fp == null)
450 m_fpath.replace ("\\", "/"); 460 { m_fpath.replace ("\\", "/");
451 461
452 // We have already asked the user whether we can overwrite so we're good 462 // We have already asked the user whether we can overwrite so we're good
453 // to go here. 463 // to go here.
454 m_fp = new QFile (m_fpath.toLocal8Bit()); 464 m_fp = new QFile (m_fpath.toLocal8Bit());
455 if (!m_fp->open (QIODevice::WriteOnly)) { 465
456 critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno))); 466 if (!m_fp->open (QIODevice::WriteOnly))
467 { critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno)));
457 m_state = Failed; 468 m_state = Failed;
458 m_reply->abort(); 469 m_reply->abort();
459 updateToTable(); 470 updateToTable();
460 m_prompt->checkIfFinished(); 471 m_prompt->checkIfFinished();
461 return; 472 return;
462 } 473 }
463 } 474 }
464 475
465 m_fp->write (m_reply->readAll()); 476 m_fp->write (m_reply->readAll());
466 } 477 }
467 478
468 // ============================================================================= 479 // =============================================================================
469 // ----------------------------------------------------------------------------- 480 // -----------------------------------------------------------------------------
470 bool PartDownloadRequest::isFinished() const { 481 bool PartDownloadRequest::isFinished() const
471 return m_state == Finished || m_state == Failed; 482 { return m_state == Finished || m_state == Failed;
472 } 483 }
473 484
474 // ============================================================================= 485 // =============================================================================
475 // ----------------------------------------------------------------------------- 486 // -----------------------------------------------------------------------------
476 const PartDownloadRequest::State& PartDownloadRequest::state() const { 487 const PartDownloadRequest::State& PartDownloadRequest::state() const
477 return m_state; 488 { return m_state;
478 } 489 }
479 490
480 // ============================================================================= 491 // =============================================================================
481 // ----------------------------------------------------------------------------- 492 // -----------------------------------------------------------------------------
482 void PartDownloadRequest::abort() { 493 void PartDownloadRequest::abort()
483 m_reply->abort(); 494 { m_reply->abort();
484 } 495 }
485 496
486 // ============================================================================= 497 // =============================================================================
487 // ----------------------------------------------------------------------------- 498 // -----------------------------------------------------------------------------
488 DEFINE_ACTION (DownloadFrom, 0) { 499 DEFINE_ACTION (DownloadFrom, 0)
489 PartDownloader::k_download(); 500 { PartDownloader::k_download();
490 } 501 }
491 #include "moc_download.cpp"

mercurial