Fix potential stale pointer bug in schematic highlight connection code.
SCH_CONNECTION objects are temporary and can become stale any time the connectivity is updated. Keeping them around to reference later is a bad idea. Even if the object pointer is still valid in an SCH_ITEM in the undo/redo buffers, comparing the pointer against another pointer as a test to see if they are the same connection is not valid. Saving the connection name is safe and ensures the connection is the same even if the pointers differ.
This commit is contained in:
parent
be59e7d67f
commit
831a6d55fc
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -231,9 +231,9 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
|
|||
wxString netName = FROM_UTF8( text );
|
||||
|
||||
if( auto sg = Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
|
||||
m_highlightedConn = sg->GetDriverConnection();
|
||||
m_highlightedConn = sg->GetDriverConnection()->Name();
|
||||
else
|
||||
m_highlightedConn = nullptr;
|
||||
m_highlightedConn = wxEmptyString;
|
||||
|
||||
GetToolManager()->RunAction( EE_ACTIONS::updateNetHighlighting, true );
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -202,9 +202,9 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow()
|
|||
m_netFilter->SetValue( g_netFilter );
|
||||
m_netFilterOpt->SetValue( true );
|
||||
}
|
||||
else if( m_parent->GetHighlightedConnection() )
|
||||
else if( !m_parent->GetHighlightedConnection().IsEmpty() )
|
||||
{
|
||||
m_netFilter->SetValue( m_parent->GetHighlightedConnection()->Name() );
|
||||
m_netFilter->SetValue( m_parent->GetHighlightedConnection() );
|
||||
}
|
||||
else if( m_selection.GetSize() )
|
||||
{
|
||||
|
|
|
@ -121,7 +121,6 @@ wxDEFINE_EVENT( EDA_EVT_SCHEMATIC_CHANGED, wxCommandEvent );
|
|||
SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), wxDefaultPosition,
|
||||
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
|
||||
m_highlightedConn( nullptr ),
|
||||
m_ercDialog( nullptr ),
|
||||
m_diffSymbolDialog( nullptr )
|
||||
{
|
||||
|
@ -1693,18 +1692,11 @@ void SCH_EDIT_FRAME::initScreenZoom()
|
|||
|
||||
void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
||||
{
|
||||
const SCH_CONNECTION* highlight = GetHighlightedConnection();
|
||||
SCH_ITEM* highlightedItem = nullptr;
|
||||
SCH_SHEET_PATH highlightPath;
|
||||
|
||||
if( highlight )
|
||||
{
|
||||
highlightPath = highlight->LocalSheet();
|
||||
highlightedItem = dynamic_cast<SCH_ITEM*>( GetItem( highlight->Parent()->m_Uuid ) );
|
||||
}
|
||||
|
||||
bool highlightedConnChanged = false;
|
||||
wxString highlightedConn = GetHighlightedConnection();
|
||||
SCHEMATIC_SETTINGS& settings = Schematic().Settings();
|
||||
SCH_SHEET_LIST list = Schematic().GetSheets();
|
||||
|
||||
#ifdef PROFILE
|
||||
PROF_TIMER timer;
|
||||
#endif
|
||||
|
@ -1732,6 +1724,11 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
|||
[&]( SCH_ITEM* aChangedItem ) -> void
|
||||
{
|
||||
GetCanvas()->GetView()->Update( aChangedItem, KIGFX::REPAINT );
|
||||
|
||||
SCH_CONNECTION* connection = aChangedItem->Connection();
|
||||
|
||||
if( connection && ( connection->Name() == highlightedConn ) )
|
||||
highlightedConnChanged = true;
|
||||
};
|
||||
|
||||
if( !ADVANCED_CFG::GetCfg().m_IncrementalConnectivity || aCleanupFlags == GLOBAL_CLEANUP
|
||||
|
@ -1858,8 +1855,13 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
|
|||
return flags;
|
||||
} );
|
||||
|
||||
if( highlightedItem )
|
||||
SetHighlightedConnection( highlightedItem->Connection( &highlightPath ) );
|
||||
if( !highlightedConn.IsEmpty() )
|
||||
{
|
||||
if( highlightedConnChanged )
|
||||
wxLogDebug( wxS( "Highlighted connection \"%s\" changed." ), highlightedConn );
|
||||
else if( !Schematic().ConnectionGraph()->FindFirstSubgraphByName( highlightedConn ) )
|
||||
wxLogDebug( wxS( "Highlighted connection \"%s\" no longer exists." ), highlightedConn );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1967,10 +1969,10 @@ void SCH_EDIT_FRAME::ShowChangedLanguage()
|
|||
|
||||
void SCH_EDIT_FRAME::UpdateNetHighlightStatus()
|
||||
{
|
||||
if( const SCH_CONNECTION* conn = GetHighlightedConnection() )
|
||||
if( !GetHighlightedConnection().IsEmpty() )
|
||||
{
|
||||
SetStatusText( wxString::Format( _( "Highlighted net: %s" ),
|
||||
UnescapeString( conn->Name() ) ) );
|
||||
UnescapeString( GetHighlightedConnection() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -304,12 +304,12 @@ public:
|
|||
*/
|
||||
void SendCrossProbeClearHighlight();
|
||||
|
||||
const SCH_CONNECTION* GetHighlightedConnection() const
|
||||
const wxString& GetHighlightedConnection() const
|
||||
{
|
||||
return m_highlightedConn;
|
||||
}
|
||||
|
||||
void SetHighlightedConnection( const SCH_CONNECTION* aConnection )
|
||||
void SetHighlightedConnection( const wxString& aConnection )
|
||||
{
|
||||
m_highlightedConn = aConnection;
|
||||
}
|
||||
|
@ -960,7 +960,7 @@ private:
|
|||
friend class SCH_FIND_REPLACE_TOOL;
|
||||
|
||||
SCHEMATIC* m_schematic; ///< The currently loaded schematic
|
||||
const SCH_CONNECTION* m_highlightedConn; ///< The highlighted net or bus, or nullptr
|
||||
wxString m_highlightedConn; ///< The highlighted net or bus or empty string.
|
||||
|
||||
wxPageSetupDialogData m_pageSetupData;
|
||||
std::vector<std::unique_ptr<SCH_ITEM>> m_items_to_repeat; ///< For the repeat-last-item cmd
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 CERN
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -221,7 +221,7 @@ bool EE_SELECTION_TOOL::Init()
|
|||
{
|
||||
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
|
||||
|
||||
return editFrame && editFrame->GetHighlightedConnection() != nullptr;
|
||||
return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
|
||||
};
|
||||
|
||||
auto haveSymbol =
|
||||
|
|
|
@ -169,7 +169,7 @@ bool SCH_EDIT_TOOL::Init()
|
|||
{
|
||||
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
|
||||
|
||||
return editFrame && editFrame->GetHighlightedConnection() != nullptr;
|
||||
return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
|
||||
};
|
||||
|
||||
auto anyTextTool =
|
||||
|
|
|
@ -622,9 +622,11 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
|||
selectionTool->BrightenItem( m_pickerItem );
|
||||
}
|
||||
|
||||
if( m_frame->GetHighlightedConnection() != conn )
|
||||
wxString connectionName = ( conn ) ? conn->Name() : wxS( "" );
|
||||
|
||||
if( m_frame->GetHighlightedConnection() != connectionName )
|
||||
{
|
||||
m_frame->SetHighlightedConnection( conn );
|
||||
m_frame->SetHighlightedConnection( connectionName );
|
||||
|
||||
TOOL_EVENT dummyEvent;
|
||||
UpdateNetHighlighting( dummyEvent );
|
||||
|
@ -637,9 +639,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
|||
if( m_pickerItem )
|
||||
m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
|
||||
|
||||
if( m_frame->GetHighlightedConnection() )
|
||||
if( !m_frame->GetHighlightedConnection().IsEmpty() )
|
||||
{
|
||||
m_frame->SetHighlightedConnection( nullptr );
|
||||
m_frame->SetHighlightedConnection( wxEmptyString );
|
||||
|
||||
TOOL_EVENT dummyEvent;
|
||||
UpdateNetHighlighting( dummyEvent );
|
||||
|
@ -796,16 +798,18 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
|||
}
|
||||
}
|
||||
|
||||
if( !conn || conn == editFrame->GetHighlightedConnection() )
|
||||
wxString connectionName = ( conn ) ? conn->Name() : wxS( "" );
|
||||
|
||||
if( !conn || connectionName == editFrame->GetHighlightedConnection() )
|
||||
{
|
||||
editFrame->SetStatusText( wxT( "" ) );
|
||||
editFrame->SendCrossProbeClearHighlight();
|
||||
editFrame->SetHighlightedConnection( nullptr );
|
||||
editFrame->SetHighlightedConnection( wxEmptyString );
|
||||
}
|
||||
else
|
||||
{
|
||||
editFrame->SetCrossProbeConnection( conn );
|
||||
editFrame->SetHighlightedConnection( conn );
|
||||
editFrame->SetHighlightedConnection( connectionName );
|
||||
}
|
||||
|
||||
editFrame->UpdateNetHighlightStatus();
|
||||
|
@ -1005,29 +1009,21 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
|
|||
SCH_SCREEN* screen = m_frame->GetCurrentSheet().LastScreen();
|
||||
CONNECTION_GRAPH* connectionGraph = m_frame->Schematic().ConnectionGraph();
|
||||
std::vector<EDA_ITEM*> itemsToRedraw;
|
||||
const SCH_CONNECTION* selectedConn = m_frame->GetHighlightedConnection();
|
||||
|
||||
if( !screen )
|
||||
return 0;
|
||||
wxCHECK( screen && connectionGraph, 0 );
|
||||
|
||||
bool selectedIsBus = selectedConn ? selectedConn->IsBus() : false;
|
||||
wxString selectedName = selectedConn ? selectedConn->Name() : wxString( wxS( "" ) );
|
||||
bool selectedIsBus = false;
|
||||
wxString selectedName = m_frame->GetHighlightedConnection();
|
||||
|
||||
bool selectedIsNoNet = false;
|
||||
CONNECTION_SUBGRAPH* selectedSubgraph = nullptr;
|
||||
|
||||
if( selectedConn && selectedConn->Driver() == nullptr )
|
||||
{
|
||||
selectedIsNoNet = true;
|
||||
selectedSubgraph = connectionGraph->GetSubgraphForItem( selectedConn->Parent() );
|
||||
}
|
||||
|
||||
for( SCH_ITEM* item : screen->Items() )
|
||||
{
|
||||
bool redraw = item->IsBrightened();
|
||||
bool highlight = false;
|
||||
|
||||
if( selectedConn )
|
||||
if( !selectedName.IsEmpty() )
|
||||
{
|
||||
SCH_CONNECTION* itemConn = nullptr;
|
||||
SCH_SYMBOL* symbol = nullptr;
|
||||
|
@ -1040,42 +1036,55 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
|
|||
else
|
||||
itemConn = item->Connection();
|
||||
|
||||
if( selectedIsNoNet && selectedSubgraph )
|
||||
if( itemConn && ( selectedName == itemConn->Name() ) )
|
||||
{
|
||||
for( SCH_ITEM* subgraphItem : selectedSubgraph->GetItems() )
|
||||
selectedIsBus = itemConn->IsBus();
|
||||
|
||||
if( itemConn->Driver() == nullptr )
|
||||
{
|
||||
if( item == subgraphItem )
|
||||
selectedIsNoNet = true;
|
||||
selectedSubgraph = connectionGraph->GetSubgraphForItem( itemConn->Parent() );
|
||||
}
|
||||
|
||||
if( selectedIsNoNet && selectedSubgraph )
|
||||
{
|
||||
for( SCH_ITEM* subgraphItem : selectedSubgraph->GetItems() )
|
||||
{
|
||||
highlight = true;
|
||||
break;
|
||||
if( item == subgraphItem )
|
||||
{
|
||||
highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( selectedIsBus && itemConn && itemConn->IsNet() )
|
||||
{
|
||||
for( const std::shared_ptr<SCH_CONNECTION>& member : selectedConn->Members() )
|
||||
else if( selectedIsBus && itemConn && itemConn->IsNet() )
|
||||
{
|
||||
if( member->Name() == itemConn->Name() )
|
||||
for( const std::shared_ptr<SCH_CONNECTION>& member : itemConn->Members() )
|
||||
{
|
||||
highlight = true;
|
||||
break;
|
||||
}
|
||||
else if( member->IsBus() )
|
||||
{
|
||||
for( const std::shared_ptr<SCH_CONNECTION>& bus_member : member->Members() )
|
||||
if( member->Name() == itemConn->Name() )
|
||||
{
|
||||
if( bus_member->Name() == itemConn->Name() )
|
||||
highlight = true;
|
||||
break;
|
||||
}
|
||||
else if( member->IsBus() )
|
||||
{
|
||||
for( const std::shared_ptr<SCH_CONNECTION>& bus_member :
|
||||
member->Members() )
|
||||
{
|
||||
highlight = true;
|
||||
break;
|
||||
if( bus_member->Name() == itemConn->Name() )
|
||||
{
|
||||
highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( selectedConn && itemConn && selectedName == itemConn->Name() )
|
||||
{
|
||||
highlight = true;
|
||||
else if( !selectedName.IsEmpty() && itemConn
|
||||
&& ( selectedName == itemConn->Name() ) )
|
||||
{
|
||||
highlight = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 CERN
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -206,7 +206,7 @@ bool SCH_LINE_WIRE_BUS_TOOL::Init()
|
|||
{
|
||||
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
|
||||
|
||||
return editFrame && editFrame->GetHighlightedConnection() != nullptr;
|
||||
return editFrame && !editFrame->GetHighlightedConnection().IsEmpty();
|
||||
};
|
||||
|
||||
auto& ctxMenu = m_menu.GetMenu();
|
||||
|
|
Loading…
Reference in New Issue