/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright The 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 /************************************************************************************************** * * PANEL_ASSIGN_COMPONENT_CLASSES implementation * This is the top-level panel for component class configuration * *************************************************************************************************/ PANEL_ASSIGN_COMPONENT_CLASSES::PANEL_ASSIGN_COMPONENT_CLASSES( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, std::shared_ptr aSettings, DIALOG_SHIM* aDlg ) : PANEL_ASSIGN_COMPONENT_CLASSES_BASE( aParentWindow ), m_dlg( aDlg ), m_frame( aFrame ), m_componentClassSettings( std::move( aSettings ) ), m_assignmentsList( static_cast( m_assignmentsScrollWindow->GetSizer() ) ) { // Load footprint fields and sheet names const BOARD* board = dynamic_cast( m_frame->GetModel() ); std::set fieldsSet; std::set sheetsSet; for( const FOOTPRINT* fp : board->Footprints() ) { wxString sheetName = fp->GetSheetname(); if( !sheetName.empty() ) { sheetName.Replace( wxT( "\"" ), wxT( "" ) ); sheetName.Replace( wxT( "'" ), wxT( "" ) ); sheetsSet.insert( fp->GetSheetname() ); } for( const PCB_FIELD* field : fp->GetFields() ) fieldsSet.insert( field->GetName() ); } // Sort field names std::vector fieldNames( fieldsSet.begin(), fieldsSet.end() ); std::ranges::sort( fieldNames, []( const wxString& a, const wxString& b ) { return a.Cmp( b ) < 0; } ); m_fieldNames = std::move( fieldNames ); // Sort sheet names std::vector sheetNames( sheetsSet.begin(), sheetsSet.end() ); std::ranges::sort( sheetNames, []( const wxString& a, const wxString& b ) { return a.Cmp( b ) < 0; } ); m_sheetNames = std::move( sheetNames ); // Get references of currently selected items std::set refsSet; for( const EDA_ITEM* item : m_frame->GetCurrentSelection() ) { if( item->Type() != PCB_FOOTPRINT_T ) continue; const FOOTPRINT* fp = static_cast( item ); wxString ref = fp->GetReferenceAsString(); refsSet.insert( ref ); } std::vector refs( refsSet.begin(), refsSet.end() ); std::ranges::sort( refs, []( const wxString& a, const wxString& b ) { return a.Cmp( b ) < 0; } ); m_selectionRefs = std::move( refs ); } PANEL_ASSIGN_COMPONENT_CLASSES::~PANEL_ASSIGN_COMPONENT_CLASSES() { BOARD* board = dynamic_cast( m_frame->GetModel() ); PCB_SELECTION_TOOL* selTool = m_frame->GetToolManager()->GetTool(); for( FOOTPRINT* fp : board->Footprints() ) selTool->UnbrightenItem( fp ); m_frame->GetCanvas()->Refresh(); } bool PANEL_ASSIGN_COMPONENT_CLASSES::TransferDataToWindow() { // Load sheet-level settings m_assignSheetClasses->SetValue( m_componentClassSettings->GetEnableSheetComponentClasses() ); // Load dynamic component class assignments for( const COMPONENT_CLASS_ASSIGNMENT_DATA& assignmentData : m_componentClassSettings->GetComponentClassAssignments() ) { PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment = addAssignment(); assignment->SetComponentClass( assignmentData.GetComponentClass() ); assignment->SetConditionsOperator( assignmentData.GetConditionsOperator() ); for( const auto& [conditionType, conditionData] : assignmentData.GetConditions() ) { CONDITION_DATA* match = assignment->AddCondition( conditionType ); match->SetPrimaryField( conditionData.first ); match->SetSecondaryField( conditionData.second ); } } return true; } bool PANEL_ASSIGN_COMPONENT_CLASSES::TransferDataFromWindow() { if( !Validate() ) return false; // Save sheet-level settings m_componentClassSettings->SetEnableSheetComponentClasses( m_assignSheetClasses->GetValue() ); // Save dynamic component class assignments m_componentClassSettings->ClearComponentClassAssignments(); for( const auto assignment : m_assignments ) { COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData = assignment->GenerateAssignmentData(); m_componentClassSettings->AddComponentClassAssignment( assignmentData ); } return true; } bool PANEL_ASSIGN_COMPONENT_CLASSES::Validate() { PCB_EDIT_FRAME* frame = GetFrame(); BOARD* board = dynamic_cast( frame->GetModel() ); frame->GetCanvas()->Refresh(); for( PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment : m_assignments ) { const COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData = assignment->GenerateAssignmentData(); const std::shared_ptr rule = board->GetComponentClassManager().CompileAssignmentRule( assignmentData ); if( !rule ) { const wxString msg = wxString::Format( _( "Error with conditions for component class assignment %s" ), assignment->GetComponentClass() ); PAGED_DIALOG::GetDialog( this )->SetError( msg, this, assignment ); scrollToAssignment( assignment ); assignment->SetFocus(); return false; } } return true; } void PANEL_ASSIGN_COMPONENT_CLASSES::OnAddAssignmentClick( wxCommandEvent& event ) { PANEL_COMPONENT_CLASS_ASSIGNMENT* assignment = addAssignment(); scrollToAssignment( assignment ); } PANEL_COMPONENT_CLASS_ASSIGNMENT* PANEL_ASSIGN_COMPONENT_CLASSES::addAssignment() { PANEL_COMPONENT_CLASS_ASSIGNMENT* assignmentPanel = new PANEL_COMPONENT_CLASS_ASSIGNMENT( m_assignmentsScrollWindow, this, m_dlg ); #if __OSX__ m_assignmentsList->Add( assignmentPanel, 0, wxEXPAND, 5 ); #else m_assignmentsList->Add( assignmentPanel, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 ); #endif Layout(); m_assignments.push_back( assignmentPanel ); return assignmentPanel; } void PANEL_ASSIGN_COMPONENT_CLASSES::scrollToAssignment( const PANEL_COMPONENT_CLASS_ASSIGNMENT* aAssignment ) const { const wxPoint viewStart = m_assignmentsScrollWindow->GetViewStart(); const wxPoint panelPosition = aAssignment->GetPosition(); const wxSize panelSize = aAssignment->GetClientSize(); m_assignmentsScrollWindow->Scroll( viewStart.x, panelPosition.y + panelSize.y ); } void PANEL_ASSIGN_COMPONENT_CLASSES::RemoveAssignment( PANEL_COMPONENT_CLASS_ASSIGNMENT* aPanel ) { m_assignments.erase( std::ranges::find( m_assignments, aPanel ) ); m_assignmentsList->Detach( aPanel ); aPanel->Destroy(); Layout(); } void PANEL_ASSIGN_COMPONENT_CLASSES::ImportSettingsFrom( const std::shared_ptr& aOtherSettings ) { std::shared_ptr savedSettings = m_componentClassSettings; m_componentClassSettings = aOtherSettings; TransferDataToWindow(); m_componentClassSettings = std::move( savedSettings ); } /************************************************************************************************** * * CONDITION_DATA implementation * Provides a common interface for all condition panel types * *************************************************************************************************/ wxString CONDITION_DATA::GetPrimaryField() const { wxString data = m_primaryCtrl->GetValue(); data.Trim( true ); data.Trim( false ); if( m_conditionType != COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) { data.Replace( wxT( "\"" ), wxT( "" ) ); data.Replace( wxT( "'" ), wxT( "" ) ); } return data; } void CONDITION_DATA::SetPrimaryField( const wxString& aVal ) { m_primaryCtrl->SetValue( aVal ); } wxString CONDITION_DATA::GetSecondaryField() const { if( !m_secondaryCtrl ) return wxEmptyString; wxString data = m_secondaryCtrl->GetValue(); data.Trim( true ); data.Trim( false ); if( m_conditionType != COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) { data.Replace( wxT( "\"" ), wxT( "" ) ); data.Replace( wxT( "'" ), wxT( "" ) ); } return data; } void CONDITION_DATA::SetSecondaryField( const wxString& aVal ) { if( m_secondaryCtrl ) m_secondaryCtrl->SetValue( aVal ); }; /************************************************************************************************** * * PANEL_COMPONENT_CLASS_ASSIGNMENT implementation * This is the dynamically-added panel for each component class assignment rule set * *************************************************************************************************/ PANEL_COMPONENT_CLASS_ASSIGNMENT::PANEL_COMPONENT_CLASS_ASSIGNMENT( wxWindow* aParent, PANEL_ASSIGN_COMPONENT_CLASSES* aPanelParent, DIALOG_SHIM* aDlg ) : PANEL_COMPONENT_CLASS_ASSIGNMENT_BASE( aParent ), m_parentPanel( aPanelParent ), m_matchesList( static_cast( GetSizer() ) ), m_dlg( aDlg ) { m_buttonAddCondition->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) ); m_buttonDeleteAssignment->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); m_buttonHighlightItems->SetBitmap( KiBitmapBundle( BITMAPS::net_highlight ) ); Connect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu ), nullptr, this ); } PANEL_COMPONENT_CLASS_ASSIGNMENT::~PANEL_COMPONENT_CLASS_ASSIGNMENT() { Disconnect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu ), nullptr, this ); } COMPONENT_CLASS_ASSIGNMENT_DATA PANEL_COMPONENT_CLASS_ASSIGNMENT::GenerateAssignmentData() const { COMPONENT_CLASS_ASSIGNMENT_DATA assignmentData; assignmentData.SetComponentClass( GetComponentClass() ); assignmentData.SetConditionsOperation( GetConditionsOperator() ); for( const auto& condition : GetConditions() ) { assignmentData.SetCondition( condition->GetConditionType(), condition->GetPrimaryField(), condition->GetSecondaryField() ); } return assignmentData; } void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnAddConditionClick( wxCommandEvent& event ) { auto hasCondition = [this]( const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition ) { return m_conditionTypes.contains( aCondition ); }; wxMenu menu; menu.Append( ID_REFERENCE, _( "Reference..." ) ); menu.Append( ID_FOOTPRINT, _( "Footprint..." ) ); menu.Append( ID_SIDE, _( "Side..." ) ); menu.Append( ID_ROTATION, _( "Rotation..." ) ); menu.Append( ID_FOOTPRINT_FIELD, _( "Footprint Field..." ) ); menu.Append( ID_SHEET_NAME, _( "Sheet Name..." ) ); menu.Append( ID_CUSTOM, _( "Custom..." ) ); menu.Enable( ID_REFERENCE, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ) ); menu.Enable( ID_FOOTPRINT, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ) ); menu.Enable( ID_SIDE, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ) ); menu.Enable( ID_ROTATION, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ) ); menu.Enable( ID_FOOTPRINT_FIELD, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ) ); menu.Enable( ID_CUSTOM, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ) ); menu.Enable( ID_SHEET_NAME, !hasCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ) ); PopupMenu( &menu ); } void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnDeleteAssignmentClick( wxCommandEvent& event ) { m_parentPanel->RemoveAssignment( this ); } void PANEL_COMPONENT_CLASS_ASSIGNMENT::SetComponentClass( const wxString& aComponentClass ) const { m_componentClass->SetValue( aComponentClass ); } const wxString PANEL_COMPONENT_CLASS_ASSIGNMENT::GetComponentClass() const { return m_componentClass->GetValue(); } void PANEL_COMPONENT_CLASS_ASSIGNMENT::onMenu( wxCommandEvent& aEvent ) { switch( aEvent.GetId() ) { case ID_REFERENCE: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ); break; case ID_FOOTPRINT: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ); break; case ID_SIDE: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ); break; case ID_ROTATION: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ); break; case ID_FOOTPRINT_FIELD: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ); break; case ID_CUSTOM: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ); break; case ID_SHEET_NAME: AddCondition( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ); break; default: wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) ); } } CONDITION_DATA* PANEL_COMPONENT_CLASS_ASSIGNMENT::AddCondition( const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE aCondition ) { wxASSERT_MSG( !m_conditionTypes.contains( aCondition ), "Condition type already exists" ); wxPanel* panelToAdd = nullptr; switch( aCondition ) { case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE: { PANEL_COMPONENT_CLASS_CONDITION_REFERENCE* refsPanel = new PANEL_COMPONENT_CLASS_CONDITION_REFERENCE( this ); refsPanel->SetSelectionRefs( m_parentPanel->GetSelectionRefs() ); panelToAdd = refsPanel; m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT: { panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT( this, m_dlg ); m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE: { panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_SIDE( this ); m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION: { panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_ROTATION( this ); m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD: { PANEL_COMPONENT_CLASS_CONDITION_FIELD* fieldPanel = new PANEL_COMPONENT_CLASS_CONDITION_FIELD( this ); fieldPanel->SetFieldsList( m_parentPanel->GetFieldNames() ); panelToAdd = fieldPanel; m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM: { panelToAdd = new PANEL_COMPONENT_CLASS_CONDITION_CUSTOM( this ); m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM ); break; } case COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME: { PANEL_COMPONENT_CLASS_CONDITION_SHEET* sheetPanel = new PANEL_COMPONENT_CLASS_CONDITION_SHEET( this ); sheetPanel->SetSheetsList( m_parentPanel->GetSheetNames() ); panelToAdd = sheetPanel; m_conditionTypes.insert( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME ); break; } } const size_t numItems = m_matchesList->GetItemCount(); m_matchesList->Insert( numItems - 1, panelToAdd, 0, wxEXPAND | wxTOP, 5 ); Layout(); GetParent()->Layout(); m_parentPanel->Layout(); CONDITION_DATA* conditionIface = dynamic_cast( panelToAdd ); m_matches.push_back( conditionIface ); return conditionIface; } void PANEL_COMPONENT_CLASS_ASSIGNMENT::RemoveCondition( wxPanel* aMatch ) { if( CONDITION_DATA* matchData = dynamic_cast( aMatch ) ) { m_conditionTypes.erase( matchData->GetConditionType() ); m_matches.erase( std::ranges::find( m_matches, matchData ) ); } m_matchesList->Detach( aMatch ); aMatch->Destroy(); Layout(); m_parentPanel->Layout(); } void PANEL_COMPONENT_CLASS_ASSIGNMENT::SetConditionsOperator( const COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR aCondition ) const { if( aCondition == COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL ) { m_radioAll->SetValue( true ); m_radioAny->SetValue( false ); } else { m_radioAll->SetValue( false ); m_radioAny->SetValue( true ); } } COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR PANEL_COMPONENT_CLASS_ASSIGNMENT::GetConditionsOperator() const { if( m_radioAll->GetValue() == true ) return COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ALL; return COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITIONS_OPERATOR::ANY; } void PANEL_COMPONENT_CLASS_ASSIGNMENT::OnHighlightItemsClick( wxCommandEvent& event ) { PCB_EDIT_FRAME* frame = m_parentPanel->GetFrame(); BOARD* board = dynamic_cast( frame->GetModel() ); PCB_SELECTION_TOOL* selTool = frame->GetToolManager()->GetTool(); const COMPONENT_CLASS_ASSIGNMENT_DATA assignment = GenerateAssignmentData(); const std::shared_ptr rule = board->GetComponentClassManager().CompileAssignmentRule( assignment ); if( !rule ) return; for( FOOTPRINT* fp : board->Footprints() ) { if( rule->Matches( fp ) ) selTool->BrightenItem( fp ); else selTool->UnbrightenItem( fp ); } frame->GetCanvas()->Refresh(); } /************************************************************************************************** * * PANEL_COMPONENT_CLASS_CONDITION_* implementations * These are the dynamically-added panels for each condition / match type * *************************************************************************************************/ PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::PANEL_COMPONENT_CLASS_CONDITION_REFERENCE( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_REFERENCE_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::REFERENCE, m_refs ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonImportRefs->SetBitmap( KiBitmapBundle( BITMAPS::config ) ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); Connect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu ), nullptr, this ); } void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); Disconnect( wxEVT_MENU, wxCommandEventHandler( PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu ), nullptr, this ); } void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::OnImportRefsClick( wxCommandEvent& event ) { wxMenu menu; menu.Append( ID_IMPORT_REFS, _( "Import references from selection" ) ); menu.Enable( ID_IMPORT_REFS, !m_selectionRefs.empty() ); PopupMenu( &menu ); } void PANEL_COMPONENT_CLASS_CONDITION_REFERENCE::onMenu( wxCommandEvent& aEvent ) { if( aEvent.GetId() != ID_IMPORT_REFS ) wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) ); if( m_selectionRefs.empty() ) return; wxString refs = m_selectionRefs[0]; for( size_t i = 1; i < m_selectionRefs.size(); i++ ) { refs += wxT( "," ); refs += m_selectionRefs[i]; } m_refs->SetValue( refs ); } PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT( wxWindow* aParent, DIALOG_SHIM* aDlg ) : PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT, m_footprint ), m_panelParent( static_cast( aParent ) ), m_dlg( aDlg ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); m_buttonShowLibrary->SetBitmap( KiBitmapBundle( BITMAPS::small_library ) ); } void PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } void PANEL_COMPONENT_CLASS_CONDITION_FOOTPRINT::OnShowLibraryClick( wxCommandEvent& event ) { wxString fpId = m_footprint->GetValue(); if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) ) { if( frame->ShowModal( &fpId, this ) ) { m_footprint->SetValue( fpId ); } frame->Destroy(); } } PANEL_COMPONENT_CLASS_CONDITION_SIDE::PANEL_COMPONENT_CLASS_CONDITION_SIDE( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_SIDE_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SIDE, m_side ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); m_side->Append( wxT( "Any" ) ); m_side->Append( wxT( "Front" ) ); m_side->Append( wxT( "Back" ) ); m_side->SetValue( wxT( "Any" ) ); } void PANEL_COMPONENT_CLASS_CONDITION_SIDE::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } PANEL_COMPONENT_CLASS_CONDITION_ROTATION::PANEL_COMPONENT_CLASS_CONDITION_ROTATION( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_ROTATION_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::ROTATION, m_rotation ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_rotUnit->SetLabel( wxT( "°" ) ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); m_rotation->Append( wxT( "Any" ) ); m_rotation->Append( wxT( "0" ) ); m_rotation->Append( wxT( "90" ) ); m_rotation->Append( wxT( "180" ) ); m_rotation->Append( wxT( "-90" ) ); m_rotation->SetValue( wxT( "Any" ) ); } void PANEL_COMPONENT_CLASS_CONDITION_ROTATION::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } PANEL_COMPONENT_CLASS_CONDITION_FIELD::PANEL_COMPONENT_CLASS_CONDITION_FIELD( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_FIELD_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::FOOTPRINT_FIELD, m_fieldName, m_fieldValue ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); } void PANEL_COMPONENT_CLASS_CONDITION_FIELD::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } void PANEL_COMPONENT_CLASS_CONDITION_FIELD::SetFieldsList( const std::vector& aFields ) { m_fieldName->Append( aFields ); } PANEL_COMPONENT_CLASS_CONDITION_CUSTOM::PANEL_COMPONENT_CLASS_CONDITION_CUSTOM( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_CUSTOM_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::CUSTOM, m_customCondition ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); } void PANEL_COMPONENT_CLASS_CONDITION_CUSTOM::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } PANEL_COMPONENT_CLASS_CONDITION_SHEET::PANEL_COMPONENT_CLASS_CONDITION_SHEET( wxWindow* aParent ) : PANEL_COMPONENT_CLASS_CONDITION_SHEET_BASE( aParent ), CONDITION_DATA( COMPONENT_CLASS_ASSIGNMENT_DATA::CONDITION_TYPE::SHEET_NAME, m_sheetName ), m_panelParent( static_cast( aParent ) ) { m_title->SetMinSize( { GetTextExtent( _( "Footprint Field:" ) ).x, -1 } ); m_buttonDeleteMatch->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) ); } void PANEL_COMPONENT_CLASS_CONDITION_SHEET::OnDeleteConditionClick( wxCommandEvent& event ) { m_panelParent->RemoveCondition( this ); } void PANEL_COMPONENT_CLASS_CONDITION_SHEET::SetSheetsList( const std::vector& aSheets ) { m_sheetName->Append( aSheets ); }