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