18 lines
6.9 KiB
JSON
18 lines
6.9 KiB
JSON
{
|
|
"sourceFile": "Project Notes/GUI_Preview_Table_Restructure_Plan.md",
|
|
"activeCommit": 0,
|
|
"commits": [
|
|
{
|
|
"activePatchIndex": 0,
|
|
"patches": [
|
|
{
|
|
"date": 1745497239689,
|
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
|
}
|
|
],
|
|
"date": 1745497239689,
|
|
"name": "Commit-0",
|
|
"content": "# GUI Preview Table Restructure Plan\r\n\r\n## Objective\r\n\r\nRestructure the Graphical User Interface (GUI) preview table to group files by source asset and display \"Ignored\" and \"Extra\" files in a new \"Additional Files\" column, aligned with the mapped files of the same asset.\r\n\r\n## Analysis\r\n\r\nBased on the review of `gui/prediction_handler.py` and `gui/preview_table_model.py`:\r\n\r\n* The `PredictionHandler` provides a flat list of file prediction dictionaries.\r\n* The `PreviewTableModel` currently stores and displays this flat list directly.\r\n* The `PreviewSortFilterProxyModel` sorts this flat list.\r\n* The data transformation to achieve the desired grouped layout must occur within the `PreviewTableModel`.\r\n\r\n## Proposed Plan\r\n\r\n1. **Modify `gui/preview_table_model.py`:**\r\n * **Add New Column:**\r\n * Define a new constant: `COL_ADDITIONAL_FILES = 5`.\r\n * Add \"Additional Files\" to the `_headers_detailed` list.\r\n * **Introduce New Internal Data Structure:**\r\n * Create a new internal list, `self._table_rows`, to store dictionaries representing the final rows to be displayed in the table.\r\n * **Update `set_data(self, data: list)`:**\r\n * Process the incoming flat `data` list (received from `PredictionHandler`).\r\n * Group file dictionaries by their `source_asset`.\r\n * Within each asset group, separate files into two lists:\r\n * `main_files`: Files with status \"Mapped\", \"Model\", or \"Error\".\r\n * `additional_files`: Files with status \"Ignored\", \"Extra\", \"Unrecognised\", or \"Unmatched Extra\".\r\n * Determine the maximum number of rows needed for this asset block: `max(len(main_files), len(additional_files))`.\r\n * Build the row dictionaries for `self._table_rows` for this asset block:\r\n * For `i` from 0 to `max_rows - 1`:\r\n * Get the `i`-th file from `main_files` (or `None` if `i` is out of bounds).\r\n * Get the `i`-th file from `additional_files` (or `None` if `i` is out of bounds).\r\n * Create a row dictionary containing:\r\n * `source_asset`: The asset name.\r\n * `predicted_asset`: From the `main_file` (if exists).\r\n * `details`: From the `main_file` (if exists).\r\n * `original_path`: From the `main_file` (if exists).\r\n * `additional_file_path`: Path from the `additional_file` (if exists).\r\n * `additional_file_details`: The original dictionary of the `additional_file` (if exists, for tooltips).\r\n * `is_main_row`: Boolean flag (True if this row corresponds to a file in `main_files`, False otherwise).\r\n * Append these row dictionaries to `self._table_rows`.\r\n * After processing all assets, call `self.beginResetModel()` and `self.endResetModel()`.\r\n * **Update `rowCount`:** Return `len(self._table_rows)` when in detailed mode.\r\n * **Update `columnCount`:** Return `len(self._headers_detailed)`.\r\n * **Update `data(self, index, role)`:**\r\n * Retrieve the row dictionary: `row_data = self._table_rows[index.row()]`.\r\n * For `Qt.ItemDataRole.DisplayRole`:\r\n * If `index.column()` is `COL_ADDITIONAL_FILES`, return `row_data.get('additional_file_path', '')`.\r\n * For other columns (`COL_STATUS`, `COL_PREDICTED_ASSET`, `COL_ORIGINAL_PATH`, `COL_DETAILS`), return data from the `main_file` part of `row_data` if `row_data['is_main_row']` is True, otherwise return an empty string or appropriate placeholder.\r\n * For `Qt.ItemDataRole.ToolTipRole`:\r\n * If `index.column()` is `COL_ADDITIONAL_FILES` and `row_data.get('additional_file_details')` exists, generate a tooltip using the status and details from `additional_file_details`.\r\n * For other columns, use the existing tooltip logic based on the `main_file` data.\r\n * For `Qt.ItemDataRole.ForegroundRole`:\r\n * Apply existing color-coding based on the status of the `main_file` if `row_data['is_main_row']` is True.\r\n * For the `COL_ADDITIONAL_FILES` cell and for rows where `row_data['is_main_row']` is False, use neutral styling (default text color).\r\n * **Update `headerData`:** Return the correct header for `COL_ADDITIONAL_FILES`.\r\n\r\n2. **Modify `gui/preview_table_model.py` (`PreviewSortFilterProxyModel`):**\r\n * **Update `lessThan(self, left, right)`:**\r\n * Retrieve the row dictionaries for `left` and `right` indices from the source model (`model._table_rows[left.row()]`, etc.).\r\n * **Level 1: Source Asset:** Compare `source_asset` from the row dictionaries.\r\n * **Level 2: Row Type:** If assets are the same, compare `is_main_row` (True sorts before False).\r\n * **Level 3 (Main Rows):** If both are main rows (`is_main_row` is True), compare `original_path`.\r\n * **Level 4 (Additional-Only Rows):** If both are additional-only rows (`is_main_row` is False), compare `additional_file_path`.\r\n\r\n## Clarifications & Decisions\r\n\r\n* **Error Handling:** \"Error\" files will remain in the main columns, similar to \"Mapped\" files, with their current \"Error\" status.\r\n* **Sorting within Asset:** The proposed sorting logic within an asset block is acceptable (mapped rows by original path, additional-only rows by additional file path).\r\n* **Styling of Additional Column:** Use neutral text and background styling for the \"Additional Files\" column, relying on tooltips for specific file details.\r\n\r\n## Mermaid Diagram (Updated Data Flow)\r\n\r\n```mermaid\r\ngraph LR\r\n A[PredictionHandler] -- prediction_results_ready(flat_list) --> B(PreviewTableModel);\r\n subgraph PreviewTableModel\r\n C[set_data] -- Processes flat_list --> D{Internal Grouping & Transformation};\r\n D -- Creates --> E[_table_rows (Structured List)];\r\n F[data()] -- Reads from --> E;\r\n end\r\n B -- Provides data via data() --> G(QTableView via Proxy);\r\n\r\n style B fill:#f9f,stroke:#333,stroke-width:2px\r\n style C fill:#ccf,stroke:#333,stroke-width:1px\r\n style D fill:#lightgrey,stroke:#333,stroke-width:1px\r\n style E fill:#ccf,stroke:#333,stroke-width:1px\r\n style F fill:#ccf,stroke:#333,stroke-width:1px"
|
|
}
|
|
]
|
|
} |