mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-04-15 05:32:21 +00:00
Introduce Toolbox to GUI
The left side of MainWindow is now a toolbox which contains Ride Analysis and Racing and Training options. The Right side tabs have been reorganised and associated with the toolbox. To support the population of the Racing and Training left tool the config dialog has been updated to enable the user to configure the location of their workouts. In addition, the config dialog now calls upon MainWindow to issue a configUpdate() signal to notify widgets when config has been updated. This is a refactoring of the existing mechanism that only called realtimeWindow->updateConfig, now any widget can connect to the MainWindow signal and re-read its config appropriately. Currently, the TrainTool and RealtimeWindow widgets have been coded to use this.
This commit is contained in:
committed by
Sean Rhea
parent
e5affbbc64
commit
e93970ed4d
@@ -153,6 +153,7 @@ void ConfigDialog::save_Clicked()
|
||||
settings->setValue(GC_CRANKLENGTH, configPage->crankLengthCombo->currentText());
|
||||
settings->setValue(GC_BIKESCOREDAYS, configPage->BSdaysEdit->text());
|
||||
settings->setValue(GC_BIKESCOREMODE, configPage->bsModeCombo->currentText());
|
||||
settings->setValue(GC_WORKOUTDIR, configPage->workoutDirectory->text());
|
||||
settings->setValue(GC_INITIAL_STS, cyclistPage->perfManStart->text());
|
||||
settings->setValue(GC_INITIAL_LTS, cyclistPage->perfManStart->text());
|
||||
settings->setValue(GC_STS_DAYS, cyclistPage->perfManSTSavg->text());
|
||||
@@ -196,9 +197,9 @@ void ConfigDialog::save_Clicked()
|
||||
DeviceConfigurations all;
|
||||
all.writeConfig(devicePage->deviceListModel->Configuration);
|
||||
|
||||
// update widgets to let them know config has changed
|
||||
// only realtime sorted thus far;
|
||||
mainWindow->realtimeWindow->configUpdate();
|
||||
// Tell MainWindow we changed config, so it can emit the signal
|
||||
// configChanged() to all its children
|
||||
mainWindow->notifyConfigChanged();
|
||||
}
|
||||
|
||||
void ConfigDialog::moveCalendarToCurrentRange() {
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#include "MetricAggregator.h"
|
||||
#include "SplitRideDialog.h"
|
||||
#include "PerformanceManagerWindow.h"
|
||||
#include "TrainTabs.h"
|
||||
#include "TrainTool.h"
|
||||
|
||||
#ifndef GC_VERSION
|
||||
#define GC_VERSION "(developer build)"
|
||||
@@ -127,6 +129,7 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
setCentralWidget(splitter);
|
||||
splitter->setContentsMargins(10, 20, 10, 10); // attempting to follow some UI guides
|
||||
|
||||
// Analysis toolbox contents
|
||||
calendar = new RideCalendar;
|
||||
calendar->setFirstDayOfWeek(Qt::Monday);
|
||||
calendar->setHome(home);
|
||||
@@ -179,7 +182,16 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
leftLayout->setCollapsible(0, true);
|
||||
leftLayout->addWidget(intervalsplitter);
|
||||
leftLayout->setCollapsible(1, false);
|
||||
splitter->addWidget(leftLayout);
|
||||
|
||||
// Train toolbox contents
|
||||
TrainTool *trainTool = new TrainTool(this, home);
|
||||
|
||||
// Setup Toolbox
|
||||
leftToolBox = new QToolBox;
|
||||
leftToolBox->addItem(leftLayout, tr("Ride Analysis"));
|
||||
leftToolBox->addItem(trainTool, tr("Racing and Training"));
|
||||
|
||||
splitter->addWidget(leftToolBox);
|
||||
splitter->setCollapsible(0, true);
|
||||
QVariant calendarSizes = settings->value(GC_SETTINGS_CALENDAR_SIZES);
|
||||
if (calendarSizes != QVariant()) {
|
||||
@@ -200,8 +212,17 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
}
|
||||
|
||||
tabWidget = new QTabWidget;
|
||||
trainTabs = new TrainTabs(this, trainTool, home);
|
||||
tabWidget->setUsesScrollButtons(true);
|
||||
|
||||
rightSide = new QStackedWidget;
|
||||
rightSide->addWidget(tabWidget);
|
||||
rightSide->addWidget(trainTabs);
|
||||
|
||||
// Start with Analysis by default
|
||||
rightSide->setCurrentIndex(0);
|
||||
leftToolBox->setCurrentIndex(0);
|
||||
|
||||
rideSummaryWindow = new RideSummaryWindow(this);
|
||||
QLabel *notesLabel = new QLabel(tr("Notes:"));
|
||||
notesLabel->setMaximumHeight(30);
|
||||
@@ -232,7 +253,7 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
/////////////////////////// Ride Plot Tab ///////////////////////////
|
||||
allPlotWindow = new AllPlotWindow(this);
|
||||
tabWidget->addTab(allPlotWindow, tr("Ride Plot"));
|
||||
splitter->addWidget(tabWidget);
|
||||
splitter->addWidget(rightSide);
|
||||
splitter->setCollapsible(1, true);
|
||||
|
||||
QVariant splitterSizes = settings->value(GC_SETTINGS_SPLITTER_SIZES);
|
||||
@@ -271,11 +292,6 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
performanceManagerWindow = new PerformanceManagerWindow(this);
|
||||
tabWidget->addTab(performanceManagerWindow, tr("Performance Manager"));
|
||||
|
||||
//////////////////////// Realtime ////////////////////////
|
||||
|
||||
realtimeWindow = new RealtimeWindow(this, home);
|
||||
tabWidget->addTab(realtimeWindow, tr("Realtime"));
|
||||
|
||||
////////////////////////////// Signals //////////////////////////////
|
||||
|
||||
connect(calendar, SIGNAL(clicked(const QDate &)),
|
||||
@@ -296,7 +312,8 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
this, SLOT(intervalTreeWidgetSelectionChanged()));
|
||||
connect(intervalWidget,SIGNAL(itemChanged(QTreeWidgetItem *,int)),
|
||||
this, SLOT(intervalEdited(QTreeWidgetItem*, int)));
|
||||
|
||||
connect(leftToolBox, SIGNAL(currentChanged(int)),
|
||||
this, SLOT(toolboxChanged(int)));
|
||||
|
||||
/////////////////////////////// Menus ///////////////////////////////
|
||||
|
||||
@@ -364,6 +381,12 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::toolboxChanged(int index)
|
||||
{
|
||||
rightSide->setCurrentIndex(index); // right stack has one page per toolbox
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
@@ -1155,3 +1178,9 @@ void MainWindow::dateChanged(const QDate &date)
|
||||
}
|
||||
}
|
||||
|
||||
// notify children that config has changed
|
||||
void
|
||||
MainWindow::notifyConfigChanged()
|
||||
{
|
||||
configChanged();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ class Zones;
|
||||
class RideCalendar;
|
||||
class PerformanceManagerWindow;
|
||||
class RideSummaryWindow;
|
||||
class TrainTabs;
|
||||
class TrainTool;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
@@ -60,14 +62,16 @@ class MainWindow : public QMainWindow
|
||||
QDir home;
|
||||
void setCriticalPower(int cp);
|
||||
|
||||
RealtimeWindow *realtimeWindow; // public so config dialog can notify it of changes config
|
||||
|
||||
const Zones *zones() const { return zones_; }
|
||||
void updateRideFileIntervals();
|
||||
void saveSilent(RideItem *);
|
||||
bool saveRideSingleDialog(RideItem *);
|
||||
RideItem *rideItem() const { return ride; }
|
||||
|
||||
void notifyConfigChanged(); // used by ConfigDialog to notify MainWindow
|
||||
// when config has changed - and to get a
|
||||
// signal emitted to notify its children
|
||||
|
||||
protected:
|
||||
|
||||
Zones *zones_;
|
||||
@@ -84,11 +88,13 @@ class MainWindow : public QMainWindow
|
||||
void intervalSelected();
|
||||
void intervalsChanged();
|
||||
void zonesChanged();
|
||||
void configChanged();
|
||||
|
||||
private slots:
|
||||
void rideTreeWidgetSelectionChanged();
|
||||
void intervalTreeWidgetSelectionChanged();
|
||||
void leftLayoutMoved();
|
||||
void toolboxChanged(int);
|
||||
void splitterMoved();
|
||||
void newCyclist();
|
||||
void openCyclist();
|
||||
@@ -130,6 +136,10 @@ class MainWindow : public QMainWindow
|
||||
boost::shared_ptr<QSettings> settings;
|
||||
IntervalItem *activeInterval; // currently active for context menu popup
|
||||
|
||||
QToolBox *leftToolBox;
|
||||
QStackedWidget *rightSide;
|
||||
|
||||
// Analysis
|
||||
RideCalendar *calendar;
|
||||
QSplitter *splitter;
|
||||
QTreeWidget *treeWidget;
|
||||
@@ -148,6 +158,10 @@ class MainWindow : public QMainWindow
|
||||
QVBoxLayout *notesLayout;
|
||||
QSplitter *summarySplitter;
|
||||
|
||||
// Train
|
||||
TrainTool *trainTool;
|
||||
TrainTabs *trainTabs;
|
||||
|
||||
QwtPlotCurve *weeklyBSCurve;
|
||||
QwtPlotCurve *weeklyRICurve;
|
||||
PerformanceManagerWindow *performanceManagerWindow;
|
||||
|
||||
@@ -136,7 +136,18 @@ ConfigurationPage::ConfigurationPage()
|
||||
bsModeLayout->addWidget(BSModeLabel);
|
||||
bsModeLayout->addWidget(bsModeCombo);
|
||||
|
||||
|
||||
// Workout Library
|
||||
QVariant workoutDir = settings->value(GC_WORKOUTDIR);
|
||||
workoutLabel = new QLabel(tr("Workout Library"));
|
||||
workoutDirectory = new QLineEdit;
|
||||
workoutDirectory->setText(workoutDir.toString());
|
||||
workoutBrowseButton = new QPushButton(tr("Browse"));
|
||||
workoutLayout = new QHBoxLayout;
|
||||
workoutLayout->addWidget(workoutLabel);
|
||||
workoutLayout->addWidget(workoutBrowseButton);
|
||||
workoutLayout->addWidget(workoutDirectory);
|
||||
connect(workoutBrowseButton, SIGNAL(clicked()),
|
||||
this, SLOT(browseWorkoutDir()));
|
||||
|
||||
|
||||
configLayout = new QVBoxLayout;
|
||||
@@ -146,6 +157,7 @@ ConfigurationPage::ConfigurationPage()
|
||||
configLayout->addLayout(crankLengthLayout);
|
||||
configLayout->addLayout(bsDaysLayout);
|
||||
configLayout->addLayout(bsModeLayout);
|
||||
configLayout->addLayout(workoutLayout);
|
||||
configLayout->addLayout(warningLayout);
|
||||
configGroup->setLayout(configLayout);
|
||||
|
||||
@@ -289,6 +301,14 @@ CyclistPage::CyclistPage(const Zones *_zones):
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void
|
||||
ConfigurationPage::browseWorkoutDir()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select Workout Library"),
|
||||
"", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
workoutDirectory->setText(dir);
|
||||
}
|
||||
|
||||
QString CyclistPage::getText()
|
||||
{
|
||||
return txtThreshold->text();
|
||||
|
||||
@@ -36,16 +36,22 @@ class ConfigurationPage : public QWidget
|
||||
QCheckBox *allRidesAscending;
|
||||
QLineEdit *BSdaysEdit;
|
||||
QComboBox *bsModeCombo;
|
||||
QLineEdit *workoutDirectory;
|
||||
QPushButton *workoutBrowseButton;
|
||||
|
||||
public slots:
|
||||
void browseWorkoutDir();
|
||||
|
||||
private:
|
||||
QGroupBox *configGroup;
|
||||
QLabel *langLabel;
|
||||
QLabel *unitLabel;
|
||||
QLabel *warningLabel;
|
||||
QLabel *workoutLabel;
|
||||
QHBoxLayout *langLayout;
|
||||
QHBoxLayout *unitLayout;
|
||||
QHBoxLayout *warningLayout;
|
||||
QHBoxLayout *workoutLayout;
|
||||
QVBoxLayout *configLayout;
|
||||
QVBoxLayout *mainLayout;
|
||||
QGridLayout *bsDaysLayout;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "SimpleNetworkController.h"
|
||||
#include "ErgFile.h"
|
||||
|
||||
#include "TrainTool.h"
|
||||
|
||||
void
|
||||
RealtimeWindow::configUpdate()
|
||||
{
|
||||
@@ -78,11 +80,13 @@ RealtimeWindow::configUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
RealtimeWindow::RealtimeWindow(MainWindow *parent, const QDir &home) : QWidget(parent)
|
||||
RealtimeWindow::RealtimeWindow(MainWindow *parent, TrainTool *trainTool, const QDir &home) : QWidget(parent)
|
||||
{
|
||||
|
||||
// set home
|
||||
this->home = home;
|
||||
this->trainTool = trainTool;
|
||||
main = parent;
|
||||
deviceController = NULL;
|
||||
streamController = NULL;
|
||||
ergFile = NULL;
|
||||
@@ -103,11 +107,6 @@ RealtimeWindow::RealtimeWindow(MainWindow *parent, const QDir &home) : QWidget(
|
||||
|
||||
deviceSelector = new QComboBox(this);
|
||||
streamSelector = new QComboBox(this);
|
||||
workoutSelector = new QComboBox(this);
|
||||
|
||||
workoutSelector->addItem(tr("Manual Mode"), 0);
|
||||
workoutSelector->addItem(tr("Workout Mode"), 1);
|
||||
workoutSelector->addItem(tr("Slope Mode"), 2);
|
||||
|
||||
// get configured devices
|
||||
DeviceConfigurations all;
|
||||
@@ -152,15 +151,16 @@ RealtimeWindow::RealtimeWindow(MainWindow *parent, const QDir &home) : QWidget(
|
||||
streamSelector->hide();
|
||||
|
||||
option_layout->addSpacing(10);
|
||||
option_layout->addWidget(workoutSelector);
|
||||
|
||||
controls_layout->addItem(option_layout);
|
||||
controls_layout->addItem(button_layout);
|
||||
|
||||
// handle config changes
|
||||
connect(main, SIGNAL(configChanged()), this, SLOT(configUpdate()));
|
||||
|
||||
connect(deviceSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(SelectDevice(int)));
|
||||
connect(recordSelector, SIGNAL(clicked()), this, SLOT(SelectRecord()));
|
||||
connect(streamSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(SelectStream(int)));
|
||||
connect(workoutSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(SelectWorkout(int)));
|
||||
connect(trainTool, SIGNAL(workoutSelected()), this, SLOT(SelectWorkout()));
|
||||
|
||||
if (Devices.count() > 0) {
|
||||
connect(startButton, SIGNAL(clicked()), this, SLOT(Start()));
|
||||
@@ -299,7 +299,6 @@ RealtimeWindow::RealtimeWindow(MainWindow *parent, const QDir &home) : QWidget(
|
||||
displayWorkoutDistance = displayDistance = displayPower = displayHeartRate =
|
||||
displaySpeed = displayCadence = displayGradient = displayLoad = 0;
|
||||
avgPower= avgHeartRate= avgSpeed= avgCadence= avgLoad= 0;
|
||||
main = parent;
|
||||
|
||||
connect(gui_timer, SIGNAL(timeout()), this, SLOT(guiUpdate()));
|
||||
connect(disk_timer, SIGNAL(timeout()), this, SLOT(diskUpdate()));
|
||||
@@ -372,7 +371,6 @@ void RealtimeWindow::Start() // when start button is pressed
|
||||
recordSelector->setEnabled(false);
|
||||
streamSelector->setEnabled(false);
|
||||
deviceSelector->setEnabled(false);
|
||||
workoutSelector->setEnabled(false);
|
||||
|
||||
if (status & RT_WORKOUT) {
|
||||
load_timer->start(LOADRATE); // start recording
|
||||
@@ -479,7 +477,6 @@ void RealtimeWindow::Stop() // when stop button is pressed
|
||||
recordSelector->setEnabled(true);
|
||||
streamSelector->setEnabled(true);
|
||||
deviceSelector->setEnabled(true);
|
||||
workoutSelector->setEnabled(true);
|
||||
|
||||
// reset counters etc
|
||||
pwrcount = 0;
|
||||
@@ -715,83 +712,72 @@ void RealtimeWindow::diskUpdate()
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void
|
||||
RealtimeWindow::SelectWorkout(int index)
|
||||
RealtimeWindow::SelectWorkout()
|
||||
{
|
||||
int mode;
|
||||
|
||||
// wip away the current selected workout
|
||||
if (ergFile) {
|
||||
delete ergFile;
|
||||
ergFile = NULL;
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
status |= RT_WORKOUT;
|
||||
// which one is selected?
|
||||
if (trainTool->currentWorkout() == NULL || trainTool->currentWorkout()->type() != WORKOUT_TYPE) return;
|
||||
|
||||
// choose a file and then parse it!
|
||||
QString filename = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Workout File"), home.dirName(), tr("Workout Files (*.erg *.mrc *.crs)"));
|
||||
|
||||
if (!filename.isEmpty()) {
|
||||
// Get users CP for relative watts calculations
|
||||
QDate today = QDate::currentDate();
|
||||
double Cp=285; // default to 285 if zones are not set
|
||||
int range = main->zones()->whichRange(today);
|
||||
if (range != -1) Cp = main->zones()->getCP(range);
|
||||
|
||||
ergFile = new ErgFile(filename, mode, Cp);
|
||||
if (ergFile->isValid()) {
|
||||
|
||||
// success! we have a load file
|
||||
// setup the course profile in the
|
||||
// display!
|
||||
ergPlot->setData(ergFile);
|
||||
ergPlot->setVisible(true);
|
||||
ergPlot->replot();
|
||||
|
||||
// set the device to the right mode
|
||||
if (mode == ERG) {
|
||||
status |= RT_MODE_ERGO;
|
||||
status &= ~RT_MODE_SPIN;
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_ERGO);
|
||||
// set the labels on the gui
|
||||
loadLabel->setText("Load WATTS");
|
||||
avgloadLabel->setText("Avg Load WATTS");
|
||||
} else { // SLOPE MODE
|
||||
status |= RT_MODE_SPIN;
|
||||
status &= ~RT_MODE_ERGO;
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_SPIN);
|
||||
// set the labels on the gui
|
||||
loadLabel->setText("Gradient PERCENT");
|
||||
avgloadLabel->setText("Avg Gradient PERCENT");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// oops didn't parse or no file selected
|
||||
workoutSelector->setCurrentIndex(0); // will drop back here and delet/unset!
|
||||
|
||||
} else if (index == 2) {
|
||||
|
||||
// spinscan mode
|
||||
// is it the auto mode?
|
||||
int index = trainTool->workoutItems()->indexOfChild((QTreeWidgetItem *)trainTool->currentWorkout());
|
||||
if (index == 0) {
|
||||
// ergo mode
|
||||
mode = ERG;
|
||||
status &= ~RT_WORKOUT;
|
||||
ergPlot->setVisible(false);
|
||||
} else if (index == 1) {
|
||||
// slope mode
|
||||
mode = CRS;
|
||||
status &= ~RT_WORKOUT;
|
||||
ergPlot->setVisible(false);
|
||||
status |= RT_MODE_SPIN;
|
||||
status &= ~RT_MODE_ERGO;
|
||||
status &= ~RT_WORKOUT; // temp
|
||||
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_SPIN);
|
||||
loadLabel->setText("Gradient PERCENT");
|
||||
avgloadLabel->setText("Avg Gradient PERCENT");
|
||||
|
||||
} else {
|
||||
// workout mode
|
||||
boost::shared_ptr<QSettings> settings = GetApplicationSettings();
|
||||
QVariant workoutDir = settings->value(GC_WORKOUTDIR);
|
||||
QString fileName = workoutDir.toString() + "/" + trainTool->currentWorkout()->text(0); // filename
|
||||
|
||||
// Get users CP for relative watts calculations
|
||||
QDate today = QDate::currentDate();
|
||||
double Cp=285; // default to 285 if zones are not set
|
||||
int range = main->zones()->whichRange(today);
|
||||
if (range != -1) Cp = main->zones()->getCP(range);
|
||||
|
||||
ergFile = new ErgFile(fileName, mode, Cp);
|
||||
if (ergFile->isValid()) {
|
||||
|
||||
status |= RT_WORKOUT;
|
||||
|
||||
// success! we have a load file
|
||||
// setup the course profile in the
|
||||
// display!
|
||||
ergPlot->setData(ergFile);
|
||||
ergPlot->setVisible(true);
|
||||
ergPlot->replot();
|
||||
}
|
||||
}
|
||||
|
||||
// set the device to the right mode
|
||||
if (mode == ERG) {
|
||||
status |= RT_MODE_ERGO;
|
||||
status &= ~RT_MODE_SPIN;
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_ERGO);
|
||||
// set the labels on the gui
|
||||
loadLabel->setText("Load WATTS");
|
||||
avgloadLabel->setText("Avg Load WATTS");
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_ERGO);
|
||||
ergPlot->setVisible(false);
|
||||
status &= ~RT_WORKOUT;
|
||||
} else { // SLOPE MODE
|
||||
status |= RT_MODE_SPIN;
|
||||
status &= ~RT_MODE_ERGO;
|
||||
if (deviceController != NULL) deviceController->setMode(RT_MODE_SPIN);
|
||||
// set the labels on the gui
|
||||
loadLabel->setText("Gradient PERCENT");
|
||||
avgloadLabel->setText("Avg Gradient PERCENT");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,14 +55,13 @@ class RealtimeWindow : public QWidget
|
||||
RealtimeController *deviceController; // read from
|
||||
RealtimeController *streamController; // send out to
|
||||
|
||||
RealtimeWindow(MainWindow *, const QDir &);
|
||||
RealtimeWindow(MainWindow *, TrainTool *, const QDir &);
|
||||
|
||||
void updateData(RealtimeData &); // to update telemetry by push devices
|
||||
void newLap(); // start new Lap!
|
||||
void nextDisplayMode(); // show next display mode
|
||||
void setDeviceController(); // based upon selected device
|
||||
void setStreamController(); // based upon selected device
|
||||
void configUpdate(); // called when config changes
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -79,7 +78,7 @@ class RealtimeWindow : public QWidget
|
||||
void SelectDevice(int); // when combobox chooses device
|
||||
void SelectRecord(); // when checkbox chooses record mode
|
||||
void SelectStream(int); // when remote server to stream to is selected
|
||||
void SelectWorkout(int); // to select a Workout to use
|
||||
void SelectWorkout(); // to select a Workout to use
|
||||
|
||||
// Timed actions
|
||||
void guiUpdate(); // refreshes the telemetry
|
||||
@@ -87,6 +86,9 @@ class RealtimeWindow : public QWidget
|
||||
void streamUpdate(); // writes to remote Peer
|
||||
void loadUpdate(); // sets Load on CT like devices
|
||||
|
||||
// Handle config updates
|
||||
void configUpdate(); // called when config changes
|
||||
|
||||
// When no config has been setup
|
||||
void warnnoConfig();
|
||||
|
||||
@@ -96,6 +98,7 @@ class RealtimeWindow : public QWidget
|
||||
// passed from MainWindow
|
||||
QDir home;
|
||||
MainWindow *main;
|
||||
TrainTool *trainTool;
|
||||
|
||||
QList<DeviceConfiguration> Devices;
|
||||
bool useMetricUnits;
|
||||
@@ -152,8 +155,7 @@ class RealtimeWindow : public QWidget
|
||||
QVBoxLayout *controls_layout;
|
||||
QCheckBox *recordSelector;
|
||||
QComboBox *deviceSelector,
|
||||
*streamSelector,
|
||||
*workoutSelector;
|
||||
*streamSelector;
|
||||
QPushButton *startButton,
|
||||
*pauseButton,
|
||||
*stopButton;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define GC_SB_ACRONYM "SB"
|
||||
#define GC_WARNCONVERT "warnconvert"
|
||||
#define GC_WARNEXIT "warnexit"
|
||||
#define GC_WORKOUTDIR "workoutDir"
|
||||
|
||||
// device Configurations NAME/SPEC/TYPE/DEFI/DEFR all get a number appended
|
||||
// to them to specify which configured device i.e. devices1 ... devicesn where
|
||||
|
||||
27
src/TrainTabs.cpp
Normal file
27
src/TrainTabs.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2009 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 "TrainTabs.h"
|
||||
#include "RealtimeWindow.h"
|
||||
|
||||
TrainTabs::TrainTabs(MainWindow *parent, TrainTool *trainTool, const QDir &home) :
|
||||
trainTool(trainTool), home(home), main(parent)
|
||||
{
|
||||
realtimeWindow = new RealtimeWindow(parent, trainTool, home); // public so config dialog can notify it of changes config
|
||||
addTab(realtimeWindow, tr("Turbo Training"));
|
||||
};
|
||||
43
src/TrainTabs.h
Normal file
43
src/TrainTabs.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2000 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
|
||||
*/
|
||||
|
||||
#ifndef _GC_TrainTabs_h
|
||||
#define _GC_TrainTabs_h 1
|
||||
|
||||
#include <QDir>
|
||||
#include <QtGui>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "TrainTool.h"
|
||||
#include "RealtimeWindow.h"
|
||||
|
||||
class TrainTabs : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TrainTabs(MainWindow *parent, TrainTool *trainTool, const QDir &home);
|
||||
|
||||
private:
|
||||
RealtimeWindow *realtimeWindow; // public so config dialog can notify it of changes config
|
||||
TrainTool *trainTool;
|
||||
const QDir home;
|
||||
const MainWindow *main;
|
||||
};
|
||||
|
||||
#endif // _GC_TrainTabs_h
|
||||
145
src/TrainTool.cpp
Normal file
145
src/TrainTool.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2009 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 "TrainTool.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Settings.h"
|
||||
#include "Units.h"
|
||||
#include "DeviceTypes.h"
|
||||
#include "DeviceConfiguration.h"
|
||||
#include <assert.h>
|
||||
#include <QApplication>
|
||||
#include <QtGui>
|
||||
#include <QRegExp>
|
||||
|
||||
|
||||
TrainTool::TrainTool(MainWindow *parent, const QDir &home) : QWidget(parent), home(home), main(parent)
|
||||
{
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
|
||||
//XXX Commented out for this release
|
||||
//serverTree = new QTreeWidget;
|
||||
//serverTree->setColumnCount(1);
|
||||
//serverTree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
//serverTree->header()->hide();
|
||||
//serverTree->setAlternatingRowColors (true);
|
||||
//serverTree->setIndentation(5);
|
||||
|
||||
//allServers = new QTreeWidgetItem(serverTree, ROOT_TYPE);
|
||||
//allServers->setText(0, tr("Race Servers"));
|
||||
//serverTree->expandItem(allServers);
|
||||
//DeviceConfigurations all;
|
||||
//QList<DeviceConfiguration> Devices;
|
||||
//Devices = all.getList();
|
||||
//for (int i=0; i<Devices.count(); i++) {
|
||||
// if (Devices.at(i).type == DEV_GSERVER) {
|
||||
// QTreeWidgetItem *server = new QTreeWidgetItem(allServers, SERVER_TYPE);
|
||||
// server->setText(0, Devices.at(i).name);
|
||||
// }
|
||||
//}
|
||||
//connect(serverTree,SIGNAL(itemSelectionChanged()),
|
||||
// this, SLOT(serverTreeWidgetSelectionChanged()));
|
||||
|
||||
workoutTree = new QTreeWidget;
|
||||
workoutTree->setColumnCount(1);
|
||||
workoutTree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
workoutTree->header()->hide();
|
||||
workoutTree->setAlternatingRowColors (true);
|
||||
workoutTree->setIndentation(5);
|
||||
|
||||
allWorkouts = new QTreeWidgetItem(workoutTree, ROOT_TYPE);
|
||||
allWorkouts->setText(0, tr("Workout Library"));
|
||||
workoutTree->expandItem(allWorkouts);
|
||||
|
||||
configChanged(); // will reset the workout tree
|
||||
|
||||
//trainSplitter = new QSplitter;
|
||||
//trainSplitter->setOrientation(Qt::Vertical);
|
||||
//trainSplitter->addWidget(serverTree);
|
||||
//trainSplitter->setCollapsible(0, true);
|
||||
//trainSplitter->addWidget(workoutTree);
|
||||
//trainSplitter->setCollapsible(0, true);
|
||||
|
||||
//mainLayout->addWidget(trainSplitter);
|
||||
mainLayout->addWidget(workoutTree); // XXX replace above line for this release
|
||||
|
||||
connect(workoutTree,SIGNAL(itemSelectionChanged()),
|
||||
this, SLOT(workoutTreeWidgetSelectionChanged()));
|
||||
connect(main, SIGNAL(configChanged()),
|
||||
this, SLOT(configChanged()));
|
||||
}
|
||||
|
||||
void
|
||||
TrainTool::configChanged()
|
||||
{
|
||||
// zap whats there
|
||||
QList<QTreeWidgetItem *> workouts = allWorkouts->takeChildren();
|
||||
for (int i=0; i<workouts.count(); i++) delete workouts.at(i);
|
||||
|
||||
// standard workouts - ergo and slope
|
||||
QTreeWidgetItem *ergomode = new QTreeWidgetItem(allWorkouts, WORKOUT_TYPE);
|
||||
ergomode->setText(0, tr("Manual Ergo Mode"));
|
||||
QTreeWidgetItem *slopemode = new QTreeWidgetItem(allWorkouts, WORKOUT_TYPE);
|
||||
slopemode->setText(0, tr("Manual Slope Mode"));
|
||||
|
||||
// add all the workouts in the library
|
||||
boost::shared_ptr<QSettings> settings = GetApplicationSettings();
|
||||
QVariant workoutDir = settings->value(GC_WORKOUTDIR);
|
||||
QStringListIterator w(listWorkoutFiles(workoutDir.toString()));
|
||||
while (w.hasNext()) {
|
||||
QString name = w.next();
|
||||
QTreeWidgetItem *work = new QTreeWidgetItem(allWorkouts, WORKOUT_TYPE);
|
||||
work->setText(0, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* Race Server or Workout Selected
|
||||
*----------------------------------------------------------------------*/
|
||||
//void
|
||||
//TrainTool::serverTreeWidgetSelectionChanged()
|
||||
//{
|
||||
// serverSelected();
|
||||
//}
|
||||
|
||||
void
|
||||
TrainTool::workoutTreeWidgetSelectionChanged()
|
||||
{
|
||||
assert(workoutTree->selectedItems().size() <= 1);
|
||||
if (workoutTree->selectedItems().isEmpty())
|
||||
workout = NULL;
|
||||
else {
|
||||
QTreeWidgetItem *which = workoutTree->selectedItems().first();
|
||||
if (which->type() != WORKOUT_TYPE)
|
||||
workout = NULL;
|
||||
else
|
||||
workout = which;
|
||||
}
|
||||
workoutSelected();
|
||||
}
|
||||
|
||||
QStringList
|
||||
TrainTool::listWorkoutFiles(const QDir &dir) const
|
||||
{
|
||||
QStringList filters;
|
||||
filters << "*.erg";
|
||||
filters << "*.mrc";
|
||||
filters << "*.crs";
|
||||
|
||||
return dir.entryList(filters, QDir::Files, QDir::Name);
|
||||
}
|
||||
69
src/TrainTool.h
Normal file
69
src/TrainTool.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2009 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
|
||||
*/
|
||||
|
||||
#ifndef _GC_TrainTool_h
|
||||
#define _GC_TrainTool_h 1
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include <QDir>
|
||||
#include <QtGui>
|
||||
|
||||
#define ROOT_TYPE 1
|
||||
#define SERVER_TYPE 2
|
||||
#define WORKOUT_TYPE 3
|
||||
|
||||
class TrainTool : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
TrainTool(MainWindow *parent, const QDir &home);
|
||||
QStringList listWorkoutFiles(const QDir &) const;
|
||||
|
||||
const QTreeWidgetItem *currentWorkout() { return workout; }
|
||||
const QTreeWidgetItem *workoutItems() { return allWorkouts; }
|
||||
//const QTreeWidgetItem *currentServer() { return server; }
|
||||
//const QTreeWidgetItem *serverItems() { return allServers; }
|
||||
|
||||
signals:
|
||||
|
||||
//void serverSelected();
|
||||
void workoutSelected();
|
||||
|
||||
private slots:
|
||||
//void serverTreeWidgetSelectionChanged();
|
||||
void workoutTreeWidgetSelectionChanged();
|
||||
void configChanged();
|
||||
|
||||
private:
|
||||
|
||||
const QDir home;
|
||||
MainWindow *main;
|
||||
QTreeWidget *workoutTree;
|
||||
QTabWidget *trainTabs;
|
||||
QTreeWidgetItem *allWorkouts;
|
||||
QTreeWidgetItem *workout;
|
||||
//QSplitter *trainSplitter; // XXX commented out for this release
|
||||
//QTreeWidget *serverTree; // XXX commented out for this release
|
||||
//QTreeWidgetItem *allServers; // XXX commented out for this release
|
||||
//QTreeWidgetItem *server; // XXX commented out for this release
|
||||
};
|
||||
|
||||
#endif // _GC_TrainTool_h
|
||||
|
||||
@@ -111,6 +111,8 @@ HEADERS += \
|
||||
TcxRideFile.h \
|
||||
TimeUtils.h \
|
||||
ToolsDialog.h \
|
||||
TrainTabs.h \
|
||||
TrainTool.h \
|
||||
Units.h \
|
||||
WeeklySummaryWindow.h \
|
||||
WkoRideFile.h \
|
||||
@@ -187,6 +189,8 @@ SOURCES += \
|
||||
TcxRideFile.cpp \
|
||||
TimeUtils.cpp \
|
||||
ToolsDialog.cpp \
|
||||
TrainTabs.cpp \
|
||||
TrainTool.cpp \
|
||||
WeeklySummaryWindow.cpp \
|
||||
WkoRideFile.cpp \
|
||||
Zones.cpp \
|
||||
|
||||
Reference in New Issue
Block a user