From 489aaf042bb7ebb0a329a8b1574373cc53b20c4b Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Wed, 7 Dec 2022 14:49:21 -0500 Subject: [PATCH] Improvements to daily overview dialog --- src/DailyOverviewDialog.cpp | 138 ++++++++++++++++++++++-------------- src/DailyOverviewDialog.h | 2 + 2 files changed, 88 insertions(+), 52 deletions(-) diff --git a/src/DailyOverviewDialog.cpp b/src/DailyOverviewDialog.cpp index 9182e4d..95372dd 100644 --- a/src/DailyOverviewDialog.cpp +++ b/src/DailyOverviewDialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "TimeEntry.h" @@ -59,57 +60,17 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointerhorizontalHeader()->setStretchLastSection(true); m_byProjectTable->setSelectionMode(QTableWidget::NoSelection); - auto updateData = [this] { - auto todaysTime = m_entries->constSliceByDate(QDateTime{m_day, QTime{}}, m_day.endOfDay()); - - m_totalTime->setText( - tr("Total time: ") - .append(QTime::fromMSecsSinceStartOfDay(std::accumulate(todaysTime.begin(), - todaysTime.end(), - 0, - [this](int a, const TimeEntry &b) -> int { - return a + b.start().msecsTo( - b.end().isValid() ? - b.end() : - m_manager->currentDateTime()); - })) - .toString(QStringLiteral("h:mm:ss")))); - - m_chronologicalTable->clearContents(); - m_chronologicalTable->setRowCount(TimeLight::rangeSize(todaysTime)); - for (auto [i, it] = std::tuple(m_chronologicalTable->rowCount() - 1, todaysTime.begin()); it != todaysTime.end(); - --i, ++it) - { - m_chronologicalTable->setItem(i, 0, new TimeTableItem{it->start()}); - m_chronologicalTable->setItem(i, 1, new TimeTableItem{it->end()}); - m_chronologicalTable->setItem(i, 2, new QTableWidgetItem{it->project().name()}); - } - - QHash msecsByProject; - for (const auto &t : todaysTime) - msecsByProject[t.project().id()] += t.start().msecsTo(t.end()); - m_byProjectTable->clearContents(); - m_byProjectTable->setRowCount(static_cast(msecsByProject.count())); - int _i = 0; - for (const auto &key : msecsByProject.keys()) - { - m_byProjectTable->setItem( - _i, - 0, - new QTableWidgetItem{ - QTime::fromMSecsSinceStartOfDay(msecsByProject[key]).toString(QStringLiteral("h:mm:ss"))}); - m_byProjectTable->setItem(_i, 1, new QTableWidgetItem{m_manager->projectName(key)}); - ++_i; - } - }; - updateData(); - auto datePicker = new QDateEdit{this}; datePicker->setDate(m_day); datePicker->setMaximumDate(m_manager->currentDateTime().date()); datePicker->setCalendarPopup(true); datePicker->setDisplayFormat(QStringLiteral("MMMM d, yyyy")); + m_loadingEntries = new QProgressBar{this}; + m_loadingEntries->setMinimum(0); + m_loadingEntries->setMaximum(0); + m_loadingEntries->setVisible(false); + auto today = new QPushButton{tr("Today"), this}; QIcon backIcon{QStringLiteral(":/icons/arrow-left.svg")}; @@ -123,6 +84,7 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointeraddWidget(m_totalTime); dayLayout->addStretch(); + dayLayout->addWidget(m_loadingEntries, 1); dayLayout->addWidget(today); dayLayout->addWidget(back); dayLayout->addWidget(datePicker); @@ -157,13 +119,57 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointeraddButton(tr("Refresh"), QDialogButtonBox::ButtonRole::ActionRole), &QPushButton::clicked, this, updateData); + auto reset = bb->addButton(tr("Refresh"), QDialogButtonBox::ButtonRole::ActionRole); m_layout->addWidget(bb, 0, Qt::AlignRight); - connect(bb, &QDialogButtonBox::accepted, this, &QDialog::close); - connect(breakdown, &QComboBox::currentIndexChanged, this, setProperTimeTable); - connect(datePicker, &QDateEdit::dateChanged, this, [this, updateData, forward, back, datePicker](const QDate &d) { - m_day = d; + auto updateTotalTime = [this] { + auto todaysTime = m_entries->constSliceByDate(QDateTime{m_day, QTime{}}, m_day.endOfDay()); + + m_totalTime->setText( + tr("Total time: ") + .append(QTime::fromMSecsSinceStartOfDay(std::accumulate(todaysTime.begin(), + todaysTime.end(), + 0, + [this](int a, const TimeEntry &b) -> int { + return a + b.start().msecsTo( + b.end().isValid() ? + b.end() : + m_manager->currentDateTime()); + })) + .toString(QStringLiteral("h:mm:ss")))); + }; + auto updateData = [this, datePicker, forward, back, today, reset, updateTotalTime] { + auto todaysTime = m_entries->constSliceByDate(QDateTime{m_day, QTime{}}, m_day.endOfDay()); + + updateTotalTime(); + + m_chronologicalTable->clearContents(); + m_chronologicalTable->setRowCount(TimeLight::rangeSize(todaysTime)); + for (auto [i, it] = std::tuple(m_chronologicalTable->rowCount() - 1, todaysTime.begin()); it != todaysTime.end(); + --i, ++it) + { + m_chronologicalTable->setItem(i, 0, new TimeTableItem{it->start()}); + m_chronologicalTable->setItem(i, 1, new TimeTableItem{it->end()}); + m_chronologicalTable->setItem(i, 2, new QTableWidgetItem{it->project().name()}); + } + + QHash msecsByProject; + for (const auto &t : todaysTime) + msecsByProject[t.project().id()] += t.start().msecsTo(t.end()); + m_byProjectTable->clearContents(); + m_byProjectTable->setRowCount(static_cast(msecsByProject.count())); + int _i = 0; + for (const auto &key : msecsByProject.keys()) + { + m_byProjectTable->setItem( + _i, + 0, + new QTableWidgetItem{ + QTime::fromMSecsSinceStartOfDay(msecsByProject[key]).toString(QStringLiteral("h:mm:ss"))}); + m_byProjectTable->setItem(_i, 1, new QTableWidgetItem{m_manager->projectName(key)}); + ++_i; + } + if (m_day == datePicker->maximumDate()) forward->setDisabled(true); else @@ -172,14 +178,42 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointersetDisabled(true); else back->setEnabled(true); - updateData(); - }); + datePicker->setEnabled(true); + today->setEnabled(true); + reset->setEnabled(true); + m_loadingEntries->setVisible(false); + }; + updateData(); + + auto totalTimeUpdater = new QTimer{this}; + totalTimeUpdater->setInterval(1000); + totalTimeUpdater->callOnTimeout(updateTotalTime); + totalTimeUpdater->start(); + + connect(bb, &QDialogButtonBox::accepted, this, &QDialog::close); + connect(breakdown, &QComboBox::currentIndexChanged, this, setProperTimeTable); + connect(datePicker, + &QDateEdit::dateChanged, + this, + [this, updateData, forward, back, datePicker, today, reset](const QDate &d) { + m_day = d; + + forward->setDisabled(true); + back->setDisabled(true); + datePicker->setDisabled(true); + today->setDisabled(true); + reset->setDisabled(true); + m_loadingEntries->setVisible(true); + + QThread::create([updateData] { updateData(); })->start(); + }); connect(back, &QPushButton::clicked, datePicker, [datePicker] { datePicker->setDate(datePicker->date().addDays(-1)); }); connect( forward, &QPushButton::clicked, datePicker, [datePicker] { datePicker->setDate(datePicker->date().addDays(1)); }); connect(today, &QPushButton::clicked, datePicker, [this, datePicker] { datePicker->setDate(m_manager->currentDateTime().date()); }); + connect(reset, &QPushButton::clicked, this, updateData); resize(600, 400); } diff --git a/src/DailyOverviewDialog.h b/src/DailyOverviewDialog.h index 52278ac..895135e 100644 --- a/src/DailyOverviewDialog.h +++ b/src/DailyOverviewDialog.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ class DailyOverviewDialog : public QDialog QLabel *m_totalTime; QTableWidget *m_chronologicalTable; QTableWidget *m_byProjectTable; + QProgressBar *m_loadingEntries; QVBoxLayout *m_layout; QDate m_day;