134 numpy.ndarray) |
138 numpy.ndarray) |
135 @type int or str |
139 @type int or str |
136 """ |
140 """ |
137 length_code = length |
141 length_code = length |
138 if isinstance(length, str): |
142 if isinstance(length, str): |
139 length = int(length.split('x')[0]) |
143 length = int(length.split("x")[0]) |
140 |
144 |
141 if indicator and length > -2: |
145 if indicator and length > -2: |
142 self.childCount = max(0, length) # Update count if array |
146 self.childCount = max(0, length) # Update count if array |
143 if dtype == 'numpy.ndarray' and length == -1: |
147 if dtype == "numpy.ndarray" and length == -1: |
144 self.value = VariableItem.unsized |
148 self.value = VariableItem.unsized |
145 else: |
149 else: |
146 self.value = VariableItem.noOfItemsStr.format(length_code) |
150 self.value = VariableItem.noOfItemsStr.format(length_code) |
147 |
151 |
148 if dtype != 'str': |
152 if dtype != "str": |
149 self.valueShort = self.value |
153 self.valueShort = self.value |
150 self.tooltip = str(self.value)[:256] |
154 self.tooltip = str(self.value)[:256] |
151 return |
155 return |
152 |
156 |
153 if VariableItem.rx_nonprintable.search(dvalue) is None: |
157 if VariableItem.rx_nonprintable.search(dvalue) is None: |
154 with contextlib.suppress(Exception): |
158 with contextlib.suppress(Exception): |
155 dvalue = ast.literal_eval(dvalue) |
159 dvalue = ast.literal_eval(dvalue) |
156 |
160 |
157 dvalue = str(dvalue) |
161 dvalue = str(dvalue) |
158 self.value = dvalue |
162 self.value = dvalue |
159 |
163 |
160 if len(dvalue) > 2048: # 2 kB |
164 if len(dvalue) > 2048: # 2 kB |
161 self.tooltip = dvalue[:2048] |
165 self.tooltip = dvalue[:2048] |
162 dvalue = QCoreApplication.translate( |
166 dvalue = QCoreApplication.translate( |
163 "VariableItem", "<double click to show value>") |
167 "VariableItem", "<double click to show value>" |
|
168 ) |
164 else: |
169 else: |
165 self.tooltip = dvalue |
170 self.tooltip = dvalue |
166 |
171 |
167 lines = dvalue[:2048].splitlines() |
172 lines = dvalue[:2048].splitlines() |
168 if len(lines) > 1: |
173 if len(lines) > 1: |
169 # only show the first non-empty line; |
174 # only show the first non-empty line; |
170 # indicate skipped lines by <...> at the |
175 # indicate skipped lines by <...> at the |
171 # beginning and/or end |
176 # beginning and/or end |
172 index = 0 |
177 index = 0 |
173 while index < len(lines) - 1 and lines[index].strip(' \t') == "": |
178 while index < len(lines) - 1 and lines[index].strip(" \t") == "": |
174 index += 1 |
179 index += 1 |
175 |
180 |
176 dvalue = "" |
181 dvalue = "" |
177 if index > 0: |
182 if index > 0: |
178 dvalue += "<...>" |
183 dvalue += "<...>" |
179 dvalue += lines[index] |
184 dvalue += lines[index] |
180 if index < len(lines) - 1 or len(dvalue) > 2048: |
185 if index < len(lines) - 1 or len(dvalue) > 2048: |
181 dvalue += "<...>" |
186 dvalue += "<...>" |
182 |
187 |
183 self.valueShort = dvalue |
188 self.valueShort = dvalue |
184 |
189 |
185 @property |
190 @property |
186 def absolutCount(self): |
191 def absolutCount(self): |
187 """ |
192 """ |
188 Public property to get the total number of children. |
193 Public property to get the total number of children. |
189 |
194 |
190 @return total number of children |
195 @return total number of children |
191 @rtype int |
196 @rtype int |
192 """ |
197 """ |
193 return self.childCount + self.methodCount |
198 return self.childCount + self.methodCount |
194 |
199 |
195 |
200 |
196 class VariablesModel(QAbstractItemModel): |
201 class VariablesModel(QAbstractItemModel): |
197 """ |
202 """ |
198 Class implementing the data model for QTreeView. |
203 Class implementing the data model for QTreeView. |
199 |
204 |
200 @signal expand trigger QTreeView to expand given index |
205 @signal expand trigger QTreeView to expand given index |
201 """ |
206 """ |
|
207 |
202 expand = pyqtSignal(QModelIndex) |
208 expand = pyqtSignal(QModelIndex) |
203 |
209 |
204 def __init__(self, treeView, globalScope): |
210 def __init__(self, treeView, globalScope): |
205 """ |
211 """ |
206 Constructor |
212 Constructor |
207 |
213 |
208 @param treeView QTreeView showing the data |
214 @param treeView QTreeView showing the data |
209 @type VariablesViewer |
215 @type VariablesViewer |
210 @param globalScope flag indicating global (True) or local (False) |
216 @param globalScope flag indicating global (True) or local (False) |
211 variables |
217 variables |
212 @type bool |
218 @type bool |
213 """ |
219 """ |
214 super().__init__() |
220 super().__init__() |
215 self.treeView = treeView |
221 self.treeView = treeView |
216 self.proxyModel = treeView.proxyModel |
222 self.proxyModel = treeView.proxyModel |
217 |
223 |
218 self.framenr = -1 |
224 self.framenr = -1 |
219 self.openItems = [] |
225 self.openItems = [] |
220 self.closedItems = [] |
226 self.closedItems = [] |
221 |
227 |
222 visibility = self.tr("Globals") if globalScope else self.tr("Locals") |
228 visibility = self.tr("Globals") if globalScope else self.tr("Locals") |
223 self.rootNode = VariableItem(None, visibility, '', self.tr("Type"), |
229 self.rootNode = VariableItem( |
224 True, 0, self.tr("Value")) |
230 None, visibility, "", self.tr("Type"), True, 0, self.tr("Value") |
225 |
231 ) |
|
232 |
226 self.__globalScope = globalScope |
233 self.__globalScope = globalScope |
227 |
234 |
228 def clear(self, reset=False): |
235 def clear(self, reset=False): |
229 """ |
236 """ |
230 Public method to clear the complete data model. |
237 Public method to clear the complete data model. |
231 |
238 |
232 @param reset flag to clear the expanded keys also |
239 @param reset flag to clear the expanded keys also |
233 @type bool |
240 @type bool |
234 """ |
241 """ |
235 self.beginResetModel() |
242 self.beginResetModel() |
236 self.rootNode.children = [] |
243 self.rootNode.children = [] |
285 else: |
292 else: |
286 itemStartIndex = -1 |
293 itemStartIndex = -1 |
287 if self.framenr != frmnr: |
294 if self.framenr != frmnr: |
288 self.clear() |
295 self.clear() |
289 self.framenr = frmnr |
296 self.framenr = frmnr |
290 |
297 |
291 parent = self.__findVariable(pathlist) |
298 parent = self.__findVariable(pathlist) |
292 if parent is None: |
299 if parent is None: |
293 return |
300 return |
294 |
301 |
295 parent.pendigFetch = False |
302 parent.pendigFetch = False |
296 |
303 |
297 if parent == self.rootNode: |
304 if parent == self.rootNode: |
298 parentIdx = QModelIndex() |
305 parentIdx = QModelIndex() |
299 parent.methodCount = len(vlist) |
306 parent.methodCount = len(vlist) |
300 else: |
307 else: |
301 row = parent.parent.children.index(parent) |
308 row = parent.parent.children.index(parent) |
302 parentIdx = self.createIndex(row, 0, parent) |
309 parentIdx = self.createIndex(row, 0, parent) |
303 |
310 |
304 if itemStartIndex == -3: |
311 if itemStartIndex == -3: |
305 # Item doesn't exist any more |
312 # Item doesn't exist any more |
306 parentIdx = self.parent(parentIdx) |
313 parentIdx = self.parent(parentIdx) |
307 self.beginRemoveRows(parentIdx, row, row) |
314 self.beginRemoveRows(parentIdx, row, row) |
308 del parent.parent.children[row] |
315 del parent.parent.children[row] |
309 self.endRemoveRows() |
316 self.endRemoveRows() |
310 parent.parent.childCount -= 1 |
317 parent.parent.childCount -= 1 |
311 return |
318 return |
312 |
319 |
313 elif itemStartIndex == -2: |
320 elif itemStartIndex == -2: |
314 parent.wasPopulated = True |
321 parent.wasPopulated = True |
315 parent.currentCount = parent.absolutCount |
322 parent.currentCount = parent.absolutCount |
316 parent.populated = True |
323 parent.populated = True |
317 # Remove items which are left over at the end of child list |
324 # Remove items which are left over at the end of child list |
318 self.__cleanupParentList(parent, parentIdx) |
325 self.__cleanupParentList(parent, parentIdx) |
319 return |
326 return |
320 |
327 |
321 elif itemStartIndex == -1: |
328 elif itemStartIndex == -1: |
322 parent.methodCount = len(vlist) |
329 parent.methodCount = len(vlist) |
323 idx = max(parent.currentCount, 0) |
330 idx = max(parent.currentCount, 0) |
324 parent.currentCount = idx + len(vlist) |
331 parent.currentCount = idx + len(vlist) |
325 parent.populated = True |
332 parent.populated = True |
326 else: |
333 else: |
327 idx = itemStartIndex |
334 idx = itemStartIndex |
328 parent.currentCount = idx + len(vlist) |
335 parent.currentCount = idx + len(vlist) |
329 |
336 |
330 # Now update the table |
337 # Now update the table |
331 endIndex = idx + len(vlist) |
338 endIndex = idx + len(vlist) |
332 newChild = None |
339 newChild = None |
333 knownChildrenCount = len(parent.children) |
340 knownChildrenCount = len(parent.children) |
334 while idx < endIndex: |
341 while idx < endIndex: |
335 # Fetch next old item from last cycle |
342 # Fetch next old item from last cycle |
336 try: |
343 try: |
337 child = parent.children[idx] |
344 child = parent.children[idx] |
338 except IndexError: |
345 except IndexError: |
339 child = None |
346 child = None |
340 |
347 |
341 # Fetch possible new item |
348 # Fetch possible new item |
342 if not newChild and vlist: |
349 if not newChild and vlist: |
343 newChild = vlist.pop(0) |
350 newChild = vlist.pop(0) |
344 |
351 |
345 # Process parameters of new item |
352 # Process parameters of new item |
346 newItem = VariableItem(parent, *newChild) |
353 newItem = VariableItem(parent, *newChild) |
347 sort = newItem.sort |
354 sort = newItem.sort |
348 |
355 |
349 # Append or insert before already existing item |
356 # Append or insert before already existing item |
350 if child is None or newChild and sort < child.sort: |
357 if child is None or newChild and sort < child.sort: |
351 self.beginInsertRows(parentIdx, idx, idx) |
358 self.beginInsertRows(parentIdx, idx, idx) |
352 parent.children.insert(idx, newItem) |
359 parent.children.insert(idx, newItem) |
353 if knownChildrenCount <= idx and not parent.wasPopulated: |
360 if knownChildrenCount <= idx and not parent.wasPopulated: |
354 parent.newItems.add(newItem) |
361 parent.newItems.add(newItem) |
355 knownChildrenCount += 1 |
362 knownChildrenCount += 1 |
356 else: |
363 else: |
357 parent.changedItems.add(newItem) |
364 parent.changedItems.add(newItem) |
358 self.endInsertRows() |
365 self.endInsertRows() |
359 |
366 |
360 idx += 1 |
367 idx += 1 |
361 newChild = None |
368 newChild = None |
362 continue |
369 continue |
363 |
370 |
364 # Check if same name, type and afterwards value |
371 # Check if same name, type and afterwards value |
365 elif sort == child.sort and child.type == newItem.type: |
372 elif sort == child.sort and child.type == newItem.type: |
366 # Check if value has changed |
373 # Check if value has changed |
367 if child.value != newItem.value: |
374 if child.value != newItem.value: |
368 child.value = newItem.value |
375 child.value = newItem.value |
369 child.valueShort = newItem.valueShort |
376 child.valueShort = newItem.valueShort |
370 child.tooltip = newItem.tooltip |
377 child.tooltip = newItem.tooltip |
371 child.nameWithId = newItem.nameWithId |
378 child.nameWithId = newItem.nameWithId |
372 |
379 |
373 child.currentCount = -1 |
380 child.currentCount = -1 |
374 child.populated = False |
381 child.populated = False |
375 child.childCount = newItem.childCount |
382 child.childCount = newItem.childCount |
376 |
383 |
377 # Highlight item because it has changed |
384 # Highlight item because it has changed |
378 parent.changedItems.add(child) |
385 parent.changedItems.add(child) |
379 |
386 |
380 changedIndexStart = self.index(idx, 0, parentIdx) |
387 changedIndexStart = self.index(idx, 0, parentIdx) |
381 changedIndexEnd = self.index(idx, 2, parentIdx) |
388 changedIndexEnd = self.index(idx, 2, parentIdx) |
382 self.dataChanged.emit(changedIndexStart, changedIndexEnd) |
389 self.dataChanged.emit(changedIndexStart, changedIndexEnd) |
383 |
390 |
384 newChild = None |
391 newChild = None |
385 idx += 1 |
392 idx += 1 |
386 continue |
393 continue |
387 |
394 |
388 # Remove obsolete item |
395 # Remove obsolete item |
389 self.beginRemoveRows(parentIdx, idx, idx) |
396 self.beginRemoveRows(parentIdx, idx, idx) |
390 parent.children.remove(child) |
397 parent.children.remove(child) |
391 self.endRemoveRows() |
398 self.endRemoveRows() |
392 # idx stay unchanged |
399 # idx stay unchanged |
393 knownChildrenCount -= 1 |
400 knownChildrenCount -= 1 |
394 |
401 |
395 # Remove items which are left over at the end of child list |
402 # Remove items which are left over at the end of child list |
396 if itemStartIndex == -1: |
403 if itemStartIndex == -1: |
397 parent.wasPopulated = True |
404 parent.wasPopulated = True |
398 self.__cleanupParentList(parent, parentIdx) |
405 self.__cleanupParentList(parent, parentIdx) |
399 |
406 |
400 # Request data for any expanded node |
407 # Request data for any expanded node |
401 self.getMore() |
408 self.getMore() |
402 |
409 |
403 def __cleanupParentList(self, parent, parentIdx): |
410 def __cleanupParentList(self, parent, parentIdx): |
404 """ |
411 """ |
405 Private method to remove items which are left over at the end of the |
412 Private method to remove items which are left over at the end of the |
406 child list. |
413 child list. |
407 |
414 |
408 @param parent to clean up |
415 @param parent to clean up |
409 @type VariableItem |
416 @type VariableItem |
410 @param parentIdx the parent index as QModelIndex |
417 @param parentIdx the parent index as QModelIndex |
411 @type QModelIndex |
418 @type QModelIndex |
412 """ |
419 """ |
413 end = len(parent.children) |
420 end = len(parent.children) |
414 if end > parent.absolutCount: |
421 if end > parent.absolutCount: |
415 self.beginRemoveRows(parentIdx, parent.absolutCount, end) |
422 self.beginRemoveRows(parentIdx, parent.absolutCount, end) |
416 del parent.children[parent.absolutCount:] |
423 del parent.children[parent.absolutCount :] |
417 self.endRemoveRows() |
424 self.endRemoveRows() |
418 |
425 |
419 def resetModifiedMarker(self, parentIdx=QModelIndex(), pathlist=()): |
426 def resetModifiedMarker(self, parentIdx=QModelIndex(), pathlist=()): |
420 """ |
427 """ |
421 Public method to remove the modified marker from changed items. |
428 Public method to remove the modified marker from changed items. |
422 |
429 |
423 @param parentIdx item to reset marker |
430 @param parentIdx item to reset marker |
424 @type QModelIndex |
431 @type QModelIndex |
425 @param pathlist full path to the variable |
432 @param pathlist full path to the variable |
426 @type list of str |
433 @type list of str |
427 """ |
434 """ |
428 parent = (parentIdx.internalPointer() if parentIdx.isValid() |
435 parent = parentIdx.internalPointer() if parentIdx.isValid() else self.rootNode |
429 else self.rootNode) |
436 |
430 |
|
431 parent.newItems.clear() |
437 parent.newItems.clear() |
432 parent.changedItems.clear() |
438 parent.changedItems.clear() |
433 |
439 |
434 pll = len(pathlist) |
440 pll = len(pathlist) |
435 posPaths = {x for x in self.openItems if len(x) > pll} |
441 posPaths = {x for x in self.openItems if len(x) > pll} |
436 posPaths |= {x for x in self.closedItems if len(x) > pll} |
442 posPaths |= {x for x in self.closedItems if len(x) > pll} |
437 posPaths = {x[pll] for x in posPaths if x[:pll] == pathlist} |
443 posPaths = {x[pll] for x in posPaths if x[:pll] == pathlist} |
438 |
444 |
439 if posPaths: |
445 if posPaths: |
440 for child in parent.children: |
446 for child in parent.children: |
441 if ( |
447 if ( |
442 child.hasChildren and |
448 child.hasChildren |
443 child.nameWithId in posPaths and |
449 and child.nameWithId in posPaths |
444 child.currentCount >= 0 |
450 and child.currentCount >= 0 |
445 ): |
451 ): |
446 # Discard loaded elements and refresh if still expanded |
452 # Discard loaded elements and refresh if still expanded |
447 child.currentCount = -1 |
453 child.currentCount = -1 |
448 child.populated = False |
454 child.populated = False |
449 row = parent.children.index(child) |
455 row = parent.children.index(child) |
450 newParentIdx = self.index(row, 0, parentIdx) |
456 newParentIdx = self.index(row, 0, parentIdx) |
451 self.resetModifiedMarker( |
457 self.resetModifiedMarker( |
452 newParentIdx, pathlist + (child.nameWithId,)) |
458 newParentIdx, pathlist + (child.nameWithId,) |
453 |
459 ) |
|
460 |
454 self.closedItems = [] |
461 self.closedItems = [] |
455 |
462 |
456 # Little quirk: Refresh all visible items to clear the changed marker |
463 # Little quirk: Refresh all visible items to clear the changed marker |
457 if parentIdx == QModelIndex(): |
464 if parentIdx == QModelIndex(): |
458 self.rootNode.currentCount = -1 |
465 self.rootNode.currentCount = -1 |
459 self.rootNode.populated = False |
466 self.rootNode.populated = False |
460 idxStart = self.index(0, 0, QModelIndex()) |
467 idxStart = self.index(0, 0, QModelIndex()) |
461 idxEnd = self.index(0, 2, QModelIndex()) |
468 idxEnd = self.index(0, 2, QModelIndex()) |
462 self.dataChanged.emit(idxStart, idxEnd) |
469 self.dataChanged.emit(idxStart, idxEnd) |
463 |
470 |
464 def columnCount(self, parent=QModelIndex()): |
471 def columnCount(self, parent=QModelIndex()): |
465 """ |
472 """ |
466 Public method to get the column count. |
473 Public method to get the column count. |
467 |
474 |
468 @param parent the model parent |
475 @param parent the model parent |
469 @type QModelIndex |
476 @type QModelIndex |
470 @return number of columns |
477 @return number of columns |
471 @rtype int |
478 @rtype int |
472 """ |
479 """ |
473 return 3 |
480 return 3 |
474 |
481 |
475 def rowCount(self, parent=QModelIndex()): |
482 def rowCount(self, parent=QModelIndex()): |
476 """ |
483 """ |
477 Public method to get the row count. |
484 Public method to get the row count. |
478 |
485 |
479 @param parent the model parent |
486 @param parent the model parent |
480 @type QModelIndex |
487 @type QModelIndex |
481 @return number of rows |
488 @return number of rows |
482 @rtype int |
489 @rtype int |
483 """ |
490 """ |
484 node = parent.internalPointer() if parent.isValid() else self.rootNode |
491 node = parent.internalPointer() if parent.isValid() else self.rootNode |
485 |
492 |
486 return len(node.children) |
493 return len(node.children) |
487 |
494 |
488 def flags(self, index): |
495 def flags(self, index): |
489 """ |
496 """ |
490 Public method to get the item flags. |
497 Public method to get the item flags. |
491 |
498 |
492 @param index of item |
499 @param index of item |
493 @type QModelIndex |
500 @type QModelIndex |
494 @return item flags |
501 @return item flags |
495 @rtype QtCore.Qt.ItemFlag |
502 @rtype QtCore.Qt.ItemFlag |
496 """ |
503 """ |
497 if not index.isValid(): |
504 if not index.isValid(): |
498 return Qt.ItemFlag.NoItemFlags |
505 return Qt.ItemFlag.NoItemFlags |
499 |
506 |
500 return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable |
507 return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable |
501 |
508 |
502 def hasChildren(self, parent=QModelIndex()): |
509 def hasChildren(self, parent=QModelIndex()): |
503 """ |
510 """ |
504 Public method to get a flag if parent has children. |
511 Public method to get a flag if parent has children. |
505 |
512 |
506 @param parent the model parent |
513 @param parent the model parent |
507 @type QModelIndex |
514 @type QModelIndex |
508 @return flag indicating parent has children |
515 @return flag indicating parent has children |
509 @rtype bool |
516 @rtype bool |
510 """ |
517 """ |
511 if not parent.isValid(): |
518 if not parent.isValid(): |
512 return self.rootNode.children != [] |
519 return self.rootNode.children != [] |
513 |
520 |
514 return parent.internalPointer().hasChildren |
521 return parent.internalPointer().hasChildren |
515 |
522 |
516 def index(self, row, column, parent=QModelIndex()): |
523 def index(self, row, column, parent=QModelIndex()): |
517 """ |
524 """ |
518 Public method to get the index of item at row:column of parent. |
525 Public method to get the index of item at row:column of parent. |
519 |
526 |
520 @param row number of rows |
527 @param row number of rows |
521 @type int |
528 @type int |
522 @param column number of columns |
529 @param column number of columns |
523 @type int |
530 @type int |
524 @param parent the model parent |
531 @param parent the model parent |
546 return QModelIndex() |
553 return QModelIndex() |
547 |
554 |
548 childNode = child.internalPointer() |
555 childNode = child.internalPointer() |
549 if childNode == self.rootNode: |
556 if childNode == self.rootNode: |
550 return QModelIndex() |
557 return QModelIndex() |
551 |
558 |
552 parentNode = childNode.parent |
559 parentNode = childNode.parent |
553 |
560 |
554 if parentNode == self.rootNode: |
561 if parentNode == self.rootNode: |
555 return QModelIndex() |
562 return QModelIndex() |
556 |
563 |
557 row = parentNode.parent.children.index(parentNode) |
564 row = parentNode.parent.children.index(parentNode) |
558 return self.createIndex(row, 0, parentNode) |
565 return self.createIndex(row, 0, parentNode) |
559 |
566 |
560 def data(self, index, role=Qt.ItemDataRole.DisplayRole): |
567 def data(self, index, role=Qt.ItemDataRole.DisplayRole): |
561 """ |
568 """ |
562 Public method get the role data of item. |
569 Public method get the role data of item. |
563 |
570 |
564 @param index the model index |
571 @param index the model index |
565 @type QModelIndex |
572 @type QModelIndex |
566 @param role the requested data role |
573 @param role the requested data role |
567 @type QtCore.Qt.ItemDataRole |
574 @type QtCore.Qt.ItemDataRole |
568 @return role data of item |
575 @return role data of item |
569 @rtype Any |
576 @rtype Any |
570 """ |
577 """ |
571 if not index.isValid() or index.row() < 0: |
578 if not index.isValid() or index.row() < 0: |
572 return None |
579 return None |
573 |
580 |
574 node = index.internalPointer() |
581 node = index.internalPointer() |
575 column = index.column() |
582 column = index.column() |
576 |
583 |
577 if role in ( |
584 if role in (Qt.ItemDataRole.DisplayRole, SORT_ROLE, Qt.ItemDataRole.EditRole): |
578 Qt.ItemDataRole.DisplayRole, SORT_ROLE, Qt.ItemDataRole.EditRole |
|
579 ): |
|
580 try: |
585 try: |
581 if column == 0: |
586 if column == 0: |
582 # Sort first column with values from third column |
587 # Sort first column with values from third column |
583 if role == SORT_ROLE: |
588 if role == SORT_ROLE: |
584 return node.sort |
589 return node.sort |
585 return node.name + node.indicator |
590 return node.name + node.indicator |
586 else: |
591 else: |
587 return { |
592 return {1: node.valueShort, 2: node.type, 3: node.sort}.get(column) |
588 1: node.valueShort, |
|
589 2: node.type, |
|
590 3: node.sort |
|
591 }.get(column) |
|
592 except AttributeError: |
593 except AttributeError: |
593 return ('None', '', '', '')[column] |
594 return ("None", "", "", "")[column] |
594 |
595 |
595 elif role == Qt.ItemDataRole.BackgroundRole: |
596 elif role == Qt.ItemDataRole.BackgroundRole: |
596 if node in node.parent.changedItems: |
597 if node in node.parent.changedItems: |
597 return self.__bgColorChanged |
598 return self.__bgColorChanged |
598 elif node in node.parent.newItems: |
599 elif node in node.parent.newItems: |
599 return self.__bgColorNew |
600 return self.__bgColorNew |
600 |
601 |
601 elif role == Qt.ItemDataRole.ToolTipRole: |
602 elif role == Qt.ItemDataRole.ToolTipRole: |
602 if column == 0: |
603 if column == 0: |
603 tooltip = node.name + node.indicator |
604 tooltip = node.name + node.indicator |
604 elif column == 1: |
605 elif column == 1: |
605 tooltip = node.tooltip |
606 tooltip = node.tooltip |
634 header = self.treeView.header() |
635 header = self.treeView.header() |
635 if textSize >= header.sectionSize(column): |
636 if textSize >= header.sectionSize(column): |
636 return tooltip |
637 return tooltip |
637 else: |
638 else: |
638 QToolTip.hideText() |
639 QToolTip.hideText() |
639 |
640 |
640 return None |
641 return None |
641 |
642 |
642 def headerData(self, section, orientation, |
643 def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole): |
643 role=Qt.ItemDataRole.DisplayRole): |
|
644 """ |
644 """ |
645 Public method get the header names. |
645 Public method get the header names. |
646 |
646 |
647 @param section the header section (row/column) |
647 @param section the header section (row/column) |
648 @type int |
648 @type int |
649 @param orientation the header's orientation |
649 @param orientation the header's orientation |
650 @type QtCore.Qt.Orientation |
650 @type QtCore.Qt.Orientation |
651 @param role the requested data role |
651 @param role the requested data role |
652 @type QtCore.Qt.ItemDataRole |
652 @type QtCore.Qt.ItemDataRole |
653 @return header name |
653 @return header name |
654 @rtype str or None |
654 @rtype str or None |
655 """ |
655 """ |
656 if ( |
656 if ( |
657 role != Qt.ItemDataRole.DisplayRole or |
657 role != Qt.ItemDataRole.DisplayRole |
658 orientation != Qt.Orientation.Horizontal |
658 or orientation != Qt.Orientation.Horizontal |
659 ): |
659 ): |
660 return None |
660 return None |
661 |
661 |
662 return { |
662 return { |
663 0: self.rootNode.name, |
663 0: self.rootNode.name, |
664 1: self.rootNode.value, |
664 1: self.rootNode.value, |
665 2: self.rootNode.type, |
665 2: self.rootNode.type, |
666 3: self.rootNode.sort |
666 3: self.rootNode.sort, |
667 }.get(section) |
667 }.get(section) |
668 |
668 |
669 def __findPendingItem(self, parent=None, pathlist=()): |
669 def __findPendingItem(self, parent=None, pathlist=()): |
670 """ |
670 """ |
671 Private method to find the next item to request data from debugger. |
671 Private method to find the next item to request data from debugger. |
672 |
672 |
673 @param parent the model parent |
673 @param parent the model parent |
674 @type VariableItem |
674 @type VariableItem |
675 @param pathlist full path to the variable |
675 @param pathlist full path to the variable |
676 @type list of str |
676 @type list of str |
677 @return next item index to request data from debugger |
677 @return next item index to request data from debugger |
678 @rtype QModelIndex |
678 @rtype QModelIndex |
679 """ |
679 """ |
680 if parent is None: |
680 if parent is None: |
681 parent = self.rootNode |
681 parent = self.rootNode |
682 |
682 |
683 for child in parent.children: |
683 for child in parent.children: |
684 if not child.hasChildren: |
684 if not child.hasChildren: |
685 continue |
685 continue |
686 |
686 |
687 if pathlist + (child.nameWithId,) in self.openItems: |
687 if pathlist + (child.nameWithId,) in self.openItems: |
688 if child.populated: |
688 if child.populated: |
689 index = None |
689 index = None |
690 else: |
690 else: |
691 idx = parent.children.index(child) |
691 idx = parent.children.index(child) |
692 index = self.createIndex(idx, 0, child) |
692 index = self.createIndex(idx, 0, child) |
693 self.expand.emit(index) |
693 self.expand.emit(index) |
694 |
694 |
695 if child.currentCount < 0: |
695 if child.currentCount < 0: |
696 return index |
696 return index |
697 |
697 |
698 possibleIndex = self.__findPendingItem( |
698 possibleIndex = self.__findPendingItem( |
699 child, pathlist + (child.nameWithId,)) |
699 child, pathlist + (child.nameWithId,) |
700 |
700 ) |
|
701 |
701 if (possibleIndex or index) is None: |
702 if (possibleIndex or index) is None: |
702 continue |
703 continue |
703 |
704 |
704 return possibleIndex or index |
705 return possibleIndex or index |
705 |
706 |
706 return None |
707 return None |
707 |
708 |
708 def getMore(self): |
709 def getMore(self): |
709 """ |
710 """ |
710 Public method to fetch the next variable from debugger. |
711 Public method to fetch the next variable from debugger. |
711 """ |
712 """ |
712 # step 1: find expanded but not populated items |
713 # step 1: find expanded but not populated items |
713 item = self.__findPendingItem() |
714 item = self.__findPendingItem() |
714 if not item or not item.isValid(): |
715 if not item or not item.isValid(): |
715 return |
716 return |
716 |
717 |
717 # step 2: check if data has to be retrieved |
718 # step 2: check if data has to be retrieved |
718 node = item.internalPointer() |
719 node = item.internalPointer() |
719 lastVisibleItem = self.index(node.currentCount - 1, 0, item) |
720 lastVisibleItem = self.index(node.currentCount - 1, 0, item) |
720 lastVisibleItem = self.proxyModel.mapFromSource(lastVisibleItem) |
721 lastVisibleItem = self.proxyModel.mapFromSource(lastVisibleItem) |
721 rect = self.treeView.visualRect(lastVisibleItem) |
722 rect = self.treeView.visualRect(lastVisibleItem) |
722 if rect.y() > self.treeView.height() or node.pendigFetch: |
723 if rect.y() > self.treeView.height() or node.pendigFetch: |
723 return |
724 return |
724 |
725 |
725 node.pendigFetch = True |
726 node.pendigFetch = True |
726 # step 3: get a pathlist up to the requested variable |
727 # step 3: get a pathlist up to the requested variable |
727 pathlist = self.__buildTreePath(node) |
728 pathlist = self.__buildTreePath(node) |
728 # step 4: request the variable from the debugger |
729 # step 4: request the variable from the debugger |
729 variablesFilter = ericApp().getObject("DebugUI").variablesFilter( |
730 variablesFilter = ( |
730 self.__globalScope) |
731 ericApp().getObject("DebugUI").variablesFilter(self.__globalScope) |
|
732 ) |
731 ericApp().getObject("DebugServer").remoteClientVariable( |
733 ericApp().getObject("DebugServer").remoteClientVariable( |
732 ericApp().getObject("DebugUI").getSelectedDebuggerId(), |
734 ericApp().getObject("DebugUI").getSelectedDebuggerId(), |
733 self.__globalScope, variablesFilter, pathlist, self.framenr) |
735 self.__globalScope, |
734 |
736 variablesFilter, |
|
737 pathlist, |
|
738 self.framenr, |
|
739 ) |
|
740 |
735 def setExpanded(self, index, state): |
741 def setExpanded(self, index, state): |
736 """ |
742 """ |
737 Public method to set the expanded state of item. |
743 Public method to set the expanded state of item. |
738 |
744 |
739 @param index item to change expanded state |
745 @param index item to change expanded state |
740 @type QModelIndex |
746 @type QModelIndex |
741 @param state state of the item |
747 @param state state of the item |
742 @type bool |
748 @type bool |
743 """ |
749 """ |
751 self.getMore() |
757 self.getMore() |
752 else: |
758 else: |
753 if pathlist in self.openItems: |
759 if pathlist in self.openItems: |
754 self.openItems.remove(pathlist) |
760 self.openItems.remove(pathlist) |
755 self.closedItems.append(pathlist) |
761 self.closedItems.append(pathlist) |
756 |
762 |
757 def __buildTreePath(self, parent): |
763 def __buildTreePath(self, parent): |
758 """ |
764 """ |
759 Private method to build up a path from the root to parent. |
765 Private method to build up a path from the root to parent. |
760 |
766 |
761 @param parent item to build the path for |
767 @param parent item to build the path for |
762 @type VariableItem |
768 @type VariableItem |
763 @return list of names denoting the path from the root |
769 @return list of names denoting the path from the root |
764 @rtype tuple of str |
770 @rtype tuple of str |
765 """ |
771 """ |
766 pathlist = [] |
772 pathlist = [] |
767 |
773 |
768 # build up a path from the top to the item |
774 # build up a path from the top to the item |
769 while parent.parent: |
775 while parent.parent: |
770 pathlist.append(parent.nameWithId) |
776 pathlist.append(parent.nameWithId) |
771 parent = parent.parent |
777 parent = parent.parent |
772 |
778 |
773 pathlist.reverse() |
779 pathlist.reverse() |
774 return tuple(pathlist) |
780 return tuple(pathlist) |
775 |
781 |
776 def handlePreferencesChanged(self): |
782 def handlePreferencesChanged(self): |
777 """ |
783 """ |
778 Public slot to handle the preferencesChanged signal. |
784 Public slot to handle the preferencesChanged signal. |
779 """ |
785 """ |
780 self.__bgColorNew = QBrush(Preferences.getDebugger("BgColorNew")) |
786 self.__bgColorNew = QBrush(Preferences.getDebugger("BgColorNew")) |
781 self.__bgColorChanged = QBrush( |
787 self.__bgColorChanged = QBrush(Preferences.getDebugger("BgColorChanged")) |
782 Preferences.getDebugger("BgColorChanged")) |
788 |
783 |
|
784 idxStart = self.index(0, 0, QModelIndex()) |
789 idxStart = self.index(0, 0, QModelIndex()) |
785 idxEnd = self.index(0, 2, QModelIndex()) |
790 idxEnd = self.index(0, 2, QModelIndex()) |
786 self.dataChanged.emit(idxStart, idxEnd) |
791 self.dataChanged.emit(idxStart, idxEnd) |
787 |
792 |
788 |
793 |
789 class VariablesProxyModel(QSortFilterProxyModel): |
794 class VariablesProxyModel(QSortFilterProxyModel): |
790 """ |
795 """ |
791 Class for handling the sort operations. |
796 Class for handling the sort operations. |
792 """ |
797 """ |
|
798 |
793 def __init__(self, parent=None): |
799 def __init__(self, parent=None): |
794 """ |
800 """ |
795 Constructor |
801 Constructor |
796 |
802 |
797 @param parent the parent model index |
803 @param parent the parent model index |
798 @type QModelIndex |
804 @type QModelIndex |
799 """ |
805 """ |
800 super().__init__(parent) |
806 super().__init__(parent) |
801 self.setSortRole(SORT_ROLE) |
807 self.setSortRole(SORT_ROLE) |
802 |
808 |
803 def hasChildren(self, parent): |
809 def hasChildren(self, parent): |
804 """ |
810 """ |
805 Public method to get a flag if parent has children. |
811 Public method to get a flag if parent has children. |
806 |
812 |
807 The given model index has to be transformed to the underlying source |
813 The given model index has to be transformed to the underlying source |
808 model to get the correct result. |
814 model to get the correct result. |
809 |
815 |
810 @param parent the model parent |
816 @param parent the model parent |
811 @type QModelIndex |
817 @type QModelIndex |
812 @return flag if parent has children |
818 @return flag if parent has children |
813 @rtype bool |
819 @rtype bool |
814 """ |
820 """ |
815 return self.sourceModel().hasChildren(self.mapToSource(parent)) |
821 return self.sourceModel().hasChildren(self.mapToSource(parent)) |
816 |
822 |
817 def setExpanded(self, index, state): |
823 def setExpanded(self, index, state): |
818 """ |
824 """ |
819 Public slot to get a flag if parent has children. |
825 Public slot to get a flag if parent has children. |
820 |
826 |
821 The given model index has to be transformed to the underlying source |
827 The given model index has to be transformed to the underlying source |
822 model to get the correct result. |
828 model to get the correct result. |
823 @param index item to change expanded state |
829 @param index item to change expanded state |
824 @type QModelIndex |
830 @type QModelIndex |
825 @param state state of the item |
831 @param state state of the item |
829 |
835 |
830 |
836 |
831 class VariablesViewer(QTreeView): |
837 class VariablesViewer(QTreeView): |
832 """ |
838 """ |
833 Class implementing the variables viewer view. |
839 Class implementing the variables viewer view. |
834 |
840 |
835 This view is used to display the variables of the program being |
841 This view is used to display the variables of the program being |
836 debugged in a tree. Compound types will be shown with |
842 debugged in a tree. Compound types will be shown with |
837 their main entry first. Once the subtree has been expanded, the |
843 their main entry first. Once the subtree has been expanded, the |
838 individual entries will be shown. Double clicking an entry will |
844 individual entries will be shown. Double clicking an entry will |
839 expand or collapse the item, if it has children and the double click |
845 expand or collapse the item, if it has children and the double click |
840 was performed on the first column of the tree, otherwise it'll |
846 was performed on the first column of the tree, otherwise it'll |
841 popup a dialog showing the variables parameters in a more readable |
847 popup a dialog showing the variables parameters in a more readable |
842 form. This is especially useful for lengthy strings. |
848 form. This is especially useful for lengthy strings. |
843 |
849 |
844 This view has two modes for displaying the global and the local |
850 This view has two modes for displaying the global and the local |
845 variables. |
851 variables. |
846 |
852 |
847 @signal preferencesChanged() to inform model about new background colours |
853 @signal preferencesChanged() to inform model about new background colours |
848 """ |
854 """ |
|
855 |
849 preferencesChanged = pyqtSignal() |
856 preferencesChanged = pyqtSignal() |
850 |
857 |
851 def __init__(self, viewer, globalScope, parent=None): |
858 def __init__(self, viewer, globalScope, parent=None): |
852 """ |
859 """ |
853 Constructor |
860 Constructor |
854 |
861 |
855 @param viewer reference to the debug viewer object |
862 @param viewer reference to the debug viewer object |
856 @type DebugViewer |
863 @type DebugViewer |
857 @param globalScope flag indicating global (True) or local (False) |
864 @param globalScope flag indicating global (True) or local (False) |
858 variables |
865 variables |
859 @type bool |
866 @type bool |
860 @param parent the parent |
867 @param parent the parent |
861 @type QWidget |
868 @type QWidget |
862 """ |
869 """ |
863 super().__init__(parent) |
870 super().__init__(parent) |
864 |
871 |
865 self.__debugViewer = viewer |
872 self.__debugViewer = viewer |
866 self.__globalScope = globalScope |
873 self.__globalScope = globalScope |
867 self.framenr = 0 |
874 self.framenr = 0 |
868 |
875 |
869 # Massive performance gain |
876 # Massive performance gain |
870 self.setUniformRowHeights(True) |
877 self.setUniformRowHeights(True) |
871 |
878 |
872 # Implements sorting and filtering |
879 # Implements sorting and filtering |
873 self.proxyModel = VariablesProxyModel() |
880 self.proxyModel = VariablesProxyModel() |
874 # Variable model implements the underlying data model |
881 # Variable model implements the underlying data model |
875 self.varModel = VariablesModel(self, globalScope) |
882 self.varModel = VariablesModel(self, globalScope) |
876 self.proxyModel.setSourceModel(self.varModel) |
883 self.proxyModel.setSourceModel(self.varModel) |
877 self.setModel(self.proxyModel) |
884 self.setModel(self.proxyModel) |
878 self.preferencesChanged.connect(self.varModel.handlePreferencesChanged) |
885 self.preferencesChanged.connect(self.varModel.handlePreferencesChanged) |
879 self.preferencesChanged.emit() # Force initialization of colors |
886 self.preferencesChanged.emit() # Force initialization of colors |
880 |
887 |
881 self.expanded.connect( |
888 self.expanded.connect(lambda idx: self.proxyModel.setExpanded(idx, True)) |
882 lambda idx: self.proxyModel.setExpanded(idx, True)) |
889 self.collapsed.connect(lambda idx: self.proxyModel.setExpanded(idx, False)) |
883 self.collapsed.connect( |
890 |
884 lambda idx: self.proxyModel.setExpanded(idx, False)) |
|
885 |
|
886 self.setExpandsOnDoubleClick(False) |
891 self.setExpandsOnDoubleClick(False) |
887 self.doubleClicked.connect(self.__itemDoubleClicked) |
892 self.doubleClicked.connect(self.__itemDoubleClicked) |
888 |
893 |
889 self.varModel.expand.connect(self.__mdlRequestExpand) |
894 self.varModel.expand.connect(self.__mdlRequestExpand) |
890 |
895 |
891 self.setSortingEnabled(True) |
896 self.setSortingEnabled(True) |
892 self.setAlternatingRowColors(True) |
897 self.setAlternatingRowColors(True) |
893 self.setSelectionBehavior( |
898 self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) |
894 QAbstractItemView.SelectionBehavior.SelectRows) |
899 |
895 |
|
896 if self.__globalScope: |
900 if self.__globalScope: |
897 self.setWindowTitle(self.tr("Global Variables")) |
901 self.setWindowTitle(self.tr("Global Variables")) |
898 self.setWhatsThis(self.tr( |
902 self.setWhatsThis( |
899 """<b>The Global Variables Viewer Window</b>""" |
903 self.tr( |
900 """<p>This window displays the global variables""" |
904 """<b>The Global Variables Viewer Window</b>""" |
901 """ of the debugged program.</p>""" |
905 """<p>This window displays the global variables""" |
902 )) |
906 """ of the debugged program.</p>""" |
|
907 ) |
|
908 ) |
903 else: |
909 else: |
904 self.setWindowTitle(self.tr("Local Variables")) |
910 self.setWindowTitle(self.tr("Local Variables")) |
905 self.setWhatsThis(self.tr( |
911 self.setWhatsThis( |
906 """<b>The Local Variables Viewer Window</b>""" |
912 self.tr( |
907 """<p>This window displays the local variables""" |
913 """<b>The Local Variables Viewer Window</b>""" |
908 """ of the debugged program.</p>""" |
914 """<p>This window displays the local variables""" |
909 )) |
915 """ of the debugged program.</p>""" |
910 |
916 ) |
|
917 ) |
|
918 |
911 header = self.header() |
919 header = self.header() |
912 header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) |
920 header.setSortIndicator(0, Qt.SortOrder.AscendingOrder) |
913 header.setSortIndicatorShown(True) |
921 header.setSortIndicatorShown(True) |
914 |
922 |
915 try: |
923 try: |
916 header.setSectionsClickable(True) |
924 header.setSectionsClickable(True) |
917 except Exception: |
925 except Exception: |
918 header.setClickable(True) |
926 header.setClickable(True) |
919 |
927 |
920 header.resizeSection(0, 130) # variable column |
928 header.resizeSection(0, 130) # variable column |
921 header.resizeSection(1, 180) # value column |
929 header.resizeSection(1, 180) # value column |
922 header.resizeSection(2, 50) # type column |
930 header.resizeSection(2, 50) # type column |
923 |
931 |
924 header.sortIndicatorChanged.connect(lambda *x: self.varModel.getMore()) |
932 header.sortIndicatorChanged.connect(lambda *x: self.varModel.getMore()) |
925 |
933 |
926 self.__createPopupMenus() |
934 self.__createPopupMenus() |
927 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
935 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
928 self.customContextMenuRequested.connect(self.__showContextMenu) |
936 self.customContextMenuRequested.connect(self.__showContextMenu) |
929 |
937 |
930 self.resortEnabled = True |
938 self.resortEnabled = True |
931 |
939 |
932 def showVariables(self, vlist, frmnr): |
940 def showVariables(self, vlist, frmnr): |
933 """ |
941 """ |
934 Public method to show variables in a list. |
942 Public method to show variables in a list. |
935 |
943 |
936 @param vlist the list of variables to be displayed. Each |
944 @param vlist the list of variables to be displayed. Each |
937 list entry is a tuple of three values. |
945 list entry is a tuple of three values. |
938 <ul> |
946 <ul> |
939 <li>the variable name (string)</li> |
947 <li>the variable name (string)</li> |
940 <li>the variables type (string)</li> |
948 <li>the variables type (string)</li> |
961 <li>the variables value (string)</li> |
969 <li>the variables value (string)</li> |
962 </ul> |
970 </ul> |
963 @type list |
971 @type list |
964 """ |
972 """ |
965 self.varModel.showVariables(vlist[1:], 0, vlist[0]) |
973 self.varModel.showVariables(vlist[1:], 0, vlist[0]) |
966 |
974 |
967 def handleResetUI(self): |
975 def handleResetUI(self): |
968 """ |
976 """ |
969 Public method to reset the VariablesViewer. |
977 Public method to reset the VariablesViewer. |
970 """ |
978 """ |
971 self.varModel.clear(True) |
979 self.varModel.clear(True) |
972 |
980 |
973 def verticalScrollbarValueChanged(self, value): |
981 def verticalScrollbarValueChanged(self, value): |
974 """ |
982 """ |
975 Public slot informing about the scrollbar change. |
983 Public slot informing about the scrollbar change. |
976 |
984 |
977 @param value current value of the vertical scrollbar |
985 @param value current value of the vertical scrollbar |
978 @type int |
986 @type int |
979 """ |
987 """ |
980 self.varModel.getMore() |
988 self.varModel.getMore() |
981 super().verticalScrollbarValueChanged(value) |
989 super().verticalScrollbarValueChanged(value) |
982 |
990 |
983 def resizeEvent(self, event): |
991 def resizeEvent(self, event): |
984 """ |
992 """ |
985 Protected slot informing about the widget size change. |
993 Protected slot informing about the widget size change. |
986 |
994 |
987 @param event information |
995 @param event information |
988 @type QResizeEvent |
996 @type QResizeEvent |
989 """ |
997 """ |
990 self.varModel.getMore() |
998 self.varModel.getMore() |
991 super().resizeEvent(event) |
999 super().resizeEvent(event) |
992 |
1000 |
993 def __itemDoubleClicked(self, index): |
1001 def __itemDoubleClicked(self, index): |
994 """ |
1002 """ |
995 Private method called if an item was double clicked. |
1003 Private method called if an item was double clicked. |
996 |
1004 |
997 @param index the double clicked item |
1005 @param index the double clicked item |
998 @type QModelIndex |
1006 @type QModelIndex |
999 """ |
1007 """ |
1000 node = self.proxyModel.mapToSource(index).internalPointer() |
1008 node = self.proxyModel.mapToSource(index).internalPointer() |
1001 if node.hasChildren and index.column() == 0: |
1009 if node.hasChildren and index.column() == 0: |
1002 state = self.isExpanded(index) |
1010 state = self.isExpanded(index) |
1003 self.setExpanded(index, not state) |
1011 self.setExpanded(index, not state) |
1004 else: |
1012 else: |
1005 self.__showVariableDetails(index) |
1013 self.__showVariableDetails(index) |
1006 |
1014 |
1007 def __mdlRequestExpand(self, modelIndex): |
1015 def __mdlRequestExpand(self, modelIndex): |
1008 """ |
1016 """ |
1009 Private method to inform the view about items to be expand. |
1017 Private method to inform the view about items to be expand. |
1010 |
1018 |
1011 @param modelIndex the model index |
1019 @param modelIndex the model index |
1012 @type QModelIndex |
1020 @type QModelIndex |
1013 """ |
1021 """ |
1014 index = self.proxyModel.mapFromSource(modelIndex) |
1022 index = self.proxyModel.mapFromSource(modelIndex) |
1015 self.expand(index) |
1023 self.expand(index) |
1016 |
1024 |
1017 def __createPopupMenus(self): |
1025 def __createPopupMenus(self): |
1018 """ |
1026 """ |
1019 Private method to generate the popup menus. |
1027 Private method to generate the popup menus. |
1020 """ |
1028 """ |
1021 self.menu = QMenu() |
1029 self.menu = QMenu() |
1074 row = node.children.index(child) |
1082 row = node.children.index(child) |
1075 idx = self.varModel.createIndex(row, 0, child) |
1083 idx = self.varModel.createIndex(row, 0, child) |
1076 idx = self.proxyModel.mapFromSource(idx) |
1084 idx = self.proxyModel.mapFromSource(idx) |
1077 if self.isExpanded(idx): |
1085 if self.isExpanded(idx): |
1078 self.collapse(idx) |
1086 self.collapse(idx) |
1079 |
1087 |
1080 def __refreshView(self): |
1088 def __refreshView(self): |
1081 """ |
1089 """ |
1082 Private slot to refresh the view. |
1090 Private slot to refresh the view. |
1083 """ |
1091 """ |
1084 if self.__globalScope: |
1092 if self.__globalScope: |
1085 self.__debugViewer.setGlobalsFilter() |
1093 self.__debugViewer.setGlobalsFilter() |
1086 else: |
1094 else: |
1087 self.__debugViewer.setLocalsFilter() |
1095 self.__debugViewer.setLocalsFilter() |
1088 |
1096 |
1089 def __showDetails(self): |
1097 def __showDetails(self): |
1090 """ |
1098 """ |
1091 Private slot to show details about the selected variable. |
1099 Private slot to show details about the selected variable. |
1092 """ |
1100 """ |
1093 idx = self.currentIndex() |
1101 idx = self.currentIndex() |
1094 self.__showVariableDetails(idx) |
1102 self.__showVariableDetails(idx) |
1095 |
1103 |
1096 def __showVariableDetails(self, index): |
1104 def __showVariableDetails(self, index): |
1097 """ |
1105 """ |
1098 Private method to show details about a variable. |
1106 Private method to show details about a variable. |
1099 |
1107 |
1100 @param index reference to the variable item |
1108 @param index reference to the variable item |
1101 @type QModelIndex |
1109 @type QModelIndex |
1102 """ |
1110 """ |
1103 node = self.proxyModel.mapToSource(index).internalPointer() |
1111 node = self.proxyModel.mapToSource(index).internalPointer() |
1104 |
1112 |
1105 val = node.value |
1113 val = node.value |
1106 vtype = node.type |
1114 vtype = node.type |
1107 name = node.name |
1115 name = node.name |
1108 |
1116 |
1109 par = node.parent |
1117 par = node.parent |
1110 nlist = [name] |
1118 nlist = [name] |
1111 |
1119 |
1112 # build up the fully qualified name |
1120 # build up the fully qualified name |
1113 while par.parent is not None: |
1121 while par.parent is not None: |
1114 pname = par.name |
1122 pname = par.name |
1115 if par.indicator: |
1123 if par.indicator: |
1116 if nlist[0].endswith("."): |
1124 if nlist[0].endswith("."): |
1117 nlist[0] = '[{0}].'.format(nlist[0][:-1]) |
1125 nlist[0] = "[{0}].".format(nlist[0][:-1]) |
1118 else: |
1126 else: |
1119 nlist[0] = '[{0}]'.format(nlist[0]) |
1127 nlist[0] = "[{0}]".format(nlist[0]) |
1120 nlist.insert(0, pname) |
1128 nlist.insert(0, pname) |
1121 else: |
1129 else: |
1122 if par.type == "django.MultiValueDict": |
1130 if par.type == "django.MultiValueDict": |
1123 nlist[0] = 'getlist({0})'.format(nlist[0]) |
1131 nlist[0] = "getlist({0})".format(nlist[0]) |
1124 elif par.type == "numpy.ndarray": |
1132 elif par.type == "numpy.ndarray": |
1125 if nlist and nlist[0][0].isalpha(): |
1133 if nlist and nlist[0][0].isalpha(): |
1126 if nlist[0] in ["min", "max", "mean"]: |
1134 if nlist[0] in ["min", "max", "mean"]: |
1127 nlist[0] = ".{0}()".format(nlist[0]) |
1135 nlist[0] = ".{0}()".format(nlist[0]) |
1128 else: |
1136 else: |
1129 nlist[0] = ".{0}".format(nlist[0]) |
1137 nlist[0] = ".{0}".format(nlist[0]) |
1130 nlist.insert(0, pname) |
1138 nlist.insert(0, pname) |
1131 else: |
1139 else: |
1132 nlist.insert(0, '{0}.'.format(pname)) |
1140 nlist.insert(0, "{0}.".format(pname)) |
1133 par = par.parent |
1141 par = par.parent |
1134 |
1142 |
1135 name = ''.join(nlist) |
1143 name = "".join(nlist) |
1136 # now show the dialog |
1144 # now show the dialog |
1137 from .VariableDetailDialog import VariableDetailDialog |
1145 from .VariableDetailDialog import VariableDetailDialog |
|
1146 |
1138 dlg = VariableDetailDialog(name, vtype, val) |
1147 dlg = VariableDetailDialog(name, vtype, val) |
1139 dlg.exec() |
1148 dlg.exec() |
1140 |
1149 |
1141 def __configure(self): |
1150 def __configure(self): |
1142 """ |
1151 """ |
1143 Private method to open the configuration dialog. |
1152 Private method to open the configuration dialog. |
1144 """ |
1153 """ |
1145 ericApp().getObject("UserInterface").showPreferences( |
1154 ericApp().getObject("UserInterface").showPreferences("debuggerGeneralPage") |
1146 "debuggerGeneralPage") |
1155 |
1147 |
|
1148 def __configureFilter(self): |
1156 def __configureFilter(self): |
1149 """ |
1157 """ |
1150 Private method to open the variables filter dialog. |
1158 Private method to open the variables filter dialog. |
1151 """ |
1159 """ |
1152 ericApp().getObject("DebugUI").dbgFilterAct.triggered.emit() |
1160 ericApp().getObject("DebugUI").dbgFilterAct.triggered.emit() |
|
1161 |
1153 |
1162 |
1154 # |
1163 # |
1155 # eflag: noqa = M822 |
1164 # eflag: noqa = M822 |