mirror of
https://github.com/gaasedelen/lighthouse
synced 2026-06-08 14:19:10 +00:00
177 lines
6.6 KiB
Python
177 lines
6.6 KiB
Python
import os
|
|
import logging
|
|
|
|
from lighthouse.util import lmsg
|
|
from lighthouse.util.qt import *
|
|
from lighthouse.util.misc import human_timestamp
|
|
from lighthouse.util.python import *
|
|
|
|
logger = logging.getLogger("Lighthouse.UI.Xref")
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Coverage Xref Dialog
|
|
#------------------------------------------------------------------------------
|
|
|
|
class CoverageXref(QtWidgets.QDialog):
|
|
"""
|
|
A Qt Dialog to list other coverage sets that contain a given address.
|
|
|
|
This class makes up a rudimentary xref dialog. It does not follow Qt
|
|
'best practices' because it does not need to be super flashy, nor does
|
|
it demand much facetime.
|
|
"""
|
|
|
|
def __init__(self, director, address):
|
|
super(CoverageXref, self).__init__()
|
|
self._director = director
|
|
|
|
# dialog attributes
|
|
self.address = address
|
|
self.selected_coverage = None
|
|
self.selected_filepath = None
|
|
|
|
# configure the widget for use
|
|
self._ui_init()
|
|
|
|
#--------------------------------------------------------------------------
|
|
# Initialization - UI
|
|
#--------------------------------------------------------------------------
|
|
|
|
def _ui_init(self):
|
|
"""
|
|
Initialize UI elements.
|
|
"""
|
|
self.setWindowTitle("Coverage Xrefs to 0x%X" % self.address)
|
|
self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
|
|
self.setModal(True)
|
|
|
|
self._font = self.font()
|
|
self._font.setPointSizeF(normalize_to_dpi(10))
|
|
self._font_metrics = QtGui.QFontMetricsF(self._font)
|
|
|
|
# initialize coverage xref table
|
|
self._ui_init_table()
|
|
self._populate_table()
|
|
|
|
# layout the populated UI just before showing it
|
|
self._ui_layout()
|
|
|
|
def _ui_init_table(self):
|
|
"""
|
|
Initialize the coverage xref table UI elements.
|
|
"""
|
|
self._table = QtWidgets.QTableWidget()
|
|
self._table.verticalHeader().setVisible(False)
|
|
self._table.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
|
self._table.horizontalHeader().setFont(self._font)
|
|
self._table.setFont(self._font)
|
|
self._table.setWordWrap(False)
|
|
|
|
# symbol, cov %, name, time
|
|
self._table.setColumnCount(4)
|
|
self._table.setHorizontalHeaderLabels(["Sym", "Cov %", "Coverage Name", "Timestamp"])
|
|
self._table.setColumnWidth(0, 45)
|
|
self._table.setColumnWidth(1, 55)
|
|
self._table.setColumnWidth(2, 400)
|
|
self._table.setColumnWidth(3, 100)
|
|
|
|
# left align text in column headers
|
|
for i in range(4):
|
|
self._table.horizontalHeaderItem(i).setTextAlignment(QtCore.Qt.AlignLeft)
|
|
|
|
# disable bolding of column headers when selected
|
|
self._table.horizontalHeader().setHighlightSections(False)
|
|
|
|
# stretch the filename field, as it is the most important
|
|
self._table.horizontalHeader().setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
|
|
|
|
# make table read only, select a full row by default
|
|
self._table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
|
self._table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
|
|
|
# catch double click events on table rows
|
|
self._table.cellDoubleClicked.connect(self._ui_cell_double_click)
|
|
|
|
def _populate_table(self):
|
|
"""
|
|
Populate the xref table with data from the coverage director.
|
|
"""
|
|
cov_xrefs = self._director.get_address_coverage(self.address)
|
|
file_xrefs = self._director.get_address_file(self.address)
|
|
|
|
# dedupe
|
|
for coverage in cov_xrefs:
|
|
if coverage.filepath in file_xrefs:
|
|
file_xrefs.remove(coverage.filepath)
|
|
|
|
# populate table with coverage details
|
|
self._table.setSortingEnabled(False)
|
|
self._table.setRowCount(len(cov_xrefs) + len(file_xrefs))
|
|
|
|
# coverage objects
|
|
for i, coverage in enumerate(cov_xrefs, 0):
|
|
self._table.setItem(i, 0, QtWidgets.QTableWidgetItem(self._director.get_shorthand(coverage.name)))
|
|
self._table.setItem(i, 1, QtWidgets.QTableWidgetItem("%5.2f" % (coverage.instruction_percent*100)))
|
|
name_entry = QtWidgets.QTableWidgetItem(coverage.name)
|
|
name_entry.setToolTip(coverage.filepath)
|
|
self._table.setItem(i, 2, name_entry)
|
|
date_entry = QtWidgets.QTableWidgetItem()
|
|
date_entry.setData(QtCore.Qt.DisplayRole, QtCore.QDateTime.fromMSecsSinceEpoch(int(coverage.timestamp*1000)))
|
|
self._table.setItem(i, 3, QtWidgets.QTableWidgetItem(date_entry))
|
|
|
|
# filepaths
|
|
for i, filepath in enumerate(file_xrefs, len(cov_xrefs)):
|
|
|
|
# try to read timestamp of the file on disk (if it exists)
|
|
try:
|
|
timestamp = os.path.getmtime(filepath)
|
|
except (OSError, TypeError):
|
|
timestamp = 0
|
|
|
|
# populate table entry
|
|
self._table.setItem(i, 0, QtWidgets.QTableWidgetItem("-"))
|
|
self._table.setItem(i, 1, QtWidgets.QTableWidgetItem("-"))
|
|
name_entry = QtWidgets.QTableWidgetItem(os.path.basename(filepath))
|
|
name_entry.setToolTip(filepath)
|
|
self._table.setItem(i, 2, name_entry)
|
|
date_entry = QtWidgets.QTableWidgetItem()
|
|
date_entry.setData(QtCore.Qt.DisplayRole, QtCore.QDateTime.fromMSecsSinceEpoch(int(timestamp*1000)))
|
|
self._table.setItem(i, 3, date_entry)
|
|
|
|
self._table.resizeColumnsToContents()
|
|
self._table.resizeRowsToContents()
|
|
|
|
self._table.setSortingEnabled(True)
|
|
|
|
def _ui_layout(self):
|
|
"""
|
|
Layout the major UI elements of the widget.
|
|
"""
|
|
layout = QtWidgets.QVBoxLayout()
|
|
|
|
# layout child widgets
|
|
layout.addWidget(self._table)
|
|
|
|
# scale widget dimensions based on DPI
|
|
height = int(get_dpi_scale() * 250)
|
|
width = int(get_dpi_scale() * 600)
|
|
self.setMinimumHeight(height)
|
|
self.setMinimumWidth(width)
|
|
|
|
# apply the widget layout
|
|
self.setLayout(layout)
|
|
|
|
#--------------------------------------------------------------------------
|
|
# Signal Handlers
|
|
#--------------------------------------------------------------------------
|
|
|
|
def _ui_cell_double_click(self, row, column):
|
|
"""
|
|
A cell/row has been double clicked in the xref table.
|
|
"""
|
|
if self._table.item(row, 0).text() == "-":
|
|
self.selected_filepath = self._table.item(row, 2).toolTip()
|
|
else:
|
|
self.selected_coverage = self._table.item(row, 2).text()
|
|
self.accept()
|