Files
GoldenCheetah/src/ErgDBDownloadDialog.cpp
Mark Liversedge ed2bdc5d3a MainWindow Refactor Part 4 of 5
Split the views in MainWindow into separate classes;

* Tab is a collection of the 4 main views

* TabView is a base class for all of the 4 view types

* {Analysis,Train,Diary,Home}View are all derived from
  TabView and deal with specifics of those views (e.g.
  Diary/Home worry about date ranges).

We should be ready to move to tabbed athletes soon.

There are a few nits left for this part of the refactor
that will need to be resolved in some fixups over the
next few days;

* tile mode segment selector has wrong segment selected
  when the view is in tile mode.

* Minimum height/width of MainWindow is large for some
  reason

* the Train view controls (play, ffwd etc) have nowhere
  to go at present -- need to fix that !!!

* When you resize the mainwindow width the sidebars expand
  and should remain a fixed width

* not sure if it will build on Windows or Mac!
2013-07-27 21:41:03 +01:00

247 lines
7.6 KiB
C++

/*
* Copyright (c) 2011 Mark Liversedge (liversedge@gmail.com)
*
* 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 "ErgDBDownloadDialog.h"
#include "MainWindow.h"
#include "TrainDB.h"
ErgDBDownloadDialog::ErgDBDownloadDialog(Context *context) : QDialog(context->mainWindow), context(context)
{
setAttribute(Qt::WA_DeleteOnClose);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
setWindowTitle(tr("Download workouts from ErgDB"));
// make the dialog a resonable size
setMinimumWidth(650);
setMinimumHeight(400);
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
files = new QTreeWidget;
#ifdef Q_OS_MAC
files->setAttribute(Qt::WA_MacShowFocusRect, 0);
#endif
files->headerItem()->setText(0, tr(""));
files->headerItem()->setText(1, tr("Name"));
files->headerItem()->setText(2, tr("Type"));
files->headerItem()->setText(3, tr("Author"));
files->headerItem()->setText(4, tr("Dated"));
files->headerItem()->setText(5, tr("Action"));
files->setColumnCount(6);
files->setColumnWidth(0, 30); // selector
files->setColumnWidth(1, 140); // filename
files->setColumnWidth(2, 100); // Type
files->setColumnWidth(3, 120); // Author
files->setColumnWidth(4, 90); // dated
files->setSelectionMode(QAbstractItemView::SingleSelection);
files->setEditTriggers(QAbstractItemView::SelectedClicked); // allow edit
files->setUniformRowHeights(true);
files->setIndentation(0);
foreach(ErgDBItem item, ergdb.items()) {
QTreeWidgetItem *add = new QTreeWidgetItem(files->invisibleRootItem());
add->setFlags(add->flags() | Qt::ItemIsEditable);
// selector
QCheckBox *checkBox = new QCheckBox("", this);
checkBox->setChecked(true);
files->setItemWidget(add, 0, checkBox);
add->setText(1, item.name);
add->setText(2, item.workoutType);
add->setText(3, item.author);
add->setText(4, item.added.toString(tr("dd MMM yyyy")));
// interval action
add->setText(5, "Download");
// hide away the id
add->setText(6, QString("%1").arg(item.id));
}
all = new QCheckBox("check/uncheck all", this);
all->setChecked(true);
// buttons
QHBoxLayout *buttons = new QHBoxLayout;
status = new QLabel("", this);
status->hide();
overwrite = new QCheckBox("Overwrite existing workouts", this);
cancel = new QPushButton("Cancel", this);
ok = new QPushButton("Download", this);
buttons->addWidget(overwrite);
buttons->addWidget(status);
buttons->addStretch();
buttons->addWidget(cancel);
buttons->addWidget(ok);
layout->addWidget(all);
layout->addWidget(files);
layout->addLayout(buttons);
downloads = fails = 0;
// connect signals and slots up..
connect(ok, SIGNAL(clicked()), this, SLOT(okClicked()));
connect(all, SIGNAL(stateChanged(int)), this, SLOT(allClicked()));
connect(cancel, SIGNAL(clicked()), this, SLOT(cancelClicked()));
}
void
ErgDBDownloadDialog::allClicked()
{
// set/uncheck all rides according to the "all"
bool checked = all->isChecked();
for(int i=0; i<files->invisibleRootItem()->childCount(); i++) {
QTreeWidgetItem *current = files->invisibleRootItem()->child(i);
static_cast<QCheckBox*>(files->itemWidget(current,0))->setChecked(checked);
}
}
void
ErgDBDownloadDialog::okClicked()
{
if (ok->text() == "Download") {
aborted = false;
overwrite->hide();
status->setText("Download...");
status->show();
cancel->hide();
ok->setText("Abort");
downloadFiles();
status->setText(QString("%1 workouts downloaded, %2 failed or skipped.").arg(downloads).arg(fails));
ok->setText("Finish");
context->notifyConfigChanged();
} else if (ok->text() == "Abort") {
aborted = true;
} else if (ok->text() == "Finish") {
accept(); // our work is done!
}
}
void
ErgDBDownloadDialog::cancelClicked()
{
reject();
}
void
ErgDBDownloadDialog::downloadFiles()
{
// where to place them
QString workoutDir = appsettings->value(this, GC_WORKOUTDIR).toString();
// what format to export as?
QString type = RideFileFactory::instance().writeSuffixes().at(0);
// for library updating, transactional for 10x performance
trainDB->startLUW();
// loop through the table and export all selected
for(int i=0; i<files->invisibleRootItem()->childCount(); i++) {
// give user a chance to abort..
QApplication::processEvents();
// did they?
if (aborted == true) {
trainDB->endLUW(); // need to commit whatever was copied.
return; // user aborted!
}
QTreeWidgetItem *current = files->invisibleRootItem()->child(i);
// is it selected
if (static_cast<QCheckBox*>(files->itemWidget(current,0))->isChecked()) {
files->setCurrentItem(current); QApplication::processEvents();
// this one then
current->setText(5, "Downloading..."); QApplication::processEvents();
// get the id
int id = current->text(6).toInt();
QString content = ergdb.getFile(id, 300);
QString filename = workoutDir + "/" + current->text(1) + ".erg";
ErgFile *p = ErgFile::fromContent(content, context);
// open success?
if (p->isValid()) {
if (QFile(filename).exists()) {
if (overwrite->isChecked() == false) {
// skip existing files
current->setText(5, "Exists already"); QApplication::processEvents();
fails++;
delete p; // free memory!
continue;
} else {
// remove existing
QFile(filename).remove();
current->setText(5, "Removing..."); QApplication::processEvents();
}
}
downloads++;
QFile out(filename);
if (out.open(QIODevice::WriteOnly) == true) {
QTextStream output(&out);
output << content;
out.close();
downloads++;
current->setText(5, "Saved"); QApplication::processEvents();
trainDB->importWorkout(filename, p); // add to library
} else {
fails++;
current->setText(5, "Write failed"); QApplication::processEvents();
}
delete p; // free memory!
// couldn't parse
} else {
delete p; // free memory!
fails++;
current->setText(5, "Invalid File"); QApplication::processEvents();
}
}
}
// for library updating, transactional for 10x performance
trainDB->endLUW();
}