diff --git a/src/app_controller.py b/src/app_controller.py index b987874..1b1456b 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -639,6 +639,7 @@ class AppController: '_refresh_from_project': self._refresh_from_project, 'save_workspace_profile': self._cb_save_workspace_profile, 'load_workspace_profile': self._cb_load_workspace_profile, + 'delete_workspace_profile': self._cb_delete_workspace_profile, } def _update_gcli_adapter(self, path: str) -> None: @@ -2261,6 +2262,13 @@ class AppController: profile = self._app._capture_workspace_profile(name) self.workspace_manager.save_profile(profile, scope=scope) self.workspace_profiles = self.workspace_manager.load_all_profiles() + self._app.workspace_profiles = self.workspace_profiles + + def _cb_delete_workspace_profile(self, name: str, scope: str = 'project') -> None: + self.workspace_manager.delete_profile(name, scope=scope) + self.workspace_profiles = self.workspace_manager.load_all_profiles() + if hasattr(self, '_app') and self._app: + self._app.workspace_profiles = self.workspace_profiles def _cb_load_workspace_profile(self, name: str) -> None: if name in self.workspace_profiles: diff --git a/src/gui_2.py b/src/gui_2.py index 2a2674a..9253845 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -238,6 +238,9 @@ class App: self.layout_presets = self.config.get("layout_presets", {}) self._new_preset_name = "" self._show_save_preset_modal = False + self._show_save_workspace_profile_modal = False + self._new_workspace_profile_name = "" + self._new_workspace_profile_scope = "project" self._comms_log_cache: list[dict[str, Any]] = [] self._tool_log_cache: list[dict[str, Any]] = [] self._last_ui_focus_agent: Optional[str] = None @@ -610,6 +613,21 @@ class App: except Exception as e: self.ai_status = f"error: {e}" imgui.end_menu() + if imgui.begin_menu("Layout"): + if imgui.menu_item("Save Current...", "", False)[0]: + self._show_save_workspace_profile_modal = True + self._new_workspace_profile_name = "" + imgui.separator() + for profile_id, profile in self.workspace_profiles.items(): + if imgui.menu_item(profile.name, "", False)[0]: + self.controller._cb_load_workspace_profile(profile_id) + imgui.separator() + if imgui.begin_menu("Delete Profile"): + for profile_id, profile in self.workspace_profiles.items(): + if imgui.menu_item(profile.name, "", False)[0]: + self.controller._cb_delete_workspace_profile(profile_id, self._new_workspace_profile_scope) + imgui.end_menu() + imgui.end_menu() # RAG status indicator if self.controller.rag_config and self.controller.rag_config.enabled: @@ -768,6 +786,7 @@ class App: self._render_patch_modal() self._render_base_prompt_diff_modal() self._render_save_preset_modal() + self._render_save_workspace_profile_modal() self._render_preset_manager_window() self._render_tool_preset_manager_window() self._render_persona_editor_window() @@ -1417,6 +1436,35 @@ class App: imgui.close_current_popup() imgui.end_popup() + def _render_save_workspace_profile_modal(self) -> None: + if self._show_save_workspace_profile_modal: + imgui.open_popup("Save Workspace Profile") + + if imgui.begin_popup_modal("Save Workspace Profile", True, imgui.WindowFlags_.always_auto_resize)[0]: + imgui.text("Name:") + _, self._new_workspace_profile_name = imgui.input_text("##profile_name", self._new_workspace_profile_name) + + imgui.text("Scope:") + if imgui.radio_button("Project", self._new_workspace_profile_scope == "project"): + self._new_workspace_profile_scope = "project" + imgui.same_line() + if imgui.radio_button("Global", self._new_workspace_profile_scope == "global"): + self._new_workspace_profile_scope = "global" + + imgui.separator() + if imgui.button("Save", (120, 0)): + if self._new_workspace_profile_name.strip(): + self.controller._cb_save_workspace_profile(self._new_workspace_profile_name, self._new_workspace_profile_scope) + self._show_save_workspace_profile_modal = False + imgui.close_current_popup() + + imgui.same_line() + if imgui.button("Cancel", (120, 0)): + self._show_save_workspace_profile_modal = False + imgui.close_current_popup() + + imgui.end_popup() + def _render_preset_manager_content(self, is_embedded: bool = False) -> None: avail = imgui.get_content_region_avail() if not hasattr(self, "_prompt_md_preview"): self._prompt_md_preview = False