aboutsummaryrefslogtreecommitdiff
path: root/src/downloadwidget.cpp
blob: 75ebf51a70cd3aeebe60100cf18d2ea17d1411eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "downloadwidget.h"

#include <QDesktopServices>
#include <QFileInfo>
#include <QUrl>
#include <QWebEngineDownloadItem>

DownloadWidget::DownloadWidget(QWebEngineDownloadItem *download,
                               QWidget *parent)
    : QFrame(parent), m_download(download) {
  setupUi(this);

  static QIcon openIcon(":/icons/eye-line.png");
  openButton->setIcon(openIcon);
  openButton->setEnabled(false);

  auto downloadFileName = m_download->downloadFileName();
  dstName->setText(QFileInfo(downloadFileName).fileName());

  auto url = m_download->url().toDisplayString();
  if (url.startsWith("data:")) {
    srcUrl->setText("data:...");
  } else {
    srcUrl->setText(url);
  }

  connect(openButton, &QPushButton::clicked, m_download, [this](bool) {
    if (m_download->state() == QWebEngineDownloadItem::DownloadCompleted) {
      QDesktopServices::openUrl(QUrl(m_download->downloadFileName()));
    }
  });

  connect(cancelButton, &QPushButton::clicked, m_download, [this](bool) {
    if (m_download->state() == QWebEngineDownloadItem::DownloadInProgress)
      m_download->cancel();
    else
      emit removeClicked(this);
  });

  connect(m_download, &QWebEngineDownloadItem::downloadProgress, this,
          &DownloadWidget::updateWidget);

  connect(m_download, &QWebEngineDownloadItem::stateChanged, this,
          &DownloadWidget::updateWidget);

  updateWidget();
}

void DownloadWidget::remove() {
  if (!isDownloading())
    emit removeClicked(this);
}

inline QString DownloadWidget::withUnit(qreal bytes) {
  if (bytes < (1 << 10))
    return tr("%L1 B").arg(bytes);
  else if (bytes < (1 << 20))
    return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2);
  else if (bytes < (1 << 30))
    return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2);
  else
    return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
}

bool DownloadWidget::isDownloading() {

  return m_download->state() == QWebEngineDownloadItem::DownloadInProgress;
}

void DownloadWidget::updateWidget() {
  qreal totalBytes = m_download->totalBytes();
  qreal receivedBytes = m_download->receivedBytes();
  qreal bytesPerSecond = receivedBytes / m_timeAdded.elapsed() * 1000;

  auto state = m_download->state();
  switch (state) {
  case QWebEngineDownloadItem::DownloadRequested:
    Q_UNREACHABLE();
    break;
  case QWebEngineDownloadItem::DownloadInProgress:
    if (totalBytes >= 0) {
      progressBar->setValue(qRound(100 * receivedBytes / totalBytes));
      progressBar->setDisabled(false);
      progressBar->setFormat(tr("%p% - %1 of %2 downloaded - %3/s")
                                 .arg(withUnit(receivedBytes),
                                      withUnit(totalBytes),
                                      withUnit(bytesPerSecond)));
    } else {
      progressBar->setValue(0);
      progressBar->setDisabled(false);
      progressBar->setFormat(
          tr("unknown size - %1 downloaded - %2/s")
              .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
    }
    openButton->setEnabled(false);
    break;
  case QWebEngineDownloadItem::DownloadCompleted:
    progressBar->setValue(100);
    progressBar->setDisabled(true);
    progressBar->setFormat(
        tr("completed - %1 downloaded - %2/s")
            .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
    openButton->setEnabled(true);
    break;
  case QWebEngineDownloadItem::DownloadCancelled:
    progressBar->setValue(0);
    progressBar->setDisabled(true);
    progressBar->setFormat(
        tr("cancelled - %1 downloaded - %2/s")
            .arg(withUnit(receivedBytes), withUnit(bytesPerSecond)));
    openButton->setEnabled(false);
    break;
  case QWebEngineDownloadItem::DownloadInterrupted:
    progressBar->setValue(0);
    progressBar->setDisabled(true);
    progressBar->setFormat(
        tr("interrupted: %1").arg(m_download->interruptReasonString()));
    openButton->setEnabled(false);
    break;
  }

  if (state == QWebEngineDownloadItem::DownloadInProgress) {
    static QIcon cancelIcon(":/icons/stop-line.png");
    cancelButton->setIcon(cancelIcon);
    cancelButton->setToolTip(tr("Stop downloading"));
  } else {
    static QIcon removeIcon(":/icons/close-fill.png");
    cancelButton->setIcon(removeIcon);
    cancelButton->setToolTip(tr("Remove from list"));
  }
}