4 from PyQt4.QtCore import *
5 from PyQt4.QtGui import *
6 from PyQt4.QtXml import *
8 from sface.config import config
9 from sface.screens.sfascreen import SfaScreen
12 class RSpecView(QTreeView):
13 def __init__(self, parent):
14 QTreeView.__init__(self, parent)
16 self.setAnimated(True)
17 self.setItemsExpandable(True)
18 self.setRootIsDecorated(True)
19 self.setHeaderHidden(True)
20 self.setAttribute(Qt.WA_MacShowFocusRect, 0)
21 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
23 def expandMatchingText(self, txt):
29 def recursiveExpand(index):
30 parent = index.parent()
31 if parent and parent.isValid():
32 recursiveExpand(parent)
36 if index.data().toString() == txt:
37 recursiveExpand(index)
38 self.scrollTo(index, self.PositionAtCenter)
41 rows = model.rowCount(index)
43 child_index = index.child(r, 0)
46 root_rows = model.rowCount()
47 for r in range(root_rows):
48 index = model.index(r, 0)
52 class DomModel(QAbstractItemModel):
53 def __init__(self, document, parent = 0):
54 QAbstractItemModel.__init__(self, parent)
55 self.domDocument = document
56 # one of the children of the rootItem is the 'xml' thing.
58 childList = document.childNodes()
59 for i in range(childList.count()):
60 currElem = childList.item(i)
61 if (currElem.nodeType() == QDomNode.ProcessingInstructionNode):
62 document.removeChild(currElem)
64 self.rootItem = DomItem(document, 0);
66 def data(self, index, role):
67 if not index.isValid():
69 if role != Qt.DisplayRole:
71 node = index.internalPointer().node()
72 attributeMap = node.attributes()
76 if node.nodeType() == QDomNode.ElementNode:
77 qslist = QStringList()
78 for i in range(attributeMap.count()):
79 attr = attributeMap.item(i)
80 elem = '%s="%s"' % (attr.nodeName(), attr.nodeValue())
82 return QString("<%s %s>" % (node.nodeName(), qslist.join(' ')))
83 elif node.nodeType() == QDomNode.AttributeNode:
84 return QString('Whozat?!')
85 elif node.nodeType() == QDomNode.TextNode:
86 return node.nodeValue()
87 elif node.nodeType() == QDomNode.CDATASectionNode:
88 return QString('unsupported node type')
89 elif node.nodeType() == QDomNode.EntityReferenceNode:
90 return QString('unsupported node type')
91 elif node.nodeType() == QDomNode.EntityNode:
92 return QString('unsupported node type')
93 elif node.nodeType() == QDomNode.ProcessingInstructionNode:
95 #return node.nodeName()
96 elif node.nodeType() == QDomNode.CommentNode:
97 return QString('#').append(node.nodeValue())
98 elif node.nodeType() == QDomNode.DocumentNode:
99 return QString('unsupported node type')
100 elif node.nodeType() == QDomNode.DocumentTypeNode:
101 return QString('unsupported node type')
102 elif node.nodeType() == QDomNode.DocumentFragmentNode:
103 return QString('unsupported node type')
104 elif node.nodeType() == QDomNode.NotationNode:
105 return QString('unsupported node type')
106 elif node.nodeType() == QDomNode.BaseNode:
107 return QString('unsupported node type')
108 elif node.nodeType() == QDomNode.CharacterDataNode:
109 return QString('unsupported node type')
115 def flags(self, index):
116 if not index.isValid():
117 return Qt.ItemIsEnabled
118 return Qt.ItemIsEnabled | Qt.ItemIsSelectable
120 def headerData(self, section, orientation, role):
123 def index(self, row, column, parent=None):
124 if not parent or not parent.isValid():
125 parentItem = self.rootItem
127 parentItem = parent.internalPointer()
129 childItem = parentItem.child(row)
130 # childItem would be None to say "false"?
132 return self.createIndex(row, column, childItem)
136 def parent(self, child):
137 if not child.isValid():
139 childItem = child.internalPointer()
140 parentItem = childItem.parent()
142 if not parentItem or parentItem == self.rootItem:
144 return self.createIndex(parentItem.row(), 0, parentItem)
146 def rowCount(self, parent=None):
147 if not parent or not parent.isValid():
148 parentItem = self.rootItem
150 parentItem = parent.internalPointer()
152 return parentItem.node().childNodes().count()
154 def columnCount(self, parent):
155 # just one column we'll print tag name (and attributes) or the
161 # wrapper around PyQt4.QtXml.QDomNode it keeps an hash of
162 # childrens for performance reasons
164 def __init__(self, node, row, parent = 0):
165 # node is of type PyQt4.QtXml.QDomNode
167 self.parentItem = parent
172 if i in self.childItems:
173 return self.childItems[i]
174 if i >= 0 and i < self.domNode.childNodes().count():
175 childNode = self.domNode.childNodes().item(i)
176 childItem = DomItem(childNode, i, self)
177 self.childItems[i] = childItem
182 return self.parentItem
188 return self.rowNumber
191 class RSpecWindow(QDialog):
192 def __init__(self, parent=None):
193 QDialog.__init__(self, parent)
194 self.setWindowTitle("RSPec View")
199 self.view = RSpecView(self)
200 layout = QVBoxLayout()
201 layout.addWidget(self.view)
202 self.setLayout(layout)
210 def showNode(self, hostname):
211 self.view.expandMatchingText(hostname)
213 def updateView(self):
219 rspec_file = config.getSliceRSpecFile()
220 if not os.path.exists(rspec_file):
223 self.document = QDomDocument("RSpec")
224 self.document.setContent(open(rspec_file,'r').read())
225 self.model = DomModel(self.document, self)
227 self.view.setModel(self.model)
228 self.view.expand(self.model.index(0, 0)) #expand first level only