From c3786a55ebf09c0bc22fc23da529d0cca14dd210 Mon Sep 17 00:00:00 2001 From: Andy Bavier Date: Mon, 21 Feb 2011 13:10:06 -0500 Subject: [PATCH] Make tags children of nodes Moved the slice tags to be children of the nodes they belong to, rather than a separate column. GUI tweaks to make it look a bit cleaner. --- sface/screens/mainscreen.py | 200 +++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 95 deletions(-) diff --git a/sface/screens/mainscreen.py b/sface/screens/mainscreen.py index 7b4bc67..4792179 100644 --- a/sface/screens/mainscreen.py +++ b/sface/screens/mainscreen.py @@ -15,6 +15,18 @@ node_status = { "in": "Already Selected", "add": "To be Added", "remove": "To be Removed"} +tag_status = { "in": "Already Set", + "out": "Not Set", + "add": "To be Added", + "remove": "To be Removed"} + +def itemType(index): + if index.parent().parent().isValid(): + return "tag" + else: + return "node" + + class NodeView(QTreeView): def __init__(self, parent): QTreeView.__init__(self, parent) @@ -33,25 +45,34 @@ class NodeView(QTreeView): model = index.model() status_index = model.index(index.row(), 2, index.parent()) status_data = status_index.data().toString() - hostname_index = model.index(index.row(), 1, index.parent()) - hostname_data = hostname_index.data().toString() - tags_index = model.index(index.row(), 3, index.parent()) - - if status_data == node_status['in']: - model.setData(status_index, QString(node_status['remove'])) - elif status_data == node_status['out']: - model.setData(status_index, QString(node_status['add'])) - elif status_data in (node_status['add'], node_status['remove']): - if hostname_data in already_in_nodes: model.setData(status_index, QString(node_status['in'])) + node_index = model.index(index.row(), 1, index.parent()) + node_data = node_index.data().toString() + + if itemType(node_index) == "tag": + if status_data == tag_status['in']: + model.setData(status_index, QString(tag_status['remove'])) + elif status_data == tag_status['add']: + model.setData(status_index, QString(tag_status['out'])) + elif status_data == tag_status['remove']: + model.setData(status_index, QString(tag_status['in'])) else: model.setData(status_index, QString(node_status['out'])) + else: + # This is a hostname + if status_data == node_status['in']: + model.setData(status_index, QString(node_status['remove'])) + elif status_data == node_status['out']: + model.setData(status_index, QString(node_status['add'])) + elif status_data in (node_status['add'], node_status['remove']): + if node_data in already_in_nodes: model.setData(status_index, QString(node_status['in'])) + else: model.setData(status_index, QString(node_status['out'])) - model.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), hostname_index, tags_index) + model.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), node_index, node_index) def currentChanged(self, current, previous): model = current.model() - hostname_index = model.index(current.row(), 1, current.parent()) - hostname_data = hostname_index.data().toString() - self.emit(SIGNAL('hostnameClicked(QString)'), hostname_data) + node_index = model.index(current.row(), 1, current.parent()) + node_data = node_index.data().toString() + self.emit(SIGNAL('hostnameClicked(QString)'), node_data) @@ -61,102 +82,87 @@ class NodeNameDelegate(QStyledItemDelegate): def paint(self, painter, option, index): model = index.model() - data = "%s" % index.data().toString() status_index = model.index(index.row(), 2, index.parent()) status_data = status_index.data().toString() - if status_data not in (node_status['in'], node_status['remove'], node_status['add']): - # default view - QStyledItemDelegate.paint(self, painter, option, index) - return - fm = QFontMetrics(option.font) rect = option.rect - rect.setWidth(fm.width(QString(data)) + 8) - rect.setHeight(rect.height() - 2) - rect.setX(rect.x() + 4) - x, y, h, w = rect.x(), rect.y(), rect.height(), rect.width() - - path = QPainterPath() - path.addRoundedRect(x, y, w, h, 4, 4) - - painter.save() - painter.setRenderHint(QPainter.Antialiasing) - painter.drawRoundedRect(rect, 4, 4) - - if status_data == node_status['in']: # already in the slice - painter.fillPath(path, QColor("cyan")) - painter.setPen(QColor.fromRgb(0, 0, 0)) - painter.drawText(option.rect, 0, QString(data)) - - elif status_data == node_status['add']: # newly added to the slice - painter.fillPath(path, QColor.fromRgb(0, 250, 0)) - painter.setPen(QColor.fromRgb(0, 0, 0)) - painter.drawText(option.rect, 0, QString(data)) - painter.drawRect(x + w + 10, y + 3, 10, 10) - painter.fillRect(x + w + 10, y + 3, 10, 10, QColor.fromRgb(0, 250, 0)) - - elif status_data == node_status['remove']: # removed from the slice - painter.fillPath(path, QColor.fromRgb(250, 0, 0)) - painter.setPen(QColor.fromRgb(0, 0, 0)) - painter.drawText(option.rect, 0, QString(data)) - painter.drawRect(x + w + 10, y + 3, 10, 10) - painter.fillRect(x + w + 10, y + 3, 10, 10, QColor.fromRgb(250, 0, 0)) - painter.restore() + if itemType(index) == "node": + data = "%s" % index.data().toString() + #if status_data not in (node_status['in'], node_status['remove'], node_status['add']): + # default view + # QStyledItemDelegate.paint(self, painter, option, index) + # return + rect.setHeight(rect.height() - 2) + rect.setWidth(fm.width(QString(data)) + 6) + rect.setX(rect.x() + 5) + rect.setY(rect.y() - 1) + x, y, h, w = rect.x(), rect.y(), rect.height(), rect.width() -class NodeTagDelegate(QStyledItemDelegate): - def __init__(self, parent): - QStyledItemDelegate.__init__(self, parent) + path = QPainterPath() + path.addRoundedRect(x - 1, y + 1, w, h, 4, 4) - def paint(self, painter, option, index): - model = index.model() - taglist = index.data().toStringList() - status_index = model.index(index.row(), 2, index.parent()) - status_data = status_index.data().toString() + painter.save() + painter.setRenderHint(QPainter.Antialiasing) - if taglist.isEmpty() or status_data not in (node_status['in'], ""): - return + if status_data == node_status['in']: # already in the slice + painter.fillPath(path, QColor("cyan")) + painter.setPen(QColor.fromRgb(0, 0, 0)) + painter.drawText(option.rect, 0, QString(data)) + elif status_data == node_status['add']: # newly added to the slice + painter.fillPath(path, QColor.fromRgb(0, 250, 0)) + painter.setPen(QColor.fromRgb(0, 0, 0)) + painter.drawText(option.rect, 0, QString(data)) + + elif status_data == node_status['remove']: # removed from the slice + painter.fillPath(path, QColor.fromRgb(250, 0, 0)) + painter.setPen(QColor.fromRgb(0, 0, 0)) + painter.drawText(option.rect, 0, QString(data)) + + else: + painter.setPen(QColor.fromRgb(0, 0, 0)) + painter.drawText(option.rect, 0, QString(data)) + + else: + indent = 16 + tag = index.data().toStringList() + data = "%s: %s" % (tag[0], tag[1]) + rect.setHeight(rect.height() - 2) + rect.setWidth(fm.width(QString(data)) + 6 + indent) + rect.setX(rect.x() + 4 + indent) + rect.setY(rect.y() - 1) - fm = QFontMetrics(option.font) - rect = option.rect - rect.setHeight(rect.height() - 2) - rect.setX(rect.x() + 4) - - for i in range(0, len(taglist), 2): - # This taglist is pretty much of a hack. Not quite sure the best - # way to use Qt data structures. - data = taglist[i] - status = taglist[i+1] - rect.setWidth(fm.width(QString(data)) + 8) x, y, h, w = rect.x(), rect.y(), rect.height(), rect.width() path = QPainterPath() - path.addRoundedRect(x, y, w, h, 4, 4) + path.addRoundedRect(x - 1, y + 1, w, h, 4, 4) painter.save() painter.setRenderHint(QPainter.Antialiasing) - painter.drawRoundedRect(rect, 4, 4) - if status == 'in': # already in the slice + if status_data == tag_status['in']: # already in the slice painter.fillPath(path, QColor("cyan")) painter.setPen(QColor.fromRgb(0, 0, 0)) painter.drawText(option.rect, 0, QString(data)) - elif status == 'add': # newly added to the slice + elif status_data == tag_status['add']: # newly added to the slice painter.fillPath(path, QColor.fromRgb(0, 250, 0)) painter.setPen(QColor.fromRgb(0, 0, 0)) painter.drawText(option.rect, 0, QString(data)) - elif status == 'remove': # removed from the slice + elif status_data == tag_status['remove']: # removed from the slice painter.fillPath(path, QColor.fromRgb(250, 0, 0)) painter.setPen(QColor.fromRgb(0, 0, 0)) painter.drawText(option.rect, 0, QString(data)) - painter.restore() - rect.setX(rect.x() + rect.width() + 4) + else: + painter.setPen(QColor.fromRgb(0, 0, 0)) + painter.drawText(option.rect, 0, QString(data)) + + painter.restore() class TreeItem: @@ -245,7 +251,7 @@ class NodeModel(QAbstractItemModel): self.__initRoot() def __initRoot(self): - self.rootItem = TreeItem([QString("Testbed"), QString("Hostname"), QString("Status"), QString("Tags")]) + self.rootItem = TreeItem([QString("Testbed"), QString("Hostname"), QString("Status")]) def getItem(self, index): if index.isValid(): @@ -311,6 +317,13 @@ class NodeModel(QAbstractItemModel): item = self.getItem(index) return item.data(index.column()) + def nodestatus(self, index): + if not index.isValid(): + return QVariant() + + item = self.getItem(index) + return item.nodestatus(index.column()) + def flags(self, index): if not index.isValid(): return 0 @@ -353,7 +366,6 @@ class SliceWidget(QWidget): self.filterModel = QSortFilterProxyModel(self) # enable filtering self.nodeNameDelegate = NodeNameDelegate(self) - self.nodeTagDelegate = NodeTagDelegate(self) refresh = QPushButton("Update Slice Data", self) refresh.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) @@ -474,12 +486,12 @@ class SliceWidget(QWidget): for network in networks: self.network_names.append(network) data = [QString(network), QString(""), QString("")] - taglist = QStringList() - attrs = rspec.get_default_sliver_attributes(network) - for (name, value) in attrs: - taglist.append(QString("%s/%s" % (name, value))) - taglist.append(QString("in")) - data.append(taglist) + #taglist = QStringList() + #attrs = rspec.get_default_sliver_attributes(network) + #for (name, value) in attrs: + # taglist.append(QString("%s/%s" % (name, value))) + # taglist.append(QString("in")) + #data.append(taglist) networkItem = TreeItem(data, self.nodeModel.rootItem) all_nodes = rspec.get_node_list(network) sliver_nodes = rspec.get_sliver_list(network) @@ -489,16 +501,15 @@ class SliceWidget(QWidget): for node in sliver_nodes: data = [QString(""), QString(node), QString(node_status['in'])] - taglist = QStringList() - attrs = rspec.get_sliver_attributes(node, network) - for (name, value) in attrs: - taglist.append(QString("%s/%s" % (name, value))) - taglist.append(QString("in")) - data.append(taglist) nodeItem = TreeItem(data, networkItem) + networkItem.appendChild(nodeItem) attrs = rspec.get_sliver_attributes(node, network) - networkItem.appendChild(nodeItem) + for (name, value) in attrs: + tagstring = QStringList([name, value]) + data = [QString(""), tagstring, QString(tag_status['in'])] + tagItem = TreeItem(data, nodeItem) + nodeItem.appendChild(tagItem) for node in available_nodes: nodeItem = TreeItem([QString(""), QString(node), QString(node_status['out']), QString("")], networkItem) @@ -511,7 +522,6 @@ class SliceWidget(QWidget): self.filterModel.setDynamicSortFilter(True) self.nodeView.setItemDelegateForColumn(1, self.nodeNameDelegate) - self.nodeView.setItemDelegateForColumn(3, self.nodeTagDelegate) self.nodeView.setModel(self.filterModel) self.nodeView.expandAll() self.nodeView.resizeColumnToContents(1) -- 2.43.0