Asset-Frameworker/ProjectNotes/GUI_FEATURE_PLAN.md
2025-04-29 18:26:13 +02:00

7.0 KiB

GUI Feature Enhancement Plan

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.

Detailed Plan:

  1. Feature: Configurable Output Path

    • File: gui/main_window.py
    • Changes:
      • UI Addition:
        • Below the preset_combo layout, add a new QHBoxLayout.
        • Inside this layout, add:
          • A QLabel with text "Output Directory:".
          • A QLineEdit (e.g., self.output_path_edit) to display/edit the path. Make it read-only initially if preferred, or editable.
          • A QPushButton (e.g., self.browse_output_button) with text "Browse...".
      • Initialization (__init__ or setup_main_panel_ui):
        • Read the default OUTPUT_BASE_DIR from core_config.
        • Resolve this path relative to the project root (project_root / output_base_dir_config).
        • Set the initial text of self.output_path_edit to this resolved default path.
      • Browse Button Logic:
        • Connect the clicked signal of self.browse_output_button to a new method (e.g., _browse_for_output_directory).
        • Implement _browse_for_output_directory:
          • Use QFileDialog.getExistingDirectory to let the user select a folder.
          • If a directory is selected, update the text of self.output_path_edit.
      • Processing Logic (start_processing):
        • Instead of reading/resolving the path from core_config, get the path string directly from self.output_path_edit.text().
        • Convert this string to a Path object.
        • 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.
        • Pass the validated output_dir_str to self.processing_handler.run_processing.
  2. Feature: Responsive UI (Address Prediction Bottleneck)

    • File: gui/prediction_handler.py
    • Changes:
      • Import: Add from concurrent.futures import ThreadPoolExecutor, as_completed.
      • Modify run_prediction:
        • 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).
        • Instead of iterating through input_paths sequentially, submit a task to the executor for each input_path_str.
        • 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.
        • _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).
        • Store the Future objects returned by executor.submit.
        • Use as_completed(futures) to process results as they become available.
        • Append the results from each completed future to the all_file_results list.
        • Emit prediction_results_ready once at the very end with the complete all_file_results list.
    • File: gui/main_window.py
    • Changes:
      • No changes needed in the on_prediction_results_ready slot itself, as the handler will still emit the full list at the end.
  3. Feature: Preview Toggle

    • File: gui/main_window.py
    • Changes:
      • UI Addition:
        • 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.
      • Modify update_preview:
        • At the beginning of the method, check self.disable_preview_checkbox.isChecked().
        • If Checked (Simple View):
          • Clear the preview_table.
          • Set simplified table headers (e.g., self.preview_table.setColumnCount(1); self.preview_table.setHorizontalHeaderLabels(["Input Path"])). Adjust column resize modes.
          • Iterate through self.current_asset_paths. For each path, add a row to the table containing just the path string.
          • Set status bar message (e.g., "Preview disabled. Showing input list.").
          • Crucially: return from the method here to prevent the PredictionHandler from being started.
        • If Unchecked (Detailed View):
          • Ensure the table headers and column count are set back to the detailed view configuration (Status, Original Path, Predicted Name, Details).
          • Continue with the rest of the existing update_preview logic to start the PredictionHandler.
      • Connect Signal: In __init__ or setup_main_panel_ui, connect the toggled signal of self.disable_preview_checkbox to the self.update_preview slot.
      • Initial State: Ensure the first call to update_preview (if any) respects the initial unchecked state of the checkbox.

Mermaid Diagram:

graph TD
    subgraph MainWindow
        A[User Action: Add Asset / Change Preset / Toggle Preview] --> B{Update Preview Triggered};
        B --> C{Is 'Disable Preview' Checked?};
        C -- Yes --> D[Show Simple List View in Table];
        C -- No --> E[Set Detailed Table Headers];
        E --> F[Start PredictionHandler Thread];
        F --> G[PredictionHandler Runs];
        G --> H[Slot: Populate Table with Detailed Results];

        I[User Clicks Start Processing] --> J{Get Output Path from UI LineEdit};
        J --> K[Validate/Create Output Path];
        K -- Path OK --> L[Start ProcessingHandler Thread];
        K -- Path Error --> M[Show Error Message];
        L --> N[ProcessingHandler Runs];
        N --> O[Update UI (Progress, Status)];

        P[User Clicks Browse...] --> Q[Show QFileDialog];
        Q --> R[Update Output Path LineEdit];
    end

    subgraph PredictionHandler [Background Thread]
        style PredictionHandler fill:#f9f,stroke:#333,stroke-width:2px
        F --> S{Use ThreadPoolExecutor};
        S --> T[Run _predict_single_asset Concurrently];
        T --> U[Collect Results];
        U --> V[Emit prediction_results_ready (Full List)];
        V --> H;
    end

    subgraph ProcessingHandler [Background Thread]
         style ProcessingHandler fill:#ccf,stroke:#333,stroke-width:2px
         L --> N;
    end