diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 39edecf703..d9fca60ad7 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -76,7 +76,7 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) m_Poly( nullptr ), m_CornerSelection( nullptr ) { - initDataFromSrcInCopyCtor( aZone ); + InitDataFromSrcInCopyCtor( aZone ); } @@ -84,7 +84,7 @@ ZONE_CONTAINER& ZONE_CONTAINER::operator=( const ZONE_CONTAINER& aOther ) { BOARD_CONNECTED_ITEM::operator=( aOther ); - initDataFromSrcInCopyCtor( aOther ); + InitDataFromSrcInCopyCtor( aOther ); return *this; } @@ -97,10 +97,10 @@ ZONE_CONTAINER::~ZONE_CONTAINER() } -void ZONE_CONTAINER::initDataFromSrcInCopyCtor( const ZONE_CONTAINER& aZone ) +void ZONE_CONTAINER::InitDataFromSrcInCopyCtor( const ZONE_CONTAINER& aZone ) { // members are expected non initialize in this. - // initDataFromSrcInCopyCtor() is expected to be called + // InitDataFromSrcInCopyCtor() is expected to be called // only from a copy constructor. // Copy only useful EDA_ITEM flags: @@ -1310,7 +1310,7 @@ MODULE_ZONE_CONTAINER::MODULE_ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ) : MODULE_ZONE_CONTAINER::MODULE_ZONE_CONTAINER( const MODULE_ZONE_CONTAINER& aZone ) : ZONE_CONTAINER( aZone.GetParent(), true ) { - initDataFromSrcInCopyCtor( aZone ); + InitDataFromSrcInCopyCtor( aZone ); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index e8aac5ba43..c95eef94c5 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -82,6 +82,11 @@ public: return aItem && aItem->Type() == PCB_ZONE_AREA_T; } + /** + * Copy aZone data to me + */ + void InitDataFromSrcInCopyCtor( const ZONE_CONTAINER& aZone ); + /** * @return a wxPoint, position of the first point of the outline */ @@ -818,12 +823,6 @@ public: virtual void SwapData( BOARD_ITEM* aImage ) override; protected: - /** Copy aZone data to me - * members are expected non initialize in this. - * copyDataFromSrc() is expected to be called *only* from a copy constructor. - */ - void initDataFromSrcInCopyCtor( const ZONE_CONTAINER& aZone ); - SHAPE_POLY_SET* m_Poly; ///< Outline of the zone. int m_cornerSmoothingType; unsigned int m_cornerRadius; diff --git a/pcbnew/kicad_clipboard.cpp b/pcbnew/kicad_clipboard.cpp index 349940a656..c8c5b8240c 100644 --- a/pcbnew/kicad_clipboard.cpp +++ b/pcbnew/kicad_clipboard.cpp @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -61,7 +64,7 @@ void CLIPBOARD_IO::SetBoard( BOARD* aBoard ) } -void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) +void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected, bool isModEdit ) { VECTOR2I refPoint( 0, 0 ); @@ -75,26 +78,6 @@ void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) // Prepare net mapping that assures that net codes saved in a file are consecutive integers m_mapping->SetBoard( m_board ); - // Differentiate how it is formatted depending on what selection contains - bool onlyModuleParts = true; - for( const auto i : aSelected ) - { - // check if it not one of the module primitives - if( ( i->Type() != PCB_MODULE_EDGE_T ) && - ( i->Type() != PCB_MODULE_TEXT_T ) && - ( i->Type() != PCB_MODULE_ZONE_AREA_T ) && - ( i->Type() != PCB_PAD_T ) ) - { - onlyModuleParts = false; - break; - } - } - - // if there is only parts of a module selected, format it as a new module else - // format it as an entire board - MODULE partialModule( m_board ); - - // only a module selected. if( aSelected.Size() == 1 && aSelected.Front()->Type() == PCB_MODULE_T ) { // make the module safe to transfer to other pcbs @@ -113,10 +96,11 @@ void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) Format( static_cast( &newModule ) ); } - // partial module selected. - else if( onlyModuleParts ) + else if( isModEdit ) { - for( const auto item : aSelected ) + MODULE partialModule( m_board ); + + for( const EDA_ITEM* item : aSelected ) { BOARD_ITEM* clone = static_cast( item->Clone() ); @@ -142,9 +126,7 @@ void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) partialModule.MoveAnchorPosition( moveVector ); Format( &partialModule, 0 ); - } - // lots of stuff selected else { // we will fake being a .kicad_pcb to get the full parser kicking @@ -152,8 +134,8 @@ void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) LOCALE_IO io; m_formatter.Print( 0, "(kicad_pcb (version %d) (host pcbnew %s)\n", - SEXPR_BOARD_FILE_VERSION, m_formatter.Quotew( GetBuildVersion() ).c_str() ); - + SEXPR_BOARD_FILE_VERSION, + m_formatter.Quotew( GetBuildVersion() ).c_str() ); m_formatter.Print( 0, "\n" ); @@ -162,28 +144,72 @@ void CLIPBOARD_IO::SaveSelection( const PCBNEW_SELECTION& aSelected ) m_formatter.Print( 0, "\n" ); - - for( const auto i : aSelected ) + for( EDA_ITEM* i : aSelected ) { - // Dont format stuff that cannot exist standalone! - if( ( i->Type() != PCB_MODULE_EDGE_T ) && - ( i->Type() != PCB_MODULE_TEXT_T ) && - ( i->Type() != PCB_MODULE_ZONE_AREA_T ) && - ( i->Type() != PCB_PAD_T ) ) + BOARD_ITEM* item = static_cast( i ); + BOARD_ITEM* copy = nullptr; + + if( item->Type() == PCB_MODULE_EDGE_T ) { - auto item = static_cast( i ); - std::unique_ptr clone( static_cast ( item->Clone() ) ); + // Convert to PCB_LINE_T + copy = (BOARD_ITEM*) reinterpret_cast( item )->Clone(); + copy->SetLayer( item->GetLayer() ); + } + else if( item->Type() == PCB_MODULE_TEXT_T ) + { + // Convert to PCB_TEXT_T + MODULE* mod = static_cast( item->GetParent() ); + TEXTE_MODULE* mod_text = static_cast( item ); + TEXTE_PCB* pcb_text = new TEXTE_PCB( m_board ); + + if( mod_text->GetText() == "${VALUE}" ) + pcb_text->SetText( mod->GetValue() ); + else if( mod_text->GetText() == "${REFERENCE}" ) + pcb_text->SetText( mod->GetReference() ); + else + pcb_text->CopyText( *mod_text ); + + pcb_text->SetEffects( *mod_text ); + pcb_text->SetLayer( mod_text->GetLayer() ); + copy = pcb_text; + } + else if( item->Type() == PCB_PAD_T ) + { + // Create a parent to own the copied pad + MODULE* mod = new MODULE( m_board ); + D_PAD* pad = (D_PAD*) item->Clone(); + + mod->SetPosition( pad->GetPosition() ); + pad->SetPos0( wxPoint() ); + mod->Add( pad ); + copy = mod; + } + else if( item->Type() == PCB_MODULE_ZONE_AREA_T ) + { + // Convert to PCB_ZONE_AREA_T + ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); + zone->InitDataFromSrcInCopyCtor( *static_cast( item ) ); + copy = zone; + } + else + { + copy = static_cast( item->Clone() ); // locked means "locked in place"; copied items therefore can't be locked - if( MODULE* module = dyn_cast( clone.get() ) ) + if( MODULE* module = dyn_cast( copy ) ) module->SetLocked( false ); - else if( TRACK* track = dyn_cast( clone.get() ) ) + else if( TRACK* track = dyn_cast( copy ) ) track->SetLocked( false ); + } + if( copy ) + { // locate the reference point at (0, 0) in the copied items - clone->Move( (wxPoint) -refPoint ); + copy->Move( (wxPoint) -refPoint ); - Format( clone.get(), 1 ); + Format( copy, 1 ); + + delete copy; } } m_formatter.Print( 0, "\n)" ); diff --git a/pcbnew/kicad_clipboard.h b/pcbnew/kicad_clipboard.h index 58111c4d19..75af2e7aff 100644 --- a/pcbnew/kicad_clipboard.h +++ b/pcbnew/kicad_clipboard.h @@ -58,7 +58,7 @@ public: /* Writes all the settings of the BOARD* set by setBoard() and then adds all * the BOARD_ITEM* found in selection formatted by PCB_IO to clipboard as a text */ - void SaveSelection( const PCBNEW_SELECTION& selected ); + void SaveSelection( const PCBNEW_SELECTION& selected, bool isModEdit ); BOARD_ITEM* Parse(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 68e359e338..f2b64fbd69 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -1466,7 +1466,7 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent ) selection.SetReferencePoint( refPoint ); io.SetBoard( board() ); - io.SaveSelection( selection ); + io.SaveSelection( selection, m_editModules ); return 0; } diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 88fbb895a8..64dcc51b1b 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -830,12 +830,12 @@ int PCBNEW_CONTROL::placeBoardItems( std::vector& aItems, bool aIsN { m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - auto selectionTool = m_toolMgr->GetTool(); - auto editTool = m_toolMgr->GetTool(); + SELECTION_TOOL* selectionTool = m_toolMgr->GetTool(); + EDIT_TOOL* editTool = m_toolMgr->GetTool(); PCBNEW_SELECTION& selection = selectionTool->GetSelection(); - for( auto item : aItems ) + for( BOARD_ITEM* item : aItems ) { item->SetSelected(); selection.Add( item );