18 lines
7.8 KiB
JSON
18 lines
7.8 KiB
JSON
{
|
|
"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"
|
|
}
|
|
]
|
|
} |