Files
2021-07-29 10:33:00 -04:00

112 lines
3.4 KiB
Python

import os
import logging
from lighthouse.util.qt import *
from lighthouse.painting import CoveragePainter
from lighthouse.director import CoverageDirector
from lighthouse.coverage import DatabaseCoverage
from lighthouse.metadata import DatabaseMetadata
from lighthouse.util.disassembler import disassembler, DisassemblerContextAPI
logger = logging.getLogger("Lighthouse.Context")
#------------------------------------------------------------------------------
# Lighthouse Session Context
#------------------------------------------------------------------------------
class LighthouseContext(object):
"""
A database/binary-unique instance of Lighthouse and its subsystems.
"""
def __init__(self, core, dctx):
disassembler[self] = DisassemblerContextAPI(dctx)
self.core = core
self.dctx = dctx
self._started = False
# the database metadata cache
self.metadata = DatabaseMetadata(self)
# the coverage engine
self.director = CoverageDirector(self.metadata, self.core.palette)
# the coverage painter
self.painter = CoveragePainter(self, self.director, self.core.palette)
# the coverage overview widget
self.coverage_overview = None
# the directory to start the coverage file dialog in
self._last_directory = None
@property
def palette(self):
return self.core.palette
def start(self):
"""
One-time activation a Lighthouse context and its subsystems.
"""
if self._started:
return
self.core.palette.warmup()
self.metadata.start()
self.director.start()
self.painter.start()
# TODO/BINJA remove this ASAP, or find a better workaround... I hate having this here
if disassembler.NAME == "BINJA":
disassembler.hide_dockable("Feature Map")
self._started = True
def terminate(self):
"""
Spin down any session subsystems before the session is deleted.
"""
if not self._started:
return
self.painter.terminate()
self.director.terminate()
self.metadata.terminate()
def select_coverage_files(self):
"""
Prompt a file selection dialog, returning file selections.
NOTE: This saves & reuses the last known directory for subsequent uses.
"""
if not self._last_directory:
self._last_directory = disassembler[self].get_database_directory()
# create & configure a Qt File Dialog for immediate use
file_dialog = QtWidgets.QFileDialog(
None,
'Open code coverage file',
self._last_directory,
'All Files (*.*)'
)
file_dialog.setFileMode(QtWidgets.QFileDialog.ExistingFiles)
# prompt the user with the file dialog, and await filename(s)
filenames, _ = file_dialog.getOpenFileNames()
#
# remember the last directory we were in (parsed from a selected file)
# for the next time the user comes to load coverage files
#
if filenames:
self._last_directory = os.path.dirname(filenames[0]) + os.sep
# log the captured (selected) filenames from the dialog
logger.debug("Captured filenames from file dialog:")
for name in filenames:
logger.debug(" - %s" % name)
# return the captured filenames
return filenames