From 6b2a2dbb65535be1a5f741bd59f869cea2a140f2 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Sun, 10 May 2015 08:30:13 +0100 Subject: [PATCH] Auto Interval Discovery (Part 3a of 3) In this part we have now reinstated the sidebar interval tree but it is refactored out of athlete and into AnalysisSidebar where it belongs. * you can hover and select/deselect intervals in the sidebar Left to do; * All the interval operations like sort, drag and drop, find delete etc do not work at present and will require some work * Add a color button to the tree to let the user change the color for USER defined intervals * Add more types of intervals to the discovery; esp routes and sustained intervals --- src/AddIntervalDialog.cpp | 6 +- src/AllPlot.cpp | 3 + src/AnalysisSidebar.cpp | 162 ++++++++++++++++++++++++++++++++++++-- src/AnalysisSidebar.h | 6 ++ src/Athlete.cpp | 49 ------------ src/Athlete.h | 16 +--- src/IntervalItem.cpp | 5 +- src/IntervalItem.h | 4 +- src/IntervalTreeView.cpp | 15 ++-- src/PowerHist.cpp | 2 +- src/RideFile.cpp | 15 ++++ src/RideFile.h | 6 +- src/RideItem.cpp | 4 +- src/Route.cpp | 2 +- src/Tab.cpp | 35 -------- 15 files changed, 202 insertions(+), 128 deletions(-) diff --git a/src/AddIntervalDialog.cpp b/src/AddIntervalDialog.cpp index 41fba869a..c0140d01b 100644 --- a/src/AddIntervalDialog.cpp +++ b/src/AddIntervalDialog.cpp @@ -852,6 +852,8 @@ AddIntervalDialog::findBests(bool typeTime, const RideFile *ride, double windowS void AddIntervalDialog::addClicked() { +//XXX REFACTOR NEED TO DECIDE HOW TO DO THIS!! +#if 0 // run through the table row by row // and when the checkbox is shown // get name from column 2 @@ -859,8 +861,6 @@ AddIntervalDialog::addClicked() // get stop in secs as a string from column 4 for (int i=0; irowCount(); i++) { -//XXX REFACTOR NEED TO DECIDE HOW TO DO THIS!! -#if 0 // is it checked? QCheckBox *c = (QCheckBox *)resultsTable->cellWidget(i,0); if (c->isChecked()) { @@ -879,8 +879,8 @@ AddIntervalDialog::addClicked() // add allIntervals->addChild(last); } -#endif } context->athlete->updateRideFileIntervals(); +#endif done(0); } diff --git a/src/AllPlot.cpp b/src/AllPlot.cpp index 2483334e1..806be65bf 100644 --- a/src/AllPlot.cpp +++ b/src/AllPlot.cpp @@ -6589,6 +6589,9 @@ AllPlot::intervalHover(IntervalItem *chosen) // no point! if (!isVisible() || chosen == hovered) return; + // don't highlight the all interval + if (chosen && chosen->type == RideFileInterval::ALL) return; + QVectorxdata, ydata; if (chosen) { diff --git a/src/AnalysisSidebar.cpp b/src/AnalysisSidebar.cpp index cd5d6a973..b7489d1c0 100644 --- a/src/AnalysisSidebar.cpp +++ b/src/AnalysisSidebar.cpp @@ -86,6 +86,22 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow activityItem->addWidget(activityHistory); // INTERVALS + intervalTree = new IntervalTreeView(context); + intervalTree->setAnimated(true); + intervalTree->setColumnCount(1); + intervalTree->setIndentation(5); + intervalTree->setSortingEnabled(false); + intervalTree->header()->hide(); + intervalTree->setAlternatingRowColors (false); + intervalTree->setSelectionBehavior(QAbstractItemView::SelectRows); + intervalTree->setEditTriggers(QAbstractItemView::NoEditTriggers); + intervalTree->setSelectionMode(QAbstractItemView::ExtendedSelection); + intervalTree->setContextMenuPolicy(Qt::CustomContextMenu); + intervalTree->setFrameStyle(QFrame::NoFrame); + //allIntervals = context->athlete->intervalWidget->invisibleRootItem(); + //allIntervals->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); + //allIntervals->setText(0, tr("Intervals")); + intervalSummaryWindow = new IntervalSummaryWindow(context); HelpWhatsThis *helpSummaryWindow = new HelpWhatsThis(intervalSummaryWindow); @@ -94,7 +110,7 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow intervalSplitter = new QSplitter(this); intervalSplitter->setHandleWidth(1); intervalSplitter->setOrientation(Qt::Vertical); - intervalSplitter->addWidget(context->athlete->intervalWidget); + intervalSplitter->addWidget(intervalTree); activeInterval = NULL; intervalSplitter->addWidget(intervalSummaryWindow); intervalSplitter->setFrameStyle(QFrame::NoFrame); @@ -121,8 +137,9 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow // right click menus... connect(rideNavigator,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showActivityMenu(const QPoint &))); - connect(context->athlete->intervalWidget,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showIntervalMenu(const QPoint &))); - connect(context->athlete->intervalWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(clickZoomInterval(QTreeWidgetItem*))); + connect(intervalTree,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showIntervalMenu(const QPoint &))); + connect(intervalTree,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(clickZoomInterval(QTreeWidgetItem*))); + connect(intervalTree,SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); connect (context, SIGNAL(filterChanged()), this, SLOT(filterChanged())); @@ -132,10 +149,96 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow void AnalysisSidebar::setRide(RideItem*ride) { + // FIRST REFRESH THE INTERVAL TREE + // stop SEGV in widgets watching for intervals being + // selected whilst we are deleting them from the tree + intervalTree->blockSignals(true); + + // refresh interval list for bottom left + // clear each tree and hide it until items + // are added. That way we get to keep the state + // for expanded (users can unexpand it and that + // is kept as they choose different activities) + QMapIterator i(trees); + i.toFront(); + while(i.hasNext()) { + + i.next(); + i.value()->takeChildren(); + + // now clean and hide the tree + QList items = i.value()->takeChildren(); + for (int j=0; jsetHidden(true); + } + + // now add the intervals for the current ride + if (ride) { // only if we have a ride pointer + + // for each type add a tree structure + foreach(IntervalItem *interval, ride->intervals()) { + + // create trees on demand, not all will be needed by all + // users and just as useful to create here than at startup + // also means we don't need to know what all the types are + // in advance, we create when we see one + QTreeWidgetItem *tree = trees.value(interval->type, NULL); + if (tree == NULL) { + tree = new QTreeWidgetItem(intervalTree->invisibleRootItem(), interval->type); + tree->setData(0, Qt::UserRole, qVariantFromValue((void *)NULL)); // no intervalitem related + tree->setText(0, RideFileInterval::typeDescription(interval->type)); + tree->setForeground(0, GColor(CPLOTMARKER)); + tree->setExpanded(true); + trees.insert(interval->type, tree); + } + tree->setHidden(false); // we have items, so make sure it is visible + + // add this interval to the tree + QTreeWidgetItem *add = new QTreeWidgetItem(tree, interval->type); + add->setText(0, interval->name); + add->setData(0, Qt::UserRole, qVariantFromValue((void*)interval)); + + // set interval to not selected (just in case) + interval->selected = false; + } + + } + + // all done, so connected widgets can receive signals now + intervalTree->blockSignals(false); + + // now the other widgets calendarWidget->setRide(ride); rideNavigator->setRide(ride); } +void +AnalysisSidebar::itemSelectionChanged() +{ + // update RideItem::intervals to reflect user selection + QMapIterator i(trees); + i.toFront(); + while(i.hasNext()) { + i.next(); + + // loop through the intervals for this tree + for(int j=0; jchildCount(); j++) { + + // get pointer to the IntervalItem for this item + QVariant v = i.value()->child(j)->data(0, Qt::UserRole); + + // make the IntervalItem selected flag reflect the current selection state + static_cast(v.value())->selected = i.value()->child(j)->isSelected(); + } + } + + // clear hover now + context->notifyIntervalHover(NULL); + + // notify the world + context->notifyIntervalSelected(); +} + void AnalysisSidebar::close() { @@ -157,8 +260,8 @@ AnalysisSidebar::configChanged(qint32) rideNavigator->tableView->viewport()->setStyleSheet(QString("background: %1;").arg(GColor(CPLOTBACKGROUND).name())); // interval tree - context->athlete->intervalWidget->setPalette(GCColor::palette()); - context->athlete->intervalWidget->setStyleSheet(GCColor::stylesheet()); + intervalTree->setPalette(GCColor::palette()); + intervalTree->setStyleSheet(GCColor::stylesheet()); repaint(); } @@ -284,6 +387,7 @@ AnalysisSidebar::showActivityMenu(const QPoint &pos) void AnalysisSidebar::intervalPopup() { +#if 0 // XXX REFACTOR - GET BASICS DONE FIRST // always show the 'find best' 'find peaks' options QMenu menu(intervalItem); @@ -334,11 +438,13 @@ AnalysisSidebar::intervalPopup() } menu.exec(mapToGlobal((QPoint(intervalItem->pos().x()+intervalItem->width()-20, intervalItem->pos().y())))); +#endif } void AnalysisSidebar::showIntervalMenu(const QPoint &pos) { +#if 0 // XXX REFACTOR GET BASICS FIRST QTreeWidgetItem *trItem = context->athlete->intervalWidget->itemAt(pos); if (trItem != NULL && trItem->text(0) != tr("Intervals")) { @@ -367,6 +473,7 @@ AnalysisSidebar::showIntervalMenu(const QPoint &pos) menu.exec(context->athlete->intervalWidget->mapToGlobal(pos)); } +#endif } /*---------------------------------------------------------------------- @@ -376,6 +483,7 @@ AnalysisSidebar::showIntervalMenu(const QPoint &pos) void AnalysisSidebar::addIntervals() { +#if 0 if (context->ride && context->ride->ride() && context->ride->ride()->dataPoints().count()) { AddIntervalDialog *p = new AddIntervalDialog(context); @@ -389,11 +497,13 @@ AnalysisSidebar::addIntervals() else QMessageBox::critical(this, tr("Find Intervals"), tr("Current activity contains no data")); } +#endif } void AnalysisSidebar::addIntervalForPowerPeaksForSecs(RideFile *ride, int windowSizeSecs, QString name) { +#if 0 QList results; BestIntervalDialog::findBests(ride, windowSizeSecs, 1, results); if (results.isEmpty()) return; @@ -408,12 +518,14 @@ AnalysisSidebar::addIntervalForPowerPeaksForSecs(RideFile *ride, int windowSizeS RideFileInterval::PEAKPOWER); peak->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); context->athlete->allIntervals->addChild(peak); +#endif } void AnalysisSidebar::findPowerPeaks() { +#if 0 if (context->ride && context->ride->ride() && context->ride->ride()->dataPoints().count()) { addIntervalForPowerPeaksForSecs(context->ride->ride(), 5, "Peak 5s"); @@ -438,6 +550,7 @@ AnalysisSidebar::findPowerPeaks() else QMessageBox::critical(this, tr("Find Power Peaks"), tr("Current activity contains no data")); } +#endif } @@ -449,6 +562,7 @@ lessItem(const IntervalItem *s1, const IntervalItem *s2) { void AnalysisSidebar::sortIntervals() { +#if 0 // sort them chronologically QList intervals; @@ -469,12 +583,14 @@ AnalysisSidebar::sortIntervals() // now update the ridefile context->athlete->updateRideFileIntervals(); // will emit intervalChanged() signal +#endif } // rename multiple intervals void AnalysisSidebar::renameIntervalsSelected() { +#if 0 QString string; // set string to first interval selected @@ -512,19 +628,23 @@ AnalysisSidebar::renameIntervalsSelected() context->athlete->updateRideFileIntervals(); // will emit intervalChanged() signal } +#endif } void AnalysisSidebar::deleteIntervalSelected() { +#if 0 // delete the intervals that are selected (from the menu) // the normal delete intervals does that already deleteInterval(); +#endif } void AnalysisSidebar::deleteInterval() { +#if 0 // now delete highlighted! for (int i=0; iathlete->allIntervals->childCount();) { if (context->athlete->allIntervals->child(i)->isSelected()) delete context->athlete->allIntervals->takeChild(i); @@ -532,11 +652,13 @@ AnalysisSidebar::deleteInterval() } context->athlete->updateRideFileIntervals(); // will emit intervalChanged() signal +#endif } void AnalysisSidebar::renameIntervalSelected() { +#if 0 // go edit the name for (int i=0; iathlete->allIntervals->childCount();) { if (context->athlete->allIntervals->child(i)->isSelected()) { @@ -546,18 +668,23 @@ AnalysisSidebar::renameIntervalSelected() } else i++; } context->athlete->updateRideFileIntervals(); // will emit intervalChanged() signal +#endif } void -AnalysisSidebar::renameInterval() { +AnalysisSidebar::renameInterval() +{ +#if 0 // go edit the name activeInterval->setFlags(activeInterval->flags() | Qt::ItemIsEditable); context->athlete->intervalWidget->editItem(activeInterval, 0); +#endif } void AnalysisSidebar::editIntervalSelected() { +#if 0 // go edit the interval for (int i=0; iathlete->allIntervals->childCount();) { if (context->athlete->allIntervals->child(i)->isSelected()) { @@ -566,11 +693,13 @@ AnalysisSidebar::editIntervalSelected() break; } else i++; } +#endif } void AnalysisSidebar::editInterval() { +#if 0 IntervalItem temp = *activeInterval; EditIntervalDialog dialog(this, temp); @@ -579,17 +708,21 @@ AnalysisSidebar::editInterval() context->athlete->updateRideFileIntervals(); // will emit intervalChanged() signal context->athlete->intervalWidget->update(); } +#endif } void AnalysisSidebar::clickZoomInterval(QTreeWidgetItem*item) { +#if 0 context->notifyIntervalZoom((IntervalItem*)item); +#endif } void AnalysisSidebar::zoomIntervalSelected() { +#if 0 // zoom the one interval that is selected via popup menu for (int i=0; iathlete->allIntervals->childCount();) { if (context->athlete->allIntervals->child(i)->isSelected()) { @@ -597,29 +730,39 @@ AnalysisSidebar::zoomIntervalSelected() break; } else i++; } +#endif } void AnalysisSidebar::zoomOut() { +#if 0 context->notifyZoomOut(); // only really used by ride plot +#endif } void -AnalysisSidebar::zoomInterval() { +AnalysisSidebar::zoomInterval() +{ +#if 0 // zoom into this interval on allPlot context->notifyIntervalZoom(activeInterval); +#endif } void -AnalysisSidebar::createRouteIntervalSelected() { +AnalysisSidebar::createRouteIntervalSelected() +{ +#if 0 // create a new route for this interval context->athlete->routes->createRouteFromInterval(activeInterval); +#endif } void AnalysisSidebar::frontInterval() { +#if 0 int oindex = activeInterval->displaySequence; for (int i=0; iathlete->allIntervals->childCount(); i++) { IntervalItem *it = (IntervalItem *)context->athlete->allIntervals->child(i); @@ -631,11 +774,13 @@ AnalysisSidebar::frontInterval() // signal! context->notifyIntervalsChanged(); +#endif } void AnalysisSidebar::backInterval() { +#if 0 int oindex = activeInterval->displaySequence; for (int i=0; iathlete->allIntervals->childCount(); i++) { IntervalItem *it = (IntervalItem *)context->athlete->allIntervals->child(i); @@ -648,6 +793,7 @@ AnalysisSidebar::backInterval() // signal! context->notifyIntervalsChanged(); +#endif } diff --git a/src/AnalysisSidebar.h b/src/AnalysisSidebar.h index efdcb5dc6..1841172d0 100644 --- a/src/AnalysisSidebar.h +++ b/src/AnalysisSidebar.h @@ -60,6 +60,9 @@ class AnalysisSidebar : public QWidget void analysisPopup(); void showActivityMenu(const QPoint &pos); + // interval selection + void itemSelectionChanged(); + // interval menu void intervalPopup(); void showIntervalMenu(const QPoint &pos); @@ -99,6 +102,9 @@ class AnalysisSidebar : public QWidget QSplitter *intervalSplitter; IntervalSummaryWindow *intervalSummaryWindow; IntervalItem *activeInterval; // currently active for context menu popup + + IntervalTreeView *intervalTree; // the interval tree + QMap trees; }; #endif // _GC_AnalysisSidebar_h diff --git a/src/Athlete.cpp b/src/Athlete.cpp index 056c078e7..6da3e438e 100644 --- a/src/Athlete.cpp +++ b/src/Athlete.cpp @@ -174,28 +174,10 @@ Athlete::Athlete(Context *context, const QDir &homeDir) davCalendar->download(true); // refresh the diary window but do not show any error messages #endif - //.INTERVALS TREE -- transitionary - intervalWidget = new IntervalTreeView(context); - intervalWidget->setColumnCount(1); - intervalWidget->setIndentation(5); - intervalWidget->setSortingEnabled(false); - intervalWidget->header()->hide(); - intervalWidget->setAlternatingRowColors (false); - intervalWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - intervalWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); - intervalWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); - intervalWidget->setContextMenuPolicy(Qt::CustomContextMenu); - intervalWidget->setFrameStyle(QFrame::NoFrame); - allIntervals = context->athlete->intervalWidget->invisibleRootItem(); - allIntervals->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); - allIntervals->setText(0, tr("Intervals")); - // trap signals connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32))); connect(context,SIGNAL(rideAdded(RideItem*)),this,SLOT(checkCPX(RideItem*))); connect(context,SIGNAL(rideDeleted(RideItem*)),this,SLOT(checkCPX(RideItem*))); - connect(intervalWidget,SIGNAL(itemSelectionChanged()), this, SLOT(intervalTreeWidgetSelectionChanged())); - connect(intervalWidget,SIGNAL(itemChanged(QTreeWidgetItem *,int)), this, SLOT(updateRideFileIntervals())); } void @@ -250,37 +232,6 @@ void Athlete::selectRideFile(QString fileName) context->notifyRideSelected(context->ride); } -void -Athlete::intervalTreeWidgetSelectionChanged() -{ - context->notifyIntervalHover(NULL); // clear - context->notifyIntervalSelected(); -} - -void -Athlete::updateRideFileIntervals() -{ - // iterate over context->athlete->allIntervals as they are now defined - // and update the RideFile->intervals - if (context->ride) { - - RideFile *current = context->ride->ride(); - current->clearIntervals(); - - for (int i=0; i < allIntervals->childCount(); i++) { - // add the intervals as updated - IntervalItem *it = (IntervalItem *)allIntervals->child(i); - current->addInterval(it->type, it->start, it->stop, it->text(0)); - } - - // emit signal for interval data changed - context->notifyIntervalsChanged(); - - // set dirty - context->ride->setDirty(true); - } -} - void Athlete::addRide(QString name, bool dosignal, bool useTempActivities) { diff --git a/src/Athlete.h b/src/Athlete.h index c8bf97112..aa57f0a05 100644 --- a/src/Athlete.h +++ b/src/Athlete.h @@ -137,7 +137,7 @@ class Athlete : public QObject void addRide(QString name, bool bSelect=true, bool useTempActivities=false); void removeCurrentRide(); - // xones etc + // zones etc void notifyZonesChanged() { zonesChanged(); } void notifySeasonsChanged() { seasonsChanged(); } void notifyNamedSearchesChanged() { namedSearchesChanged(); } @@ -151,23 +151,9 @@ class Athlete : public QObject void namedSearchesChanged(); public slots: - void intervalTreeWidgetSelectionChanged(); void checkCPX(RideItem*ride); - void updateRideFileIntervals(); void configChanged(qint32); - protected: - //XXX REFACTOR THIS WILL GO EVENTUALLY - friend class ::AnalysisSidebar; - friend class ::Tab; - - // interval selection - QTreeWidgetItem *allIntervals; - IntervalTreeView *intervalWidget; - const QTreeWidgetItem *allIntervalItems() { return allIntervals; } - IntervalTreeView *intervalTreeWidget() { return intervalWidget; } - QTreeWidgetItem *mutableIntervalItems() { return allIntervals; } - }; diff --git a/src/IntervalItem.cpp b/src/IntervalItem.cpp index 54125e6cf..f28d1bc87 100644 --- a/src/IntervalItem.cpp +++ b/src/IntervalItem.cpp @@ -37,7 +37,6 @@ IntervalItem::IntervalItem(const RideFile *ride, QString name, double start, dou this->color = color; this->selected = false; metrics_.fill(0, RideMetricFactory::instance().metricCount()); - setText(0, name); } IntervalItem::IntervalItem() : rideItem_(NULL), name(""), type(RideFileInterval::USER), start(0), stop(0), @@ -163,7 +162,7 @@ EditIntervalDialog::EditIntervalDialog(QWidget *parent, IntervalItem &interval) QLabel *to = new QLabel("To"); nameEdit = new QLineEdit(this); - nameEdit->setText(interval.text(0)); + //nameEdit->setText(interval.text(0)); fromEdit = new QTimeEdit(this); fromEdit->setDisplayFormat("hh:mm:ss"); @@ -200,7 +199,7 @@ void EditIntervalDialog::applyClicked() { // get the values back - interval.setText(0, nameEdit->text()); + //interval.setText(0, nameEdit->text()); interval.start = QTime(0,0,0).secsTo(fromEdit->time()); interval.stop = QTime(0,0,0).secsTo(toEdit->time()); accept(); diff --git a/src/IntervalItem.h b/src/IntervalItem.h index c1b66f081..1515b4f51 100644 --- a/src/IntervalItem.h +++ b/src/IntervalItem.h @@ -24,13 +24,13 @@ #include #include #include -#include #include class RideFile; -class IntervalItem : public QTreeWidgetItem +class IntervalItem { + public: // constructors and accessors diff --git a/src/IntervalTreeView.cpp b/src/IntervalTreeView.cpp index 6d4eea5f6..dcd9e3676 100644 --- a/src/IntervalTreeView.cpp +++ b/src/IntervalTreeView.cpp @@ -49,20 +49,19 @@ IntervalTreeView::IntervalTreeView(Context *context) : context(context) void IntervalTreeView::mouseHover(QTreeWidgetItem *item, int) { - int index = invisibleRootItem()->indexOfChild(item); - if (index >=0 && context->rideItem() && context->rideItem()->ride() && - context->rideItem()->ride()->intervals().count() > index) { + QVariant v = item->data(0, Qt::UserRole); + IntervalItem *hover = static_cast(v.value()); - //XXX REFACTORING XXX context->notifyIntervalHover(context->rideItem()->ride()->intervals()[index]); - } + // NULL is a tree, non-NULL is a node + if (hover) context->notifyIntervalHover(hover); } void IntervalTreeView::dropEvent(QDropEvent* event) { - IntervalItem* item1 = (IntervalItem *)itemAt(event->pos()); + QTreeWidgetItem* item1 = (QTreeWidgetItem *)itemAt(event->pos()); QTreeWidget::dropEvent(event); - IntervalItem* item2 = (IntervalItem *)itemAt(event->pos()); + QTreeWidgetItem* item2 = (QTreeWidgetItem *)itemAt(event->pos()); if (item1==topLevelItem(0) || item1 != item2) QTreeWidget::itemChanged(item2, 0); @@ -87,6 +86,7 @@ IntervalTreeView::mimeData (const QList items) const QDataStream stream(&rawData, QIODevice::WriteOnly); stream.setVersion(QDataStream::Qt_4_6); +#if 0 //XXX REFACTOR PROLY TO PACK INTERVALITEM* ONLY // pack data stream << (quint64)(context); // where did this come from? stream << (int)items.count(); @@ -103,6 +103,7 @@ IntervalTreeView::mimeData (const QList items) const stream << (quint64)i->displaySequence; } +#endif // and return as mime data returning->setData("application/x-gc-intervals", rawData); diff --git a/src/PowerHist.cpp b/src/PowerHist.cpp index 8a854a81d..80bf90606 100644 --- a/src/PowerHist.cpp +++ b/src/PowerHist.cpp @@ -2258,7 +2258,7 @@ bool PowerHist::isSelected(const RideFilePoint *p, double sample) if (!rideItem) { foreach (IntervalItem *interval, rideItem->intervalsSelected()) { - if (interval->isSelected() && p->secs+sample>interval->start && p->secsstop) + if (interval->selected && p->secs+sample>interval->start && p->secsstop) return true; } } diff --git a/src/RideFile.cpp b/src/RideFile.cpp index 08da36200..6d08c1a96 100644 --- a/src/RideFile.cpp +++ b/src/RideFile.cpp @@ -367,6 +367,21 @@ struct ComparePointSecs { } }; +QString RideFileInterval::typeDescription(intervaltype x) +{ + switch (x) { + case ALL : return tr("ALL"); break; + case DEVICE : return tr("DEVICE"); break; + case USER : return tr("USER"); break; + case PEAKPOWER : return tr("PEAK POWER"); break; + case ROUTE : return tr("SEGMENTS"); break; + case PEAKHR : return tr("PEAK HR"); break; + case CLIMB : return tr("CLIMBING"); break; + case EFFORT : return tr("EFFORTS"); break; + case MATCH : return tr("MATCHES"); break; + } +} + int RideFile::intervalBegin(const RideFileInterval &interval) const { diff --git a/src/RideFile.h b/src/RideFile.h index 7b6e4b6cc..40c8fa85b 100644 --- a/src/RideFile.h +++ b/src/RideFile.h @@ -88,7 +88,7 @@ class RideFileInterval Q_DECLARE_TR_FUNCTIONS(RideFileInterval); public: - enum intervaltype { ALL, // Entire workout + enum intervaltype { ALL, // Entire workout DEVICE, // Came from Device (Calibration?) USER, // User defined PEAKPOWER, // Peak Power incl. ranking 1-10 in ride @@ -96,13 +96,13 @@ class RideFileInterval PEAKHR, // PEAK HR CLIMB, // Hills and Cols EFFORT, // Sustained effort - LAP, // When a loop we extract each lap MATCH // W'bal based "match from a matchbook" } types; // ALWAYS ADD TO END (RideDB.json uses int values) typedef enum intervaltype IntervalType; - QString typeString; + static QString typeDescription(IntervalType); // return a string to represent the type + QString typeString; IntervalType type; double start, stop; QString name; diff --git a/src/RideItem.cpp b/src/RideItem.cpp index 280b87634..8811716e7 100644 --- a/src/RideItem.cpp +++ b/src/RideItem.cpp @@ -586,7 +586,9 @@ RideItem::updateIntervals() if (interval.start <= begin->secs && interval.stop >= end->secs) continue; // same as ride but offset by recintsecs - if ((interval.start - f->recIntSecs()) <= begin->secs && (interval.stop-f->recIntSecs()) >= end->secs) continue; + if (((interval.start - f->recIntSecs()) <= begin->secs && (interval.stop-f->recIntSecs()) >= end->secs) || + (interval.start <= begin->secs && (interval.stop+f->recIntSecs()) >= end->secs)) + continue; // skip empty backward intervals if (interval.start >= interval.stop) continue; diff --git a/src/Route.cpp b/src/Route.cpp index b14a50ad0..462382510 100644 --- a/src/Route.cpp +++ b/src/Route.cpp @@ -497,7 +497,7 @@ Routes::createRouteFromInterval(IntervalItem *activeInterval) { QRegExp watts("\\([0-9]* *watts\\)"); - QString name = activeInterval->text(0).trimmed(); + QString name = activeInterval->name; //activeInterval->text(0).trimmed(); if (name.contains(watts)) name = name.left(name.indexOf(watts)).trimmed(); diff --git a/src/Tab.cpp b/src/Tab.cpp index 2eb464b90..2c70dd484 100644 --- a/src/Tab.cpp +++ b/src/Tab.cpp @@ -177,41 +177,6 @@ Tab::selectView(int index) void Tab::rideSelected(RideItem*) { - // stop SEGV in widgets watching for intervals being - // selected whilst we are deleting them from the tree - context->athlete->intervalWidget->blockSignals(true); - - // refresh interval list for bottom left - // first lets wipe away the existing intervals - QList intervals = context->athlete->allIntervals->takeChildren(); - for (int i=0; iride) { // only if we have a ride pointer - RideFile *selected = context->ride->ride(); - if (selected) { - // get all the intervals in the currently selected RideFile - QList intervals = selected->intervals(); - for (int i=0; i < intervals.count(); i++) { - // add as a child to context->athlete->allIntervals - IntervalItem *add = new IntervalItem(selected, - intervals.at(i).name, - intervals.at(i).start, - intervals.at(i).stop, - selected->timeToDistance(intervals.at(i).start), - selected->timeToDistance(intervals.at(i).stop), - context->athlete->allIntervals->childCount()+1, - intervals.at(i).type); - add->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); - context->athlete->allIntervals->addChild(add); - } - } - } -#endif - // all done, so connected widgets can receive signals now - context->athlete->intervalWidget->blockSignals(false); - // update the ride property on all widgets // to let them know they need to replot new // selected ride (now the tree is up to date)