From dc4f639c61e1790677912a666cea324047212bfd Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 14 Jul 2025 22:46:35 +0100 Subject: [PATCH] Make sure selected item is still valid before activating (KICAD-18S). --- kicad/project_tree.cpp | 14 ++++++++++++++ kicad/project_tree.h | 2 ++ kicad/project_tree_pane.cpp | 30 ++++++++++++++++++++---------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/kicad/project_tree.cpp b/kicad/project_tree.cpp index 8c5832a6b7..d53918a045 100644 --- a/kicad/project_tree.cpp +++ b/kicad/project_tree.cpp @@ -208,6 +208,20 @@ void PROJECT_TREE::LoadIcons() } +void PROJECT_TREE::GetItemsRecursively( const wxTreeItemId& aParentId, std::vector& aItems ) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child = GetFirstChild( aParentId, cookie ); + + while( child.IsOk() ) + { + aItems.push_back( child ); + GetItemsRecursively( child, aItems ); + child = GetNextChild( aParentId, cookie ); + } +} + + int PROJECT_TREE::OnCompareItems( const wxTreeItemId& item1, const wxTreeItemId& item2 ) { PROJECT_TREE_ITEM* myitem1 = (PROJECT_TREE_ITEM*) GetItemData( item1 ); diff --git a/kicad/project_tree.h b/kicad/project_tree.h index f9174b3d78..dc0d469894 100644 --- a/kicad/project_tree.h +++ b/kicad/project_tree.h @@ -57,6 +57,8 @@ public: void LoadIcons(); + void GetItemsRecursively( const wxTreeItemId& aParentId, std::vector& aItems ); + void SetGitRepo( git_repository* aRepo ) { m_gitCommon->SetRepo( aRepo ); } git_repository* GetGitRepo() const { return m_gitCommon->GetRepo(); } diff --git a/kicad/project_tree_pane.cpp b/kicad/project_tree_pane.cpp index 93d393c2dd..8dd0d7e615 100644 --- a/kicad/project_tree_pane.cpp +++ b/kicad/project_tree_pane.cpp @@ -1177,12 +1177,23 @@ void PROJECT_TREE_PANE::onIdle( wxIdleEvent& aEvent ) if( m_selectedItem != nullptr ) { - // Activate launches a window which may run the event loop on top of us and cause OnIdle - // to get called again, so be sure to block off the activation condition first. - PROJECT_TREE_ITEM* item = m_selectedItem; - m_selectedItem = nullptr; + // Make sure m_selectedItem still exists in the tree before activating it. + std::vector validItemIds; + m_TreeProject->GetItemsRecursively( m_TreeProject->GetRootItem(), validItemIds ); - item->Activate( this ); + for( wxTreeItemId id : validItemIds ) + { + if( GetItemIdData( id ) == m_selectedItem ) + { + // Activate launches a window which may run the event loop on top of us and cause + // onIdle to get called again, so be sure to null out m_selectedItem first. + PROJECT_TREE_ITEM* item = m_selectedItem; + m_selectedItem = nullptr; + + item->Activate( this ); + break; + } + } } } @@ -1254,19 +1265,18 @@ void PROJECT_TREE_PANE::onExpand( wxTreeEvent& Event ) std::vector PROJECT_TREE_PANE::GetSelectedData() { - wxArrayTreeItemIds selection; + wxArrayTreeItemIds selection; std::vector data; m_TreeProject->GetSelections( selection ); - for( auto it = selection.begin(); it != selection.end(); it++ ) + for( const wxTreeItemId itemId : selection ) { - PROJECT_TREE_ITEM* item = GetItemIdData( *it ); + PROJECT_TREE_ITEM* item = GetItemIdData( itemId ); if( !item ) { - wxLogTrace( traceGit, wxS( "Null tree item returned for selection, dynamic_cast " - "failed?" ) ); + wxLogTrace( traceGit, wxS( "Null tree item returned for selection, dynamic_cast failed?" ) ); continue; }