Sat, 03 Aug 2013 02:18:41 +0300
stability to downloading
src/configDialog.cpp | file | annotate | diff | comparison | revisions | |
src/dialogs.cpp | file | annotate | diff | comparison | revisions | |
src/download.cpp | file | annotate | diff | comparison | revisions | |
src/download.h | file | annotate | diff | comparison | revisions | |
src/file.cpp | file | annotate | diff | comparison | revisions | |
src/file.h | file | annotate | diff | comparison | revisions | |
src/ui/config.ui | file | annotate | diff | comparison | revisions |
--- a/src/configDialog.cpp Sat Aug 03 00:56:02 2013 +0300 +++ b/src/configDialog.cpp Sat Aug 03 02:18:41 2013 +0300 @@ -47,6 +47,8 @@ extern_cfg (bool, gl_blackedges); extern_cfg (bool, gui_implicitfiles); extern_cfg (str, net_downloadpath); +extern_cfg (bool, net_guesspaths); +extern_cfg (bool, net_autoclose); extern_cfg (str, prog_ytruder); extern_cfg (str, prog_rectifier); @@ -78,6 +80,8 @@ initExtProgTab(); ui->downloadPath->setText (net_downloadpath); + ui->guessNetPaths->setChecked (net_guesspaths); + ui->autoCloseNetPrompt->setChecked (net_autoclose); connect (ui->findDownloadPath, SIGNAL (clicked(bool)), this, SLOT (slot_findDownloadFolder())); } @@ -578,8 +582,10 @@ gl_maincolor_alpha = ((double) dlg.getUI()->mainColorAlpha->value()) / 10.0f; gl_linethickness = dlg.getUI()->lineThickness->value(); gui_implicitfiles = dlg.getUI()->implicitFiles->isChecked(); + net_downloadpath = dlg.getUI()->downloadPath->text(); + net_guesspaths = dlg.getUI()->guessNetPaths->isChecked(); + net_autoclose = dlg.getUI()->autoCloseNetPrompt->isChecked(); - net_downloadpath = dlg.getUI()->downloadPath->text(); if (net_downloadpath.value.right (1) != DIRSLASH) net_downloadpath += DIRSLASH;
--- a/src/dialogs.cpp Sat Aug 03 00:56:02 2013 +0300 +++ b/src/dialogs.cpp Sat Aug 03 02:18:41 2013 +0300 @@ -25,7 +25,7 @@ #include <QPushButton> #include <QBoxLayout> #include <QGridLayout> -#include <qprogressbar.h> +#include <QProgressBar> #include <QCheckBox> #include "dialogs.h"
--- a/src/download.cpp Sat Aug 03 00:56:02 2013 +0300 +++ b/src/download.cpp Sat Aug 03 02:18:41 2013 +0300 @@ -32,6 +32,8 @@ PartDownloader g_PartDownloader; cfg (str, net_downloadpath, ""); +cfg (bool, net_guesspaths, true); +cfg (bool, net_autoclose, false); constexpr const char* PartDownloader::k_OfficialURL, *PartDownloader::k_UnofficialURL; @@ -104,8 +106,9 @@ void PartDownloadPrompt::modifyDest (str& dest) const { dest = dest.simplified(); - if (getSource() == CustomURL) - dest = basename (dest); + // If the user doesn't want us to guess, stop right here. + if (net_guesspaths == false) + return; // Ensure .dat extension if (dest.right (4) != ".dat") { @@ -174,13 +177,25 @@ // ============================================================================= // ----------------------------------------------------------------------------- void PartDownloadPrompt::startDownload() { + str dest = ui->fname->text(); + setPrimaryFile (null); + + if (getSource() == CustomURL) + dest = basename (getURL()); + + modifyDest (dest); + + if (QFile::exists (PartDownloader::getDownloadPath() + dest)) { + const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest); + + if (!confirm (tr ("Overwrite?"), overwritemsg)) + return; + } + ui->progress->setEnabled (true); ui->buttonBox->setEnabled (false); ui->fname->setEnabled (false); ui->source->setEnabled (false); - - str dest = ui->fname->text(); - modifyDest (dest); downloadFile (dest, getURL(), true); } @@ -207,23 +222,39 @@ // ============================================================================= // ----------------------------------------------------------------------------- void PartDownloadPrompt::checkIfFinished() { + bool failed = false; + // If there is some download still working, we're not finished. - for (PartDownloadRequest* req : m_requests) + for (PartDownloadRequest* req : m_requests) { if (!req->isFinished()) return; + + if (req->state() == PartDownloadRequest::Failed) + failed = true; + } + + for (PartDownloadRequest* req : m_requests) + delete req; // Update everything now - reloadAllSubfiles(); - g_win->fullRefresh(); - g_win->R()->resetAngles(); - - // Allow the prompt be closed now. - ui->buttonBox->disconnect (SIGNAL (accepted())); - connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept())); - ui->buttonBox->setEnabled (true); - ui->progress->setEnabled (false); - - // accept(); + if (primaryFile()) { + LDFile::setCurrent (primaryFile()); + reloadAllSubfiles(); + g_win->fullRefresh(); + g_win->R()->resetAngles(); + m_requests.clear(); + + if (net_autoclose && !failed) { + // Close automatically if desired. + accept(); + } else { + // Allow the prompt be closed now. + ui->buttonBox->disconnect (SIGNAL (accepted())); + connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept())); + ui->buttonBox->setEnabled (true); + ui->progress->setEnabled (false); + } + } } // ============================================================================= @@ -237,11 +268,9 @@ m_nam (new QNetworkAccessManager), m_firstUpdate (true), m_state (Requesting), - m_primary (primary) + m_primary (primary), + m_fp (null) { - m_fpath.replace ("\\", "/"); - QFile::remove (m_fpath); - // Make sure that we have a valid destination. str dirpath = dirname (m_fpath); @@ -285,7 +314,6 @@ case Finished: case Failed: - case Aborted: { QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : "<b><span style=\"color: #800\">FAILED</span></b>"); @@ -311,15 +339,27 @@ // ============================================================================= // ----------------------------------------------------------------------------- void PartDownloadRequest::downloadFinished() { - m_state = m_reply->error() == QNetworkReply::NoError ? Finished : Failed; + if (m_reply->error() != QNetworkReply::NoError) + m_state = Failed; + elif (state() != Failed) + m_state = Finished; + m_bytesRead = m_bytesTotal; updateToTable(); + if (m_fp) { + m_fp->close(); + delete m_fp; + m_fp = null; + } + if (m_state != Finished) { m_prompt->checkIfFinished(); return; } + print ("state: %1\n", (int) m_state); + // Try to load this file now. LDFile* f = openDATFile (m_fpath, false); if (!f) @@ -345,7 +385,7 @@ } if (m_primary) - LDFile::setCurrent (f); + m_prompt->setPrimaryFile (f); m_prompt->checkIfFinished(); } @@ -362,12 +402,26 @@ // ============================================================================= // ----------------------------------------------------------------------------- void PartDownloadRequest::readyRead() { - QFile f (m_fpath); - if (!f.open (QIODevice::Append)) + if (state() == Failed) return; - f.write (m_reply->readAll()); - f.close(); + if (m_fp == null) { + m_fpath.replace ("\\", "/"); + + // We have already asked the user whether we can overwrite so we're good + // to go here. + m_fp = new QFile (m_fpath); + if (!m_fp->open (QIODevice::WriteOnly)) { + critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno))); + m_state = Failed; + m_reply->abort(); + updateToTable(); + m_prompt->checkIfFinished(); + return; + } + } + + m_fp->write (m_reply->readAll()); } // ============================================================================= @@ -384,7 +438,13 @@ // ============================================================================= // ----------------------------------------------------------------------------- bool PartDownloadRequest::isFinished() const { - return m_state == Finished || m_state == Failed || m_state == Aborted; + return m_state == Finished || m_state == Failed; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +const PartDownloadRequest::State& PartDownloadRequest::state() const { + return m_state; } // =============================================================================
--- a/src/download.h Sat Aug 03 00:56:02 2013 +0300 +++ b/src/download.h Sat Aug 03 02:18:41 2013 +0300 @@ -23,6 +23,8 @@ #include "common.h" #include "types.h" +class LDFile; +class QFile; class PartDownloadRequest; class Ui_DownloadFrom; class QNetworkAccessManager; @@ -46,18 +48,17 @@ // ----------------------------------------------------------------------------- class PartDownloadPrompt : public QDialog { Q_OBJECT + PROPERTY (LDFile*, primaryFile, setPrimaryFile) public: enum Source { -/* OfficialLibrary, - */ PartsTracker, + PartsTracker, CustomURL, }; explicit PartDownloadPrompt (QWidget* parent = null); virtual ~PartDownloadPrompt(); str getURL() const; - str getDest(str fname) const; Source getSource() const; void downloadFile (str dest, str url, bool primary); void modifyDest (str& dest) const; @@ -93,7 +94,6 @@ Downloading, Finished, Failed, - Aborted, }; explicit PartDownloadRequest (str url, str dest, bool primary, PartDownloadPrompt* parent); @@ -101,6 +101,7 @@ virtual ~PartDownloadRequest(); void updateToTable(); bool isFinished() const; + const State& state() const; void operator= (const PartDownloadRequest&) = delete; @@ -119,6 +120,7 @@ State m_state; int64 m_bytesRead, m_bytesTotal; bool m_primary; + QFile* m_fp; }; #endif // LDFORGE_DOWNLOAD_H \ No newline at end of file
--- a/src/file.cpp Sat Aug 03 00:56:02 2013 +0300 +++ b/src/file.cpp Sat Aug 03 02:18:41 2013 +0300 @@ -241,7 +241,7 @@ work (0); } -void FileLoader::work (ulong i) { +void FileLoader::work (int i) { if (aborted()) { // We were flagged for abortion, so abort. for (LDObject* obj : m_objs) @@ -252,10 +252,10 @@ return; } - ulong max = i + 300; + int max = i + 300; - for (; i < max && i < lines().size(); ++i) { - str line = lines() [i]; + for (; i < max && i < (int) lines().size(); ++i) { + str line = lines()[i]; // Trim the trailing newline qchar c; @@ -269,9 +269,8 @@ if (obj->getType() == LDObject::Error) { log ("Couldn't parse line #%1: %2", m_progress + 1, static_cast<LDErrorObject*> (obj)->reason); - if (m_warningsPointer) { - (*m_warningsPointer) ++; - } + if (m_warningsPointer) + (*m_warningsPointer)++; } m_objs << obj; @@ -281,9 +280,10 @@ dlg->updateProgress (i); } - if (i >= lines().size() - 1) { + if (i >= ((int) lines().size()) - 1) { emit workDone(); setDone (true); + return; } if (!done()) { @@ -701,7 +701,7 @@ // If we cannot open the file, mark it an error if (!load) { - LDErrorObject* obj = new LDErrorObject (line, "Could not open referred file"); + LDErrorObject* obj = new LDErrorObject (line, fmt ("Could not open %1", tokens[14])); obj->setFileRef (tokens[14]); return obj; }
--- a/src/file.h Sat Aug 03 00:56:02 2013 +0300 +++ b/src/file.h Sat Aug 03 02:18:41 2013 +0300 @@ -202,7 +202,7 @@ OpenProgressDialog* dlg; private slots: - void work (ulong i); + void work (int i); signals: void progressUpdate (int progress);
--- a/src/ui/config.ui Sat Aug 03 00:56:02 2013 +0300 +++ b/src/ui/config.ui Sat Aug 03 02:18:41 2013 +0300 @@ -495,7 +495,7 @@ </widget> <widget class="QWidget" name="tab_6"> <attribute name="title"> - <string>Downloads</string> + <string>Downloading</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_7"> <item> @@ -524,6 +524,34 @@ </layout> </item> <item> + <widget class="QCheckBox" name="guessNetPaths"> + <property name="whatsThis"> + <string><p>When this is set, LDForge tries to adjust and correct part paths based on the input. A full path given to the download prompt should be of form <tt>"&lt;dir&gt;/&lt;file&gt;.dat"</tt> - with this set, input can be automatically completed.</p> + +<p>Examples: +<ul> +<li>3002 -> parts/3002.dat</li> +<li>3002.da -> parts/3002.dat</li> +<li>3002s01 -> parts/s/3002s01.dat</li> +<li>4-4cyli -> p/4-4cyli.dat</li> +</ul></p></string> + </property> + <property name="text"> + <string>Correct and guess part paths</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="autoCloseNetPrompt"> + <property name="whatsThis"> + <string>If this is set, LDForge will close the download prompt after everything has been downloaded. The prompt will not be closed if a download has failed.</string> + </property> + <property name="text"> + <string>Close download prompt after completion</string> + </property> + </widget> + </item> + <item> <spacer name="verticalSpacer_5"> <property name="orientation"> <enum>Qt::Vertical</enum>