Debugger/VariablesViewer.py

changeset 5171
f1e9eebd5469
parent 5169
74e000797a93
child 5173
632257ad7337
equal deleted inserted replaced
5169:74e000797a93 5171:f1e9eebd5469
14 pass 14 pass
15 15
16 from PyQt5.QtCore import Qt, QRegExp, qVersion, QCoreApplication 16 from PyQt5.QtCore import Qt, QRegExp, qVersion, QCoreApplication
17 from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, \ 17 from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, \
18 QMenu 18 QMenu
19 from PyQt5.QtGui import QTextDocument # __IGNORE_WARNING__
20 19
21 from E5Gui.E5Application import e5App 20 from E5Gui.E5Application import e5App
22 21
23 from DebugClients.Python3.DebugConfig import ConfigVarTypeStrings
24
25 from .Config import ConfigVarTypeDispStrings 22 from .Config import ConfigVarTypeDispStrings
26 23
27 import Preferences 24 import Preferences
28 import Utilities 25 import Utilities
29 26
30 27
31 class VariableItem(QTreeWidgetItem): 28 class VariableItem(QTreeWidgetItem):
32 """ 29 """
33 Class implementing the data structure for variable items. 30 Class implementing the data structure for variable items.
34 """ 31 """
32 Indicators = ("()", "[]", "{:}", "{}") # __IGNORE_WARNING_M613__
33 Type2Indicators = {
34 # Python types
35 'list': '[]',
36 'tuple': '()',
37 'dict': '{:}', # __IGNORE_WARNING_M613__
38 'set': '{}', # __IGNORE_WARNING_M613__
39 'frozenset': '{}', # __IGNORE_WARNING_M613__
40 }
41
35 def __init__(self, parent, dvar, dvalue, dtype): 42 def __init__(self, parent, dvar, dvalue, dtype):
36 """ 43 """
37 Constructor 44 Constructor
38 45
39 @param parent reference to the parent item 46 @param parent reference to the parent item
40 @param dvar variable name (string) 47 @param dvar variable name (string)
41 @param dvalue value string (string) 48 @param dvalue value string (string)
42 @param dtype type string (string) 49 @param dtype type string (string)
43 """ 50 """
51 dvar, self.__varID = VariableItem.extractId(dvar)
52
44 self.__value = dvalue 53 self.__value = dvalue
45 if len(dvalue) > 2048: # 1024 * 2 54 if len(dvalue) > 2048: # 1024 * 2
46 dvalue = QCoreApplication.translate( 55 dvalue = QCoreApplication.translate(
47 "VariableItem", "<double click to show value>") 56 "VariableItem", "<double click to show value>")
48 self.__tooltip = dvalue 57 self.__tooltip = dvalue
75 Public method to return the value of the item. 84 Public method to return the value of the item.
76 85
77 @return value of the item (string) 86 @return value of the item (string)
78 """ 87 """
79 return self.__value 88 return self.__value
80 89
90 def getId(self):
91 """
92 Public method to get the ID string.
93
94 @return ID string
95 @rtype str
96 """
97 return self.__varID
98
99 @classmethod
100 def extractId(cls, var):
101 """
102 Class method to extract the ID string from a variable text.
103
104 @param var variable text
105 @type str
106 @return tuple containing the variable text without ID and the ID string
107 @rtype tuple of two str
108 """
109 if " (ID:" in var:
110 dvar, varID = var.rsplit(None, 1)
111 if varID.endswith(VariableItem.Indicators):
112 varID, indicators = VariableItem.extractIndicators(varID)
113 dvar += indicators
114 else:
115 dvar = var
116 varID = None
117
118 return dvar, varID
119
120 @classmethod
121 def extractIndicators(cls, var):
122 """
123 Class method to extract the indicator string from a variable text.
124
125 @param var variable text
126 @type str
127 @return tuple containing the variable text without indicators and the
128 indicator string
129 @rtype tuple of two str
130 """
131 for indicator in VariableItem.Indicators:
132 if var.endswith(indicator):
133 return var[:-len(indicator)], indicator
134
135 return var, ""
136
137 def _buildKey(self):
138 """
139 Protected method to build the access key for the variable.
140
141 @return access key
142 @type str
143 """
144 indicators = ""
145 txt = self.text(0)
146 if txt.endswith(VariableItem.Indicators):
147 txt, indicators = VariableItem.extractIndicators(txt)
148 if self.__varID:
149 txt = "{0} {1}{2}".format(txt, self.__varID, indicators)
150 else:
151 txt = "{0}{1}".format(txt, indicators)
152 return txt
153
81 def data(self, column, role): 154 def data(self, column, role):
82 """ 155 """
83 Public method to return the data for the requested role. 156 Public method to return the data for the requested role.
84 157
85 This implementation changes the original behavior in a way, that the 158 This implementation changes the original behavior in a way, that the
154 Public method to expand the item. 227 Public method to expand the item.
155 """ 228 """
156 self.deleteChildren() 229 self.deleteChildren()
157 self.populated = True 230 self.populated = True
158 231
159 pathlist = [self.text(0)] 232 pathlist = [self._buildKey()]
160 par = self.parent() 233 par = self.parent()
161 234
162 # step 1: get a pathlist up to the requested variable 235 # step 1: get a pathlist up to the requested variable
163 while par is not None: 236 while par is not None:
164 pathlist.insert(0, par.text(0)) 237 pathlist.insert(0, par._buildKey())
165 par = par.parent() 238 par = par.parent()
166 239
167 # step 2: request the variable from the debugger 240 # step 2: request the variable from the debugger
168 filter = e5App().getObject("DebugUI").variablesFilter(self.globalScope) 241 filter = e5App().getObject("DebugUI").variablesFilter(self.globalScope)
169 e5App().getObject("DebugServer").remoteClientVariable( 242 e5App().getObject("DebugServer").remoteClientVariable(
219 Array elements have numbers as names, but the key must be 292 Array elements have numbers as names, but the key must be
220 right justified and zero filled to 6 decimal places. Then 293 right justified and zero filled to 6 decimal places. Then
221 element 2 will have a key of '000002' and appear before 294 element 2 will have a key of '000002' and appear before
222 element 10 with a key of '000010' 295 element 10 with a key of '000010'
223 """ 296 """
224 col0Str = self.text(0)[:-2] # strip off [], () or {} 297 # strip off [], () or {}
225 indicator = self.text(0)[-2:] 298 col0Str, indicators = VariableItem.extractIndicators(self.text(0))
226 self.setText(0, "{0:6d}{1}".format(int(col0Str), indicator)) 299 self.setText(0, "{0:6d}{1}".format(int(col0Str), indicators))
227 300
228 301
229 class VariablesViewer(QTreeWidget): 302 class VariablesViewer(QTreeWidget):
230 """ 303 """
231 Class implementing the variables viewer widget. 304 Class implementing the variables viewer widget.
251 """ 324 """
252 super(VariablesViewer, self).__init__(parent) 325 super(VariablesViewer, self).__init__(parent)
253 326
254 self.__debugViewer = viewer 327 self.__debugViewer = viewer
255 self.__globalScope = globalScope 328 self.__globalScope = globalScope
256
257 self.indicators = {
258 # Python types
259 'list': '[]',
260 'tuple': '()',
261 'dict': '{}', # __IGNORE_WARNING__
262
263 }
264 329
265 self.rx_class = QRegExp('<.*(instance|object) at 0x.*>') 330 self.rx_class = QRegExp('<.*(instance|object) at 0x.*>')
266 self.rx_class2 = QRegExp('class .*') 331 self.rx_class2 = QRegExp('class .*')
267 self.rx_class3 = QRegExp('<class .* at 0x.*>') 332 self.rx_class3 = QRegExp('<class .* at 0x.*>')
268 self.dvar_rx_class1 = QRegExp( 333 self.dvar_rx_class1 = QRegExp(
368 if node is None: 433 if node is None:
369 count = self.topLevelItemCount() 434 count = self.topLevelItemCount()
370 else: 435 else:
371 count = node.childCount() 436 count = node.childCount()
372 437
438 if column == 0:
439 searchStr = VariableItem.extractId(slist[0])[0]
440 else:
441 searchStr = slist[0]
442
373 for index in range(count): 443 for index in range(count):
374 if node is None: 444 if node is None:
375 itm = self.topLevelItem(index) 445 itm = self.topLevelItem(index)
376 else: 446 else:
377 itm = node.child(index) 447 itm = node.child(index)
378 if itm.text(column) == slist[0]: 448 if itm.text(column) == searchStr:
379 if len(slist) > 1: 449 if len(slist) > 1:
380 itm = self.__findItem(slist[1:], column, itm) 450 itm = self.__findItem(slist[1:], column, itm)
381 return itm 451 return itm
382 452
383 return None 453 return None
540 @return The item that was added to the listview (QTreeWidgetItem). 610 @return The item that was added to the listview (QTreeWidgetItem).
541 """ 611 """
542 if parent is None: 612 if parent is None:
543 parent = self 613 parent = self
544 try: 614 try:
545 dvar = '{0}{1}'.format(var, self.indicators[vtype]) 615 dvar = '{0}{1}'.format(var, VariableItem.Type2Indicators[vtype])
546 except KeyError: 616 except KeyError:
547 dvar = var 617 dvar = var
548 dvtype = self.__getDispType(vtype) 618 dvtype = self.__getDispType(vtype)
549 619
550 if vtype in ['list', 'Array', 'tuple', 'dict', 'Hash']: 620 if vtype in ['list', 'tuple', 'dict', 'set', 'frozenset']:
551 itm = self.__generateItem(parent, dvar, 621 itm = self.__generateItem(parent, dvar,
552 self.tr("{0} items").format(value), 622 self.tr("{0} items").format(value),
553 dvtype, True) 623 dvtype, True)
554 elif vtype in ['unicode', 'str']: 624 elif vtype in ['unicode', 'str']:
555 if self.rx_nonprintable.indexIn(value) != -1: 625 if self.rx_nonprintable.indexIn(value) != -1:
573 @param vtype the type, the display string should be looked up for 643 @param vtype the type, the display string should be looked up for
574 (string) 644 (string)
575 @return displaystring (string) 645 @return displaystring (string)
576 """ 646 """
577 try: 647 try:
578 i = ConfigVarTypeStrings.index(vtype) 648 dvtype = self.tr(ConfigVarTypeDispStrings[vtype])
579 dvtype = self.tr(ConfigVarTypeDispStrings[i]) 649 except KeyError:
580 except ValueError:
581 if vtype == 'classobj': 650 if vtype == 'classobj':
582 dvtype = self.tr(ConfigVarTypeDispStrings[ 651 dvtype = self.tr(ConfigVarTypeDispStrings['instance'])
583 ConfigVarTypeStrings.index('instance')])
584 else: 652 else:
585 dvtype = vtype 653 dvtype = vtype
586 return dvtype 654 return dvtype
587 655
588 def __refreshView(self): 656 def __refreshView(self):
626 694
627 if not val: 695 if not val:
628 return # do not display anything, if the variable has no value 696 return # do not display anything, if the variable has no value
629 697
630 vtype = itm.text(2) 698 vtype = itm.text(2)
631 name = itm.text(0) 699 name = VariableItem.extractIndicators(itm.text(0).strip())[0]
632 if name[-2:] in ['[]', '{}', '()']: # __IGNORE_WARNING__
633 name = name[:-2]
634 700
635 par = itm.parent() 701 par = itm.parent()
636 nlist = [name] 702 nlist = [name]
637 # build up the fully qualified name 703 # build up the fully qualified name
638 while par is not None: 704 while par is not None:
639 pname = par.text(0) 705 pname, indicators = VariableItem.extractIndicators(
640 if pname[-2:] in ['[]', '{}', '()']: # __IGNORE_WARNING__ 706 par.text(0).strip())
707 if indicators:
641 if nlist[0].endswith("."): 708 if nlist[0].endswith("."):
642 nlist[0] = '[{0}].'.format(nlist[0][:-1]) 709 nlist[0] = '[{0}].'.format(nlist[0][:-1])
643 else: 710 else:
644 nlist[0] = '[{0}]'.format(nlist[0]) 711 nlist[0] = '[{0}]'.format(nlist[0])
645 nlist.insert(0, pname[:-2]) 712 nlist.insert(0, pname)
646 else: 713 else:
647 nlist.insert(0, '{0}.'.format(pname)) 714 nlist.insert(0, '{0}.'.format(pname))
648 par = par.parent() 715 par = par.parent()
649 716
650 name = ''.join(nlist) 717 name = ''.join(nlist)

eric ide

mercurial