32 |
30 |
33 class DownloadState(enum.Enum): |
31 class DownloadState(enum.Enum): |
34 """ |
32 """ |
35 Class implementing the various download states. |
33 Class implementing the various download states. |
36 """ |
34 """ |
|
35 |
37 Downloading = 0 |
36 Downloading = 0 |
38 Successful = 1 |
37 Successful = 1 |
39 Cancelled = 2 |
38 Cancelled = 2 |
40 |
39 |
41 |
40 |
42 class DownloadItem(QWidget, Ui_DownloadItem): |
41 class DownloadItem(QWidget, Ui_DownloadItem): |
43 """ |
42 """ |
44 Class implementing a widget controlling a download. |
43 Class implementing a widget controlling a download. |
45 |
44 |
46 @signal statusChanged() emitted upon a status change of a download |
45 @signal statusChanged() emitted upon a status change of a download |
47 @signal downloadFinished(success) emitted when a download finished |
46 @signal downloadFinished(success) emitted when a download finished |
48 @signal progress(int, int) emitted to signal the download progress |
47 @signal progress(int, int) emitted to signal the download progress |
49 """ |
48 """ |
|
49 |
50 statusChanged = pyqtSignal() |
50 statusChanged = pyqtSignal() |
51 downloadFinished = pyqtSignal(bool) |
51 downloadFinished = pyqtSignal(bool) |
52 progress = pyqtSignal(int, int) |
52 progress = pyqtSignal(int, int) |
53 |
53 |
54 def __init__(self, downloadRequest=None, pageUrl=None, parent=None): |
54 def __init__(self, downloadRequest=None, pageUrl=None, parent=None): |
55 """ |
55 """ |
56 Constructor |
56 Constructor |
57 |
57 |
58 @param downloadRequest reference to the download object containing the |
58 @param downloadRequest reference to the download object containing the |
59 download data. |
59 download data. |
60 @type QWebEngineDownloadRequest |
60 @type QWebEngineDownloadRequest |
61 @param pageUrl URL of the calling page |
61 @param pageUrl URL of the calling page |
62 @type QUrl |
62 @type QUrl |
63 @param parent reference to the parent widget |
63 @param parent reference to the parent widget |
64 @type QWidget |
64 @type QWidget |
65 """ |
65 """ |
66 super().__init__(parent) |
66 super().__init__(parent) |
67 self.setupUi(self) |
67 self.setupUi(self) |
68 |
68 |
69 self.fileIcon.setStyleSheet("background-color: transparent") |
69 self.fileIcon.setStyleSheet("background-color: transparent") |
70 self.datetimeLabel.setStyleSheet("background-color: transparent") |
70 self.datetimeLabel.setStyleSheet("background-color: transparent") |
71 self.filenameLabel.setStyleSheet("background-color: transparent") |
71 self.filenameLabel.setStyleSheet("background-color: transparent") |
72 if ericApp().usesDarkPalette(): |
72 if ericApp().usesDarkPalette(): |
73 self.infoLabel.setStyleSheet( |
73 self.infoLabel.setStyleSheet( |
74 "color: #c0c0c0; background-color: transparent" |
74 "color: #c0c0c0; background-color: transparent" |
75 ) # light gray |
75 ) # light gray |
76 else: |
76 else: |
77 self.infoLabel.setStyleSheet( |
77 self.infoLabel.setStyleSheet( |
78 "color: #808080; background-color: transparent" |
78 "color: #808080; background-color: transparent" |
79 ) # dark gray |
79 ) # dark gray |
80 |
80 |
81 self.progressBar.setMaximum(0) |
81 self.progressBar.setMaximum(0) |
82 |
82 |
83 self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause")) |
83 self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause")) |
84 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading")) |
84 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading")) |
85 self.openButton.setIcon(UI.PixmapCache.getIcon("open")) |
85 self.openButton.setIcon(UI.PixmapCache.getIcon("open")) |
86 self.openButton.setEnabled(False) |
86 self.openButton.setEnabled(False) |
87 self.openButton.setVisible(False) |
87 self.openButton.setVisible(False) |
88 |
88 |
89 self.__state = DownloadState.Downloading |
89 self.__state = DownloadState.Downloading |
90 |
90 |
91 icon = self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) |
91 icon = self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon) |
92 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
92 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
93 |
93 |
94 self.__downloadRequest = downloadRequest |
94 self.__downloadRequest = downloadRequest |
95 if pageUrl is None: |
95 if pageUrl is None: |
96 self.__pageUrl = QUrl() |
96 self.__pageUrl = QUrl() |
97 else: |
97 else: |
98 self.__pageUrl = pageUrl |
98 self.__pageUrl = pageUrl |
104 self.__finishedDownloading = False |
104 self.__finishedDownloading = False |
105 self.__gettingFileName = False |
105 self.__gettingFileName = False |
106 self.__canceledFileSelect = False |
106 self.__canceledFileSelect = False |
107 self.__autoOpen = False |
107 self.__autoOpen = False |
108 self.__downloadedDateTime = QDateTime() |
108 self.__downloadedDateTime = QDateTime() |
109 |
109 |
110 self.__initialize() |
110 self.__initialize() |
111 |
111 |
112 def __initialize(self): |
112 def __initialize(self): |
113 """ |
113 """ |
114 Private method to initialize the widget. |
114 Private method to initialize the widget. |
115 """ |
115 """ |
116 if self.__downloadRequest is None: |
116 if self.__downloadRequest is None: |
117 return |
117 return |
118 |
118 |
119 self.__finishedDownloading = False |
119 self.__finishedDownloading = False |
120 self.__bytesReceived = 0 |
120 self.__bytesReceived = 0 |
121 self.__bytesTotal = -1 |
121 self.__bytesTotal = -1 |
122 |
122 |
123 # start timer for the download estimation |
123 # start timer for the download estimation |
124 self.__downloadTime = QTime.currentTime() |
124 self.__downloadTime = QTime.currentTime() |
125 |
125 |
126 # attach to the download item object |
126 # attach to the download item object |
127 self.__url = self.__downloadRequest.url() |
127 self.__url = self.__downloadRequest.url() |
128 self.__downloadRequest.receivedBytesChanged.connect( |
128 self.__downloadRequest.receivedBytesChanged.connect(self.__downloadProgress) |
129 self.__downloadProgress) |
|
130 self.__downloadRequest.isFinishedChanged.connect(self.__finished) |
129 self.__downloadRequest.isFinishedChanged.connect(self.__finished) |
131 |
130 |
132 # reset info |
131 # reset info |
133 self.datetimeLabel.clear() |
132 self.datetimeLabel.clear() |
134 self.datetimeLabel.hide() |
133 self.datetimeLabel.hide() |
135 self.infoLabel.clear() |
134 self.infoLabel.clear() |
136 self.progressBar.setValue(0) |
135 self.progressBar.setValue(0) |
137 if ( |
136 if ( |
138 self.__downloadRequest.state() == |
137 self.__downloadRequest.state() |
139 QWebEngineDownloadRequest.DownloadState.DownloadRequested |
138 == QWebEngineDownloadRequest.DownloadState.DownloadRequested |
140 ): |
139 ): |
141 self.__getFileName() |
140 self.__getFileName() |
142 if not self.__fileName: |
141 if not self.__fileName: |
143 self.__downloadRequest.cancel() |
142 self.__downloadRequest.cancel() |
144 else: |
143 else: |
145 self.__downloadRequest.setDownloadFileName(self.__fileName) |
144 self.__downloadRequest.setDownloadFileName(self.__fileName) |
146 self.__downloadRequest.accept() |
145 self.__downloadRequest.accept() |
147 else: |
146 else: |
148 fileName = self.__downloadRequest.downloadFileName() |
147 fileName = self.__downloadRequest.downloadFileName() |
149 self.__setFileName(fileName) |
148 self.__setFileName(fileName) |
150 |
149 |
151 def __getFileName(self): |
150 def __getFileName(self): |
152 """ |
151 """ |
153 Private method to get the file name to save to from the user. |
152 Private method to get the file name to save to from the user. |
154 """ |
153 """ |
155 if self.__gettingFileName: |
154 if self.__gettingFileName: |
156 return |
155 return |
157 |
156 |
158 savePage = self.__downloadRequest.isSavePageDownload() |
157 savePage = self.__downloadRequest.isSavePageDownload() |
159 |
158 |
160 documentLocation = QStandardPaths.writableLocation( |
159 documentLocation = QStandardPaths.writableLocation( |
161 QStandardPaths.StandardLocation.DocumentsLocation) |
160 QStandardPaths.StandardLocation.DocumentsLocation |
162 downloadDirectory = ( |
|
163 WebBrowserWindow.downloadManager().downloadDirectory() |
|
164 ) |
161 ) |
165 |
162 downloadDirectory = WebBrowserWindow.downloadManager().downloadDirectory() |
|
163 |
166 if self.__fileName: |
164 if self.__fileName: |
167 fileName = self.__fileName |
165 fileName = self.__fileName |
168 originalFileName = self.__originalFileName |
166 originalFileName = self.__originalFileName |
169 self.__toDownload = True |
167 self.__toDownload = True |
170 ask = False |
168 ask = False |
171 else: |
169 else: |
172 defaultFileName, originalFileName = self.__saveFileName( |
170 defaultFileName, originalFileName = self.__saveFileName( |
173 documentLocation if savePage else downloadDirectory) |
171 documentLocation if savePage else downloadDirectory |
|
172 ) |
174 fileName = defaultFileName |
173 fileName = defaultFileName |
175 self.__originalFileName = originalFileName |
174 self.__originalFileName = originalFileName |
176 ask = True |
175 ask = True |
177 self.__autoOpen = False |
176 self.__autoOpen = False |
178 |
177 |
179 if not savePage: |
178 if not savePage: |
180 from .DownloadAskActionDialog import DownloadAskActionDialog |
179 from .DownloadAskActionDialog import DownloadAskActionDialog |
|
180 |
181 url = self.__downloadRequest.url() |
181 url = self.__downloadRequest.url() |
182 mimetype = Utilities.MimeTypes.mimeType(originalFileName) |
182 mimetype = Utilities.MimeTypes.mimeType(originalFileName) |
183 dlg = DownloadAskActionDialog( |
183 dlg = DownloadAskActionDialog( |
184 pathlib.Path(originalFileName).name, |
184 pathlib.Path(originalFileName).name, |
185 mimetype, |
185 mimetype, |
186 "{0}://{1}".format(url.scheme(), url.authority()), |
186 "{0}://{1}".format(url.scheme(), url.authority()), |
187 self) |
187 self, |
188 |
188 ) |
189 if ( |
189 |
190 dlg.exec() == QDialog.DialogCode.Rejected or |
190 if dlg.exec() == QDialog.DialogCode.Rejected or dlg.getAction() == "cancel": |
191 dlg.getAction() == "cancel" |
|
192 ): |
|
193 self.progressBar.setVisible(False) |
191 self.progressBar.setVisible(False) |
194 self.on_stopButton_clicked() |
192 self.on_stopButton_clicked() |
195 self.filenameLabel.setText( |
193 self.filenameLabel.setText( |
196 self.tr("Download canceled: {0}").format( |
194 self.tr("Download canceled: {0}").format( |
197 pathlib.Path(defaultFileName).name)) |
195 pathlib.Path(defaultFileName).name |
|
196 ) |
|
197 ) |
198 self.__canceledFileSelect = True |
198 self.__canceledFileSelect = True |
199 self.__setDateTime() |
199 self.__setDateTime() |
200 return |
200 return |
201 |
201 |
202 if dlg.getAction() == "scan": |
202 if dlg.getAction() == "scan": |
203 self.__mainWindow.requestVirusTotalScan(url) |
203 self.__mainWindow.requestVirusTotalScan(url) |
204 |
204 |
205 self.progressBar.setVisible(False) |
205 self.progressBar.setVisible(False) |
206 self.on_stopButton_clicked() |
206 self.on_stopButton_clicked() |
207 self.filenameLabel.setText( |
207 self.filenameLabel.setText( |
208 self.tr("VirusTotal scan scheduled: {0}").format( |
208 self.tr("VirusTotal scan scheduled: {0}").format( |
209 pathlib.Path(defaultFileName).name)) |
209 pathlib.Path(defaultFileName).name |
|
210 ) |
|
211 ) |
210 self.__canceledFileSelect = True |
212 self.__canceledFileSelect = True |
211 return |
213 return |
212 |
214 |
213 self.__autoOpen = dlg.getAction() == "open" |
215 self.__autoOpen = dlg.getAction() == "open" |
214 |
216 |
215 tempLocation = QStandardPaths.writableLocation( |
217 tempLocation = QStandardPaths.writableLocation( |
216 QStandardPaths.StandardLocation.TempLocation) |
218 QStandardPaths.StandardLocation.TempLocation |
217 fileName = ( |
|
218 tempLocation + '/' + |
|
219 pathlib.Path(fileName).stem |
|
220 ) |
219 ) |
221 |
220 fileName = tempLocation + "/" + pathlib.Path(fileName).stem |
|
221 |
222 if ask and not self.__autoOpen: |
222 if ask and not self.__autoOpen: |
223 self.__gettingFileName = True |
223 self.__gettingFileName = True |
224 fileName = EricFileDialog.getSaveFileName( |
224 fileName = EricFileDialog.getSaveFileName( |
225 None, |
225 None, self.tr("Save File"), defaultFileName, "" |
226 self.tr("Save File"), |
226 ) |
227 defaultFileName, |
|
228 "") |
|
229 self.__gettingFileName = False |
227 self.__gettingFileName = False |
230 |
228 |
231 if not fileName: |
229 if not fileName: |
232 self.progressBar.setVisible(False) |
230 self.progressBar.setVisible(False) |
233 self.on_stopButton_clicked() |
231 self.on_stopButton_clicked() |
234 self.filenameLabel.setText( |
232 self.filenameLabel.setText( |
235 self.tr("Download canceled: {0}") |
233 self.tr("Download canceled: {0}").format( |
236 .format(pathlib.Path(defaultFileName).name)) |
234 pathlib.Path(defaultFileName).name |
|
235 ) |
|
236 ) |
237 self.__canceledFileSelect = True |
237 self.__canceledFileSelect = True |
238 self.__setDateTime() |
238 self.__setDateTime() |
239 return |
239 return |
240 |
240 |
241 self.__setFileName(fileName) |
241 self.__setFileName(fileName) |
242 |
242 |
243 def __setFileName(self, fileName): |
243 def __setFileName(self, fileName): |
244 """ |
244 """ |
245 Private method to set the file name to save the download into. |
245 Private method to set the file name to save the download into. |
246 |
246 |
247 @param fileName name of the file to save into |
247 @param fileName name of the file to save into |
248 @type str |
248 @type str |
249 """ |
249 """ |
250 fpath = pathlib.Path(fileName) |
250 fpath = pathlib.Path(fileName) |
251 WebBrowserWindow.downloadManager().setDownloadDirectory( |
251 WebBrowserWindow.downloadManager().setDownloadDirectory(fpath.parent.resolve()) |
252 fpath.parent.resolve()) |
|
253 self.filenameLabel.setText(fpath.name) |
252 self.filenameLabel.setText(fpath.name) |
254 |
253 |
255 self.__fileName = str(fpath) |
254 self.__fileName = str(fpath) |
256 |
255 |
257 # check file path for saving |
256 # check file path for saving |
258 saveDirPath = pathlib.Path(self.__fileName).parent() |
257 saveDirPath = pathlib.Path(self.__fileName).parent() |
259 if not saveDirPath.exists(): |
258 if not saveDirPath.exists(): |
260 saveDirPath.mkdir(parents=True) |
259 saveDirPath.mkdir(parents=True) |
261 |
260 |
262 def __saveFileName(self, directory): |
261 def __saveFileName(self, directory): |
263 """ |
262 """ |
264 Private method to calculate a name for the file to download. |
263 Private method to calculate a name for the file to download. |
265 |
264 |
266 @param directory name of the directory to store the file into (string) |
265 @param directory name of the directory to store the file into (string) |
267 @return proposed filename and original filename (string, string) |
266 @return proposed filename and original filename (string, string) |
268 """ |
267 """ |
269 fpath = pathlib.Path(self.__downloadRequest.downloadFileName()) |
268 fpath = pathlib.Path(self.__downloadRequest.downloadFileName()) |
270 origName = fpath.name |
269 origName = fpath.name |
271 name = os.path.join(directory, origName) |
270 name = os.path.join(directory, origName) |
272 return name, origName |
271 return name, origName |
273 |
272 |
274 @pyqtSlot(bool) |
273 @pyqtSlot(bool) |
275 def on_pauseButton_clicked(self, checked): |
274 def on_pauseButton_clicked(self, checked): |
276 """ |
275 """ |
277 Private slot to pause the download. |
276 Private slot to pause the download. |
278 |
277 |
279 @param checked flag indicating the state of the button |
278 @param checked flag indicating the state of the button |
280 @type bool |
279 @type bool |
281 """ |
280 """ |
282 if checked: |
281 if checked: |
283 self.__downloadRequest.pause() |
282 self.__downloadRequest.pause() |
284 else: |
283 else: |
285 self.__downloadRequest.resume() |
284 self.__downloadRequest.resume() |
286 |
285 |
287 @pyqtSlot() |
286 @pyqtSlot() |
288 def on_stopButton_clicked(self): |
287 def on_stopButton_clicked(self): |
289 """ |
288 """ |
290 Private slot to stop the download. |
289 Private slot to stop the download. |
291 """ |
290 """ |
292 self.cancelDownload() |
291 self.cancelDownload() |
293 |
292 |
294 def cancelDownload(self): |
293 def cancelDownload(self): |
295 """ |
294 """ |
296 Public slot to stop the download. |
295 Public slot to stop the download. |
297 """ |
296 """ |
298 self.setUpdatesEnabled(False) |
297 self.setUpdatesEnabled(False) |
341 if self.__bytesTotal > 0: |
340 if self.__bytesTotal > 0: |
342 currentValue = self.__bytesReceived * 100 // self.__bytesTotal |
341 currentValue = self.__bytesReceived * 100 // self.__bytesTotal |
343 totalValue = 100 |
342 totalValue = 100 |
344 self.progressBar.setValue(currentValue) |
343 self.progressBar.setValue(currentValue) |
345 self.progressBar.setMaximum(totalValue) |
344 self.progressBar.setMaximum(totalValue) |
346 |
345 |
347 self.progress.emit(currentValue, totalValue) |
346 self.progress.emit(currentValue, totalValue) |
348 self.__updateInfoLabel() |
347 self.__updateInfoLabel() |
349 |
348 |
350 def downloadProgress(self): |
349 def downloadProgress(self): |
351 """ |
350 """ |
352 Public method to get the download progress. |
351 Public method to get the download progress. |
353 |
352 |
354 @return current download progress |
353 @return current download progress |
355 @rtype int |
354 @rtype int |
356 """ |
355 """ |
357 return self.progressBar.value() |
356 return self.progressBar.value() |
358 |
357 |
359 def bytesTotal(self): |
358 def bytesTotal(self): |
360 """ |
359 """ |
361 Public method to get the total number of bytes of the download. |
360 Public method to get the total number of bytes of the download. |
362 |
361 |
363 @return total number of bytes (integer) |
362 @return total number of bytes (integer) |
364 """ |
363 """ |
365 if self.__bytesTotal == -1: |
364 if self.__bytesTotal == -1: |
366 self.__bytesTotal = self.__downloadRequest.totalBytes() |
365 self.__bytesTotal = self.__downloadRequest.totalBytes() |
367 return self.__bytesTotal |
366 return self.__bytesTotal |
368 |
367 |
369 def bytesReceived(self): |
368 def bytesReceived(self): |
370 """ |
369 """ |
371 Public method to get the number of bytes received. |
370 Public method to get the number of bytes received. |
372 |
371 |
373 @return number of bytes received (integer) |
372 @return number of bytes received (integer) |
374 """ |
373 """ |
375 return self.__bytesReceived |
374 return self.__bytesReceived |
376 |
375 |
377 def remainingTime(self): |
376 def remainingTime(self): |
378 """ |
377 """ |
379 Public method to get an estimation for the remaining time. |
378 Public method to get an estimation for the remaining time. |
380 |
379 |
381 @return estimation for the remaining time (float) |
380 @return estimation for the remaining time (float) |
382 """ |
381 """ |
383 if not self.downloading(): |
382 if not self.downloading(): |
384 return -1.0 |
383 return -1.0 |
385 |
384 |
386 if self.bytesTotal() == -1: |
385 if self.bytesTotal() == -1: |
387 return -1.0 |
386 return -1.0 |
388 |
387 |
389 cSpeed = self.currentSpeed() |
388 cSpeed = self.currentSpeed() |
390 timeRemaining = ( |
389 timeRemaining = ( |
391 (self.bytesTotal() - self.bytesReceived()) / cSpeed |
390 (self.bytesTotal() - self.bytesReceived()) / cSpeed if cSpeed != 0 else 1 |
392 if cSpeed != 0 else |
|
393 1 |
|
394 ) |
391 ) |
395 |
392 |
396 # ETA should never be 0 |
393 # ETA should never be 0 |
397 if timeRemaining == 0: |
394 if timeRemaining == 0: |
398 timeRemaining = 1 |
395 timeRemaining = 1 |
399 |
396 |
400 return timeRemaining |
397 return timeRemaining |
401 |
398 |
402 def currentSpeed(self): |
399 def currentSpeed(self): |
403 """ |
400 """ |
404 Public method to get an estimation for the download speed. |
401 Public method to get an estimation for the download speed. |
405 |
402 |
406 @return estimation for the download speed (float) |
403 @return estimation for the download speed (float) |
407 """ |
404 """ |
408 if not self.downloading(): |
405 if not self.downloading(): |
409 return -1.0 |
406 return -1.0 |
410 |
407 |
411 return ( |
408 return ( |
412 self.__bytesReceived * 1000.0 / |
409 self.__bytesReceived |
413 self.__downloadTime.msecsTo(QTime.currentTime()) |
410 * 1000.0 |
|
411 / self.__downloadTime.msecsTo(QTime.currentTime()) |
414 ) |
412 ) |
415 |
413 |
416 def __updateInfoLabel(self): |
414 def __updateInfoLabel(self): |
417 """ |
415 """ |
418 Private method to update the info label. |
416 Private method to update the info label. |
419 """ |
417 """ |
420 bytesTotal = self.bytesTotal() |
418 bytesTotal = self.bytesTotal() |
421 running = not self.downloadedSuccessfully() |
419 running = not self.downloadedSuccessfully() |
422 |
420 |
423 speed = self.currentSpeed() |
421 speed = self.currentSpeed() |
424 timeRemaining = self.remainingTime() |
422 timeRemaining = self.remainingTime() |
425 |
423 |
426 info = "" |
424 info = "" |
427 if running: |
425 if running: |
428 remaining = "" |
426 remaining = "" |
429 |
427 |
430 if bytesTotal > 0: |
428 if bytesTotal > 0: |
431 remaining = timeString(timeRemaining) |
429 remaining = timeString(timeRemaining) |
432 |
430 |
433 info = self.tr( |
431 info = self.tr("{0} of {1} ({2}/sec) {3}").format( |
434 "{0} of {1} ({2}/sec) {3}" |
|
435 ).format( |
|
436 dataString(self.__bytesReceived), |
432 dataString(self.__bytesReceived), |
437 bytesTotal == -1 and self.tr("?") or |
433 bytesTotal == -1 and self.tr("?") or dataString(bytesTotal), |
438 dataString(bytesTotal), |
|
439 speedString(speed), |
434 speedString(speed), |
440 remaining |
435 remaining, |
441 ) |
436 ) |
442 else: |
437 else: |
443 if bytesTotal in (self.__bytesReceived, -1): |
438 if bytesTotal in (self.__bytesReceived, -1): |
444 info = self.tr( |
439 info = self.tr("{0} downloaded").format( |
445 "{0} downloaded" |
440 dataString(self.__bytesReceived) |
446 ).format(dataString(self.__bytesReceived)) |
441 ) |
447 else: |
442 else: |
448 info = self.tr( |
443 info = self.tr("{0} of {1} - Stopped").format( |
449 "{0} of {1} - Stopped" |
444 dataString(self.__bytesReceived), dataString(bytesTotal) |
450 ).format(dataString(self.__bytesReceived), |
445 ) |
451 dataString(bytesTotal)) |
|
452 self.infoLabel.setText(info) |
446 self.infoLabel.setText(info) |
453 |
447 |
454 def downloading(self): |
448 def downloading(self): |
455 """ |
449 """ |
456 Public method to determine, if a download is in progress. |
450 Public method to determine, if a download is in progress. |
457 |
451 |
458 @return flag indicating a download is in progress (boolean) |
452 @return flag indicating a download is in progress (boolean) |
459 """ |
453 """ |
460 return self.__state == DownloadState.Downloading |
454 return self.__state == DownloadState.Downloading |
461 |
455 |
462 def downloadedSuccessfully(self): |
456 def downloadedSuccessfully(self): |
463 """ |
457 """ |
464 Public method to check for a successful download. |
458 Public method to check for a successful download. |
465 |
459 |
466 @return flag indicating a successful download (boolean) |
460 @return flag indicating a successful download (boolean) |
467 """ |
461 """ |
468 return self.__state == DownloadState.Successful |
462 return self.__state == DownloadState.Successful |
469 |
463 |
470 def downloadCanceled(self): |
464 def downloadCanceled(self): |
471 """ |
465 """ |
472 Public method to check, if the download was cancelled. |
466 Public method to check, if the download was cancelled. |
473 |
467 |
474 @return flag indicating a canceled download (boolean) |
468 @return flag indicating a canceled download (boolean) |
475 """ |
469 """ |
476 return self.__state == DownloadState.Cancelled |
470 return self.__state == DownloadState.Cancelled |
477 |
471 |
478 def __finished(self): |
472 def __finished(self): |
479 """ |
473 """ |
480 Private slot to handle the download finished. |
474 Private slot to handle the download finished. |
481 """ |
475 """ |
482 self.__finishedDownloading = True |
476 self.__finishedDownloading = True |
483 |
477 |
484 noError = (self.__downloadRequest.state() == |
478 noError = ( |
485 QWebEngineDownloadRequest.DownloadState.DownloadCompleted) |
479 self.__downloadRequest.state() |
486 |
480 == QWebEngineDownloadRequest.DownloadState.DownloadCompleted |
|
481 ) |
|
482 |
487 self.progressBar.setVisible(False) |
483 self.progressBar.setVisible(False) |
488 self.pauseButton.setEnabled(False) |
484 self.pauseButton.setEnabled(False) |
489 self.pauseButton.setVisible(False) |
485 self.pauseButton.setVisible(False) |
490 self.stopButton.setEnabled(False) |
486 self.stopButton.setEnabled(False) |
491 self.stopButton.setVisible(False) |
487 self.stopButton.setVisible(False) |
492 self.openButton.setEnabled(noError) |
488 self.openButton.setEnabled(noError) |
493 self.openButton.setVisible(noError) |
489 self.openButton.setVisible(noError) |
494 self.__state = DownloadState.Successful |
490 self.__state = DownloadState.Successful |
495 self.__updateInfoLabel() |
491 self.__updateInfoLabel() |
496 self.__setDateTime() |
492 self.__setDateTime() |
497 |
493 |
498 self.__adjustSize() |
494 self.__adjustSize() |
499 |
495 |
500 self.statusChanged.emit() |
496 self.statusChanged.emit() |
501 self.downloadFinished.emit(True) |
497 self.downloadFinished.emit(True) |
502 |
498 |
503 if self.__autoOpen: |
499 if self.__autoOpen: |
504 self.openFile() |
500 self.openFile() |
505 |
501 |
506 def canceledFileSelect(self): |
502 def canceledFileSelect(self): |
507 """ |
503 """ |
508 Public method to check, if the user canceled the file selection. |
504 Public method to check, if the user canceled the file selection. |
509 |
505 |
510 @return flag indicating cancellation (boolean) |
506 @return flag indicating cancellation (boolean) |
511 """ |
507 """ |
512 return self.__canceledFileSelect |
508 return self.__canceledFileSelect |
513 |
509 |
514 def setIcon(self, icon): |
510 def setIcon(self, icon): |
515 """ |
511 """ |
516 Public method to set the download icon. |
512 Public method to set the download icon. |
517 |
513 |
518 @param icon reference to the icon to be set (QIcon) |
514 @param icon reference to the icon to be set (QIcon) |
519 """ |
515 """ |
520 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
516 self.fileIcon.setPixmap(icon.pixmap(48, 48)) |
521 |
517 |
522 def fileName(self): |
518 def fileName(self): |
523 """ |
519 """ |
524 Public method to get the name of the output file. |
520 Public method to get the name of the output file. |
525 |
521 |
526 @return name of the output file (string) |
522 @return name of the output file (string) |
527 """ |
523 """ |
528 return self.__fileName |
524 return self.__fileName |
529 |
525 |
530 def absoluteFilePath(self): |
526 def absoluteFilePath(self): |
531 """ |
527 """ |
532 Public method to get the absolute path of the output file. |
528 Public method to get the absolute path of the output file. |
533 |
529 |
534 @return absolute path of the output file (string) |
530 @return absolute path of the output file (string) |
535 """ |
531 """ |
536 return pathlib.Path(self.__fileName).resolve() |
532 return pathlib.Path(self.__fileName).resolve() |
537 |
533 |
538 def getData(self): |
534 def getData(self): |
539 """ |
535 """ |
540 Public method to get the relevant download data. |
536 Public method to get the relevant download data. |
541 |
537 |
542 @return dictionary containing the URL, save location, done flag, |
538 @return dictionary containing the URL, save location, done flag, |
543 the URL of the related web page and the date and time of the |
539 the URL of the related web page and the date and time of the |
544 download |
540 download |
545 @rtype dict of {"URL": QUrl, "Location": str, "Done": bool, |
541 @rtype dict of {"URL": QUrl, "Location": str, "Done": bool, |
546 "PageURL": QUrl, "Downloaded": QDateTime} |
542 "PageURL": QUrl, "Downloaded": QDateTime} |
548 return { |
544 return { |
549 "URL": self.__url, |
545 "URL": self.__url, |
550 "Location": self.__fileName, |
546 "Location": self.__fileName, |
551 "Done": self.downloadedSuccessfully(), |
547 "Done": self.downloadedSuccessfully(), |
552 "PageURL": self.__pageUrl, |
548 "PageURL": self.__pageUrl, |
553 "Downloaded": self.__downloadedDateTime |
549 "Downloaded": self.__downloadedDateTime, |
554 } |
550 } |
555 |
551 |
556 def setData(self, data): |
552 def setData(self, data): |
557 """ |
553 """ |
558 Public method to set the relevant download data. |
554 Public method to set the relevant download data. |
559 |
555 |
560 @param data dictionary containing the URL, save location, done flag, |
556 @param data dictionary containing the URL, save location, done flag, |
561 the URL of the related web page and the date and time of the |
557 the URL of the related web page and the date and time of the |
562 download |
558 download |
563 @type dict of {"URL": QUrl, "Location": str, "Done": bool, |
559 @type dict of {"URL": QUrl, "Location": str, "Done": bool, |
564 "PageURL": QUrl, "Downloaded": QDateTime} |
560 "PageURL": QUrl, "Downloaded": QDateTime} |
565 """ |
561 """ |
566 self.__url = data["URL"] |
562 self.__url = data["URL"] |
567 self.__fileName = data["Location"] |
563 self.__fileName = data["Location"] |
568 self.__pageUrl = data["PageURL"] |
564 self.__pageUrl = data["PageURL"] |
569 |
565 |
570 self.filenameLabel.setText(pathlib.Path(self.__fileName).name) |
566 self.filenameLabel.setText(pathlib.Path(self.__fileName).name) |
571 self.infoLabel.setText(self.__fileName) |
567 self.infoLabel.setText(self.__fileName) |
572 |
568 |
573 try: |
569 try: |
574 self.__setDateTime(data["Downloaded"]) |
570 self.__setDateTime(data["Downloaded"]) |
575 except KeyError: |
571 except KeyError: |
576 self.__setDateTime(QDateTime()) |
572 self.__setDateTime(QDateTime()) |
577 |
573 |
578 self.pauseButton.setEnabled(False) |
574 self.pauseButton.setEnabled(False) |
579 self.pauseButton.setVisible(False) |
575 self.pauseButton.setVisible(False) |
580 self.stopButton.setEnabled(False) |
576 self.stopButton.setEnabled(False) |
581 self.stopButton.setVisible(False) |
577 self.stopButton.setVisible(False) |
582 self.openButton.setEnabled(data["Done"]) |
578 self.openButton.setEnabled(data["Done"]) |