stability to downloading

Sat, 03 Aug 2013 02:18:41 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 03 Aug 2013 02:18:41 +0300
changeset 431
ec1e2059319b
parent 430
8458cf2719d1
child 432
ef382b98a8af

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>&lt;p&gt;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 &lt;tt&gt;&quot;&amp;lt;dir&amp;gt;/&amp;lt;file&amp;gt;.dat&quot;&lt;/tt&gt; - with this set, input can be automatically completed.&lt;/p&gt;
+
+&lt;p&gt;Examples:
+&lt;ul&gt;
+&lt;li&gt;3002 -&gt; parts/3002.dat&lt;/li&gt;
+&lt;li&gt;3002.da -&gt; parts/3002.dat&lt;/li&gt;
+&lt;li&gt;3002s01 -&gt; parts/s/3002s01.dat&lt;/li&gt;
+&lt;li&gt;4-4cyli -&gt; p/4-4cyli.dat&lt;/li&gt;
+&lt;/ul&gt;&lt;/p&gt;</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>

mercurial