diff --git a/include/class_board_item.h b/include/class_board_item.h index 9c2c541251..19cc26b962 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -67,11 +67,6 @@ enum STROKE_T */ class BOARD_ITEM : public EDA_ITEM { - // These are made private here so they may not be used. - // Instead everything derived from BOARD_ITEM is handled via DLIST<>'s - // use of DHEAD's member functions. - void SetNext( EDA_ITEM* aNext ) { Pnext = aNext; } - void SetBack( EDA_ITEM* aBack ) { Pback = aBack; } protected: PCB_LAYER_ID m_Layer; @@ -166,7 +161,7 @@ public: * Pnext and Pback because aItem is not changed in the linked list * @param aImage = the item image which contains data to swap */ - void SwapData( BOARD_ITEM* aImage ); + virtual void SwapData( BOARD_ITEM* aImage ); /** * Function IsOnLayer diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 34d3477f98..38f3ecff34 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -314,6 +314,7 @@ set( PCBNEW_CLASS_SRCS tools/tools_common.cpp tools/tool_event_utils.cpp tools/size_menu.cpp + tools/selection.cpp footprint_preview_panel.cpp ) diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 6cacf21f55..1f5c580581 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -258,3 +258,9 @@ void BOARD_ITEM::DeleteStructure() delete this; } + + +void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) +{ + +} diff --git a/pcbnew/class_dimension.cpp b/pcbnew/class_dimension.cpp index 3724d90b4c..b8a42620e5 100644 --- a/pcbnew/class_dimension.cpp +++ b/pcbnew/class_dimension.cpp @@ -505,3 +505,10 @@ EDA_ITEM* DIMENSION::Clone() const { return new DIMENSION( *this ); } + +void DIMENSION::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_DIMENSION_T ); + + std::swap( *((DIMENSION*) this), *((DIMENSION*) aImage) ); +} diff --git a/pcbnew/class_dimension.h b/pcbnew/class_dimension.h index b799e11435..961104ce6d 100644 --- a/pcbnew/class_dimension.h +++ b/pcbnew/class_dimension.h @@ -227,6 +227,8 @@ public: virtual const BOX2I ViewBBox() const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index 7629469812..fc547ce14a 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -759,3 +759,10 @@ const std::vector DRAWSEGMENT::GetPolyPoints() const return rv; } + +void DRAWSEGMENT::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_LINE_T ); + + std::swap( *((DRAWSEGMENT*) this), *((DRAWSEGMENT*) aImage) ); +} diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 35bb464641..5348cc7ac1 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -240,6 +240,8 @@ public: virtual const BOX2I ViewBBox() const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_mire.cpp b/pcbnew/class_mire.cpp index fc5c5ee6f8..f99252088f 100644 --- a/pcbnew/class_mire.cpp +++ b/pcbnew/class_mire.cpp @@ -206,3 +206,10 @@ EDA_ITEM* PCB_TARGET::Clone() const { return new PCB_TARGET( *this ); } + +void PCB_TARGET::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_TARGET_T ); + + std::swap( *((PCB_TARGET*) this), *((PCB_TARGET*) aImage) ); +} diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index 13b19bcb08..7621d11bfe 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -104,6 +104,8 @@ public: EDA_ITEM* Clone() const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index a3540c8a68..784b6ddf17 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -1304,3 +1304,10 @@ bool MODULE::BuildPolyCourtyard() return success; } + +void MODULE::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_MODULE_T ); + + std::swap( *((MODULE*) this), *((MODULE*) aImage) ); +} diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index e3397bbf3c..f8f74a6fc6 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -674,6 +674,8 @@ public: */ bool BuildPolyCourtyard(); + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 9847fafefc..1ec339a269 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -1392,3 +1392,10 @@ void D_PAD::ImportSettingsFromMaster( const D_PAD& aMasterPad ) SetAnchorPadShape( aMasterPad.GetAnchorPadShape() ); MergePrimitivesAsPolygon(); } + +void D_PAD::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_PAD_T ); + + std::swap( *((MODULE*) this), *((MODULE*) aImage) ); +} diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index ed0ffee6a5..274553f3ba 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -731,6 +731,8 @@ public: */ void CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings ); + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index c0acff6338..0b79dea428 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -206,3 +206,10 @@ EDA_ITEM* TEXTE_PCB::Clone() const { return new TEXTE_PCB( *this ); } + +void TEXTE_PCB::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_TEXT_T ); + + std::swap( *((TEXTE_PCB*) this), *((TEXTE_PCB*) aImage) ); +} diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index ae54a6a0df..8af0d1e977 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -140,6 +140,8 @@ public: EDA_ITEM* Clone() const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined(DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 4984c4ab95..913b33711f 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1608,11 +1608,24 @@ wxString TRACK::GetSelectMenuText() const } -BITMAP_DEF TRACK:: GetMenuImage() const +BITMAP_DEF TRACK::GetMenuImage() const { return showtrack_xpm; } +void TRACK::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_TRACE_T ); + + std::swap( *((TRACK*) this), *((TRACK*) aImage) ); +} + +void VIA::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_VIA_T ); + + std::swap( *((VIA*) this), *((VIA*) aImage) ); +} #if defined(DEBUG) diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 542dba3fa0..c152ab006f 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -302,6 +302,8 @@ public: virtual unsigned int ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + virtual void SwapData( BOARD_ITEM* aImage ) override; + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } @@ -475,6 +477,8 @@ public: */ bool IsDrillDefault() const { return m_Drill <= 0; } + virtual void SwapData( BOARD_ITEM* aImage ) override; + protected: virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) override; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 94c0541300..97a7687d61 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -1305,3 +1305,10 @@ BITMAP_DEF ZONE_CONTAINER::GetMenuImage() const { return add_zone_xpm; } + +void ZONE_CONTAINER::SwapData( BOARD_ITEM* aImage ) +{ + assert( aImage->Type() == PCB_ZONE_AREA_T ); + + std::swap( *((ZONE_CONTAINER*) this), *((ZONE_CONTAINER*) aImage) ); +} diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index a99359c027..0a8e72ed82 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -733,7 +733,7 @@ public: virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif - + virtual void SwapData( BOARD_ITEM* aImage ) override; private: void buildFeatureHoleList( BOARD* aPcb, SHAPE_POLY_SET& aFeatures ); diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index eef6d69e38..2bca3af8ba 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -168,6 +168,33 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem ) return std::binary_search( itemsList.begin(), itemsList.end(), aItem ); } +static void SwapItemData( BOARD_ITEM* aItem, BOARD_ITEM* aImage ) +{ + if( aImage == NULL ) + return; + + wxASSERT( aItem->Type() == aImage->Type() ); + + // Remark: to create images of edited items to undo, we are using Clone method + // which can duplication of items foe copy, but does not clone all members + // mainly pointers in chain and time stamp, which is set to new, unique value. + // So we have to use the current values of these parameters. + + EDA_ITEM* pnext = aItem->Next(); + EDA_ITEM* pback = aItem->Back(); + DHEAD* mylist = aItem->GetList(); + time_t timestamp = aItem->GetTimeStamp(); + EDA_ITEM* parent = aItem->GetParent(); + + aItem->SwapData( aImage ); + + // Restore pointers and time stamp, to be sure they are not broken + aItem->SetNext( pnext ); + aItem->SetBack( pback ); + aItem->SetList( mylist ); + aItem->SetTimeStamp( timestamp ); + aItem->SetParent( parent ); +} void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, const wxPoint& aTransformPoint ) @@ -470,7 +497,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool view->Remove( item ); connectivity->Remove( item ); - item->SwapData( image ); + SwapItemData( item, image ); // Update all pads/drawings/texts, as they become invalid // for the VIEW after SwapData() called for modules @@ -564,71 +591,6 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool } -void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) -{ - if( aImage == NULL ) - return; - - wxASSERT( Type() == aImage->Type() ); - - // Remark: to create images of edited items to undo, we are using Clone method - // which can duplication of items foe copy, but does not clone all members - // mainly pointers in chain and time stamp, which is set to new, unique value. - // So we have to use the current values of these parameters. - - EDA_ITEM* pnext = Next(); - EDA_ITEM* pback = Back(); - DHEAD* mylist = m_List; - time_t timestamp = GetTimeStamp(); - EDA_ITEM* parent = GetParent(); - - switch( Type() ) - { - case PCB_MODULE_T: - std::swap( *((MODULE*) this), *((MODULE*) aImage) ); - break; - - case PCB_ZONE_AREA_T: - std::swap( *((ZONE_CONTAINER*) this), *((ZONE_CONTAINER*) aImage) ); - break; - - case PCB_LINE_T: - std::swap( *((DRAWSEGMENT*) this), *((DRAWSEGMENT*) aImage) ); - break; - - case PCB_TRACE_T: - std::swap( *((TRACK*) this), *((TRACK*) aImage) ); - break; - - case PCB_VIA_T: - std::swap( *((VIA*) this), *((VIA*) aImage) ); - break; - - case PCB_TEXT_T: - std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); - break; - - case PCB_TARGET_T: - std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); - break; - - case PCB_DIMENSION_T: - std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); - break; - - case PCB_ZONE_T: - default: - wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); - break; - } - - // Restore pointers and time stamp, to be sure they are not broken - Pnext = pnext; - Pback = pback; - m_List = mylist; - SetTimeStamp( timestamp ); - SetParent( parent ); -} void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount )