PerfPlot::PerfPlot() : STScurve(NULL), LTScurve(NULL), SBcurve(NULL), DAYcurve(NULL) { setInstanceName("PM Plot"); insertLegend(new QwtLegend(), QwtPlot::BottomLegend); setAxisTitle(yLeft, "Exponentially Weighted Average Stress"); setAxisTitle(xBottom, "Time (days)"); setAxisTitle(yRight, "Daily Stress"); enableAxis(yRight, true); canvas()->setFrameStyle(QFrame::NoFrame); setAxisMaxMinor(xBottom, 0); setAxisMaxMinor(yLeft, 0); setAxisMaxMinor(yRight, 0); QwtScaleDraw *sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(QwtPlot::xBottom, sd); sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(QwtPlot::yLeft, sd); sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(QwtPlot::yRight, sd); grid = new QwtPlotGrid(); grid->attach(this); configUpdate(); }
void IoDisk::setup(const StringMap & settings) { Io::setup(settings); // -------------------------- // Get name from instance std::string instanceName = settings.at("name"); setInstanceName(instanceName); // -------------------------- // Check if need to draw timestamp bool drawTimestamp = (settings.at("ios.Disk.markWithTimestamp") == "true"); setDrawTimestamp(drawTimestamp); cv::Scalar color = getColor(settings.at("ios.Disk.timestampColor")); setTimestampColor(color); std::string timezone = settings.at("timezone"); std::replace(timezone.begin(), timezone.end(), '-', '/'); std::replace(timezone.begin(), timezone.end(), '$', '_'); setTimezone(timezone); // ------------------------------------------------------------- // Filemanager is mapped to a directory and is used by an image // to save to the correct directory. setFileFormat(settings.at("ios.Disk.fileFormat")); m_fileManager.setBaseDirectory(settings.at("ios.Disk.directory")); }
DialWindow::DialWindow(MainWindow *mainWindow) : GcWindow(mainWindow), mainWindow(mainWindow), average(1), isNewLap(false) { rolling.resize(150); // enough for 30 seconds at 5hz setContentsMargins(0,0,0,0); setInstanceName("Dial"); QWidget *c = new QWidget; QVBoxLayout *cl = new QVBoxLayout(c); setControls(c); // setup the controls QFormLayout *controlsLayout = new QFormLayout(); controlsLayout->setSpacing(0); controlsLayout->setContentsMargins(5,5,5,5); cl->addLayout(controlsLayout); // data series selection QLabel *seriesLabel = new QLabel(tr("Data Series"), this); seriesLabel->setAutoFillBackground(true); seriesSelector = new QComboBox(this); foreach (RealtimeData::DataSeries x, RealtimeData::listDataSeries()) { seriesSelector->addItem(RealtimeData::seriesName(x), static_cast<int>(x)); }
CpintPlot::CpintPlot(Context *context, QString p, const Zones *zones) : path(p), thisCurve(NULL), CPCurve(NULL), allCurve(NULL), zones(zones), series(RideFile::watts), context(context), current(NULL), bests(NULL), isFiltered(false), shadeMode(2) { setInstanceName("CP Plot"); assert(!USE_T0_IN_CP_MODEL); // doesn't work with energyMode=true setAxisTitle(xBottom, tr("Interval Length")); LogTimeScaleDraw *ld = new LogTimeScaleDraw; ld->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(xBottom, ld); setAxisScaleEngine(xBottom, new LogTimeScaleEngine); setAxisScale(xBottom, (double)0.017, (double)60); QwtScaleDraw *sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(yLeft, sd); setAxisTitle(yLeft, tr("Average Power (watts)")); setAxisMaxMinor(yLeft, 0); plotLayout()->setAlignCanvasToScales(true); grid = new QwtPlotGrid(); grid->enableX(true); grid->attach(this); curveTitle.attach(this); curveTitle.setXValue(5); curveTitle.setYValue(20); curveTitle.setLabel(QwtText("", QwtText::PlainText)); // default to no title zoomer = new penTooltip(this->canvas()); zoomer->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier); canvasPicker = new LTMCanvasPicker(this); canvas()->setFrameStyle(QFrame::NoFrame); connect(canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), this, SLOT(pointHover(QwtPlotCurve*, int))); configChanged(); // apply colors }
void IoWebhook::setup(const StringMap & settings) { Io::setup(settings); // -------------------------- // Get name from instance std::string instanceName = settings.at("name"); setInstanceName(instanceName); // ------- // Get url setUrl(settings.at("ios.Webhook.url").c_str()); }
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 {
void IoDisk::setup(const StringMap & settings) { Io::setup(settings); // -------------------------- // Get name from instance std::string instanceName = settings.at("name"); setInstanceName(instanceName); // ------------------------------------------------------------- // Filemanager is mapped to a directory and is used by an image // to save to the correct directory. setFileFormat(settings.at("ios.Disk.fileFormat")); m_fileManager.setBaseDirectory(settings.at("ios.Disk.directory")); }
MetadataWindow::MetadataWindow(Context *context) : GcChartWindow(context), context(context) { setInstanceName("Metadata Window"); setControls(NULL); setRideItem(NULL); setContentsMargins(0,0,0,0); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->setSpacing(0); rideMetadata = new RideMetadata(context); QFont font; font.setPointSize(font.pointSize()); rideMetadata->setFont(font); rideMetadata->setContentsMargins(20,0,20,20); vlayout->addWidget(rideMetadata); setChartLayout(vlayout); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideItemChanged())); }
ScatterPlot::ScatterPlot(Context *context) : context(context) { setInstanceName("2D Plot"); all = NULL; grid = NULL; canvas()->setFrameStyle(QFrame::NoFrame); setAxisMaxMinor(xBottom, 0); setAxisMaxMinor(yLeft, 0); QwtScaleDraw *sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(QwtPlot::xBottom, sd); sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(QwtPlot::yLeft, sd); connect(context, SIGNAL(configChanged()), this, SLOT(configChanged())); configChanged(); // use latest colors etc }
SpinScanPlot::SpinScanPlot(QWidget *parent, uint8_t *spinData) : QwtPlot(parent), leftCurve(NULL), rightCurve(NULL), spinData(spinData) { setInstanceName("SpinScan Plot"); // Setup the axis setAxisTitle(yLeft, "SpinScan"); setAxisMaxMinor(xBottom, 0); setAxisMaxMinor(yLeft, 0); QPalette pal; setAxisScale(yLeft, 0, 90); // max 8 bit plus a little setAxisScale(xBottom, 0, 24); // max 8 bit plus a little pal.setColor(QPalette::WindowText, GColor(CSPINSCANLEFT)); pal.setColor(QPalette::Text, GColor(CSPINSCANLEFT)); axisWidget(QwtPlot::yLeft)->setPalette(pal); axisWidget(QwtPlot::yLeft)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); enableAxis(xBottom, false); // very little value and some cpu overhead enableAxis(yLeft, true); // 30s Power curve rightCurve = new QwtPlotCurve("SpinScan Left"); rightCurve->setRenderHint(QwtPlotItem::RenderAntialiased); // too cpu intensive rightCurve->attach(this); rightCurve->setYAxis(QwtPlot::yLeft); leftCurve = new QwtPlotCurve("SpinScan Right"); leftCurve->setRenderHint(QwtPlotItem::RenderAntialiased); // too cpu intensive leftCurve->attach(this); leftCurve->setYAxis(QwtPlot::yLeft); leftSpinScanData = new SpinScanData(spinData, true); rightSpinScanData = new SpinScanData(spinData, false); canvas()->setFrameStyle(QFrame::NoFrame); configChanged(); // set colors }
CriticalPowerWindow::CriticalPowerWindow(const QDir &home, MainWindow *parent, bool rangemode) : GcWindow(parent), _dateRange("{00000000-0000-0000-0000-000000000001}"), home(home), mainWindow(parent), currentRide(NULL), rangemode(rangemode), stale(true), useCustom(false) { setInstanceName("Critical Power Window"); // main plot area QVBoxLayout *vlayout = new QVBoxLayout; cpintPlot = new CpintPlot(mainWindow, home.path(), mainWindow->zones()); vlayout->addWidget(cpintPlot); setLayout(vlayout); // controls QWidget *c = new QWidget; QFormLayout *cl = new QFormLayout(c); setControls(c); #ifdef GC_HAVE_LUCENE // searchbox searchBox = new SearchFilterBox(this, parent); connect(searchBox, SIGNAL(searchClear()), cpintPlot, SLOT(clearFilter())); connect(searchBox, SIGNAL(searchResults(QStringList)), cpintPlot, SLOT(setFilter(QStringList))); connect(searchBox, SIGNAL(searchClear()), this, SLOT(filterChanged())); connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(filterChanged())); cl->addRow(new QLabel(tr("Filter")), searchBox); cl->addWidget(new QLabel("")); //spacing #endif // picker details QLabel *cpintTimeLabel = new QLabel(tr("Duration:"), this); cpintTimeValue = new QLineEdit("0 s"); QLabel *cpintTodayLabel = new QLabel(tr("Today:"), this); cpintTodayValue = new QLabel(tr("no data")); QLabel *cpintAllLabel = new QLabel(tr("Best:"), this); cpintAllValue = new QLabel(tr("no data")); QLabel *cpintCPLabel = new QLabel(tr("CP Curve:"), this); cpintCPValue = new QLabel(tr("no data")); //QFontMetrics metrics(QApplication::font()); //int width = metrics.width("8888 watts (88/88/8888)") + 10; //cpintAllValue->setFixedWidth(width); //cpintCPValue->setFixedWidth(width); // so lines up nicely cpintTimeValue->setReadOnly(false); //cpintTodayValue->setReadOnly(true); //cpintAllValue->setReadOnly(true); //cpintCPValue->setReadOnly(true); QFont font = cpintTimeValue->font(); font.setPointSize(font.pointSize()); cpintTodayValue->setFont(font); cpintAllValue->setFont(font); cpintCPValue->setFont(font); cl->addRow(cpintTimeLabel, cpintTimeValue); cl->addRow(cpintTodayLabel, cpintTodayValue); cl->addRow(cpintAllLabel, cpintAllValue); cl->addRow(cpintCPLabel, cpintCPValue); cl->addWidget(new QLabel("")); //spacing // tools /properties seriesCombo = new QComboBox(this); addSeries(); cComboSeason = new QComboBox(this); seasons = parent->seasons; resetSeasons(); QLabel *label = new QLabel(tr("Date range")); QLabel *label2 = new QLabel(tr("Date range")); if (rangemode) { cComboSeason->hide(); label2->hide(); } cpintSetCPButton = new QPushButton(tr("&Save CP value"), this); cpintSetCPButton->setEnabled(false); cl->addRow(label2, cComboSeason); dateSetting = new DateSettingsEdit(this); cl->addRow(label, dateSetting); if (rangemode == false) { dateSetting->hide(); label->hide(); } cl->addWidget(new QLabel("")); //spacing cl->addRow(new QLabel(tr("Data series")), seriesCombo); cl->addRow(new QLabel(""), cpintSetCPButton); picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::VLineRubberBand, QwtPicker::AlwaysOff, cpintPlot->canvas()); picker->setStateMachine(new QwtPickerDragPointMachine); picker->setRubberBandPen(GColor(CPLOTTRACKER)); connect(picker, SIGNAL(moved(const QPoint &)), SLOT(pickerMoved(const QPoint &))); connect(cpintTimeValue, SIGNAL(editingFinished()), this, SLOT(cpintTimeValueEntered())); connect(cpintSetCPButton, SIGNAL(clicked()), this, SLOT(cpintSetCPButtonClicked())); if (rangemode) { connect(this, SIGNAL(dateRangeChanged(DateRange)), SLOT(dateRangeChanged(DateRange))); } else { connect(cComboSeason, SIGNAL(currentIndexChanged(int)), this, SLOT(seasonSelected(int))); } connect(seriesCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setSeries(int))); //connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected())); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); connect(mainWindow, SIGNAL(configChanged()), cpintPlot, SLOT(configChanged())); // redraw on config change -- this seems the simplest approach connect(mainWindow, SIGNAL(configChanged()), this, SLOT(rideSelected())); connect(mainWindow, SIGNAL(rideAdded(RideItem*)), this, SLOT(newRideAdded(RideItem*))); connect(mainWindow, SIGNAL(rideDeleted(RideItem*)), this, SLOT(newRideAdded(RideItem*))); connect(seasons, SIGNAL(seasonsChanged()), this, SLOT(resetSeasons())); connect(dateSetting, SIGNAL(useCustomRange(DateRange)), this, SLOT(useCustomRange(DateRange))); connect(dateSetting, SIGNAL(useThruToday()), this, SLOT(useThruToday())); connect(dateSetting, SIGNAL(useStandardRange()), this, SLOT(useStandardRange())); }
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*))); }
MainWindow::MainWindow(const QDir &home) { /*---------------------------------------------------------------------- * Bootstrap *--------------------------------------------------------------------*/ setAttribute(Qt::WA_DeleteOnClose); mainwindows.append(this); // add us to the list of open windows context = new Context(this); context->athlete = new Athlete(context, home); setInstanceName(context->athlete->cyclist); setWindowIcon(QIcon(":images/gc.png")); setWindowTitle(context->athlete->home.dirName()); setContentsMargins(0,0,0,0); setAcceptDrops(true); GCColor *GCColorSet = new GCColor(context); // get/keep colorset GCColorSet->colorSet(); // shut up the compiler #ifdef Q_OS_MAC // get an autorelease pool setup static CocoaInitializer cocoaInitializer; #endif #ifdef GC_HAVE_WFAPI WFApi *w = WFApi::getInstance(); // ensure created on main thread w->apiVersion();//shutup compiler #endif Library::initialise(context->athlete->home); QNetworkProxyQuery npq(QUrl("http://www.google.com")); QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(npq); if (listOfProxies.count() > 0) { QNetworkProxy::setApplicationProxy(listOfProxies.first()); } if (desktop == NULL) desktop = QApplication::desktop(); static const QIcon hideIcon(":images/toolbar/main/hideside.png"); static const QIcon rhideIcon(":images/toolbar/main/hiderside.png"); static const QIcon showIcon(":images/toolbar/main/showside.png"); static const QIcon rshowIcon(":images/toolbar/main/showrside.png"); static const QIcon tabIcon(":images/toolbar/main/tab.png"); static const QIcon tileIcon(":images/toolbar/main/tile.png"); static const QIcon fullIcon(":images/toolbar/main/togglefull.png"); #if (defined Q_OS_MAC) && (defined GC_HAVE_LION) fullScreen = new LionFullScreen(context); #endif #ifndef Q_OS_MAC fullScreen = new QTFullScreen(context); #endif // if no workout directory is configured, default to the // top level GoldenCheetah directory if (appsettings->value(NULL, GC_WORKOUTDIR).toString() == "") appsettings->setValue(GC_WORKOUTDIR, QFileInfo(context->athlete->home.absolutePath() + "/../").absolutePath()); /*---------------------------------------------------------------------- * GUI setup *--------------------------------------------------------------------*/ // need to restore geometry before setUnifiedToolBar.. on Mac appsettings->setValue(GC_SETTINGS_LAST, context->athlete->home.dirName()); QVariant geom = appsettings->value(this, GC_SETTINGS_MAIN_GEOM); if (geom == QVariant()) { // first run -- lets set some sensible defaults... // lets put it in the middle of screen 1 QRect size = desktop->availableGeometry(); struct SizeSettings app = GCColor::defaultSizes(size.height(), size.width()); // center on the available screen (minus toolbar/sidebar) move((size.width()-size.x())/2 - app.width/2, (size.height()-size.y())/2 - app.height/2); // set to the right default resize(app.width, app.height); // set all the default font sizes appsettings->setValue(GC_FONT_DEFAULT_SIZE, app.defaultFont); appsettings->setValue(GC_FONT_TITLES_SIZE, app.titleFont); appsettings->setValue(GC_FONT_CHARTMARKERS_SIZE, app.markerFont); appsettings->setValue(GC_FONT_CHARTLABELS_SIZE, app.labelFont); appsettings->setValue(GC_FONT_CALENDAR_SIZE, app.calendarFont); appsettings->setValue(GC_FONT_POPUP_SIZE, app.popupFont); // set the default fontsize QFont font; font.setPointSize(app.defaultFont); QApplication::setFont(font); } else { QRect size = desktop->availableGeometry(); // ensure saved geometry isn't greater than current screen size if ((geom.toRect().height() >= size.height()) || (geom.toRect().width() >= size.width())) setGeometry(size.x()+30,size.y()+30,size.width()-60,size.height()-60); else setGeometry(geom.toRect()); } /*---------------------------------------------------------------------- * Mac Toolbar *--------------------------------------------------------------------*/ #ifdef Q_OS_MAC setUnifiedTitleAndToolBarOnMac(true); head = addToolBar(context->athlete->cyclist); head->setContentsMargins(0,0,0,0); // widgets QWidget *macAnalButtons = new QWidget(this); macAnalButtons->setContentsMargins(0,0,20,0); // lhs buttons QHBoxLayout *lb = new QHBoxLayout(macAnalButtons); lb->setContentsMargins(0,0,0,0); lb->setSpacing(0); import = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *importImg = new QPixmap(":images/mac/download.png"); import->setImage(importImg); import->setToolTip("Download"); lb->addWidget(import); lb->addWidget(new Spacer(this)); compose = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *composeImg = new QPixmap(":images/mac/compose.png"); compose->setImage(composeImg); compose->setToolTip("Create"); lb->addWidget(compose); // connect to actions connect(import, SIGNAL(clicked(bool)), this, SLOT(downloadRide())); connect(compose, SIGNAL(clicked(bool)), this, SLOT(manualRide())); lb->addWidget(new Spacer(this)); // activity actions .. peaks, split, delete QWidget *acts = new QWidget(this); acts->setContentsMargins(0,0,0,0); QHBoxLayout *pp = new QHBoxLayout(acts); pp->setContentsMargins(0,0,0,0); pp->setContentsMargins(0,0,0,0); pp->setSpacing(5); sidebar = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *sidebarImg = new QPixmap(":images/mac/sidebar.png"); sidebar->setImage(sidebarImg); sidebar->setMinimumSize(25, 25); sidebar->setMaximumSize(25, 25); sidebar->setToolTip("Sidebar"); sidebar->setSelected(true); // assume always start up with sidebar selected actbuttons = new QtMacSegmentedButton(3, acts); actbuttons->setWidth(115); actbuttons->setNoSelect(); actbuttons->setImage(0, new QPixmap(":images/mac/stop.png")); actbuttons->setImage(1, new QPixmap(":images/mac/split.png")); actbuttons->setImage(2, new QPixmap(":images/mac/trash.png")); pp->addWidget(actbuttons); lb->addWidget(acts); lb->addStretch(); connect(actbuttons, SIGNAL(clicked(int,bool)), this, SLOT(actionClicked(int))); lb->addWidget(new Spacer(this)); QWidget *viewsel = new QWidget(this); viewsel->setContentsMargins(0,0,0,0); QHBoxLayout *pq = new QHBoxLayout(viewsel); pq->setContentsMargins(0,0,0,0); pq->setSpacing(5); pq->addWidget(sidebar); styleSelector = new QtMacSegmentedButton(2, viewsel); styleSelector->setWidth(80); // actually its 80 but we want a 30px space between is and the searchbox styleSelector->setImage(0, new QPixmap(":images/mac/tabbed.png"), 24); styleSelector->setImage(1, new QPixmap(":images/mac/tiled.png"), 24); pq->addWidget(styleSelector); connect(sidebar, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar())); connect(styleSelector, SIGNAL(clicked(int,bool)), this, SLOT(toggleStyle())); // setup Mac thetoolbar head->addWidget(macAnalButtons); head->addWidget(new Spacer(this)); head->addWidget(new Spacer(this)); head->addWidget(viewsel); #ifdef GC_HAVE_LUCENE SearchFilterBox *searchBox = new SearchFilterBox(this,context,false); QCleanlooksStyle *toolStyle = new QCleanlooksStyle(); searchBox->setStyle(toolStyle); searchBox->setFixedWidth(200); head->addWidget(searchBox); connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(setFilter(QStringList))); connect(searchBox, SIGNAL(searchClear()), this, SLOT(clearFilter())); #endif #endif /*---------------------------------------------------------------------- * Windows and Linux Toolbar *--------------------------------------------------------------------*/ #ifndef Q_OS_MAC head = new GcToolBar(this); QCleanlooksStyle *toolStyle = new QCleanlooksStyle(); QPalette metal; metal.setColor(QPalette::Button, QColor(215,215,215)); // get those icons importIcon = iconFromPNG(":images/mac/download.png"); composeIcon = iconFromPNG(":images/mac/compose.png"); intervalIcon = iconFromPNG(":images/mac/stop.png"); splitIcon = iconFromPNG(":images/mac/split.png"); deleteIcon = iconFromPNG(":images/mac/trash.png"); sidebarIcon = iconFromPNG(":images/mac/sidebar.png"); tabbedIcon = iconFromPNG(":images/mac/tabbed.png"); tiledIcon = iconFromPNG(":images/mac/tiled.png"); QSize isize(19,19); Spacer *spacerl = new Spacer(this); spacerl->setFixedWidth(5); import = new QPushButton(this); import->setIcon(importIcon); import->setIconSize(isize); import->setFixedHeight(25); import->setStyle(toolStyle); import->setToolTip(tr("Download from Device")); import->setPalette(metal); connect(import, SIGNAL(clicked(bool)), this, SLOT(downloadRide())); compose = new QPushButton(this); compose->setIcon(composeIcon); compose->setIconSize(isize); compose->setFixedHeight(25); compose->setStyle(toolStyle); compose->setToolTip(tr("Create Manual Activity")); compose->setPalette(metal); connect(compose, SIGNAL(clicked(bool)), this, SLOT(manualRide())); sidebar = new QPushButton(this); sidebar->setIcon(sidebarIcon); sidebar->setIconSize(isize); sidebar->setFixedHeight(25); sidebar->setStyle(toolStyle); sidebar->setToolTip(tr("Toggle Sidebar")); sidebar->setPalette(metal); connect(sidebar, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar())); actbuttons = new QtSegmentControl(this); actbuttons->setStyle(toolStyle); actbuttons->setIconSize(isize); actbuttons->setCount(3); actbuttons->setSegmentIcon(0, intervalIcon); actbuttons->setSegmentIcon(1, splitIcon); actbuttons->setSegmentIcon(2, deleteIcon); actbuttons->setSelectionBehavior(QtSegmentControl::SelectNone); //wince. spelling. ugh actbuttons->setFixedHeight(25); actbuttons->setSegmentToolTip(0, tr("Find Intervals...")); actbuttons->setSegmentToolTip(1, tr("Split Activity...")); actbuttons->setSegmentToolTip(2, tr("Delete Activity")); actbuttons->setPalette(metal); connect(actbuttons, SIGNAL(segmentSelected(int)), this, SLOT(actionClicked(int))); styleSelector = new QtSegmentControl(this); styleSelector->setStyle(toolStyle); styleSelector->setIconSize(isize); styleSelector->setCount(2); styleSelector->setSegmentIcon(0, tabbedIcon); styleSelector->setSegmentIcon(1, tiledIcon); styleSelector->setSegmentToolTip(0, tr("Tabbed View")); styleSelector->setSegmentToolTip(1, tr("Tiled View")); styleSelector->setSelectionBehavior(QtSegmentControl::SelectOne); //wince. spelling. ugh styleSelector->setFixedHeight(25); styleSelector->setPalette(metal); connect(styleSelector, SIGNAL(segmentSelected(int)), this, SLOT(setStyleFromSegment(int))); //avoid toggle infinitely head->addWidget(spacerl); head->addWidget(import); head->addWidget(compose); head->addWidget(actbuttons); head->addStretch(); head->addWidget(sidebar); head->addWidget(styleSelector); #ifdef GC_HAVE_LUCENE // add a search box on far right, but with a little space too SearchFilterBox *searchBox = new SearchFilterBox(this,context,false); searchBox->setStyle(toolStyle); searchBox->setFixedWidth(200); head->addWidget(searchBox); connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(setFilter(QStringList))); connect(searchBox, SIGNAL(searchClear()), this, SLOT(clearFilter())); #endif Spacer *spacer = new Spacer(this); spacer->setFixedWidth(5); head->addWidget(spacer); #endif /*---------------------------------------------------------------------- * ScopeBar *--------------------------------------------------------------------*/ scopebar = new GcScopeBar(context); connect(scopebar, SIGNAL(selectDiary()), this, SLOT(selectDiary())); connect(scopebar, SIGNAL(selectHome()), this, SLOT(selectHome())); connect(scopebar, SIGNAL(selectAnal()), this, SLOT(selectAnalysis())); connect(scopebar, SIGNAL(selectTrain()), this, SLOT(selectTrain())); // Add chart is on the scope bar chartMenu = new QMenu(this); QCleanlooksStyle *styler = new QCleanlooksStyle(); QPushButton *newchart = new QPushButton("+", this); scopebar->addWidget(newchart); newchart->setStyle(styler); newchart->setFixedHeight(20); newchart->setFixedWidth(24); newchart->setFlat(true); newchart->setFocusPolicy(Qt::NoFocus); newchart->setToolTip(tr("Add Chart")); newchart->setAutoFillBackground(false); newchart->setAutoDefault(false); newchart->setMenu(chartMenu); connect(chartMenu, SIGNAL(aboutToShow()), this, SLOT(setChartMenu())); connect(chartMenu, SIGNAL(triggered(QAction*)), this, SLOT(addChart(QAction*))); /*---------------------------------------------------------------------- * Central Widget *--------------------------------------------------------------------*/ tab = new Tab(context); /*---------------------------------------------------------------------- * Central Widget *--------------------------------------------------------------------*/ QWidget *central = new QWidget(this); setContentsMargins(0,0,0,0); central->setContentsMargins(0,0,0,0); QVBoxLayout *mainLayout = new QVBoxLayout(central); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0,0,0,0); #ifndef Q_OS_MAC // nonmac toolbar on main view -- its not // unified with the title bar. mainLayout->addWidget(head); #endif mainLayout->addWidget(scopebar); mainLayout->addWidget(tab); setCentralWidget(central); /*---------------------------------------------------------------------- * Application Menus *--------------------------------------------------------------------*/ #ifdef WIN32 menuBar()->setStyleSheet("QMenuBar { background: rgba(225,225,225); }" "QMenuBar::item { background: rgba(225,225,225); }"); menuBar()->setContentsMargins(0,0,0,0); #endif QMenu *fileMenu = menuBar()->addMenu(tr("&Athlete")); fileMenu->addAction(tr("&New..."), this, SLOT(newCyclist()), tr("Ctrl+N")); fileMenu->addAction(tr("&Open..."), this, SLOT(openCyclist()), tr("Ctrl+O")); fileMenu->addAction(tr("&Close Window"), this, SLOT(close()), tr ("Ctrl+W")); fileMenu->addAction(tr("&Quit All Windows"), this, SLOT(closeAll()), tr("Ctrl+Q")); QMenu *rideMenu = menuBar()->addMenu(tr("A&ctivity")); rideMenu->addAction(tr("&Download from device..."), this, SLOT(downloadRide()), tr("Ctrl+D")); rideMenu->addAction(tr("&Import from file..."), this, SLOT (importFile()), tr ("Ctrl+I")); rideMenu->addAction(tr("&Manual activity entry..."), this, SLOT(manualRide()), tr("Ctrl+M")); rideMenu->addSeparator (); rideMenu->addAction(tr("&Export..."), this, SLOT(exportRide()), tr("Ctrl+E")); rideMenu->addAction(tr("&Batch export..."), this, SLOT(exportBatch()), tr("Ctrl+B")); rideMenu->addAction(tr("Export Metrics as CSV..."), this, SLOT(exportMetrics()), tr("")); #ifdef GC_HAVE_SOAP rideMenu->addSeparator (); rideMenu->addAction(tr("&Upload to TrainingPeaks"), this, SLOT(uploadTP()), tr("Ctrl+U")); rideMenu->addAction(tr("Down&load from TrainingPeaks..."), this, SLOT(downloadTP()), tr("Ctrl+L")); #endif #ifdef GC_HAVE_LIBOAUTH tweetAction = new QAction(tr("Tweet Activity"), this); connect(tweetAction, SIGNAL(triggered(bool)), this, SLOT(tweetRide())); rideMenu->addAction(tweetAction); shareAction = new QAction(tr("Share (Strava, RideWithGPS, CyclingAnalytics)..."), this); connect(shareAction, SIGNAL(triggered(bool)), this, SLOT(share())); rideMenu->addAction(shareAction); #endif ttbAction = new QAction(tr("Upload to Trainingstagebuch..."), this); connect(ttbAction, SIGNAL(triggered(bool)), this, SLOT(uploadTtb())); rideMenu->addAction(ttbAction); rideMenu->addSeparator (); rideMenu->addAction(tr("&Save activity"), this, SLOT(saveRide()), tr("Ctrl+S")); rideMenu->addAction(tr("D&elete activity..."), this, SLOT(deleteRide())); rideMenu->addAction(tr("Split &activity..."), this, SLOT(splitRide())); rideMenu->addAction(tr("Merge activities..."), this, SLOT(mergeRide())); rideMenu->addSeparator (); QMenu *optionsMenu = menuBar()->addMenu(tr("&Tools")); optionsMenu->addAction(tr("&Options..."), this, SLOT(showOptions())); optionsMenu->addAction(tr("Critical Power Estimator..."), this, SLOT(showTools())); optionsMenu->addAction(tr("Air Density (Rho) Estimator..."), this, SLOT(showRhoEstimator())); optionsMenu->addSeparator(); optionsMenu->addAction(tr("Get &Withings Data..."), this, SLOT (downloadMeasures())); optionsMenu->addAction(tr("Get &Zeo Data..."), this, SLOT (downloadMeasuresFromZeo())); optionsMenu->addSeparator(); optionsMenu->addAction(tr("Create a new workout..."), this, SLOT(showWorkoutWizard())); optionsMenu->addAction(tr("Download workouts from ErgDB..."), this, SLOT(downloadErgDB())); optionsMenu->addAction(tr("Import workouts or videos..."), this, SLOT(importWorkout())); optionsMenu->addAction(tr("Scan disk for videos and workouts..."), this, SLOT(manageLibrary())); #ifdef GC_HAVE_ICAL optionsMenu->addSeparator(); optionsMenu->addAction(tr("Upload Activity to Calendar"), this, SLOT(uploadCalendar()), tr ("")); //optionsMenu->addAction(tr("Import Calendar..."), this, SLOT(importCalendar()), tr ("")); // planned for v3.1 //optionsMenu->addAction(tr("Export Calendar..."), this, SLOT(exportCalendar()), tr ("")); // planned for v3.1 optionsMenu->addAction(tr("Refresh Calendar"), this, SLOT(refreshCalendar()), tr ("")); #endif optionsMenu->addSeparator(); optionsMenu->addAction(tr("Find intervals..."), this, SLOT(addIntervals()), tr ("")); // Add all the data processors to the tools menu const DataProcessorFactory &factory = DataProcessorFactory::instance(); QMap<QString, DataProcessor*> processors = factory.getProcessors(); if (processors.count()) { optionsMenu->addSeparator(); toolMapper = new QSignalMapper(this); // maps each option QMapIterator<QString, DataProcessor*> i(processors); connect(toolMapper, SIGNAL(mapped(const QString &)), this, SLOT(manualProcess(const QString &))); i.toFront(); while (i.hasNext()) { i.next(); // The localized processor name is shown in menu QAction *action = new QAction(QString("%1...").arg(i.value()->name()), this); optionsMenu->addAction(action); connect(action, SIGNAL(triggered()), toolMapper, SLOT(map())); toolMapper->setMapping(action, i.key()); } }
VideoWindow::VideoWindow(Context *context, const QDir &home) : GcWindow(context), home(home), context(context), m_MediaChanged(false) { setControls(NULL); setInstanceName("Video Window"); setProperty("color", Qt::black); QHBoxLayout *layout = new QHBoxLayout(); setLayout(layout); // config paramaters to libvlc const char * const vlc_args[] = { "-I", "dummy", /* Don't use any interface */ "--ignore-config", /* Don't use VLC's config */ "--disable-screensaver", /* disable screensaver during playback */ #ifdef Q_OS_LINUX "--no-xlib", // avoid xlib thread error messages #endif "--verbose=-1", // -1 = no output at all "--quiet" }; /* create an exception handler */ //libvlc_exception_init(&exceptions); //vlc_exceptions(&exceptions); /* Load the VLC engine */ inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args); //vlc_exceptions(&exceptions); /* Create a new item */ m = NULL; //vlc_exceptions(&exceptions); /* Create a media player playing environement */ mp = libvlc_media_player_new (inst); //vlc_exceptions(&exceptions); //vlc_exceptions(&exceptions); /* This is a non working code that show how to hooks into a window, * if we have a window around */ #ifdef Q_OS_LINUX x11Container = new QX11EmbedContainer(this); layout->addWidget(x11Container); libvlc_media_player_set_xwindow (mp, x11Container->winId()); #endif #ifdef WIN32 container = new QWidget(this); layout->addWidget(container); libvlc_media_player_set_hwnd (mp, container->winId()); #endif connect(context, SIGNAL(stop()), this, SLOT(stopPlayback())); connect(context, SIGNAL(start()), this, SLOT(startPlayback())); connect(context, SIGNAL(pause()), this, SLOT(pausePlayback())); connect(context, SIGNAL(seek(long)), this, SLOT(seekPlayback(long))); connect(context, SIGNAL(unpause()), this, SLOT(resumePlayback())); connect(context, SIGNAL(mediaSelected(QString)), this, SLOT(mediaSelected(QString))); }
HomeWindow::HomeWindow(MainWindow *mainWindow, QString name, QString /* windowtitle */) : GcWindow(mainWindow), mainWindow(mainWindow), name(name), active(false), clicked(NULL), dropPending(false), chartCursor(-2), loaded(false) { setInstanceName("Home Window"); // setup control area QWidget *cw = new QWidget(this); cw->setContentsMargins(0,0,0,0); QVBoxLayout *cl = new QVBoxLayout(cw); cl->setSpacing(0); cl->setContentsMargins(0,0,0,0); QLabel *titleLabel = new QLabel("Title", this); QHBoxLayout *hl = new QHBoxLayout; hl->setSpacing(5); hl->setContentsMargins(0,0,0,0); titleEdit = new QLineEdit(this); titleEdit->setEnabled(false); controlStack = new QStackedWidget(this); controlStack->setContentsMargins(0,0,0,0); hl->addWidget(titleLabel); hl->addWidget(titleEdit); cl->addLayout(hl); cl->addSpacing(15); cl->addWidget(controlStack); setControls(cw); setProperty("isManager", true); setAcceptDrops(true); QVBoxLayout *layout = new QVBoxLayout(this); QFont bigandbold; bigandbold.setPointSize(bigandbold.pointSize() + 2); bigandbold.setWeight(QFont::Bold); QHBoxLayout *titleBar = new QHBoxLayout; QLabel *space = new QLabel("", this); space->setFixedHeight(20); titleBar->addWidget(space); style = new QStackedWidget(this); style->setAutoFillBackground(false); layout->setSpacing(0); layout->setContentsMargins(0,0,0,0); layout->addWidget(style); QPalette palette; palette.setBrush(backgroundRole(), QColor("#B3B4B6")); setAutoFillBackground(false); // each style has its own container widget QWidget *tabArea = new QWidget(this); tabArea->setContentsMargins(20,20,20,20); QVBoxLayout *tabLayout = new QVBoxLayout(tabArea); tabLayout->setContentsMargins(0,0,0,0); tabLayout->setSpacing(0); tabbed = new QTabWidget(this); #ifdef Q_OS_MAC tabbed->setAttribute(Qt::WA_MacShowFocusRect, 0); #endif tabbed->setContentsMargins(0,0,0,0); tabbed->setTabsClosable(false); tabbed->setPalette(palette); tabbed->setDocumentMode(false); tabbed->setMovable(true); tabbed->setElideMode(Qt::ElideNone); tabbed->setUsesScrollButtons(true); QTabBar *tb = tabbed->findChild<QTabBar*>(QLatin1String("qt_tabwidget_tabbar")); tb->setShape(QTabBar::RoundedSouth); tb->setDrawBase(false); tabbed->setStyleSheet("QTabWidget::tab-bar { alignment: center; }" "QTabWidget::pane { top: 20px; }"); tabLayout->addWidget(tabbed); style->addWidget(tabArea); // tiled tileWidget = new QWidget(this); tileWidget->setAutoFillBackground(false); tileWidget->setPalette(palette); tileWidget->setContentsMargins(0,0,0,0); tileGrid = new QGridLayout(tileWidget); tileGrid->setSpacing(0); tileArea = new QScrollArea(this); tileArea->setAutoFillBackground(false); tileArea->setPalette(palette); tileArea->setWidgetResizable(true); tileArea->setWidget(tileWidget); tileArea->setFrameStyle(QFrame::NoFrame); tileArea->setContentsMargins(0,0,0,0); style->addWidget(tileArea); winWidget = new QWidget(this); winWidget->setAutoFillBackground(false); winWidget->setContentsMargins(0,0,0,0); winWidget->setPalette(palette); winFlow = new GcWindowLayout(winWidget, 0, tileSpacing, tileSpacing); winFlow->setContentsMargins(tileMargin,tileMargin,tileMargin,tileMargin); winArea = new QScrollArea(this); winArea->setAutoFillBackground(false); winArea->setPalette(palette); winArea->setWidgetResizable(true); winArea->setWidget(winWidget); winArea->setFrameStyle(QFrame::NoFrame); winArea->setContentsMargins(0,0,0,0); style->addWidget(winArea); winWidget->installEventFilter(this); // to draw cursor winWidget->setMouseTracking(true); // to draw cursor // enable right click to add a chart winArea->setContextMenuPolicy(Qt::CustomContextMenu); tabArea->setContextMenuPolicy(Qt::CustomContextMenu); connect(winArea,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(rightClick(const QPoint &))); connect(tabArea,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(rightClick(const QPoint &))); currentStyle=-1; styleChanged(2); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); connect(this, SIGNAL(dateRangeChanged(DateRange)), this, SLOT(dateRangeChanged(DateRange))); connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(tabbed, SIGNAL(currentChanged(int)), this, SLOT(tabSelected(int))); connect(tabbed, SIGNAL(tabCloseRequested(int)), this, SLOT(removeChart(int))); connect(tb, SIGNAL(tabMoved(int,int)), this, SLOT(tabMoved(int,int))); connect(titleEdit, SIGNAL(textChanged(const QString&)), SLOT(titleChanged())); installEventFilter(this); application->installEventFilter(this); }
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())); }
AerolabWindow::AerolabWindow(MainWindow *mainWindow) : GcWindow(mainWindow), mainWindow(mainWindow) { setInstanceName("Aerolab Window"); setControls(NULL); // Aerolab tab layout: QVBoxLayout *vLayout = new QVBoxLayout; QHBoxLayout *cLayout = new QHBoxLayout; // Plot: aerolab = new Aerolab(this, mainWindow); // Left controls layout: QVBoxLayout *leftControls = new QVBoxLayout; QFontMetrics metrics(QApplication::font()); int labelWidth1 = metrics.width("Crr") + 10; // Crr: QHBoxLayout *crrLayout = new QHBoxLayout; QLabel *crrLabel = new QLabel(tr("Crr"), this); crrLabel->setFixedWidth(labelWidth1); crrLineEdit = new QLineEdit(); crrLineEdit->setFixedWidth(75); crrLineEdit->setText(QString("%1").arg(aerolab->getCrr()) ); /*crrQLCDNumber = new QLCDNumber(7); crrQLCDNumber->setMode(QLCDNumber::Dec); crrQLCDNumber->setSmallDecimalPoint(false); crrQLCDNumber->setSegmentStyle(QLCDNumber::Flat); crrQLCDNumber->display(QString("%1").arg(aerolab->getCrr()) );*/ crrSlider = new QSlider(Qt::Horizontal); crrSlider->setTickPosition(QSlider::TicksBelow); crrSlider->setTickInterval(1000); crrSlider->setMinimum(1000); crrSlider->setMaximum(10000); crrSlider->setValue(aerolab->intCrr()); crrLayout->addWidget( crrLabel ); crrLayout->addWidget( crrLineEdit ); //crrLayout->addWidget( crrQLCDNumber ); crrLayout->addWidget( crrSlider ); // CdA: QHBoxLayout *cdaLayout = new QHBoxLayout; QLabel *cdaLabel = new QLabel(tr("CdA"), this); cdaLabel->setFixedWidth(labelWidth1); cdaLineEdit = new QLineEdit(); cdaLineEdit->setFixedWidth(75); cdaLineEdit->setText(QString("%1").arg(aerolab->getCda()) ); /*cdaQLCDNumber = new QLCDNumber(7); cdaQLCDNumber->setMode(QLCDNumber::Dec); cdaQLCDNumber->setSmallDecimalPoint(false); cdaQLCDNumber->setSegmentStyle(QLCDNumber::Flat); cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()) );*/ cdaSlider = new QSlider(Qt::Horizontal); cdaSlider->setTickPosition(QSlider::TicksBelow); cdaSlider->setTickInterval(100); cdaSlider->setMinimum(1); cdaSlider->setMaximum(6000); cdaSlider->setValue(aerolab->intCda()); cdaLayout->addWidget( cdaLabel ); //cdaLayout->addWidget( cdaQLCDNumber ); cdaLayout->addWidget( cdaLineEdit ); cdaLayout->addWidget( cdaSlider ); // Eta: QHBoxLayout *etaLayout = new QHBoxLayout; QLabel *etaLabel = new QLabel(tr("Eta"), this); etaLabel->setFixedWidth(labelWidth1); etaLineEdit = new QLineEdit(); etaLineEdit->setFixedWidth(75); etaLineEdit->setText(QString("%1").arg(aerolab->getEta()) ); /*etaQLCDNumber = new QLCDNumber(7); etaQLCDNumber->setMode(QLCDNumber::Dec); etaQLCDNumber->setSmallDecimalPoint(false); etaQLCDNumber->setSegmentStyle(QLCDNumber::Flat); etaQLCDNumber->display(QString("%1").arg(aerolab->getEta()) );*/ etaSlider = new QSlider(Qt::Horizontal); etaSlider->setTickPosition(QSlider::TicksBelow); etaSlider->setTickInterval(1000); etaSlider->setMinimum(8000); etaSlider->setMaximum(12000); etaSlider->setValue(aerolab->intEta()); etaLayout->addWidget( etaLabel ); etaLayout->addWidget( etaLineEdit ); //etaLayout->addWidget( etaQLCDNumber ); etaLayout->addWidget( etaSlider ); // Add to leftControls: leftControls->addLayout( crrLayout ); leftControls->addLayout( cdaLayout ); leftControls->addLayout( etaLayout ); // Right controls layout: QVBoxLayout *rightControls = new QVBoxLayout; int labelWidth2 = metrics.width("Total Mass (kg)") + 10; // Total mass: QHBoxLayout *mLayout = new QHBoxLayout; QLabel *mLabel = new QLabel(tr("Total Mass (kg)"), this); mLabel->setFixedWidth(labelWidth2); mLineEdit = new QLineEdit(); mLineEdit->setFixedWidth(70); mLineEdit->setText(QString("%1").arg(aerolab->getTotalMass()) ); /*mQLCDNumber = new QLCDNumber(7); mQLCDNumber->setMode(QLCDNumber::Dec); mQLCDNumber->setSmallDecimalPoint(false); mQLCDNumber->setSegmentStyle(QLCDNumber::Flat); mQLCDNumber->display(QString("%1").arg(aerolab->getTotalMass()) );*/ mSlider = new QSlider(Qt::Horizontal); mSlider->setTickPosition(QSlider::TicksBelow); mSlider->setTickInterval(1000); mSlider->setMinimum(3500); mSlider->setMaximum(15000); mSlider->setValue(aerolab->intTotalMass()); mLayout->addWidget( mLabel ); mLayout->addWidget( mLineEdit ); //mLayout->addWidget( mQLCDNumber ); mLayout->addWidget( mSlider ); // Rho: QHBoxLayout *rhoLayout = new QHBoxLayout; QLabel *rhoLabel = new QLabel(tr("Rho (kg/m^3)"), this); rhoLabel->setFixedWidth(labelWidth2); rhoLineEdit = new QLineEdit(); rhoLineEdit->setFixedWidth(70); rhoLineEdit->setText(QString("%1").arg(aerolab->getRho()) ); /*rhoQLCDNumber = new QLCDNumber(7); rhoQLCDNumber->setMode(QLCDNumber::Dec); rhoQLCDNumber->setSmallDecimalPoint(false); rhoQLCDNumber->setSegmentStyle(QLCDNumber::Flat); rhoQLCDNumber->display(QString("%1").arg(aerolab->getRho()) );*/ rhoSlider = new QSlider(Qt::Horizontal); rhoSlider->setTickPosition(QSlider::TicksBelow); rhoSlider->setTickInterval(1000); rhoSlider->setMinimum(9000); rhoSlider->setMaximum(14000); rhoSlider->setValue(aerolab->intRho()); rhoLayout->addWidget( rhoLabel ); rhoLayout->addWidget( rhoLineEdit ); //rhoLayout->addWidget( rhoQLCDNumber ); rhoLayout->addWidget( rhoSlider ); // Elevation offset: QHBoxLayout *eoffsetLayout = new QHBoxLayout; QLabel *eoffsetLabel = new QLabel(tr("Eoffset (m)"), this); eoffsetLabel->setFixedWidth(labelWidth2); eoffsetLineEdit = new QLineEdit(); eoffsetLineEdit->setFixedWidth(70); eoffsetLineEdit->setText(QString("%1").arg(aerolab->getEoffset()) ); /*eoffsetQLCDNumber = new QLCDNumber(7); eoffsetQLCDNumber->setMode(QLCDNumber::Dec); eoffsetQLCDNumber->setSmallDecimalPoint(false); eoffsetQLCDNumber->setSegmentStyle(QLCDNumber::Flat); eoffsetQLCDNumber->display(QString("%1").arg(aerolab->getEoffset()) );*/ eoffsetSlider = new QSlider(Qt::Horizontal); eoffsetSlider->setTickPosition(QSlider::TicksBelow); eoffsetSlider->setTickInterval(20000); eoffsetSlider->setMinimum(-30000); eoffsetSlider->setMaximum(250000); eoffsetSlider->setValue(aerolab->intEoffset()); eoffsetLayout->addWidget( eoffsetLabel ); eoffsetLayout->addWidget( eoffsetLineEdit ); //eoffsetLayout->addWidget( eoffsetQLCDNumber ); eoffsetLayout->addWidget( eoffsetSlider ); QCheckBox *eoffsetAuto = new QCheckBox(tr("eoffset auto"), this); eoffsetAuto->setCheckState(Qt::Checked); eoffsetLayout->addWidget(eoffsetAuto); QHBoxLayout *smoothLayout = new QHBoxLayout; QComboBox *comboDistance = new QComboBox(); comboDistance->addItem(tr("X Axis Shows Time")); comboDistance->addItem(tr("X Axis Shows Distance")); comboDistance->setCurrentIndex(1); smoothLayout->addWidget(comboDistance); QPushButton *btnEstCdACrr = new QPushButton(tr("&Estimate CdA and Crr"), this); smoothLayout->addWidget(btnEstCdACrr); // Add to leftControls: rightControls->addLayout( mLayout ); rightControls->addLayout( rhoLayout ); rightControls->addLayout( eoffsetLayout ); rightControls->addLayout( smoothLayout ); // Assemble controls layout: cLayout->addLayout(leftControls); cLayout->addLayout(rightControls); // Zoomer: allZoomer = new QwtPlotZoomer(aerolab->canvas()); allZoomer->setRubberBand(QwtPicker::RectRubberBand); allZoomer->setTrackerMode(QwtPicker::AlwaysOff); allZoomer->setEnabled(true); allZoomer->setMousePattern( QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier ); allZoomer->setMousePattern( QwtEventPattern::MouseSelect3, Qt::RightButton ); // SIGNALs to SLOTs: //connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected())); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); connect(crrSlider, SIGNAL(valueChanged(int)),this, SLOT(setCrrFromSlider())); connect(crrLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setCrrFromText(const QString))); connect(cdaSlider, SIGNAL(valueChanged(int)), this, SLOT(setCdaFromSlider())); connect(cdaLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setCdaFromText(const QString))); connect(mSlider, SIGNAL(valueChanged(int)),this, SLOT(setTotalMassFromSlider())); connect(mLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setTotalMassFromText(const QString))); connect(rhoSlider, SIGNAL(valueChanged(int)), this, SLOT(setRhoFromSlider())); connect(rhoLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setRhoFromText(const QString))); connect(etaSlider, SIGNAL(valueChanged(int)), this, SLOT(setEtaFromSlider())); connect(etaLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setEtaFromText(const QString))); connect(eoffsetSlider, SIGNAL(valueChanged(int)), this, SLOT(setEoffsetFromSlider())); connect(eoffsetLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setEoffsetFromText(const QString))); connect(eoffsetAuto, SIGNAL(stateChanged(int)), this, SLOT(setAutoEoffset(int))); connect(comboDistance, SIGNAL(currentIndexChanged(int)), this, SLOT(setByDistance(int))); connect(btnEstCdACrr, SIGNAL(clicked()), this, SLOT(doEstCdACrr())); connect(mainWindow, SIGNAL(configChanged()), aerolab, SLOT(configChanged())); connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(mainWindow, SIGNAL(intervalSelected() ), this, SLOT(intervalSelected())); connect(mainWindow, SIGNAL(intervalZoom(IntervalItem*) ), this, SLOT(zoomInterval(IntervalItem*))); connect(allZoomer, SIGNAL( zoomed(const QRectF) ), this, SLOT(zoomChanged())); // Build the tab layout: vLayout->addWidget(aerolab); vLayout->addLayout(cLayout); setLayout(vLayout); // tooltip on hover over point //************************************ aerolab->tooltip = new LTMToolTip( QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::VLineRubberBand, QwtPicker::AlwaysOn, aerolab->canvas(), "" ); aerolab->tooltip->setRubberBand( QwtPicker::VLineRubberBand ); aerolab->tooltip->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier ); aerolab->tooltip->setTrackerPen( QColor( Qt::black ) ); QColor inv( Qt::white ); inv.setAlpha( 0 ); aerolab->tooltip->setRubberBandPen( inv ); aerolab->tooltip->setEnabled( true ); aerolab->_canvasPicker = new LTMCanvasPicker( aerolab ); connect( aerolab->_canvasPicker, SIGNAL( pointHover( QwtPlotCurve*, int ) ), aerolab, SLOT ( pointHover( QwtPlotCurve*, int ) ) ); configChanged(); // pickup colors etc }
ModelWindow::ModelWindow(MainWindow *parent, const QDir &home) : GcWindow(parent), home(home), main(parent), ride(NULL), current(NULL) { setInstanceName("3D Window"); QWidget *c = new QWidget; QFormLayout *cl = new QFormLayout(c); setControls(c); // hidden text when plot invalid nodata = new QLabel(tr("No data or bin size too large."), this); nodata->hide(); // the plot widget QHBoxLayout *mainLayout = new QHBoxLayout; modelPlot= new ModelPlot(main, NULL); zpane = new QSlider(Qt::Vertical); zpane->setTickInterval(1); zpane->setMinimum(0); zpane->setMaximum(100); zpane->setValue(0); mainLayout->addWidget(zpane); mainLayout->addWidget(modelPlot); mainLayout->addWidget(nodata); setLayout(mainLayout); // preset Values presetLabel = new QLabel(tr("Analyse"), this); presetValues = new QComboBox; fillPresets(presetValues); presetValues->setCurrentIndex(1); cl->addRow(presetLabel, presetValues); // labels xLabel = new QLabel(tr("X-Axis:"), this); xSelector = new QComboBox; addStandardChannels(xSelector); xSelector->setCurrentIndex(0); // power cl->addRow(xLabel, xSelector); yLabel = new QLabel(tr("Y-Axis:"), this); ySelector = new QComboBox; addStandardChannels(ySelector); ySelector->setCurrentIndex(1); // cadence cl->addRow(yLabel, ySelector); zLabel = new QLabel(tr("Z-Axis:"), this); zSelector = new QComboBox; addStandardChannels(zSelector); zSelector->addItem(tr("Time at X&Y"), MODEL_XYTIME); zSelector->setCurrentIndex(12); // time at xy cl->addRow(zLabel, zSelector); colorLabel = new QLabel(tr("Color:"), this); colorSelector = new QComboBox; addStandardChannels(colorSelector); colorSelector->addItem(tr("Power Zone"), MODEL_POWERZONE); colorSelector->addItem(tr("Time at X&Y"), MODEL_XYTIME); colorSelector->setCurrentIndex(12); // power zone cl->addRow(colorLabel, colorSelector); binLabel = new QLabel(tr("Bin Width:"), this); binWidthLineEdit = new QLineEdit(this); binWidthLineEdit->setFixedWidth(30); binWidthLineEdit->setText("5"); cl->addRow(binLabel, binWidthLineEdit); binWidthSlider = new QSlider(Qt::Horizontal); binWidthSlider->setTickPosition(QSlider::TicksBelow); binWidthSlider->setTickInterval(1); binWidthSlider->setMinimum(3); binWidthSlider->setMaximum(100); binWidthSlider->setValue(5); cl->addRow(binWidthSlider); // selectors styleSelector = new QComboBox; styleSelector->addItem(tr("Bar")); styleSelector->addItem(tr("Grid")); styleSelector->addItem(tr("Surface")); styleSelector->addItem(tr("Dots")); styleSelector->setCurrentIndex(0); cl->addRow(styleSelector); 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); legend = new QCheckBox(tr("Legend")); legend->setChecked(true); cl->addRow(legend); resetView = new QPushButton(tr("Reset View")); cl->addRow(resetView); // 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(presetValues, SIGNAL(currentIndexChanged(int)), this, SLOT(applyPreset(int))); connect(xSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setDirty())); connect(ySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setDirty())); connect(zSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setDirty())); connect(colorSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setDirty())); 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(styleSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(styleSelected(int))); connect(ignore, SIGNAL(stateChanged(int)), this, SLOT(setDirty())); connect(binWidthSlider, SIGNAL(valueChanged(int)), this, SLOT(setBinWidthFromSlider())); connect(binWidthLineEdit, SIGNAL(editingFinished()), this, SLOT(setBinWidthFromLineEdit())); connect(resetView, SIGNAL(clicked()), this, SLOT(resetViewPoint())); connect(zpane, SIGNAL(valueChanged(int)), this, SLOT(setZPane(int))); }
RealtimePlot::RealtimePlot() : pwrCurve(NULL), showPowerState(Qt::Checked), showPow30sState(Qt::Checked), showHrState(Qt::Checked), showSpeedState(Qt::Checked), showCadState(Qt::Checked), showAltState(Qt::Checked), smooth(0) { setInstanceName("Realtime Plot"); //insertLegend(new QwtLegend(), QwtPlot::BottomLegend); pwr30Data = new Realtime30PwrData; pwrData = new RealtimePwrData; altPwrData = new RealtimePwrData; spdData = new RealtimeSpdData; hrData = new RealtimeHrData; cadData = new RealtimeCadData; // Setup the axis (of evil :-) setAxisTitle(yLeft, "Watts"); setAxisTitle(yRight, "Cadence / HR"); setAxisTitle(yRight2, "Speed"); setAxisTitle(xBottom, "Seconds Ago"); setAxisMaxMinor(xBottom, 0); setAxisMaxMinor(yLeft, 0); setAxisMaxMinor(yLeft2, 0); setAxisMaxMinor(yRight, 0); setAxisMaxMinor(yRight2, 0); QPalette pal; setAxisScale(yLeft, 0, 500); // watts pal.setColor(QPalette::WindowText, GColor(CPOWER)); pal.setColor(QPalette::Text, GColor(CPOWER)); axisWidget(QwtPlot::yLeft)->setPalette(pal); axisWidget(QwtPlot::yLeft)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(yRight, 0, 230); // cadence / hr pal.setColor(QPalette::WindowText, GColor(CHEARTRATE)); pal.setColor(QPalette::Text, GColor(CHEARTRATE)); axisWidget(QwtPlot::yRight)->setPalette(pal); axisWidget(QwtPlot::yRight)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(xBottom, MAXSAMPLES, 0, 15); // time ago pal.setColor(QPalette::WindowText, GColor(CPLOTMARKER)); pal.setColor(QPalette::Text, GColor(CPLOTMARKER)); axisWidget(QwtPlot::xBottom)->setPalette(pal); axisWidget(QwtPlot::xBottom)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(yRight2, 0, 60); // speed km/h - 60kmh on a turbo is good going! pal.setColor(QPalette::WindowText, GColor(CSPEED)); pal.setColor(QPalette::Text, GColor(CSPEED)); axisWidget(QwtPlot::yRight2)->setPalette(pal); axisWidget(QwtPlot::yRight2)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisLabelRotation(yRight2,90); setAxisLabelAlignment(yRight2,Qt::AlignVCenter); enableAxis(xBottom, false); // very little value and some cpu overhead enableAxis(yLeft, true); enableAxis(yRight, true); enableAxis(yRight2, true); // 30s Power curve pwr30Curve = new QwtPlotCurve("30s Power"); pwr30Curve->setRenderHint(QwtPlotItem::RenderAntialiased); // too cpu intensive pwr30Curve->attach(this); pwr30Curve->setYAxis(QwtPlot::yLeft); // Power curve pwrCurve = new QwtPlotCurve("Power"); //pwrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); pwrCurve->setData(pwrData); pwrCurve->attach(this); pwrCurve->setYAxis(QwtPlot::yLeft); altPwrCurve = new QwtPlotCurve("Alt Power"); //pwrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); altPwrCurve->setData(altPwrData); altPwrCurve->attach(this); altPwrCurve->setYAxis(QwtPlot::yLeft); // HR hrCurve = new QwtPlotCurve("HeartRate"); //hrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); hrCurve->setData(hrData); hrCurve->attach(this); hrCurve->setYAxis(QwtPlot::yRight); // Cadence cadCurve = new QwtPlotCurve("Cadence"); //cadCurve->setRenderHint(QwtPlotItem::RenderAntialiased); cadCurve->setData(cadData); cadCurve->attach(this); cadCurve->setYAxis(QwtPlot::yRight); // Speed spdCurve = new QwtPlotCurve("Speed"); //spdCurve->setRenderHint(QwtPlotItem::RenderAntialiased); spdCurve->setData(spdData); spdCurve->attach(this); spdCurve->setYAxis(QwtPlot::yRight2); // Load // lodCurve = new QwtPlotCurve("Load"); // //lodCurve->setRenderHint(QwtPlotItem::RenderAntialiased); // QPen lodpen = QPen(QColor(128,128,128)); // lodpen.setWidth(2.0); // lodCurve->setPen(lodpen); // QColor brush_color = QColor(124, 91, 31); // brush_color.setAlpha(64); // lodCurve->setBrush(brush_color); // fill below the line // lodCurve->setData(lodData); // lodCurve->attach(this); // lodCurve->setYAxis(QwtPlot::yLeft); canvas()->setFrameStyle(QFrame::NoFrame); configChanged(); // set colors }
HrPwWindow::HrPwWindow(MainWindow *mainWindow) : GcWindow(mainWindow), mainWindow(mainWindow), current(NULL) { setControls(NULL); setInstanceName("HrPw"); QVBoxLayout *vlayout = new QVBoxLayout; setLayout(vlayout); // just the hr and power as a plot smallPlot = new SmallPlot(this); smallPlot->setMaximumHeight(200); smallPlot->setMinimumHeight(100); vlayout->addWidget(smallPlot); vlayout->setStretch(0, 20); // main plot hrPwPlot = new HrPwPlot(mainWindow, this); // tooltip on hover over point hrPwPlot->tooltip = new LTMToolTip(QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::VLineRubberBand, QwtPicker::AlwaysOn, hrPwPlot->canvas(), ""); hrPwPlot->tooltip->setRubberBand(QwtPicker::VLineRubberBand); hrPwPlot->tooltip->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier); hrPwPlot->tooltip->setTrackerPen(QColor(Qt::black)); hrPwPlot->_canvasPicker = new LTMCanvasPicker(hrPwPlot); // setup the plot QColor inv(Qt::white); inv.setAlpha(0); hrPwPlot->tooltip->setRubberBandPen(inv); hrPwPlot->tooltip->setEnabled(true); vlayout->addWidget(hrPwPlot); vlayout->setStretch(1, 100); // the controls QWidget *c = new QWidget(this); setControls(c); QFormLayout *cl = new QFormLayout(c); QLabel *delayLabel = new QLabel(tr("HR delay"), this); delayEdit = new QLineEdit(this); delayEdit->setFixedWidth(30); cl->addRow(delayLabel, delayEdit); delaySlider = new QSlider(Qt::Horizontal); delaySlider->setTickPosition(QSlider::TicksBelow); delaySlider->setTickInterval(1); delaySlider->setMinimum(1); delaySlider->setMaximum(100); delayEdit->setValidator(new QIntValidator(delaySlider->minimum(), delaySlider->maximum(), delayEdit)); cl->addRow(delaySlider); smooth = 240; QLabel *smoothLabel = new QLabel(tr("Smooth"), this); smoothEdit = new QLineEdit(this); smoothEdit->setFixedWidth(30); smoothEdit->setText(QString("%1").arg(smooth)); cl->addRow(smoothLabel, smoothEdit); smoothSlider = new QSlider(Qt::Horizontal); smoothSlider->setTickPosition(QSlider::TicksBelow); smoothSlider->setTickInterval(10); smoothSlider->setMinimum(0); smoothSlider->setMaximum(500); smoothSlider->setValue(smooth); smoothEdit->setValidator(new QIntValidator(smoothSlider->minimum(), smoothSlider->maximum(), smoothEdit)); cl->addRow(smoothSlider); joinlineCheckBox = new QCheckBox(this);; joinlineCheckBox->setText(tr("Join points")); joinlineCheckBox->setCheckState(Qt::Unchecked); setJoinLineFromCheckBox(); cl->addRow(joinlineCheckBox); shadeZones = new QCheckBox(this);; shadeZones->setText(tr("Shade Zones")); shadeZones->setCheckState(Qt::Checked); setShadeZones(); cl->addRow(shadeZones); // connect them all up now initialised connect(hrPwPlot->_canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), hrPwPlot, SLOT(pointHover(QwtPlotCurve*, int))); connect(joinlineCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setJoinLineFromCheckBox())); connect(shadeZones, SIGNAL(stateChanged(int)), this, SLOT(setShadeZones())); connect(smoothEdit, SIGNAL(editingFinished()), this, SLOT(setSmoothingFromLineEdit())); connect(smoothSlider, SIGNAL(valueChanged(int)), this, SLOT(setSmoothingFromSlider())); connect(delayEdit, SIGNAL(editingFinished()), this, SLOT(setDelayFromLineEdit())); connect(delaySlider, SIGNAL(valueChanged(int)), this, SLOT(setDelayFromSlider())); //connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); }
DiaryWindow::DiaryWindow(MainWindow *mainWindow) : GcWindow(mainWindow), mainWindow(mainWindow), active(false) { setInstanceName("Diary Window"); setControls(NULL); // get config fieldDefinitions = mainWindow->rideMetadata()->getFields(); QVBoxLayout *vlayout = new QVBoxLayout(this); // controls QHBoxLayout *controls = new QHBoxLayout; QFont bold; bold.setPointSize(14); bold.setWeight(QFont::Bold); title = new QLabel("", this); title->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); title->setFont(bold); QIcon prevIcon(":images/toolbar/back_alt.png"); QIcon nextIcon(":images/toolbar/forward_alt.png"); next = new QPushButton(nextIcon, "", this); prev = new QPushButton(prevIcon, "", this); #ifdef Q_OS_MAC next->setFlat(true); prev->setFlat(true); #endif #if 0 // viewMode - monthly or weekly viewMode = new QComboBox; viewMode->addItem("View Month"); viewMode->addItem("View Week"); // we can add more later... viewMode->addItem("View Ride"); // we can add more later... viewMode->setFixedWidth(120); viewMode->setCurrentIndex(appsettings->cvalue(mainWindow->cyclist, GC_DIARY_VIEW, "1").toInt()); #endif controls->addWidget(prev); controls->addWidget(next); controls->addStretch(); controls->addWidget(title, Qt::AlignCenter | Qt::AlignVCenter); controls->addStretch(); #if 0 controls->addWidget(viewMode); #endif vlayout->addLayout(controls); // monthly view via QCalendarWidget calendarModel = new GcCalendarModel(this, &fieldDefinitions, mainWindow); calendarModel->setSourceModel(mainWindow->listView->sqlModel); monthlyView = new QTableView(this); monthlyView->setItemDelegate(new GcCalendarDelegate); monthlyView->setModel(calendarModel); monthlyView->horizontalHeader()->setResizeMode(QHeaderView::Stretch); monthlyView->verticalHeader()->setResizeMode(QHeaderView::Stretch); monthlyView->verticalHeader()->hide(); monthlyView->viewport()->installEventFilter(this); monthlyView->setGridStyle(Qt::DotLine); monthlyView->setFrameStyle(QFrame::NoFrame); // weekly view via QxtScheduleView weeklyView = new QxtScheduleView; weeklyViewProxy = new QxtScheduleViewProxy(this, &fieldDefinitions, mainWindow); weeklyViewProxy->setSourceModel(mainWindow->listView->sqlModel); weeklyView->setCurrentZoomDepth (30, Qxt::Minute); weeklyView->setDateRange(QDate(2010,9,2), QDate(2010,9,8)); weeklyView->setModel(weeklyViewProxy); RideSummaryWindow *rideSummary = new RideSummaryWindow(mainWindow); allViews = new QStackedWidget(this); allViews->addWidget(monthlyView); allViews->addWidget(weeklyView); allViews->addWidget(rideSummary); //allViews->setCurrentIndex(viewMode->currentIndex()); allViews->setCurrentIndex(0); vlayout->addWidget(allViews); //connect(viewMode, SIGNAL(currentIndexChanged(int)), allViews, SLOT(setCurrentIndex(int))); //connect(viewMode, SIGNAL(currentIndexChanged(int)), this, SLOT(setDefaultView(int))); //connect(viewMode, SIGNAL(currentIndexChanged(int)), this, SLOT(rideSelected())); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); //connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected())); connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(weeklyView, SIGNAL(indexSelected(QModelIndex)), this, SLOT(weeklySelected(QModelIndex))); connect(next, SIGNAL(clicked()), this, SLOT(nextClicked())); connect(prev, SIGNAL(clicked()), this, SLOT(prevClicked())); }
PfPvPlot::PfPvPlot(MainWindow *mainWindow) : rideItem (NULL), mainWindow(mainWindow), cp_ (0), cad_ (85), cl_ (0.175), shade_zones(true) { setInstanceName("PfPv Plot"); setCanvasBackground(Qt::white); canvas()->setFrameStyle(QFrame::NoFrame); setAxisTitle(yLeft, tr("Average Effective Pedal Force (N)")); setAxisScale(yLeft, 0, 600); setAxisTitle(xBottom, tr("Circumferential Pedal Velocity (m/s)")); setAxisScale(xBottom, 0, 3); setAxisMaxMinor(yLeft, 0); setAxisMaxMinor(xBottom, 0); QwtScaleDraw *sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(xBottom, sd); sd = new QwtScaleDraw; sd->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScaleDraw(yLeft, sd); mX = new QwtPlotMarker(); mX->setLineStyle(QwtPlotMarker::VLine); mX->attach(this); mY = new QwtPlotMarker(); mY->setLineStyle(QwtPlotMarker::HLine); mY->attach(this); cpCurve = new QwtPlotCurve(); cpCurve->setRenderHint(QwtPlotItem::RenderAntialiased); cpCurve->attach(this); curve = new QwtPlotCurve(); curve->attach(this); cl_ = appsettings->value(this, GC_CRANKLENGTH).toDouble() / 1000.0; // markup timeInQuadrant tiqMarker[0] = new QwtPlotMarker(); tiqMarker[0]->attach(this); tiqMarker[0]->setXValue(2.9); tiqMarker[0]->setYValue(580); tiqMarker[1] = new QwtPlotMarker(); tiqMarker[1]->attach(this); tiqMarker[1]->setXValue(0.1); tiqMarker[1]->setYValue(580); tiqMarker[2] = new QwtPlotMarker(); tiqMarker[2]->attach(this); tiqMarker[2]->setXValue(0.1); tiqMarker[2]->setYValue(10); tiqMarker[3] = new QwtPlotMarker(); tiqMarker[3]->attach(this); tiqMarker[3]->setXValue(2.9); tiqMarker[3]->setYValue(10); merge_intervals = false; frame_intervals = true; // only default on first time through, after this the user may have adjusted if (appsettings->value(this, GC_SHADEZONES, true).toBool()==false) shade_zones = false; else shade_zones = true; configChanged(); recalc(); }
DiaryWindow::DiaryWindow(Context *context) : GcWindow(context), context(context), active(false) { setInstanceName("Diary Window"); setControls(NULL); // get config fieldDefinitions = context->athlete->rideMetadata()->getFields(); QVBoxLayout *vlayout = new QVBoxLayout(this); // controls QHBoxLayout *controls = new QHBoxLayout; QFont bold; bold.setPointSize(14); bold.setWeight(QFont::Bold); title = new QLabel("", this); title->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); title->setFont(bold); QIcon prevIcon(":images/toolbar/back_alt.png"); QIcon nextIcon(":images/toolbar/forward_alt.png"); next = new QPushButton(nextIcon, "", this); prev = new QPushButton(prevIcon, "", this); #ifdef Q_OS_MAC next->setFlat(true); prev->setFlat(true); #endif controls->addWidget(prev); controls->addWidget(next); controls->addStretch(); controls->addWidget(title, Qt::AlignCenter | Qt::AlignVCenter); controls->addStretch(); vlayout->addLayout(controls); // monthly view via QCalendarWidget calendarModel = new GcCalendarModel(this, &fieldDefinitions, context); calendarModel->setSourceModel(context->athlete->sqlModel); monthlyView = new QTableView(this); monthlyView->setItemDelegate(new GcCalendarDelegate); monthlyView->setModel(calendarModel); monthlyView->horizontalHeader()->setResizeMode(QHeaderView::Stretch); monthlyView->verticalHeader()->setResizeMode(QHeaderView::Stretch); monthlyView->verticalHeader()->hide(); monthlyView->viewport()->installEventFilter(this); monthlyView->setGridStyle(Qt::DotLine); monthlyView->setFrameStyle(QFrame::NoFrame); allViews = new QStackedWidget(this); allViews->addWidget(monthlyView); allViews->setCurrentIndex(0); vlayout->addWidget(allViews); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); connect(context, SIGNAL(filterChanged()), this, SLOT(rideSelected())); connect(context, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(next, SIGNAL(clicked()), this, SLOT(nextClicked())); connect(prev, SIGNAL(clicked()), this, SLOT(prevClicked())); }