12 from PyQt6.QtCore import ( |
12 from PyQt6.QtCore import ( |
13 pyqtSlot, pyqtSignal, Qt, QTime, QUrl, QStandardPaths, QFileInfo, QDateTime |
13 pyqtSlot, pyqtSignal, Qt, QTime, QUrl, QStandardPaths, QFileInfo, QDateTime |
14 ) |
14 ) |
15 from PyQt6.QtGui import QPalette, QDesktopServices |
15 from PyQt6.QtGui import QPalette, QDesktopServices |
16 from PyQt6.QtWidgets import QWidget, QStyle, QDialog |
16 from PyQt6.QtWidgets import QWidget, QStyle, QDialog |
17 from PyQt6.QtWebEngineCore import QWebEngineDownloadItem |
17 from PyQt6.QtWebEngineCore import QWebEngineDownloadRequest |
18 |
18 |
19 from EricWidgets import EricFileDialog |
19 from EricWidgets import EricFileDialog |
20 |
20 |
21 from .Ui_DownloadItem import Ui_DownloadItem |
21 from .Ui_DownloadItem import Ui_DownloadItem |
22 |
22 |
37 """ |
37 """ |
38 statusChanged = pyqtSignal() |
38 statusChanged = pyqtSignal() |
39 downloadFinished = pyqtSignal(bool) |
39 downloadFinished = pyqtSignal(bool) |
40 progress = pyqtSignal(int, int) |
40 progress = pyqtSignal(int, int) |
41 |
41 |
|
42 # TODO: convert this to an enum |
42 Downloading = 0 |
43 Downloading = 0 |
43 DownloadSuccessful = 1 |
44 DownloadSuccessful = 1 |
44 DownloadCancelled = 2 |
45 DownloadCancelled = 2 |
45 |
46 |
46 def __init__(self, downloadItem=None, pageUrl=None, parent=None): |
47 def __init__(self, downloadRequest=None, pageUrl=None, parent=None): |
47 """ |
48 """ |
48 Constructor |
49 Constructor |
49 |
50 |
50 @param downloadItem reference to the download object containing the |
51 @param downloadRequest reference to the download object containing the |
51 download data. |
52 download data. |
52 @type QWebEngineDownloadItem |
53 @type QWebEngineDownloadRequest |
53 @param pageUrl URL of the calling page |
54 @param pageUrl URL of the calling page |
54 @type QUrl |
55 @type QUrl |
55 @param parent reference to the parent widget |
56 @param parent reference to the parent widget |
56 @type QWidget |
57 @type QWidget |
57 """ |
58 """ |
67 self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause")) |
68 self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause")) |
68 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading")) |
69 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading")) |
69 self.openButton.setIcon(UI.PixmapCache.getIcon("open")) |
70 self.openButton.setIcon(UI.PixmapCache.getIcon("open")) |
70 self.openButton.setEnabled(False) |
71 self.openButton.setEnabled(False) |
71 self.openButton.setVisible(False) |
72 self.openButton.setVisible(False) |
72 if not hasattr(QWebEngineDownloadItem, "pause"): |
|
73 # pause/resume was defined in Qt 5.10.0 / PyQt 5.10.0 |
|
74 self.pauseButton.setEnabled(False) |
|
75 self.pauseButton.setVisible(False) |
|
76 |
73 |
77 self.__state = DownloadItem.Downloading |
74 self.__state = DownloadItem.Downloading |
78 |
75 |
79 icon = self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) |
76 icon = self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) |
80 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
77 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
81 |
78 |
82 self.__downloadItem = downloadItem |
79 self.__downloadRequest = downloadRequest |
83 if pageUrl is None: |
80 if pageUrl is None: |
84 self.__pageUrl = QUrl() |
81 self.__pageUrl = QUrl() |
85 else: |
82 else: |
86 self.__pageUrl = pageUrl |
83 self.__pageUrl = pageUrl |
87 self.__bytesReceived = 0 |
84 self.__bytesReceived = 0 |
99 |
96 |
100 def __initialize(self): |
97 def __initialize(self): |
101 """ |
98 """ |
102 Private method to initialize the widget. |
99 Private method to initialize the widget. |
103 """ |
100 """ |
104 if self.__downloadItem is None: |
101 if self.__downloadRequest is None: |
105 return |
102 return |
106 |
103 |
107 self.__finishedDownloading = False |
104 self.__finishedDownloading = False |
108 self.__bytesReceived = 0 |
105 self.__bytesReceived = 0 |
109 self.__bytesTotal = -1 |
106 self.__bytesTotal = -1 |
110 |
107 |
111 # start timer for the download estimation |
108 # start timer for the download estimation |
112 self.__downloadTime = QTime.currentTime() |
109 self.__downloadTime = QTime.currentTime() |
113 |
110 |
114 # attach to the download item object |
111 # attach to the download item object |
115 self.__url = self.__downloadItem.url() |
112 self.__url = self.__downloadRequest.url() |
116 self.__downloadItem.downloadProgress.connect(self.__downloadProgress) |
113 self.__downloadRequest.receivedBytesChanged.connect(self.__downloadProgress) |
117 self.__downloadItem.finished.connect(self.__finished) |
114 self.__downloadRequest.isFinishedChanged.connect(self.__finished) |
118 |
115 |
119 # reset info |
116 # reset info |
120 self.datetimeLabel.clear() |
117 self.datetimeLabel.clear() |
121 self.datetimeLabel.hide() |
118 self.datetimeLabel.hide() |
122 self.infoLabel.clear() |
119 self.infoLabel.clear() |
123 self.progressBar.setValue(0) |
120 self.progressBar.setValue(0) |
124 if ( |
121 if ( |
125 self.__downloadItem.state() == |
122 self.__downloadRequest.state() == |
126 QWebEngineDownloadItem.DownloadState.DownloadRequested |
123 QWebEngineDownloadRequest.DownloadState.DownloadRequested |
127 ): |
124 ): |
128 self.__getFileName() |
125 self.__getFileName() |
129 if not self.__fileName: |
126 if not self.__fileName: |
130 self.__downloadItem.cancel() |
127 self.__downloadRequest.cancel() |
131 else: |
128 else: |
132 self.__downloadItem.setPath(self.__fileName) |
129 self.__downloadRequest.setDownloadFileName(self.__fileName) |
133 self.__downloadItem.accept() |
130 self.__downloadRequest.accept() |
134 else: |
131 else: |
135 fileName = self.__downloadItem.path() |
132 fileName = self.__downloadRequest.downloadFileName() |
136 self.__setFileName(fileName) |
133 self.__setFileName(fileName) |
137 |
134 |
138 def __getFileName(self): |
135 def __getFileName(self): |
139 """ |
136 """ |
140 Private method to get the file name to save to from the user. |
137 Private method to get the file name to save to from the user. |
141 """ |
138 """ |
142 if self.__gettingFileName: |
139 if self.__gettingFileName: |
143 return |
140 return |
144 |
141 |
145 savePage = self.__downloadItem.type() == ( |
142 savePage = self.__downloadRequest.isSavePageDownload() |
146 QWebEngineDownloadItem.DownloadType.SavePage |
|
147 ) |
|
148 |
143 |
149 documentLocation = QStandardPaths.writableLocation( |
144 documentLocation = QStandardPaths.writableLocation( |
150 QStandardPaths.StandardLocation.DocumentsLocation) |
145 QStandardPaths.StandardLocation.DocumentsLocation) |
151 downloadDirectory = ( |
146 downloadDirectory = ( |
152 WebBrowserWindow.downloadManager().downloadDirectory() |
147 WebBrowserWindow.downloadManager().downloadDirectory() |
165 ask = True |
160 ask = True |
166 self.__autoOpen = False |
161 self.__autoOpen = False |
167 |
162 |
168 if not savePage: |
163 if not savePage: |
169 from .DownloadAskActionDialog import DownloadAskActionDialog |
164 from .DownloadAskActionDialog import DownloadAskActionDialog |
170 url = self.__downloadItem.url() |
165 url = self.__downloadRequest.url() |
171 mimetype = Utilities.MimeTypes.mimeType(originalFileName) |
166 mimetype = Utilities.MimeTypes.mimeType(originalFileName) |
172 dlg = DownloadAskActionDialog( |
167 dlg = DownloadAskActionDialog( |
173 QFileInfo(originalFileName).fileName(), |
168 QFileInfo(originalFileName).fileName(), |
174 mimetype, |
169 mimetype, |
175 "{0}://{1}".format(url.scheme(), url.authority()), |
170 "{0}://{1}".format(url.scheme(), url.authority()), |
264 Private method to calculate a name for the file to download. |
259 Private method to calculate a name for the file to download. |
265 |
260 |
266 @param directory name of the directory to store the file into (string) |
261 @param directory name of the directory to store the file into (string) |
267 @return proposed filename and original filename (string, string) |
262 @return proposed filename and original filename (string, string) |
268 """ |
263 """ |
269 path = self.__downloadItem.path() |
264 path = self.__downloadRequest.downloadFileName() |
270 info = QFileInfo(path) |
265 info = QFileInfo(path) |
271 baseName = info.completeBaseName() |
266 baseName = info.completeBaseName() |
272 endName = info.suffix() |
267 endName = info.suffix() |
273 |
268 |
274 origName = baseName |
269 origName = baseName |
311 self.openButton.setVisible(False) |
306 self.openButton.setVisible(False) |
312 self.pauseButton.setEnabled(False) |
307 self.pauseButton.setEnabled(False) |
313 self.pauseButton.setVisible(False) |
308 self.pauseButton.setVisible(False) |
314 self.setUpdatesEnabled(True) |
309 self.setUpdatesEnabled(True) |
315 self.__state = DownloadItem.DownloadCancelled |
310 self.__state = DownloadItem.DownloadCancelled |
316 self.__downloadItem.cancel() |
311 self.__downloadRequest.cancel() |
317 self.__setDateTime() |
312 self.__setDateTime() |
318 self.downloadFinished.emit(False) |
313 self.downloadFinished.emit(False) |
319 |
314 |
320 @pyqtSlot() |
315 @pyqtSlot() |
321 def on_openButton_clicked(self): |
316 def on_openButton_clicked(self): |
338 """ |
333 """ |
339 info = QFileInfo(self.__fileName) |
334 info = QFileInfo(self.__fileName) |
340 url = QUrl.fromLocalFile(info.absolutePath()) |
335 url = QUrl.fromLocalFile(info.absolutePath()) |
341 QDesktopServices.openUrl(url) |
336 QDesktopServices.openUrl(url) |
342 |
337 |
343 def __downloadProgress(self, bytesReceived, bytesTotal): |
338 @pyqtSlot() |
344 """ |
339 def __downloadProgress(self): |
345 Private method to show the download progress. |
340 """ |
346 |
341 Private slot to show the download progress. |
347 @param bytesReceived number of bytes received (integer) |
342 """ |
348 @param bytesTotal number of total bytes (integer) |
343 self.__bytesReceived = self.__downloadRequest.receivedBytes() |
349 """ |
344 self.__bytesTotal = self.__downloadRequest.totalBytes() |
350 self.__bytesReceived = bytesReceived |
|
351 self.__bytesTotal = bytesTotal |
|
352 currentValue = 0 |
345 currentValue = 0 |
353 totalValue = 0 |
346 totalValue = 0 |
354 if bytesTotal > 0: |
347 if self.__bytesTotal > 0: |
355 currentValue = bytesReceived * 100 / bytesTotal |
348 currentValue = self.__bytesReceived * 100 / self.__bytesTotal |
356 totalValue = 100 |
349 totalValue = 100 |
357 self.progressBar.setValue(currentValue) |
350 self.progressBar.setValue(currentValue) |
358 self.progressBar.setMaximum(totalValue) |
351 self.progressBar.setMaximum(totalValue) |
359 |
352 |
360 self.progress.emit(currentValue, totalValue) |
353 self.progress.emit(currentValue, totalValue) |
374 Public method to get the total number of bytes of the download. |
367 Public method to get the total number of bytes of the download. |
375 |
368 |
376 @return total number of bytes (integer) |
369 @return total number of bytes (integer) |
377 """ |
370 """ |
378 if self.__bytesTotal == -1: |
371 if self.__bytesTotal == -1: |
379 self.__bytesTotal = self.__downloadItem.totalBytes() |
372 self.__bytesTotal = self.__downloadRequest.totalBytes() |
380 return self.__bytesTotal |
373 return self.__bytesTotal |
381 |
374 |
382 def bytesReceived(self): |
375 def bytesReceived(self): |
383 """ |
376 """ |
384 Public method to get the number of bytes received. |
377 Public method to get the number of bytes received. |
492 """ |
485 """ |
493 Private slot to handle the download finished. |
486 Private slot to handle the download finished. |
494 """ |
487 """ |
495 self.__finishedDownloading = True |
488 self.__finishedDownloading = True |
496 |
489 |
497 noError = (self.__downloadItem.state() == |
490 noError = (self.__downloadRequest.state() == |
498 QWebEngineDownloadItem.DownloadState.DownloadCompleted) |
491 QWebEngineDownloadRequest.DownloadState.DownloadCompleted) |
499 |
492 |
500 self.progressBar.setVisible(False) |
493 self.progressBar.setVisible(False) |
501 self.pauseButton.setEnabled(False) |
494 self.pauseButton.setEnabled(False) |
502 self.pauseButton.setVisible(False) |
495 self.pauseButton.setVisible(False) |
503 self.stopButton.setEnabled(False) |
496 self.stopButton.setEnabled(False) |