4c8c041ec4a4cb5c45cb3eb2d83729f5778142b8
[sface.git] / sface / screens / rspecscreen.py
1 import os
2 import sys
3
4 from PyQt4.QtCore import *
5 from PyQt4.QtGui import *
6 from PyQt4.QtXml import *
7
8 from sface.config import config
9 from sface.screens.sfascreen import SfaScreen
10
11
12 class DomModel(QAbstractItemModel):
13     def __init__(self, document, parent = 0):
14         QAbstractItemModel.__init__(self, parent)
15         self.domDocument = document
16         self.rootItem = DomItem(document, 0);
17
18     def data(self, index, role):
19         if not index.isValid():
20             return QVariant()
21         if role != Qt.DisplayRole:
22             return QVariant()
23         node = index.internalPointer().node()
24         attributeMap = node.attributes()
25
26         col = index.column()
27         if col == 0:
28             if node.nodeType() == QDomNode.ElementNode:
29                 qslist = QStringList()
30                 for i in range(attributeMap.count()):
31                     attr = attributeMap.item(i)
32                     elem = (attr.nodeName()
33                             .append(QString('="'))
34                             .append(attr.nodeValue())
35                             .append(QString('"')))
36                     qslist.append(elem)
37                 return (QString('<').
38                         append(node.nodeName()).
39                         append(' ').
40                         append(qslist.join(' ')).
41                         append('>'))
42             elif node.nodeType() == QDomNode.AttributeNode:
43                 return QString('Whozat?!')
44             elif node.nodeType() == QDomNode.TextNode:
45                 return node.nodeValue()
46             elif node.nodeType() == QDomNode.CDATASectionNode:
47                 return QString('unsupported node type')
48             elif node.nodeType() == QDomNode.EntityReferenceNode:
49                 return QString('unsupported node type')
50             elif node.nodeType() == QDomNode.EntityNode:
51                 return QString('unsupported node type')
52             elif node.nodeType() == QDomNode.ProcessingInstructionNode:
53                 return node.nodeName()
54             elif node.nodeType() == QDomNode.CommentNode:
55                 return QString('#').append(node.nodeValue())
56             elif node.nodeType() == QDomNode.DocumentNode:
57                 return QString('unsupported node type')
58             elif node.nodeType() == QDomNode.DocumentTypeNode:
59                 return QString('unsupported node type')
60             elif node.nodeType() == QDomNode.DocumentFragmentNode:
61                 return QString('unsupported node type')
62             elif node.nodeType() == QDomNode.NotationNode:
63                 return QString('unsupported node type')
64             elif node.nodeType() == QDomNode.BaseNode:
65                 return QString('unsupported node type')
66             elif node.nodeType() == QDomNode.CharacterDataNode:
67                 return QString('unsupported node type')
68             else:
69                 return QVariant()
70         else:
71             return QVariant()
72
73     def flags(self, index):
74         if not index.isValid():
75             return Qt.ItemIsEnabled
76         # does this `|` thing hold?
77         return Qt.ItemIsEnabled | Qt.ItemIsSelectable
78         
79     def headerData(self, section, orientation, role):
80         if orientation == Qt.Horizontal and role == Qt.DisplayRole:
81             if section == 0:
82                 return QString("Do I need an header?")
83             else:
84                 return QVariant()
85         else:
86             return QVariant()
87
88     def index(self, row, column, parent):
89         if not parent.isValid():
90             parentItem = self.rootItem
91         else:
92             parentItem = parent.internalPointer()
93
94         childItem = parentItem.child(row)
95         # childItem would be None to say "false"?
96         if childItem:
97             return self.createIndex(row, column, childItem)
98         else:
99             return QModelIndex()
100
101     def parent(self, child):
102         if not child.isValid():
103             return QModelIndex()
104         childItem = child.internalPointer()
105         parentItem = childItem.parent()
106         
107         if not parentItem or parentItem == self.rootItem:
108             return QModelIndex()
109         return self.createIndex(parentItem.row(), 0, parentItem)
110
111     def rowCount(self, parent):
112         if not parent.isValid():
113             parentItem = self.rootItem
114         else:
115             parentItem = parent.internalPointer()
116
117         return parentItem.node().childNodes().count()
118
119     def columnCount(self, parent):
120         # just one column
121         # we'll print tag name (and attributes)
122         # or the tag content
123         return 1
124
125
126 class DomItem:
127     # wrapper around PyQt4.QtXml.QDomNode
128     # it keeps an hash of childrens for
129     # performance reasons
130
131     def __init__(self, node, row, parent = 0):
132         # node is of type PyQt4.QtXml.QDomNode
133         self.domNode = node
134         self.parentItem = parent
135         self.rowNumber = row
136         self.childItems = {}
137
138     def child(self, i):
139         if i in self.childItems:
140             return self.childItems[i]
141         if i >= 0 and i < self.domNode.childNodes().count():
142             childNode = self.domNode.childNodes().item(i)
143             childItem = DomItem(childNode, i, self)
144             self.childItems[i] = childItem
145             return childItem
146         return None
147             
148     def parent(self):
149         return self.parentItem
150
151     def node(self):
152         return self.domNode
153
154     def row(self):
155         return self.rowNumber
156     
157
158 class RSpecWidget(QWidget):
159     def __init__(self, parent=None):
160         QWidget.__init__(self, parent)
161
162     def init_view(self):
163         document = QDomDocument("RSpec")
164         rspec_file = config.getSliceRSpecFile()
165         if not os.path.exists(rspec_file):
166             return
167
168         document.setContent(open(rspec_file,'r').read())
169         model = DomModel(document, self)
170
171         view = QTreeView()
172         view.setModel(model)
173
174         layout = QVBoxLayout()
175         layout.addWidget(view)
176         self.setLayout(layout)
177
178
179 class RSpecScreen(SfaScreen):
180     def __init__(self, parent):
181         SfaScreen.__init__(self, parent)
182         
183         widget = RSpecWidget(self)
184         self.init(widget, "RSpec Window", "RSPec View")
185
186