X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sface%2Fxmlwidget.py;h=b24de60248a918289c4fb3d6e77ff03135e34196;hb=9c27ebe87eabf14d9bcc3d7b54e88ce6b33b3be6;hp=da6563ed585007983b9d8f6b99fcebbf753a52b7;hpb=99a5613d5bf887070a67eb2208ba907091fe41fb;p=sface.git diff --git a/sface/xmlwidget.py b/sface/xmlwidget.py index da6563e..b24de60 100644 --- a/sface/xmlwidget.py +++ b/sface/xmlwidget.py @@ -8,6 +8,19 @@ from PyQt4.QtXml import * from sface.config import config from sface.screens.sfascreen import SfaScreen +def QVarMapAccess(qv, key): + # helper function. qv is a dict wrapped into a QVariant + print 10*'=' + print "DICT:", qv.toMap() + if len(qv.toMap().keys()) == 0: + print "EMPTY!" + import traceback + traceback.print_stack() + return None + else: + return qv.toMap()[QString(key)].toString() + + class DomModel(QAbstractItemModel): def __init__(self, document, parent = 0): QAbstractItemModel.__init__(self, parent) @@ -19,11 +32,12 @@ class DomModel(QAbstractItemModel): currElem = childList.item(i) if (currElem.nodeType() == QDomNode.ProcessingInstructionNode): document.removeChild(currElem) + print "REMOVED!" break self.rootItem = DomItem(document, 0); def data(self, index, role = Qt.DisplayRole): - # sometimes it return a QString, sometimes a QVariant. not good. + # for interesting nodes, returns a dict wrapped into a QVariant. if not index.isValid(): return QVariant() if role != Qt.DisplayRole: @@ -40,45 +54,58 @@ class DomModel(QAbstractItemModel): elem = ' %s="%s"' % (attr.nodeName(), attr.nodeValue()) qslist.append(elem) ElemNameAndAtts = '%s%s'% (node.nodeName(), qslist.join(' ')) - obj = QObject() - obj.setProperty('nodeType', QString('element')) - obj.setProperty('content', ElemNameAndAtts) - return obj + print "1" + return QVariant( + {'nodeType':QVariant(QString('element')), + 'content':ElemNameAndAtts}) elif node.nodeType() == QDomNode.AttributeNode: + print "2" return QVariant() elif node.nodeType() == QDomNode.TextNode: - obj = QObject() - obj.setProperty('nodeType', QString('text')) - obj.setProperty('content', node.nodeValue()) - return obj + print "3" + return QVariant( + {'nodeType':QVariant(QString('text')), + 'content':node.nodeValue()}) elif node.nodeType() == QDomNode.CDATASectionNode: + print "4" return QString('unsupported node type') elif node.nodeType() == QDomNode.EntityReferenceNode: + print "5" return QString('unsupported node type') elif node.nodeType() == QDomNode.EntityNode: + print "6" return QString('unsupported node type') elif node.nodeType() == QDomNode.ProcessingInstructionNode: + print "7" return QVariant() elif node.nodeType() == QDomNode.CommentNode: - obj = QObject() - obj.setProperty('nodeType', QString('comment')) - obj.setProperty('content', node.nodeValue()) - return obj + print "8" + return QVariant( + {'nodeType':QVariant(QString('comment')), + 'content':node.nodeValue()}) elif node.nodeType() == QDomNode.DocumentNode: + print "9" return QString('unsupported node type') elif node.nodeType() == QDomNode.DocumentTypeNode: + print "10" return QString('unsupported node type') elif node.nodeType() == QDomNode.DocumentFragmentNode: + print "12" return QString('unsupported node type') elif node.nodeType() == QDomNode.NotationNode: + print "13" return QString('unsupported node type') elif node.nodeType() == QDomNode.BaseNode: + print "14" return QString('unsupported node type') elif node.nodeType() == QDomNode.CharacterDataNode: + print "15" return QString('unsupported node type') else: + print "16" return QVariant() else: + print "17" return QVariant() def flags(self, index): @@ -157,9 +184,15 @@ class DomItem: return self.rowNumber class XmlView(QTreeView): - def __init__(self, parent): + def __init__(self, parent=None): QTreeView.__init__(self, parent) + delegate = XmlDelegate(self) + delegate.insertNodeDelegate('element', ElemNodeDelegate()) + delegate.insertNodeDelegate('text', TextNodeDelegate()) + delegate.insertNodeDelegate('comment', CommentNodeDelegate()) + self.setItemDelegate(delegate) + self.setAnimated(True) self.setItemsExpandable(True) self.setRootIsDecorated(True) @@ -167,52 +200,6 @@ class XmlView(QTreeView): self.setAttribute(Qt.WA_MacShowFocusRect, 0) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) -class XmlWindow(QDialog): - def __init__(self, parent=None, title='XML Window'): - QDialog.__init__(self, parent) - self.setWindowTitle(title) - - self.document = None - self.model = None - self.title = title - - self.view = XmlView(self) - self.delegate = XmlDelegate(self) - self.view.setItemDelegate(self.delegate) - self.delegate.insertNodeDelegate('element', ElemNodeDelegate()) - self.delegate.insertNodeDelegate('text', TextNodeDelegate()) - self.delegate.insertNodeDelegate('comment', CommentNodeDelegate()) - layout = QVBoxLayout() - layout.addWidget(self.view) - self.setLayout(layout) - - self.updateView() - - def show(self): - self.updateView() - QDialog.show(self) - - def updateView(self): - del self.document - del self.model - self.document = None - self.model = None - - self.document = QDomDocument(self.title) - 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() - if not os.path.exists(rspec_file): - return - - self.document.setContent(open(rspec_file,'r').read()) - - - class XmlDelegate(QItemDelegate): def __init__(self, parent=None): @@ -228,9 +215,11 @@ class XmlDelegate(QItemDelegate): del self.delegates[nodeType] def paint(self, painter, option, index): - nodeType = index.model().data(index).property('nodeType') - delegate = self.delegates.get(str(nodeType.toString())) - #print "TYPE:", str(type(str(nodeType.toString()))) + print "ASKING FOR DATA" + dataAsQVarMap = index.model().data(index) + print "GOT DATA" + nodeType = str(QVarMapAccess(dataAsQVarMap, 'nodeType')) + delegate = self.delegates.get(nodeType) #print "DELEGS DICT:", self.delegates #print "NODETYPE:", nodeType.toString() if delegate is not None: @@ -239,47 +228,106 @@ class XmlDelegate(QItemDelegate): else: #print "ELSE BRANCH" # not sure this will ever work. this delegate - # doesn't know about my QObject strategy. + # doesn't know about my QMap strategy. QItemDelegate.paint(self, painter, option, index) - def sizeHint(self, option, index): - fm = option.fontMetrics - 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) - - - +# def sizeHint(self, option, index): +# fm = option.fontMetrics +# print "TYPE:", str(type(index.model().data(index).convert(QObject))) +# text = "the fish doesn't talk" +# #text = str(index.model().data(index).property('content').toString()) +# nodeType = str(index.model().data(index).property('nodeType').toString()) +# if nodeType == 'element' or nodeType == 'comment': +# numlines = 1 +# elif nodeType == 'text': +# numlines = text.count('\n') +# sys.__stdout__.write("TEXT: \n" + text) +# else: +# numlines = 1 +# 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) * numlines) class ElemNodeDelegate(QAbstractItemDelegate): def paint(self, painter, option, index): - text = index.model().data(index).property('content').toString() + palette = QApplication.palette() + document = QTextDocument() + document.setDefaultFont(option.font) + nonHighGlobPattern = '<%s%s>' + nonHighAttPattern = ' %s="%s"' + highGlobPattern = '<%s%s>' + highAttPattern = ' %s="%s"' + def getHtmlText(plainText, globPattern, attPattern): + tmp = plainText.split(' ', 1) + elemName = tmp[0] + AttListHtml = '' + if len(tmp) > 1: + # many elems don't have atts... + attList = tmp[1].split() + for att in attList: + tmp = att.split('=') + attName = tmp[0] + attValue = tmp[1][1:-1] + AttListHtml += (nonHighAttPattern % (attName, attValue)) + html = (globPattern % (elemName, AttListHtml)) + return html + def colorize(color, text): + return '' + text + '' + dataAsQVarMap = index.model().data(index) + text = str(QVarMapAccess(dataAsQVarMap, 'content')) + if option.state & QStyle.State_Selected: + htmlText = colorize(palette.highlightedText().color().name(), + getHtmlText(text, highGlobPattern, highAttPattern)) + document.setHtml(QString(htmlText)) + else: + htmlText = getHtmlText(text, nonHighGlobPattern, nonHighAttPattern) + document.setHtml(QString(htmlText)) + color = palette.highlight().color() \ + if option.state & QStyle.State_Selected \ + else palette.base().color() painter.save() - font = option.font - font.setBold(True) - painter.setFont(font) - painter.drawText(option.rect, Qt.AlignLeft, QString(text)) - #print "ELEM DELEG CALLED" + # voodoo: if not highlighted, filling the rect + # with the base color makes no difference + painter.fillRect(option.rect, color) + painter.translate(option.rect.x(), option.rect.y()) + document.drawContents(painter) painter.restore() - def sizeHint(self, option, index): - sizeHint(self, option, index) - class TextNodeDelegate(QAbstractItemDelegate): def paint(self, painter, option, index): - #print "TEXT DELEG CALLED" - paint(self, painter, option, index) - - def sizeHint(self, option, index): - sizeHint(self, option, index) + palette = QApplication.palette() + document = QTextDocument() + document.setDefaultFont(option.font) + def verbatimize(text): + text.replace('\n', '
') + return '
' + text + '' + text + ''
+        dataAsQVarMap = index.model().data(index)
+        text = str(QVarMapAccess(dataAsQVarMap, 'content'))
+        if option.state & QStyle.State_Selected:
+            htmlText = colorize(palette.highlightedText().color().name(),
+                                verbatimize(text))
+            document.setHtml(QString(htmlText))
+        else:
+            htmlText = verbatimize(text)
+            document.setHtml(QString(htmlText))
+        color = palette.highlight().color() \
+            if option.state & QStyle.State_Selected \
+            else palette.base().color()
+        painter.save()
+        # voodoo: if not highlighted, filling the rect
+        # with the base color makes no difference
+        painter.fillRect(option.rect, color)
+        painter.translate(option.rect.x(), option.rect.y())
+        document.drawContents(painter)
+        painter.restore()
 
 class CommentNodeDelegate(QAbstractItemDelegate):
     def paint(self, painter, option, index): 
-        #print "TEXT DELEG CALLED"
         paint(self, painter, option, index)
 
 def paint(self, painter, option, index):