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:
Mark Liversedge
2009-12-22 13:46:03 +00:00
committed by Sean Rhea
parent 7a90ac8783
commit 32b94d954f
9 changed files with 101 additions and 42 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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()
{

View File

@@ -126,6 +126,8 @@ class MainWindow : public QMainWindow
void deleteInterval();
void renameInterval();
void zoomInterval();
void frontInterval();
void backInterval();
void intervalEdited(QTreeWidgetItem *, int);
protected:

View File

@@ -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;
}

View File

@@ -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_;

View File

@@ -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()));
}