Package node_manager_fkie :: Module html_delegate
[frames] | no frames]

Source Code for Module node_manager_fkie.html_delegate

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding.QtCore import QPoint, QSize 
 34  from python_qt_binding.QtGui import QAbstractTextDocumentLayout, QFontMetrics, QTextDocument 
 35  try: 
 36      from python_qt_binding.QtGui import QApplication, QStyledItemDelegate, QStyle 
 37      from python_qt_binding.QtGui import QStyleOptionViewItemV4 as QStyleOptionViewItem 
 38  except: 
 39      from python_qt_binding.QtWidgets import QApplication, QStyledItemDelegate, QStyle 
 40      from python_qt_binding.QtWidgets import QStyleOptionViewItem 
 41   
 42  from rosgraph.names import is_legal_name 
43 44 45 -class HTMLDelegate(QStyledItemDelegate):
46 ''' 47 A class to display the HTML text in QTreeView. 48 '''
49 - def __init__(self, parent=None, check_for_ros_names=True, dec_ascent=False, is_node=False):
50 QStyledItemDelegate.__init__(self, parent) 51 self._check_for_ros_names = check_for_ros_names 52 self._cached_size = None 53 self._red_ascent = 4 if not dec_ascent else 2 54 self._dec_ascent = dec_ascent 55 self._is_node = is_node
56
57 - def paint(self, painter, option, index):
58 ''' 59 Use the QTextDokument to represent the HTML text. 60 @see: U{http://www.pyside.org/docs/pyside/PySide/QtGui/QAbstractItemDelegate.html#PySide.QtGui.QAbstractItemDelegate} 61 ''' 62 options = QStyleOptionViewItem(option) 63 self.initStyleOption(options, index) 64 65 style = QApplication.style() if options.widget is None else options.widget.style() 66 67 doc = QTextDocument() 68 doc.setHtml(self.toHTML(options.text, self._check_for_ros_names, self._is_node)) 69 70 options.text = '' 71 style.drawControl(QStyle.CE_ItemViewItem, options, painter) 72 73 ctx = QAbstractTextDocumentLayout.PaintContext() 74 75 # Highlighting text if item is selected 76 # if (optionV4.state and QStyle::State_Selected): 77 # ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText)); 78 79 textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options, options.widget) 80 if textRect.width() < 10: 81 textRect.setWidth(options.rect.width()) 82 textRect.setHeight(options.rect.height()) 83 painter.save() 84 red = self._red_ascent if not self._dec_ascent else self._red_ascent / 2 + 1 85 painter.translate(QPoint(textRect.topLeft().x(), textRect.topLeft().y() - red)) 86 painter.setClipRect(textRect.translated(-textRect.topLeft())) 87 doc.documentLayout().draw(painter, ctx) 88 89 painter.restore()
90
91 - def sizeHint(self, option, index):
92 ''' 93 Determines and returns the size of the text after the format. 94 @see: U{http://www.pyside.org/docs/pyside/PySide/QtGui/QAbstractItemDelegate.html#PySide.QtGui.QAbstractItemDelegate} 95 ''' 96 if self._cached_size is not None: 97 return self._cached_size 98 options = QStyleOptionViewItem(option) 99 self.initStyleOption(options, index) 100 doc = QTextDocument() 101 doc.setHtml(options.text) 102 doc.setTextWidth(options.rect.width()) 103 metric = QFontMetrics(doc.defaultFont()) 104 self._red_ascent = abs(metric.height() - metric.ascent()) 105 self._cached_size = QSize(doc.idealWidth(), metric.height() + self._red_ascent) 106 return self._cached_size
107 108 @classmethod
109 - def toHTML(cls, text, check_for_ros_names=True, is_node=False):
110 ''' 111 Creates a HTML representation of the given text. It could be a node, topic service or group name. 112 :param str text: a name with ROS representation 113 :return: the HTML representation of the given name 114 :rtype: str 115 ''' 116 if text.rfind('@') > 0: # handle host names 117 name, sep, host = text.rpartition('@') 118 result = '' 119 if sep: 120 result = '%s<span style="color:#3c3c3c;">%s%s</span>' % (name, sep, host) 121 else: 122 result = text 123 elif text.find('{') > -1: # handle group names 124 text = text.strip('{}') 125 ns, sep, name = text.rpartition('/') 126 result = '' 127 if sep: 128 result = '{<span style="color:#3c3c3c;">%s%s</span>%s}' % (ns, sep, name) 129 else: 130 result = '<span style="color:#3c3c3c;">{%s}</span>' % (name) 131 # result = '<b>{</b><span style="color:gray;">%s</span><b>}</b>' % (name) 132 # result = '<b>{%s}</b>' % (name) 133 elif text.find('[') > -1: 134 start_idx = text.find('[') 135 end_idx = text.find(']', start_idx) 136 nr_idx = text.find(':') 137 last_part = "" 138 if end_idx + 1 < len(text): 139 last_part = text[end_idx + 1:] 140 if nr_idx > -1 and nr_idx < start_idx: 141 result = '%s<b>%s</b><span style="color:gray;">%s</span><b>%s</b>' % (text[0:nr_idx + 1], text[nr_idx + 1:start_idx], text[start_idx:end_idx + 1], last_part) 142 else: 143 result = '<b>%s</b><span style="color:gray;">%s</span><b>%s</b>' % (text[0:start_idx], text[start_idx:end_idx + 1], last_part) 144 elif check_for_ros_names and not is_legal_name(text): # handle all invalid names (used space in the name) 145 ns, sep, name = text.rpartition('/') 146 result = '' 147 if sep: 148 result = '<span style="color:#FF6600;">%s%s<b>%s</b></span' % (ns, sep, name) 149 else: 150 result = '<span style="color:#FF6600;">%s</span>' % (name) 151 else: # handle all ROS names 152 ns, sep, name = text.rpartition('/') 153 result = '' 154 if sep: 155 result = '<span style="color:#3c3c3c;">%s%s</span><b>%s</b>' % (ns, sep, name) 156 elif is_node: 157 result = '<b>%s</b>' % name 158 else: 159 result = name 160 return result
161