added config option, refined logic and regexps. This behaves coherently now. :)

Sat, 03 Aug 2013 00:56:02 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 03 Aug 2013 00:56:02 +0300
changeset 430
8458cf2719d1
parent 429
3488534b2b31
child 431
ec1e2059319b

added config option, refined logic and regexps. This behaves coherently now. :)

src/config.cpp file | annotate | diff | comparison | revisions
src/configDialog.cpp file | annotate | diff | comparison | revisions
src/configDialog.h 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/ui/config.ui file | annotate | diff | comparison | revisions
--- a/src/config.cpp	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/config.cpp	Sat Aug 03 00:56:02 2013 +0300
@@ -44,7 +44,7 @@
 		return false;
 
 	// Read the values.
-for (str line : f) {
+	for (str line : f) {
 		ln++;
 
 		if (line.isEmpty() || line[0] == '#')
--- a/src/configDialog.cpp	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/configDialog.cpp	Sat Aug 03 00:56:02 2013 +0300
@@ -46,6 +46,20 @@
 extern_cfg (bool, edit_schemanticinline);
 extern_cfg (bool, gl_blackedges);
 extern_cfg (bool, gui_implicitfiles);
+extern_cfg (str, net_downloadpath);
+
+extern_cfg (str, prog_ytruder);
+extern_cfg (str, prog_rectifier);
+extern_cfg (str, prog_intersector);
+extern_cfg (str, prog_coverer);
+extern_cfg (str, prog_isecalc);
+extern_cfg (str, prog_edger2);
+extern_cfg (bool, prog_ytruder_wine);
+extern_cfg (bool, prog_rectifier_wine);
+extern_cfg (bool, prog_intersector_wine);
+extern_cfg (bool, prog_coverer_wine);
+extern_cfg (bool, prog_isecalc_wine);
+extern_cfg (bool, prog_edger2_wine);
 
 #define act(N) extern_cfg (keyseq, key_##N);
 #include "actions.h"
@@ -62,6 +76,9 @@
 	initQuickColorTab();
 	initGridTab();
 	initExtProgTab();
+	
+	ui->downloadPath->setText (net_downloadpath);
+	connect (ui->findDownloadPath, SIGNAL (clicked(bool)), this, SLOT (slot_findDownloadFolder()));
 }
 
 // =============================================================================
@@ -187,19 +204,6 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-extern_cfg (str, prog_ytruder);
-extern_cfg (str, prog_rectifier);
-extern_cfg (str, prog_intersector);
-extern_cfg (str, prog_coverer);
-extern_cfg (str, prog_isecalc);
-extern_cfg (str, prog_edger2);
-extern_cfg (bool, prog_ytruder_wine);
-extern_cfg (bool, prog_rectifier_wine);
-extern_cfg (bool, prog_intersector_wine);
-extern_cfg (bool, prog_coverer_wine);
-extern_cfg (bool, prog_isecalc_wine);
-extern_cfg (bool, prog_edger2_wine);
-
 static const struct extProgInfo {
 	const str name, iconname;
 	strconfig* const path;
@@ -516,6 +520,13 @@
 }
 
 // =============================================================================
+// -----------------------------------------------------------------------------
+void ConfigDialog::slot_findDownloadFolder() {
+	str dpath = QFileDialog::getExistingDirectory();
+	ui->downloadPath->setText (dpath);
+}
+
+// =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void ConfigDialog::setShortcutText (ShortcutListItem* item) {
@@ -568,6 +579,10 @@
 		gl_linethickness = dlg.getUI()->lineThickness->value();
 		gui_implicitfiles = dlg.getUI()->implicitFiles->isChecked();
 		
+		net_downloadpath = dlg.getUI()->downloadPath->text();
+		if (net_downloadpath.value.right (1) != DIRSLASH)
+			net_downloadpath += DIRSLASH;
+		
 		// Rebuild the quick color toolbar
 		g_win->setQuickColors (dlg.quickColors);
 		gui_colortoolbar = dlg.quickColorString();
--- a/src/configDialog.h	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/configDialog.h	Sat Aug 03 00:56:02 2013 +0300
@@ -83,6 +83,7 @@
 	void slot_moveColor();
 	void slot_clearColors();
 	void slot_setExtProgPath();
+	void slot_findDownloadFolder();
 };
 
 // =============================================================================
