|    133 	// 48\ and p/48/. | 
   133 	// 48\ and p/48/. | 
|    134 	if (dest.left (2) == "s\\" || dest.left (2) == "s/") | 
   134 	if (dest.left (2) == "s\\" || dest.left (2) == "s/") | 
|    135 	{	dest.remove (0, 2); | 
   135 	{	dest.remove (0, 2); | 
|    136 		dest.prepend ("parts/s/"); | 
   136 		dest.prepend ("parts/s/"); | 
|    137 	} elif (dest.left (3) == "48\\" || dest.left (3) == "48/") | 
   137 	} elif (dest.left (3) == "48\\" || dest.left (3) == "48/") | 
|    138  | 
        | 
|    139 	{	dest.remove (0, 3); | 
   138 	{	dest.remove (0, 3); | 
|    140 		dest.prepend ("p/48/"); | 
   139 		dest.prepend ("p/48/"); | 
|    141 	} | 
   140 	} | 
|    142  | 
   141  | 
|    143 	/* Try determine where to put this part. We have four directories: | 
   142 	/* Try determine where to put this part. We have four directories: | 
|    185 // ============================================================================= | 
   184 // ============================================================================= | 
|    186 // ----------------------------------------------------------------------------- | 
   185 // ----------------------------------------------------------------------------- | 
|    187 void PartDownloader::buttonClicked (QAbstractButton* btn) | 
   186 void PartDownloader::buttonClicked (QAbstractButton* btn) | 
|    188 {	if (btn == getButton (Close)) | 
   187 {	if (btn == getButton (Close)) | 
|    189 	{	reject(); | 
   188 	{	reject(); | 
|    190 	} | 
   189 	} elif (btn == getButton (Abort)) | 
|    191 	elif (btn == getButton (Abort)) | 
        | 
|    192 	{	setAborted (true); | 
   190 	{	setAborted (true); | 
|    193  | 
   191  | 
|    194 		for (PartDownloadRequest* req : m_requests) | 
   192 		for (PartDownloadRequest* req : m_requests) | 
|    195 			req->abort(); | 
   193 			req->abort(); | 
|    196 	} | 
   194 	} elif (btn == getButton (Download)) | 
|    197 	elif (btn == getButton (Download)) | 
        | 
|    198 	{	str dest = ui->fname->text(); | 
   195 	{	str dest = ui->fname->text(); | 
|    199 		setPrimaryFile (null); | 
   196 		setPrimaryFile (null); | 
|    200 		setAborted (false); | 
   197 		setAborted (false); | 
|    201  | 
   198  | 
|    202 		if (getSource() == CustomURL) | 
   199 		if (getSource() == CustomURL) | 
|    242 } | 
   239 } | 
|    243  | 
   240  | 
|    244 // ============================================================================= | 
   241 // ============================================================================= | 
|    245 // ----------------------------------------------------------------------------- | 
   242 // ----------------------------------------------------------------------------- | 
|    246 void PartDownloader::checkIfFinished() | 
   243 void PartDownloader::checkIfFinished() | 
|    247 {	bool failed = aborted(); | 
   244 {	bool failed = isAborted(); | 
|    248  | 
   245  | 
|    249 	// If there is some download still working, we're not finished. | 
   246 	// If there is some download still working, we're not finished. | 
|    250 	for (PartDownloadRequest* req : m_requests) | 
   247 	for (PartDownloadRequest* req : m_requests) | 
|    251 	{	if (!req->isFinished()) | 
   248 	{	if (!req->isFinished()) | 
|    252 			return; | 
   249 			return; | 
|    347 	QProgressBar* prog; | 
   344 	QProgressBar* prog; | 
|    348  | 
   345  | 
|    349 	switch (m_state) | 
   346 	switch (m_state) | 
|    350 	{	case Requesting: | 
   347 	{	case Requesting: | 
|    351 		case Downloading: | 
   348 		case Downloading: | 
|    352 		{	prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol)); | 
   349 		{	prog = qobject_cast<QProgressBar*> (table->cellWidget (getTableRow(), progcol)); | 
|    353  | 
   350  | 
|    354 			if (!prog) | 
   351 			if (!prog) | 
|    355 			{	prog = new QProgressBar; | 
   352 			{	prog = new QProgressBar; | 
|    356 				table->setCellWidget (tableRow(), progcol, prog); | 
   353 				table->setCellWidget (getTableRow(), progcol, prog); | 
|    357 			} | 
   354 			} | 
|    358  | 
   355  | 
|    359 			prog->setRange (0, m_bytesTotal); | 
   356 			prog->setRange (0, m_bytesTotal); | 
|    360 			prog->setValue (m_bytesRead); | 
   357 			prog->setValue (m_bytesRead); | 
|    361 		} break; | 
   358 		} break; | 
|    363 		case Finished: | 
   360 		case Finished: | 
|    364 		case Failed: | 
   361 		case Failed: | 
|    365 		{	QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : | 
   362 		{	QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : | 
|    366 									  "<b><span style=\"color: #800\">FAILED</span></b>"); | 
   363 									  "<b><span style=\"color: #800\">FAILED</span></b>"); | 
|    367 			lb->setAlignment (Qt::AlignCenter); | 
   364 			lb->setAlignment (Qt::AlignCenter); | 
|    368 			table->setCellWidget (tableRow(), progcol, lb); | 
   365 			table->setCellWidget (getTableRow(), progcol, lb); | 
|    369 		} break; | 
   366 		} break; | 
|    370 	} | 
   367 	} | 
|    371  | 
   368  | 
|    372 	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), labelcol)); | 
   369 	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (getTableRow(), labelcol)); | 
|    373  | 
   370  | 
|    374 	if (m_firstUpdate) | 
   371 	if (m_firstUpdate) | 
|    375 	{	lb = new QLabel (fmt ("<b>%1</b>", m_dest), table); | 
   372 	{	lb = new QLabel (fmt ("<b>%1</b>", m_dest), table); | 
|    376 		table->setCellWidget (tableRow(), labelcol, lb); | 
   373 		table->setCellWidget (getTableRow(), labelcol, lb); | 
|    377 	} | 
   374 	} | 
|    378  | 
   375  | 
|    379 	// Make sure that the cell is big enough to contain the label | 
   376 	// Make sure that the cell is big enough to contain the label | 
|    380 	if (table->columnWidth (labelcol) < lb->width()) | 
   377 	if (table->columnWidth (labelcol) < lb->width()) | 
|    381 		table->setColumnWidth (labelcol, lb->width()); | 
   378 		table->setColumnWidth (labelcol, lb->width()); | 
|    385  | 
   382  | 
|    386 // ============================================================================= | 
   383 // ============================================================================= | 
|    387 // ----------------------------------------------------------------------------- | 
   384 // ----------------------------------------------------------------------------- | 
|    388 void PartDownloadRequest::downloadFinished() | 
   385 void PartDownloadRequest::downloadFinished() | 
|    389 {	if (m_reply->error() != QNetworkReply::NoError) | 
   386 {	if (m_reply->error() != QNetworkReply::NoError) | 
|    390 	{	if (m_primary && !m_prompt->aborted()) | 
   387 	{	if (m_primary && !m_prompt->isAborted()) | 
|    391 			critical (m_reply->errorString()); | 
   388 			critical (m_reply->errorString()); | 
|    392  | 
   389  | 
|    393 		m_state = Failed; | 
   390 		m_state = Failed; | 
|    394 	} elif (state() != Failed) | 
   391 	} elif (state() != Failed) | 
|    395 		m_state = Finished; | 
   392 		m_state = Finished; | 
|    421  | 
   418  | 
|    422 	// Iterate through this file and check for errors. If there's any that stems | 
   419 	// Iterate through this file and check for errors. If there's any that stems | 
|    423 	// from unknown file references, try resolve that by downloading the reference. | 
   420 	// from unknown file references, try resolve that by downloading the reference. | 
|    424 	// This is why downloading a part may end up downloading multiple files, as | 
   421 	// This is why downloading a part may end up downloading multiple files, as | 
|    425 	// it resolves dependencies. | 
   422 	// it resolves dependencies. | 
|    426 	for (LDObject* obj : f->objects()) | 
   423 	for (LDObject* obj : f->getObjects()) | 
|    427 	{	LDError* err = dynamic_cast<LDError*> (obj); | 
   424 	{	LDError* err = dynamic_cast<LDError*> (obj); | 
|    428  | 
   425  | 
|    429 		if (!err || err->fileRef().isEmpty()) | 
   426 		if (!err || err->getFileReferenced().isEmpty()) | 
|    430 			continue; | 
   427 			continue; | 
|    431  | 
   428  | 
|    432 		str dest = err->fileRef(); | 
   429 		str dest = err->getFileReferenced(); | 
|    433 		m_prompt->modifyDestination (dest); | 
   430 		m_prompt->modifyDestination (dest); | 
|    434 		m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); | 
   431 		m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); | 
|    435 	} | 
   432 	} | 
|    436  | 
   433  | 
|    437 	if (m_primary) | 
   434 	if (m_primary) |