X-Git-Url: http://git.onelab.eu/?p=sface.git;a=blobdiff_plain;f=sface%2Fxmlwidget.py;h=47dedebd0c5f65fcfeff788784aa9dc0ba855c75;hp=a2d3ec2312d6a9a24c484e843ba4c68df92e5779;hb=9be93c1e7a8a2a4e0cd1c890e9ebe2acf6030787;hpb=1dbdb55c8d56e3c82047dc29a6789183f76d07a7 diff --git a/sface/xmlwidget.py b/sface/xmlwidget.py index a2d3ec2..47dedeb 100644 --- a/sface/xmlwidget.py +++ b/sface/xmlwidget.py @@ -1,4 +1,5 @@ import os +import shlex import sys from PyQt4.QtCore import * @@ -12,14 +13,6 @@ class DomModel(QAbstractItemModel): def __init__(self, document, parent = 0): QAbstractItemModel.__init__(self, parent) self.domDocument = document - # one of the children of the rootItem is the 'xml' thing. - # here I delete it. - childList = document.childNodes() - for i in range(childList.count()): - currElem = childList.item(i) - if (currElem.nodeType() == QDomNode.ProcessingInstructionNode): - document.removeChild(currElem) - break self.rootItem = DomItem(document, 0); def data(self, index, role = Qt.DisplayRole): @@ -58,7 +51,10 @@ class DomModel(QAbstractItemModel): elif node.nodeType() == QDomNode.EntityNode: return QString('unsupported node type') elif node.nodeType() == QDomNode.ProcessingInstructionNode: - return QVariant() + obj = QObject() + obj.setProperty('nodeType', QString('element')) + obj.setProperty('content', node.nodeName() + " " + node.nodeValue()) + return obj elif node.nodeType() == QDomNode.CommentNode: obj = QObject() obj.setProperty('nodeType', QString('comment')) @@ -85,7 +81,7 @@ class DomModel(QAbstractItemModel): if not index.isValid(): return Qt.ItemIsEnabled return Qt.ItemIsEnabled | Qt.ItemIsSelectable - + def headerData(self, section, orientation, role): return QVariant() @@ -176,7 +172,7 @@ class XmlWindow(QDialog): self.model = None self.title = title - self.view = XmlView(self) + self.view = self.initView() self.delegate = XmlDelegate(self) self.view.setItemDelegate(self.delegate) self.delegate.insertNodeDelegate('element', ElemNodeDelegate()) @@ -188,10 +184,13 @@ class XmlWindow(QDialog): self.updateView() + def initView(self): + return XmlView(self) + def show(self): self.updateView() QDialog.show(self) - + def updateView(self): del self.document del self.model @@ -202,7 +201,6 @@ class XmlWindow(QDialog): self.model = DomModel(self.document, self) self.view.setModel(self.model) - self.view.expand(self.model.index(0, 0)) #expand first level only #move the code below to rspec window rspec_file = config.getSliceRSpecFile() @@ -211,6 +209,18 @@ class XmlWindow(QDialog): self.document.setContent(open(rspec_file,'r').read()) + if self.document.childNodes().count() == 0: + # empty document - do nothing + pass + elif self.document.childNodes().item(0).nodeType() == QDomNode.ProcessingInstructionNode: + # the first item is the tag, so expand the second + self.view.expand(self.model.index(1,0)) + else: + # the document didn't start with an tag; let's try to expand + # the first item on the assumption that it is our root level xml + # tag. + self.view.expand(self.model.index(0,0)) + class XmlDelegate(QItemDelegate): @@ -228,6 +238,8 @@ class XmlDelegate(QItemDelegate): del self.delegates[nodeType] def paint(self, painter, option, index): + if isinstance(index.model().data(index),QVariant): + return nodeType = index.model().data(index).property('nodeType') delegate = self.delegates.get(str(nodeType.toString())) #print "TYPE:", str(type(str(nodeType.toString()))) @@ -244,13 +256,15 @@ class XmlDelegate(QItemDelegate): def sizeHint(self, option, index): fm = option.fontMetrics + if isinstance(index.model().data(index),QVariant): + return QSize(0, 0) text = index.model().data(index).property('content').toString() document = QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) # the +5 is for margin. The +4 is voodoo; # fm.height just give it too small. - return QSize(document.idealWidth() + 5, fm.height() + 4) + return QSize(document.idealWidth() + 5, fm.height() + 4) class ElemNodeDelegate(QAbstractItemDelegate): def paint(self, painter, option, index): @@ -263,25 +277,35 @@ class ElemNodeDelegate(QAbstractItemDelegate): highGlobPattern = '<%s%s>' highAttPattern = ' %s="%s"' def getHtmlText(plainText, globPattern, attPattern): - print "PLAIN TEXT:", plainText +# print "PLAIN TEXT:", plainText tmp = plainText.split(' ', 1) - print "TMP:", tmp +# print "TMP:", tmp elemName = tmp[0] AttListHtml = '' if len(tmp) > 1: # many elems don't have atts... - attList = tmp[1].split() + # use shlex.split so we can handle quoted strings with spaces + # in them, like . Note that there are + # documented problems with shlex.split and unicode, so we + # convert any potential unicode to a string first. + attList = shlex.split(str(tmp[1])) for att in attList: - tmp = att.split('=') - attName = tmp[0] - attValue = tmp[1][1:-1] + tmp = att.split('=',1) + if len(tmp)>=2: + attName = tmp[0] + attValue = tmp[1] + else: + # this shouldn't happen, but if it does, pretend the + # attribute value is blank. + attName = tmp[0] + attValue = "" AttListHtml += (nonHighAttPattern % (attName, attValue)) html = (globPattern % (elemName, AttListHtml)) return html def colorize(color, text): return '' + text + '' text = str(index.model().data(index).property('content').toString()) - print "TEXT:", text +# print "TEXT:", text if option.state & QStyle.State_Selected: htmlText = colorize(palette.highlightedText().color().name(), getHtmlText(text, highGlobPattern, highAttPattern)) @@ -293,7 +317,7 @@ class ElemNodeDelegate(QAbstractItemDelegate): if option.state & QStyle.State_Selected \ else palette.base().color() painter.save() - print "COLOR:", color.name() +# print "COLOR:", color.name() # voodoo: if not highlighted, filling the rect # with the base color makes no difference painter.fillRect(option.rect, color)