diff options
author | mkaay <mkaay@mkaay.de> | 2009-12-13 00:26:58 +0100 |
---|---|---|
committer | mkaay <mkaay@mkaay.de> | 2009-12-13 00:26:58 +0100 |
commit | d9bb207f5c5553fb86f44bb78c8ad7519a6be8cd (patch) | |
tree | 85a3ac9c1b44ede10df1d431995dc7ce926124a2 | |
parent | create automatic script folders (diff) | |
download | pyload-d9bb207f5c5553fb86f44bb78c8ad7519a6be8cd.tar.xz |
gui queue view - unstable (non thread safe)
-rw-r--r-- | pyLoadQtGui.py | 322 |
1 files changed, 214 insertions, 108 deletions
diff --git a/pyLoadQtGui.py b/pyLoadQtGui.py index f77c6b962..94fd33aa5 100644 --- a/pyLoadQtGui.py +++ b/pyLoadQtGui.py @@ -23,7 +23,7 @@ SERVER_VERSION = "0.3" import sys -from time import sleep +from time import sleep, time from PyQt4.QtCore import * from PyQt4.QtGui import * @@ -41,6 +41,7 @@ class main(QObject): self.connector = connector() self.connector.start() + sleep(1) self.mainWindow.show() self.testStuff() @@ -89,6 +90,7 @@ class main(QObject): self.mainWindow.tabs["collector_packages"]["treewidget"].addTopLevelItem(item) #test for queue + """ packs = self.connector.getPackageQueue() for data in packs: item = QTreeWidgetItem() @@ -101,6 +103,12 @@ class main(QObject): sub.setData(0, Qt.DisplayRole, QVariant(info["filename"])) sub.setData(1, Qt.DisplayRole, QVariant(info["status_type"])) self.mainWindow.tabs["queue"]["treewidget"].addTopLevelItem(item) + """ + model = QueueModel(self.connector) + model.setView(self.mainWindow.tabs["queue"]["view"]) + self.mainWindow.tabs["queue"]["view"].setModel(model) + self.mainWindow.tabs["queue"]["view"].setup() + model.startLoop() class connector(QThread): def __init__(self): @@ -171,6 +179,12 @@ class connector(QThread): grab package files and return ids """ return self.proxy.get_package_files(id) + + def getDownloadQueue(self): + """ + grab files that are currently downloading and return info + """ + return self.proxy.status_downloads() class mainWindow(QMainWindow): def __init__(self): @@ -230,10 +244,8 @@ class mainWindow(QMainWindow): #queue self.tabs["queue"]["l"] = QGridLayout() self.tabs["queue"]["w"].setLayout(self.tabs["queue"]["l"]) - self.tabs["queue"]["treewidget"] = QTreeWidget() - self.tabs["queue"]["l"].addWidget(self.tabs["queue"]["treewidget"]) - self.tabs["queue"]["treewidget"].setColumnCount(2) - self.tabs["queue"]["treewidget"].setHeaderLabels(["Name", "Status"]) + self.tabs["queue"]["view"] = QueueView() + self.tabs["queue"]["l"].addWidget(self.tabs["queue"]["view"]) #collector_packages self.tabs["collector_packages"]["l"] = QGridLayout() @@ -256,23 +268,25 @@ class QueueFile(): self.data = data def getID(self): - return self.data.id + return self.data["id"] class QueuePack(): def __init__(self, data): - self.data = {} + self.data = data self.children = [] - self.update(data) def update(self, data): self.data = data - def addChild(self, NewQFile): - for QFile in self.children: + def addChild(self, NewQFile, model, index): + for k, QFile in enumerate(self.children): if QFile.getID() == NewQFile.getID(): QFile.update(NewQFile.data) + #model.emit(SIGNAL("dataChanged(const QModelIndex topLeft, const QModelIndex bottomRight)"), model.index(k, 0, index), model.index(k, 2, index)) return - self.children.append(QFile) + model.beginInsertRows(index, len(self.children), len(self.children)+1) + self.children.append(NewQFile) + model.endInsertRows() def getChildren(self): return self.children @@ -280,73 +294,64 @@ class QueuePack(): def getID(self): return self.data["id"] -class QueueIndex(QModelIndex): - def __init__(self): - QModelIndex.__init__(self, model) - self.model = model - self.row = None - self.col = None - self.type = None - self.id = None - - def isValid(self, checkID=True): - if self.col >= self.model.columnCount(): - #column not exists - return False - if self.type == "pack": - #index points to a package - pos = self.model._inQueue(self.id) - if pos == self.row: - #row match - if checkID and self.model.queue[pos].getID() != self.id: - #should I check the id? if yes, is it wrong? - return False - #id okay or check off - return True - elif self.type == "file": - #index points to a file - for pack in self.model.queue: - #all packs - for k, child in enumerate(pack.getChildren()): - #all children - if k == self.row: - #row match - if checkID and child.getID() != self.id: - #should I check the id? if yes, is it wrong? - return False - #id okay or check off - return True - #row invalid or type not matched - return False - class QueueModel(QAbstractItemModel): def __init__(self, connector): + QAbstractItemModel.__init__(self) + self.mutex = QMutex() + self.mutex.lock() self.connector = connector self.queue = [] + self.downloading = [] + self.statusMap = { + "finished": 0, + "checking": 1, + "waiting": 2, + "reconnected": 3, + "downloading": 4, + "failed": 5, + "aborted": 6, + } + self.statusMapReverse = dict((v,k) for k, v in self.statusMap.iteritems()) self.cols = 3 - self._update() + self.interval = 1 + self.view = None + self.mutex.unlock() + self.update() + self.loop = self.Loop(self) + + def setView(self, view): + self.view = view def _update(self): packs = self.connector.getPackageQueue() previous = None for data in packs: pos = self._inQueue(data["id"]) - if pos != False: - pack = self.queue[pos] - pack.update(data) + if not type(pos) == int: + pack = QueuePack(data) else: pack = QueuePack(data) + self.queue[pos] = pack + if not type(pos) == int: + self._insertPack(pack, previous) files = self.connector.getPackageFiles(data["id"]) - for id in files: - info = self.connector.getLinkInfo(id) + pos = self._inQueue(data["id"]) + for fid in files: + info = self.connector.getLinkInfo(fid) qFile = QueueFile(info, pack) - pack.addChild(qFile) - if pos == False: - tmpID = None - if previous != None: - tmpID = previous.getID() - self._insertPack(self, pack, tmpID) - previous = pack + if type(pos) == int: + pack.addChild(qFile, self, self.index(pos, 0)) + previous = pack.getID() + + def update(self): + locker = QMutexLocker(self.mutex) + self._update() + self.downloading = self.connector.getDownloadQueue() + #if self.view: + # self.view.emit(SIGNAL("update()")) + + def startLoop(self): + self.loop.start() def _inQueue(self, pid): for k, pack in enumerate(self.queue): @@ -354,83 +359,184 @@ class QueueModel(QAbstractItemModel): return k return False - def _insertPack(self, pack, prevID): + def _insertPack(self, newpack, prevID): + ck = 0 for k, pack in enumerate(self.queue): - if pack.getID() == pid: + ck = k + if pack.getID() == prevID: break - self.queue.insert(k+1, pack) + self.beginInsertRows(QModelIndex(),ck+1, ck+2) + self.queue.insert(ck+1, newpack) + self.endInsertRows() def index(self, row, column, parent=QModelIndex()): if parent == QModelIndex(): - #create from root - index = QueueIndex(self) - index.row, index.col, index.type = row, col, "pack" - if index.isValid(checkID=False): - #row and column okay - index.id = self.queue[row].getID() + pointer = self.queue[row] + index = self.createIndex(row, column, pointer) elif parent.isValid(): - #package or file - index = QueueIndex(self) - index.row, index.col, index.type = row, col, "file" - if index.isValid(checkID=False): - #row and column okay - for pack in self.queue: - if pack.getID() == parent.id: - #it is our pack - #now grab the id of the file - index.id = pack.getChildren()[row].getID() + q = self.nodeFromIndex(parent) + pointer = q.getChildren()[row] + index = self.createIndex(row, column, pointer) + else: + index = QModelIndex() + return index + + def nodeFromIndex(self, index): + if index.isValid(): + return index.internalPointer() + else: + return None def parent(self, index): - if index.type == "pack": + if index == QModelIndex(): return QModelIndex() if index.isValid(): - index = QueueIndex(self) - index.col, index.type = 0, "pack" - for k, pack in enumerate(self.queue): - if pack.getChildren()[index.row].getID() == index.id: - index.row, index.id = k, pack.getID() - if index.isValid(): - return index - else: - break + q = self.nodeFromIndex(index) + if isinstance(q, QueueFile): + row = None + for k, pack in enumerate(self.queue): + if pack.getID() == q.pack.getID(): + row = k + if row != None: + return self.createIndex(row, 0, q.pack) + return QModelIndex() def rowCount(self, parent=QModelIndex()): if parent == QModelIndex(): #return package count return len(self.queue) else: - if parent.isVaild(): + if parent.isValid(): #index is valid - if parent.type == "pack": + q = self.nodeFromIndex(parent) + if isinstance(q, QueuePack): #index points to a package #return len of children - return len(self.queue[parent.row].getChildren()) + return len(q.getChildren()) else: #index is invalid return False #files have no children - return None + return 0 def columnCount(self, parent=QModelIndex()): return self.cols def data(self, index, role=Qt.DisplayRole): - if not parent.isValid() or parent.col != 0: + if not index.isValid(): return QVariant() if role == Qt.DisplayRole: - if parent.type == "pack": - return QVariant(self.queue[parent.row].data["package_name"]) - else: - #TODO: return something! - return QVariant() - else: - return QVariant() - - def fetchMore(self, parent): - pass + q = self.nodeFromIndex(index) + if index.column() == 0: + if isinstance(q, QueuePack): + return QVariant(q.data["package_name"]) + else: + return QVariant(q.data["filename"]) + elif index.column() == 1: + if isinstance(q, QueueFile): + return QVariant(q.data["status_type"]) + else: + status = 0 + for child in q.getChildren(): + if self.statusMap.has_key(child.data["status_type"]) and self.statusMap[child.data["status_type"]] > status: + status = self.statusMap[child.data["status_type"]] + return QVariant(self.statusMapReverse[status]) + return QVariant() + + def hasChildren(self, parent=QModelIndex()): + if not parent.isValid(): + return True + return (self.rowCount(parent) > 0) def canFetchMore(self, parent): - return True + return False + + def headerData(self, section, orientation, role=Qt.DisplayRole): + if orientation == Qt.Horizontal and role == Qt.DisplayRole: + if section == 0: + return QVariant("Name") + elif section == 1: + return QVariant("Status") + elif section == 2: + return QVariant("Fortschritt") + return QVariant() + + def getProgress(self, index): + q = self.nodeFromIndex(index) + if isinstance(q, QueueFile): + for d in self.downloading: + if d["id"] == q.getID(): + return int(d["percent"]) + if q.data["status_type"] == "finished" or \ + q.data["status_type"] == "failed" or \ + q.data["status_type"] == "aborted": + return 100 + elif isinstance(q, QueuePack): + children = q.getChildren() + count = len(children) + perc_sum = 0 + for child in children: + val = 0 + for d in self.downloading: + if d["id"] == child.getID(): + val = int(d["percent"]) + break + if child.data["status_type"] == "finished" or \ + child.data["status_type"] == "failed" or \ + child.data["status_type"] == "aborted": + val = 100 + perc_sum += val + if count == 0: + return None + return perc_sum/count + return None + + class Loop(QThread): + def __init__(self, module): + QThread.__init__(self) + self.module = module + self.running = True + + def run(self): + while self.running: + sleep(self.module.interval) + self.module.update() + +class QueueView(QTreeView): + def __init__(self): + QTreeView.__init__(self) + + def setup(self): + self.setColumnWidth(0, 300) + self.setColumnWidth(1, 100) + self.setColumnWidth(2, 100) + delegate = QueueProgressBarDelegate(self) + self.setItemDelegateForColumn(2, delegate) + +class QueueProgressBarDelegate(QItemDelegate): + def __init__(self, parent): + QItemDelegate.__init__(self, parent) + + def paint(self, painter, option, index): + if index.column() == 2: + model = index.model() + progress = model.getProgress(index) + if progress == None: + QItemDelegate.paint(self, painter, option, index) + return + opts = QStyleOptionProgressBarV2()
+ opts.maximum = 100
+ opts.minimum = 0
+ opts.progress = progress
+ opts.rect = option.rect
+ opts.rect.setRight(option.rect.right()-1)
+ opts.rect.setHeight(option.rect.height()-1)
+ opts.textVisible = True
+ opts.textAlignment = Qt.AlignCenter + opts.text = QString.number(opts.progress) + "%"
+ QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter) + return + QItemDelegate.paint(painter, option, index) if __name__ == "__main__": app = main() |