mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-15 08:59:55 +00:00
GC supports two download port types: serial ports and D2XX. Before, if either of these failed to load, the download dialog wouldn't show either port type. With this patch, if both fail, GC displays a warning, but if either one succeeds, GC will proceed with only that port type. This change should fix the problem that users were having to download and install both the FTDI drivers and the PL2303 ones in order to download from the SRM PCV.
251 lines
8.1 KiB
C++
251 lines
8.1 KiB
C++
/*
|
|
* $Id: DownloadRideDialog.cpp,v 1.4 2006/08/11 20:02:13 srhea Exp $
|
|
*
|
|
* Copyright (c) 2006-2008 Sean C. Rhea (srhea@srhea.net)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "DownloadRideDialog.h"
|
|
#include "Device.h"
|
|
#include "MainWindow.h"
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <QtGui>
|
|
#include <boost/bind.hpp>
|
|
#include <boost/foreach.hpp>
|
|
|
|
DownloadRideDialog::DownloadRideDialog(MainWindow *mainWindow,
|
|
const QDir &home) :
|
|
mainWindow(mainWindow), home(home), cancelled(false),
|
|
downloadInProgress(false)
|
|
{
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
setWindowTitle("Download Ride Data");
|
|
|
|
portCombo = new QComboBox(this);
|
|
|
|
QLabel *instructLabel = new QLabel(tr("Instructions:"), this);
|
|
label = new QLabel(this);
|
|
label->setIndent(10);
|
|
|
|
deviceCombo = new QComboBox(this);
|
|
QList<QString> deviceTypes = Device::deviceTypes();
|
|
assert(deviceTypes.size() > 0);
|
|
BOOST_FOREACH(QString device, deviceTypes) {
|
|
deviceCombo->addItem(device);
|
|
}
|
|
|
|
downloadButton = new QPushButton(tr("&Download"), this);
|
|
eraseRideButton = new QPushButton(tr("&Erase Ride(s)"), this);
|
|
rescanButton = new QPushButton(tr("&Rescan"), this);
|
|
cancelButton = new QPushButton(tr("&Cancel"), this);
|
|
|
|
connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadClicked()));
|
|
connect(eraseRideButton, SIGNAL(clicked()), this, SLOT(eraseClicked()));
|
|
connect(rescanButton, SIGNAL(clicked()), this, SLOT(scanCommPorts()));
|
|
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked()));
|
|
|
|
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
|
buttonLayout->addWidget(downloadButton);
|
|
buttonLayout->addWidget(eraseRideButton);
|
|
buttonLayout->addWidget(rescanButton);
|
|
buttonLayout->addWidget(cancelButton);
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
|
mainLayout->addWidget(new QLabel(tr("Select port:"), this));
|
|
mainLayout->addWidget(portCombo);
|
|
mainLayout->addWidget(new QLabel(tr("Select device type:"), this));
|
|
mainLayout->addWidget(deviceCombo);
|
|
mainLayout->addWidget(instructLabel);
|
|
mainLayout->addWidget(label);
|
|
mainLayout->addLayout(buttonLayout);
|
|
|
|
scanCommPorts();
|
|
}
|
|
|
|
void
|
|
DownloadRideDialog::setReadyInstruct()
|
|
{
|
|
if (portCombo->count() == 0) {
|
|
label->setText(tr("No devices found. Make sure the device\n"
|
|
"unit is plugged into the computer,\n"
|
|
"then click \"Rescan\" to check again."));
|
|
downloadButton->setEnabled(false);
|
|
eraseRideButton->setEnabled(false);
|
|
}
|
|
else {
|
|
Device &device = Device::device(deviceCombo->currentText());
|
|
QString inst = device.downloadInstructions();
|
|
if (inst.size() == 0)
|
|
label->setText("Click Download to begin downloading.");
|
|
else
|
|
label->setText(inst + ", \nthen click Download.");
|
|
downloadButton->setEnabled(true);
|
|
if (deviceCombo->currentText() == "SRM") // only SRM supports erase ride for now
|
|
eraseRideButton->setEnabled(true);
|
|
}
|
|
}
|
|
|
|
void
|
|
DownloadRideDialog::scanCommPorts()
|
|
{
|
|
portCombo->clear();
|
|
QString err;
|
|
devList = CommPort::listCommPorts(err);
|
|
if (err != "") {
|
|
QString msg = "Warning(s):\n\n" + err + "\n\nYou may need to (re)install "
|
|
"the FTDI or PL2303 drivers before downloading.";
|
|
QMessageBox::warning(0, "Error Loading Device Drivers", msg,
|
|
QMessageBox::Ok, QMessageBox::NoButton);
|
|
}
|
|
for (int i = 0; i < devList.size(); ++i) {
|
|
portCombo->addItem(devList[i]->name());
|
|
// Hack: SRM PCV download cables use the PL2203 chipset. If the
|
|
// first device name contains "PL2303", then, we're probably dealing
|
|
// with an SRM, so go ahead and select the SRM device. Generalize?
|
|
if ((i == 0) && devList[i]->name().contains("PL2303")) {
|
|
int j = deviceCombo->findText("SRM");
|
|
if (j >= 0)
|
|
deviceCombo->setCurrentIndex(j);
|
|
}
|
|
}
|
|
if (portCombo->count() > 0)
|
|
downloadButton->setFocus();
|
|
setReadyInstruct();
|
|
}
|
|
|
|
bool
|
|
DownloadRideDialog::statusCallback(const QString &statusText)
|
|
{
|
|
label->setText(statusText);
|
|
QCoreApplication::processEvents();
|
|
return !cancelled;
|
|
}
|
|
|
|
void
|
|
DownloadRideDialog::downloadClicked()
|
|
{
|
|
downloadButton->setEnabled(false);
|
|
eraseRideButton->setEnabled(false);
|
|
rescanButton->setEnabled(false);
|
|
downloadInProgress = true;
|
|
CommPortPtr dev;
|
|
for (int i = 0; i < devList.size(); ++i) {
|
|
if (devList[i]->name() == portCombo->currentText()) {
|
|
dev = devList[i];
|
|
break;
|
|
}
|
|
}
|
|
assert(dev);
|
|
QString err;
|
|
QString tmpname, filename;
|
|
Device &device = Device::device(deviceCombo->currentText());
|
|
if (!device.download(
|
|
dev, home, tmpname, filename,
|
|
boost::bind(&DownloadRideDialog::statusCallback, this, _1), err))
|
|
{
|
|
if (cancelled) {
|
|
QMessageBox::information(this, tr("Download canceled"),
|
|
tr("Cancel clicked by user."));
|
|
cancelled = false;
|
|
}
|
|
else {
|
|
QMessageBox::information(this, tr("Download failed"), err);
|
|
}
|
|
downloadInProgress = false;
|
|
reject();
|
|
return;
|
|
}
|
|
|
|
QString filepath = home.absolutePath() + "/" + filename;
|
|
if (QFile::exists(filepath)) {
|
|
if (QMessageBox::warning(
|
|
this,
|
|
tr("Ride Already Downloaded"),
|
|
tr("This ride appears to have already ")
|
|
+ tr("been downloaded. Do you want to ")
|
|
+ tr("overwrite the previous download?"),
|
|
tr("&Overwrite"), tr("&Cancel"),
|
|
QString(), 1, 1) == 1) {
|
|
reject();
|
|
return;
|
|
}
|
|
}
|
|
|
|
#ifdef __WIN32__
|
|
// Windows ::rename won't overwrite an existing file.
|
|
if (QFile::exists(filepath)) {
|
|
QFile old(filepath);
|
|
if (!old.remove()) {
|
|
QMessageBox::critical(this, tr("Error"),
|
|
tr("Failed to remove existing file ")
|
|
+ filepath + ": " + old.error());
|
|
QFile::remove(tmpname);
|
|
reject();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Use ::rename() instead of QFile::rename() to get forced overwrite.
|
|
if (rename(QFile::encodeName(tmpname), QFile::encodeName(filepath)) < 0) {
|
|
QMessageBox::critical(this, tr("Error"),
|
|
tr("Failed to rename ") + tmpname + tr(" to ")
|
|
+ filepath + ": " + strerror(errno));
|
|
QFile::remove(tmpname);
|
|
reject();
|
|
return;
|
|
}
|
|
|
|
QMessageBox::information(this, tr("Success"), tr("Download complete."));
|
|
mainWindow->addRide(filename);
|
|
|
|
device.cleanup(dev);
|
|
|
|
downloadInProgress = false;
|
|
accept();
|
|
}
|
|
|
|
void
|
|
DownloadRideDialog::eraseClicked()
|
|
{
|
|
downloadButton->setEnabled(false);
|
|
eraseRideButton->setEnabled(false);
|
|
rescanButton->setEnabled(false);
|
|
downloadInProgress = true;
|
|
CommPortPtr dev;
|
|
for (int i = 0; i < devList.size(); ++i) {
|
|
if (devList[i]->name() == portCombo->currentText()) {
|
|
dev = devList[i];
|
|
break;
|
|
}
|
|
}
|
|
assert(dev);
|
|
Device &device = Device::device(deviceCombo->currentText());
|
|
device.cleanup(dev);
|
|
downloadInProgress = false;
|
|
accept();
|
|
}
|
|
|
|
void
|
|
DownloadRideDialog::cancelClicked()
|
|
{
|
|
if (!downloadInProgress)
|
|
reject();
|
|
else
|
|
cancelled = true;
|
|
}
|
|
|