mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 08:08:42 +00:00
add bring to front/send to back to PfPvPlot
Another rightclick menu for intervals, adding a bring to front and send to back option but only when viewing the pfPvPlot, additionally the algorithm in PfPv plot for determining which interval a point is used for has been adjusted to fully populate every interval curve where appropriate (and incorrect comments and redundant code have been removed). IntervalItems now have a display sequence number so when you have overlapping intervals you can bring to front and send to back on the PfPv plot. The display sequence could be used on other plots if/when they distinguish between intervals. Previously, the coloring of intervals on PfPvPlot was determined solely by the order they were defined which could be quite confusing.
This commit is contained in:
committed by
Sean Rhea
parent
7a90ac8783
commit
32b94d954f
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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; i<allIntervals->childCount(); 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; i<allIntervals->childCount(); 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; i<allIntervals->childCount(); 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()
|
||||
{
|
||||
|
||||
@@ -126,6 +126,8 @@ class MainWindow : public QMainWindow
|
||||
void deleteInterval();
|
||||
void renameInterval();
|
||||
void zoomInterval();
|
||||
void frontInterval();
|
||||
void backInterval();
|
||||
void intervalEdited(QTreeWidgetItem *, int);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -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<std::pair<double, double> > dataSet;
|
||||
std::set<std::pair<double, double> > dataSetSelected;
|
||||
|
||||
int num_intervals=intervalCount();
|
||||
|
||||
if (mergeIntervals()) num_intervals = 1;
|
||||
QVector<std::set<std::pair<double, double> > > 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<double, double>(aepf, cpv));
|
||||
for (int high=-1, t=0; t<mainWindow->allIntervalItems()->childCount(); t++) {
|
||||
IntervalItem *current = dynamic_cast<IntervalItem *>(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<double, double>(aepf, cpv));
|
||||
else
|
||||
dataSetInterval[high].insert(std::make_pair<double, double>(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<int, int> intervalOrder;
|
||||
int count=0;
|
||||
|
||||
if (mergeIntervals()) intervalOrder.insert(1,0);
|
||||
else {
|
||||
for (int i=0; i<mainWindow->allIntervalItems()->childCount(); i++) {
|
||||
IntervalItem *current = dynamic_cast<IntervalItem *>(mainWindow->allIntervalItems()->child(i));
|
||||
if (current != NULL && current->isSelected() == true) {
|
||||
intervalOrder.insert(current->displaySequence, count++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMapIterator<int, int> 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; i<mainWindow->allIntervalItems()->childCount(); i++) {
|
||||
IntervalItem *current = dynamic_cast<IntervalItem *>(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;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ signals:
|
||||
QwtPlotMarker *mY;
|
||||
|
||||
static QwtArray<double> contour_xvalues; // values used in CP and contour plots: djconnel
|
||||
int isSelected(const RideFilePoint *p);
|
||||
|
||||
int cp_;
|
||||
int cad_;
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user