SF.net SVN: fclient:[895] trunk/fclient/fclient/impl/ViewDownloads.py
Status: Pre-Alpha
Brought to you by:
jurner
From: <jU...@us...> - 2008-08-11 10:41:55
|
Revision: 895 http://fclient.svn.sourceforge.net/fclient/?rev=895&view=rev Author: jUrner Date: 2008-08-11 10:42:00 +0000 (Mon, 11 Aug 2008) Log Message: ----------- massive comb over ++ irems can now be removed groupwise Modified Paths: -------------- trunk/fclient/fclient/impl/ViewDownloads.py Modified: trunk/fclient/fclient/impl/ViewDownloads.py =================================================================== --- trunk/fclient/fclient/impl/ViewDownloads.py 2008-08-11 10:41:15 UTC (rev 894) +++ trunk/fclient/fclient/impl/ViewDownloads.py 2008-08-11 10:42:00 UTC (rev 895) @@ -38,6 +38,7 @@ # like the only way to control the flood is to have one connection/dl. maybe wait for freenet devels # to realize that this is a serious problem... # x. byte amount postfixes must be transllated ++ use Kib or Kb or let the user decide? +# x. sometimes groups of dls get not removed #************************************************************************************************************** from __future__ import absolute_import if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below @@ -155,12 +156,31 @@ trigger=parent.onRestartSelectedDownloads, isEnabled=False, ) + + #TODO: enable/disable if items of that type are available? + group = self.group( + name='GroupRemoveGroup', + trigger=parent.onRemoveGroup, + ) + self.action( + name='ActionRemoveFailed', + group=group, + text=self.trUtf8('Failed'), + isEnabled=False, + ) + self.action( + name='ActionRemoveCompleted', + group=group, + text=self.trUtf8('Completed'), + isEnabled=False, + ) class DownloadsWidgetSettings(config.SettingsBase): _key_ = config.IdViewDownloadsWidget _settings_ = ( + ('MaxSimultaneousDownloads', 'UInt', 3), ) #********************************************************************************** # @@ -175,28 +195,49 @@ #********************************************************************************** class TreeItem(QtGui.QTreeWidgetItem): + IndexName = 0 + IndexSize = 1 + IndexMimeType = 2 + IndexStatus = 3 + IndexProgress = 4 + IndexPriority = 5 + IndexElapsed = 6 + + ProgressBarName = 'downloadKey' + + StatusPending = 'pending' + StatusLoading = 'loading' + StatusComplete = 'complete' + StatusError = 'error' + StatusRemoved = 'removed' + def __init__(self, fcpRequest, *params): QtGui.QTreeWidgetItem.__init__(self, *params) self.fcpRequest = fcpRequest + self.fcOldStatus = self.StatusPending - -# exposes properties for stylesheets + def status(self): + if self.fcpRequest is None: + return self.StatusRemoved + elif self.fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Success: + return self.StatusComplete + elif self.fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Error: + return self.StatusError + elif self.fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Started: + return self.StatusLoading + else: + return self.StatusPending + +# exposes status property for stylesheets class ProgressBar(QtGui.QProgressBar): def __init__(self, parent, item): QtGui.QProgressBar.__init__(self, parent) self.item = item - def _status(self): - if self.item.fcpRequest is not None: - if self.item.fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Error: - return "error" - elif self.item.fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Completed: - return "complete" - else: - return QtCore.QString("loading") - return "notset" - status= QtCore.pyqtProperty("QString", _status) + def _get_status(self): + return self.item.status() + status= QtCore.pyqtProperty("QString", _get_status) #********************************************************************************** # @@ -204,21 +245,14 @@ class ViewDownloadsWidget(QtGui.QWidget, Ui_ViewDownloadsWidget): IdTree = 'tree' - - - HeaderIndexName = 0 - HeaderIndexSize = 1 - HeaderIndexMimeType = 2 - HeaderIndexStatus = 3 - HeaderIndexProgress = 4 - HeaderIndexElapsed = 5 - + def __init__(self, parent, idGlobalFeedback=config.IdMainWindow): QtGui.QWidget.__init__(self, parent) self._isCreated = False self.fcHeaderLabels = {} # fcpIdentifier --> treeItem self.fcpRequests = {} - self.fcRequestStatus = {} + self.fcRequestStatusNames = {} + self.menuRemoveGroup = QtGui.QMenu(self) self.setupUi(self) @@ -240,29 +274,59 @@ ) config.fcpClient.events += self.fcpClientEvents + # setup menus + for action in self.fcActions['GroupRemoveGroup'].actions(): + self.menuRemoveGroup.addAction(action) + ############################ ## private methods ############################ - def _adjustStatusBar(self, item, status): + def _adjustItemStatus(self, item): # to take Css styling into account we have to set a new statusBar for each state change - oldProgressBar= self.tree.itemWidget(item, self.HeaderIndexProgress) - progressBar = ProgressBar(self.tree, item) - progressBar.setObjectName('downloadKey') - if status == 'loading': + tree = self.controlById(self.IdTree) + oldProgressBar = progressBar = self.tree.itemWidget(item, TreeItem.IndexProgress) + itemStatus = item.status() + itemStatusChanged = itemStatus != item.fcOldStatus + if itemStatusChanged: + progressBar = ProgressBar(self.tree, item) + + # adjust statusBar and set a new one if necessary + # ..bit much work here, but necessary, cos Fcp might come up with + # ..a completed message without any prior progress notifications + if itemStatus == TreeItem.StatusPending: progressBar.setRange(0, 0) - elif status == 'complete': + elif itemStatus == TreeItem.StatusLoading: + progressBar.setRange(0, item.fcpRequest['ProgressRequired']) + progressBar.setValue(item.fcpRequest['ProgressSucceeded']) + elif itemStatus == TreeItem.StatusComplete: progressBar.setRange(0, 1) progressBar.setValue(progressBar.maximum()) - elif status == 'error': - progressbar.setMinimum(oldProgressBar.minimum()) - progressbar.setMaximum(oldProgressBar.maximum()) - progressbar.setValue(oldProgressBar.value()) + elif itemStatus == TreeItem.StatusError: + progressBar.setMinimum(oldProgressBar.minimum()) + progressBar.setMaximum(oldProgressBar.maximum()) + progressBar.setValue(oldProgressBar.value()) + elif itemStatus == TreeItem.StatusRemoved: + pass else: - raise ValueError('Unknown status: %r' % status) - self.tree.setItemWidget(item, self.HeaderIndexProgress, progressBar) + raise ValueError('Unknown status: %r' % itemStatus) + if itemStatusChanged: + progressBar.setObjectName(TreeItem.ProgressBarName) + tree.setItemWidget(item, TreeItem.IndexProgress, progressBar) + item.setData( + TreeItem.IndexStatus, + QtCore.Qt.DisplayRole, + QtCore.QVariant(self.fcRequestStatusNames[itemStatus]), + ) + item.fcOldStatus = itemStatus def _createItemFromFcpRequest(self, fcpRequest): - item= TreeItem(fcpRequest, self.tree) + tree = self.controlById(self.IdTree) + root = tree.invisibleRootItem() + item= TreeItem(fcpRequest, root) + progressBar = ProgressBar(self.tree, item) + + progressBar.setObjectName(TreeItem.ProgressBarName) + tree.setItemWidget(item, TreeItem.IndexProgress, progressBar) fileName = fcpRequest['Filename'] mimeType = mimetypes.guess_type(fileName)[0] icon = config.fcResources.getIcon( @@ -272,12 +336,21 @@ ) item.setIcon(0, icon) item.setData( - self.HeaderIndexName, + TreeItem.IndexName, QtCore.Qt.DisplayRole, QtCore.QVariant(os.path.basename(fcpRequest['Filename'])) ) - self._adjustStatusBar(item, 'loading') + + #TODO: take a wild guess at the size. no other way to do it currently + estimatedSize = int((BLOCK_SIZE * fcpRequest['ProgressRequired']) + 1) + item.setData( + TreeItem.IndexSize, + QtCore.Qt.DisplayRole, + QtCore.QVariant(self.trUtf8('< ') + numbers.format_num_bytes(estimatedSize)), + ) + self.fcpRequests[fcpRequest['Identifier']] = item + self._adjustItemStatus(item) return item ############################ @@ -286,24 +359,36 @@ def retranslateUi(self, parent): Ui_ViewDownloadsWidget.retranslateUi(self, parent) tree = self.controlById(self.IdTree) + root = tree.invisibleRootItem() + + # adjust header labels self.fcHeaderLabels = { - self.HeaderIndexName: self.trUtf8('Name'), - self.HeaderIndexSize: self.trUtf8('Size'), - self.HeaderIndexMimeType: self.trUtf8('MimeType'), - self.HeaderIndexStatus: self.trUtf8('Status'), - self.HeaderIndexProgress: self.trUtf8('Progress'), - self.HeaderIndexElapsed: self.trUtf8('Elapsed'), + TreeItem.IndexName: self.trUtf8('Name'), + TreeItem.IndexSize: self.trUtf8('Size'), + TreeItem.IndexMimeType: self.trUtf8('MimeType'), + TreeItem.IndexStatus: self.trUtf8('Status'), + TreeItem.IndexPriority: self.trUtf8('Priority'), + TreeItem.IndexProgress: self.trUtf8('Progress'), + TreeItem.IndexElapsed: self.trUtf8('Elapsed'), } tree.setHeaderLabels([i[1] for i in sorted(self.fcHeaderLabels.items())]) - self.fcRequestStatus = { - None: self.trUtf8('Pending'), - fcp2.ConstRequestStatus.Started: self.trUtf8('Loading'), - fcp2.ConstRequestStatus.Completed: self.trUtf8('Complete'), - fcp2.ConstRequestStatus.Error: self.trUtf8('Error'), + # adjust status names and retranslate all items + self.fcRequestStatusNames = { + TreeItem.StatusPending: self.trUtf8('Pending'), + TreeItem.StatusLoading: self.trUtf8('Loading'), + TreeItem.StatusComplete: self.trUtf8('Complete'), + TreeItem.StatusError: self.trUtf8('Error'), + TreeItem.StatusRemoved: self.trUtf8('Removed'), } - #TODO: retranslate all tree items - + for item in treewidgetwrap.walkItem(root): + fcpRequest = getattr(item, 'fcpRequest', None) + if hasattr(item, 'fcpRequest'): + item.setText(TreeItem.IndexStatus, self.fcRequestStatusNames[item.status()]) + + # others + self.menuRemoveGroup.setTitle(self.trUtf8('Remove group')) + def closeEvent(self): self.viewClose() @@ -335,7 +420,6 @@ def downloadFile(self, fcpKey, fileName, **kws): """""" - fileName = unicode(fileName) fcpRequest = config.fcpClient.getFile( fcpKey, @@ -347,13 +431,7 @@ **kws ) item = self._createItemFromFcpRequest(fcpRequest) - item.setData( - self.HeaderIndexStatus, - QtCore.Qt.DisplayRole, - QtCore.QVariant(self.fcRequestStatus[None]), - ) - def populateMenu(self, menu): menu.addAction(self.fcActions['ActionDownloadKeyToDisk']) return menu @@ -397,9 +475,7 @@ del self.fcpRequests[tmp_item.fcpRequest['Identifier']] config.fcpClient.removeRequest(tmp_item.fcpRequest) tmp_item.fcpRequest = None - - - + def onRestartSelectedDownloads(self, action): tree = self.controlById(self.IdTree) for item in tree.selectedItems(): @@ -408,8 +484,37 @@ del self.fcpRequests[item.fcpRequest['Identifier']] item.fcpRequest = config.fcpClient.resendRequest(item.fcpRequest) self.fcpRequests[item.fcpRequest['Identifier']] = item - self._adjustStatusBar(item, 'loading') + self._adjustItemStatus(item) + def onRemoveGroup(self, action): + tree = self.controlById(self.IdTree) + root = tree.invisibleRootItem() + + if action == self.fcActions['ActionRemoveCompleted']: + flag = fcp2.ConstRequestStatus.Success + elif action == self.fcActions['ActionRemoveFailed']: + flag = fcp2.ConstRequestStatus.Error + else: + raise ValueError('Not implemented') + + for item in treewidgetwrap.walkItem(root, topdown=False): + fcpRequest = getattr(item, 'fcpRequest', None) + if fcpRequest is not None: + if fcpRequest['Identifier'] in self.fcpRequests: #TODO: should never be False?! check + del self.fcpRequests[fcpRequest['Identifier']] + + if fcpRequest['RequestStatus'] & fcp2.ConstRequestStatus.Removed: + pass + elif not fcpRequest['RequestStatus'] & flag: + continue + else: + item.fcpRequest = None + config.fcpClient.removeRequest(fcpRequest) + parent = item.parent() + if parent is None: + parent = root + parent.removeChild(item) + def onTreeCustomContextMenuRequested(self, pt): tree = self.controlById(self.IdTree) pt = tree.viewport().mapToGlobal(pt) @@ -417,13 +522,12 @@ menu = QtGui.QMenu(self) menu.addAction(self.fcActions['ActionRemoveSelectedDownloads']) menu.addAction(self.fcActions['ActionRestartSelectedDownloads']) - + menu.addMenu(self.menuRemoveGroup) menu.exec_(pt) def onTreeItemSelectionChanged(self): tree = self.controlById(self.IdTree) hasSelectedItems = tree.selectionModel().hasSelection() - self.fcActions['ActionRemoveSelectedDownloads'].setEnabled(hasSelectedItems) self.fcActions['ActionRestartSelectedDownloads'].setEnabled(hasSelectedItems) @@ -447,33 +551,22 @@ item = self.fcpRequests.get(fcpRequest['Identifier'], None) if item is not None: item.setData( - self.HeaderIndexSize, + TreeItem.IndexSize, QtCore.Qt.DisplayRole, QtCore.QVariant(numbers.format_num_bytes(fcpRequest['MetadataSize'])) ) item.setData( - self.HeaderIndexMimeType, + TreeItem.IndexMimeType, QtCore.Qt.DisplayRole, QtCore.QVariant(fcpRequest['MetadataContentType']) ) - item.setData( - self.HeaderIndexStatus, - QtCore.Qt.DisplayRole, - QtCore.QVariant(self.fcRequestStatus[fcp2.ConstRequestStatus.Completed]), - ) - self._adjustStatusBar(item, 'complete') + self._adjustItemStatus(item) def onFcpClientRequestFailed(self, fcpEvent, fcpRequest): - item = self.fcpRequests.get(rfcpRequest['Identifier'], None) + item = self.fcpRequests.get(fcpRequest['Identifier'], None) if item is not None: - self._adjustStatusBar(item, 'error') - item.setData( - self.HeaderIndexStatus, - QtCore.Qt.DisplayRole, - QtCore.QVariant(self.fcRequestStatus[fcp2.ConstRequestStatus.Error]), - ) - - + self._adjustItemStatus(item) + #TODO: not tested def onFcpClientRequestModified(self, fcpEvent, fcpRequest): @@ -490,7 +583,7 @@ if fcp2.ConstRequestModified.Filename in fcpRequest['Modified']: item.setData( - self.HeaderIndexName, + TreeItem.IndexName, QtCore.Qt.DisplayRole, QtCore.QVariant(os.path.basename(fcpRequest['Filename'])) ) @@ -499,20 +592,8 @@ def onFcpClientRequestProgress(self, fcpEvent, fcpRequest): item = self.fcpRequests.get(fcpRequest['Identifier'], None) if item is not None: - progressBar = self.tree.itemWidget(item, self.HeaderIndexProgress) - - progressBar.setRange(0, fcpRequest['ProgressRequired']) - progressBar.setValue(fcpRequest['ProgressSucceeded']) - - #TODO: take a wild guess at the size. no other way to do it currently - estimatedSize = int((BLOCK_SIZE * fcpRequest['ProgressRequired']) + 1) - item.setData( - self.HeaderIndexSize, - QtCore.Qt.DisplayRole, - QtCore.QVariant(self.trUtf8('< ') + numbers.format_num_bytes(estimatedSize)), - ) + self._adjustItemStatus(item) - def onFcpClientRequestRemoved(self, fcpEvent, fcpRequest): pass @@ -525,11 +606,10 @@ else: if requestData.get('ClientName', None) == self.objectName(): item = self._createItemFromFcpRequest(fcpRequest) - item.setData( - self.HeaderIndexStatus, - QtCore.Qt.DisplayRole, - QtCore.QVariant(self.fcRequestStatus[fcp2.ConstRequestStatus.Started]), - ) + else: + item = self.fcpRequests.get(fcpRequest['Identifier'], None) + if item is not None: + self._adjustItemStatus(item) #********************************************************************************** # This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |