src/download.cpp

changeset 431
ec1e2059319b
parent 430
8458cf2719d1
child 432
ef382b98a8af
--- 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;
 }
 
 // =============================================================================

mercurial