diff --git a/include/eda_item_flags.h b/include/eda_item_flags.h index 8b71d4ad00..9898d96316 100644 --- a/include/eda_item_flags.h +++ b/include/eda_item_flags.h @@ -29,8 +29,7 @@ #include -// These define are used for the .m_flags and .m_UndoRedoStatus member of the -// class EDA_ITEM +// These define are used for the .m_flags member of the class EDA_ITEM // // NB: DO NOT ADD FLAGS ANYWHERE BUT AT THE END: THE FLAG-SET IS STORED AS AN INTEGER IN FILES. // @@ -65,8 +64,8 @@ #define SHOW_ELEC_TYPE (1 << 25) ///< Show pin electrical type. Shared with IS_ROLLOVER. #define BRIGHTENED (1 << 26) ///< item is drawn with a bright contour -#define DP_COUPLED (1 << 27) ///< item is coupled with another item making a differential pair - ///< (applies to segments only) +#define IS_MODIFIED_CHILD (1 << 27)///< when a child is promoted to its parent for a COMMIT, this + ///< flag indicates the modified child #define UR_TRANSIENT (1 << 28) ///< indicates the item is owned by the undo/redo stack #define IS_DANGLING (1 << 29) ///< indicates a pin is dangling diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index 15136c7e76..9261417820 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -79,14 +79,26 @@ BOARD* BOARD_COMMIT::GetBoard() const COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ) { - // if aItem belongs a footprint, the full footprint will be saved - // because undo/redo does not handle "sub items" modifications - if( aItem && aItem->Type() != PCB_FOOTPRINT_T && aChangeType == CHT_MODIFY ) - { - EDA_ITEM* item = aItem->GetParent(); + aItem->ClearFlags( IS_MODIFIED_CHILD ); - if( item && item->Type() == PCB_FOOTPRINT_T ) // means aItem belongs a footprint - aItem = item; + // If aItem belongs a footprint, the full footprint will be saved because undo/redo does + // not handle "sub items" modifications. This has implications for auto-zone-refill, so + // we need to store a bit more information. + if( aItem && aChangeType == CHT_MODIFY ) + { + if( aItem->Type() == PCB_FOOTPRINT_T ) + { + static_cast( aItem )->RunOnChildren( + [&]( BOARD_ITEM* child ) + { + child->SetFlags( IS_MODIFIED_CHILD ); + } ); + } + else if( FOOTPRINT* fp = dynamic_cast( aItem->GetParent() ) ) + { + aItem->SetFlags( IS_MODIFIED_CHILD ); + aItem = fp; + } } return COMMIT::Stage( aItem, aChangeType ); @@ -105,7 +117,7 @@ COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag } -void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item ) +void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType ) { wxCHECK( item, /* void */ ); @@ -119,7 +131,8 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item ) static_cast( item )->RunOnChildren( [&]( BOARD_ITEM* child ) { - dirtyIntersectingZones( child ); + if( aChangeType != CHT_MODIFY || ( child->GetFlags() & IS_MODIFIED_CHILD ) ) + dirtyIntersectingZones( child, aChangeType ); } ); } else if( item->Type() == PCB_GROUP_T ) @@ -127,7 +140,7 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item ) static_cast( item )->RunOnChildren( [&]( BOARD_ITEM* child ) { - dirtyIntersectingZones( child ); + dirtyIntersectingZones( child, aChangeType ); } ); } else @@ -295,7 +308,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) } if( autofillZones && boardItem->Type() != PCB_MARKER_T ) - dirtyIntersectingZones( boardItem ); + dirtyIntersectingZones( boardItem, changeType ); if( view && boardItem->Type() != PCB_NETINFO_T ) view->Add( boardItem ); @@ -322,7 +335,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) parentGroup->RemoveItem( boardItem ); if( autofillZones ) - dirtyIntersectingZones( boardItem ); + dirtyIntersectingZones( boardItem, changeType ); switch( boardItem->Type() ) { @@ -462,8 +475,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) if( autofillZones ) { - dirtyIntersectingZones( static_cast( ent.m_copy )); // before - dirtyIntersectingZones( boardItem ); // after + dirtyIntersectingZones( static_cast( ent.m_copy ), changeType ); // before + dirtyIntersectingZones( boardItem, changeType ); // after } if( view ) diff --git a/pcbnew/board_commit.h b/pcbnew/board_commit.h index 355b462e96..0a09e36daa 100644 --- a/pcbnew/board_commit.h +++ b/pcbnew/board_commit.h @@ -77,7 +77,7 @@ private: EDA_ITEM* makeImage( EDA_ITEM* aItem ) const override; - void dirtyIntersectingZones( BOARD_ITEM* item ); + void dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType ); private: TOOL_MANAGER* m_toolMgr;