Helpviewer/Download/DownloadManager.py

changeset 668
b0061a6f7484
child 669
d405dc3e2ed6
equal deleted inserted replaced
666:fdd568d3533d 668:b0061a6f7484
1 # -*- coding: utf-8 -*-
2
3 """
4 Module implementing the download manager class.
5 """
6
7 from PyQt4.QtCore import pyqtSlot, QModelIndex, QFileInfo
8 from PyQt4.QtGui import QDialog, QStyle, QFileIconProvider
9 from PyQt4.QtNetwork import QNetworkRequest
10 from PyQt4.QtWebKit import QWebSettings
11
12 from E5Gui import E5MessageBox
13
14 from .Ui_DownloadManager import Ui_DownloadManager
15
16 from .DownloadItem import DownloadItem
17 from .DownloadModel import DownloadModel
18
19 import Helpviewer.HelpWindow
20
21 from Utilities.AutoSaver import AutoSaver
22 import Preferences
23
24 class DownloadManager(QDialog, Ui_DownloadManager):
25 """
26 Class implementing the download manager
27 """
28 RemoveNever = 0
29 RemoveExit = 1
30 RemoveSuccessFullDownload = 2
31
32 def __init__(self, parent = None):
33 """
34 Constructor
35
36 @param parent reference to the parent widget (QWidget)
37 """
38 QDialog.__init__(self, parent)
39 self.setupUi(self)
40
41 self.__saveTimer = AutoSaver(self, self.save)
42
43 self.__model = DownloadModel(self)
44 self.__manager = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
45
46 self.__iconProvider = None
47 self.__removePolicy = DownloadManager.RemoveNever
48 self.__downloads = []
49 self.__downloadDirectory = ""
50 self.__loaded = False
51
52 self.setDownloadDirectory(Preferences.getUI("DownloadPath"))
53
54 self.downloadsView.setShowGrid(False)
55 self.downloadsView.verticalHeader().hide()
56 self.downloadsView.horizontalHeader().hide()
57 self.downloadsView.setAlternatingRowColors(True)
58 self.downloadsView.horizontalHeader().setStretchLastSection(True)
59 self.downloadsView.setModel(self.__model)
60
61 self.__load()
62
63 def shutdown(self):
64 """
65 Public method to stop the download manager.
66 """
67 self.__saveTimer.changeOccurred()
68 self.__saveTimer.saveIfNeccessary()
69 self.close()
70
71 def activeDownloads(self):
72 """
73 Public method to get the number of active downloads.
74
75 @return number of active downloads (integer)
76 """
77 count = 0
78
79 for download in self.__downloads:
80 if download.downloading():
81 count += 1
82 return count
83
84 def allowQuit(self):
85 """
86 Public method to check, if it is ok to quit.
87
88 @return flag indicating allowance to quit (boolean)
89 """
90 if self.activeDownloads() > 0:
91 res = E5MessageBox.yesNo(self,
92 self.trUtf8(""),
93 self.trUtf8("""There are %n downloads in progress.\n"""
94 """Do you want to quit anyway?""", "",
95 self.activeDownloads()),
96 icon = E5MessageBox.Warning)
97 if not res:
98 self.show()
99 return False
100 return True
101
102 def download(self, requestOrUrl, requestFileName = False):
103 """
104 Public method to download a file.
105
106 @param requestOrUrl reference to a request object (QNetworkRequest)
107 or a URL to be downloaded (QUrl)
108 @keyparam requestFileName flag indicating to ask for the
109 download file name (boolean)
110 """
111 request = QNetworkRequest(requestOrUrl)
112 if request.url().isEmpty():
113 return
114 self.handleUnsupportedContent(self.__manager.get(request),
115 requestFileName = requestFileName,
116 download = True)
117
118 def handleUnsupportedContent(self, reply, requestFileName = False,
119 webPage = None, download = False):
120 if reply is None or reply.url().isEmpty():
121 return
122
123 size = reply.header(QNetworkRequest.ContentLengthHeader)
124 if size == 0:
125 return
126
127 itm = DownloadItem(reply = reply, requestFilename = requestFileName,
128 webPage = webPage, download = download, parent = self)
129 self.__addItem(itm)
130
131 if itm.canceledFileSelect():
132 return
133
134 if not self.isVisible():
135 self.show()
136
137 self.activateWindow()
138 self.raise_()
139
140 def __addItem(self, itm):
141 """
142 Private method to add a download to the list of downloads.
143
144 @param itm reference to the download item (DownloadItem)
145 """
146 itm.statusChanged.connect(self.__updateRow)
147
148 row = len(self.__downloads)
149 self.__model.beginInsertRows(QModelIndex(), row, row)
150 self.__downloads.append(itm)
151 self.__model.endInsertRows()
152 self.__updateItemCount()
153
154 self.downloadsView.setIndexWidget(self.__model.index(row, 0), itm)
155 icon = self.style().standardIcon(QStyle.SP_FileIcon)
156 itm.setIcon(icon)
157 self.downloadsView.setRowHeight(row, itm.sizeHint().height())
158 # just in case the download finished before the constructor returned
159 self.__updateRow(itm)
160
161 def __updateRow(self, itm = None):
162 """
163 Private slot to update a download item.
164
165 @param itm reference to the download item (DownloadItem)
166 """
167 if itm is None:
168 itm = self.sender()
169
170 if itm not in self.__downloads:
171 return
172
173 row = self.__downloads.index(itm)
174
175 if self.__iconProvider is None:
176 self.__iconProvider = QFileIconProvider()
177
178 icon = self.__iconProvider.icon(QFileInfo(itm.fileName()))
179 if icon.isNull():
180 icon = self.style().standardIcon(QStyle.SP_FileIcon)
181 itm.setIcon(icon)
182
183 oldHeight = self.downloadsView.rowHeight(row)
184 self.downloadsView.setRowHeight(row,
185 max(oldHeight, itm.minimumSizeHint().height()))
186
187 remove = False
188 globalSettings = QWebSettings.globalSettings()
189 if not itm.downloading() and \
190 globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled):
191 remove = True
192
193 if itm.downloadedSuccessfully() and \
194 self.removePolicy() == DownloadManager.RemoveSuccessFullDownload:
195 remove = True
196
197 if remove:
198 self.__model.removeRow(row)
199
200 self.cleanupButton.setEnabled(
201 (len(self.__downloads) - self.activeDownloads()) > 0)
202
203 def removePolicy(self):
204 """
205 Public method to get the remove policy.
206
207 @return remove policy (integer)
208 """
209 return self.__removePolicy
210
211 def setRemovePolicy(self, policy):
212 """
213 Public method to set the remove policy.
214
215 @param policy policy to be set
216 (DownloadManager.RemoveExit, DownloadManager.RemoveNever,
217 DownloadManager.RemoveSuccessFullDownload)
218 """
219 assert policy in (DownloadManager.RemoveExit, DownloadManager.RemoveNever,
220 DownloadManager.RemoveSuccessFullDownload)
221
222 if policy == self.__removePolicy:
223 return
224
225 self.__removePolicy = policy
226 self.__saveTimer.changeOccurred()
227
228 def save(self):
229 """
230 Public method to save the download settings.
231 """
232 if not self.__loaded:
233 return
234
235 Preferences.setHelp("DownloadManagerRemovePolicy", self.__removePolicy)
236 Preferences.setHelp("DownloadManagerSize", self.size())
237 if self.__removePolicy == DownloadManager.RemoveExit:
238 return
239
240 downloads = []
241 for download in self.__downloads:
242 downloads.append(download.getData())
243 Preferences.setHelp("DownloadManagerDownloads", downloads)
244
245 def __load(self):
246 """
247 Public method to load the download settings.
248 """
249 if self.__loaded:
250 return
251
252 self.__removePolicy = Preferences.getHelp("DownloadManagerRemovePolicy")
253 size = Preferences.getHelp("DownloadManagerSize")
254 if size.isValid():
255 self.resize(size)
256 downloads = Preferences.getHelp("DownloadManagerDownloads")
257 for download in downloads:
258 if not download[0].isEmpty() and \
259 download[1] != "":
260 itm = DownloadItem(parent = self)
261 itm.setData(download)
262 self.__addItem(itm)
263 self.cleanupButton.setEnabled(
264 (len(self.__downloads) - self.activeDownloads()) > 0)
265
266 self.__loaded = True
267
268 def cleanup(self):
269 """
270 Public slot to cleanup the downloads.
271 """
272 self.on_cleanupButton_clicked()
273
274 @pyqtSlot()
275 def on_cleanupButton_clicked(self):
276 """
277 Private slot cleanup the downloads.
278 """
279 if len(self.__downloads) == 0:
280 return
281
282 self.__model.removeRows(0, len(self.__downloads))
283 self.__updateItemCount()
284 if len(self.__downloads) == 0 and \
285 self.__iconProvider is not None:
286 self.__iconProvider = None
287
288 self.__saveTimer.changeOccurred()
289
290 def __updateItemCount(self):
291 """
292 Private method to update the count label.
293 """
294 count = len(self.__downloads)
295 self.countLabel.setText(self.trUtf8("%n Download(s)", "", count))
296
297 def setDownloadDirectory(self, directory):
298 """
299 Public method to set the current download directory.
300
301 @param directory current download directory (string)
302 """
303 self.__downloadDirectory = directory
304 if self.__downloadDirectory != "":
305 self.__downloadDirectory += "/"
306
307 def downloadDirectory(self):
308 """
309 Public method to get the current download directory.
310
311 @return current download directory (string)
312 """
313 return self.__downloadDirectory
314
315 def count(self):
316 """
317 Public method to get the number of downloads.
318
319 @return number of downloads (integer)
320 """
321 return len(self.__downloads)
322
323 def downloads(self):
324 """
325 Public method to get a reference to the downloads.
326
327 @return reference to the downloads (list of DownloadItem)
328 """
329 return self.__downloads
330
331 def changeOccurred(self):
332 """
333 Public method to signal a change.
334 """
335 self.__saveTimer.changeOccurred()

eric ide

mercurial