Add composite update callback to BOARD_LISTENER

Required for net inspector otherwise composite operations (such
as undo / redo, and length tuning) can result in multiple add /
remove events firing which results in inconsistent length state.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17527
(for 9.0)
This commit is contained in:
JamesJ 2024-03-27 10:26:05 +00:00 committed by Jon Evans
parent ca5ca2858c
commit 951065390e
12 changed files with 85 additions and 24 deletions

View File

@ -2516,6 +2516,15 @@ void BOARD::OnItemsChanged( std::vector<BOARD_ITEM*>& aItems )
}
void BOARD::OnItemsCompositeUpdate( std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aChangedItems )
{
InvokeListeners( &BOARD_LISTENER::OnBoardCompositeUpdate, *this, aAddedItems, aRemovedItems,
aChangedItems );
}
void BOARD::OnRatsnestChanged()
{
InvokeListeners( &BOARD_LISTENER::OnBoardRatsnestChanged, *this );

View File

@ -252,6 +252,11 @@ public:
virtual void OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aBoardItem ) { }
virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) { }
virtual void OnBoardRatsnestChanged( BOARD& aBoard ) { }
virtual void OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems )
{
}
};
/**
@ -1193,6 +1198,14 @@ public:
*/
void OnItemsChanged( std::vector<BOARD_ITEM*>& aItems );
/**
* Notify the board and its listeners that items on the board have
* been modified in a composite operations
*/
void OnItemsCompositeUpdate( std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aChangedItems );
/**
* Notify the board and its listeners that the ratsnest has been recomputed.
*/

View File

@ -483,14 +483,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
} );
}
if( bulkAddedItems.size() > 0 )
board->FinalizeBulkAdd( bulkAddedItems );
if( bulkRemovedItems.size() > 0 )
board->FinalizeBulkRemove( bulkRemovedItems );
if( itemsChanged.size() > 0 )
board->OnItemsChanged( itemsChanged );
if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
if( m_isBoardEditor )
{
@ -717,14 +711,8 @@ void BOARD_COMMIT::Revert()
boardItem->ClearEditFlags();
}
if( bulkAddedItems.size() > 0 )
board->FinalizeBulkAdd( bulkAddedItems );
if( bulkRemovedItems.size() > 0 )
board->FinalizeBulkRemove( bulkRemovedItems );
if( itemsChanged.size() > 0 )
board->OnItemsChanged( itemsChanged );
if( bulkAddedItems.size() > 0 || bulkRemovedItems.size() > 0 || itemsChanged.size() > 0 )
board->OnItemsCompositeUpdate( bulkAddedItems, bulkRemovedItems, itemsChanged );
if( m_isBoardEditor )
{

View File

@ -342,6 +342,15 @@ void DIALOG_GENERATORS::OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_IT
}
void DIALOG_GENERATORS::OnBoardCompositeUpdate( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems )
{
RebuildModels();
}
DIALOG_GENERATORS::DIALOG_GENERATORS( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
DIALOG_GENERATORS_BASE( aParent )
{

View File

@ -71,6 +71,9 @@ private:
virtual void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) override;
virtual void OnBoardItemsChanged( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems ) override;
std::map<wxString, std::vector<std::pair<wxString, wxString>>> m_columnNameTypes;
std::map<wxString, wxDataViewListStore*> m_dataModels;

View File

@ -601,14 +601,8 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
}
}
if( added_items.size() > 0 )
GetBoard()->FinalizeBulkAdd( added_items );
if( deleted_items.size() > 0 )
GetBoard()->FinalizeBulkRemove( deleted_items );
if( changed_items.size() > 0 )
GetBoard()->OnItemsChanged( changed_items );
if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
}

View File

@ -1157,6 +1157,19 @@ void APPEARANCE_CONTROLS::OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_
}
void APPEARANCE_CONTROLS::OnBoardCompositeUpdate( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems )
{
if( doesBoardItemNeedRebuild( aAddedItems ) || doesBoardItemNeedRebuild( aRemovedItems )
|| doesBoardItemNeedRebuild( aDeletedItems ) )
{
handleBoardItemsChanged();
}
}
void APPEARANCE_CONTROLS::handleBoardItemsChanged()
{
Freeze();

View File

@ -210,6 +210,9 @@ public:
void OnBoardItemsRemoved( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override;
void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aItem ) override;
void OnBoardItemsChanged( BOARD& aBoard, std::vector<BOARD_ITEM*>& aItems ) override;
void OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems ) override;
///< Update the colors on all the widgets from the new chosen color theme.
void OnColorThemeChanged();

View File

@ -1097,6 +1097,19 @@ void PCB_NET_INSPECTOR_PANEL::OnBoardItemsChanged( BOARD& aBo
}
void PCB_NET_INSPECTOR_PANEL::OnBoardCompositeUpdate( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems )
{
if( !IsShownOnScreen() )
return;
buildNetsList();
m_netsList->Refresh();
}
void PCB_NET_INSPECTOR_PANEL::OnBoardHighlightNetChanged( BOARD& aBoard )
{
if( m_highlighting_nets || !IsShownOnScreen() )

View File

@ -82,6 +82,9 @@ public:
virtual void OnBoardItemsChanged( BOARD& aBoard,
std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) override;
virtual void OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems ) override;
/**
* Prepare the panel when shown in the editor

View File

@ -153,3 +153,13 @@ void PCB_SEARCH_PANE::OnBoardRatsnestChanged( BOARD& aBoard )
RefreshSearch();
}
void PCB_SEARCH_PANE::OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems )
{
if( !IsShownOnScreen() )
return;
RefreshSearch();
}

View File

@ -42,6 +42,9 @@ public:
std::vector<BOARD_ITEM*>& aBoardItems ) override;
virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) override;
virtual void OnBoardRatsnestChanged( BOARD& aBoard ) override;
virtual void OnBoardCompositeUpdate( BOARD& aBoard, std::vector<BOARD_ITEM*>& aAddedItems,
std::vector<BOARD_ITEM*>& aRemovedItems,
std::vector<BOARD_ITEM*>& aDeletedItems ) override;
private:
void onUnitsChanged( wxCommandEvent& event );