/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std::placeholders; void FOOTPRINT_EDIT_FRAME::OnLoadFootprintFromBoard( wxCommandEvent& event ) { LoadFootprintFromBoard( nullptr ); } void FOOTPRINT_EDIT_FRAME::LoadFootprintFromLibrary( LIB_ID aFPID ) { bool is_last_fp_from_brd = IsCurrentFPFromBoard(); FOOTPRINT* footprint = LoadFootprint( aFPID ); if( !footprint ) return; if( !Clear_Pcb( true ) ) return; GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false ); AddFootprintToBoard( footprint ); footprint->ClearFlags(); // if either reference or value are missing, reinstall them - // otherwise you cannot see what you are doing on board if( footprint->Reference().GetText().IsEmpty() ) footprint->SetReference( wxT( "Ref**" ) ); if( footprint->Value().GetText().IsEmpty() ) footprint->SetValue( wxT( "Val**" ) ); Zoom_Automatique( false ); Update3DView( true, true ); GetScreen()->SetContentModified( false ); UpdateView(); GetCanvas()->Refresh(); // Update the save items if needed. if( is_last_fp_from_brd ) { ReCreateMenuBar(); ReCreateHToolbar(); } m_treePane->GetLibTree()->ExpandLibId( aFPID ); m_centerItemOnIdle = aFPID; Bind( wxEVT_IDLE, &FOOTPRINT_EDIT_FRAME::centerItemIdleHandler, this ); m_treePane->GetLibTree()->RefreshLibTree(); // update highlighting } void FOOTPRINT_EDIT_FRAME::centerItemIdleHandler( wxIdleEvent& aEvent ) { m_treePane->GetLibTree()->CenterLibId( m_centerItemOnIdle ); Unbind( wxEVT_IDLE, &FOOTPRINT_EDIT_FRAME::centerItemIdleHandler, this ); } void FOOTPRINT_EDIT_FRAME::SelectLayer( wxCommandEvent& event ) { SetActiveLayer( ToLAYER_ID( m_selLayerBox->GetLayerSelection() ) ); if( GetDisplayOptions().m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ) GetCanvas()->Refresh(); } void FOOTPRINT_EDIT_FRAME::OnSaveFootprintToBoard( wxCommandEvent& event ) { SaveFootprintToBoard( true ); } class BASIC_FOOTPRINT_INFO : public FOOTPRINT_INFO { public: BASIC_FOOTPRINT_INFO( FOOTPRINT* aFootprint ) { wxASSERT( aFootprint ); m_nickname = aFootprint->GetFPID().GetLibNickname().wx_str(); m_fpname = aFootprint->GetFPID().GetLibItemName().wx_str(); m_pad_count = aFootprint->GetPadCount( DO_NOT_INCLUDE_NPTH ); m_unique_pad_count = aFootprint->GetUniquePadCount( DO_NOT_INCLUDE_NPTH ); m_keywords = aFootprint->GetKeywords(); m_doc = aFootprint->GetLibDescription(); m_loaded = true; } }; void FOOTPRINT_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, FOOTPRINT* aFootprint ) { wxCHECK( aFootprint, /* void */ ); BASIC_FOOTPRINT_INFO footprintInfo( aFootprint ); if( aTreeItem.IsOk() ) // Can be not found in tree if the current footprint is imported // from file therefore not yet in tree. { static_cast( aTreeItem.GetID() )->Update( &footprintInfo ); m_treePane->GetLibTree()->RefreshLibTree(); } } void FOOTPRINT_EDIT_FRAME::editFootprintProperties( FOOTPRINT* aFootprint ) { LIB_ID oldFPID = aFootprint->GetFPID(); DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR dialog( this, aFootprint ); dialog.ShowModal(); // Update library tree and title in case of a name change wxDataViewItem treeItem = m_adapter->FindItem( oldFPID ); UpdateLibraryTree( treeItem, aFootprint ); UpdateTitle(); UpdateMsgPanel(); } void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem ) { switch( aItem->Type() ) { case PCB_BITMAP_T: ShowBitmapPropertiesDialog( aItem ); break; case PCB_PAD_T: ShowPadPropertiesDialog( static_cast( aItem ) ); break; case PCB_FOOTPRINT_T: editFootprintProperties( static_cast( aItem ) ); GetCanvas()->Refresh(); break; case PCB_FIELD_T: case PCB_TEXT_T: ShowTextPropertiesDialog( static_cast( aItem ) ); break; case PCB_TEXTBOX_T: ShowTextBoxPropertiesDialog( static_cast( aItem ) ); break; case PCB_SHAPE_T : ShowGraphicItemPropertiesDialog( static_cast( aItem ) ); break; case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: case PCB_DIM_RADIAL_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: { DIALOG_DIMENSION_PROPERTIES dlg( this, static_cast( aItem ) ); dlg.ShowQuasiModal(); break; } case PCB_ZONE_T: { ZONE* zone = static_cast( aItem ); bool success = false; ZONE_SETTINGS zoneSettings; zoneSettings << *static_cast( aItem ); if( zone->GetIsRuleArea() ) { success = InvokeRuleAreaEditor( this, &zoneSettings ) == wxID_OK; } else if( zone->IsOnCopperLayer() ) { success = InvokeCopperZonesEditor( this, &zoneSettings ) == wxID_OK; } else { success = InvokeNonCopperZonesEditor( this, &zoneSettings ) == wxID_OK; } if( success ) { BOARD_COMMIT commit( this ); commit.Modify( zone ); commit.Push( _( "Edit Zone" ) ); zoneSettings.ExportSetting( *static_cast( aItem ) ); } break; } case PCB_GROUP_T: m_toolManager->RunAction( PCB_ACTIONS::groupProperties, static_cast( aItem ) ); break; case PCB_MARKER_T: m_toolManager->GetTool()->CrossProbe( static_cast( aItem ) ); break; default: wxFAIL_MSG( wxT( "FOOTPRINT_EDIT_FRAME::OnEditItemRequest: unsupported item type " ) + aItem->GetClass() ); break; } } COLOR4D FOOTPRINT_EDIT_FRAME::GetGridColor() { return GetColorSettings()->GetColor( LAYER_GRID ); } void FOOTPRINT_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer ) { PCB_BASE_FRAME::SetActiveLayer( aLayer ); m_appearancePanel->OnLayerChanged(); m_toolManager->PostAction( PCB_ACTIONS::layerChanged ); // notify other tools GetCanvas()->SetFocus(); // allow capture of hotkeys GetCanvas()->SetHighContrastLayer( aLayer ); GetCanvas()->Refresh(); } bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, int aCtl ) { if( !Clear_Pcb( true ) ) return false; // this command is aborted GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false ); ImportFootprint( aFileSet[ 0 ] ); if( GetBoard()->GetFirstFootprint() ) GetBoard()->GetFirstFootprint()->ClearFlags(); GetScreen()->SetContentModified( false ); Zoom_Automatique( false ); GetCanvas()->Refresh(); return true; } void FOOTPRINT_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) { const std::string& payload = mail.GetPayload(); switch( mail.Command() ) { case MAIL_FP_EDIT: if( !payload.empty() ) { wxFileName fpFileName( payload ); wxString libNickname; wxString msg; FP_LIB_TABLE* libTable = PROJECT_PCBNEW::PcbFootprintLibs( &Prj() ); const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() ); if( !libTableRow ) { msg.Printf( _( "The current configuration does not include a library named '%s'.\n" "Use Manage Footprint Libraries to edit the configuration." ), fpFileName.GetPath() ); DisplayErrorMessage( this, _( "Library not found in footprint library table." ), msg ); break; } libNickname = libTableRow->GetNickName(); if( !libTable->HasLibrary( libNickname, true ) ) { msg.Printf( _( "The library '%s' is not enabled in the current configuration.\n" "Use Manage Footprint Libraries to edit the configuration." ), libNickname ); DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg ); break; } LIB_ID fpId( libNickname, fpFileName.GetName() ); if( m_treePane ) { m_treePane->GetLibTree()->SelectLibId( fpId ); wxCommandEvent event( SYMBOL_SELECTED ); wxPostEvent( m_treePane, event ); } } break; case MAIL_RELOAD_LIB: SyncLibraryTree( true ); RefreshLibraryTree(); break; default: break; } }