{
    "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"
        }
    ]
}