2 |
2 |
3 """ |
3 """ |
4 Module implementing the download manager class. |
4 Module implementing the download manager class. |
5 """ |
5 """ |
6 |
6 |
7 from PyQt4.QtCore import pyqtSlot, QModelIndex, QFileInfo |
7 from PyQt4.QtCore import pyqtSlot, Qt, QModelIndex, QFileInfo |
8 from PyQt4.QtGui import QDialog, QStyle, QFileIconProvider |
8 from PyQt4.QtGui import QDialog, QStyle, QFileIconProvider, QMenu, QCursor, QApplication |
9 from PyQt4.QtNetwork import QNetworkRequest |
9 from PyQt4.QtNetwork import QNetworkRequest |
10 from PyQt4.QtWebKit import QWebSettings |
10 from PyQt4.QtWebKit import QWebSettings |
11 |
11 |
12 from E5Gui import E5MessageBox |
12 from E5Gui import E5MessageBox |
13 |
13 |
17 from .DownloadModel import DownloadModel |
17 from .DownloadModel import DownloadModel |
18 |
18 |
19 import Helpviewer.HelpWindow |
19 import Helpviewer.HelpWindow |
20 |
20 |
21 from Utilities.AutoSaver import AutoSaver |
21 from Utilities.AutoSaver import AutoSaver |
|
22 import UI.PixmapCache |
22 import Preferences |
23 import Preferences |
23 |
24 |
24 class DownloadManager(QDialog, Ui_DownloadManager): |
25 class DownloadManager(QDialog, Ui_DownloadManager): |
25 """ |
26 """ |
26 Class implementing the download manager |
27 Class implementing the download manager |
54 self.downloadsView.verticalHeader().hide() |
55 self.downloadsView.verticalHeader().hide() |
55 self.downloadsView.horizontalHeader().hide() |
56 self.downloadsView.horizontalHeader().hide() |
56 self.downloadsView.setAlternatingRowColors(True) |
57 self.downloadsView.setAlternatingRowColors(True) |
57 self.downloadsView.horizontalHeader().setStretchLastSection(True) |
58 self.downloadsView.horizontalHeader().setStretchLastSection(True) |
58 self.downloadsView.setModel(self.__model) |
59 self.downloadsView.setModel(self.__model) |
|
60 self.downloadsView.setContextMenuPolicy(Qt.CustomContextMenu) |
|
61 self.downloadsView.customContextMenuRequested.connect( |
|
62 self.__customContextMenuRequested) |
59 |
63 |
60 self.__load() |
64 self.__load() |
|
65 |
|
66 def __customContextMenuRequested(self, pos): |
|
67 """ |
|
68 Private slot to handle the context menu request for the bookmarks tree. |
|
69 |
|
70 @param pos position the context menu was requested (QPoint) |
|
71 """ |
|
72 menu = QMenu() |
|
73 |
|
74 selectedRowsCount = len(self.downloadsView.selectionModel().selectedRows()) |
|
75 |
|
76 if selectedRowsCount == 1: |
|
77 row = self.downloadsView.selectionModel().selectedRows()[0].row() |
|
78 itm = self.__downloads[row] |
|
79 if itm.downloadCanceled(): |
|
80 menu.addAction(UI.PixmapCache.getIcon("restart.png"), |
|
81 self.trUtf8("Retry"), self.__contextMenuRetry) |
|
82 else: |
|
83 if itm.downloadedSuccessfully(): |
|
84 menu.addAction(UI.PixmapCache.getIcon("open.png"), |
|
85 self.trUtf8("Open"), self.__contextMenuOpen) |
|
86 elif itm.downloading(): |
|
87 menu.addAction(UI.PixmapCache.getIcon("stopLoading.png"), |
|
88 self.trUtf8("Cancel"), self.__contextMenuCancel) |
|
89 menu.addSeparator() |
|
90 menu.addAction(self.trUtf8("Open Containing Folder"), |
|
91 self.__contextMenuOpenFolder) |
|
92 menu.addSeparator() |
|
93 menu.addAction(self.trUtf8("Go to Download Page"), |
|
94 self.__contextMenuGotoPage) |
|
95 menu.addAction(self.trUtf8("Copy Download Link"), |
|
96 self.__contextMenuCopyLink) |
|
97 menu.addSeparator() |
|
98 menu.addAction(self.trUtf8("Select All"), self.__contextMenuSelectAll) |
|
99 if selectedRowsCount > 1 or \ |
|
100 (selectedRowsCount == 1 and \ |
|
101 not self.__downloads[ |
|
102 self.downloadsView.selectionModel().selectedRows()[0].row()]\ |
|
103 .downloading()): |
|
104 menu.addSeparator() |
|
105 menu.addAction(self.trUtf8("Remove From List"), |
|
106 self.__contextMenuRemoveSelected) |
|
107 |
|
108 menu.exec_(QCursor.pos()) |
61 |
109 |
62 def shutdown(self): |
110 def shutdown(self): |
63 """ |
111 """ |
64 Public method to stop the download manager. |
112 Public method to stop the download manager. |
65 """ |
113 """ |
146 |
194 |
147 row = len(self.__downloads) |
195 row = len(self.__downloads) |
148 self.__model.beginInsertRows(QModelIndex(), row, row) |
196 self.__model.beginInsertRows(QModelIndex(), row, row) |
149 self.__downloads.append(itm) |
197 self.__downloads.append(itm) |
150 self.__model.endInsertRows() |
198 self.__model.endInsertRows() |
151 self.__updateItemCount() |
|
152 |
199 |
153 self.downloadsView.setIndexWidget(self.__model.index(row, 0), itm) |
200 self.downloadsView.setIndexWidget(self.__model.index(row, 0), itm) |
154 icon = self.style().standardIcon(QStyle.SP_FileIcon) |
201 icon = self.style().standardIcon(QStyle.SP_FileIcon) |
155 itm.setIcon(icon) |
202 itm.setIcon(icon) |
156 self.downloadsView.setRowHeight(row, itm.sizeHint().height()) |
203 self.downloadsView.setRowHeight(row, itm.sizeHint().height()) |
157 # just in case the download finished before the constructor returned |
204 # just in case the download finished before the constructor returned |
158 self.__updateRow(itm) |
205 self.__updateRow(itm) |
|
206 self.changeOccurred() |
159 |
207 |
160 def __updateRow(self, itm = None): |
208 def __updateRow(self, itm = None): |
161 """ |
209 """ |
162 Private slot to update a download item. |
210 Private slot to update a download item. |
163 |
211 |
193 self.removePolicy() == DownloadManager.RemoveSuccessFullDownload: |
241 self.removePolicy() == DownloadManager.RemoveSuccessFullDownload: |
194 remove = True |
242 remove = True |
195 |
243 |
196 if remove: |
244 if remove: |
197 self.__model.removeRow(row) |
245 self.__model.removeRow(row) |
198 self.__updateItemCount() |
|
199 |
246 |
200 self.cleanupButton.setEnabled( |
247 self.cleanupButton.setEnabled( |
201 (len(self.__downloads) - self.activeDownloads()) > 0) |
248 (len(self.__downloads) - self.activeDownloads()) > 0) |
|
249 |
|
250 # record the change |
|
251 self.changeOccurred() |
202 |
252 |
203 def removePolicy(self): |
253 def removePolicy(self): |
204 """ |
254 """ |
205 Public method to get the remove policy. |
255 Public method to get the remove policy. |
206 |
256 |
279 """ |
329 """ |
280 if len(self.__downloads) == 0: |
330 if len(self.__downloads) == 0: |
281 return |
331 return |
282 |
332 |
283 self.__model.removeRows(0, len(self.__downloads)) |
333 self.__model.removeRows(0, len(self.__downloads)) |
284 self.__updateItemCount() |
|
285 if len(self.__downloads) == 0 and \ |
334 if len(self.__downloads) == 0 and \ |
286 self.__iconProvider is not None: |
335 self.__iconProvider is not None: |
287 self.__iconProvider = None |
336 self.__iconProvider = None |
288 |
337 |
289 self.__saveTimer.changeOccurred() |
338 self.changeOccurred() |
290 |
339 |
291 def __updateItemCount(self): |
340 def __updateItemCount(self): |
292 """ |
341 """ |
293 Private method to update the count label. |
342 Private method to update the count label. |
294 """ |
343 """ |
332 def changeOccurred(self): |
381 def changeOccurred(self): |
333 """ |
382 """ |
334 Public method to signal a change. |
383 Public method to signal a change. |
335 """ |
384 """ |
336 self.__saveTimer.changeOccurred() |
385 self.__saveTimer.changeOccurred() |
|
386 self.__updateItemCount() |
|
387 |
|
388 ############################################################################ |
|
389 ## Context menu related methods below |
|
390 ############################################################################ |
|
391 |
|
392 def __currentItem(self): |
|
393 """ |
|
394 Private method to get a reference to the current item. |
|
395 |
|
396 @return reference to the current item (DownloadItem) |
|
397 """ |
|
398 index = self.downloadsView.currentIndex() |
|
399 if index and index.isValid(): |
|
400 row = index.row() |
|
401 return self.__downloads[row] |
|
402 |
|
403 return None |
|
404 |
|
405 def __contextMenuRetry(self): |
|
406 """ |
|
407 Private method to retry of the download. |
|
408 """ |
|
409 itm = self.__currentItem() |
|
410 if itm is not None: |
|
411 itm.retry() |
|
412 |
|
413 def __contextMenuOpen(self): |
|
414 """ |
|
415 Private method to open the downloaded file. |
|
416 """ |
|
417 itm = self.__currentItem() |
|
418 if itm is not None: |
|
419 itm.openFile() |
|
420 |
|
421 def __contextMenuOpenFolder(self): |
|
422 """ |
|
423 Private method to open the folder containing the downloaded file. |
|
424 """ |
|
425 itm = self.__currentItem() |
|
426 if itm is not None: |
|
427 itm.openFolder() |
|
428 |
|
429 def __contextMenuCancel(self): |
|
430 """ |
|
431 Private method to cancel the current download. |
|
432 """ |
|
433 itm = self.__currentItem() |
|
434 if itm is not None: |
|
435 itm.cancelDownload() |
|
436 |
|
437 def __contextMenuGotoPage(self): |
|
438 """ |
|
439 Private method to open the download page. |
|
440 """ |
|
441 itm = self.__currentItem() |
|
442 if itm is not None: |
|
443 url = itm.getPageUrl() |
|
444 Helpviewer.HelpWindow.HelpWindow.mainWindow().openUrl(url, "") |
|
445 |
|
446 def __contextMenuCopyLink(self): |
|
447 """ |
|
448 Private method to copy the download link to the clipboard. |
|
449 """ |
|
450 itm = self.__currentItem() |
|
451 if itm is not None: |
|
452 url = itm.getPageUrl().toString() |
|
453 QApplication.clipboard().setText(url) |
|
454 |
|
455 def __contextMenuSelectAll(self): |
|
456 """ |
|
457 Private method to select all downloads. |
|
458 """ |
|
459 self.downloadsView.selectAll() |
|
460 |
|
461 def __contextMenuRemoveSelected(self): |
|
462 """ |
|
463 Private method to remove the selected downloads from the list. |
|
464 """ |
|
465 self.downloadsView.removeSelected() |
|
466 |