#include "DownloadWidget.h" #include #include #include #include #include DownloadWidget::DownloadWidget(QWebEngineDownloadRequest *downloadReq) : QFrame(nullptr), download(downloadReq) { setFrameStyle(QFrame::StyledPanel | QFrame::Plain); setFrameShape(QFrame::NoFrame); auto *layout = new QHBoxLayout(this); layout->setContentsMargins(4, 2, 4, 2); layout->setSpacing(6); QString filename = downloadReq->downloadFileName(); if (filename.isEmpty()) { QString path = downloadReq->url().path(); filename = path.mid(path.lastIndexOf('/') + 1); if (filename.isEmpty()) { filename = "download"; } } filenameLabel = new QLabel(filename, this); filenameLabel->setMaximumWidth(250); progressBar = new QProgressBar(this); progressBar->setMinimum(0); progressBar->setMaximum(100); progressBar->setValue(0); progressBar->setTextVisible(false); progressBar->setFixedHeight(18); statusLabel = new QLabel("0%", this); statusLabel->setFixedWidth(80); statusLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); button = new QPushButton(QStringLiteral("\u2715"), this); button->setFixedSize(22, 22); button->setFlat(true); layout->addWidget(filenameLabel); layout->addWidget(progressBar, 1); layout->addWidget(statusLabel); layout->addWidget(button); connect(button, &QPushButton::clicked, this, &DownloadWidget::onButtonClicked); connect(download, &QWebEngineDownloadRequest::receivedBytesChanged, this, [this]() { onDownloadProgress(download->receivedBytes(), download->totalBytes()); }); connect(download, &QWebEngineDownloadRequest::totalBytesChanged, this, [this]() { onDownloadProgress(download->receivedBytes(), download->totalBytes()); }); connect(download, &QWebEngineDownloadRequest::stateChanged, this, &DownloadWidget::onStateChanged); connect(download, &QWebEngineDownloadRequest::isFinishedChanged, this, &DownloadWidget::onStateChanged); if (download->state() == QWebEngineDownloadRequest::DownloadInProgress || download->state() == QWebEngineDownloadRequest::DownloadCompleted) { onStateChanged(); } } bool DownloadWidget::isCompleted() const { auto state = download->state(); return state == QWebEngineDownloadRequest::DownloadCompleted || state == QWebEngineDownloadRequest::DownloadCancelled || state == QWebEngineDownloadRequest::DownloadInterrupted; } void DownloadWidget::onDownloadProgress(qint64 received, qint64 total) { if (total > 0) { int pct = qBound(0, static_cast(received * 100 / total), 100); progressBar->setValue(pct); statusLabel->setText(QString("%1%").arg(pct)); } else { progressBar->setValue(0); statusLabel->setText(formatSize(received) + " / ?"); } } void DownloadWidget::onStateChanged() { switch (download->state()) { case QWebEngineDownloadRequest::DownloadInProgress: statusLabel->setStyleSheet("color: inherit;"); button->setText(QStringLiteral("\u2715")); break; case QWebEngineDownloadRequest::DownloadCompleted: progressBar->setValue(100); statusLabel->setText("Complete"); statusLabel->setStyleSheet("color: green;"); button->setText("Dismiss"); break; case QWebEngineDownloadRequest::DownloadCancelled: statusLabel->setText("Cancelled"); statusLabel->setStyleSheet("color: orange;"); button->setText("Dismiss"); break; case QWebEngineDownloadRequest::DownloadInterrupted: statusLabel->setText("Failed"); statusLabel->setStyleSheet("color: red;"); button->setText("Dismiss"); break; default: break; } } void DownloadWidget::onButtonClicked() { if (download->state() == QWebEngineDownloadRequest::DownloadInProgress || download->state() == QWebEngineDownloadRequest::DownloadRequested) { download->cancel(); } else { emit removeRequested(this); } } QString DownloadWidget::formatSize(qint64 bytes) { if (bytes < 1024) { return QString("%1 B").arg(bytes); } if (bytes < 1024 * 1024) { return QString("%1 KB").arg(bytes / 1024); } if (bytes < 1024 * 1024 * 1024) { return QString("%1 MB").arg(bytes / (1024 * 1024)); } return QString("%1 GB").arg(bytes / (1024 * 1024 * 1024)); }