diff --git a/python/graph_list_table_model.py b/python/graph_list_table_model.py index 1dfc34cabd5e42dd8c8122d02f7511f8fc8a810a..338ca5c42ad7ed7b638e5c0e00b58371dc8d2e6e 100644 --- a/python/graph_list_table_model.py +++ b/python/graph_list_table_model.py @@ -1,5 +1,6 @@ from PySide6.QtCore import Qt, QAbstractTableModel, QModelIndex from mp_code_parser import mp_code_say_headers, say_info +from message_popup import message_popup # graph list model column constants GRAPH_COLUMN = 0 # the graph item @@ -29,7 +30,8 @@ class GraphListTableModel(QAbstractTableModel): * dataChanged - call this to reflect change into views """ - def __init__(self): + def __init__(self, parent_window): + self.parent_window = parent_window self.headers = list() super().__init__() @@ -37,18 +39,27 @@ class GraphListTableModel(QAbstractTableModel): self.headers = list() def set_graph_list(self, graphs, mp_code): - self.beginResetModel() - # set the data - self.graphs = graphs + # calculate headers from SAY statements + say_headers, warnings = mp_code_say_headers(mp_code) - # set the headers - say_headers = mp_code_say_headers(mp_code) + # change the model's data and header titles + self.beginResetModel() + self.graphs = graphs self.headers = _HARDCODED_HEADERS.copy() self.headers.extend(say_headers) - self.endResetModel() + # maybe show warnings + if warnings: + message = "SAY statements containing both variables and text " \ + "with embedded numbers " \ + "cannot be used when sorting traces by attribute. " \ + "Columns will not be provided for SAY events " \ + "generated from the following SAY text:\n\n%s" \ + %("\n\n".join(warnings)) + message_popup(self.parent_window, message) + def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole): if role == Qt.ItemDataRole.DisplayRole \ diff --git a/python/gui_manager.py b/python/gui_manager.py index 34948c60a44ccb3b92d96879dcef16d2e83af1b6..502127301e346a109e881a6f53e26c040194e960 100644 --- a/python/gui_manager.py +++ b/python/gui_manager.py @@ -123,7 +123,7 @@ class GUIManager(QObject): self.spellcheck_whitelist_manager) # the graph list table model - self.graph_list_table_model = GraphListTableModel() + self.graph_list_table_model = GraphListTableModel(self.w) # the graphs manager self.graphs_manager = GraphsManager(self.graph_list_table_model, diff --git a/python/mp_code_parser.py b/python/mp_code_parser.py index e8ca8e36759ddb6551b9327739ebca51f3eb9544..76ee511c30ec50ff7688887d14cde5a3ec301dae 100644 --- a/python/mp_code_parser.py +++ b/python/mp_code_parser.py @@ -243,15 +243,18 @@ def _say_text_and_number_count(say_line): return quoted_text, number_count +# Return header list and warning list # derive sorted say headers from mp_code_text # We do not cache these results. This mp_code_text is from trace generation # and is called by graph_list_table_model when the graph is loaded. +_number_pattern = re.compile(r"[0-9.]+") def mp_code_say_headers(mp_code_text): # convert text into lines without comments non_comment_lines = _non_comment_lines(mp_code_text) header_list = list() + warnings = list() for line in non_comment_lines: non_quote_line = _non_quote_line(line) @@ -264,8 +267,15 @@ def mp_code_say_headers(mp_code_text): if _SAY_EXEMPTION_EXPRESSION.globalMatch(non_quote_line).hasNext(): continue + # parse out say_text and number count say_text, number_count = _say_text_and_number_count(line) + # say_text must not contain numbers else warn and drop + if number_count >= 1 and _number_pattern.findall(say_text): + say_content = _SAY_CONTENT.match(line).captured(1) + warnings.append(say_content) + continue + # add to texts and columns if number_count == 0: header_list.append(say_text) @@ -274,11 +284,10 @@ def mp_code_say_headers(mp_code_text): header_list.append("%s (%d)"%(say_text, i+1)) header_list = sorted(header_list, key=str.casefold) - return header_list + return header_list, warnings # Return text for the matching column else X or checkmark # Say nodes are type="T".""" -_number_pattern = re.compile(r"[0-9.]+") def say_info(gry_graph, column_title): if not "trace" in gry_graph: raise RuntimeError("bad")