{
    "sourceFile": "Project Notes/GUI_FEATURE_PLAN.md",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 0,
            "patches": [
                {
                    "date": 1745236031597,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                }
            ],
            "date": 1745236031597,
            "name": "Commit-0",
            "content": "# GUI Feature Enhancement Plan\r\n\r\n**Overall Goal:** Modify the GUI (`gui/main_window.py`, `gui/prediction_handler.py`) to make the output path configurable, improve UI responsiveness during preview generation, and add a toggle to switch between detailed file preview and a simple input path list.\r\n\r\n**Detailed Plan:**\r\n\r\n1.  **Feature: Configurable Output Path**\r\n    *   **File:** `gui/main_window.py`\r\n    *   **Changes:**\r\n        *   **UI Addition:**\r\n            *   Below the `preset_combo` layout, add a new `QHBoxLayout`.\r\n            *   Inside this layout, add:\r\n                *   A `QLabel` with text \"Output Directory:\".\r\n                *   A `QLineEdit` (e.g., `self.output_path_edit`) to display/edit the path. Make it read-only initially if preferred, or editable.\r\n                *   A `QPushButton` (e.g., `self.browse_output_button`) with text \"Browse...\".\r\n        *   **Initialization (`__init__` or `setup_main_panel_ui`):**\r\n            *   Read the default `OUTPUT_BASE_DIR` from `core_config`.\r\n            *   Resolve this path relative to the project root (`project_root / output_base_dir_config`).\r\n            *   Set the initial text of `self.output_path_edit` to this resolved default path.\r\n        *   **Browse Button Logic:**\r\n            *   Connect the `clicked` signal of `self.browse_output_button` to a new method (e.g., `_browse_for_output_directory`).\r\n            *   Implement `_browse_for_output_directory`:\r\n                *   Use `QFileDialog.getExistingDirectory` to let the user select a folder.\r\n                *   If a directory is selected, update the text of `self.output_path_edit`.\r\n        *   **Processing Logic (`start_processing`):**\r\n            *   Instead of reading/resolving the path from `core_config`, get the path string directly from `self.output_path_edit.text()`.\r\n            *   Convert this string to a `Path` object.\r\n            *   **Add Validation:** Before passing the path to the handler, check if the directory exists. If not, attempt to create it using `output_dir.mkdir(parents=True, exist_ok=True)`. Handle potential `OSError` exceptions during creation and show an error message if it fails. Also, consider adding a basic writability check if possible.\r\n            *   Pass the validated `output_dir_str` to `self.processing_handler.run_processing`.\r\n\r\n2.  **Feature: Responsive UI (Address Prediction Bottleneck)**\r\n    *   **File:** `gui/prediction_handler.py`\r\n    *   **Changes:**\r\n        *   **Import:** Add `from concurrent.futures import ThreadPoolExecutor, as_completed`.\r\n        *   **Modify `run_prediction`:**\r\n            *   Inside the `try` block (after loading `config`), create a `ThreadPoolExecutor` (e.g., `with ThreadPoolExecutor(max_workers=...) as executor:`). Determine a reasonable `max_workers` count (e.g., `os.cpu_count() // 2` or a fixed number like 4 or 8).\r\n            *   Instead of iterating through `input_paths` sequentially, submit a task to the executor for each `input_path_str`.\r\n            *   The task submitted should be a helper method (e.g., `_predict_single_asset`) that takes `input_path_str` and the loaded `config` object as arguments.\r\n            *   `_predict_single_asset` will contain the logic currently inside the loop: instantiate `AssetProcessor`, call `get_detailed_file_predictions`, handle exceptions, and return the list of prediction dictionaries for that *single* asset (or an error dictionary).\r\n            *   Store the `Future` objects returned by `executor.submit`.\r\n            *   Use `as_completed(futures)` to process results as they become available.\r\n            *   Append the results from each completed future to the `all_file_results` list.\r\n            *   Emit `prediction_results_ready` once at the very end with the complete `all_file_results` list.\r\n    *   **File:** `gui/main_window.py`\r\n    *   **Changes:**\r\n        *   No changes needed in the `on_prediction_results_ready` slot itself, as the handler will still emit the full list at the end.\r\n\r\n3.  **Feature: Preview Toggle**\r\n    *   **File:** `gui/main_window.py`\r\n    *   **Changes:**\r\n        *   **UI Addition:**\r\n            *   Add a `QCheckBox` (e.g., `self.disable_preview_checkbox`) with text \"Disable Detailed Preview\". Place it logically, perhaps near the `overwrite_checkbox` or above the `preview_table`. Set its default state to unchecked.\r\n        *   **Modify `update_preview`:**\r\n            *   At the beginning of the method, check `self.disable_preview_checkbox.isChecked()`.\r\n            *   **If Checked (Simple View):**\r\n                *   Clear the `preview_table`.\r\n                *   Set simplified table headers (e.g., `self.preview_table.setColumnCount(1); self.preview_table.setHorizontalHeaderLabels([\"Input Path\"])`). Adjust column resize modes.\r\n                *   Iterate through `self.current_asset_paths`. For each path, add a row to the table containing just the path string.\r\n                *   Set status bar message (e.g., \"Preview disabled. Showing input list.\").\r\n                *   **Crucially:** `return` from the method here to prevent the `PredictionHandler` from being started.\r\n            *   **If Unchecked (Detailed View):**\r\n                *   Ensure the table headers and column count are set back to the detailed view configuration (Status, Original Path, Predicted Name, Details).\r\n                *   Continue with the rest of the existing `update_preview` logic to start the `PredictionHandler`.\r\n        *   **Connect Signal:** In `__init__` or `setup_main_panel_ui`, connect the `toggled` signal of `self.disable_preview_checkbox` to the `self.update_preview` slot.\r\n        *   **Initial State:** Ensure the first call to `update_preview` (if any) respects the initial unchecked state of the checkbox.\r\n\r\n**Mermaid Diagram:**\r\n\r\n```mermaid\r\ngraph TD\r\n    subgraph MainWindow\r\n        A[User Action: Add Asset / Change Preset / Toggle Preview] --> B{Update Preview Triggered};\r\n        B --> C{Is 'Disable Preview' Checked?};\r\n        C -- Yes --> D[Show Simple List View in Table];\r\n        C -- No --> E[Set Detailed Table Headers];\r\n        E --> F[Start PredictionHandler Thread];\r\n        F --> G[PredictionHandler Runs];\r\n        G --> H[Slot: Populate Table with Detailed Results];\r\n\r\n        I[User Clicks Start Processing] --> J{Get Output Path from UI LineEdit};\r\n        J --> K[Validate/Create Output Path];\r\n        K -- Path OK --> L[Start ProcessingHandler Thread];\r\n        K -- Path Error --> M[Show Error Message];\r\n        L --> N[ProcessingHandler Runs];\r\n        N --> O[Update UI (Progress, Status)];\r\n\r\n        P[User Clicks Browse...] --> Q[Show QFileDialog];\r\n        Q --> R[Update Output Path LineEdit];\r\n    end\r\n\r\n    subgraph PredictionHandler [Background Thread]\r\n        style PredictionHandler fill:#f9f,stroke:#333,stroke-width:2px\r\n        F --> S{Use ThreadPoolExecutor};\r\n        S --> T[Run _predict_single_asset Concurrently];\r\n        T --> U[Collect Results];\r\n        U --> V[Emit prediction_results_ready (Full List)];\r\n        V --> H;\r\n    end\r\n\r\n    subgraph ProcessingHandler [Background Thread]\r\n         style ProcessingHandler fill:#ccf,stroke:#333,stroke-width:2px\r\n         L --> N;\r\n    end"
        }
    ]
}