From 00bb52bcd7d99b89dd016078795c1f8682166e19 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 3 Jun 2026 21:36:03 +0800 Subject: [PATCH] fix(automation): select_tab_by_name resolves prepare/preview by page window (viewer-mode safe) --- src/slic3r/GUI/MainFrame.cpp | 26 +++++++++++++++----------- src/slic3r/GUI/MainFrame.hpp | 5 +++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 024a215b28..c6e2fce061 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -3885,15 +3885,17 @@ void MainFrame::select_tab(wxPanel* panel) int MainFrame::select_tab_by_name(const std::string& name) { - // Prepare/Preview share m_plater and sit at fixed indices (always before any - // conditionally-present tab), so select them by index. Every other view selects - // by its page window via FindPage, which stays correct even when optional tabs - // (e.g. Multi-device) shift the raw indices. - if (name == "prepare") { select_tab(size_t(tp3DEditor)); return m_tabpanel->GetSelection(); } - if (name == "preview") { select_tab(size_t(tpPreview)); return m_tabpanel->GetSelection(); } - - wxWindow* page = nullptr; - if (name == "home") page = m_webview; + // Resolve every view by its page window via FindPage, so the mapping stays + // correct when optional tabs (e.g. Multi-device) shift raw indices, and + // self-disables (returns -1) in layouts where a page is absent (e.g. + // GCodeViewer mode has no plater page). Prepare and Preview share m_plater: + // it is inserted as two adjacent pages, so Prepare is FindPage(m_plater) and + // Preview is the next index. + wxWindow* page = nullptr; + int offset = 0; + if (name == "prepare") { page = m_plater; offset = 0; } + else if (name == "preview") { page = m_plater; offset = 1; } + else if (name == "home") page = m_webview; else if (name == "device") page = m_monitor; else if (name == "multi_device") page = m_multi_machine; else if (name == "project") page = m_project; @@ -3901,8 +3903,10 @@ int MainFrame::select_tab_by_name(const std::string& name) else return -1; // unknown view name if (page == nullptr) return -1; // view not available in this layout - const int idx = m_tabpanel->FindPage(page); - if (idx == wxNOT_FOUND) return -1; + const int found = m_tabpanel->FindPage(page); + if (found == wxNOT_FOUND) return -1; + const int idx = found + offset; + if (idx < 0 || idx >= (int)m_tabpanel->GetPageCount()) return -1; select_tab(size_t(idx)); return m_tabpanel->GetSelection(); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index fca7efbbe4..478058c4e8 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -331,8 +331,9 @@ public: // "preview", "device", "multi_device", "project", "calibration"). Returns the // resulting notebook page index, or -1 if that view is unavailable in the // current layout. Robust to conditionally-present tabs (e.g. Multi-device) that - // shift raw indices: Prepare/Preview select by fixed index (they share m_plater - // at 1/2), every other view selects by its page window via FindPage. + // shift raw indices: every view selects by its page window via FindPage. + // Prepare/Preview share m_plater (inserted as two adjacent pages), so Prepare + // is FindPage(m_plater) and Preview is the next index. int select_tab_by_name(const std::string& name); void request_select_tab(TabPosition pos); int get_calibration_curr_tab();