Exemple #1
0
//
// Ward Smith Model
//
WSModel::WSModel(Context *context) : PDModel(context)
{
    // set default intervals to search CP 30-60
    anI1=1800;
    anI2=2400;
    aeI1=2400;
    aeI2=3600;

    connect (this, SIGNAL(dataChanged()), this, SLOT(onDataChanged()));
    connect (this, SIGNAL(intervalsChanged()), this, SLOT(onIntervalsChanged()));
}
Exemple #2
0
CP2Model::CP2Model(Context *context) :
    PDModel(context)
{
    // set default intervals to search CP 2-3 mins and 7-20 mins
    anI1=120;
    anI2=200;
    aeI1=420;
    aeI2=1200;

    connect (this, SIGNAL(dataChanged()), this, SLOT(onDataChanged()));
    connect (this, SIGNAL(intervalsChanged()), this, SLOT(onIntervalsChanged()));
}
Exemple #3
0
// set the intervals to search for bests
void
PDModel::setIntervals(double sanI1, double sanI2, double anI1, double anI2,
                  double aeI1, double aeI2, double laeI1, double laeI2)
{
    this->sanI1 = sanI1;
    this->sanI2 = sanI2;
    this->anI1 = anI1;
    this->anI2 = anI2;
    this->aeI1 = aeI1;
    this->aeI2 = aeI2;
    this->laeI1 = laeI1;
    this->laeI2 = laeI2;

    emit intervalsChanged();
}
Exemple #4
0
//
// Veloclinic Multicomponent Model
//
// p(t) = pc1 + pc2
//        Power at time t is the sum of;
//        pc1 - the power from component 1 (fast twitch pools)
//        pc2 - the power from component 2 (slow twitch motor units)
//
// The inputs are derived from the CP2-20 model and 3 constants:
//
//      Pmax - as derived from the CP2-20 model (via t0)
//      w1   - W' as derived from the CP2-20 model
//      p1   - pmax - cp as derived from the CP2-20 model
//      p2   - cp as derived from the CP2-20 model
//      tau1 - W'1 / p1
//      tau2 - 15,000
//      w2   -  A slow twitch W' derived from p2 * tau2
//      alpha- 0.1 thru -0.1, we default to zero
//      beta - 1.0
//
// Fast twitch component is:
//      pc1(t) = W'1 / t * (1-exp(-t/tau1)) * ((1-exp(-t/10)) ^ (1/alpha))
//
// Slow twitch component has three formulations:
//      sprint capped linear)          pc2(t) = p2 * tau2 * (1-exp(-t/tau2))
//      sprint capped regeneration)    pc2(t) = p2 / (1 + t/tau2)
//      sprint capped exponential)     pc2(t) = p2 / (1 + t/5400) ^ (1/beta)
//
// Currently deciding which of the three formulations to use
// as the base for GoldenCheetah (we have enough models already !)
MultiModel::MultiModel(Context *context) :
    PDModel(context)
{
    // set default intervals to search CP 30-60
    // uses the same as the 3 parameter model
    anI1=1800;
    anI2=2400;
    aeI1=2400;
    aeI2=3600;

    variant = 0; // use exp top/bottom by default.

    connect (this, SIGNAL(dataChanged()), this, SLOT(onDataChanged()));
    connect (this, SIGNAL(intervalsChanged()), this, SLOT(onIntervalsChanged()));
}
Exemple #5
0
//
// Extended CP Model
//
ExtendedModel::ExtendedModel(Context *context) :
    PDModel(context)
{
    // set default intervals to search Extended CP
    sanI1=20;
    sanI2=90;
    anI1=120;
    anI2=300;
    aeI1=600;
    aeI2=3000;
    laeI1=3600;
    laeI2=30000;

    connect (this, SIGNAL(dataChanged()), this, SLOT(onDataChanged()));
    connect (this, SIGNAL(intervalsChanged()), this, SLOT(onIntervalsChanged()));
}
RideSummaryWindow::RideSummaryWindow(MainWindow *mainWindow, bool ridesummary) :
     GcChartWindow(mainWindow), mainWindow(mainWindow), ridesummary(ridesummary), useCustom(false), useToToday(false)
{
    setInstanceName("Ride Summary Window");
    setRideItem(NULL);

    // allow user to select date range if in summary mode
    dateSetting = new DateSettingsEdit(this);
    if (ridesummary) {

        setControls(NULL);
        dateSetting->hide(); // not needed, but holds property values

    } else {

        QWidget *c = new QWidget;
        c->setContentsMargins(0,0,0,0);
        QFormLayout *cl = new QFormLayout(c);
        cl->setContentsMargins(0,0,0,0);
        cl->setSpacing(0);
        setControls(c);

        cl->addRow(new QLabel(tr("Date range")), dateSetting);
    }

    QVBoxLayout *vlayout = new QVBoxLayout;
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(10,10,10,10);
    rideSummary = new QWebView(this);
    rideSummary->setContentsMargins(0,0,0,0);
    rideSummary->page()->view()->setContentsMargins(0,0,0,0);
    rideSummary->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    rideSummary->setAcceptDrops(false);

    QFont defaultFont; // mainwindow sets up the defaults.. we need to apply
    rideSummary->settings()->setFontSize(QWebSettings::DefaultFontSize, defaultFont.pointSize()+1);
    rideSummary->settings()->setFontFamily(QWebSettings::StandardFont, defaultFont.family());

    vlayout->addWidget(rideSummary);

    if (ridesummary) {

        connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideItemChanged()));
        connect(mainWindow, SIGNAL(zonesChanged()), this, SLOT(refresh()));
        connect(mainWindow, SIGNAL(intervalsChanged()), this, SLOT(refresh()));

    } else {
IntervalSummaryWindow::IntervalSummaryWindow(Context *context) : context(context)
{
    setWindowTitle(tr("Interval Summary"));
    setReadOnly(true);
    setFrameStyle(QFrame::NoFrame);
#ifdef Q_OS_WIN
    QStyle *cde = QStyleFactory::create(OS_STYLE);
    verticalScrollBar()->setStyle(cde);
#endif

#ifdef Q_OS_MAC
    setAttribute(Qt::WA_MacShowFocusRect, 0);
#endif
    connect(context, SIGNAL(intervalsChanged()), this, SLOT(intervalSelected()));
    connect(context, SIGNAL(intervalSelected()), this, SLOT(intervalSelected()));
    connect(context, SIGNAL(intervalHover(IntervalItem*)), this, SLOT(intervalHover(IntervalItem*)));
    connect(context, SIGNAL(configChanged(qint32)), this, SLOT(intervalSelected()));

    setHtml(GCColor::css() + "<body></body>");
}
AllPlotWindow::AllPlotWindow(MainWindow *mainWindow) :
    GcWindow(mainWindow), current(NULL), mainWindow(mainWindow), active(false), stale(true)
{
    setInstanceName("Ride Plot Window");

    QWidget *c = new QWidget;
    QVBoxLayout *cl = new QVBoxLayout(c);
    setControls(c);

    setContentsMargins(0,0,0,0);

    // setup the controls
    QLabel *showLabel = new QLabel(tr("Show"), c);
    cl->addWidget(showLabel);

    showStack = new QCheckBox(tr("Stacked view"), this);
    showStack->setCheckState(Qt::Unchecked);
    cl->addWidget(showStack);

    stackWidth = 15;
    stackZoomUp = new QwtArrowButton(1, Qt::UpArrow,this);
    stackZoomUp->setFixedHeight(15);
    stackZoomUp->setFixedWidth(15);
    stackZoomUp->setEnabled(false);
    stackZoomUp->setContentsMargins(0,0,0,0);
    stackZoomUp->setFlat(true);
    cl->addWidget(stackZoomUp);

    stackZoomDown = new QwtArrowButton(1, Qt::DownArrow,this);
    stackZoomDown->setFixedHeight(15);
    stackZoomDown->setFixedWidth(15);
    stackZoomDown->setEnabled(false);
    stackZoomDown->setContentsMargins(0,0,0,0);
    stackZoomDown->setFlat(true);
    cl->addWidget(stackZoomDown);

    showFull = new QCheckBox(tr("Full plot"), this);
    showFull->setCheckState(Qt::Checked);
    cl->addWidget(showFull);

    paintBrush = new QCheckBox(tr("Fill Curves"), this);
    paintBrush->setCheckState(Qt::Unchecked);
    cl->addWidget(paintBrush);

    showGrid = new QCheckBox(tr("Grid"), this);
    showGrid->setCheckState(Qt::Checked);
    cl->addWidget(showGrid);

    showHr = new QCheckBox(tr("Heart Rate"), this);
    showHr->setCheckState(Qt::Checked);
    cl->addWidget(showHr);

    showSpeed = new QCheckBox(tr("Speed"), this);
    showSpeed->setCheckState(Qt::Checked);
    cl->addWidget(showSpeed);

    showCad = new QCheckBox(tr("Cadence"), this);
    showCad->setCheckState(Qt::Checked);
    cl->addWidget(showCad);

    showAlt = new QCheckBox(tr("Altitude"), this);
    showAlt->setCheckState(Qt::Checked);
    cl->addWidget(showAlt);

    showTemp = new QCheckBox(tr("Temperature"), this);
    showTemp->setCheckState(Qt::Checked);
    cl->addWidget(showTemp);

    showWind = new QCheckBox(tr("Headwind"), this);
    showWind->setCheckState(Qt::Checked);
    cl->addWidget(showWind);

    showTorque = new QCheckBox(tr("Torque"), this);
    showTorque->setCheckState(Qt::Checked);
    cl->addWidget(showTorque);

    showBalance = new QCheckBox(tr("Power balance"), this);
    showBalance->setCheckState(Qt::Checked);
    cl->addWidget(showBalance);

    showPower = new QComboBox();
    showPower->addItem(tr("Power + shade"));
    showPower->addItem(tr("Power - shade"));
    showPower->addItem(tr("No Power"));
    cl->addWidget(showPower);
    showPower->setCurrentIndex(0);

    comboDistance = new QComboBox();
    comboDistance->addItem(tr("X Axis Shows Time"));
    comboDistance->addItem(tr("X Axis Shows Distance"));
    cl->addWidget(comboDistance);

    QLabel *smoothLabel = new QLabel(tr("Smoothing (secs)"), this);
    smoothLineEdit = new QLineEdit(this);
    smoothLineEdit->setFixedWidth(40);

    cl->addWidget(smoothLabel);
    cl->addWidget(smoothLineEdit);
    smoothSlider = new QSlider(Qt::Horizontal);
    smoothSlider->setTickPosition(QSlider::TicksBelow);
    smoothSlider->setTickInterval(10);
    smoothSlider->setMinimum(1);
    smoothSlider->setMaximum(600);
    smoothLineEdit->setValidator(new QIntValidator(smoothSlider->minimum(),
                                                   smoothSlider->maximum(),
                                                   smoothLineEdit));
    cl->addWidget(smoothSlider);
    cl->addStretch();

    allPlot = new AllPlot(this, mainWindow);
    allPlot->setInstanceName("allPlot");
    allPlot->setContentsMargins(0,0,0,0);

    smoothSlider->setValue(allPlot->smooth);
    smoothLineEdit->setText(QString("%1").arg(allPlot->smooth));

    allZoomer = new QwtPlotZoomer(allPlot->canvas());
    allZoomer->setRubberBand(QwtPicker::RectRubberBand);
    allZoomer->setRubberBandPen(GColor(CPLOTSELECT));
    allZoomer->setTrackerMode(QwtPicker::AlwaysOff);
    allZoomer->setEnabled(true);

    // TODO: Hack for OS X one-button mouse
    // allZoomer->initMousePattern(1);

    // RightButton: zoom out by 1
    // Ctrl+RightButton: zoom out to full size
    allZoomer->setMousePattern(QwtEventPattern::MouseSelect1,
                               Qt::LeftButton, Qt::ShiftModifier);
    allZoomer->setMousePattern(QwtEventPattern::MouseSelect2,
                               Qt::RightButton, Qt::ControlModifier);
    allZoomer->setMousePattern(QwtEventPattern::MouseSelect3,
                               Qt::RightButton);

    allPanner = new QwtPlotPanner(allPlot->canvas());
    allPanner->setMouseButton(Qt::MidButton);

    // TODO: zoomer doesn't interact well with automatic axis resizing

    // tooltip on hover over point
    allPlot->tooltip = new LTMToolTip(QwtPlot::xBottom, QwtPlot::yLeft,
                               QwtPicker::VLineRubberBand,
                               QwtPicker::AlwaysOn,
                               allPlot->canvas(),
                               "");
    allPlot->tooltip->setRubberBand(QwtPicker::VLineRubberBand);
    allPlot->tooltip->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton);
    allPlot->tooltip->setTrackerPen(QColor(Qt::black));
    QColor inv(Qt::white);
    inv.setAlpha(0);
    allPlot->tooltip->setRubberBandPen(inv);
    allPlot->tooltip->setEnabled(true);

    allPlot->_canvasPicker = new LTMCanvasPicker(allPlot);
    connect(allPlot->_canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), allPlot, SLOT(pointHover(QwtPlotCurve*, int)));
    connect(allPlot->tooltip, SIGNAL(moved(const QPoint &)), this, SLOT(plotPickerMoved(const QPoint &)));
    connect(allPlot->tooltip, SIGNAL(appended(const QPoint &)), this, SLOT(plotPickerSelected(const QPoint &)));

    QwtPlotMarker* allMarker1 = new QwtPlotMarker();
    allMarker1->setLineStyle(QwtPlotMarker::VLine);
    allMarker1->attach(allPlot);
    allMarker1->setLabelAlignment(Qt::AlignTop|Qt::AlignRight);
    allPlot->allMarker1=allMarker1;

    QwtPlotMarker* allMarker2 = new QwtPlotMarker();
    allMarker2->setLineStyle(QwtPlotMarker::VLine);
    allMarker2->attach(allPlot);
    allMarker2->setLabelAlignment(Qt::AlignTop|Qt::AlignRight);
    allPlot->allMarker2=allMarker2;

    // Container widgets should not paint
    // since they tend to use naff defaults and
    // 'complicate' or 'make busy' the general
    // look and feel
    QPalette palette;
    palette.setBrush(QPalette::Background, Qt::NoBrush);

    //
    // stack view
    //
    stackPlotLayout = new QVBoxLayout();
    stackPlotLayout->setSpacing(0);
    stackPlotLayout->setContentsMargins(0,0,0,0);
    stackWidget = new QWidget();
    stackWidget->setAutoFillBackground(false);
    stackWidget->setPalette(palette);
    stackWidget->setLayout(stackPlotLayout);

    stackFrame = new QScrollArea();
    stackFrame->hide();
    stackFrame->setPalette(palette);
    stackFrame->setAutoFillBackground(false);
    stackFrame->setWidgetResizable(true);
    stackFrame->setWidget(stackWidget);
    stackFrame->setFrameStyle(QFrame::NoFrame);
    stackFrame->setContentsMargins(0,0,0,0);

    //
    // allPlot view
    //
    allPlotLayout = new QVBoxLayout;
    allPlotLayout->setSpacing(0);
    allPlotLayout->setContentsMargins(0,0,0,0);
    allPlotFrame = new QScrollArea();
    allPlotFrame->setFrameStyle(QFrame::NoFrame);
    allPlotFrame->setAutoFillBackground(false);
    allPlotFrame->setPalette(palette);
    allPlotFrame->setContentsMargins(0,0,0,0);

    spanSlider = new QxtSpanSlider(Qt::Horizontal);
    spanSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
    spanSlider->setLowerValue(0);
    spanSlider->setUpperValue(15);

    QFont small;
    small.setPointSize(6);

    scrollLeft = new QPushButton("<");
    scrollLeft->setFont(small);
    scrollLeft->setAutoRepeat(true);
    scrollLeft->setFixedHeight(16);
    scrollLeft->setFixedWidth(16);
    scrollLeft->setContentsMargins(0,0,0,0);

    scrollRight = new QPushButton(">");
    scrollRight->setFont(small);
    scrollRight->setAutoRepeat(true);
    scrollRight->setFixedHeight(16);
    scrollRight->setFixedWidth(16);
    scrollRight->setContentsMargins(0,0,0,0);

