1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
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
76
77
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
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:
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:
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
132
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):
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:
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