diff --git a/src/AllPlotWindow.cpp b/src/AllPlotWindow.cpp index d30a95cb9..bdf8e3eb6 100644 --- a/src/AllPlotWindow.cpp +++ b/src/AllPlotWindow.cpp @@ -405,7 +405,8 @@ AllPlotWindow::setEndSelection(double xValue, bool newInterval, QString name) // add average power to the end of the selection name name += QString("(%1 watts)").arg(round((wattsTotal && arrayLength) ? wattsTotal/arrayLength : 0)); - QTreeWidgetItem *last = new IntervalItem(ride->ride(), name, duration1, duration2, distance1, distance2); + QTreeWidgetItem *last = new IntervalItem(ride->ride(), name, duration1, duration2, distance1, distance2, + allIntervals->childCount()+1); allIntervals->addChild(last); // now update the RideFileIntervals and all the plots etc diff --git a/src/BestIntervalDialog.cpp b/src/BestIntervalDialog.cpp index dbedf415d..02ad889f5 100644 --- a/src/BestIntervalDialog.cpp +++ b/src/BestIntervalDialog.cpp @@ -283,13 +283,13 @@ BestIntervalDialog::addClicked() QString name = resultsTable->item(i,2)->text(); const RideFile *ride = mainWindow->currentRide(); + QTreeWidgetItem *allIntervals = mainWindow->mutableIntervalItems(); QTreeWidgetItem *last = new IntervalItem(ride, name, start, stop, ride->timeToDistance(start), - ride->timeToDistance(stop)); - + ride->timeToDistance(stop), + allIntervals->childCount()+1); // add - QTreeWidgetItem *allIntervals = mainWindow->mutableIntervalItems(); allIntervals->addChild(last); } } diff --git a/src/IntervalItem.cpp b/src/IntervalItem.cpp index f8421bd1e..127061fc2 100644 --- a/src/IntervalItem.cpp +++ b/src/IntervalItem.cpp @@ -19,7 +19,7 @@ #include "IntervalItem.h" #include "RideFile.h" -IntervalItem::IntervalItem(const RideFile *ride, QString name, double start, double stop, double startKM, double stopKM) : ride(ride), start(start), stop(stop), startKM(startKM), stopKM(stopKM) +IntervalItem::IntervalItem(const RideFile *ride, QString name, double start, double stop, double startKM, double stopKM, int displaySequence) : ride(ride), start(start), stop(stop), startKM(startKM), stopKM(stopKM), displaySequence(displaySequence) { setText(0, name); } diff --git a/src/IntervalItem.h b/src/IntervalItem.h index 3f53661b1..25073e6c3 100644 --- a/src/IntervalItem.h +++ b/src/IntervalItem.h @@ -29,8 +29,10 @@ class IntervalItem : public QTreeWidgetItem const RideFile *ride; double start, stop; // by Time double startKM, stopKM; // by Distance + int displaySequence; - IntervalItem(const RideFile *, QString, double, double, double, double); + IntervalItem(const RideFile *, QString, double, double, double, double, int); + void setDisplaySequence(int seq) { displaySequence = seq; } }; #endif // _GC_IntervalItem_h diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 3406d9b6a..a26aac395 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -695,7 +695,10 @@ MainWindow::addIntervalForPowerPeaksForSecs(RideFile *ride, int windowSizeSecs, double watts = j.value(); QTreeWidgetItem *peak = new IntervalItem(ride, name+tr(" (%1 watts)").arg((int) round(watts)), - secs, secs+windowSizeSecs, ride->timeToDistance(secs), ride->timeToDistance(secs+windowSizeSecs)); + secs, secs+windowSizeSecs, + ride->timeToDistance(secs), + ride->timeToDistance(secs+windowSizeSecs), + allIntervals->childCount()+1); allIntervals->addChild(peak); } } @@ -766,7 +769,8 @@ MainWindow::rideTreeWidgetSelectionChanged() intervals.at(i).start, intervals.at(i).stop, selected->timeToDistance(intervals.at(i).start), - selected->timeToDistance(intervals.at(i).stop)); + selected->timeToDistance(intervals.at(i).stop), + allIntervals->childCount()+1); allIntervals->addChild(add); } } @@ -834,14 +838,22 @@ MainWindow::showContextMenuPopup(const QPoint &pos) QAction *actRenameInt = new QAction(tr("Rename interval"), intervalWidget); QAction *actDeleteInt = new QAction(tr("Delete interval"), intervalWidget); QAction *actZoomInt = new QAction(tr("Zoom to interval"), intervalWidget); + QAction *actFrontInt = new QAction(tr("Bring to Front"), intervalWidget); + QAction *actBackInt = new QAction(tr("Send to back"), intervalWidget); connect(actRenameInt, SIGNAL(triggered(void)), this, SLOT(renameInterval(void))); connect(actDeleteInt, SIGNAL(triggered(void)), this, SLOT(deleteInterval(void))); connect(actZoomInt, SIGNAL(triggered(void)), this, SLOT(zoomInterval(void))); + connect(actFrontInt, SIGNAL(triggered(void)), this, SLOT(frontInterval(void))); + connect(actBackInt, SIGNAL(triggered(void)), this, SLOT(backInterval(void))); if (tabWidget->currentIndex() == 1) // on ride plot menu.addAction(actZoomInt); menu.addAction(actRenameInt); menu.addAction(actDeleteInt); + if (tabWidget->currentIndex() == 4 && activeInterval->isSelected()) { // on PfPv plot + menu.addAction(actFrontInt); + menu.addAction(actBackInt); + } menu.exec(intervalWidget->mapToGlobal( pos )); } } @@ -867,7 +879,17 @@ MainWindow::updateRideFileIntervals() } void -MainWindow::deleteInterval() { +MainWindow::deleteInterval() +{ + // renumber remaining + int oindex = activeInterval->displaySequence; + for (int i=0; ichildCount(); i++) { + IntervalItem *it = (IntervalItem *)allIntervals->child(i); + int ds = it->displaySequence; + if (ds > oindex) it->setDisplaySequence(ds-1); + } + + // now delete! int index = allIntervals->indexOfChild(activeInterval); delete allIntervals->takeChild(index); updateRideFileIntervals(); // will emit intervalChanged() signal @@ -892,6 +914,39 @@ MainWindow::zoomInterval() { allPlotWindow->zoomInterval(activeInterval); } +void +MainWindow::frontInterval() +{ + int oindex = activeInterval->displaySequence; + for (int i=0; ichildCount(); i++) { + IntervalItem *it = (IntervalItem *)allIntervals->child(i); + int ds = it->displaySequence; + if (ds > oindex) + it->setDisplaySequence(ds-1); + } + activeInterval->setDisplaySequence(allIntervals->childCount()); + + // signal! + intervalsChanged(); +} + +void +MainWindow::backInterval() +{ + int oindex = activeInterval->displaySequence; + for (int i=0; ichildCount(); i++) { + IntervalItem *it = (IntervalItem *)allIntervals->child(i); + int ds = it->displaySequence; + if (ds < oindex) + it->setDisplaySequence(ds+1); + } + activeInterval->setDisplaySequence(1); + + // signal! + intervalsChanged(); + +} + void MainWindow::intervalTreeWidgetSelectionChanged() { diff --git a/src/MainWindow.h b/src/MainWindow.h index 606a63231..12ae5fc49 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -126,6 +126,8 @@ class MainWindow : public QMainWindow void deleteInterval(); void renameInterval(); void zoomInterval(); + void frontInterval(); + void backInterval(); void intervalEdited(QTreeWidgetItem *, int); protected: diff --git a/src/PfPvPlot.cpp b/src/PfPvPlot.cpp index b2ed59e3a..04954a849 100644 --- a/src/PfPvPlot.cpp +++ b/src/PfPvPlot.cpp @@ -412,14 +412,8 @@ PfPvPlot::showIntervals(RideItem *_rideItem) RideFile *ride = rideItem->ride(); if (ride) { - // due to the discrete power and cadence values returned by the - // power meter, there will very likely be many duplicate values. - // Rather than pass them all to the curve, use a set to strip - // out duplicates. - std::set > dataSet; - std::set > dataSetSelected; - int num_intervals=intervalCount(); + if (mergeIntervals()) num_intervals = 1; QVector > > dataSetInterval(num_intervals); @@ -432,9 +426,17 @@ PfPvPlot::showIntervals(RideItem *_rideItem) double aepf = (p1->watts * 60.0) / (p1->cad * cl_ * 2.0 * PI); double cpv = (p1->cad * cl_ * 2.0 * PI) / 60.0; - int selection = isSelected(p1); - if (selection > -1) { - dataSetInterval[selection].insert(std::make_pair(aepf, cpv)); + for (int high=-1, t=0; tallIntervalItems()->childCount(); t++) { + IntervalItem *current = dynamic_cast(mainWindow->allIntervalItems()->child(t)); + if ((current != NULL) && current->isSelected()) { + ++high; + if (p1->secs>=current->start && p1->secs<=current->stop) { + if (mergeIntervals()) + dataSetInterval[0].insert(std::make_pair(aepf, cpv)); + else + dataSetInterval[high].insert(std::make_pair(aepf, cpv)); + } + } } tot_cad += p1->cad; tot_cad_points++; @@ -476,7 +478,25 @@ PfPvPlot::showIntervals(RideItem *_rideItem) } } - for (int z = 0; z < num_intervals; z ++) { + // honor display sequencing + QMap intervalOrder; + int count=0; + + if (mergeIntervals()) intervalOrder.insert(1,0); + else { + for (int i=0; iallIntervalItems()->childCount(); i++) { + IntervalItem *current = dynamic_cast(mainWindow->allIntervalItems()->child(i)); + if (current != NULL && current->isSelected() == true) { + intervalOrder.insert(current->displaySequence, count++); + } + } + } + + QMapIterator order(intervalOrder); + while (order.hasNext()) { + order.next(); + int z = order.value(); + QwtPlotCurve *curve; curve = new QwtPlotCurve(); @@ -599,24 +619,3 @@ PfPvPlot::setMergeIntervals(bool value) merge_intervals = value; showIntervals(rideItem); } - -int -PfPvPlot::isSelected(const RideFilePoint *p) { - int highlighted=-1; // Return -1 for point not in interval - if (mainWindow->allIntervalItems() != NULL) { - for (int i=0; iallIntervalItems()->childCount(); i++) { - IntervalItem *current = dynamic_cast(mainWindow->allIntervalItems()->child(i)); - if (current != NULL) { - if (current->isSelected()) { - ++highlighted; - if (p->secs>=current->start && p->secs<=current->stop) { - if (mergeIntervals()) - return 0; - return highlighted; - } - } - } - } - } - return -1; -} diff --git a/src/PfPvPlot.h b/src/PfPvPlot.h index 4aaf56370..0a85976d4 100644 --- a/src/PfPvPlot.h +++ b/src/PfPvPlot.h @@ -78,7 +78,6 @@ signals: QwtPlotMarker *mY; static QwtArray contour_xvalues; // values used in CP and contour plots: djconnel - int isSelected(const RideFilePoint *p); int cp_; int cad_; diff --git a/src/PfPvWindow.cpp b/src/PfPvWindow.cpp index 2d887db12..be369f14c 100644 --- a/src/PfPvWindow.cpp +++ b/src/PfPvWindow.cpp @@ -75,6 +75,7 @@ PfPvWindow::PfPvWindow(MainWindow *mainWindow) : this, SLOT(setMergeIntervalsPfPvFromCheckBox())); connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected())); connect(mainWindow, SIGNAL(intervalSelected()), this, SLOT(intervalSelected())); + connect(mainWindow, SIGNAL(intervalsChanged()), this, SLOT(intervalSelected())); connect(mainWindow, SIGNAL(zonesChanged()), this, SLOT(zonesChanged())); }