eric6/Debugger/VariablesViewer.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 6953
b06cb5bbc880
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the variables viewer widget.
8 """
9
10 from __future__ import unicode_literals
11 try:
12 str = unicode
13 except NameError:
14 pass
15
16 from PyQt5.QtCore import Qt, QRegExp, QCoreApplication
17 from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, \
18 QMenu
19
20 from E5Gui.E5Application import e5App
21
22 from .Config import ConfigVarTypeDispStrings
23
24 import Preferences
25 import Utilities
26 from Globals import qVersionTuple
27
28
29 class VariableItem(QTreeWidgetItem):
30 """
31 Class implementing the data structure for variable items.
32 """
33 Indicators = ("()", "[]", "{:}", "{}") # __IGNORE_WARNING_M613__
34 Type2Indicators = {
35 # Python types
36 'list': '[]',
37 'tuple': '()',
38 'dict': '{:}', # __IGNORE_WARNING_M613__
39 'set': '{}', # __IGNORE_WARNING_M613__
40 'frozenset': '{}', # __IGNORE_WARNING_M613__
41 }
42
43 def __init__(self, parent, dvar, dvalue, dtype):
44 """
45 Constructor
46
47 @param parent reference to the parent item
48 @param dvar variable name (string)
49 @param dvalue value string (string)
50 @param dtype type string (string)
51 """
52 dvar, self.__varID = VariableItem.extractId(dvar)
53
54 self.__value = dvalue
55 if len(dvalue) > 2048: # 1024 * 2
56 dvalue = QCoreApplication.translate(
57 "VariableItem", "<double click to show value>")
58 self.__tooltip = dvalue
59 elif dvalue == "@@TOO_BIG_TO_SHOW@@":
60 dvalue = QCoreApplication.translate(
61 "VariableItem", "<variable value is too big>")
62 else:
63 if Qt.mightBeRichText(dvalue):
64 self.__tooltip = Utilities.html_encode(dvalue)
65 else:
66 self.__tooltip = dvalue
67 lines = dvalue.splitlines()
68 if len(lines) > 1:
69 # only show the first non-empty line;
70 # indicate skipped lines by <...> at the
71 # beginning and/or end
72 index = 0
73 while index < len(lines) - 1 and lines[index] == "":
74 index += 1
75 dvalue = ""
76 if index > 0:
77 dvalue += "<...>"
78 dvalue += lines[index]
79 if index < len(lines) - 1:
80 dvalue += "<...>"
81
82 super(VariableItem, self).__init__(parent, [dvar, dvalue, dtype])
83
84 self.populated = True
85
86 def getValue(self):
87 """
88 Public method to return the value of the item.
89
90 @return value of the item (string)
91 """
92 return self.__value
93
94 def getId(self):
95 """
96 Public method to get the ID string.
97
98 @return ID string
99 @rtype str
100 """
101 return self.__varID
102
103 @classmethod
104 def extractId(cls, var):
105 """
106 Class method to extract the ID string from a variable text.
107
108 @param var variable text
109 @type str
110 @return tuple containing the variable text without ID and the ID string
111 @rtype tuple of two str
112 """
113 if " (ID:" in var:
114 dvar, varID = var.rsplit(None, 1)
115 if varID.endswith(VariableItem.Indicators):
116 varID, indicators = VariableItem.extractIndicators(varID)
117 dvar += indicators
118 else:
119 dvar = var
120 varID = None
121
122 return dvar, varID
123
124 @classmethod
125 def extractIndicators(cls, var):
126 """
127 Class method to extract the indicator string from a variable text.
128
129 @param var variable text
130 @type str
131 @return tuple containing the variable text without indicators and the
132 indicator string
133 @rtype tuple of two str
134 """
135 for indicator in VariableItem.Indicators:
136 if var.endswith(indicator):
137 return var[:-len(indicator)], indicator
138
139 return var, ""
140
141 def _buildKey(self):
142 """
143 Protected method to build the access key for the variable.
144
145 @return access key
146 @rtype str
147 """
148 indicators = ""
149 txt = self.text(0)
150 if txt.endswith(VariableItem.Indicators):
151 txt, indicators = VariableItem.extractIndicators(txt)
152 if self.__varID:
153 txt = "{0} {1}{2}".format(txt, self.__varID, indicators)
154 else:
155 txt = "{0}{1}".format(txt, indicators)
156 return txt
157
158 def data(self, column, role):
159 """
160 Public method to return the data for the requested role.
161
162 This implementation changes the original behavior in a way, that the
163 display data is returned as the tooltip for column 1.
164
165 @param column column number (integer)
166 @param role data role (Qt.ItemDataRole)
167 @return requested data
168 """
169 if column == 1 and role == Qt.ToolTipRole:
170 return self.__tooltip
171 return super(VariableItem, self).data(column, role)
172
173 def attachDummy(self):
174 """
175 Public method to attach a dummy sub item to allow for lazy population.
176 """
177 QTreeWidgetItem(self, ["DUMMY"])
178
179 def deleteChildren(self):
180 """
181 Public method to delete all children (cleaning the subtree).
182 """
183 for itm in self.takeChildren():
184 del itm
185
186 def expand(self):
187 """
188 Public method to expand the item.
189
190 Note: This is just a do nothing and should be overwritten.
191 """
192 return
193
194 def collapse(self):
195 """
196 Public method to collapse the item.
197
198 Note: This is just a do nothing and should be overwritten.
199 """
200 return
201
202
203 class SpecialVarItem(VariableItem):
204 """
205 Class implementing a VariableItem that represents a special variable node.
206
207 These special variable nodes are generated for classes, lists,
208 tuples and dictionaries.
209 """
210 def __init__(self, parent, dvar, dvalue, dtype, frmnr, globalScope):
211 """
212 Constructor
213
214 @param parent parent of this item
215 @param dvar variable name (string)
216 @param dvalue value string (string)
217 @param dtype type string (string)
218 @param frmnr frame number (0 is the current frame) (int)
219 @param globalScope flag indicating global (True) or local (False)
220 variables
221 """
222 VariableItem.__init__(self, parent, dvar, dvalue, dtype)
223 self.attachDummy()
224 self.populated = False
225
226 self.framenr = frmnr
227 self.globalScope = globalScope
228
229 def expand(self):
230 """
231 Public method to expand the item.
232 """
233 self.deleteChildren()
234 self.populated = True
235
236 pathlist = [self._buildKey()]
237 par = self.parent()
238
239 # step 1: get a pathlist up to the requested variable
240 while par is not None:
241 pathlist.insert(0, par._buildKey())
242 par = par.parent()
243
244 # step 2: request the variable from the debugger
245 variablesFilter = e5App().getObject("DebugUI").variablesFilter(
246 self.globalScope)
247 e5App().getObject("DebugServer").remoteClientVariable(
248 self.globalScope, variablesFilter, pathlist, self.framenr)
249
250
251 class ArrayElementVarItem(VariableItem):
252 """
253 Class implementing a VariableItem that represents an array element.
254 """
255 def __init__(self, parent, dvar, dvalue, dtype):
256 """
257 Constructor
258
259 @param parent parent of this item
260 @param dvar variable name (string)
261 @param dvalue value string (string)
262 @param dtype type string (string)
263 """
264 VariableItem.__init__(self, parent, dvar, dvalue, dtype)
265
266 """
267 Array elements have numbers as names, but the key must be
268 right justified and zero filled to 6 decimal places. Then
269 element 2 will have a key of '000002' and appear before
270 element 10 with a key of '000010'
271 """
272 col0Str = self.text(0)
273 self.setText(0, "{0:6d}".format(int(col0Str)))
274
275
276 class SpecialArrayElementVarItem(SpecialVarItem):
277 """
278 Class implementing a QTreeWidgetItem that represents a special array
279 variable node.
280 """
281 def __init__(self, parent, dvar, dvalue, dtype, frmnr, globalScope):
282 """
283 Constructor
284
285 @param parent parent of this item
286 @param dvar variable name (string)
287 @param dvalue value string (string)
288 @param dtype type string (string)
289 @param frmnr frame number (0 is the current frame) (int)
290 @param globalScope flag indicating global (True) or local (False)
291 variables
292 """
293 SpecialVarItem.__init__(self, parent, dvar, dvalue, dtype, frmnr,
294 globalScope)
295
296 """
297 Array elements have numbers as names, but the key must be
298 right justified and zero filled to 6 decimal places. Then
299 element 2 will have a key of '000002' and appear before
300 element 10 with a key of '000010'
301 """
302 # strip off [], () or {}
303 col0Str, indicators = VariableItem.extractIndicators(self.text(0))
304 self.setText(0, "{0:6d}{1}".format(int(col0Str), indicators))
305
306
307 class VariablesViewer(QTreeWidget):
308 """
309 Class implementing the variables viewer widget.
310
311 This widget is used to display the variables of the program being
312 debugged in a tree. Compound types will be shown with
313 their main entry first. Once the subtree has been expanded, the
314 individual entries will be shown. Double clicking an entry will
315 popup a dialog showing the variables parameters in a more readable
316 form. This is especially useful for lengthy strings.
317
318 This widget has two modes for displaying the global and the local
319 variables.
320 """
321 def __init__(self, viewer, globalScope, parent=None):
322 """
323 Constructor
324
325 @param viewer reference to the debug viewer object (DebugViewer)
326 @param globalScope flag indicating global (True) or local (False)
327 variables
328 @param parent the parent (QWidget)
329 """
330 super(VariablesViewer, self).__init__(parent)
331
332 self.__debugViewer = viewer
333 self.__globalScope = globalScope
334
335 indicatorPattern = "|".join([QRegExp.escape(indicator)
336 for indicator in VariableItem.Indicators])
337 self.rx_class = QRegExp('<.*(instance|object) at 0x.*>')
338 self.rx_class2 = QRegExp('class .*')
339 self.rx_class3 = QRegExp('<class .* at 0x.*>')
340 self.dvar_rx_class1 = QRegExp(
341 r'<.*(instance|object) at 0x.*>({0})'.format(indicatorPattern))
342 self.dvar_rx_class2 = QRegExp(
343 r'<class .* at 0x.*>({0})'.format(indicatorPattern))
344 self.dvar_rx_array_element = QRegExp(r'^\d+$')
345 self.dvar_rx_special_array_element = QRegExp(
346 r'^\d+({0})$'.format(indicatorPattern))
347 self.rx_nonprintable = QRegExp(r"""(\\x\d\d)+""")
348
349 self.framenr = 0
350
351 self.loc = Preferences.getSystem("StringEncoding")
352
353 self.openItems = []
354
355 self.setRootIsDecorated(True)
356 self.setAlternatingRowColors(True)
357 self.setSelectionBehavior(QAbstractItemView.SelectRows)
358
359 if self.__globalScope:
360 self.setWindowTitle(self.tr("Global Variables"))
361 self.setHeaderLabels([
362 self.tr("Globals"),
363 self.tr("Value"),
364 self.tr("Type")])
365 self.setWhatsThis(self.tr(
366 """<b>The Global Variables Viewer Window</b>"""
367 """<p>This window displays the global variables"""
368 """ of the debugged program.</p>"""
369 ))
370 else:
371 self.setWindowTitle(self.tr("Local Variables"))
372 self.setHeaderLabels([
373 self.tr("Locals"),
374 self.tr("Value"),
375 self.tr("Type")])
376 self.setWhatsThis(self.tr(
377 """<b>The Local Variables Viewer Window</b>"""
378 """<p>This window displays the local variables"""
379 """ of the debugged program.</p>"""
380 ))
381
382 header = self.header()
383 header.setSortIndicator(0, Qt.AscendingOrder)
384 header.setSortIndicatorShown(True)
385 if qVersionTuple() >= (5, 0, 0):
386 header.setSectionsClickable(True)
387 else:
388 header.setClickable(True)
389 header.sectionClicked.connect(self.__sectionClicked)
390 header.resizeSection(0, 120) # variable column
391 header.resizeSection(1, 150) # value column
392
393 self.__createPopupMenus()
394 self.setContextMenuPolicy(Qt.CustomContextMenu)
395 self.customContextMenuRequested.connect(self.__showContextMenu)
396
397 self.itemExpanded.connect(self.__expandItemSignal)
398 self.itemCollapsed.connect(self.collapseItem)
399
400 self.resortEnabled = True
401
402 def __createPopupMenus(self):
403 """
404 Private method to generate the popup menus.
405 """
406 self.menu = QMenu()
407 self.menu.addAction(self.tr("Show Details..."), self.__showDetails)
408 self.menu.addAction(self.tr("Refresh"), self.__refreshView)
409 self.menu.addSeparator()
410 self.menu.addAction(self.tr("Configure..."), self.__configure)
411
412 self.backMenu = QMenu()
413 self.backMenu.addAction(self.tr("Refresh"), self.__refreshView)
414 self.backMenu.addSeparator()
415 self.backMenu.addAction(self.tr("Configure..."), self.__configure)
416
417 def __showContextMenu(self, coord):
418 """
419 Private slot to show the context menu.
420
421 @param coord the position of the mouse pointer (QPoint)
422 """
423 gcoord = self.mapToGlobal(coord)
424 if self.itemAt(coord) is not None:
425 self.menu.popup(gcoord)
426 else:
427 self.backMenu.popup(gcoord)
428
429 def __findItem(self, slist, column, node=None):
430 """
431 Private method to search for an item.
432
433 It is used to find a specific item in column,
434 that is a child of node. If node is None, a child of the
435 QTreeWidget is searched.
436
437 @param slist searchlist (list of strings)
438 @param column index of column to search in (int)
439 @param node start point of the search
440 @return the found item or None
441 """
442 if node is None:
443 count = self.topLevelItemCount()
444 else:
445 count = node.childCount()
446
447 if column == 0:
448 searchStr = VariableItem.extractId(slist[0])[0]
449 else:
450 searchStr = slist[0]
451
452 for index in range(count):
453 if node is None:
454 itm = self.topLevelItem(index)
455 else:
456 itm = node.child(index)
457 if itm.text(column) == searchStr:
458 if len(slist) > 1:
459 itm = self.__findItem(slist[1:], column, itm)
460 return itm
461
462 return None
463
464 def showVariables(self, vlist, frmnr):
465 """
466 Public method to show variables in a list.
467
468 @param vlist the list of variables to be displayed. Each
469 listentry is a tuple of three values.
470 <ul>
471 <li>the variable name (string)</li>
472 <li>the variables type (string)</li>
473 <li>the variables value (string)</li>
474 </ul>
475 @param frmnr frame number (0 is the current frame) (int)
476 """
477 self.current = self.currentItem()
478 if self.current:
479 self.curpathlist = self.__buildTreePath(self.current)
480 self.clear()
481 self.__scrollToItem = None
482 self.framenr = frmnr
483
484 if len(vlist):
485 self.resortEnabled = False
486 for (var, vtype, value) in vlist:
487 self.__addItem(None, vtype, var, value)
488
489 # re-expand tree
490 openItems = sorted(self.openItems[:])
491 self.openItems = []
492 for itemPath in openItems:
493 itm = self.__findItem(itemPath, 0)
494 if itm is not None:
495 self.expandItem(itm)
496 else:
497 self.openItems.append(itemPath)
498
499 if self.current:
500 citm = self.__findItem(self.curpathlist, 0)
501 if citm:
502 self.setCurrentItem(citm)
503 citm.setSelected(True)
504 self.scrollToItem(citm, QAbstractItemView.PositionAtTop)
505 self.current = None
506
507 self.resortEnabled = True
508 self.__resort()
509
510 def showVariable(self, vlist):
511 """
512 Public method to show variables in a list.
513
514 @param vlist the list of subitems to be displayed.
515 The first element gives the path of the
516 parent variable. Each other listentry is
517 a tuple of three values.
518 <ul>
519 <li>the variable name (string)</li>
520 <li>the variables type (string)</li>
521 <li>the variables value (string)</li>
522 </ul>
523 """
524 resortEnabled = self.resortEnabled
525 self.resortEnabled = False
526 if self.current is None:
527 self.current = self.currentItem()
528 if self.current:
529 self.curpathlist = self.__buildTreePath(self.current)
530
531 if vlist:
532 itm = self.__findItem(vlist[0], 0)
533 for var, vtype, value in vlist[1:]:
534 self.__addItem(itm, vtype, var, value)
535
536 # re-expand tree
537 openItems = sorted(self.openItems[:])
538 self.openItems = []
539 for itemPath in openItems:
540 itm = self.__findItem(itemPath, 0)
541 if itm is not None and not itm.isExpanded():
542 if itm.populated:
543 self.blockSignals(True)
544 itm.setExpanded(True)
545 self.blockSignals(False)
546 else:
547 self.expandItem(itm)
548 self.openItems = openItems[:]
549
550 if self.current:
551 citm = self.__findItem(self.curpathlist, 0)
552 if citm:
553 self.setCurrentItem(citm)
554 citm.setSelected(True)
555 if self.__scrollToItem:
556 self.scrollToItem(self.__scrollToItem,
557 QAbstractItemView.PositionAtTop)
558 else:
559 self.scrollToItem(citm, QAbstractItemView.PositionAtTop)
560 self.current = None
561 elif self.__scrollToItem:
562 self.scrollToItem(self.__scrollToItem,
563 QAbstractItemView.PositionAtTop)
564
565 self.resortEnabled = resortEnabled
566 self.__resort()
567
568 def __generateItem(self, parent, dvar, dvalue, dtype, isSpecial=False):
569 """
570 Private method used to generate a VariableItem.
571
572 @param parent parent of the item to be generated
573 @param dvar variable name (string)
574 @param dvalue value string (string)
575 @param dtype type string (string)
576 @param isSpecial flag indicating that a special node should be
577 generated (boolean)
578 @return The item that was generated (VariableItem).
579 """
580 if isSpecial and \
581 (self.dvar_rx_class1.exactMatch(dvar) or
582 self.dvar_rx_class2.exactMatch(dvar)):
583 isSpecial = False
584
585 if self.rx_class2.exactMatch(dtype):
586 return SpecialVarItem(
587 parent, dvar, dvalue, dtype[7:-1], self.framenr,
588 self.__globalScope)
589 elif dtype != "void *" and \
590 (self.rx_class.exactMatch(dvalue) or
591 self.rx_class3.exactMatch(dvalue) or
592 isSpecial):
593 if self.dvar_rx_special_array_element.exactMatch(dvar):
594 return SpecialArrayElementVarItem(
595 parent, dvar, dvalue, dtype, self.framenr,
596 self.__globalScope)
597 else:
598 return SpecialVarItem(parent, dvar, dvalue, dtype,
599 self.framenr, self.__globalScope)
600 elif dtype in ["numpy.ndarray", "django.MultiValueDict",
601 "array.array"]:
602 return SpecialVarItem(
603 parent, dvar, self.tr("{0} items").format(dvalue), dtype,
604 self.framenr, self.__globalScope)
605 else:
606 if self.dvar_rx_array_element.exactMatch(dvar):
607 return ArrayElementVarItem(parent, dvar, dvalue, dtype)
608 else:
609 return VariableItem(parent, dvar, dvalue, dtype)
610
611 def __addItem(self, parent, vtype, var, value):
612 """
613 Private method used to add an item to the list.
614
615 If the item is of a type with subelements (i.e. list, dictionary,
616 tuple), these subelements are added by calling this method recursively.
617
618 @param parent the parent of the item to be added
619 (QTreeWidgetItem or None)
620 @param vtype the type of the item to be added
621 (string)
622 @param var the variable name (string)
623 @param value the value string (string)
624 @return The item that was added to the listview (QTreeWidgetItem).
625 """
626 if parent is None:
627 parent = self
628 try:
629 dvar = '{0}{1}'.format(var, VariableItem.Type2Indicators[vtype])
630 except KeyError:
631 dvar = var
632 dvtype = self.__getDispType(vtype)
633
634 if vtype in ['list', 'tuple', 'dict', 'set', 'frozenset']:
635 itm = self.__generateItem(parent, dvar,
636 self.tr("{0} items").format(value),
637 dvtype, True)
638 elif vtype in ['unicode', 'str']:
639 if self.rx_nonprintable.indexIn(value) != -1:
640 sval = value
641 else:
642 try:
643 sval = eval(value)
644 except Exception:
645 sval = value
646 itm = self.__generateItem(parent, dvar, str(sval), dvtype)
647
648 else:
649 itm = self.__generateItem(parent, dvar, value, dvtype)
650
651 return itm
652
653 def __getDispType(self, vtype):
654 """
655 Private method used to get the display string for type vtype.
656
657 @param vtype the type, the display string should be looked up for
658 (string)
659 @return displaystring (string)
660 """
661 try:
662 dvtype = self.tr(ConfigVarTypeDispStrings[vtype])
663 except KeyError:
664 if vtype == 'classobj':
665 dvtype = self.tr(ConfigVarTypeDispStrings['instance'])
666 else:
667 dvtype = vtype
668 return dvtype
669
670 def __refreshView(self):
671 """
672 Private slot to refresh the view.
673 """
674 if self.__globalScope:
675 self.__debugViewer.setGlobalsFilter()
676 else:
677 self.__debugViewer.setLocalsFilter()
678
679 def mouseDoubleClickEvent(self, mouseEvent):
680 """
681 Protected method of QAbstractItemView.
682
683 Reimplemented to disable expanding/collapsing of items when
684 double-clicking. Instead the double-clicked entry is opened.
685
686 @param mouseEvent the mouse event object (QMouseEvent)
687 """
688 itm = self.itemAt(mouseEvent.pos())
689 self.__showVariableDetails(itm)
690
691 def __showDetails(self):
692 """
693 Private slot to show details about the selected variable.
694 """
695 itm = self.currentItem()
696 self.__showVariableDetails(itm)
697
698 def __showVariableDetails(self, itm):
699 """
700 Private method to show details about a variable.
701
702 @param itm reference to the variable item
703 """
704 if itm is None:
705 return
706
707 val = itm.getValue()
708
709 if not val:
710 return # do not display anything, if the variable has no value
711
712 vtype = itm.text(2)
713 name = VariableItem.extractIndicators(itm.text(0).strip())[0]
714
715 par = itm.parent()
716 if name.startswith("["): # numpy.ndarray, array.array
717 nlist = []
718 else:
719 nlist = [name]
720
721 # build up the fully qualified name
722 while par is not None:
723 pname, indicators = VariableItem.extractIndicators(
724 par.text(0).strip())
725 if indicators:
726 if nlist[0].endswith("."):
727 nlist[0] = '[{0}].'.format(nlist[0][:-1])
728 else:
729 nlist[0] = '[{0}]'.format(nlist[0])
730 if not pname.startswith("["): # numpy.ndarray, array.array
731 nlist.insert(0, pname)
732 else:
733 if par.text(2) == "django.MultiValueDict":
734 nlist[0] = 'getlist({0})'.format(nlist[0])
735 elif par.text(2) == "numpy.ndarray":
736 if nlist[0][0].isalpha():
737 if nlist[0] in ["min", "max", "mean"]:
738 nlist[0] = ".{0}()".format(nlist[0])
739 else:
740 nlist[0] = ".{0}".format(nlist[0])
741 nlist.insert(0, pname)
742 else:
743 nlist.insert(0, '{0}.'.format(pname))
744 par = par.parent()
745
746 name = ''.join(nlist)
747 # now show the dialog
748 from .VariableDetailDialog import VariableDetailDialog
749 dlg = VariableDetailDialog(name, vtype, val)
750 dlg.exec_()
751
752 def __buildTreePath(self, itm):
753 """
754 Private method to build up a path from the top to an item.
755
756 @param itm item to build the path for (QTreeWidgetItem)
757 @return list of names denoting the path from the top (list of strings)
758 """
759 name = itm.text(0)
760 pathlist = [name]
761
762 par = itm.parent()
763 # build up a path from the top to the item
764 while par is not None:
765 pname = par.text(0)
766 pathlist.insert(0, pname)
767 par = par.parent()
768
769 return pathlist[:]
770
771 def __expandItemSignal(self, parentItem):
772 """
773 Private slot to handle the expanded signal.
774
775 @param parentItem reference to the item being expanded
776 (QTreeWidgetItem)
777 """
778 self.expandItem(parentItem)
779 self.__scrollToItem = parentItem
780
781 def expandItem(self, parentItem):
782 """
783 Public slot to handle the expanded signal.
784
785 @param parentItem reference to the item being expanded
786 (QTreeWidgetItem)
787 """
788 pathlist = self.__buildTreePath(parentItem)
789 self.openItems.append(pathlist)
790 if parentItem.populated:
791 return
792
793 try:
794 parentItem.expand()
795 except AttributeError:
796 super(VariablesViewer, self).expandItem(parentItem)
797
798 def collapseItem(self, parentItem):
799 """
800 Public slot to handle the collapsed signal.
801
802 @param parentItem reference to the item being collapsed
803 (QTreeWidgetItem)
804 """
805 pathlist = self.__buildTreePath(parentItem)
806 self.openItems.remove(pathlist)
807
808 try:
809 parentItem.collapse()
810 except AttributeError:
811 super(VariablesViewer, self).collapseItem(parentItem)
812
813 def __sectionClicked(self):
814 """
815 Private method handling a click onto a header section.
816 """
817 self.__resort()
818
819 def __resort(self, parent=None):
820 """
821 Private method to resort the tree.
822
823 @param parent reference to a parent item
824 @type QTreeWidgetItem
825 """
826 if self.resortEnabled:
827 if parent is not None:
828 parent.sortChildren(self.sortColumn(),
829 self.header().sortIndicatorOrder())
830 else:
831 self.sortItems(self.sortColumn(),
832 self.header().sortIndicatorOrder())
833
834 def handleResetUI(self):
835 """
836 Public method to reset the VariablesViewer.
837 """
838 self.clear()
839 self.openItems = []
840
841 def __configure(self):
842 """
843 Private method to open the configuration dialog.
844 """
845 e5App().getObject("UserInterface")\
846 .showPreferences("debuggerGeneralPage")

eric ide

mercurial