mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-04-15 05:32:21 +00:00
Multi Metrics support for Agenda (#4793)
Agenda used to display entries similar to the Calendar: Primary line for a field, secondary line for one metric, tertiary line for a multi-line field. As the agenda has more space available per line, this change adds support for multiple metrics in the secondary line. Defaults are Duration and TriScore.
This commit is contained in:
committed by
GitHub
parent
6fde458393
commit
24269f0dbf
@@ -48,7 +48,6 @@ AgendaWindow::AgendaWindow(Context *context)
|
|||||||
setAgendaFutureDays(7);
|
setAgendaFutureDays(7);
|
||||||
setPrimaryMainField("Route");
|
setPrimaryMainField("Route");
|
||||||
setPrimaryFallbackField("Workout Code");
|
setPrimaryFallbackField("Workout Code");
|
||||||
setSecondaryMetric("workout_time");
|
|
||||||
setShowSecondaryLabel(true);
|
setShowSecondaryLabel(true);
|
||||||
setTertiaryField("Notes");
|
setTertiaryField("Notes");
|
||||||
setShowTertiaryFor(0);
|
setShowTertiaryFor(0);
|
||||||
@@ -69,7 +68,7 @@ AgendaWindow::AgendaWindow(Context *context)
|
|||||||
connect(context, &Context::rideDeleted, this, &AgendaWindow::updateActivitiesIfInRange);
|
connect(context, &Context::rideDeleted, this, &AgendaWindow::updateActivitiesIfInRange);
|
||||||
connect(context, &Context::rideChanged, this, &AgendaWindow::updateActivitiesIfInRange);
|
connect(context, &Context::rideChanged, this, &AgendaWindow::updateActivitiesIfInRange);
|
||||||
connect(context, &Context::configChanged, this, &AgendaWindow::configChanged);
|
connect(context, &Context::configChanged, this, &AgendaWindow::configChanged);
|
||||||
connect(agendaView, &AgendaView::showInTrainMode, this, [context](const CalendarEntry &activity) {
|
connect(agendaView, &AgendaView::showInTrainMode, this, [context](const AgendaEntry &activity) {
|
||||||
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
||||||
if (rideItem != nullptr && rideItem->fileName == activity.reference) {
|
if (rideItem != nullptr && rideItem->fileName == activity.reference) {
|
||||||
QString filter = buildWorkoutFilter(rideItem);
|
QString filter = buildWorkoutFilter(rideItem);
|
||||||
@@ -82,7 +81,7 @@ AgendaWindow::AgendaWindow(Context *context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(agendaView, &AgendaView::viewActivity, this, [context](const CalendarEntry &activity) {
|
connect(agendaView, &AgendaView::viewActivity, this, [context](const AgendaEntry &activity) {
|
||||||
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
||||||
if (rideItem != nullptr && rideItem->fileName == activity.reference) {
|
if (rideItem != nullptr && rideItem->fileName == activity.reference) {
|
||||||
context->notifyRideSelected(rideItem);
|
context->notifyRideSelected(rideItem);
|
||||||
@@ -181,18 +180,34 @@ AgendaWindow::setPrimaryFallbackField
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AgendaWindow::setSecondaryMetric
|
AgendaWindow::setSecondaryMetrics
|
||||||
(const QString &name)
|
(const QString &metrics)
|
||||||
{
|
{
|
||||||
secondaryCombo->setCurrentIndex(std::max(0, secondaryCombo->findData(name)));
|
multiMetricSelector->setSymbols(metrics.split(',', Qt::SkipEmptyParts));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AgendaWindow::setSecondaryMetrics
|
||||||
|
(const QStringList &metrics)
|
||||||
|
{
|
||||||
|
multiMetricSelector->setSymbols(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
AgendaWindow::getSecondaryMetric
|
AgendaWindow::getSecondaryMetrics
|
||||||
() const
|
() const
|
||||||
{
|
{
|
||||||
return secondaryCombo->currentData(Qt::UserRole).toString();
|
return multiMetricSelector->getSymbols().join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QStringList
|
||||||
|
AgendaWindow::getSecondaryMetricsList
|
||||||
|
() const
|
||||||
|
{
|
||||||
|
return multiMetricSelector->getSymbols();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -290,7 +305,7 @@ AgendaWindow::configChanged
|
|||||||
if ( (what & CONFIG_FIELDS)
|
if ( (what & CONFIG_FIELDS)
|
||||||
|| (what & CONFIG_USERMETRICS)) {
|
|| (what & CONFIG_USERMETRICS)) {
|
||||||
updatePrimaryConfigCombos();
|
updatePrimaryConfigCombos();
|
||||||
updateSecondaryConfigCombo();
|
multiMetricSelector->updateMetrics();
|
||||||
updateTertiaryConfigCombo();
|
updateTertiaryConfigCombo();
|
||||||
}
|
}
|
||||||
if (what & CONFIG_APPEARANCE) {
|
if (what & CONFIG_APPEARANCE) {
|
||||||
@@ -370,27 +385,31 @@ AgendaWindow::mkControls
|
|||||||
agendaPastDaysSpin = new QSpinBox();
|
agendaPastDaysSpin = new QSpinBox();
|
||||||
agendaPastDaysSpin->setMaximum(31);
|
agendaPastDaysSpin->setMaximum(31);
|
||||||
agendaPastDaysSpin->setSuffix(" " + tr("day(s)"));
|
agendaPastDaysSpin->setSuffix(" " + tr("day(s)"));
|
||||||
|
|
||||||
agendaFutureDaysSpin = new QSpinBox();
|
agendaFutureDaysSpin = new QSpinBox();
|
||||||
agendaFutureDaysSpin->setMaximum(31);
|
agendaFutureDaysSpin->setMaximum(31);
|
||||||
agendaFutureDaysSpin->setSuffix(" " + tr("day(s)"));
|
agendaFutureDaysSpin->setSuffix(" " + tr("day(s)"));
|
||||||
|
|
||||||
primaryMainCombo = new QComboBox();
|
primaryMainCombo = new QComboBox();
|
||||||
primaryFallbackCombo = new QComboBox();
|
primaryFallbackCombo = new QComboBox();
|
||||||
secondaryCombo = new QComboBox();
|
|
||||||
showSecondaryLabelCheck = new QCheckBox(tr("Show Label"));
|
QStringList summaryMetrics { "workout_time", "triscore" };
|
||||||
|
multiMetricSelector = new MultiMetricSelector(tr("Available Metrics"), tr("Selected Metrics"), summaryMetrics);
|
||||||
|
multiMetricSelector->setContentsMargins(10 * dpiXFactor, 10 * dpiYFactor, 10 * dpiXFactor, 10 * dpiYFactor);
|
||||||
|
multiMetricSelector->setMinimumHeight(300 * dpiYFactor);
|
||||||
|
|
||||||
|
QPushButton *gotoMetrics = new QPushButton(tr("Configure Metrics"));
|
||||||
|
|
||||||
|
showSecondaryLabelCheck = new QCheckBox(tr("Show Names of Metrics"));
|
||||||
showTertiaryForCombo = new QComboBox();
|
showTertiaryForCombo = new QComboBox();
|
||||||
tertiaryCombo = new QComboBox();
|
tertiaryCombo = new QComboBox();
|
||||||
updatePrimaryConfigCombos();
|
updatePrimaryConfigCombos();
|
||||||
updateSecondaryConfigCombo();
|
|
||||||
showTertiaryForCombo->addItem(tr("all dates"));
|
showTertiaryForCombo->addItem(tr("all dates"));
|
||||||
showTertiaryForCombo->addItem(tr("today"));
|
showTertiaryForCombo->addItem(tr("today"));
|
||||||
showTertiaryForCombo->addItem(tr("no dates"));
|
showTertiaryForCombo->addItem(tr("no dates"));
|
||||||
updateTertiaryConfigCombo();
|
updateTertiaryConfigCombo();
|
||||||
primaryMainCombo->setCurrentText("Route");
|
primaryMainCombo->setCurrentText("Route");
|
||||||
primaryFallbackCombo->setCurrentText("Workout Code");
|
primaryFallbackCombo->setCurrentText("Workout Code");
|
||||||
int secondaryIndex = secondaryCombo->findData("workout_time");
|
|
||||||
if (secondaryIndex >= 0) {
|
|
||||||
secondaryCombo->setCurrentIndex(secondaryIndex);
|
|
||||||
}
|
|
||||||
activityMaxTertiaryLinesSpin = new QSpinBox();
|
activityMaxTertiaryLinesSpin = new QSpinBox();
|
||||||
activityMaxTertiaryLinesSpin->setRange(1, 5);
|
activityMaxTertiaryLinesSpin->setRange(1, 5);
|
||||||
eventMaxTertiaryLinesSpin = new QSpinBox();
|
eventMaxTertiaryLinesSpin = new QSpinBox();
|
||||||
@@ -407,7 +426,7 @@ AgendaWindow::mkControls
|
|||||||
activityForm->addRow(tr("Fallback Field"), primaryFallbackCombo);
|
activityForm->addRow(tr("Fallback Field"), primaryFallbackCombo);
|
||||||
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
|
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
|
||||||
activityForm->addRow(new QLabel(HLO + tr("Metric Line") + HLC));
|
activityForm->addRow(new QLabel(HLO + tr("Metric Line") + HLC));
|
||||||
activityForm->addRow(tr("Metric"), secondaryCombo);
|
activityForm->addRow("", gotoMetrics);
|
||||||
activityForm->addRow("", showSecondaryLabelCheck);
|
activityForm->addRow("", showSecondaryLabelCheck);
|
||||||
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
|
activityForm->addItem(new QSpacerItem(0, 20 * dpiYFactor));
|
||||||
activityForm->addRow(new QLabel(HLO + tr("Detail Line") + HLC));
|
activityForm->addRow(new QLabel(HLO + tr("Detail Line") + HLC));
|
||||||
@@ -430,13 +449,15 @@ AgendaWindow::mkControls
|
|||||||
|
|
||||||
QTabWidget *controlsTabs = new QTabWidget();
|
QTabWidget *controlsTabs = new QTabWidget();
|
||||||
controlsTabs->addTab(activityScroller, tr("Activities"));
|
controlsTabs->addTab(activityScroller, tr("Activities"));
|
||||||
|
controlsTabs->addTab(multiMetricSelector, tr("Metrics"));
|
||||||
controlsTabs->addTab(eventScroller, tr("Events"));
|
controlsTabs->addTab(eventScroller, tr("Events"));
|
||||||
|
|
||||||
connect(agendaPastDaysSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setAgendaPastDays);
|
connect(agendaPastDaysSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setAgendaPastDays);
|
||||||
connect(agendaFutureDaysSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setAgendaFutureDays);
|
connect(agendaFutureDaysSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setAgendaFutureDays);
|
||||||
connect(primaryMainCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
connect(primaryMainCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
||||||
connect(primaryFallbackCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
connect(primaryFallbackCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
||||||
connect(secondaryCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
connect(multiMetricSelector, &MultiMetricSelector::selectedChanged, this, &AgendaWindow::updateActivities);
|
||||||
|
connect(gotoMetrics, &QPushButton::clicked, this, [controlsTabs]() { controlsTabs->setCurrentIndex(1); });
|
||||||
connect(showTertiaryForCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
connect(showTertiaryForCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
||||||
connect(tertiaryCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
connect(tertiaryCombo, &QComboBox::currentIndexChanged, this, &AgendaWindow::updateActivities);
|
||||||
connect(activityMaxTertiaryLinesSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setActivityMaxTertiaryLines);
|
connect(activityMaxTertiaryLinesSpin, &QSpinBox::valueChanged, this, &AgendaWindow::setActivityMaxTertiaryLines);
|
||||||
@@ -473,27 +494,6 @@ AgendaWindow::updatePrimaryConfigCombos
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
AgendaWindow::updateSecondaryConfigCombo
|
|
||||||
()
|
|
||||||
{
|
|
||||||
QString symbol = getSecondaryMetric();
|
|
||||||
|
|
||||||
secondaryCombo->blockSignals(true);
|
|
||||||
secondaryCombo->clear();
|
|
||||||
const RideMetricFactory &factory = RideMetricFactory::instance();
|
|
||||||
for (const QString &metricSymbol : factory.allMetrics()) {
|
|
||||||
if (metricSymbol.startsWith("compatibility_")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
secondaryCombo->addItem(Utils::unprotect(factory.rideMetric(metricSymbol)->name()), metricSymbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
secondaryCombo->blockSignals(false);
|
|
||||||
setSecondaryMetric(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AgendaWindow::updateTertiaryConfigCombo
|
AgendaWindow::updateTertiaryConfigCombo
|
||||||
()
|
()
|
||||||
@@ -514,26 +514,33 @@ AgendaWindow::updateTertiaryConfigCombo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QHash<QDate, QList<CalendarEntry>>
|
QHash<QDate, QList<AgendaEntry>>
|
||||||
AgendaWindow::getActivities
|
AgendaWindow::getActivities
|
||||||
(const QDate &firstDay, const QDate &today, const QDate &lastDay) const
|
(const QDate &firstDay, const QDate &today, const QDate &lastDay) const
|
||||||
{
|
{
|
||||||
QHash<QDate, QList<CalendarEntry>> activities;
|
QHash<QDate, QList<AgendaEntry>> activities;
|
||||||
const RideMetricFactory &factory = RideMetricFactory::instance();
|
const RideMetricFactory &factory = RideMetricFactory::instance();
|
||||||
const RideMetric *rideMetric = factory.rideMetric(getSecondaryMetric());
|
QList<RideMetric const *> rideMetrics;
|
||||||
QString rideMetricName;
|
QStringList rideMetricNames;
|
||||||
QString rideMetricUnit;
|
QStringList rideMetricUnits;
|
||||||
if (rideMetric != nullptr) {
|
for (const QString &metric : getSecondaryMetricsList()) {
|
||||||
rideMetricName = rideMetric->name();
|
RideMetric const *rideMetric = factory.rideMetric(metric);
|
||||||
if ( ! rideMetric->isTime()
|
if (rideMetric != nullptr) {
|
||||||
&& ! rideMetric->isDate()) {
|
rideMetrics << rideMetric;
|
||||||
rideMetricUnit = rideMetric->units(GlobalContext::context()->useMetricUnits);
|
rideMetricNames << rideMetric->name();
|
||||||
|
if ( ! rideMetric->isTime()
|
||||||
|
&& ! rideMetric->isDate()) {
|
||||||
|
rideMetricUnits << rideMetric->units(GlobalContext::context()->useMetricUnits);
|
||||||
|
} else {
|
||||||
|
rideMetricUnits << "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int showTertiaryFor = getShowTertiaryFor();
|
int showTertiaryFor = getShowTertiaryFor();
|
||||||
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
for (RideItem *rideItem : context->athlete->rideCache->rides()) {
|
||||||
if ( rideItem == nullptr
|
if ( rideItem == nullptr
|
||||||
|
|| ! rideItem->planned
|
||||||
|| rideItem->dateTime.date() < firstDay
|
|| rideItem->dateTime.date() < firstDay
|
||||||
|| rideItem->dateTime.date() > lastDay
|
|| rideItem->dateTime.date() > lastDay
|
||||||
|| rideItem->hasLinkedActivity()) {
|
|| rideItem->hasLinkedActivity()) {
|
||||||
@@ -545,7 +552,7 @@ AgendaWindow::getActivities
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString sport = rideItem->sport;
|
QString sport = rideItem->sport;
|
||||||
CalendarEntry activity;
|
AgendaEntry activity;
|
||||||
|
|
||||||
QString primaryMain = rideItem->getText(getPrimaryMainField(), "").trimmed();
|
QString primaryMain = rideItem->getText(getPrimaryMainField(), "").trimmed();
|
||||||
if (! primaryMain.isEmpty()) {
|
if (! primaryMain.isEmpty()) {
|
||||||
@@ -560,42 +567,41 @@ AgendaWindow::getActivities
|
|||||||
activity.primary = tr("<unknown>");
|
activity.primary = tr("<unknown>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rideMetric != nullptr && rideMetric->isRelevantForRide(rideItem)) {
|
for (int i = 0; i < rideMetrics.count(); ++i) {
|
||||||
activity.secondary = rideItem->getStringForSymbol(getSecondaryMetric(), GlobalContext::context()->useMetricUnits);
|
RideMetric const *rideMetric = rideMetrics[i];
|
||||||
if (! rideMetricUnit.isEmpty()) {
|
if (rideMetric->isRelevantForRide(rideItem)) {
|
||||||
activity.secondary += " " + rideMetricUnit;
|
QString value = rideItem->getStringForSymbol(rideMetric->symbol(), GlobalContext::context()->useMetricUnits);
|
||||||
|
if (! rideMetricUnits.value(i, "").isEmpty()) {
|
||||||
|
value.append(" " + rideMetricUnits.value(i, ""));
|
||||||
|
}
|
||||||
|
activity.secondaryValues << Utils::unprotect(value);
|
||||||
|
if (isShowSecondaryLabel()) {
|
||||||
|
activity.secondaryLabels << Utils::unprotect(rideMetricNames.value(i, ""));
|
||||||
|
} else {
|
||||||
|
activity.secondaryLabels << "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isShowSecondaryLabel()) {
|
}
|
||||||
activity.secondaryMetric = rideMetricName;
|
if (activity.secondaryValues.count() == 0) {
|
||||||
}
|
activity.secondaryValues << tr("N/A");
|
||||||
} else {
|
activity.secondaryLabels << "";
|
||||||
activity.secondary = tr("N/A");
|
|
||||||
activity.secondaryMetric = "";
|
|
||||||
}
|
}
|
||||||
if (showTertiaryFor == 0 || (showTertiaryFor == 1 && rideItem->dateTime.date() == today)) {
|
if (showTertiaryFor == 0 || (showTertiaryFor == 1 && rideItem->dateTime.date() == today)) {
|
||||||
activity.tertiary = rideItem->getText(getTertiaryField(), "").trimmed();
|
activity.tertiary = rideItem->getText(getTertiaryField(), "").trimmed();
|
||||||
activity.tertiary = Utils::unprotect(activity.tertiary);
|
activity.tertiary = Utils::unprotect(activity.tertiary);
|
||||||
}
|
}
|
||||||
activity.primary = Utils::unprotect(activity.primary);
|
activity.primary = Utils::unprotect(activity.primary);
|
||||||
activity.secondary = Utils::unprotect(activity.secondary);
|
|
||||||
activity.secondaryMetric = Utils::unprotect(activity.secondaryMetric);
|
|
||||||
|
|
||||||
activity.iconFile = IconManager::instance().getFilepath(rideItem);
|
activity.iconFile = IconManager::instance().getFilepath(rideItem);
|
||||||
if (rideItem->color.alpha() < 255 || rideItem->planned) {
|
activity.color = GColor(CCALPLANNED);
|
||||||
activity.color = GColor(CCALPLANNED);
|
|
||||||
} else {
|
|
||||||
activity.color = rideItem->color;
|
|
||||||
}
|
|
||||||
activity.reference = rideItem->fileName;
|
activity.reference = rideItem->fileName;
|
||||||
activity.start = rideItem->dateTime.time();
|
activity.start = rideItem->dateTime.time();
|
||||||
activity.durationSecs = rideItem->getForSymbol("workout_time", GlobalContext::context()->useMetricUnits);
|
activity.type = ENTRY_TYPE_PLANNED_ACTIVITY;
|
||||||
activity.type = rideItem->planned ? ENTRY_TYPE_PLANNED_ACTIVITY : ENTRY_TYPE_ACTIVITY;
|
activity.hasTrainMode = sport == "Bike" && ! buildWorkoutFilter(rideItem).isEmpty();
|
||||||
activity.isRelocatable = rideItem->planned;
|
|
||||||
activity.hasTrainMode = rideItem->planned && sport == "Bike" && ! buildWorkoutFilter(rideItem).isEmpty();
|
|
||||||
activities[rideItem->dateTime.date()] << activity;
|
activities[rideItem->dateTime.date()] << activity;
|
||||||
}
|
}
|
||||||
for (auto dayIt = activities.begin(); dayIt != activities.end(); ++dayIt) {
|
for (auto dayIt = activities.begin(); dayIt != activities.end(); ++dayIt) {
|
||||||
std::sort(dayIt.value().begin(), dayIt.value().end(), [](const CalendarEntry &a, const CalendarEntry &b) {
|
std::sort(dayIt.value().begin(), dayIt.value().end(), [](const AgendaEntry &a, const AgendaEntry &b) {
|
||||||
if (a.start == b.start) {
|
if (a.start == b.start) {
|
||||||
return a.primary < b.primary;
|
return a.primary < b.primary;
|
||||||
} else {
|
} else {
|
||||||
@@ -607,12 +613,12 @@ AgendaWindow::getActivities
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<QList<CalendarEntry>, QList<CalendarEntry>>
|
std::pair<QList<AgendaEntry>, QList<AgendaEntry>>
|
||||||
AgendaWindow::getPhases
|
AgendaWindow::getPhases
|
||||||
(const Season &season, const QDate &firstDay) const
|
(const Season &season, const QDate &firstDay) const
|
||||||
{
|
{
|
||||||
QList<CalendarEntry> ongoingPhases;
|
QList<AgendaEntry> ongoingPhases;
|
||||||
QList<CalendarEntry> futurePhases;
|
QList<AgendaEntry> futurePhases;
|
||||||
for (const Phase &phase : season.phases) {
|
for (const Phase &phase : season.phases) {
|
||||||
if (phase.getAbsoluteStart().isValid() && phase.getAbsoluteEnd().isValid()) {
|
if (phase.getAbsoluteStart().isValid() && phase.getAbsoluteEnd().isValid()) {
|
||||||
QString phaseType;
|
QString phaseType;
|
||||||
@@ -623,37 +629,36 @@ AgendaWindow::getPhases
|
|||||||
default:
|
default:
|
||||||
phaseType = Phase::types[static_cast<int>(phase.getType()) - static_cast<int>(Phase::phase)];
|
phaseType = Phase::types[static_cast<int>(phase.getType()) - static_cast<int>(Phase::phase)];
|
||||||
}
|
}
|
||||||
CalendarEntry entry;
|
AgendaEntry entry;
|
||||||
entry.primary = phase.getName();
|
entry.primary = phase.getName();
|
||||||
entry.iconFile = ":images/breeze/network-mobile-100.svg";
|
entry.iconFile = ":images/breeze/network-mobile-100.svg";
|
||||||
entry.color = GColor(CCALPHASE);
|
entry.color = GColor(CCALPHASE);
|
||||||
entry.reference = phase.id().toString();
|
entry.reference = phase.id().toString();
|
||||||
entry.start = QTime(0, 0, 1);
|
entry.start = QTime(0, 0, 1);
|
||||||
entry.type = ENTRY_TYPE_PHASE;
|
entry.type = ENTRY_TYPE_PHASE;
|
||||||
entry.isRelocatable = false;
|
|
||||||
entry.spanStart = phase.getAbsoluteStart();
|
entry.spanStart = phase.getAbsoluteStart();
|
||||||
entry.spanEnd = phase.getAbsoluteEnd();
|
entry.spanEnd = phase.getAbsoluteEnd();
|
||||||
int duration = entry.spanStart.daysTo(entry.spanEnd);
|
int duration = entry.spanStart.daysTo(entry.spanEnd);
|
||||||
ShowDaysAsUnit unit = showDaysAs(duration);
|
ShowDaysAsUnit unit = showDaysAs(duration);
|
||||||
if (unit == ShowDaysAsUnit::Days) {
|
if (unit == ShowDaysAsUnit::Days) {
|
||||||
if (duration > 1) {
|
if (duration > 1) {
|
||||||
entry.secondary = tr("%1 • %2 days").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 days").arg(phaseType).arg(duration);
|
||||||
} else {
|
} else {
|
||||||
entry.secondary = tr("%1 • %2 day").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 day").arg(phaseType).arg(duration);
|
||||||
}
|
}
|
||||||
} else if (unit == ShowDaysAsUnit::Weeks) {
|
} else if (unit == ShowDaysAsUnit::Weeks) {
|
||||||
duration = daysToWeeks(duration);
|
duration = daysToWeeks(duration);
|
||||||
if (duration > 1) {
|
if (duration > 1) {
|
||||||
entry.secondary = tr("%1 • %2 weeks").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 weeks").arg(phaseType).arg(duration);
|
||||||
} else {
|
} else {
|
||||||
entry.secondary = tr("%1 • %2 week").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 week").arg(phaseType).arg(duration);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
duration = daysToMonths(duration);
|
duration = daysToMonths(duration);
|
||||||
if (duration > 1) {
|
if (duration > 1) {
|
||||||
entry.secondary = tr("%1 • %2 months").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 months").arg(phaseType).arg(duration);
|
||||||
} else {
|
} else {
|
||||||
entry.secondary = tr("%1 • %2 month").arg(phaseType).arg(duration);
|
entry.secondaryValues << tr("%1 • %2 month").arg(phaseType).arg(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (phase.getAbsoluteStart() <= firstDay && phase.getAbsoluteEnd() >= firstDay) {
|
if (phase.getAbsoluteStart() <= firstDay && phase.getAbsoluteEnd() >= firstDay) {
|
||||||
@@ -663,10 +668,10 @@ AgendaWindow::getPhases
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(ongoingPhases.begin(), ongoingPhases.end(), [](const CalendarEntry &a, const CalendarEntry &b) {
|
std::sort(ongoingPhases.begin(), ongoingPhases.end(), [](const AgendaEntry &a, const AgendaEntry &b) {
|
||||||
return a.spanEnd < b.spanEnd;
|
return a.spanEnd < b.spanEnd;
|
||||||
});
|
});
|
||||||
std::sort(futurePhases.begin(), futurePhases.end(), [](const CalendarEntry &a, const CalendarEntry &b) {
|
std::sort(futurePhases.begin(), futurePhases.end(), [](const AgendaEntry &a, const AgendaEntry &b) {
|
||||||
return a.spanStart < b.spanStart;
|
return a.spanStart < b.spanStart;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -674,11 +679,11 @@ AgendaWindow::getPhases
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QHash<QDate, QList<CalendarEntry>>
|
QHash<QDate, QList<AgendaEntry>>
|
||||||
AgendaWindow::getEvents
|
AgendaWindow::getEvents
|
||||||
(const QDate &firstDay) const
|
(const QDate &firstDay) const
|
||||||
{
|
{
|
||||||
QHash<QDate, QList<CalendarEntry>> events;
|
QHash<QDate, QList<AgendaEntry>> events;
|
||||||
QList<Season> tmpSeasons = context->athlete->seasons->seasons;
|
QList<Season> tmpSeasons = context->athlete->seasons->seasons;
|
||||||
std::sort(tmpSeasons.begin(), tmpSeasons.end(), Season::LessThanForStarts);
|
std::sort(tmpSeasons.begin(), tmpSeasons.end(), Season::LessThanForStarts);
|
||||||
for (const Season &s : tmpSeasons) {
|
for (const Season &s : tmpSeasons) {
|
||||||
@@ -686,36 +691,34 @@ AgendaWindow::getEvents
|
|||||||
if ( ( ( firstDay.isValid()
|
if ( ( ( firstDay.isValid()
|
||||||
&& event.date >= firstDay)
|
&& event.date >= firstDay)
|
||||||
|| ! firstDay.isValid())) {
|
|| ! firstDay.isValid())) {
|
||||||
CalendarEntry entry;
|
AgendaEntry entry;
|
||||||
entry.primary = event.name;
|
entry.primary = event.name;
|
||||||
if (event.priority == 0) {
|
if (event.priority == 0) {
|
||||||
entry.iconFile = ":images/breeze/task-process-4.svg";
|
entry.iconFile = ":images/breeze/task-process-4.svg";
|
||||||
entry.secondary = tr("Uncategorized");
|
entry.secondaryValues << tr("Uncategorized");
|
||||||
} else if (event.priority == 1) {
|
} else if (event.priority == 1) {
|
||||||
entry.iconFile = ":images/breeze/task-process-4.svg";
|
entry.iconFile = ":images/breeze/task-process-4.svg";
|
||||||
entry.secondary = tr("Category A");
|
entry.secondaryValues << tr("Category A");
|
||||||
} else if (event.priority == 2) {
|
} else if (event.priority == 2) {
|
||||||
entry.iconFile = ":images/breeze/task-process-3.svg";
|
entry.iconFile = ":images/breeze/task-process-3.svg";
|
||||||
entry.secondary = tr("Category B");
|
entry.secondaryValues << tr("Category B");
|
||||||
} else if (event.priority == 3) {
|
} else if (event.priority == 3) {
|
||||||
entry.iconFile = ":images/breeze/task-process-2.svg";
|
entry.iconFile = ":images/breeze/task-process-2.svg";
|
||||||
entry.secondary = tr("Category C");
|
entry.secondaryValues << tr("Category C");
|
||||||
} else if (event.priority == 4) {
|
} else if (event.priority == 4) {
|
||||||
entry.iconFile = ":images/breeze/task-process-1.svg";
|
entry.iconFile = ":images/breeze/task-process-1.svg";
|
||||||
entry.secondary = tr("Category D");
|
entry.secondaryValues << tr("Category D");
|
||||||
} else {
|
} else {
|
||||||
entry.iconFile = ":images/breeze/task-process-0.svg";
|
entry.iconFile = ":images/breeze/task-process-0.svg";
|
||||||
entry.secondary = tr("Category E");
|
entry.secondaryValues << tr("Category E");
|
||||||
}
|
}
|
||||||
entry.tertiary = event.description.trimmed();
|
entry.tertiary = event.description.trimmed();
|
||||||
entry.color = GColor(CCALEVENT);
|
entry.color = GColor(CCALEVENT);
|
||||||
entry.reference = event.id;
|
entry.reference = event.id;
|
||||||
entry.start = QTime(0, 0, 0);
|
entry.start = QTime(0, 0, 0);
|
||||||
entry.durationSecs = 0;
|
|
||||||
entry.type = ENTRY_TYPE_EVENT;
|
entry.type = ENTRY_TYPE_EVENT;
|
||||||
entry.spanStart = event.date;
|
entry.spanStart = event.date;
|
||||||
entry.spanEnd = event.date;
|
entry.spanEnd = event.date;
|
||||||
entry.isRelocatable = false;
|
|
||||||
events[event.date] << entry;
|
events[event.date] << entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -733,9 +736,9 @@ AgendaWindow::updateActivities
|
|||||||
agendaView->updateDate();
|
agendaView->updateDate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QHash<QDate, QList<CalendarEntry>> activities = getActivities(agendaView->firstVisibleDay(), agendaView->selectedDate(), agendaView->lastVisibleDay());
|
QHash<QDate, QList<AgendaEntry>> activities = getActivities(agendaView->firstVisibleDay(), agendaView->selectedDate(), agendaView->lastVisibleDay());
|
||||||
std::pair<QList<CalendarEntry>, QList<CalendarEntry>> phases;
|
std::pair<QList<AgendaEntry>, QList<AgendaEntry>> phases;
|
||||||
QHash<QDate, QList<CalendarEntry>> events;
|
QHash<QDate, QList<AgendaEntry>> events;
|
||||||
QString seasonName;
|
QString seasonName;
|
||||||
|
|
||||||
tertiaryCombo->setEnabled(getShowTertiaryFor() != 2);
|
tertiaryCombo->setEnabled(getShowTertiaryFor() != 2);
|
||||||
@@ -765,7 +768,7 @@ AgendaWindow::updateActivitiesIfInRange
|
|||||||
|
|
||||||
void
|
void
|
||||||
AgendaWindow::editPhaseEntry
|
AgendaWindow::editPhaseEntry
|
||||||
(const CalendarEntry &entry)
|
(const AgendaEntry &entry)
|
||||||
{
|
{
|
||||||
if (entry.type != ENTRY_TYPE_PHASE) {
|
if (entry.type != ENTRY_TYPE_PHASE) {
|
||||||
return;
|
return;
|
||||||
@@ -799,7 +802,7 @@ AgendaWindow::editPhaseEntry
|
|||||||
|
|
||||||
void
|
void
|
||||||
AgendaWindow::editEventEntry
|
AgendaWindow::editEventEntry
|
||||||
(const CalendarEntry &entry)
|
(const AgendaEntry &entry)
|
||||||
{
|
{
|
||||||
if (entry.type != ENTRY_TYPE_EVENT) {
|
if (entry.type != ENTRY_TYPE_EVENT) {
|
||||||
return;
|
return;
|
||||||
@@ -810,13 +813,14 @@ AgendaWindow::editEventEntry
|
|||||||
for (SeasonEvent &event : s.events) {
|
for (SeasonEvent &event : s.events) {
|
||||||
// FIXME: Ugly comparison required because SeasonEvent::id is not populated
|
// FIXME: Ugly comparison required because SeasonEvent::id is not populated
|
||||||
if ( event.name == entry.primary
|
if ( event.name == entry.primary
|
||||||
&& ( (event.priority == 0 && entry.secondary == tr("Uncategorized"))
|
&& entry.secondaryValues.count() == 1
|
||||||
|| (event.priority == 1 && entry.secondary == tr("Category A"))
|
&& ( (event.priority == 0 && entry.secondaryValues[0] == tr("Uncategorized"))
|
||||||
|| (event.priority == 2 && entry.secondary == tr("Category B"))
|
|| (event.priority == 1 && entry.secondaryValues[0] == tr("Category A"))
|
||||||
|| (event.priority == 3 && entry.secondary == tr("Category C"))
|
|| (event.priority == 2 && entry.secondaryValues[0] == tr("Category B"))
|
||||||
|| (event.priority == 4 && entry.secondary == tr("Category D"))
|
|| (event.priority == 3 && entry.secondaryValues[0] == tr("Category C"))
|
||||||
|
|| (event.priority == 4 && entry.secondaryValues[0] == tr("Category D"))
|
||||||
|| ( (event.priority < 0 || event.priority > 4)
|
|| ( (event.priority < 0 || event.priority > 4)
|
||||||
&& entry.secondary == tr("Category E")))
|
&& entry.secondaryValues[0] == tr("Category E")))
|
||||||
&& event.description.trimmed() == entry.tertiary
|
&& event.description.trimmed() == entry.tertiary
|
||||||
&& event.id == entry.reference
|
&& event.id == entry.reference
|
||||||
&& event.date == entry.spanStart
|
&& event.date == entry.spanStart
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ class AgendaWindow : public GcChartWindow
|
|||||||
Q_PROPERTY(int agendaFutureDays READ getAgendaFutureDays WRITE setAgendaFutureDays USER true)
|
Q_PROPERTY(int agendaFutureDays READ getAgendaFutureDays WRITE setAgendaFutureDays USER true)
|
||||||
Q_PROPERTY(QString primaryMainField READ getPrimaryMainField WRITE setPrimaryMainField USER true)
|
Q_PROPERTY(QString primaryMainField READ getPrimaryMainField WRITE setPrimaryMainField USER true)
|
||||||
Q_PROPERTY(QString primaryFallbackField READ getPrimaryFallbackField WRITE setPrimaryFallbackField USER true)
|
Q_PROPERTY(QString primaryFallbackField READ getPrimaryFallbackField WRITE setPrimaryFallbackField USER true)
|
||||||
Q_PROPERTY(QString secondaryMetric READ getSecondaryMetric WRITE setSecondaryMetric USER true)
|
|
||||||
|
Q_PROPERTY(QString secondaryMetrics READ getSecondaryMetrics WRITE setSecondaryMetrics USER true)
|
||||||
|
|
||||||
Q_PROPERTY(bool showSecondaryLabel READ isShowSecondaryLabel WRITE setShowSecondaryLabel USER true)
|
Q_PROPERTY(bool showSecondaryLabel READ isShowSecondaryLabel WRITE setShowSecondaryLabel USER true)
|
||||||
Q_PROPERTY(int showTertiaryFor READ getShowTertiaryFor WRITE setShowTertiaryFor USER true)
|
Q_PROPERTY(int showTertiaryFor READ getShowTertiaryFor WRITE setShowTertiaryFor USER true)
|
||||||
Q_PROPERTY(QString tertiaryField READ getTertiaryField WRITE setTertiaryField USER true)
|
Q_PROPERTY(QString tertiaryField READ getTertiaryField WRITE setTertiaryField USER true)
|
||||||
@@ -59,7 +61,8 @@ class AgendaWindow : public GcChartWindow
|
|||||||
|
|
||||||
QString getPrimaryMainField() const;
|
QString getPrimaryMainField() const;
|
||||||
QString getPrimaryFallbackField() const;
|
QString getPrimaryFallbackField() const;
|
||||||
QString getSecondaryMetric() const;
|
QString getSecondaryMetrics() const;
|
||||||
|
QStringList getSecondaryMetricsList() const;
|
||||||
bool isShowSecondaryLabel() const;
|
bool isShowSecondaryLabel() const;
|
||||||
int getShowTertiaryFor() const;
|
int getShowTertiaryFor() const;
|
||||||
QString getTertiaryField() const;
|
QString getTertiaryField() const;
|
||||||
@@ -71,7 +74,8 @@ class AgendaWindow : public GcChartWindow
|
|||||||
void setAgendaFutureDays(int days);
|
void setAgendaFutureDays(int days);
|
||||||
void setPrimaryMainField(const QString &name);
|
void setPrimaryMainField(const QString &name);
|
||||||
void setPrimaryFallbackField(const QString &name);
|
void setPrimaryFallbackField(const QString &name);
|
||||||
void setSecondaryMetric(const QString &name);
|
void setSecondaryMetrics(const QString &metrics);
|
||||||
|
void setSecondaryMetrics(const QStringList &metrics);
|
||||||
void setShowSecondaryLabel(bool showSecondaryLabel);
|
void setShowSecondaryLabel(bool showSecondaryLabel);
|
||||||
void setShowTertiaryFor(int showFor);
|
void setShowTertiaryFor(int showFor);
|
||||||
void setTertiaryField(const QString &name);
|
void setTertiaryField(const QString &name);
|
||||||
@@ -90,7 +94,7 @@ class AgendaWindow : public GcChartWindow
|
|||||||
QSpinBox *agendaFutureDaysSpin;
|
QSpinBox *agendaFutureDaysSpin;
|
||||||
QComboBox *primaryMainCombo;
|
QComboBox *primaryMainCombo;
|
||||||
QComboBox *primaryFallbackCombo;
|
QComboBox *primaryFallbackCombo;
|
||||||
QComboBox *secondaryCombo;
|
MultiMetricSelector *multiMetricSelector;
|
||||||
QCheckBox *showSecondaryLabelCheck;
|
QCheckBox *showSecondaryLabelCheck;
|
||||||
QComboBox *showTertiaryForCombo;
|
QComboBox *showTertiaryForCombo;
|
||||||
QComboBox *tertiaryCombo;
|
QComboBox *tertiaryCombo;
|
||||||
@@ -100,17 +104,16 @@ class AgendaWindow : public GcChartWindow
|
|||||||
|
|
||||||
void mkControls();
|
void mkControls();
|
||||||
void updatePrimaryConfigCombos();
|
void updatePrimaryConfigCombos();
|
||||||
void updateSecondaryConfigCombo();
|
|
||||||
void updateTertiaryConfigCombo();
|
void updateTertiaryConfigCombo();
|
||||||
QHash<QDate, QList<CalendarEntry>> getActivities(const QDate &firstDay, const QDate &today, const QDate &lastDay) const;
|
QHash<QDate, QList<AgendaEntry>> getActivities(const QDate &firstDay, const QDate &today, const QDate &lastDay) const;
|
||||||
std::pair<QList<CalendarEntry>, QList<CalendarEntry>> getPhases(const Season &season, const QDate &firstDay) const;
|
std::pair<QList<AgendaEntry>, QList<AgendaEntry>> getPhases(const Season &season, const QDate &firstDay) const;
|
||||||
QHash<QDate, QList<CalendarEntry>> getEvents(const QDate &firstDay) const;
|
QHash<QDate, QList<AgendaEntry>> getEvents(const QDate &firstDay) const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateActivities();
|
void updateActivities();
|
||||||
void updateActivitiesIfInRange(RideItem *rideItem);
|
void updateActivitiesIfInRange(RideItem *rideItem);
|
||||||
void editPhaseEntry(const CalendarEntry &entry);
|
void editPhaseEntry(const AgendaEntry &entry);
|
||||||
void editEventEntry(const CalendarEntry &entry);
|
void editEventEntry(const AgendaEntry &entry);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ ActivityTree::ActivityTree
|
|||||||
|
|
||||||
QVariant data = item->data(1, AgendaEntryDelegate::EntryRole);
|
QVariant data = item->data(1, AgendaEntryDelegate::EntryRole);
|
||||||
if (! data.isNull()) {
|
if (! data.isNull()) {
|
||||||
CalendarEntry entry = data.value<CalendarEntry>();
|
AgendaEntry entry = data.value<AgendaEntry>();
|
||||||
if (entry.type == ENTRY_TYPE_PLANNED_ACTIVITY) {
|
if (entry.type == ENTRY_TYPE_PLANNED_ACTIVITY) {
|
||||||
emit viewActivity(entry);
|
emit viewActivity(entry);
|
||||||
}
|
}
|
||||||
@@ -406,7 +406,7 @@ ActivityTree::setFutureDays
|
|||||||
|
|
||||||
void
|
void
|
||||||
ActivityTree::fillEntries
|
ActivityTree::fillEntries
|
||||||
(const QHash<QDate, QList<CalendarEntry>> &activities)
|
(const QHash<QDate, QList<AgendaEntry>> &activities)
|
||||||
{
|
{
|
||||||
QDate today = selectedDate();
|
QDate today = selectedDate();
|
||||||
QDate pastFirst = today.addDays(-pastDays);
|
QDate pastFirst = today.addDays(-pastDays);
|
||||||
@@ -417,13 +417,13 @@ ActivityTree::fillEntries
|
|||||||
bool todayHasPlanned = false;
|
bool todayHasPlanned = false;
|
||||||
QList<QDate> missedDays;
|
QList<QDate> missedDays;
|
||||||
QList<QDate> upcomingDays;
|
QList<QDate> upcomingDays;
|
||||||
QHash<QDate, QList<CalendarEntry>> missedEntries;
|
QHash<QDate, QList<AgendaEntry>> missedEntries;
|
||||||
QList<CalendarEntry> todayEntries;
|
QList<AgendaEntry> todayEntries;
|
||||||
QHash<QDate, QList<CalendarEntry>> upcomingEntries;
|
QHash<QDate, QList<AgendaEntry>> upcomingEntries;
|
||||||
for (QDate date = pastFirst; date <= futureLast; date = date.addDays(1)) {
|
for (QDate date = pastFirst; date <= futureLast; date = date.addDays(1)) {
|
||||||
QList<CalendarEntry> dateEntries;
|
QList<AgendaEntry> dateEntries;
|
||||||
dateEntries = activities.value(date);
|
dateEntries = activities.value(date);
|
||||||
for (const CalendarEntry &entry : dateEntries) {
|
for (const AgendaEntry &entry : dateEntries) {
|
||||||
if (entry.type == ENTRY_TYPE_PLANNED_ACTIVITY) {
|
if (entry.type == ENTRY_TYPE_PLANNED_ACTIVITY) {
|
||||||
if (date < today) {
|
if (date < today) {
|
||||||
if (! missedDays.contains(date)) {
|
if (! missedDays.contains(date)) {
|
||||||
@@ -547,29 +547,30 @@ ActivityTree::createContextMenu
|
|||||||
if (entryData.isNull()) {
|
if (entryData.isNull()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CalendarEntry entry = entryData.value<CalendarEntry>();
|
AgendaEntry entry = entryData.value<AgendaEntry>();
|
||||||
if (entry.type != ENTRY_TYPE_PLANNED_ACTIVITY) {
|
if (entry.type != ENTRY_TYPE_PLANNED_ACTIVITY) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
QMenu *contextMenu = new QMenu(this);
|
QMenu *contextMenu = new QMenu(this);
|
||||||
|
contextMenu->addAction(tr("View planned activity..."), this, [this, entry]() {
|
||||||
|
emit viewActivity(entry);
|
||||||
|
});
|
||||||
if (entry.hasTrainMode) {
|
if (entry.hasTrainMode) {
|
||||||
|
contextMenu->addSeparator();
|
||||||
contextMenu->addAction(tr("Show in train mode..."), this, [this, entry]() {
|
contextMenu->addAction(tr("Show in train mode..."), this, [this, entry]() {
|
||||||
emit showInTrainMode(entry);
|
emit showInTrainMode(entry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
contextMenu->addAction(tr("View planned activity..."), this, [this, entry]() {
|
|
||||||
emit viewActivity(entry);
|
|
||||||
});
|
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ActivityTree::addEntries
|
ActivityTree::addEntries
|
||||||
(const QDate &today, const QDate &date, const QList<CalendarEntry> &activities, QTreeWidgetItem *parent, const Fonts &fonts)
|
(const QDate &today, const QDate &date, const QList<AgendaEntry> &activities, QTreeWidgetItem *parent, const Fonts &fonts)
|
||||||
{
|
{
|
||||||
int activityIdx = 0;
|
int activityIdx = 0;
|
||||||
for (const CalendarEntry &activity : activities) {
|
for (const AgendaEntry &activity : activities) {
|
||||||
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
||||||
QString diffStr;
|
QString diffStr;
|
||||||
int diff = date.daysTo(today);
|
int diff = date.daysTo(today);
|
||||||
@@ -607,7 +608,7 @@ ActivityTree::addEntries
|
|||||||
|
|
||||||
void
|
void
|
||||||
PhaseTree::fillEntries
|
PhaseTree::fillEntries
|
||||||
(const std::pair<QList<CalendarEntry>, QList<CalendarEntry>> &phases)
|
(const std::pair<QList<AgendaEntry>, QList<AgendaEntry>> &phases)
|
||||||
{
|
{
|
||||||
QDate today = selectedDate();
|
QDate today = selectedDate();
|
||||||
if (! today.isValid()) {
|
if (! today.isValid()) {
|
||||||
@@ -665,7 +666,7 @@ PhaseTree::createContextMenu
|
|||||||
if (entryData.isNull()) {
|
if (entryData.isNull()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CalendarEntry entry = entryData.value<CalendarEntry>();
|
AgendaEntry entry = entryData.value<AgendaEntry>();
|
||||||
if (entry.type != ENTRY_TYPE_PHASE) {
|
if (entry.type != ENTRY_TYPE_PHASE) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -679,9 +680,9 @@ PhaseTree::createContextMenu
|
|||||||
|
|
||||||
void
|
void
|
||||||
PhaseTree::addEntries
|
PhaseTree::addEntries
|
||||||
(const QDate &today, const QList<CalendarEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts)
|
(const QDate &today, const QList<AgendaEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts)
|
||||||
{
|
{
|
||||||
for (const CalendarEntry &phase : phases) {
|
for (const AgendaEntry &phase : phases) {
|
||||||
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
||||||
QString diffStr;
|
QString diffStr;
|
||||||
int diffStart = today.daysTo(phase.spanStart);
|
int diffStart = today.daysTo(phase.spanStart);
|
||||||
@@ -760,7 +761,7 @@ PhaseTree::addEntries
|
|||||||
|
|
||||||
void
|
void
|
||||||
EventTree::fillEntries
|
EventTree::fillEntries
|
||||||
(const QHash<QDate, QList<CalendarEntry>> &events)
|
(const QHash<QDate, QList<AgendaEntry>> &events)
|
||||||
{
|
{
|
||||||
QDate today = selectedDate();
|
QDate today = selectedDate();
|
||||||
if (! today.isValid()) {
|
if (! today.isValid()) {
|
||||||
@@ -807,7 +808,7 @@ EventTree::createContextMenu
|
|||||||
if (entryData.isNull()) {
|
if (entryData.isNull()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CalendarEntry entry = entryData.value<CalendarEntry>();
|
AgendaEntry entry = entryData.value<AgendaEntry>();
|
||||||
if (entry.type != ENTRY_TYPE_EVENT) {
|
if (entry.type != ENTRY_TYPE_EVENT) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -821,10 +822,10 @@ EventTree::createContextMenu
|
|||||||
|
|
||||||
void
|
void
|
||||||
EventTree::addEntries
|
EventTree::addEntries
|
||||||
(const QDate &today, const QList<CalendarEntry> &events, QTreeWidgetItem *parent, const Fonts &fonts)
|
(const QDate &today, const QList<AgendaEntry> &events, QTreeWidgetItem *parent, const Fonts &fonts)
|
||||||
{
|
{
|
||||||
bool firstEntry = true;
|
bool firstEntry = true;
|
||||||
for (const CalendarEntry &event : events) {
|
for (const AgendaEntry &event : events) {
|
||||||
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
QTreeWidgetItem *entryItem = new QTreeWidgetItem();
|
||||||
int diffStart = today.daysTo(event.spanStart);
|
int diffStart = today.daysTo(event.spanStart);
|
||||||
QString diffStr;
|
QString diffStr;
|
||||||
@@ -899,16 +900,16 @@ AgendaView::AgendaView
|
|||||||
|
|
||||||
activityTree = new ActivityTree();
|
activityTree = new ActivityTree();
|
||||||
connect(activityTree, &ActivityTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
connect(activityTree, &ActivityTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
||||||
connect(activityTree, &ActivityTree::showInTrainMode, this, [this](const CalendarEntry &activity) { emit showInTrainMode(activity); });
|
connect(activityTree, &ActivityTree::showInTrainMode, this, [this](const AgendaEntry &activity) { emit showInTrainMode(activity); });
|
||||||
connect(activityTree, &ActivityTree::viewActivity, this, [this](const CalendarEntry &activity) { emit viewActivity(activity); });
|
connect(activityTree, &ActivityTree::viewActivity, this, [this](const AgendaEntry &activity) { emit viewActivity(activity); });
|
||||||
|
|
||||||
phaseTree = new PhaseTree();
|
phaseTree = new PhaseTree();
|
||||||
connect(phaseTree, &PhaseTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
connect(phaseTree, &PhaseTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
||||||
connect(phaseTree, &PhaseTree::editPhaseEntry, this, [this](const CalendarEntry &phase) { emit editPhaseEntry(phase); });
|
connect(phaseTree, &PhaseTree::editPhaseEntry, this, [this](const AgendaEntry &phase) { emit editPhaseEntry(phase); });
|
||||||
|
|
||||||
eventTree = new EventTree();
|
eventTree = new EventTree();
|
||||||
connect(eventTree, &EventTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
connect(eventTree, &EventTree::dayChanged, this, [this](const QDate &date) { emit dayChanged(date); });
|
||||||
connect(eventTree, &EventTree::editEventEntry, this, [this](const CalendarEntry &event) { emit editEventEntry(event); });
|
connect(eventTree, &EventTree::editEventEntry, this, [this](const AgendaEntry &event) { emit editEventEntry(event); });
|
||||||
|
|
||||||
QGridLayout* headLayout = new QGridLayout();
|
QGridLayout* headLayout = new QGridLayout();
|
||||||
headLayout->setColumnStretch(0, 1);
|
headLayout->setColumnStretch(0, 1);
|
||||||
@@ -965,7 +966,7 @@ AgendaView::setFutureDays
|
|||||||
|
|
||||||
void
|
void
|
||||||
AgendaView::fillEntries
|
AgendaView::fillEntries
|
||||||
(const QHash<QDate, QList<CalendarEntry>> &activities, std::pair<QList<CalendarEntry>, QList<CalendarEntry>> &phases , const QHash<QDate, QList<CalendarEntry>> &events, const QString &seasonName, bool isFiltered)
|
(const QHash<QDate, QList<AgendaEntry>> &activities, std::pair<QList<AgendaEntry>, QList<AgendaEntry>> &phases , const QHash<QDate, QList<AgendaEntry>> &events, const QString &seasonName, bool isFiltered)
|
||||||
{
|
{
|
||||||
if (! seasonName.isNull()) {
|
if (! seasonName.isNull()) {
|
||||||
seasonLabel->setText(tr("Season: %1").arg(seasonName));
|
seasonLabel->setText(tr("Season: %1").arg(seasonName));
|
||||||
|
|||||||
@@ -92,13 +92,13 @@ public:
|
|||||||
|
|
||||||
void setPastDays(int days);
|
void setPastDays(int days);
|
||||||
void setFutureDays(int days);
|
void setFutureDays(int days);
|
||||||
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activities);
|
void fillEntries(const QHash<QDate, QList<AgendaEntry>> &activities);
|
||||||
QDate firstVisibleDay() const;
|
QDate firstVisibleDay() const;
|
||||||
QDate lastVisibleDay() const;
|
QDate lastVisibleDay() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showInTrainMode(const CalendarEntry &activity);
|
void showInTrainMode(const AgendaEntry &activity);
|
||||||
void viewActivity(const CalendarEntry &activity);
|
void viewActivity(const AgendaEntry &activity);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QMenu *createContextMenu(const QModelIndex &index) override;
|
QMenu *createContextMenu(const QModelIndex &index) override;
|
||||||
@@ -107,7 +107,7 @@ private:
|
|||||||
int pastDays = 7;
|
int pastDays = 7;
|
||||||
int futureDays = 7;
|
int futureDays = 7;
|
||||||
|
|
||||||
void addEntries(const QDate &today, const QDate &date, const QList<CalendarEntry> &activities, QTreeWidgetItem *parent, const Fonts &fonts);
|
void addEntries(const QDate &today, const QDate &date, const QList<AgendaEntry> &activities, QTreeWidgetItem *parent, const Fonts &fonts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -115,16 +115,16 @@ class PhaseTree : public AgendaTree {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void fillEntries(const std::pair<QList<CalendarEntry>, QList<CalendarEntry>> &phases);
|
void fillEntries(const std::pair<QList<AgendaEntry>, QList<AgendaEntry>> &phases);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void editPhaseEntry(const CalendarEntry &entry);
|
void editPhaseEntry(const AgendaEntry &entry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QMenu *createContextMenu(const QModelIndex &index) override;
|
QMenu *createContextMenu(const QModelIndex &index) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addEntries(const QDate &today, const QList<CalendarEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts);
|
void addEntries(const QDate &today, const QList<AgendaEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -132,16 +132,16 @@ class EventTree : public AgendaTree {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &events);
|
void fillEntries(const QHash<QDate, QList<AgendaEntry>> &events);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void editEventEntry(const CalendarEntry &entry);
|
void editEventEntry(const AgendaEntry &entry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QMenu *createContextMenu(const QModelIndex &index);
|
virtual QMenu *createContextMenu(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addEntries(const QDate &today, const QList<CalendarEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts);
|
void addEntries(const QDate &today, const QList<AgendaEntry> &phases, QTreeWidgetItem *parent, const Fonts &fonts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ public:
|
|||||||
void setDateRange(const DateRange &dateRange);
|
void setDateRange(const DateRange &dateRange);
|
||||||
void setPastDays(int days);
|
void setPastDays(int days);
|
||||||
void setFutureDays(int days);
|
void setFutureDays(int days);
|
||||||
void fillEntries(const QHash<QDate, QList<CalendarEntry>> &activities, std::pair<QList<CalendarEntry>, QList<CalendarEntry>> &phases, const QHash<QDate, QList<CalendarEntry>> &events, const QString &seasonName, bool isFiltered);
|
void fillEntries(const QHash<QDate, QList<AgendaEntry>> &activities, std::pair<QList<AgendaEntry>, QList<AgendaEntry>> &phases, const QHash<QDate, QList<AgendaEntry>> &events, const QString &seasonName, bool isFiltered);
|
||||||
|
|
||||||
QDate firstVisibleDay() const;
|
QDate firstVisibleDay() const;
|
||||||
QDate lastVisibleDay() const;
|
QDate lastVisibleDay() const;
|
||||||
@@ -166,10 +166,10 @@ public slots:
|
|||||||
void setEventMaxTertiaryLines(int maxTertiaryLines);
|
void setEventMaxTertiaryLines(int maxTertiaryLines);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showInTrainMode(const CalendarEntry &activity);
|
void showInTrainMode(const AgendaEntry &activity);
|
||||||
void viewActivity(const CalendarEntry &activity);
|
void viewActivity(const AgendaEntry &activity);
|
||||||
void editPhaseEntry(const CalendarEntry &entry);
|
void editPhaseEntry(const AgendaEntry &entry);
|
||||||
void editEventEntry(const CalendarEntry &entry);
|
void editEventEntry(const AgendaEntry &entry);
|
||||||
void dayChanged(const QDate &date);
|
void dayChanged(const QDate &date);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -35,6 +35,22 @@
|
|||||||
#define ENTRY_TYPE_OTHER 99
|
#define ENTRY_TYPE_OTHER 99
|
||||||
|
|
||||||
|
|
||||||
|
struct AgendaEntry {
|
||||||
|
QString primary;
|
||||||
|
QStringList secondaryValues;
|
||||||
|
QStringList secondaryLabels;
|
||||||
|
QString tertiary;
|
||||||
|
QString iconFile;
|
||||||
|
QColor color;
|
||||||
|
QString reference;
|
||||||
|
QTime start;
|
||||||
|
int type = 0;
|
||||||
|
bool hasTrainMode = false;
|
||||||
|
QDate spanStart = QDate();
|
||||||
|
QDate spanEnd = QDate();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CalendarEntry {
|
struct CalendarEntry {
|
||||||
QString primary;
|
QString primary;
|
||||||
QString secondary;
|
QString secondary;
|
||||||
@@ -80,6 +96,7 @@ struct CalendarSummary {
|
|||||||
QList<std::pair<QString, QString>> keyValues;
|
QList<std::pair<QString, QString>> keyValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(AgendaEntry)
|
||||||
Q_DECLARE_METATYPE(CalendarEntry)
|
Q_DECLARE_METATYPE(CalendarEntry)
|
||||||
Q_DECLARE_METATYPE(CalendarEntryLayout)
|
Q_DECLARE_METATYPE(CalendarEntryLayout)
|
||||||
Q_DECLARE_METATYPE(CalendarDay)
|
Q_DECLARE_METATYPE(CalendarDay)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static bool toolTipHeadlineEntry(const QPoint &pos, QAbstractItemView *view, con
|
|||||||
static bool toolTipDayEntry(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day, int idx);
|
static bool toolTipDayEntry(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day, int idx);
|
||||||
static bool toolTipMore(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day);
|
static bool toolTipMore(const QPoint &pos, QAbstractItemView *view, const CalendarDay &day);
|
||||||
static QRect paintHeadline(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index, HitTester &headlineTester, const QString &dateFormat, int pressedEntryIdx, int leftMargin, int rightMargin, int topMargin, int lineSpacing, int radius);
|
static QRect paintHeadline(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index, HitTester &headlineTester, const QString &dateFormat, int pressedEntryIdx, int leftMargin, int rightMargin, int topMargin, int lineSpacing, int radius);
|
||||||
static void paintMetric(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label);
|
static int paintMetric(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label, bool first = true);
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1318,7 +1318,7 @@ AgendaEntryDelegate::paint
|
|||||||
if (column < 0) {
|
if (column < 0) {
|
||||||
column = index.column();
|
column = index.column();
|
||||||
}
|
}
|
||||||
CalendarEntry entry = index.data(EntryRole).value<CalendarEntry>();
|
AgendaEntry entry = index.data(EntryRole).value<AgendaEntry>();
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
@@ -1360,7 +1360,6 @@ AgendaEntryDelegate::paint
|
|||||||
QFontMetrics line1FM(line1Font);
|
QFontMetrics line1FM(line1Font);
|
||||||
const int lineSpacing = attributes.lineSpacing * dpiYFactor;
|
const int lineSpacing = attributes.lineSpacing * dpiYFactor;
|
||||||
const int lineHeight = line1FM.height();
|
const int lineHeight = line1FM.height();
|
||||||
// const int radius = 4 * dpiXFactor;
|
|
||||||
const int iconInnerSpacing = 4 * dpiXFactor;
|
const int iconInnerSpacing = 4 * dpiXFactor;
|
||||||
const int iconTextSpacing = attributes.iconTextSpacing * dpiXFactor;
|
const int iconTextSpacing = attributes.iconTextSpacing * dpiXFactor;
|
||||||
const int iconWidth = 2 * lineHeight + lineSpacing;
|
const int iconWidth = 2 * lineHeight + lineSpacing;
|
||||||
@@ -1396,9 +1395,16 @@ AgendaEntryDelegate::paint
|
|||||||
painter->setFont(line1Font);
|
painter->setFont(line1Font);
|
||||||
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, primary);
|
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, primary);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
if (! entry.secondary.isEmpty()) {
|
textRect.translate(0, lineHeight + lineSpacing);
|
||||||
textRect.translate(0, lineHeight + lineSpacing);
|
int advance = 0;
|
||||||
paintMetric(painter, textRect, secondaryWeight, secondaryMetricWeight, entry.secondary, entry.secondaryMetric);
|
for (int i = 0; i < entry.secondaryValues.count(); ++i) {
|
||||||
|
QString value = entry.secondaryValues[i];
|
||||||
|
QString label = entry.secondaryLabels.value(i, "");
|
||||||
|
textRect.setLeft(textRect.left() + advance);
|
||||||
|
if (textRect.width() <= 20 * dpiXFactor) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
advance = paintMetric(painter, textRect, secondaryWeight, secondaryMetricWeight, value, label, i == 0);
|
||||||
}
|
}
|
||||||
if (! entry.tertiary.isEmpty()) {
|
if (! entry.tertiary.isEmpty()) {
|
||||||
painter->save();
|
painter->save();
|
||||||
@@ -1447,7 +1453,7 @@ AgendaEntryDelegate::sizeHint
|
|||||||
if (! data.isNull()) {
|
if (! data.isNull()) {
|
||||||
const int lineSpacing = attributes.lineSpacing * dpiYFactor;
|
const int lineSpacing = attributes.lineSpacing * dpiYFactor;
|
||||||
const int lineHeight = option.fontMetrics.height();
|
const int lineHeight = option.fontMetrics.height();
|
||||||
CalendarEntry entry = data.value<CalendarEntry>();
|
AgendaEntry entry = data.value<AgendaEntry>();
|
||||||
int tertiaryHeight = 0;
|
int tertiaryHeight = 0;
|
||||||
if (! entry.tertiary.isEmpty()) {
|
if (! entry.tertiary.isEmpty()) {
|
||||||
const int iconWidth = 2 * lineHeight + lineSpacing;
|
const int iconWidth = 2 * lineHeight + lineSpacing;
|
||||||
@@ -1485,7 +1491,7 @@ AgendaEntryDelegate::hasToolTip
|
|||||||
if (! index.isValid()) {
|
if (! index.isValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CalendarEntry entry = index.data(EntryRole).value<CalendarEntry>();
|
AgendaEntry entry = index.data(EntryRole).value<AgendaEntry>();
|
||||||
QString text(entry.tertiary.trimmed());
|
QString text(entry.tertiary.trimmed());
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1872,24 +1878,41 @@ paintHeadline
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static int
|
||||||
paintMetric
|
paintMetric
|
||||||
(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label)
|
(QPainter *painter, const QRect &rect, const QFont::Weight &valueWeight, const QFont::Weight &labelWeight, const QString &value, const QString &label, bool first)
|
||||||
{
|
{
|
||||||
|
int advance = 0;
|
||||||
painter->save();
|
painter->save();
|
||||||
QFont font = painter->font();
|
QFont font = painter->font();
|
||||||
font.setWeight(valueWeight);
|
font.setWeight(valueWeight);
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
QFontMetrics valueFM(font);
|
QFontMetrics valueFM(font);
|
||||||
int valueWidth = valueFM.horizontalAdvance(value);
|
QString fullValue(value);
|
||||||
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, value);
|
if (! first) {
|
||||||
|
fullValue.prepend(" • ");
|
||||||
|
}
|
||||||
|
int valueWidth = valueFM.horizontalAdvance(fullValue);
|
||||||
|
advance += valueWidth;
|
||||||
|
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, fullValue);
|
||||||
if (! label.isEmpty()) {
|
if (! label.isEmpty()) {
|
||||||
QRect labelRect(rect);
|
QRect labelRect(rect);
|
||||||
labelRect.setX(rect.x() + valueWidth + valueFM.horizontalAdvance(" "));
|
int spaceAdvance = valueFM.horizontalAdvance(" ");
|
||||||
|
advance += spaceAdvance;
|
||||||
|
labelRect.setX(rect.x() + valueWidth + spaceAdvance);
|
||||||
font.setWeight(labelWeight);
|
font.setWeight(labelWeight);
|
||||||
QFontMetrics labelFM(font);
|
QFontMetrics labelFM(font);
|
||||||
|
int labelWidth;
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
|
if (labelWeight <= QFont::Light) {
|
||||||
|
QRect labelBounds = painter->boundingRect(labelRect, Qt::AlignLeft | Qt::AlignTop, label);
|
||||||
|
labelWidth = labelBounds.width();
|
||||||
|
} else {
|
||||||
|
labelWidth = labelFM.horizontalAdvance(label);
|
||||||
|
}
|
||||||
painter->drawText(labelRect, Qt::AlignLeft | Qt::AlignTop, label);
|
painter->drawText(labelRect, Qt::AlignLeft | Qt::AlignTop, label);
|
||||||
|
advance += labelWidth;
|
||||||
}
|
}
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
return advance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,18 +239,18 @@ class AgendaEntryDelegate : public QStyledItemDelegate {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
EntryRole = Qt::UserRole, // [CalendarEntry] Entry to be displayed
|
EntryRole = Qt::UserRole, // [AgendaEntry] Entry to be displayed
|
||||||
EntryDateRole // [bool] Date of the CalendarEntry
|
EntryDateRole // [bool] Date of the AgendaEntry
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Attributes {
|
struct Attributes {
|
||||||
QMargins padding; // Padding of the element
|
QMargins padding; // Padding of the element
|
||||||
QFont::Weight primaryWeight = QFont::Medium; // Primary row
|
QFont::Weight primaryWeight = QFont::Medium; // Primary row
|
||||||
QFont::Weight primaryHoverWeight = QFont::DemiBold; // Primary row (hovered)
|
QFont::Weight primaryHoverWeight = QFont::Medium; // Primary row (hovered)
|
||||||
QFont::Weight secondaryWeight = QFont::Light; // Secondary row
|
QFont::Weight secondaryWeight = QFont::Medium; // Secondary row
|
||||||
QFont::Weight secondaryHoverWeight = QFont::DemiBold; // Secondary row (hovered)
|
QFont::Weight secondaryHoverWeight = QFont::Medium; // Secondary row (hovered)
|
||||||
QFont::Weight secondaryMetricWeight = QFont::ExtraLight; // Metric in the secondary row
|
QFont::Weight secondaryMetricWeight = QFont::ExtraLight; // Metric in the secondary row
|
||||||
QFont::Weight secondaryMetricHoverWeight = QFont::Normal; // Metric in the secondary row (hovered)
|
QFont::Weight secondaryMetricHoverWeight = QFont::ExtraLight; // Metric in the secondary row (hovered)
|
||||||
int lineSpacing = 2; // Vertical spacing between primary and secondary row (dpiYFactor not applied)
|
int lineSpacing = 2; // Vertical spacing between primary and secondary row (dpiYFactor not applied)
|
||||||
int iconTextSpacing = 10; // Horizontal spacing between icon and text (dpiXFactor not applied)
|
int iconTextSpacing = 10; // Horizontal spacing between icon and text (dpiXFactor not applied)
|
||||||
float tertiaryDimLevel = 0.5; // Dimming amount for tertiary row
|
float tertiaryDimLevel = 0.5; // Dimming amount for tertiary row
|
||||||
|
|||||||
@@ -199,6 +199,7 @@ MultiMetricSelector::MultiMetricSelector
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
filterEdit = new QLineEdit();
|
filterEdit = new QLineEdit();
|
||||||
|
filterEdit->setClearButtonEnabled(true);
|
||||||
filterEdit->setPlaceholderText(tr("Filter..."));
|
filterEdit->setPlaceholderText(tr("Filter..."));
|
||||||
|
|
||||||
availList = new QListWidget();
|
availList = new QListWidget();
|
||||||
|
|||||||
Reference in New Issue
Block a user