#ifdef Q_OS_MAC
    // BUG in QMacStyle and painting of spanSlider
    // so we use a plain style to avoid it, but only
    // on a MAC, since win and linux are fine
    QCleanlooksStyle *style = new QCleanlooksStyle();
    spanSlider->setStyle(style);
    scrollLeft->setStyle(style);
    scrollRight->setStyle(style);
#endif

    fullPlot = new AllPlot(this, mainWindow);
    fullPlot->setInstanceName("fullPlot");
    fullPlot->grid->enableY(false);
    QPalette def;
    //fullPlot->setCanvasBackground(def.color(QPalette::Window));
    fullPlot->setCanvasBackground(Qt::white);
    fullPlot->setCanvasLineWidth(0);
    fullPlot->enableAxis(QwtPlot::yLeft, false);
    fullPlot->enableAxis(QwtPlot::yLeft2, false);
    fullPlot->enableAxis(QwtPlot::yRight, false);
    fullPlot->enableAxis(QwtPlot::yRight2, false);
    fullPlot->enableAxis(QwtPlot::xBottom, false);
    //fullPlot->legend()->clear();
    //fullPlot->setTitle("");
    fullPlot->setContentsMargins(0,0,0,0);

    allPlotLayout->addWidget(allPlot);
    allPlotFrame->setLayout(allPlotLayout);

    // controls...
    controlsLayout = new QGridLayout;
    controlsLayout->setSpacing(0);
    controlsLayout->setContentsMargins(5,5,5,5);
    controlsLayout->addWidget(fullPlot, 0,1);
    controlsLayout->addWidget(spanSlider, 1,1);
    controlsLayout->addWidget(scrollLeft,1,0);
    controlsLayout->addWidget(scrollRight,1,2);
    controlsLayout->setRowStretch(0, 10);
    controlsLayout->setRowStretch(1, 1);
    controlsLayout->setContentsMargins(0,0,0,0);