--- a/src/download.cpp	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/download.cpp	Sat Aug 03 00:56:02 2013 +0300
@@ -31,18 +31,39 @@
 
 PartDownloader g_PartDownloader;
 
+cfg (str, net_downloadpath, "");
+
 constexpr const char* PartDownloader::k_OfficialURL,
 	*PartDownloader::k_UnofficialURL;
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloader::download() {
+	str path = getDownloadPath();
+	if (path == "" || QDir (path).exists() == false) {
+		critical (PartDownloadPrompt::tr ("You need to specify a valid path for "
+			"downloaded files in the configuration to download paths."));
+		return;
+	}
+	
 	PartDownloadPrompt* dlg = new PartDownloadPrompt;
 	dlg->exec();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
+str PartDownloader::getDownloadPath() {
+	str path = net_downloadpath;
+	
+#if DIRSLASH_CHAR != '/'
+	path.replace (DIRSLASH, "/");
+#endif
+	
+	return path;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
 PartDownloadPrompt::PartDownloadPrompt (QWidget* parent) : QDialog (parent) {
 	ui = new Ui_DownloadFrom;
 	ui->setupUi (this);
@@ -62,13 +83,13 @@
 // -----------------------------------------------------------------------------
 str PartDownloadPrompt::getURL() const {
 	const Source src = getSource();
+	str dest;
 	
 	switch (src) {
-/*	case OfficialLibrary:
-		return str (PartDownloader::k_OfficialURL) + getDest();
-*/
 	case PartsTracker:
-		return str (PartDownloader::k_UnofficialURL) + getDest();
+		dest = ui->fname->text();
+		modifyDest (dest);
+		return str (PartDownloader::k_UnofficialURL) + dest;
 	
 	case CustomURL:
 		return ui->fname->text();
@@ -80,30 +101,31 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-str PartDownloadPrompt::getDest() const {
-	str fname = ui->fname->text();
+void PartDownloadPrompt::modifyDest (str& dest) const {
+	dest = dest.simplified();
 	
 	if (getSource() == CustomURL)
-		fname = basename (fname);
+		dest = basename (dest);
 	
 	// Ensure .dat extension
-	if (fname.right (4) != ".dat") {
+	if (dest.right (4) != ".dat") {
 		// Remove the existing extension, if any. It may be we're here over a
 		// typo in the .dat extension.
-		if (fname.lastIndexOf (".") >= fname.length() - 4)
-			fname.chop (fname.length() - fname.lastIndexOf ("."));
+		const int dotpos = dest.lastIndexOf (".");
+		if (dotpos != -1 && dotpos >= dest.length() - 4)
+			dest.chop (dest.length() - dotpos);
 		
-		fname += ".dat";
+		dest += ".dat";
 	}
 	
 	// If the part starts with s\ or s/, then use parts/s/. Same goes with
 	// 48\ and p/48/.
-	if (fname.left (2) == "s\\" || fname.left (2) == "s/") {
-		fname.remove (0, 2);
-		fname.prepend ("parts/s/");
-	} elif (fname.left (3) == "48\\" || fname.left (3) == "48/") {
-		fname.remove (0, 3);
-		fname.prepend ("p/48/");
+	if (dest.left (2) == "s\\" || dest.left (2) == "s/") {
+		dest.remove (0, 2);
+		dest.prepend ("parts/s/");
+	} elif (dest.left (3) == "48\\" || dest.left (3) == "48/") {
+		dest.remove (0, 3);
+		dest.prepend ("p/48/");
 	}
 	
 	/* Try determine where to put this part. We have four directories:
@@ -119,27 +141,19 @@
 	 * file names.
 	 */
 	{
-		str partRegex = "^[0-9]+(c[0-9][0-9]+)*(d[0-9][0-9]+)*[a-z]?";
+		str partRegex = "^u?[0-9]+(c[0-9][0-9]+)*(d[0-9][0-9]+)*[a-z]?(p[0-9a-z][0-9a-z]+)*";
 		str subpartRegex = partRegex + "s[0-9][0-9]+";
 		
 		partRegex += "\\.dat$";
 		subpartRegex += "\\.dat$";
 		
-		if (QRegExp (subpartRegex).exactMatch (fname))
-			fname.prepend ("parts/s/");
-		elif (QRegExp (partRegex).exactMatch (fname))
-			fname.prepend ("parts/");
-		elif (fname.left (6) != "parts/" && fname.left (2) != "p/")
-			fname.prepend ("p/");
+		if (QRegExp (subpartRegex).exactMatch (dest))
+			dest.prepend ("parts/s/");
+		elif (QRegExp (partRegex).exactMatch (dest))
+			dest.prepend ("parts/");
+		elif (dest.left (6) != "parts/" && dest.left (2) != "p/")
+			dest.prepend ("p/");
 	}
-	
-	return fname;
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-str PartDownloadPrompt::fullFilePath() const {
-	return "/home/arezey/ldraw/downloads/" + getDest(); // FIXME: hehe
 }
 
 // =============================================================================
@@ -164,22 +178,26 @@
 	ui->buttonBox->setEnabled (false);
 	ui->fname->setEnabled (false);
 	ui->source->setEnabled (false);
-	downloadFile (getDest(), true);
+	
+	str dest = ui->fname->text();
+	modifyDest (dest);
+	downloadFile (dest, getURL(), true);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void PartDownloadPrompt::downloadFile (const str& path, bool primary) {
+void PartDownloadPrompt::downloadFile (str dest, str url, bool primary) {
 	const int row = ui->progress->rowCount();
 	
 	// Don't download files repeadetly.
-	if (m_filesToDownload.find (path) != -1u)
+	if (m_filesToDownload.find (dest) != -1u)
 		return;
 	
-	print ("%1: row: %2\n", path, row);
-	PartDownloadRequest* req = new PartDownloadRequest (getURL(), path, primary, this);
+	modifyDest (dest);
+	print ("DOWNLOAD: %1 -> %2\n", url, PartDownloader::getDownloadPath() + dest);
+	PartDownloadRequest* req = new PartDownloadRequest (url, dest, primary, this);
 	
-	m_filesToDownload << path;
+	m_filesToDownload << dest;
 	m_requests << req;
 	ui->progress->insertRow (row);
 	req->setTableRow (row);
@@ -195,11 +213,17 @@
 			return;
 	
 	// Update everything now
+	reloadAllSubfiles();
 	g_win->fullRefresh();
 	g_win->R()->resetAngles();
 	
-	// Close the dialog
-	accept();
+	// 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();
 }
 
 // =============================================================================
@@ -209,12 +233,15 @@
 	m_prompt (parent),
 	m_url (url),
 	m_dest (dest),
-	m_fpath (m_prompt->fullFilePath()),
+	m_fpath (PartDownloader::getDownloadPath() + dest),
 	m_nam (new QNetworkAccessManager),
 	m_firstUpdate (true),
 	m_state (Requesting),
 	m_primary (primary)
 {
+	m_fpath.replace ("\\", "/");
+	QFile::remove (m_fpath);
+	
 	// Make sure that we have a valid destination.
 	str dirpath = dirname (m_fpath);
 	
@@ -270,9 +297,8 @@
 	
 	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), PartLabelColumn));
 	if (m_firstUpdate) {
-		lb = new QLabel (fmt ("<b>%1</b><br>%2", m_dest, m_url), table);
+		lb = new QLabel (fmt ("<b>%1</b>", m_dest), table);
 		table->setCellWidget (tableRow(), PartLabelColumn, lb);
-		table->setRowHeight (tableRow(), lb->height());
 	}
 	
 	// Make sure that the cell is big enough to contain the label
@@ -301,8 +327,10 @@
 	
 	f->setImplicit (!m_primary);
 	
-	// Check for any errors which stemmed from unresolved references.
-	// Try to solve these by downloading them.
+	// Iterate through this file and check for errors. If there's any that stems
+	// from unknown file references, try resolve that by downloading the reference.
+	// This is why downloading a part may end up downloading multiple files, as
+	// it resolves dependencies.
 	for (LDObject* obj : *f) {
 		if (obj->getType() != LDObject::Error)
 			continue;
@@ -311,7 +339,9 @@
 		if (err->fileRef() == "")
 			continue;
 		
-		m_prompt->downloadFile (err->fileRef(), false);
+		str dest = err->fileRef();
+		m_prompt->modifyDest (dest);
+		m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false);
 	}
 	
 	if (m_primary)
--- a/src/download.h	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/download.h	Sat Aug 03 00:56:02 2013 +0300
@@ -38,6 +38,7 @@
 	
 	PartDownloader() {}
 	void download();
+	static str getDownloadPath();
 	void operator()() { download(); }
 } g_PartDownloader;
 
@@ -56,10 +57,10 @@
 	explicit PartDownloadPrompt (QWidget* parent = null);
 	virtual ~PartDownloadPrompt();
 	str getURL() const;
-	str fullFilePath() const;
-	str getDest() const;
+	str getDest(str fname) const;
 	Source getSource() const;
-	void downloadFile (const str& path, bool primary);
+	void downloadFile (str dest, str url, bool primary);
+	void modifyDest (str& dest) const;
 	
 public slots:
 	void sourceChanged (int i);
--- a/src/file.cpp	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/file.cpp	Sat Aug 03 00:56:02 2013 +0300
@@ -33,6 +33,7 @@
 
 cfg (str, io_ldpath, "");
 cfg (str, io_recentfiles, "");
+extern_cfg (str, net_downloadpath);
 
 static bool g_loadingMainFile = false;
 static const int g_MaxRecentFiles = 5;
@@ -182,9 +183,8 @@
 		// in the immediate vicinity of the current model to override stock LDraw stuff.
 		str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->name()), relpath);
 		
-		if (f->open (partpath, File::Read)) {
+		if (f->open (partpath, File::Read))
 			return f;
-		}
 	}
 	
 	if (f->open (relpath, File::Read))
@@ -197,10 +197,10 @@
 		return f;
 	
 	if (subdirs) {
-		// Look in sub-directories: parts and p
-		for (auto subdir : initlist<const str> ({ "parts", "p" })) {
-			fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", io_ldpath, subdir, relpath);
-			
+		// Look in sub-directories: parts and p. Also look in net_downloadpath.
+		for (const str& topdir : initlist<str> ({ io_ldpath, net_downloadpath }))
+		for (const str& subdir : initlist<str> ({ "parts", "p" })) {
+			fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath);
 			if (f->open (fullPath, File::Read))
 				return f;
 		}
--- a/src/ui/config.ui	Fri Aug 02 23:24:49 2013 +0300
+++ b/src/ui/config.ui	Sat Aug 03 00:56:02 2013 +0300
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>476</width>
+    <width>513</width>
     <height>377</height>
    </rect>
   </property>
@@ -24,7 +24,7 @@
       <enum>QTabWidget::North</enum>
      </property>
      <property name="currentIndex">
-      <number>0</number>
+      <number>5</number>
      </property>
      <property name="elideMode">
       <enum>Qt::ElideNone</enum>
@@ -493,6 +493,51 @@
        </item>
       </layout>
      </widget>
+     <widget class="QWidget" name="tab_6">
+      <attribute name="title">
+       <string>Downloads</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_7">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QLabel" name="label_4">
+           <property name="text">
+            <string>Download path:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="downloadPath"/>
+         </item>
+         <item>
+          <widget class="QPushButton" name="findDownloadPath">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset resource="../../ldforge.qrc">
+             <normaloff>:/icons/folder.png</normaloff>:/icons/folder.png</iconset>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
     </widget>
    </item>
    <item>

mercurial