Eeschema: fix segfault when updating selected pins via pin table

This commit is contained in:
John Beard
2025-05-04 20:34:48 +08:00
parent d691a257b2
commit ec7129212c
3 changed files with 42 additions and 26 deletions
+16 -23
View File
@@ -353,8 +353,10 @@ void getSelectedArea( WX_GRID* aGrid, int* aRowStart, int* aRowCount )
class PIN_TABLE_DATA_MODEL : public wxGridTableBase
{
public:
PIN_TABLE_DATA_MODEL( SYMBOL_EDIT_FRAME* aFrame, DIALOG_LIB_EDIT_PIN_TABLE* aPinTable,
LIB_SYMBOL* aSymbol, SCH_SELECTION_TOOL& aSelectionTool ) :
PIN_TABLE_DATA_MODEL( SYMBOL_EDIT_FRAME* aFrame,
DIALOG_LIB_EDIT_PIN_TABLE* aPinTable,
LIB_SYMBOL* aSymbol,
const std::vector<SCH_PIN*>& aOrigSelectedPins ) :
m_frame( aFrame ),
m_unitFilter( -1 ),
m_bodyStyleFilter( -1 ),
@@ -362,7 +364,7 @@ public:
m_edited( false ),
m_pinTable( aPinTable ),
m_symbol( aSymbol ),
m_selectionTool( aSelectionTool )
m_origSelectedPins( aOrigSelectedPins )
{
m_eval = std::make_unique<NUMERIC_EVALUATOR>( m_frame->GetUserUnits() );
@@ -672,32 +674,22 @@ public:
if( groupBySelection )
m_rows.emplace_back( std::vector<SCH_PIN*>() );
std::set<SCH_PIN*> selectedPins;
std::set<wxString> selectedNumbers;
if( m_filterBySelection )
for( SCH_PIN* pin : m_origSelectedPins )
{
SCH_SELECTION& selection = m_selectionTool.GetSelection();
for( EDA_ITEM* item : selection )
{
if( item->Type() == SCH_PIN_T )
{
SCH_PIN* pinItem = static_cast<SCH_PIN*>( item );
selectedPins.insert( pinItem );
selectedNumbers.insert( pinItem->GetNumber() );
}
}
selectedNumbers.insert( pin->GetNumber() );
}
const auto pinIsInEditorSelection = [&]( SCH_PIN* pin )
{
// Quick check before we iterate the whole thing
// Quick check before we iterate the whole thing in N^2 time.
// (3000^2 = FPGAs causing issues down the road).
if( selectedNumbers.count( pin->GetNumber() ) == 0 )
{
return false;
}
for( SCH_PIN* selectedPin : selectedPins )
for( SCH_PIN* selectedPin : m_origSelectedPins )
{
// The selected pin is in the editor, but the pins in the table
// are copies. We will mark the pin as selected if it's a match
@@ -844,7 +836,9 @@ private:
DIALOG_LIB_EDIT_PIN_TABLE* m_pinTable;
LIB_SYMBOL* m_symbol; // Parent symbol that the pins belong to.
SCH_SELECTION_TOOL& m_selectionTool; // Selection tool for the selection filter
/// The pins in the symbol that are selected at dialog start
const std::vector<SCH_PIN*>& m_origSelectedPins;
std::unique_ptr<NUMERIC_EVALUATOR> m_eval;
std::map< std::pair<std::vector<SCH_PIN*>, int>, wxString > m_evalOriginal;
};
@@ -1030,14 +1024,13 @@ private:
DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
LIB_SYMBOL* aSymbol ) :
LIB_SYMBOL* aSymbol,
const std::vector<SCH_PIN*>& aSelectedPins ) :
DIALOG_LIB_EDIT_PIN_TABLE_BASE( parent ),
m_editFrame( parent ),
m_symbol( aSymbol )
{
SCH_SELECTION_TOOL* selTool = parent->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
m_dataModel = new PIN_TABLE_DATA_MODEL( m_editFrame, this, this->m_symbol, *selTool );
m_dataModel = new PIN_TABLE_DATA_MODEL( m_editFrame, this, this->m_symbol, aSelectedPins );
// Save original columns widths so we can do proportional sizing.
for( int i = 0; i < COL_COUNT; ++i )
+5 -2
View File
@@ -54,7 +54,8 @@ class SYMBOL_EDIT_FRAME;
class DIALOG_LIB_EDIT_PIN_TABLE : public DIALOG_LIB_EDIT_PIN_TABLE_BASE
{
public:
DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent, LIB_SYMBOL* aSymbol );
DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent, LIB_SYMBOL* aSymbol,
const std::vector<SCH_PIN*>& aSelectedPins );
~DIALOG_LIB_EDIT_PIN_TABLE() override;
bool TransferDataToWindow() override;
@@ -89,9 +90,11 @@ protected:
int m_originalColWidths[ COL_COUNT ];
std::bitset<64> m_columnsShown;
LIB_SYMBOL* m_symbol;
std::vector<SCH_PIN*> m_pins; // a copy of the pins owned by me
std::vector<SCH_PIN*> m_pins; // a copy of the pins owned by the dialog
bool m_modified; ///< true when there are unsaved changes
wxSize m_size;
PIN_TABLE_DATA_MODEL* m_dataModel;
std::unique_ptr<ACTION_MENU> m_menu;
};
+21 -1
View File
@@ -772,7 +772,27 @@ int SYMBOL_EDITOR_EDIT_TOOL::PinTable( const TOOL_EVENT& aEvent )
commit.Modify( symbol );
DIALOG_LIB_EDIT_PIN_TABLE dlg( m_frame, symbol );
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
wxCHECK( selTool, -1 );
std::vector<SCH_PIN*> selectedPins;
SCH_SELECTION& selection = selTool->GetSelection();
for( EDA_ITEM* item : selection )
{
if( item->Type() == SCH_PIN_T )
{
SCH_PIN* pinItem = static_cast<SCH_PIN*>( item );
selectedPins.push_back( pinItem );
}
}
// And now clear the selection so if we change the pins we don't have dangling pointers
// in the selection.
m_toolMgr->RunAction( ACTIONS::selectionClear );
DIALOG_LIB_EDIT_PIN_TABLE dlg( m_frame, symbol, selectedPins );
if( dlg.ShowModal() == wxID_CANCEL )
return -1;