#ifdef Q_OS_MAC
    // macs  dpscing is weird
    //controlsLayout->setSpacing(5);
#else
    controlsLayout->setSpacing(0);
#endif
    allPlotLayout->addLayout(controlsLayout);
    allPlotLayout->setStretch(0,100);
    allPlotLayout->setStretch(1,20);

    QVBoxLayout *vlayout = new QVBoxLayout(this);
    vlayout->setContentsMargins(2,2,2,2);
    vlayout->setSpacing(0);
    vlayout->addWidget(allPlotFrame);
    vlayout->addWidget(stackFrame);
    vlayout->setSpacing(1);
    setLayout(vlayout);

    setContentsMargins(0,0,0,0);

    // common controls
    connect(showPower, SIGNAL(currentIndexChanged(int)), this, SLOT(setShowPower(int)));
    connect(showHr, SIGNAL(stateChanged(int)), this, SLOT(setShowHr(int)));
    connect(showSpeed, SIGNAL(stateChanged(int)), this, SLOT(setShowSpeed(int)));
    connect(showCad, SIGNAL(stateChanged(int)), this, SLOT(setShowCad(int)));
    connect(showAlt, SIGNAL(stateChanged(int)), this, SLOT(setShowAlt(int)));
    connect(showTemp, SIGNAL(stateChanged(int)), this, SLOT(setShowTemp(int)));
    connect(showWind, SIGNAL(stateChanged(int)), this, SLOT(setShowWind(int)));
    connect(showTorque, SIGNAL(stateChanged(int)), this, SLOT(setShowTorque(int)));
    connect(showBalance, SIGNAL(stateChanged(int)), this, SLOT(setShowBalance(int)));
    connect(showGrid, SIGNAL(stateChanged(int)), this, SLOT(setShowGrid(int)));
    connect(showFull, SIGNAL(stateChanged(int)), this, SLOT(setShowFull(int)));
    connect(showStack, SIGNAL(stateChanged(int)), this, SLOT(showStackChanged(int)));
    connect(paintBrush, SIGNAL(stateChanged(int)), this, SLOT(setPaintBrush(int)));
    connect(comboDistance, SIGNAL(currentIndexChanged(int)), this, SLOT(setByDistance(int)));
    connect(smoothSlider, SIGNAL(valueChanged(int)), this, SLOT(setSmoothingFromSlider()));
    connect(smoothLineEdit, SIGNAL(editingFinished()), this, SLOT(setSmoothingFromLineEdit()));

    // normal view
    connect(spanSlider, SIGNAL(lowerPositionChanged(int)), this, SLOT(zoomChanged()));
    connect(spanSlider, SIGNAL(upperPositionChanged(int)), this, SLOT(zoomChanged()));

    // stacked view
    connect(stackZoomUp, SIGNAL(clicked()), this, SLOT(setStackZoomUp()));
    connect(stackZoomDown, SIGNAL(clicked()), this, SLOT(setStackZoomDown()));
    connect(scrollLeft, SIGNAL(clicked()), this, SLOT(moveLeft()));
    connect(scrollRight, SIGNAL(clicked()), this, SLOT(moveRight()));

    // GC signals
    //connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected()));
    connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected()));
    connect(mainWindow, SIGNAL(rideDirty()), this, SLOT(rideSelected()));
    connect(mainWindow, SIGNAL(zonesChanged()), this, SLOT(zonesChanged()));
    connect(mainWindow, SIGNAL(intervalsChanged()), this, SLOT(intervalsChanged()));
    connect(mainWindow, SIGNAL(intervalZoom(IntervalItem*)), this, SLOT(zoomInterval(IntervalItem*)));
    connect(mainWindow, SIGNAL(intervalSelected()), this, SLOT(intervalSelected()));
    connect(mainWindow, SIGNAL(configChanged()), allPlot, SLOT(configChanged()));
    connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged()));
    connect(mainWindow, SIGNAL(rideDeleted(RideItem*)), this, SLOT(rideDeleted(RideItem*)));
}
Exemple #9
0
void
MultiModel::setVariant(int variant)
{
    this->variant = variant;
    emit intervalsChanged(); // refresh then
}
PfPvWindow::PfPvWindow(Context *context) :
    GcChartWindow(context), context(context), current(NULL), compareStale(true), stale(false)
{
    QWidget *c = new QWidget;
    HelpWhatsThis *helpConfig = new HelpWhatsThis(c);
    c->setWhatsThis(helpConfig->getWhatsThisText(HelpWhatsThis::ChartRides_PFvV));
    QVBoxLayout *cl = new QVBoxLayout(c);
    setControls(c);

    //
    // reveal controls widget
    //

    // layout reveal controls
    QHBoxLayout *revealLayout = new QHBoxLayout;
    revealLayout->setContentsMargins(0,0,0,0);

    rShade = new QCheckBox(tr("Shade zones"));
    if (appsettings->value(this, GC_SHADEZONES, true).toBool() == true)
        rShade->setCheckState(Qt::Checked);
    else
        rShade->setCheckState(Qt::Unchecked);
    rMergeInterval = new QCheckBox;
    rMergeInterval->setText(tr("Merge intervals"));
    rMergeInterval->setCheckState(Qt::Unchecked);
    rMergeInterval->hide(); // lets not - its not that useful
    rFrameInterval = new QCheckBox;
    rFrameInterval->setText(tr("Frame intervals"));
    rFrameInterval->setCheckState(Qt::Checked);

    QVBoxLayout *checks = new QVBoxLayout;
    checks->addStretch();
    checks->addWidget(rShade);
    checks->addWidget(rMergeInterval);
    checks->addWidget(rFrameInterval);
    checks->addStretch();

    revealLayout->addStretch();
    revealLayout->addLayout(checks);
    revealLayout->addStretch();

    setRevealLayout(revealLayout);

    // the plot
    QVBoxLayout *vlayout = new QVBoxLayout;
    pfPvPlot = new PfPvPlot(context);
    vlayout->addWidget(pfPvPlot);
    HelpWhatsThis *help = new HelpWhatsThis(pfPvPlot);
    pfPvPlot->setWhatsThis(help->getWhatsThisText(HelpWhatsThis::ChartRides_PFvV));

    setChartLayout(vlayout);
    setAutoFillBackground(true);

    // allow zooming
    pfpvZoomer = new QwtPlotZoomer(pfPvPlot->canvas());
    pfpvZoomer->setRubberBand(QwtPicker::RectRubberBand);
    pfpvZoomer->setRubberBandPen(GColor(CPLOTSELECT));
    pfpvZoomer->setTrackerMode(QwtPicker::AlwaysOff);
    pfpvZoomer->setEnabled(true);
    pfpvZoomer->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton);
    pfpvZoomer->setMousePattern(QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier);
    pfpvZoomer->setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton);

    // double click
    doubleClickPicker = new PfPvDoubleClickPicker(pfPvPlot);

    // the controls
    QFormLayout *f = new QFormLayout;
    cl->addLayout(f);

    QLabel *qaCPLabel = new QLabel(tr("Watts:"), this);
    qaCPValue = new QLineEdit(QString("%1").arg(pfPvPlot->getCP()));
    qaCPValue->setValidator(new QIntValidator(0, 9999, qaCPValue));
    f->addRow(qaCPLabel, qaCPValue);

    QLabel *qaCadLabel = new QLabel(tr("RPM:"), this);
    qaCadValue = new QLineEdit(QString("%1").arg(pfPvPlot->getCAD()));
    qaCadValue->setValidator(new QIntValidator(0, 999, qaCadValue));
    f->addRow(qaCadLabel, qaCadValue);

    QLabel *qaClLabel = new QLabel(tr("Crank Length (m):"), this);
    qaClValue = new QLineEdit(QString("%1").arg(1000 * pfPvPlot->getCL()));
    f->addRow(qaClLabel, qaClValue);

    shadeZonesPfPvCheckBox = new QCheckBox;
    shadeZonesPfPvCheckBox->setText(tr("Shade zones"));
    if (appsettings->value(this, GC_SHADEZONES, true).toBool() == true)
        shadeZonesPfPvCheckBox->setCheckState(Qt::Checked);
    else
        shadeZonesPfPvCheckBox->setCheckState(Qt::Unchecked);
    cl->addWidget(shadeZonesPfPvCheckBox);

    mergeIntervalPfPvCheckBox = new QCheckBox;
    mergeIntervalPfPvCheckBox->setText(tr("Merge intervals"));
    mergeIntervalPfPvCheckBox->setCheckState(Qt::Unchecked);
    cl->addWidget(mergeIntervalPfPvCheckBox);

    frameIntervalPfPvCheckBox = new QCheckBox;
    frameIntervalPfPvCheckBox->setText(tr("Frame intervals"));
    frameIntervalPfPvCheckBox->setCheckState(Qt::Checked);
    cl->addWidget(frameIntervalPfPvCheckBox);

    gearRatioDisplayPfPvCheckBox = new QCheckBox;
    gearRatioDisplayPfPvCheckBox->setText(tr("Gear Ratio Display"));
    gearRatioDisplayPfPvCheckBox->setCheckState(Qt::Checked);
    cl->addWidget(gearRatioDisplayPfPvCheckBox);
    cl->addStretch();

    connect(pfPvPlot, SIGNAL(changedCP(const QString&)), qaCPValue, SLOT(setText(const QString&)) );
    connect(pfPvPlot, SIGNAL(changedCAD(const QString&)), qaCadValue, SLOT(setText(const QString&)) );
    connect(pfPvPlot, SIGNAL(changedCL(const QString&)), qaClValue, SLOT(setText(const QString&)) );
    connect(qaCPValue, SIGNAL(editingFinished()), this, SLOT(setQaCPFromLineEdit()));
    connect(qaCadValue, SIGNAL(editingFinished()), this, SLOT(setQaCADFromLineEdit()));
    connect(qaClValue, SIGNAL(editingFinished()), this, SLOT(setQaCLFromLineEdit()));
    connect(shadeZonesPfPvCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setShadeZonesPfPvFromCheckBox()));
    connect(rShade, SIGNAL(stateChanged(int)), this, SLOT(setrShadeZonesPfPvFromCheckBox()));
    connect(mergeIntervalPfPvCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setMergeIntervalsPfPvFromCheckBox()));
    connect(rMergeInterval, SIGNAL(stateChanged(int)), this, SLOT(setrMergeIntervalsPfPvFromCheckBox()));
    connect(frameIntervalPfPvCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setFrameIntervalsPfPvFromCheckBox()));
    connect(rFrameInterval, SIGNAL(stateChanged(int)), this, SLOT(setrFrameIntervalsPfPvFromCheckBox()));
    connect(gearRatioDisplayPfPvCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setGearRatioDisplayPfPvFromCheckBox()));
    connect(doubleClickPicker, SIGNAL(doubleClicked(int, int)), this, SLOT(doubleClicked(int, int)));

    // GC signals
    connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected()));
    connect(context, SIGNAL(rideChanged(RideItem*)), this, SLOT(forceReplot()));
    connect(context, SIGNAL(intervalSelected()), this, SLOT(intervalSelected()));
    connect(context, SIGNAL(intervalsChanged()), this, SLOT(intervalSelected()));
    connect(context, SIGNAL(intervalHover(IntervalItem*)), this, SLOT(intervalHover(IntervalItem*)));
    connect(context->athlete, SIGNAL(zonesChanged()), this, SLOT(zonesChanged()));
    connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
    connect(context, SIGNAL(configChanged(qint32)), pfPvPlot, SLOT(configChanged(qint32)));

    // comparing things
    connect(context, SIGNAL(compareIntervalsStateChanged(bool)), this, SLOT(compareChanged()));
    connect(context, SIGNAL(compareIntervalsChanged()), this, SLOT(compareChanged()));

    configChanged(CONFIG_APPEARANCE);
    // share current setting with Plot
    setGearRatioDisplayPfPvFromCheckBox();
}
AllPlotWindow::AllPlotWindow(MainWindow *mainWindow) :
    QWidget(mainWindow), current(NULL), mainWindow(mainWindow), active(false), stale(true)
{
    boost::shared_ptr<QSettings> settings = GetApplicationSettings();
    QVBoxLayout *vlayout = new QVBoxLayout;

    QHBoxLayout *showLayout = new QHBoxLayout;
    QLabel *showLabel = new QLabel(tr("Show:"), this);
    showLayout->addWidget(showLabel);

    showStack = new QCheckBox(tr("Stacked view"), this);

    if (settings->value(GC_RIDE_PLOT_STACK).toInt())
        showStack->setCheckState(Qt::Checked);
    else
        showStack->setCheckState(Qt::Unchecked);
    showLayout->addWidget(showStack);

    stackWidth = 15;

    QLabel *labelspacer = new QLabel(this);
    labelspacer->setFixedWidth(5);
    showLayout->addWidget(labelspacer);

    stackZoomUp = new QwtArrowButton(1, Qt::UpArrow,this);
    stackZoomUp->setFixedHeight(15);
    stackZoomUp->setFixedWidth(15);
    stackZoomUp->setEnabled(false);
    stackZoomUp->setContentsMargins(0,0,0,0);
    stackZoomUp->setFlat(true);
    showLayout->addWidget(stackZoomUp);

    stackZoomDown = new QwtArrowButton(1, Qt::DownArrow,this);
    stackZoomDown->setFixedHeight(15);
    stackZoomDown->setFixedWidth(15);
    stackZoomDown->setEnabled(false);
    stackZoomDown->setContentsMargins(0,0,0,0);
    stackZoomDown->setFlat(true);
    showLayout->addWidget(stackZoomDown);

    QCheckBox *showGrid = new QCheckBox(tr("Grid"), this);
    showGrid->setCheckState(Qt::Checked);
    showLayout->addWidget(showGrid);

    showHr = new QCheckBox(tr("Heart Rate"), this);
    showHr->setCheckState(Qt::Checked);
    showLayout->addWidget(showHr);

    showSpeed = new QCheckBox(tr("Speed"), this);
    showSpeed->setCheckState(Qt::Checked);
    showLayout->addWidget(showSpeed);

    showCad = new QCheckBox(tr("Cadence"), this);
    showCad->setCheckState(Qt::Checked);
    showLayout->addWidget(showCad);

    showAlt = new QCheckBox(tr("Altitude"), this);
    showAlt->setCheckState(Qt::Checked);
    showLayout->addWidget(showAlt);

    showPower = new QComboBox();
    showPower->addItem(tr("Power + shade"));
    showPower->addItem(tr("Power - shade"));
    showPower->addItem(tr("No Power"));
    showLayout->addWidget(showPower);

    // shade zones defaults will come in with a
    // future patch. For now we have place holder
    // to update when new config arrives
    if (true) showPower->setCurrentIndex(0);
    else showPower->setCurrentIndex(1);

    QHBoxLayout *smoothLayout = new QHBoxLayout;
    QComboBox *comboDistance = new QComboBox();
    comboDistance->addItem(tr("X Axis Shows Time"));
    comboDistance->addItem(tr("X Axis Shows Distance"));
    smoothLayout->addWidget(comboDistance);

    QLabel *smoothLabel = new QLabel(tr("Smoothing (secs)"), this);
    smoothLineEdit = new QLineEdit(this);
    smoothLineEdit->setFixedWidth(40);

    smoothLayout->addWidget(smoothLabel);
    smoothLayout->addWidget(smoothLineEdit);
    smoothSlider = new QSlider(Qt::Horizontal);
    smoothSlider->setTickPosition(QSlider::TicksBelow);
    smoothSlider->setTickInterval(10);
    smoothSlider->setMinimum(1);
    smoothSlider->setMaximum(600);
    smoothLineEdit->setValidator(new QIntValidator(smoothSlider->minimum(),
                                                   smoothSlider->maximum(),
                                                   smoothLineEdit));
    smoothLayout->addWidget(smoothSlider);

    allPlot = new AllPlot(this, mainWindow);
    smoothSlider->setValue(allPlot->smooth);
    smoothLineEdit->setText(QString("%1").arg(allPlot->smooth));

    allZoomer = new QwtPlotZoomer(allPlot->canvas());
    allZoomer->setRubberBand(QwtPicker::RectRubberBand);
    allZoomer->setRubberBandPen(GColor(CPLOTSELECT));
    allZoomer->setSelectionFlags(QwtPicker::DragSelection
                                 | QwtPicker::CornerToCorner);
    allZoomer->setTrackerMode(QwtPicker::AlwaysOff);
    allZoomer->setEnabled(true);

    // TODO: Hack for OS X one-button mouse
    // allZoomer->initMousePattern(1);

    // RightButton: zoom out by 1
    // Ctrl+RightButton: zoom out to full size
    allZoomer->setMousePattern(QwtEventPattern::MouseSelect2,
                               Qt::RightButton, Qt::ControlModifier);
    allZoomer->setMousePattern(QwtEventPattern::MouseSelect3,
                               Qt::RightButton);

    allPanner = new QwtPlotPanner(allPlot->canvas());
    allPanner->setMouseButton(Qt::MidButton);

    // TODO: zoomer doesn't interact well with automatic axis resizing

    // tooltip on hover over point
    allPlot->tooltip = new LTMToolTip(QwtPlot::xBottom, QwtPlot::yLeft,
                               QwtPicker::PointSelection,
                               QwtPicker::VLineRubberBand,
                               QwtPicker::AlwaysOn,
                               allPlot->canvas(),
                               "");
    allPlot->tooltip->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::RectSelection | QwtPicker::DragSelection);
    allPlot->tooltip->setRubberBand(QwtPicker::VLineRubberBand);
    allPlot->tooltip->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier);
    allPlot->tooltip->setTrackerPen(QColor(Qt::black));
    QColor inv(Qt::white);
    inv.setAlpha(0);
    allPlot->tooltip->setRubberBandPen(inv);
    allPlot->tooltip->setEnabled(true);

    allPlot->_canvasPicker = new LTMCanvasPicker(allPlot);
    connect(allPlot->_canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), allPlot, SLOT(pointHover(QwtPlotCurve*, int)));
    connect(allPlot->tooltip, SIGNAL(moved(const QPoint &)), this, SLOT(plotPickerMoved(const QPoint &)));
    connect(allPlot->tooltip, SIGNAL(appended(const QPoint &)), this, SLOT(plotPickerSelected(const QPoint &)));

    QwtPlotMarker* allMarker1 = new QwtPlotMarker();
    allMarker1->setLineStyle(QwtPlotMarker::VLine);
    allMarker1->attach(allPlot);
    allMarker1->setLabelAlignment(Qt::AlignTop|Qt::AlignRight);
    allPlot->allMarker1=allMarker1;

    QwtPlotMarker* allMarker2 = new QwtPlotMarker();
    allMarker2->setLineStyle(QwtPlotMarker::VLine);
    allMarker2->attach(allPlot);
    allMarker2->setLabelAlignment(Qt::AlignTop|Qt::AlignRight);
    allPlot->allMarker2=allMarker2;

    //
    // stack view
    //
    stackFrame = new QScrollArea();
    stackFrame->hide();
    stackPlotLayout = new QVBoxLayout();
    stackWidget = new QWidget();
    stackWidget->setLayout(stackPlotLayout);
    stackFrame->setWidgetResizable(true);
    stackFrame->setWidget(stackWidget);

    //
    // allPlot view
    //
    QVBoxLayout *allPlotLayout = new QVBoxLayout;
    allPlotFrame = new QScrollArea();

    spanSlider = new QxtSpanSlider(Qt::Horizontal);
    spanSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
    spanSlider->setLowerValue(0);
    spanSlider->setUpperValue(15);

    QFont small;
    small.setPointSize(6);

    scrollLeft = new QPushButton("<");
    scrollLeft->setFont(small);
    scrollLeft->setAutoRepeat(true);
    scrollLeft->setFixedHeight(16);
    scrollLeft->setFixedWidth(16);
    scrollLeft->setContentsMargins(0,0,0,0);

    scrollRight = new QPushButton(">");
    scrollRight->setFont(small);
    scrollRight->setAutoRepeat(true);
    scrollRight->setFixedHeight(16);
    scrollRight->setFixedWidth(16);
    scrollRight->setContentsMargins(0,0,0,0);

