Helpviewer/Download/DownloadManager.py

changeset 668
b0061a6f7484
child 669
d405dc3e2ed6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Helpviewer/Download/DownloadManager.py	Sun Oct 10 21:12:43 2010 +0200
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+
+"""
+Module implementing the download manager class.
+"""
+
+from PyQt4.QtCore import pyqtSlot, QModelIndex, QFileInfo
+from PyQt4.QtGui import QDialog, QStyle, QFileIconProvider
+from PyQt4.QtNetwork import QNetworkRequest
+from PyQt4.QtWebKit import QWebSettings
+
+from E5Gui import E5MessageBox
+
+from .Ui_DownloadManager import Ui_DownloadManager
+
+from .DownloadItem import DownloadItem
+from .DownloadModel import DownloadModel
+
+import Helpviewer.HelpWindow
+
+from Utilities.AutoSaver import AutoSaver
+import Preferences
+
+class DownloadManager(QDialog, Ui_DownloadManager):
+    """
+    Class implementing the download manager
+    """
+    RemoveNever               = 0
+    RemoveExit                = 1
+    RemoveSuccessFullDownload = 2
+    
+    def __init__(self, parent = None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        QDialog.__init__(self, parent)
+        self.setupUi(self)
+        
+        self.__saveTimer = AutoSaver(self, self.save)
+        
+        self.__model = DownloadModel(self)
+        self.__manager = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
+        
+        self.__iconProvider = None
+        self.__removePolicy = DownloadManager.RemoveNever
+        self.__downloads = []
+        self.__downloadDirectory = ""
+        self.__loaded = False
+        
+        self.setDownloadDirectory(Preferences.getUI("DownloadPath"))
+        
+        self.downloadsView.setShowGrid(False)
+        self.downloadsView.verticalHeader().hide()
+        self.downloadsView.horizontalHeader().hide()
+        self.downloadsView.setAlternatingRowColors(True)
+        self.downloadsView.horizontalHeader().setStretchLastSection(True)
+        self.downloadsView.setModel(self.__model)
+        
+        self.__load()
+    
+    def shutdown(self):
+        """
+        Public method to stop the download manager.
+        """
+        self.__saveTimer.changeOccurred()
+        self.__saveTimer.saveIfNeccessary()
+        self.close()
+    
+    def activeDownloads(self):
+        """
+        Public method to get the number of active downloads.
+        
+        @return number of active downloads (integer)
+        """
+        count = 0
+        
+        for download in self.__downloads:
+            if download.downloading():
+                count += 1
+        return count
+    
+    def allowQuit(self):
+        """
+        Public method to check, if it is ok to quit.
+        
+        @return flag indicating allowance to quit (boolean)
+        """
+        if self.activeDownloads() > 0:
+            res = E5MessageBox.yesNo(self,
+                self.trUtf8(""),
+                self.trUtf8("""There are %n downloads in progress.\n"""
+                            """Do you want to quit anyway?""", "", 
+                            self.activeDownloads()),
+                icon = E5MessageBox.Warning)
+            if not res:
+                self.show()
+                return False
+        return True
+    
+    def download(self, requestOrUrl, requestFileName = False):
+        """
+        Public method to download a file.
+        
+        @param requestOrUrl reference to a request object (QNetworkRequest)
+            or a URL to be downloaded (QUrl)
+        @keyparam requestFileName flag indicating to ask for the 
+            download file name (boolean)
+        """
+        request = QNetworkRequest(requestOrUrl)
+        if request.url().isEmpty():
+            return
+        self.handleUnsupportedContent(self.__manager.get(request), 
+            requestFileName = requestFileName, 
+            download = True)
+    
+    def handleUnsupportedContent(self, reply, requestFileName = False, 
+                                 webPage = None, download = False):
+        if reply is None or reply.url().isEmpty():
+            return
+        
+        size = reply.header(QNetworkRequest.ContentLengthHeader)
+        if size == 0:
+            return
+        
+        itm = DownloadItem(reply = reply, requestFilename = requestFileName, 
+            webPage = webPage, download = download, parent = self)
+        self.__addItem(itm)
+        
+        if itm.canceledFileSelect():
+            return
+        
+        if not self.isVisible():
+            self.show()
+        
+        self.activateWindow()
+        self.raise_()
+    
+    def __addItem(self, itm):
+        """
+        Private method to add a download to the list of downloads.
+        
+        @param itm reference to the download item (DownloadItem)
+        """
+        itm.statusChanged.connect(self.__updateRow)
+        
+        row = len(self.__downloads)
+        self.__model.beginInsertRows(QModelIndex(), row, row)
+        self.__downloads.append(itm)
+        self.__model.endInsertRows()
+        self.__updateItemCount()
+        
+        self.downloadsView.setIndexWidget(self.__model.index(row, 0), itm)
+        icon = self.style().standardIcon(QStyle.SP_FileIcon)
+        itm.setIcon(icon)
+        self.downloadsView.setRowHeight(row, itm.sizeHint().height())
+        # just in case the download finished before the constructor returned
+        self.__updateRow(itm)
+    
+    def __updateRow(self, itm = None):
+        """
+        Private slot to update a download item.
+        
+        @param itm reference to the download item (DownloadItem)
+        """
+        if itm is None:
+            itm = self.sender()
+        
+        if itm not in self.__downloads:
+            return
+        
+        row = self.__downloads.index(itm)
+        
+        if self.__iconProvider is None:
+            self.__iconProvider = QFileIconProvider()
+        
+        icon = self.__iconProvider.icon(QFileInfo(itm.fileName()))
+        if icon.isNull():
+            icon = self.style().standardIcon(QStyle.SP_FileIcon)
+        itm.setIcon(icon)
+        
+        oldHeight = self.downloadsView.rowHeight(row)
+        self.downloadsView.setRowHeight(row, 
+            max(oldHeight, itm.minimumSizeHint().height()))
+        
+        remove = False
+        globalSettings = QWebSettings.globalSettings()
+        if not itm.downloading() and \
+           globalSettings.testAttribute(QWebSettings.PrivateBrowsingEnabled):
+            remove = True
+        
+        if itm.downloadedSuccessfully() and \
+           self.removePolicy() == DownloadManager.RemoveSuccessFullDownload:
+            remove = True
+        
+        if remove:
+            self.__model.removeRow(row)
+        
+        self.cleanupButton.setEnabled(
+            (len(self.__downloads) - self.activeDownloads()) > 0)
+    
+    def removePolicy(self):
+        """
+        Public method to get the remove policy.
+        
+        @return remove policy (integer)
+        """
+        return self.__removePolicy
+    
+    def setRemovePolicy(self, policy):
+        """
+        Public method to set the remove policy.
+        
+        @param policy policy to be set 
+            (DownloadManager.RemoveExit, DownloadManager.RemoveNever, 
+             DownloadManager.RemoveSuccessFullDownload)
+        """
+        assert policy in (DownloadManager.RemoveExit, DownloadManager.RemoveNever, 
+                          DownloadManager.RemoveSuccessFullDownload)
+        
+        if policy == self.__removePolicy:
+            return
+        
+        self.__removePolicy = policy
+        self.__saveTimer.changeOccurred()
+    
+    def save(self):
+        """
+        Public method to save the download settings.
+        """
+        if not self.__loaded:
+            return
+        
+        Preferences.setHelp("DownloadManagerRemovePolicy", self.__removePolicy)
+        Preferences.setHelp("DownloadManagerSize", self.size())
+        if self.__removePolicy == DownloadManager.RemoveExit:
+            return
+        
+        downloads = []
+        for download in self.__downloads:
+            downloads.append(download.getData())
+        Preferences.setHelp("DownloadManagerDownloads", downloads)
+    
+    def __load(self):
+        """
+        Public method to load the download settings.
+        """
+        if self.__loaded:
+            return
+        
+        self.__removePolicy = Preferences.getHelp("DownloadManagerRemovePolicy")
+        size = Preferences.getHelp("DownloadManagerSize")
+        if size.isValid():
+            self.resize(size)
+        downloads = Preferences.getHelp("DownloadManagerDownloads")
+        for download in downloads:
+            if not download[0].isEmpty() and \
+               download[1] != "":
+                itm = DownloadItem(parent = self)
+                itm.setData(download)
+                self.__addItem(itm)
+        self.cleanupButton.setEnabled(
+            (len(self.__downloads) - self.activeDownloads()) > 0)
+        
+        self.__loaded = True
+    
+    def cleanup(self):
+        """
+        Public slot to cleanup the downloads.
+        """
+        self.on_cleanupButton_clicked()
+    
+    @pyqtSlot()
+    def on_cleanupButton_clicked(self):
+        """
+        Private slot cleanup the downloads.
+        """
+        if len(self.__downloads) == 0:
+            return
+        
+        self.__model.removeRows(0, len(self.__downloads))
+        self.__updateItemCount()
+        if len(self.__downloads) == 0 and \
+           self.__iconProvider is not None:
+               self.__iconProvider = None
+        
+        self.__saveTimer.changeOccurred()
+    
+    def __updateItemCount(self):
+        """
+        Private method to update the count label.
+        """
+        count = len(self.__downloads)
+        self.countLabel.setText(self.trUtf8("%n Download(s)", "", count))
+    
+    def setDownloadDirectory(self, directory):
+        """
+        Public method to set the current download directory.
+        
+        @param directory current download directory (string)
+        """
+        self.__downloadDirectory = directory
+        if self.__downloadDirectory != "":
+            self.__downloadDirectory += "/"
+    
+    def downloadDirectory(self):
+        """
+        Public method to get the current download directory.
+        
+        @return current download directory (string)
+        """
+        return self.__downloadDirectory
+    
+    def count(self):
+        """
+        Public method to get the number of downloads.
+        
+        @return number of downloads (integer)
+        """
+        return len(self.__downloads)
+    
+    def downloads(self):
+        """
+        Public method to get a reference to the downloads.
+        
+        @return reference to the downloads (list of DownloadItem)
+        """
+        return self.__downloads
+    
+    def changeOccurred(self):
+        """
+        Public method to signal a change.
+        """
+        self.__saveTimer.changeOccurred()

eric ide

mercurial