Skip to content

Commit

Permalink
Add margin symbols for context errors
Browse files Browse the repository at this point in the history
Also added a warning dialog that appears when the user tries to move a ROI when
there's a syntax error in the code (which libcst will fail to parse).
  • Loading branch information
JamesWrigley committed Mar 16, 2022
1 parent d5771d4 commit 4b8f0e0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
9 changes: 9 additions & 0 deletions extra_foam/special_suite/correlator_proc.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,17 @@ def send_index(self):
class CorrelatorProcessor(QThreadWorker):
# Emitted when the views are changed
updated_views_sgn = pyqtSignal(dict)

# Emitted when incoming data is processed, only contains paths generated
# from the incoming data (not including e.g. view paths).
updated_data_paths_sgn = pyqtSignal(dict)

# Emitted upon a ContextError
context_error_sgn = pyqtSignal(object)

# Emitted upon a successful reload
reloaded_sgn = pyqtSignal()

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

Expand Down Expand Up @@ -424,6 +431,7 @@ def setContext(self, source: str):
except ContextError as e:
# ContextError's have their own functions for pretty printing
logger.error(e.format_for_context(source))
self.context_error_sgn.emit(e)
return
except Exception as e:
# For all other exceptions we log the traceback and error
Expand All @@ -434,6 +442,7 @@ def setContext(self, source: str):
self._paths = self._ctx.get_paths()
self._pipeline.set_context(self._ctx)

self.reloaded_sgn.emit()
self.log.info("Reloaded")

def close(self, timeout=1):
Expand Down
54 changes: 50 additions & 4 deletions extra_foam/special_suite/correlator_w.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
QStackedWidget, QComboBox, QLabel, QAction, QMenu,
QStyle, QTabBar, QToolButton, QFileDialog,
QCheckBox, QGridLayout, QHBoxLayout, QMessageBox,
QTreeWidget, QTreeWidgetItem, QAbstractItemView)
QTreeWidget, QTreeWidgetItem, QAbstractItemView,
QApplication)
from PyQt5.Qsci import QsciScintilla, QsciLexerPython, QsciAbstractAPIs

from metropc.client import ViewOutput
from metropc import error as mpc_error

from .. import ROOT_PATH
from ..utils import RectROI as MetroRectROI
Expand Down Expand Up @@ -973,11 +975,14 @@ def initUI(self):
self._editor.setIndentationsUseTabs(False)
self._editor.setTabWidth(4)
self._editor.setAutoIndent(True)
self._editor.setMarginWidth(0, "0000")
self._editor.setMarginLineNumbers(0, True)
self._editor.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch)
self._editor.textChanged.connect(self._onContextModified)

self._editor.setMarginWidth(0, "0000")
self._editor.setMarginLineNumbers(0, True)
self._editor.setMarginWidth(1, "0000")
self._editor.setMarginType(1, QsciScintilla.MarginType.SymbolMargin)

self._tab_widget.addTab(self._editor, "Context")

# Add fake tab to add create new tabs
Expand All @@ -996,6 +1001,11 @@ def initUI(self):

self.resize(self._TOTAL_W, self._TOTAL_H)

error_marker_nr = 0
self._editor.markerDefine(QsciScintilla.MarkerSymbol.Circle, error_marker_nr)
self._editor.setMarkerForegroundColor(FColor.mkColor("r"), error_marker_nr)
self._editor.setMarkerBackgroundColor(FColor.mkColor("r"), error_marker_nr)

def initConnections(self):
ctrl = self._ctrl_widget_st
worker = self._worker_st
Expand All @@ -1012,10 +1022,30 @@ def initConnections(self):
self._com_ctrl_st.port_changed_sgn.connect(self._onPortChanged)
self._com_ctrl_st.client_type_changed_sgn.connect(self._onClientTypeChanged)

worker.reloaded_sgn.connect(self._clearMarkers)
worker.context_error_sgn.connect(self._onContextError)
worker.updated_views_sgn.connect(self._onViewsUpdated)
worker.updated_data_paths_sgn.connect(self._completer.setDataPaths)
worker.updated_data_paths_sgn.connect(self._ctrl_widget_st.setDataPaths)

def _onContextError(self, error):
if isinstance(error, cst.ParserSyntaxError):
lineno = error.raw_line
elif isinstance(error, mpc_error.PathResolutionError):
lineno = error.view.kernel.__code__.co_firstlineno
elif isinstance(error, mpc_error.ViewDefError):
lineno = error._find_context_frame("<ctx>") - 1
elif isinstance(error, mpc_error.ContextSyntaxError):
lineno = error.orig_error.lineno
else:
logger.error(f"Couldn't get line number from {type(error)} for display")
return

handle = self._editor.markerAdd(lineno - 1, self._error_marker_nr)

def _clearMarkers(self):
self._editor.markerDeleteAll()

@property
def context(self):
return self._worker_st._ctx
Expand Down Expand Up @@ -1064,7 +1094,23 @@ def onRoiChanged(self, roi):
raise RuntimeError("Unsupported ROI type")

# Modify the source as needed
module = cstmeta.MetadataWrapper(cst.parse_module(ctx))
try:
module = cstmeta.MetadataWrapper(cst.parse_module(ctx))
except cst.ParserSyntaxError as e:
logger.error(str(e))

marker_exists = self._editor.markerFindNext(e.raw_line - 1, 1) == e.raw_line - 1
if not marker_exists:
self._onContextError(e)
active_window = QApplication.activeWindow()
QMessageBox.warning(active_window,
"Syntax error in context",
"The context file has a syntax error, updating the parameters in the context file will not work until it is fixed.")

return
else:
self._clearMarkers()

transformer = RoiTransformer(roi_cls, roi_name, roi_args)
new_source = module.visit(transformer)

Expand Down

0 comments on commit 4b8f0e0

Please sign in to comment.