#ifdef Q_OS_MAC
    // BUG in QMacStyle and painting of spanSlider
    // so we use a plain style to avoid it, but only
    // on a MAC, since win and linux are fine
    QCleanlooksStyle *style = new QCleanlooksStyle();
    spanSlider->setStyle(style);
    scrollLeft->setStyle(style);
    scrollRight->setStyle(style);
#endif

    fullPlot = new AllPlot(this, mainWindow);
    fullPlot->grid->enableY(false);
    fullPlot->setCanvasBackground(GColor(CPLOTTHUMBNAIL));
    fullPlot->setCanvasLineWidth(0);
    fullPlot->enableAxis(QwtPlot::yLeft, false);
    fullPlot->enableAxis(QwtPlot::yLeft2, false);
    fullPlot->enableAxis(QwtPlot::yRight, false);
    fullPlot->enableAxis(QwtPlot::yRight2, false);
    fullPlot->enableAxis(QwtPlot::xBottom, false);
    fullPlot->legend()->clear();
    //fullPlot->setTitle("");
    fullPlot->setContentsMargins(0,0,0,0);

    allPlotLayout->addWidget(allPlot);
    allPlotFrame->setLayout(allPlotLayout);

    // controls...
    controlsLayout = new QGridLayout;
    controlsLayout->addWidget(fullPlot, 0,1);
    controlsLayout->addWidget(spanSlider, 1,1);
    controlsLayout->addWidget(scrollLeft,1,0);
    controlsLayout->addWidget(scrollRight,1,2);
    controlsLayout->setRowStretch(0, 10);
    controlsLayout->setRowStretch(1, 1);
    controlsLayout->setContentsMargins(0,0,0,0);
