diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 884b40cc0..b366eb174 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -303,6 +303,8 @@ #define GC_NAVGROUPBY "navigator/groupby" #define GC_SORTBY "navigator/sortby" #define GC_SORTBYORDER "navigator/sortbyorder" +#define GC_NAVDISPLAYFILTER "navigator/displayfilter" + // Calendar sync #define GC_WEBCAL_URL "webcal_url" diff --git a/src/Gui/AnalysisSidebar.cpp b/src/Gui/AnalysisSidebar.cpp index 2b80d1090..cc2853010 100644 --- a/src/Gui/AnalysisSidebar.cpp +++ b/src/Gui/AnalysisSidebar.cpp @@ -151,6 +151,21 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow splitter->addWidget(activityItem); splitter->addWidget(intervalItem); + // create the ride navs display filter + activityFilter = new QComboBox(this); + activityFilter->addItem(tr("All"), static_cast(RideNavFilter::ALL)); + activityFilter->addItem(tr("Actual"), static_cast(RideNavFilter::COMPLETED)); + activityFilter->addItem(tr("Planned"), static_cast(RideNavFilter::PLANNED)); + int index = appsettings->cvalue(context->athlete->cyclist, GC_NAVDISPLAYFILTER, "0").toInt(); + activityFilter->setCurrentIndex(index); + setDisplayFilter(index); + + // add ride navs display filter to splitter's banner + QHBoxLayout* splitterBanner = activityItem->splitterHandle->getTitleLayout(); + splitterBanner->insertStretch(2); + splitterBanner->insertWidget(2, activityFilter); + splitterBanner->insertStretch(2); + splitter->prepare(context->athlete->cyclist, "analysis"); // GC signal @@ -164,11 +179,19 @@ AnalysisSidebar::AnalysisSidebar(Context *context) : QWidget(context->mainWindow connect(intervalTree,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(clickZoomInterval(QTreeWidgetItem*))); connect(intervalTree,SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged())); + connect(activityFilter, &QComboBox::currentIndexChanged, this, &AnalysisSidebar::setDisplayFilter); connect (context, SIGNAL(filterChanged()), this, SLOT(filterChanged())); configChanged(CONFIG_APPEARANCE); } +void +AnalysisSidebar::setDisplayFilter(int index) +{ + appsettings->setCValue(context->athlete->cyclist, GC_NAVDISPLAYFILTER, index); + rideNavigator->setDisplayFilter(static_cast(index)); +} + void AnalysisSidebar::intervalItemSelectionChanged(IntervalItem*x) { @@ -332,6 +355,15 @@ AnalysisSidebar::configChanged(qint32) //intervalSummaryWindow->setStyleSheet(GCColor::stylesheet()); splitter->setPalette(GCColor::palette()); + + // mimic the perspective selector colors for the activity filter + QColor selected; + if (GCColor::invertColor(GColor(CTOOLBAR)) == Qt::white) selected = QColor(Qt::lightGray); + else selected = QColor(Qt::darkGray); + activityFilter->setStyleSheet( + QString("QComboBox { background: %1; color: %2; border: 1px solid rgba(127,127,127,127); border-radius: 3; }") + .arg(GColor(CTOOLBAR).name()).arg(selected.name())); + activityHistory->setStyleSheet(QString("background: %1;").arg(GColor(CPLOTBACKGROUND).name())); rideNavigator->tableView->viewport()->setPalette(GCColor::palette()); rideNavigator->tableView->viewport()->setStyleSheet(QString("background: %1;").arg(GColor(CPLOTBACKGROUND).name())); diff --git a/src/Gui/AnalysisSidebar.h b/src/Gui/AnalysisSidebar.h index 5bf1543c1..fc53fe172 100644 --- a/src/Gui/AnalysisSidebar.h +++ b/src/Gui/AnalysisSidebar.h @@ -43,6 +43,7 @@ class AnalysisSidebar : public QWidget AnalysisSidebar(Context *context); void close(); void setWidth(int x) { rideNavigator->setWidth(x); } + RideNavigator *rideNavigator; signals: @@ -89,6 +90,10 @@ class AnalysisSidebar : public QWidget void perfTestIntervalSelected(); void createPerfTestIntervalSelected(); + protected slots: + + void setDisplayFilter(int index); + private: Context *context; @@ -97,6 +102,7 @@ class AnalysisSidebar : public QWidget QWidget *activityHistory; GcSplitterItem *activityItem; QSignalMapper *groupByMapper; + QComboBox* activityFilter; GcSplitterItem *calendarItem; GcMultiCalendar *calendarWidget; diff --git a/src/Gui/GcSideBarItem.h b/src/Gui/GcSideBarItem.h index f25dc3760..3c60b51ee 100644 --- a/src/Gui/GcSideBarItem.h +++ b/src/Gui/GcSideBarItem.h @@ -109,6 +109,8 @@ public: void addAction(QAction *action); void addActions(QList actions); + QHBoxLayout* getTitleLayout() { return titleLayout; } + protected: void paintEvent(QPaintEvent *); GcSubSplitter *gcSplitter; diff --git a/src/Gui/RideNavigator.cpp b/src/Gui/RideNavigator.cpp index e54de327b..62fe26484 100644 --- a/src/Gui/RideNavigator.cpp +++ b/src/Gui/RideNavigator.cpp @@ -371,6 +371,13 @@ void RideNavigator::clearSearch() setWidth(geometry().width()); // before we update column sizes! } +void +RideNavigator::setDisplayFilter(RideNavFilter filter) +{ + searchFilter->setDisplayFilter(filter); + QApplication::processEvents(); // repaint/resize list view - scrollbar.. +} + void RideNavigator::setWidth(int x) { // use helper function diff --git a/src/Gui/RideNavigator.h b/src/Gui/RideNavigator.h index 2afcd0a02..adbbb4794 100644 --- a/src/Gui/RideNavigator.h +++ b/src/Gui/RideNavigator.h @@ -51,6 +51,9 @@ class EditUserSeriesDialog; class OverviewItemConfig; class RideMetric; +// Ride Navigator activity list display filter options +enum class RideNavFilter { ALL=0, COMPLETED, PLANNED }; + // // The RideNavigator // @@ -158,6 +161,8 @@ class RideNavigator : public GcChartWindow void resetView(); // when columns/width changes + void setDisplayFilter(RideNavFilter filter); + void searchStrings(QStringList); void clearSearch(); diff --git a/src/Gui/RideNavigatorProxy.h b/src/Gui/RideNavigatorProxy.h index fa7f492a7..e81d100cd 100644 --- a/src/Gui/RideNavigatorProxy.h +++ b/src/Gui/RideNavigatorProxy.h @@ -629,7 +629,7 @@ class SearchFilter : public QSortFilterProxyModel public: - SearchFilter(QWidget *p) : QSortFilterProxyModel(p), searchActive(false) {} + SearchFilter(QWidget *p) : QSortFilterProxyModel(p), searchActive(false), rideNavFilter(RideNavFilter::ALL) {} void setSourceModel(QAbstractItemModel *model) { QAbstractProxyModel::setSourceModel(model); @@ -637,11 +637,15 @@ class SearchFilter : public QSortFilterProxyModel // find the filename column fileIndex = -1; + plannedIndex = -1; for(int i=0; icolumnCount(); i++) { if (model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString() == "filename" || model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString() == tr("File")) { fileIndex = i; } + if (model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString() == "planned") { + plannedIndex = i; + } } // make sure changes are propogated upstream @@ -654,18 +658,45 @@ class SearchFilter : public QSortFilterProxyModel bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const { - if (fileIndex == -1 || searchActive == false) return true; // nothing to do + if (fileIndex == -1 || plannedIndex == -1) return true; // nothing to do + + bool keyFound = true; + bool display = true; + + // lets get the ride nav display filter first + QModelIndex planned_index = model->index(source_row, plannedIndex, source_parent); + + if (planned_index.isValid()) { + if (model->data(planned_index, Qt::DisplayRole).toBool()) { + if (rideNavFilter == RideNavFilter::COMPLETED) display = false; // planned row, hide if completed only + } else { + if (rideNavFilter == RideNavFilter::PLANNED) display = false; // completed activity, hide if planned only + } + } // lets get the filename - QModelIndex source_index = model->index(source_row, fileIndex, source_parent); - if (!source_index.isValid()) return true; + if (searchActive) { - QString key = model->data(source_index, Qt::DisplayRole).toString(); - return strings.contains(key); + QModelIndex source_index = model->index(source_row, fileIndex, source_parent); + + if (source_index.isValid()) { + QString key = model->data(source_index, Qt::DisplayRole).toString(); + keyFound = strings.contains(key); + } + } + + // combine the two filters + return keyFound && display; } public slots: + void setDisplayFilter(RideNavFilter filter) { + beginResetModel(); + rideNavFilter = filter; + endResetModel(); + } + void setStrings(QStringList list) { beginResetModel(); strings = list; @@ -684,6 +715,8 @@ class SearchFilter : public QSortFilterProxyModel QAbstractItemModel *model; QStringList strings; int fileIndex; + int plannedIndex; bool searchActive; + RideNavFilter rideNavFilter; }; #endif