void DownloadFromDCWidget::on_ok_clicked()
{
	updateState(DOWNLOADING);

	// I don't really think that create/destroy the thread
	// is really necessary.
	if (thread) {
		thread->deleteLater();
	}

	data.devname = strdup(ui.device->currentText().toUtf8().data());
	data.vendor = strdup(ui.vendor->currentText().toUtf8().data());
	data.product = strdup(ui.product->currentText().toUtf8().data());

	data.descriptor = descriptorLookup[ui.vendor->currentText() + ui.product->currentText()];
	data.force_download = ui.forceDownload->isChecked();
	data.deviceid = data.diveid = 0;
	set_default_dive_computer(data.vendor, data.product);
	set_default_dive_computer_device(data.devname);

	thread = new DownloadThread(this, &data);

	connect(thread, SIGNAL(finished()),
			this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection);

	MainWindow *w = MainWindow::instance();
	connect(thread, SIGNAL(finished()), w, SLOT(refreshDisplay()));

	// before we start, remember where the dive_table ended
	previousLast = dive_table.nr;

	thread->start();
}
void DownloadFromDCWidget::on_downloadCancelRetryButton_clicked()
{
	if (currentState == DOWNLOADING) {
		updateState(CANCELLING);
		return;
	}
	if (currentState == DONE) {
		// this means we are retrying - so we better clean out the partial
		// list of downloaded dives from the last attempt
		diveImportedModel->clearTable();
		clear_table(&downloadTable);
	}
	updateState(DOWNLOADING);

	// you cannot cancel the dialog, just the download
	ui.cancel->setEnabled(false);
	ui.downloadCancelRetryButton->setText("Cancel download");

	// I don't really think that create/destroy the thread
	// is really necessary.
	if (thread) {
		thread->deleteLater();
	}

	data.vendor = strdup(ui.vendor->currentText().toUtf8().data());
	data.product = strdup(ui.product->currentText().toUtf8().data());
#if defined(BT_SUPPORT)
	data.bluetooth_mode = ui.bluetoothMode->isChecked();
	if (data.bluetooth_mode && btDeviceSelectionDialog != NULL) {
		// Get the selected device address
		data.devname = strdup(btDeviceSelectionDialog->getSelectedDeviceAddress().toUtf8().data());
	} else
		// this breaks an "else if" across lines... not happy...
#endif
	if (same_string(data.vendor, "Uemis")) {
		char *colon;
		char *devname = strdup(ui.device->currentText().toUtf8().data());

		if ((colon = strstr(devname, ":\\ (UEMISSDA)")) != NULL) {
			*(colon + 2) = '\0';
			fprintf(stderr, "shortened devname to \"%s\"", data.devname);
		}
		data.devname = devname;
	} else {
		data.devname = strdup(ui.device->currentText().toUtf8().data());
	}
	data.descriptor = descriptorLookup[ui.vendor->currentText() + ui.product->currentText()];
	data.force_download = ui.forceDownload->isChecked();
	data.create_new_trip = ui.createNewTrip->isChecked();
	data.trip = NULL;
	data.deviceid = data.diveid = 0;

	auto dc = SettingsObjectWrapper::instance()->dive_computer_settings;
	dc->setVendor(data.vendor);
	dc->setProduct(data.product);
	dc->setDevice(data.devname);
#if defined(BT_SUPPORT) && defined(SSRF_CUSTOM_SERIAL)
	dc->setDownloadMode(ui.bluetoothMode->isChecked() ? DC_TRANSPORT_BLUETOOTH : DC_TRANSPORT_SERIAL);
#endif

	thread = new DownloadThread(this, &data);
	connect(thread, SIGNAL(finished()),
		this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection);

	//TODO: Don't call mainwindow.
	MainWindow *w = MainWindow::instance();
	connect(thread, SIGNAL(finished()), w, SLOT(refreshDisplay()));

	// before we start, remember where the dive_table ended
	previousLast = dive_table.nr;

	thread->start();

	QString product(ui.product->currentText());
	if (product == "OSTC 3" || product == "OSTC 3+" ||
			product == "OSTC Cr" || product == "OSTC Sport")
		ostcFirmwareCheck = new OstcFirmwareCheck(product);
}
DownloadFromDCWidget::DownloadFromDCWidget(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f),
	downloading(false),
	previousLast(0),
	timer(new QTimer(this)),
	dumpWarningShown(false),
	ostcFirmwareCheck(0),
	currentState(INITIAL)
{
	diveImportedModel = new DiveImportedModel(this);
	diveImportedModel->setDiveTable(&downloadTable);
	vendorModel.setStringList(vendorList);
	QShortcut *close = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
	QShortcut *quit = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this);

	int startingWidth = defaultModelFont().pointSize();

	clear_table(&downloadTable);
	ui.setupUi(this);
	ui.progressBar->hide();
	ui.progressBar->setMinimum(0);
	ui.progressBar->setMaximum(100);
	ui.downloadedView->setModel(diveImportedModel);
	ui.downloadedView->setSelectionBehavior(QAbstractItemView::SelectRows);
	ui.downloadedView->setSelectionMode(QAbstractItemView::SingleSelection);
	ui.downloadedView->setColumnWidth(0, startingWidth * 20);
	ui.downloadedView->setColumnWidth(1, startingWidth * 10);
	ui.downloadedView->setColumnWidth(2, startingWidth * 10);
	ui.chooseDumpFile->setEnabled(ui.dumpToFile->isChecked());
	ui.chooseLogFile->setEnabled(ui.logToFile->isChecked());
	ui.selectAllButton->setEnabled(false);
	ui.unselectAllButton->setEnabled(false);
	ui.vendor->setModel(&vendorModel);
	ui.product->setModel(&productModel);

	progress_bar_text = "";

	timer->setInterval(200);

	connect(ui.downloadedView, SIGNAL(clicked(QModelIndex)), diveImportedModel, SLOT(changeSelected(QModelIndex)));
	connect(ui.chooseDumpFile, SIGNAL(clicked()), this, SLOT(pickDumpFile()));
	connect(ui.dumpToFile, SIGNAL(stateChanged(int)), this, SLOT(checkDumpFile(int)));
	connect(ui.chooseLogFile, SIGNAL(clicked()), this, SLOT(pickLogFile()));
	connect(ui.logToFile, SIGNAL(stateChanged(int)), this, SLOT(checkLogFile(int)));
	connect(ui.selectAllButton, SIGNAL(clicked()), diveImportedModel, SLOT(selectAll()));
	connect(ui.unselectAllButton, SIGNAL(clicked()), diveImportedModel, SLOT(selectNone()));
	connect(timer, SIGNAL(timeout()), this, SLOT(updateProgressBar()));
	connect(close, SIGNAL(activated()), this, SLOT(close()));
	connect(quit, SIGNAL(activated()), parent, SLOT(close()));

	connect(&thread, SIGNAL(finished()),
		this, SLOT(onDownloadThreadFinished()), Qt::QueuedConnection);

	//TODO: Don't call mainwindow.
	MainWindow *w = MainWindow::instance();
	connect(&thread, SIGNAL(finished()), w, SLOT(refreshDisplay()));

	if (!qPrefDiveComputer::vendor().isEmpty()) {
		ui.vendor->setCurrentIndex(ui.vendor->findText(qPrefDiveComputer::vendor()));
		productModel.setStringList(productList[qPrefDiveComputer::vendor()]);
		if (!qPrefDiveComputer::product().isEmpty())
			ui.product->setCurrentIndex(ui.product->findText(qPrefDiveComputer::product()));
	}

	updateState(INITIAL);
	ui.ok->setEnabled(false);
	ui.downloadCancelRetryButton->setEnabled(true);
	ui.downloadCancelRetryButton->setText(tr("Download"));

	QString deviceText = qPrefDiveComputer::device();
#if defined(BT_SUPPORT)
	ui.bluetoothMode->setText(tr("Choose Bluetooth download mode"));
	ui.bluetoothMode->setChecked(qPrefDiveComputer::download_mode() == DC_TRANSPORT_BLUETOOTH);
	btDeviceSelectionDialog = 0;
	connect(ui.bluetoothMode, SIGNAL(stateChanged(int)), this, SLOT(enableBluetoothMode(int)));
	connect(ui.chooseBluetoothDevice, SIGNAL(clicked()), this, SLOT(selectRemoteBluetoothDevice()));
	ui.chooseBluetoothDevice->setEnabled(ui.bluetoothMode->isChecked());
	if (ui.bluetoothMode->isChecked())
		deviceText = BtDeviceSelectionDialog::formatDeviceText(qPrefDiveComputer::device(), qPrefDiveComputer::device_name());
#else
	ui.bluetoothMode->hide();
	ui.chooseBluetoothDevice->hide();
#endif
	if (!deviceText.isEmpty())
		ui.device->setEditText(deviceText);
}