#ifdef Q_OS_MAC
    // macs  dpscing is weird
    //controlsLayout->setSpacing(5);
#else
    controlsLayout->setSpacing(0);
#endif

    vlayout->addWidget(allPlotFrame);
    vlayout->addWidget(stackFrame);
    vlayout->addLayout(controlsLayout);
    vlayout->addLayout(showLayout);
    vlayout->addLayout(smoothLayout);
    vlayout->setStretch(0,100);
    vlayout->setStretch(1,100);
    vlayout->setStretch(2,15);
    vlayout->setStretch(3,1);
    vlayout->setStretch(4,1);
    vlayout->setSpacing(1);
    setLayout(vlayout);

    // common controls
    connect(showPower, SIGNAL(currentIndexChanged(int)), this, SLOT(setShowPower(int)));
    connect(showHr, SIGNAL(stateChanged(int)), this, SLOT(setShowHr(int)));
    connect(showSpeed, SIGNAL(stateChanged(int)), this, SLOT(setShowSpeed(int)));
    connect(showCad, SIGNAL(stateChanged(int)), this, SLOT(setShowCad(int)));
    connect(showAlt, SIGNAL(stateChanged(int)), this, SLOT(setShowAlt(int)));
    connect(showGrid, SIGNAL(stateChanged(int)), this, SLOT(setShowGrid(int)));
    connect(showStack, SIGNAL(stateChanged(int)), this, SLOT(showStackChanged(int)));
    connect(comboDistance, SIGNAL(currentIndexChanged(int)), this, SLOT(setByDistance(int)));
    connect(smoothSlider, SIGNAL(valueChanged(int)), this, SLOT(setSmoothingFromSlider()));
    connect(smoothLineEdit, SIGNAL(editingFinished()), this, SLOT(setSmoothingFromLineEdit()));

    // normal view
    connect(spanSlider, SIGNAL(lowerPositionChanged(int)), this, SLOT(zoomChanged()));
    connect(spanSlider, SIGNAL(upperPositionChanged(int)), this, SLOT(zoomChanged()));

    // stacked view
    connect(stackZoomUp, SIGNAL(clicked()), this, SLOT(setStackZoomUp()));
    connect(stackZoomDown, SIGNAL(clicked()), this, SLOT(setStackZoomDown()));
    connect(scrollLeft, SIGNAL(clicked()), this, SLOT(moveLeft()));
    connect(scrollRight, SIGNAL(clicked()), this, SLOT(moveRight()));

    // GC signals
    connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected()));
    connect(mainWindow, SIGNAL(rideDirty()), this, SLOT(rideSelected()));
    connect(mainWindow, SIGNAL(zonesChanged()), this, SLOT(zonesChanged()));
    connect(mainWindow, SIGNAL(intervalsChanged()), this, SLOT(intervalsChanged()));
    connect(mainWindow, SIGNAL(intervalSelected()), this, SLOT(intervalSelected()));
    connect(mainWindow, SIGNAL(configChanged()), allPlot, SLOT(configChanged()));
    connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged()));
}
ScatterWindow::ScatterWindow(MainWindow *parent, const QDir &home) :
    GcChartWindow(parent), home(home), main(parent), ride(NULL), current(NULL)
{
    setInstanceName("2D Window");

    //
    // reveal controls widget
    //

    // reveal controls
    QLabel *rxLabel = new QLabel(tr("X-Axis:"), this);
    rxSelector = new QxtStringSpinBox();
    addrStandardChannels(rxSelector);

    QLabel *ryLabel = new QLabel(tr("Y-Axis:"), this);
    rySelector = new QxtStringSpinBox();
    addrStandardChannels(rySelector);

    rIgnore = new QCheckBox(tr("Ignore Zero"));
    rIgnore->setChecked(true);
    rIgnore->hide();
    rFrameInterval = new QCheckBox(tr("Frame intervals"));
    rFrameInterval->setChecked(true);

    // layout reveal controls
    QHBoxLayout *r = new QHBoxLayout;
    r->setContentsMargins(0,0,0,0);
    r->addStretch();
    r->addWidget(rxLabel);
    r->addWidget(rxSelector);
    r->addWidget(ryLabel);
    r->addWidget(rySelector);
    r->addSpacing(5);
    r->addWidget(rIgnore);
    r->addWidget(rFrameInterval);
    r->addStretch();
    setRevealLayout(r);

    QWidget *c = new QWidget;
    QFormLayout *cl = new QFormLayout(c);
    setControls(c);

    // the plot widget
    scatterPlot= new ScatterPlot(main);
    QVBoxLayout *vlayout = new QVBoxLayout;
    vlayout->addWidget(scatterPlot);

    setChartLayout(vlayout);

    // labels
    xLabel = new QLabel(tr("X-Axis:"), this);
    xSelector = new QComboBox;
    addStandardChannels(xSelector);
    xSelector->setCurrentIndex(0); // power
    rxSelector->setValue(0);
    cl->addRow(xLabel, xSelector);

    yLabel = new QLabel(tr("Y-Axis:"), this);
    ySelector = new QComboBox;
    addStandardChannels(ySelector);
    ySelector->setCurrentIndex(2); // heartrate
    rySelector->setValue(2);
    cl->addRow(yLabel, ySelector);

    timeLabel = new QLabel(tr("00:00:00"), this);
    timeSlider = new QSlider(Qt::Horizontal);
    timeSlider->setTickPosition(QSlider::TicksBelow);
    timeSlider->setTickInterval(1);
    timeSlider->setMinimum(0);
    timeSlider->setTickInterval(5);
    timeSlider->setMaximum(100);
    timeSlider->setValue(0);
    timeSlider->setTracking(true);
    cl->addRow(timeLabel, timeSlider);

    // selectors
    ignore = new QCheckBox(tr("Ignore Zero"));
    ignore->setChecked(true);
    cl->addRow(ignore);

    grid = new QCheckBox(tr("Show Grid"));
    grid->setChecked(true);
    cl->addRow(grid);

    frame = new QCheckBox(tr("Frame Intervals"));
    frame->setChecked(true);
    cl->addRow(frame);

    // now connect up the widgets
    //connect(main, SIGNAL(rideSelected()), this, SLOT(rideSelected()));
    connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected()));
    connect(main, SIGNAL(intervalSelected()), this, SLOT(intervalSelected()));
    connect(main, SIGNAL(intervalsChanged()), this, SLOT(intervalSelected()));
    connect(xSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setData()));
    connect(ySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setData()));
    connect(rxSelector, SIGNAL(valueChanged(int)), this, SLOT(rxSelectorChanged(int)));
    connect(rySelector, SIGNAL(valueChanged(int)), this, SLOT(rySelectorChanged(int)));
    connect(timeSlider, SIGNAL(valueChanged(int)), this, SLOT(setTime(int)));
    connect(grid, SIGNAL(stateChanged(int)), this, SLOT(setGrid()));
    //connect(legend, SIGNAL(stateChanged(int)), this, SLOT(setLegend()));
    connect(frame, SIGNAL(stateChanged(int)), this, SLOT(setFrame()));
    connect(ignore, SIGNAL(stateChanged(int)), this, SLOT(setIgnore()));
    connect(rFrameInterval, SIGNAL(stateChanged(int)), this, SLOT(setrFrame()));
    connect(rIgnore, SIGNAL(stateChanged(int)), this, SLOT(setrIgnore()));

}