diff --git a/src/contentmanagerdelegate.cpp b/src/contentmanagerdelegate.cpp index 60a55e4d..747e646d 100644 --- a/src/contentmanagerdelegate.cpp +++ b/src/contentmanagerdelegate.cpp @@ -84,7 +84,8 @@ void createCancelButton(QPainter *painter, const QRect& r) painter->setFont(oldFont); } -void createDownloadStats(QPainter *painter, QRect box, QString downloadSpeed, QString completedLength) +// Modified to draw three lines: download speed, completed length and estimated time remaining. +void createDownloadStats(QPainter *painter, QRect box, QString downloadSpeed, QString completedLength, QString timeRemaining) { QPen pen; int x = box.x(); @@ -95,10 +96,12 @@ void createDownloadStats(QPainter *painter, QRect box, QString downloadSpeed, QS painter->setPen(pen); auto oldFont = painter->font(); painter->setFont(QFont("Selawik", 8)); - QRect nRect(x - 20, y - 10, w, h); - painter->drawText(nRect,Qt::AlignCenter | Qt::AlignJustify, downloadSpeed); - QRect fRect(x - 20, y + 10, w, h); - painter->drawText(fRect,Qt::AlignCenter | Qt::AlignJustify, completedLength); + QRect speedRect(x - 20, y - 10, w, h); + painter->drawText(speedRect, Qt::AlignCenter | Qt::AlignJustify, downloadSpeed); + QRect completedRect(x - 20, y + 10, w, h); + painter->drawText(completedRect, Qt::AlignCenter | Qt::AlignJustify, completedLength); + QRect timeRect(x - 20, y + 30, w, h); + painter->drawText(timeRect, Qt::AlignCenter | Qt::AlignJustify, timeRemaining); painter->setFont(oldFont); } @@ -131,13 +134,15 @@ void showDownloadProgress(QPainter *painter, QRect box, const DownloadState& dow progress = -progress; auto completedLength = downloadInfo.completedLength; auto downloadSpeed = downloadInfo.getDownloadSpeed(); + auto timeRemaining = downloadInfo.getEstimatedTimeRemaining(); if (downloadInfo.getStatus() == DownloadState::PAUSED) { createResumeSymbol(painter, dcl.pauseResumeButtonRect); createCancelButton(painter, dcl.cancelButtonRect); } else if (downloadInfo.getStatus() == DownloadState::DOWNLOADING) { createPauseSymbol(painter, dcl.pauseResumeButtonRect); - createDownloadStats(painter, box, downloadSpeed, completedLength); + // Pass the estimated time remaining to display it + createDownloadStats(painter, box, downloadSpeed, completedLength, timeRemaining); } QPen pen; diff --git a/src/downloadmanagement.cpp b/src/downloadmanagement.cpp index 16a4f7cd..e66518a4 100644 --- a/src/downloadmanagement.cpp +++ b/src/downloadmanagement.cpp @@ -35,6 +35,23 @@ DownloadState::Status getDownloadStatus(QString status) return DownloadState::UNKNOWN; } +QString formatTimeRemaining(double seconds) +{ + int totalSec = int(seconds); + int hours = totalSec / 3600; + int minutes = (totalSec % 3600) / 60; + int secs = totalSec % 60; + if (hours > 0) + return QString("%1:%2:%3") + .arg(hours, 2, 10, QChar('0')) + .arg(minutes, 2, 10, QChar('0')) + .arg(secs, 2, 10, QChar('0')); + else + return QString("%1:%2") + .arg(minutes, 2, 10, QChar('0')) + .arg(secs, 2, 10, QChar('0')); +} + } // unnamed namespace bool DownloadState::isLateUpdateInfo(const DownloadInfo& info) const @@ -49,11 +66,17 @@ bool DownloadState::isLateUpdateInfo(const DownloadInfo& info) const void DownloadState::update(const DownloadInfo& info) { const auto completedBytes = info["completedLength"].toDouble(); - const double percentage = completedBytes / info["totalLength"].toDouble(); + const double totalBytes = info["totalLength"].toDouble(); + const double percentage = completedBytes / totalBytes; progress = QString::number(100 * percentage, 'g', 3).toDouble(); completedLength = convertToUnits(completedBytes); - downloadSpeed = convertToUnits(info["downloadSpeed"].toDouble()) + "/s"; + double speedVal = info["downloadSpeed"].toDouble(); + downloadSpeed = convertToUnits(speedVal) + "/s"; + // Compute estimated time remaining + double remainingSeconds = (speedVal > 0) ? ((totalBytes - completedBytes) / speedVal) : 0; + estimatedTimeRemaining = (speedVal > 0) ? formatTimeRemaining(remainingSeconds) + : "---"; if ( !isLateUpdateInfo(info) ) { status = getDownloadStatus(info["status"].toString()); } @@ -229,12 +252,20 @@ DownloadInfo DownloadManager::getDownloadInfo(QString bookId) const const auto d = mp_downloader->getDownload(b.getDownloadId()); d->updateStatus(true); + // Calculate estimated time remaining. + double total = d->getTotalLength(); + double completed = d->getCompletedLength(); + double speed = d->getDownloadSpeed(); // bytes per second + double remainingSeconds = (speed > 0) ? ((total - completed) / speed) : 0; + QString timeRemaining = (speed > 0) ? formatTimeRemaining(remainingSeconds) : "---"; + return { - { "status" , downloadStatus2QString(d->getStatus()) }, - { "completedLength" , QString::number(d->getCompletedLength()) }, - { "totalLength" , QString::number(d->getTotalLength()) }, - { "downloadSpeed" , QString::number(d->getDownloadSpeed()) }, - { "path" , QString::fromStdString(d->getPath()) } + { "status" , downloadStatus2QString(d->getStatus()) }, + { "completedLength" , QString::number(d->getCompletedLength()) }, + { "totalLength" , QString::number(d->getTotalLength()) }, + { "downloadSpeed" , QString::number(d->getDownloadSpeed()) }, + { "estimatedTimeRemaining", timeRemaining }, + { "path" , QString::fromStdString(d->getPath()) } }; } diff --git a/src/downloadmanagement.h b/src/downloadmanagement.h index 7e6cddd7..8ea0a7ba 100644 --- a/src/downloadmanagement.h +++ b/src/downloadmanagement.h @@ -79,6 +79,8 @@ class DownloadState double progress = 0; QString completedLength; + // New member for estimated time remaining + QString estimatedTimeRemaining; public: // functions void update(const DownloadInfo& info); @@ -96,6 +98,9 @@ class DownloadState // time in seconds since last update double timeSinceLastUpdate() const; + // Optional accessor: + QString getEstimatedTimeRemaining() const { return estimatedTimeRemaining; } + private: // data Status status = UNKNOWN; QString downloadSpeed;