PCB: convert footprints to use PCB_FIELDs for fields from schematics
This commit is contained in:
parent
968785382e
commit
a859b25d2c
|
@ -77,7 +77,7 @@ DIALOG_FOOTPRINT_PROPERTIES::DIALOG_FOOTPRINT_PROPERTIES( PCB_EDIT_FRAME* aParen
|
||||||
m_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
|
m_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
|
||||||
m_posY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
|
m_posY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
|
||||||
|
|
||||||
m_texts = new FP_TEXT_GRID_TABLE( m_frame );
|
m_fields = new FP_TEXT_GRID_TABLE( m_frame );
|
||||||
|
|
||||||
m_delayedErrorMessage = wxEmptyString;
|
m_delayedErrorMessage = wxEmptyString;
|
||||||
m_delayedFocusGrid = nullptr;
|
m_delayedFocusGrid = nullptr;
|
||||||
|
@ -93,7 +93,7 @@ DIALOG_FOOTPRINT_PROPERTIES::DIALOG_FOOTPRINT_PROPERTIES( PCB_EDIT_FRAME* aParen
|
||||||
// Give a bit more room for combobox editors
|
// Give a bit more room for combobox editors
|
||||||
m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
|
m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
|
||||||
|
|
||||||
m_itemsGrid->SetTable( m_texts );
|
m_itemsGrid->SetTable( m_fields );
|
||||||
m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
|
m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
|
||||||
|
|
||||||
// Show/hide text item columns according to the user's preference
|
// Show/hide text item columns according to the user's preference
|
||||||
|
@ -177,7 +177,7 @@ DIALOG_FOOTPRINT_PROPERTIES::~DIALOG_FOOTPRINT_PROPERTIES()
|
||||||
cfg->m_FootprintTextShownColumns = m_itemsGrid->GetShownColumnsAsString();
|
cfg->m_FootprintTextShownColumns = m_itemsGrid->GetShownColumnsAsString();
|
||||||
|
|
||||||
// Prevents crash bug in wxGrid's d'tor
|
// Prevents crash bug in wxGrid's d'tor
|
||||||
m_itemsGrid->DestroyTable( m_texts );
|
m_itemsGrid->DestroyTable( m_fields );
|
||||||
|
|
||||||
// Delete the GRID_TRICKS.
|
// Delete the GRID_TRICKS.
|
||||||
m_itemsGrid->PopEventHandler( true );
|
m_itemsGrid->PopEventHandler( true );
|
||||||
|
@ -244,18 +244,13 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
|
||||||
if( !m_3dPanel->TransferDataToWindow() )
|
if( !m_3dPanel->TransferDataToWindow() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Footprint Texts
|
// Footprint Fields
|
||||||
m_texts->push_back( m_footprint->Reference() );
|
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||||
m_texts->push_back( m_footprint->Value() );
|
m_fields->push_back( field );
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
|
||||||
{
|
|
||||||
if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item ) )
|
|
||||||
m_texts->push_back( *textItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify the grid
|
// notify the grid
|
||||||
wxGridTableMessage tmsg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_texts->GetNumberRows() );
|
wxGridTableMessage tmsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
|
||||||
|
m_fields->GetNumberRows() );
|
||||||
m_itemsGrid->ProcessTableMessage( tmsg );
|
m_itemsGrid->ProcessTableMessage( tmsg );
|
||||||
|
|
||||||
// Footprint Properties
|
// Footprint Properties
|
||||||
|
@ -328,7 +323,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
|
||||||
m_itemsGrid->SetColSize( col, col_size );
|
m_itemsGrid->SetColSize( col, col_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, false, true, true ) );
|
m_itemsGrid->SetRowLabelSize( 0 );
|
||||||
|
|
||||||
Layout();
|
Layout();
|
||||||
adjustGridColumns();
|
adjustGridColumns();
|
||||||
|
@ -346,24 +341,19 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Validate texts.
|
// Validate texts.
|
||||||
for( size_t i = 0; i < m_texts->size(); ++i )
|
for( size_t i = 0; i < m_fields->size(); ++i )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = m_texts->at( i );
|
PCB_FIELD* field = m_fields->at( i );
|
||||||
|
|
||||||
if( i >= 2 )
|
// Check for missing field names.
|
||||||
|
if( field->GetName( false ).IsEmpty() )
|
||||||
{
|
{
|
||||||
if( text.GetText().IsEmpty() )
|
m_delayedFocusGrid = m_itemsGrid;
|
||||||
{
|
m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
|
||||||
if( m_NoteBook->GetSelection() != 0 )
|
m_delayedFocusColumn = FPT_NAME;
|
||||||
m_NoteBook->SetSelection( 0 );
|
m_delayedFocusRow = i;
|
||||||
|
|
||||||
m_delayedFocusGrid = m_itemsGrid;
|
return false;
|
||||||
m_delayedErrorMessage = _( "Text items must have some content." );
|
|
||||||
m_delayedFocusColumn = FPT_TEXT;
|
|
||||||
m_delayedFocusRow = i;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
|
int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
|
||||||
|
@ -426,9 +416,9 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for acceptable values for thickness and size and clamp if fails
|
// Test for acceptable values for thickness and size and clamp if fails
|
||||||
int maxPenWidth = Clamp_Text_PenSize( text.GetTextThickness(), text.GetTextSize() );
|
int maxPenWidth = Clamp_Text_PenSize( field->GetTextThickness(), field->GetTextSize() );
|
||||||
|
|
||||||
if( text.GetTextThickness() > maxPenWidth )
|
if( field->GetTextThickness() > maxPenWidth )
|
||||||
{
|
{
|
||||||
wxString clamped = m_frame->StringFromValue( maxPenWidth, true );
|
wxString clamped = m_frame->StringFromValue( maxPenWidth, true );
|
||||||
|
|
||||||
|
@ -470,30 +460,24 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataFromWindow()
|
||||||
BOARD_COMMIT commit( m_frame );
|
BOARD_COMMIT commit( m_frame );
|
||||||
commit.Modify( m_footprint );
|
commit.Modify( m_footprint );
|
||||||
|
|
||||||
// copy reference and value
|
// Update fields
|
||||||
m_footprint->Reference() = m_texts->at( 0 );
|
size_t i = 0;
|
||||||
m_footprint->Value() = m_texts->at( 1 );
|
|
||||||
|
|
||||||
size_t i = 2;
|
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
|
||||||
{
|
{
|
||||||
if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item ) )
|
// copy grid table entries till we run out, then delete any remaining texts
|
||||||
{
|
if( i < m_fields->size() )
|
||||||
// copy grid table entries till we run out, then delete any remaining texts
|
field = m_fields->at( i++ );
|
||||||
if( i < m_texts->size() )
|
else
|
||||||
*textItem = m_texts->at( i++ );
|
field->DeleteStructure();
|
||||||
else
|
|
||||||
textItem->DeleteStructure();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there are still grid table entries, create new texts for them
|
// if there are still grid table entries, create new texts for them
|
||||||
while( i < m_texts->size() )
|
while( i < m_fields->size() )
|
||||||
{
|
{
|
||||||
PCB_TEXT* newText = new PCB_TEXT( m_texts->at( i++ ) );
|
PCB_FIELD* newField = m_fields->at( i++ );
|
||||||
m_footprint->Add( newText, ADD_MODE::APPEND );
|
m_footprint->Add( newField, ADD_MODE::APPEND );
|
||||||
view->Add( newText );
|
view->Add( newField );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize masks clearances
|
// Initialize masks clearances
|
||||||
|
@ -583,30 +567,21 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnAddField( wxCommandEvent& )
|
||||||
if( !m_itemsGrid->CommitPendingChanges() )
|
if( !m_itemsGrid->CommitPendingChanges() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
|
PCB_FIELD* newField = new PCB_FIELD( m_footprint, m_fields->size() );
|
||||||
PCB_TEXT textItem( m_footprint, PCB_TEXT::TEXT_is_DIVERS );
|
|
||||||
|
|
||||||
// Set active layer if legal; otherwise copy layer from previous text item
|
newField->SetLayer( m_footprint->GetLayer() == F_Cu ? F_Fab : B_Fab );
|
||||||
if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
|
newField->SetVisible( false );
|
||||||
textItem.SetLayer( m_frame->GetActiveLayer() );
|
newField->StyleFromSettings( m_frame->GetDesignSettings() );
|
||||||
else
|
|
||||||
textItem.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
|
|
||||||
|
|
||||||
textItem.SetTextSize( dsnSettings.GetTextSize( textItem.GetLayer() ) );
|
m_fields->push_back( newField );
|
||||||
textItem.SetTextThickness( dsnSettings.GetTextThickness( textItem.GetLayer() ) );
|
|
||||||
textItem.SetItalic( dsnSettings.GetTextItalic( textItem.GetLayer() ) );
|
|
||||||
textItem.SetKeepUpright( dsnSettings.GetTextUpright( textItem.GetLayer() ) );
|
|
||||||
textItem.SetMirrored( IsBackLayer( textItem.GetLayer() ) );
|
|
||||||
|
|
||||||
m_texts->push_back( textItem );
|
|
||||||
|
|
||||||
// notify the grid
|
// notify the grid
|
||||||
wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
||||||
m_itemsGrid->ProcessTableMessage( msg );
|
m_itemsGrid->ProcessTableMessage( msg );
|
||||||
|
|
||||||
m_itemsGrid->SetFocus();
|
m_itemsGrid->SetFocus();
|
||||||
m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
|
m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
|
||||||
m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
|
m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
|
||||||
|
|
||||||
m_itemsGrid->EnableCellEditControl( true );
|
m_itemsGrid->EnableCellEditControl( true );
|
||||||
m_itemsGrid->ShowCellEditControl();
|
m_itemsGrid->ShowCellEditControl();
|
||||||
|
@ -628,22 +603,26 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnDeleteField( wxCommandEvent& )
|
||||||
|
|
||||||
for( int row : selectedRows )
|
for( int row : selectedRows )
|
||||||
{
|
{
|
||||||
if( row < 2 )
|
if( row < MANDATORY_FIELDS )
|
||||||
{
|
{
|
||||||
DisplayError( nullptr, _( "Reference and value are mandatory." ) );
|
DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
|
||||||
|
MANDATORY_FIELDS ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
|
||||||
|
m_itemsGrid->ClearSelection();
|
||||||
|
|
||||||
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
||||||
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
||||||
|
|
||||||
for( int row : selectedRows )
|
for( int row : selectedRows )
|
||||||
{
|
{
|
||||||
m_texts->erase( m_texts->begin() + row );
|
m_fields->erase( m_fields->begin() + row );
|
||||||
|
|
||||||
// notify the grid
|
// notify the grid
|
||||||
wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
|
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
|
||||||
m_itemsGrid->ProcessTableMessage( msg );
|
m_itemsGrid->ProcessTableMessage( msg );
|
||||||
|
|
||||||
if( m_itemsGrid->GetNumberRows() > 0 )
|
if( m_itemsGrid->GetNumberRows() > 0 )
|
||||||
|
@ -662,11 +641,16 @@ void DIALOG_FOOTPRINT_PROPERTIES::adjustGridColumns()
|
||||||
|
|
||||||
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
||||||
|
|
||||||
for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
|
for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
{
|
||||||
|
if( i == 1 )
|
||||||
|
continue;
|
||||||
|
|
||||||
m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
|
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||||
m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
}
|
||||||
|
|
||||||
|
m_itemsGrid->SetColSize(
|
||||||
|
1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||||
|
|
||||||
// Update the width of the 3D panel
|
// Update the width of the 3D panel
|
||||||
m_3dPanel->AdjustGridColumnWidths();
|
m_3dPanel->AdjustGridColumnWidths();
|
||||||
|
@ -710,7 +694,10 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& )
|
||||||
if( !m_initialFocus || grid == m_itemsGrid )
|
if( !m_initialFocus || grid == m_itemsGrid )
|
||||||
{
|
{
|
||||||
grid->SetGridCursor( row, col );
|
grid->SetGridCursor( row, col );
|
||||||
grid->EnableCellEditControl( true );
|
|
||||||
|
if( !( col == 0 && row < MANDATORY_FIELDS ) )
|
||||||
|
grid->EnableCellEditControl( true );
|
||||||
|
|
||||||
grid->ShowCellEditControl();
|
grid->ShowCellEditControl();
|
||||||
|
|
||||||
if( grid == m_itemsGrid && row == 0 && col == 0 )
|
if( grid == m_itemsGrid && row == 0 && col == 0 )
|
||||||
|
|
|
@ -82,7 +82,7 @@ private:
|
||||||
|
|
||||||
static int m_page; // remember the last open page during session
|
static int m_page; // remember the last open page during session
|
||||||
|
|
||||||
FP_TEXT_GRID_TABLE* m_texts;
|
FP_TEXT_GRID_TABLE* m_fields;
|
||||||
UNIT_BINDER m_posX;
|
UNIT_BINDER m_posX;
|
||||||
UNIT_BINDER m_posY;
|
UNIT_BINDER m_posY;
|
||||||
UNIT_BINDER m_orientation;
|
UNIT_BINDER m_orientation;
|
||||||
|
|
|
@ -142,7 +142,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(
|
||||||
m_3dPanel = new PANEL_FP_PROPERTIES_3D_MODEL( m_frame, m_footprint, this, m_NoteBook );
|
m_3dPanel = new PANEL_FP_PROPERTIES_3D_MODEL( m_frame, m_footprint, this, m_NoteBook );
|
||||||
m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
|
m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
|
||||||
|
|
||||||
m_texts = new FP_TEXT_GRID_TABLE( m_frame );
|
m_fields = new FP_TEXT_GRID_TABLE( m_frame );
|
||||||
m_privateLayers = new PRIVATE_LAYERS_GRID_TABLE( m_frame );
|
m_privateLayers = new PRIVATE_LAYERS_GRID_TABLE( m_frame );
|
||||||
|
|
||||||
m_delayedErrorMessage = wxEmptyString;
|
m_delayedErrorMessage = wxEmptyString;
|
||||||
|
@ -161,7 +161,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(
|
||||||
m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
|
m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
|
||||||
m_privateLayersGrid->SetDefaultRowSize( m_privateLayersGrid->GetDefaultRowSize() + 4 );
|
m_privateLayersGrid->SetDefaultRowSize( m_privateLayersGrid->GetDefaultRowSize() + 4 );
|
||||||
|
|
||||||
m_itemsGrid->SetTable( m_texts );
|
m_itemsGrid->SetTable( m_fields );
|
||||||
m_privateLayersGrid->SetTable( m_privateLayers );
|
m_privateLayersGrid->SetTable( m_privateLayers );
|
||||||
|
|
||||||
m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
|
m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
|
||||||
|
@ -232,7 +232,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::~DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR()
|
||||||
cfg->m_FootprintTextShownColumns = m_itemsGrid->GetShownColumnsAsString();
|
cfg->m_FootprintTextShownColumns = m_itemsGrid->GetShownColumnsAsString();
|
||||||
|
|
||||||
// Prevents crash bug in wxGrid's d'tor
|
// Prevents crash bug in wxGrid's d'tor
|
||||||
m_itemsGrid->DestroyTable( m_texts );
|
m_itemsGrid->DestroyTable( m_fields );
|
||||||
m_privateLayersGrid->DestroyTable( m_privateLayers );
|
m_privateLayersGrid->DestroyTable( m_privateLayers );
|
||||||
|
|
||||||
// Delete the GRID_TRICKS.
|
// Delete the GRID_TRICKS.
|
||||||
|
@ -267,18 +267,13 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::TransferDataToWindow()
|
||||||
if( !m_3dPanel->TransferDataToWindow() )
|
if( !m_3dPanel->TransferDataToWindow() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Footprint Texts
|
// Footprint Fields
|
||||||
m_texts->push_back( m_footprint->Reference() );
|
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||||
m_texts->push_back( m_footprint->Value() );
|
m_fields->push_back( field );
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
|
||||||
{
|
|
||||||
if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item) )
|
|
||||||
m_texts->push_back( *textItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the grid
|
// Notify the grid
|
||||||
wxGridTableMessage tmsg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_texts->GetNumberRows() );
|
wxGridTableMessage tmsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
|
||||||
|
m_fields->GetNumberRows() );
|
||||||
m_itemsGrid->ProcessTableMessage( tmsg );
|
m_itemsGrid->ProcessTableMessage( tmsg );
|
||||||
|
|
||||||
if( m_footprint->GetAttributes() & FP_THROUGH_HOLE )
|
if( m_footprint->GetAttributes() & FP_THROUGH_HOLE )
|
||||||
|
@ -352,7 +347,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::TransferDataToWindow()
|
||||||
m_itemsGrid->SetColSize( col, col_size );
|
m_itemsGrid->SetColSize( col, col_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
|
m_itemsGrid->SetRowLabelSize( 0 );
|
||||||
|
|
||||||
Layout();
|
Layout();
|
||||||
adjustGridColumns();
|
adjustGridColumns();
|
||||||
|
@ -401,19 +396,17 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for empty texts.
|
// Check for valid field text properties
|
||||||
for( size_t i = 2; i < m_texts->size(); ++i )
|
for( size_t i = 0; i < m_fields->size(); ++i )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = m_texts->at( i );
|
PCB_FIELD* field = m_fields->at( i );
|
||||||
|
|
||||||
if( text.GetText().IsEmpty() )
|
// Check for missing field names.
|
||||||
|
if( field->GetName( false ).IsEmpty() )
|
||||||
{
|
{
|
||||||
if( m_NoteBook->GetSelection() != 0 )
|
|
||||||
m_NoteBook->SetSelection( 0 );
|
|
||||||
|
|
||||||
m_delayedErrorMessage = _( "Text items must have some content." );
|
|
||||||
m_delayedFocusGrid = m_itemsGrid;
|
m_delayedFocusGrid = m_itemsGrid;
|
||||||
m_delayedFocusColumn = FPT_TEXT;
|
m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
|
||||||
|
m_delayedFocusColumn = FPT_NAME;
|
||||||
m_delayedFocusRow = i;
|
m_delayedFocusRow = i;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -422,7 +415,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||||
int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
|
int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
|
||||||
int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
|
int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
|
||||||
|
|
||||||
if( text.GetTextWidth() < minSize || text.GetTextWidth() > maxSize )
|
if( field->GetTextWidth() < minSize || field->GetTextWidth() > maxSize )
|
||||||
{
|
{
|
||||||
m_delayedFocusGrid = m_itemsGrid;
|
m_delayedFocusGrid = m_itemsGrid;
|
||||||
m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
|
m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
|
||||||
|
@ -434,7 +427,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( text.GetTextHeight() < minSize || text.GetTextHeight() > maxSize )
|
if( field->GetTextHeight() < minSize || field->GetTextHeight() > maxSize )
|
||||||
{
|
{
|
||||||
m_delayedFocusGrid = m_itemsGrid;
|
m_delayedFocusGrid = m_itemsGrid;
|
||||||
m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
|
m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
|
||||||
|
@ -447,9 +440,9 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for acceptable values for thickness and size and clamp if fails
|
// Test for acceptable values for thickness and size and clamp if fails
|
||||||
int maxPenWidth = Clamp_Text_PenSize( text.GetTextThickness(), text.GetTextSize() );
|
int maxPenWidth = Clamp_Text_PenSize( field->GetTextThickness(), field->GetTextSize() );
|
||||||
|
|
||||||
if( text.GetTextThickness() > maxPenWidth )
|
if( field->GetTextThickness() > maxPenWidth )
|
||||||
{
|
{
|
||||||
m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
|
m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
|
||||||
m_frame->StringFromValue( maxPenWidth, true ) );
|
m_frame->StringFromValue( maxPenWidth, true ) );
|
||||||
|
@ -502,44 +495,37 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::TransferDataFromWindow()
|
||||||
m_footprint->SetDescription( m_DocCtrl->GetValue() );
|
m_footprint->SetDescription( m_DocCtrl->GetValue() );
|
||||||
m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
|
m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
|
||||||
|
|
||||||
// copy reference and value
|
// Update fields
|
||||||
m_footprint->Reference() = m_texts->at( 0 );
|
|
||||||
m_footprint->Value() = m_texts->at( 1 );
|
|
||||||
|
|
||||||
size_t i = 2;
|
|
||||||
std::vector<PCB_TEXT*> items_to_remove;
|
std::vector<PCB_TEXT*> items_to_remove;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||||
{
|
{
|
||||||
PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item );
|
// copy grid table entries till we run out, then delete any remaining texts
|
||||||
|
if( i < m_fields->size() )
|
||||||
if( textItem )
|
field = m_fields->at( i++ );
|
||||||
{
|
else
|
||||||
// copy grid table entries till we run out, then delete any remaining texts
|
items_to_remove.push_back( field );
|
||||||
if( i < m_texts->size() )
|
|
||||||
*textItem = m_texts->at( i++ );
|
|
||||||
else // store this item to remove and delete it later,
|
|
||||||
// after the graphic list is explored:
|
|
||||||
items_to_remove.push_back( textItem );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove text items:
|
// Remove text items:
|
||||||
PCB_SELECTION_TOOL* selTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
PCB_SELECTION_TOOL* selTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
|
||||||
|
|
||||||
for( PCB_TEXT* item: items_to_remove )
|
for( PCB_TEXT* item : items_to_remove )
|
||||||
{
|
{
|
||||||
selTool->RemoveItemFromSel( item );
|
selTool->RemoveItemFromSel( item );
|
||||||
view->Remove( item );
|
view->Remove( item );
|
||||||
item->DeleteStructure();
|
item->DeleteStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if there are still grid table entries, create new texts for them
|
// if there are still grid table entries, create new texts for them
|
||||||
while( i < m_texts->size() )
|
while( i < m_fields->size() )
|
||||||
{
|
{
|
||||||
PCB_TEXT* newText = new PCB_TEXT( m_texts->at( i++ ) );
|
PCB_FIELD* field = m_fields->at( i++ );
|
||||||
m_footprint->Add( newText, ADD_MODE::APPEND );
|
m_footprint->AddField( field );
|
||||||
view->Add( newText );
|
view->Add( field );
|
||||||
}
|
}
|
||||||
|
|
||||||
LSET privateLayers;
|
LSET privateLayers;
|
||||||
|
@ -636,27 +622,27 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnAddField( wxCommandEvent& event )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
|
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
|
||||||
PCB_TEXT textItem( m_footprint );
|
PCB_FIELD* newField = new PCB_FIELD( m_footprint, m_fields->size() );
|
||||||
|
|
||||||
// Set active layer if legal; otherwise copy layer from previous text item
|
// Set active layer if legal; otherwise copy layer from previous text item
|
||||||
if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
|
if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
|
||||||
textItem.SetLayer( m_frame->GetActiveLayer() );
|
newField->SetLayer( m_frame->GetActiveLayer() );
|
||||||
else
|
else
|
||||||
textItem.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
|
newField->SetLayer( m_fields->at( m_fields->size() - 1 )->GetLayer() );
|
||||||
|
|
||||||
textItem.SetTextSize( dsnSettings.GetTextSize( textItem.GetLayer() ) );
|
newField->SetTextSize( dsnSettings.GetTextSize( newField->GetLayer() ) );
|
||||||
textItem.SetTextThickness( dsnSettings.GetTextThickness( textItem.GetLayer() ) );
|
newField->SetTextThickness( dsnSettings.GetTextThickness( newField->GetLayer() ) );
|
||||||
textItem.SetItalic( dsnSettings.GetTextItalic( textItem.GetLayer() ) );
|
newField->SetItalic( dsnSettings.GetTextItalic( newField->GetLayer() ) );
|
||||||
|
|
||||||
m_texts->push_back( textItem );
|
m_fields->push_back( newField );
|
||||||
|
|
||||||
// notify the grid
|
// notify the grid
|
||||||
wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
|
||||||
m_itemsGrid->ProcessTableMessage( msg );
|
m_itemsGrid->ProcessTableMessage( msg );
|
||||||
|
|
||||||
m_itemsGrid->SetFocus();
|
m_itemsGrid->SetFocus();
|
||||||
m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
|
m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
|
||||||
m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
|
m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
|
||||||
|
|
||||||
m_itemsGrid->EnableCellEditControl( true );
|
m_itemsGrid->EnableCellEditControl( true );
|
||||||
m_itemsGrid->ShowCellEditControl();
|
m_itemsGrid->ShowCellEditControl();
|
||||||
|
@ -678,22 +664,26 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnDeleteField( wxCommandEvent& event
|
||||||
|
|
||||||
for( int row : selectedRows )
|
for( int row : selectedRows )
|
||||||
{
|
{
|
||||||
if( row < 2 )
|
if( row < MANDATORY_FIELDS )
|
||||||
{
|
{
|
||||||
DisplayError( nullptr, _( "Reference and value are mandatory." ) );
|
DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
|
||||||
|
MANDATORY_FIELDS ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
|
||||||
|
m_itemsGrid->ClearSelection();
|
||||||
|
|
||||||
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
||||||
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
||||||
|
|
||||||
for( int row : selectedRows )
|
for( int row : selectedRows )
|
||||||
{
|
{
|
||||||
m_texts->erase( m_texts->begin() + row );
|
m_fields->erase( m_fields->begin() + row );
|
||||||
|
|
||||||
// notify the grid
|
// notify the grid
|
||||||
wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
|
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
|
||||||
m_itemsGrid->ProcessTableMessage( msg );
|
m_itemsGrid->ProcessTableMessage( msg );
|
||||||
|
|
||||||
if( m_itemsGrid->GetNumberRows() > 0 )
|
if( m_itemsGrid->GetNumberRows() > 0 )
|
||||||
|
@ -800,11 +790,16 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::adjustGridColumns()
|
||||||
|
|
||||||
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
||||||
|
|
||||||
for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
|
for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
{
|
||||||
|
if( i == 1 )
|
||||||
|
continue;
|
||||||
|
|
||||||
m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
|
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||||
m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
}
|
||||||
|
|
||||||
|
m_itemsGrid->SetColSize(
|
||||||
|
1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||||
|
|
||||||
// Update the width private layers grid
|
// Update the width private layers grid
|
||||||
m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
|
m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
|
||||||
|
@ -860,7 +855,9 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
|
||||||
m_delayedFocusGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
|
m_delayedFocusGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
|
||||||
m_delayedFocusGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
|
m_delayedFocusGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
|
||||||
|
|
||||||
m_delayedFocusGrid->EnableCellEditControl( true );
|
if( !( m_delayedFocusColumn == 0 && m_delayedFocusRow < MANDATORY_FIELDS ) )
|
||||||
|
m_delayedFocusGrid->EnableCellEditControl( true );
|
||||||
|
|
||||||
m_delayedFocusGrid->ShowCellEditControl();
|
m_delayedFocusGrid->ShowCellEditControl();
|
||||||
|
|
||||||
m_delayedFocusGrid = nullptr;
|
m_delayedFocusGrid = nullptr;
|
||||||
|
|
|
@ -102,7 +102,7 @@ private:
|
||||||
|
|
||||||
static NOTEBOOK_PAGES m_page; // remember the last open page during session
|
static NOTEBOOK_PAGES m_page; // remember the last open page during session
|
||||||
|
|
||||||
FP_TEXT_GRID_TABLE* m_texts;
|
FP_TEXT_GRID_TABLE* m_fields;
|
||||||
PRIVATE_LAYERS_GRID_TABLE* m_privateLayers;
|
PRIVATE_LAYERS_GRID_TABLE* m_privateLayers;
|
||||||
|
|
||||||
UNIT_BINDER m_netClearance;
|
UNIT_BINDER m_netClearance;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <pcb_dimension.h>
|
#include <pcb_dimension.h>
|
||||||
#include <pcb_bitmap.h>
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
|
#include <pcb_field.h>
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <zone.h>
|
#include <zone.h>
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
|
@ -76,9 +77,31 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
|
||||||
m_zoneConnection = ZONE_CONNECTION::INHERITED;
|
m_zoneConnection = ZONE_CONNECTION::INHERITED;
|
||||||
m_fileFormatVersionAtLoad = 0;
|
m_fileFormatVersionAtLoad = 0;
|
||||||
|
|
||||||
// These are special and mandatory text fields
|
// These are the mandatory fields for the editor to work
|
||||||
m_reference = new PCB_TEXT( this, PCB_TEXT::TEXT_is_REFERENCE );
|
for( int i = 0; i < MANDATORY_FIELDS; i++ )
|
||||||
m_value = new PCB_TEXT( this, PCB_TEXT::TEXT_is_VALUE );
|
{
|
||||||
|
PCB_FIELD* field = AddField( new PCB_FIELD( this, i ) );
|
||||||
|
|
||||||
|
// Style according to the board settings if we have them
|
||||||
|
if( parent )
|
||||||
|
ApplyDefaultFieldSettings( *parent );
|
||||||
|
|
||||||
|
switch( i )
|
||||||
|
{
|
||||||
|
case REFERENCE_FIELD:
|
||||||
|
field->SetLayer( F_SilkS );
|
||||||
|
field->SetVisible( true );
|
||||||
|
break;
|
||||||
|
case VALUE_FIELD:
|
||||||
|
field->SetLayer( F_Fab );
|
||||||
|
field->SetVisible( true );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
field->SetLayer( F_Fab );
|
||||||
|
field->SetVisible( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_3D_Drawings.clear();
|
m_3D_Drawings.clear();
|
||||||
}
|
}
|
||||||
|
@ -115,14 +138,13 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
|
||||||
|
|
||||||
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
||||||
|
|
||||||
// Copy reference and value.
|
// Copy fields
|
||||||
m_reference = new PCB_TEXT( *aFootprint.m_reference );
|
for( PCB_FIELD* field : aFootprint.Fields() )
|
||||||
m_reference->SetParent( this );
|
{
|
||||||
ptrMap[ aFootprint.m_reference ] = m_reference;
|
PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
|
||||||
|
ptrMap[field] = newField;
|
||||||
m_value = new PCB_TEXT( *aFootprint.m_value );
|
Add( newField, ADD_MODE::APPEND ); // Append to ensure indexes are identical
|
||||||
m_value->SetParent( this );
|
}
|
||||||
ptrMap[ aFootprint.m_value ] = m_value;
|
|
||||||
|
|
||||||
// Copy pads
|
// Copy pads
|
||||||
for( PAD* pad : aFootprint.Pads() )
|
for( PAD* pad : aFootprint.Pads() )
|
||||||
|
@ -180,7 +202,6 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
|
||||||
m_3D_Drawings = aFootprint.m_3D_Drawings;
|
m_3D_Drawings = aFootprint.m_3D_Drawings;
|
||||||
m_doc = aFootprint.m_doc;
|
m_doc = aFootprint.m_doc;
|
||||||
m_keywords = aFootprint.m_keywords;
|
m_keywords = aFootprint.m_keywords;
|
||||||
m_fields = aFootprint.m_fields;
|
|
||||||
m_privateLayers = aFootprint.m_privateLayers;
|
m_privateLayers = aFootprint.m_privateLayers;
|
||||||
|
|
||||||
m_arflag = 0;
|
m_arflag = 0;
|
||||||
|
@ -207,10 +228,13 @@ FOOTPRINT::~FOOTPRINT()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the owned elements
|
// Clean up the owned elements
|
||||||
delete m_reference;
|
|
||||||
delete m_value;
|
|
||||||
delete m_initial_comments;
|
delete m_initial_comments;
|
||||||
|
|
||||||
|
for( PCB_FIELD* f : m_fields )
|
||||||
|
delete f;
|
||||||
|
|
||||||
|
m_fields.clear();
|
||||||
|
|
||||||
for( PAD* p : m_pads )
|
for( PAD* p : m_pads )
|
||||||
delete p;
|
delete p;
|
||||||
|
|
||||||
|
@ -236,13 +260,115 @@ FOOTPRINT::~FOOTPRINT()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_FIELD* FOOTPRINT::GetField( MANDATORY_FIELD_T aFieldType )
|
||||||
|
{
|
||||||
|
return m_fields[aFieldType];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const PCB_FIELD* FOOTPRINT::GetField( MANDATORY_FIELD_T aFieldType ) const
|
||||||
|
{
|
||||||
|
return m_fields[aFieldType];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_FIELD* FOOTPRINT::GetFieldById( int aFieldId )
|
||||||
|
{
|
||||||
|
for( size_t ii = 0; ii < m_fields.size(); ++ii )
|
||||||
|
{
|
||||||
|
if( m_fields[ii]->GetId() == aFieldId )
|
||||||
|
return m_fields[ii];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FOOTPRINT::HasFieldByName( const wxString& aFieldName ) const
|
||||||
|
{
|
||||||
|
for( size_t ii = 0; ii < m_fields.size(); ++ii )
|
||||||
|
{
|
||||||
|
if( m_fields[ii]->GetCanonicalName() == aFieldName )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PCB_FIELD* FOOTPRINT::GetFieldByName( const wxString& aFieldName )
|
||||||
|
{
|
||||||
|
for( size_t ii = 0; ii < m_fields.size(); ++ii )
|
||||||
|
{
|
||||||
|
if( m_fields[ii]->GetName() == aFieldName )
|
||||||
|
return m_fields[ii];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString FOOTPRINT::GetFieldText( const wxString& aFieldName ) const
|
||||||
|
{
|
||||||
|
for( const PCB_FIELD* field : m_fields )
|
||||||
|
{
|
||||||
|
if( aFieldName == field->GetName() || aFieldName == field->GetCanonicalName() )
|
||||||
|
return field->GetText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FOOTPRINT::GetFields( std::vector<PCB_FIELD*>& aVector, bool aVisibleOnly )
|
||||||
|
{
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
{
|
||||||
|
if( aVisibleOnly )
|
||||||
|
{
|
||||||
|
if( !field->IsVisible() || field->GetText().IsEmpty() )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aVector.push_back( field );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_FIELD* FOOTPRINT::AddField( PCB_FIELD* aField )
|
||||||
|
{
|
||||||
|
int newNdx = m_fields.size();
|
||||||
|
|
||||||
|
m_fields.push_back( aField );
|
||||||
|
return m_fields[newNdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FOOTPRINT::RemoveField( const wxString& aFieldName )
|
||||||
|
{
|
||||||
|
for( unsigned i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
|
||||||
|
{
|
||||||
|
if( aFieldName == m_fields[i]->GetName( false ) )
|
||||||
|
{
|
||||||
|
m_fields.erase( m_fields.begin() + i );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FOOTPRINT::ApplyDefaultFieldSettings( BOARD& board )
|
||||||
|
{
|
||||||
|
for( PCB_FIELD* f : m_fields )
|
||||||
|
f->StyleFromSettings( board.GetDesignSettings() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FOOTPRINT::FixUuids()
|
bool FOOTPRINT::FixUuids()
|
||||||
{
|
{
|
||||||
// replace null UUIDs if any by a valid uuid
|
// replace null UUIDs if any by a valid uuid
|
||||||
std::vector< BOARD_ITEM* > item_list;
|
std::vector< BOARD_ITEM* > item_list;
|
||||||
|
|
||||||
item_list.push_back( m_reference );
|
for( PCB_FIELD* field : m_fields )
|
||||||
item_list.push_back( m_value );
|
item_list.push_back( field );
|
||||||
|
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
item_list.push_back( pad );
|
item_list.push_back( pad );
|
||||||
|
@ -303,12 +429,11 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
|
||||||
m_zoneConnection = aOther.m_zoneConnection;
|
m_zoneConnection = aOther.m_zoneConnection;
|
||||||
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
||||||
|
|
||||||
// Move reference and value
|
// Move the fields
|
||||||
m_reference = aOther.m_reference;
|
m_fields.clear();
|
||||||
m_reference->SetParent( this );
|
|
||||||
m_value = aOther.m_value;
|
|
||||||
m_value->SetParent( this );
|
|
||||||
|
|
||||||
|
for( PCB_FIELD* field : aOther.Fields() )
|
||||||
|
Add( field );
|
||||||
|
|
||||||
// Move the pads
|
// Move the pads
|
||||||
m_pads.clear();
|
m_pads.clear();
|
||||||
|
@ -354,17 +479,15 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
|
||||||
m_3D_Drawings = aOther.m_3D_Drawings;
|
m_3D_Drawings = aOther.m_3D_Drawings;
|
||||||
m_doc = aOther.m_doc;
|
m_doc = aOther.m_doc;
|
||||||
m_keywords = aOther.m_keywords;
|
m_keywords = aOther.m_keywords;
|
||||||
m_fields = aOther.m_fields;
|
|
||||||
m_privateLayers = aOther.m_privateLayers;
|
m_privateLayers = aOther.m_privateLayers;
|
||||||
|
|
||||||
m_initial_comments = aOther.m_initial_comments;
|
m_initial_comments = aOther.m_initial_comments;
|
||||||
|
|
||||||
// Clear the other item's containers since this is a move
|
// Clear the other item's containers since this is a move
|
||||||
|
aOther.Fields().clear();
|
||||||
aOther.Pads().clear();
|
aOther.Pads().clear();
|
||||||
aOther.Zones().clear();
|
aOther.Zones().clear();
|
||||||
aOther.GraphicalItems().clear();
|
aOther.GraphicalItems().clear();
|
||||||
aOther.m_value = nullptr;
|
|
||||||
aOther.m_reference = nullptr;
|
|
||||||
aOther.m_initial_comments = nullptr;
|
aOther.m_initial_comments = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -400,14 +523,18 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
|
||||||
m_zoneConnection = aOther.m_zoneConnection;
|
m_zoneConnection = aOther.m_zoneConnection;
|
||||||
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
||||||
|
|
||||||
// Copy reference and value
|
|
||||||
*m_reference = *aOther.m_reference;
|
|
||||||
m_reference->SetParent( this );
|
|
||||||
*m_value = *aOther.m_value;
|
|
||||||
m_value->SetParent( this );
|
|
||||||
|
|
||||||
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
||||||
|
|
||||||
|
// Copy fields
|
||||||
|
m_fields.clear();
|
||||||
|
|
||||||
|
for( PCB_FIELD* field : aOther.GetFields() )
|
||||||
|
{
|
||||||
|
PCB_FIELD* newField = new PCB_FIELD( *field );
|
||||||
|
ptrMap[field] = newField;
|
||||||
|
Add( newField );
|
||||||
|
}
|
||||||
|
|
||||||
// Copy pads
|
// Copy pads
|
||||||
m_pads.clear();
|
m_pads.clear();
|
||||||
|
|
||||||
|
@ -462,7 +589,6 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
|
||||||
m_3D_Drawings = aOther.m_3D_Drawings;
|
m_3D_Drawings = aOther.m_3D_Drawings;
|
||||||
m_doc = aOther.m_doc;
|
m_doc = aOther.m_doc;
|
||||||
m_keywords = aOther.m_keywords;
|
m_keywords = aOther.m_keywords;
|
||||||
m_fields = aOther.m_fields;
|
|
||||||
m_privateLayers = aOther.m_privateLayers;
|
m_privateLayers = aOther.m_privateLayers;
|
||||||
|
|
||||||
m_initial_comments = aOther.m_initial_comments ?
|
m_initial_comments = aOther.m_initial_comments ?
|
||||||
|
@ -498,12 +624,12 @@ bool FOOTPRINT::ResolveTextVar( wxString* token, int aDepth ) const
|
||||||
|
|
||||||
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
||||||
{
|
{
|
||||||
*token = m_reference->GetShownText( false, aDepth + 1 );
|
*token = Reference().GetShownText( false, aDepth + 1 );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if( token->IsSameAs( wxT( "VALUE" ) ) )
|
else if( token->IsSameAs( wxT( "VALUE" ) ) )
|
||||||
{
|
{
|
||||||
*token = m_value->GetShownText( false, aDepth + 1 );
|
*token = Value().GetShownText( false, aDepth + 1 );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if( token->IsSameAs( wxT( "LAYER" ) ) )
|
else if( token->IsSameAs( wxT( "LAYER" ) ) )
|
||||||
|
@ -543,9 +669,9 @@ bool FOOTPRINT::ResolveTextVar( wxString* token, int aDepth ) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( m_fields.count( *token ) )
|
else if( HasFieldByName( *token ) )
|
||||||
{
|
{
|
||||||
*token = m_fields.at( *token );
|
*token = GetFieldText( *token );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,8 +696,22 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv
|
||||||
switch( aBoardItem->Type() )
|
switch( aBoardItem->Type() )
|
||||||
{
|
{
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
// Only user text can be added this way.
|
|
||||||
wxASSERT( static_cast<PCB_TEXT*>( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS );
|
if( dynamic_cast<PCB_FIELD*>( aBoardItem ) != nullptr )
|
||||||
|
{
|
||||||
|
if( aMode == ADD_MODE::APPEND )
|
||||||
|
m_fields.push_back( static_cast<PCB_FIELD*>( aBoardItem ) );
|
||||||
|
else
|
||||||
|
m_fields.push_front( static_cast<PCB_FIELD*>( aBoardItem ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only user text can be added this way.
|
||||||
|
wxASSERT( static_cast<PCB_TEXT*>( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS );
|
||||||
|
}
|
||||||
|
|
||||||
KI_FALLTHROUGH;
|
KI_FALLTHROUGH;
|
||||||
|
|
||||||
case PCB_DIM_ALIGNED_T:
|
case PCB_DIM_ALIGNED_T:
|
||||||
|
@ -633,6 +773,14 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode )
|
||||||
// Only user text can be removed this way.
|
// Only user text can be removed this way.
|
||||||
wxCHECK_RET( static_cast<PCB_TEXT*>( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS,
|
wxCHECK_RET( static_cast<PCB_TEXT*>( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS,
|
||||||
wxT( "Please report this bug: Invalid remove operation on required text" ) );
|
wxT( "Please report this bug: Invalid remove operation on required text" ) );
|
||||||
|
for( auto it = m_fields.begin(); it != m_fields.end(); ++it )
|
||||||
|
{
|
||||||
|
if( *it == aBoardItem )
|
||||||
|
{
|
||||||
|
m_fields.erase( it );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
KI_FALLTHROUGH;
|
KI_FALLTHROUGH;
|
||||||
|
|
||||||
case PCB_DIM_ALIGNED_T:
|
case PCB_DIM_ALIGNED_T:
|
||||||
|
@ -890,28 +1038,28 @@ const BOX2I FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisible
|
||||||
// not being present in the current PCB stackup. Values, references, and all
|
// not being present in the current PCB stackup. Values, references, and all
|
||||||
// footprint text can also be turned off via the GAL meta-layers, so the 2nd and
|
// footprint text can also be turned off via the GAL meta-layers, so the 2nd and
|
||||||
// 3rd "&&" conditionals handle that.
|
// 3rd "&&" conditionals handle that.
|
||||||
valueLayerIsVisible = board->IsLayerVisible( m_value->GetLayer() )
|
valueLayerIsVisible = board->IsLayerVisible( Value().GetLayer() )
|
||||||
&& board->IsElementVisible( LAYER_MOD_VALUES )
|
&& board->IsElementVisible( LAYER_MOD_VALUES )
|
||||||
&& board->IsElementVisible( LAYER_MOD_TEXT );
|
&& board->IsElementVisible( LAYER_MOD_TEXT );
|
||||||
|
|
||||||
refLayerIsVisible = board->IsLayerVisible( m_reference->GetLayer() )
|
refLayerIsVisible = board->IsLayerVisible( Reference().GetLayer() )
|
||||||
&& board->IsElementVisible( LAYER_MOD_REFERENCES )
|
&& board->IsElementVisible( LAYER_MOD_REFERENCES )
|
||||||
&& board->IsElementVisible( LAYER_MOD_TEXT );
|
&& board->IsElementVisible( LAYER_MOD_TEXT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( ( m_value->IsVisible() && valueLayerIsVisible )
|
if( ( Value().IsVisible() && valueLayerIsVisible )
|
||||||
|| aIncludeInvisibleText
|
|| aIncludeInvisibleText
|
||||||
|| noDrawItems )
|
|| noDrawItems )
|
||||||
{
|
{
|
||||||
bbox.Merge( m_value->GetBoundingBox() );
|
bbox.Merge( Value().GetBoundingBox() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( m_reference->IsVisible() && refLayerIsVisible )
|
if( ( Reference().IsVisible() && refLayerIsVisible )
|
||||||
|| aIncludeInvisibleText
|
|| aIncludeInvisibleText
|
||||||
|| noDrawItems )
|
|| noDrawItems )
|
||||||
{
|
{
|
||||||
bbox.Merge( m_reference->GetBoundingBox() );
|
bbox.Merge( Reference().GetBoundingBox() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,8 +1173,8 @@ void FOOTPRINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
||||||
wxString msg, msg2;
|
wxString msg, msg2;
|
||||||
|
|
||||||
// Don't use GetShownText(); we want to see the variable references here
|
// Don't use GetShownText(); we want to see the variable references here
|
||||||
aList.emplace_back( UnescapeString( m_reference->GetText() ),
|
aList.emplace_back( UnescapeString( Reference().GetText() ),
|
||||||
UnescapeString( m_value->GetText() ) );
|
UnescapeString( Value().GetText() ) );
|
||||||
|
|
||||||
if( aFrame->IsType( FRAME_FOOTPRINT_VIEWER )
|
if( aFrame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||||
|| aFrame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
|| aFrame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||||
|
@ -1112,6 +1260,12 @@ bool FOOTPRINT::IsOnLayer( PCB_LAYER_ID aLayer, bool aIncludeCourtyards ) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
{
|
||||||
|
if( !field->IsOnLayer( aLayer ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_drawings )
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
{
|
{
|
||||||
if( !item->IsOnLayer( aLayer ) )
|
if( !item->IsOnLayer( aLayer ) )
|
||||||
|
@ -1161,6 +1315,12 @@ bool FOOTPRINT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
{
|
||||||
|
if( field->HitTest( arect, false, 0 ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for( ZONE* zone : m_zones )
|
for( ZONE* zone : m_zones )
|
||||||
{
|
{
|
||||||
if( zone->HitTest( arect, false, 0 ) )
|
if( zone->HitTest( arect, false, 0 ) )
|
||||||
|
@ -1319,10 +1479,10 @@ INSPECT_RESULT FOOTPRINT::Visit( INSPECTOR inspector, void* testData,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
if( inspector( m_reference, testData ) == INSPECT_RESULT::QUIT )
|
if( inspector( &Reference(), testData ) == INSPECT_RESULT::QUIT )
|
||||||
return INSPECT_RESULT::QUIT;
|
return INSPECT_RESULT::QUIT;
|
||||||
|
|
||||||
if( inspector( m_value, testData ) == INSPECT_RESULT::QUIT )
|
if( inspector( &Value(), testData ) == INSPECT_RESULT::QUIT )
|
||||||
return INSPECT_RESULT::QUIT;
|
return INSPECT_RESULT::QUIT;
|
||||||
|
|
||||||
// Intentionally fall through since m_Drawings can hold PCB_TEXT_T also
|
// Intentionally fall through since m_Drawings can hold PCB_TEXT_T also
|
||||||
|
@ -1393,6 +1553,9 @@ void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM*)>& aFuncti
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
aFunction( static_cast<PCB_FIELD*>( field ) );
|
||||||
|
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
aFunction( static_cast<BOARD_ITEM*>( pad ) );
|
aFunction( static_cast<BOARD_ITEM*>( pad ) );
|
||||||
|
|
||||||
|
@ -1404,9 +1567,6 @@ void FOOTPRINT::RunOnChildren( const std::function<void ( BOARD_ITEM*)>& aFuncti
|
||||||
|
|
||||||
for( BOARD_ITEM* drawing : m_drawings )
|
for( BOARD_ITEM* drawing : m_drawings )
|
||||||
aFunction( static_cast<BOARD_ITEM*>( drawing ) );
|
aFunction( static_cast<BOARD_ITEM*>( drawing ) );
|
||||||
|
|
||||||
aFunction( static_cast<BOARD_ITEM*>( m_reference ) );
|
|
||||||
aFunction( static_cast<BOARD_ITEM*>( m_value ) );
|
|
||||||
}
|
}
|
||||||
catch( std::bad_function_call& )
|
catch( std::bad_function_call& )
|
||||||
{
|
{
|
||||||
|
@ -1567,8 +1727,8 @@ void FOOTPRINT::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
|
||||||
SetPosition( newpos );
|
SetPosition( newpos );
|
||||||
SetOrientation( newOrientation );
|
SetOrientation( newOrientation );
|
||||||
|
|
||||||
m_reference->KeepUpright( orientation, newOrientation );
|
for( PCB_FIELD* field : m_fields )
|
||||||
m_value->KeepUpright( orientation, newOrientation );
|
field->KeepUpright( orientation, newOrientation );
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_drawings )
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
{
|
{
|
||||||
|
@ -1619,6 +1779,10 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||||
newOrientation.Normalize180();
|
newOrientation.Normalize180();
|
||||||
m_orient = ANGLE_0;
|
m_orient = ANGLE_0;
|
||||||
|
|
||||||
|
// Mirror fields to other side of board.
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
field->Flip( m_pos, false );
|
||||||
|
|
||||||
// Mirror pads to other side of board.
|
// Mirror pads to other side of board.
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
pad->Flip( m_pos, false );
|
pad->Flip( m_pos, false );
|
||||||
|
@ -1630,10 +1794,6 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||||
for( ZONE* zone : m_zones )
|
for( ZONE* zone : m_zones )
|
||||||
zone->Flip( m_pos, false );
|
zone->Flip( m_pos, false );
|
||||||
|
|
||||||
// Mirror reference and value.
|
|
||||||
m_reference->Flip( m_pos, false );
|
|
||||||
m_value->Flip( m_pos, false );
|
|
||||||
|
|
||||||
// Reverse mirror footprint graphics and texts.
|
// Reverse mirror footprint graphics and texts.
|
||||||
for( BOARD_ITEM* item : m_drawings )
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
item->Flip( m_pos, false );
|
item->Flip( m_pos, false );
|
||||||
|
@ -1659,8 +1819,8 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos )
|
||||||
|
|
||||||
m_pos += delta;
|
m_pos += delta;
|
||||||
|
|
||||||
m_reference->EDA_TEXT::Offset( delta );
|
for( PCB_FIELD* field : m_fields )
|
||||||
m_value->EDA_TEXT::Offset( delta );
|
field->EDA_TEXT::Offset( delta );
|
||||||
|
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
pad->SetPosition( pad->GetPosition() + delta );
|
pad->SetPosition( pad->GetPosition() + delta );
|
||||||
|
@ -1695,9 +1855,9 @@ void FOOTPRINT::MoveAnchorPosition( const VECTOR2I& aMoveVector )
|
||||||
VECTOR2I moveVector = aMoveVector;
|
VECTOR2I moveVector = aMoveVector;
|
||||||
RotatePoint( moveVector, -GetOrientation() );
|
RotatePoint( moveVector, -GetOrientation() );
|
||||||
|
|
||||||
// Update of the reference and value.
|
// Update field local coordinates
|
||||||
m_reference->Move( moveVector );
|
for( PCB_FIELD* field : m_fields )
|
||||||
m_value->Move( moveVector );
|
field->Move( moveVector );
|
||||||
|
|
||||||
// Update the pad local coordinates.
|
// Update the pad local coordinates.
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
|
@ -1732,16 +1892,15 @@ void FOOTPRINT::SetOrientation( const EDA_ANGLE& aNewAngle )
|
||||||
m_orient = aNewAngle;
|
m_orient = aNewAngle;
|
||||||
m_orient.Normalize180();
|
m_orient.Normalize180();
|
||||||
|
|
||||||
|
for( PCB_FIELD* field : m_fields )
|
||||||
|
field->Rotate( GetPosition(), angleChange );
|
||||||
|
|
||||||
for( PAD* pad : m_pads )
|
for( PAD* pad : m_pads )
|
||||||
pad->Rotate( GetPosition(), angleChange );
|
pad->Rotate( GetPosition(), angleChange );
|
||||||
|
|
||||||
for( ZONE* zone : m_zones )
|
for( ZONE* zone : m_zones )
|
||||||
zone->Rotate( GetPosition(), angleChange );
|
zone->Rotate( GetPosition(), angleChange );
|
||||||
|
|
||||||
// Update of the reference and value.
|
|
||||||
m_reference->Rotate( GetPosition(), angleChange );
|
|
||||||
m_value->Rotate( GetPosition(), angleChange );
|
|
||||||
|
|
||||||
for( BOARD_ITEM* item : m_drawings )
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
item->Rotate( GetPosition(), angleChange );
|
item->Rotate( GetPosition(), angleChange );
|
||||||
|
|
||||||
|
@ -2436,11 +2595,11 @@ void FOOTPRINT::CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
|
||||||
copperItems.push_back( zone );
|
copperItems.push_back( zone );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_reference->IsOnCopperLayer() )
|
for( PCB_FIELD* field : m_fields )
|
||||||
copperItems.push_back( m_reference );
|
{
|
||||||
|
if( field->IsOnCopperLayer() )
|
||||||
if( m_value->IsOnCopperLayer() )
|
copperItems.push_back( field );
|
||||||
copperItems.push_back( m_value );
|
}
|
||||||
|
|
||||||
for( PCB_LAYER_ID layer : { F_Cu, In1_Cu, B_Cu } )
|
for( PCB_LAYER_ID layer : { F_Cu, In1_Cu, B_Cu } )
|
||||||
{
|
{
|
||||||
|
@ -2719,7 +2878,7 @@ void FOOTPRINT::TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_I
|
||||||
bool aIncludeText, bool aIncludeShapes,
|
bool aIncludeText, bool aIncludeShapes,
|
||||||
bool aIncludePrivateItems ) const
|
bool aIncludePrivateItems ) const
|
||||||
{
|
{
|
||||||
std::vector<PCB_TEXT*> texts; // List of PCB_TEXTs to convert
|
std::vector<const PCB_TEXT*> texts; // List of PCB_TEXTs to convert
|
||||||
|
|
||||||
for( BOARD_ITEM* item : GraphicalItems() )
|
for( BOARD_ITEM* item : GraphicalItems() )
|
||||||
{
|
{
|
||||||
|
@ -2753,11 +2912,11 @@ void FOOTPRINT::TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_I
|
||||||
|
|
||||||
if( aIncludeText )
|
if( aIncludeText )
|
||||||
{
|
{
|
||||||
if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
|
for( const PCB_FIELD* field : m_fields )
|
||||||
texts.push_back( &Reference() );
|
{
|
||||||
|
if( field->GetLayer() == aLayer && field->IsVisible() )
|
||||||
if( Value().GetLayer() == aLayer && Value().IsVisible() )
|
texts.push_back( field );
|
||||||
texts.push_back( &Value() );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( const PCB_TEXT* text : texts )
|
for( const PCB_TEXT* text : texts )
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#include <template_fieldnames.h>
|
||||||
|
|
||||||
#include <board_item_container.h>
|
#include <board_item_container.h>
|
||||||
#include <board_item.h>
|
#include <board_item.h>
|
||||||
#include <collectors.h>
|
#include <collectors.h>
|
||||||
|
@ -38,6 +40,7 @@
|
||||||
#include <convert_shape_list_to_polygon.h>
|
#include <convert_shape_list_to_polygon.h>
|
||||||
#include <pcb_item_containers.h>
|
#include <pcb_item_containers.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
|
#include <pcb_field.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <math/vector3.h>
|
#include <math/vector3.h>
|
||||||
|
|
||||||
|
@ -169,6 +172,9 @@ public:
|
||||||
const BOX2I GetBoundingBox() const override;
|
const BOX2I GetBoundingBox() const override;
|
||||||
const BOX2I GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const;
|
const BOX2I GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const;
|
||||||
|
|
||||||
|
PCB_FIELDS& Fields() { return m_fields; }
|
||||||
|
const PCB_FIELDS& Fields() const { return m_fields; }
|
||||||
|
|
||||||
PADS& Pads() { return m_pads; }
|
PADS& Pads() { return m_pads; }
|
||||||
const PADS& Pads() const { return m_pads; }
|
const PADS& Pads() const { return m_pads; }
|
||||||
|
|
||||||
|
@ -518,19 +524,13 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return reference designator text.
|
* @return reference designator text.
|
||||||
*/
|
*/
|
||||||
const wxString& GetReference() const
|
const wxString& GetReference() const { return Reference().GetText(); }
|
||||||
{
|
|
||||||
return m_reference->GetText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aReference A reference to a wxString object containing the reference designator
|
* @param aReference A reference to a wxString object containing the reference designator
|
||||||
* text.
|
* text.
|
||||||
*/
|
*/
|
||||||
void SetReference( const wxString& aReference )
|
void SetReference( const wxString& aReference ) { Reference().SetText( aReference ); }
|
||||||
{
|
|
||||||
m_reference->SetText( aReference );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Property system doesn't like const references
|
// Property system doesn't like const references
|
||||||
wxString GetReferenceAsString() const
|
wxString GetReferenceAsString() const
|
||||||
|
@ -546,18 +546,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return the value text.
|
* @return the value text.
|
||||||
*/
|
*/
|
||||||
const wxString& GetValue() const
|
const wxString& GetValue() const { return Value().GetText(); }
|
||||||
{
|
|
||||||
return m_value->GetText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aValue A reference to a wxString object containing the value text.
|
* @param aValue A reference to a wxString object containing the value text.
|
||||||
*/
|
*/
|
||||||
void SetValue( const wxString& aValue )
|
void SetValue( const wxString& aValue ) { Value().SetText( aValue ); }
|
||||||
{
|
|
||||||
m_value->SetText( aValue );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Property system doesn't like const references
|
// Property system doesn't like const references
|
||||||
wxString GetValueAsString() const
|
wxString GetValueAsString() const
|
||||||
|
@ -566,21 +560,105 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read/write accessors:
|
/// read/write accessors:
|
||||||
PCB_TEXT& Value() { return *m_value; }
|
PCB_FIELD& Value() { return *GetField( VALUE_FIELD ); }
|
||||||
PCB_TEXT& Reference() { return *m_reference; }
|
PCB_FIELD& Reference() { return *GetField( REFERENCE_FIELD ); }
|
||||||
|
|
||||||
/// The const versions to keep the compiler happy.
|
/// The const versions to keep the compiler happy.
|
||||||
PCB_TEXT& Value() const { return *m_value; }
|
const PCB_FIELD& Value() const { return *GetField( VALUE_FIELD ); }
|
||||||
PCB_TEXT& Reference() const { return *m_reference; }
|
const PCB_FIELD& Reference() const { return *GetField( REFERENCE_FIELD ); }
|
||||||
|
|
||||||
const std::map<wxString, wxString>& GetFields() const { return m_fields; }
|
//-----<Fields>-----------------------------------------------------------
|
||||||
void SetFields( const std::map<wxString, wxString>& aFields ) { m_fields = aFields; }
|
|
||||||
const wxString& GetField( const wxString& aKey) { return m_fields[ aKey ]; }
|
/**
|
||||||
bool HasField( const wxString& aKey)
|
* Return a mandatory field in this symbol.
|
||||||
{
|
*
|
||||||
return m_fields.find( aKey ) != m_fields.end();
|
* @note If you need to fetch a user field, use GetFieldById.
|
||||||
}
|
*
|
||||||
void SetField( const wxString& aKey, const wxString& aVal ) { m_fields[ aKey ] = aVal; }
|
* @param aFieldType is one of the mandatory field types (REFERENCE_FIELD, VALUE_FIELD, etc.).
|
||||||
|
* @return is the field at \a aFieldType or NULL if the field does not exist.
|
||||||
|
*/
|
||||||
|
PCB_FIELD* GetField( MANDATORY_FIELD_T aFieldType );
|
||||||
|
const PCB_FIELD* GetField( MANDATORY_FIELD_T aFieldNdx ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a field in this symbol.
|
||||||
|
*
|
||||||
|
* @param aFieldId is the id of the field requested. Note that this id ONLY SOMETIMES equates
|
||||||
|
* to the field's position in the vector.
|
||||||
|
* @return is the field at \a aFieldType or NULL if the field does not exist.
|
||||||
|
*/
|
||||||
|
PCB_FIELD* GetFieldById( int aFieldId );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a field in this symbol.
|
||||||
|
*
|
||||||
|
* @param aFieldName is the name of the field
|
||||||
|
*
|
||||||
|
* @return is the field with \a aFieldName or NULL if the field does not exist.
|
||||||
|
*/
|
||||||
|
PCB_FIELD* GetFieldByName( const wxString& aFieldName );
|
||||||
|
|
||||||
|
bool HasFieldByName( const wxString& aFieldName ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for a field named \a aFieldName and returns text associated with this field.
|
||||||
|
*
|
||||||
|
* @param aFieldName is the name of the field
|
||||||
|
*/
|
||||||
|
wxString GetFieldText( const wxString& aFieldName ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate a std::vector with PCB_TEXTs.
|
||||||
|
*
|
||||||
|
* @param aVector is the vector to populate.
|
||||||
|
* @param aVisibleOnly is used to add only the fields that are visible and contain text.
|
||||||
|
*/
|
||||||
|
void GetFields( std::vector<PCB_FIELD*>& aVector, bool aVisibleOnly );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a vector of fields from the symbol
|
||||||
|
*/
|
||||||
|
PCB_FIELDS GetFields() { return m_fields; }
|
||||||
|
const PCB_FIELDS& GetFields() const { return m_fields; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a field to the symbol.
|
||||||
|
*
|
||||||
|
* @param aField is the field to add to this symbol.
|
||||||
|
*
|
||||||
|
* @return the newly inserted field.
|
||||||
|
*/
|
||||||
|
PCB_FIELD* AddField( PCB_FIELD* aField );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user field from the footprint.
|
||||||
|
* @param aFieldName is the user fieldName to remove. Attempts to remove a mandatory
|
||||||
|
* field or a non-existant field are silently ignored.
|
||||||
|
*/
|
||||||
|
void RemoveField( const wxString& aFieldName );
|
||||||
|
|
||||||
|
void RemoveField( PCB_FIELD* aField ) { RemoveField( aField->GetName() ); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set multiple schematic fields.
|
||||||
|
*
|
||||||
|
* @param aFields are the fields to set in this symbol.
|
||||||
|
*/
|
||||||
|
void SetFields( PCB_FIELDS aFields ) { m_fields = aFields; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of fields in this symbol.
|
||||||
|
*/
|
||||||
|
int GetFieldCount() const { return (int) m_fields.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply default board settings to the footprint field text properties.
|
||||||
|
*
|
||||||
|
* This is needed because the board settings are not available when the footprint is
|
||||||
|
* being created in the footprint library cache, and we want these fields to have
|
||||||
|
* the correct default text properties.
|
||||||
|
*/
|
||||||
|
void ApplyDefaultFieldSettings( BOARD& board );
|
||||||
|
|
||||||
bool IsBoardOnly() const { return m_attributes & FP_BOARD_ONLY; }
|
bool IsBoardOnly() const { return m_attributes & FP_BOARD_ONLY; }
|
||||||
void SetBoardOnly( bool aIsBoardOnly = true )
|
void SetBoardOnly( bool aIsBoardOnly = true )
|
||||||
|
@ -836,6 +914,7 @@ protected:
|
||||||
virtual void swapData( BOARD_ITEM* aImage ) override;
|
virtual void swapData( BOARD_ITEM* aImage ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PCB_FIELDS m_fields;
|
||||||
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
|
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
|
||||||
PADS m_pads; // PAD items, owned by pointer
|
PADS m_pads; // PAD items, owned by pointer
|
||||||
ZONES m_zones; // PCB_ZONE items, owned by pointer
|
ZONES m_zones; // PCB_ZONE items, owned by pointer
|
||||||
|
@ -843,8 +922,6 @@ private:
|
||||||
|
|
||||||
EDA_ANGLE m_orient; // Orientation
|
EDA_ANGLE m_orient; // Orientation
|
||||||
VECTOR2I m_pos; // Position of footprint on the board in internal units.
|
VECTOR2I m_pos; // Position of footprint on the board in internal units.
|
||||||
PCB_TEXT* m_reference; // Component reference designator value (U34, R18..)
|
|
||||||
PCB_TEXT* m_value; // Component value (74LS00, 22K..)
|
|
||||||
LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT.
|
LIB_ID m_fpid; // The #LIB_ID of the FOOTPRINT.
|
||||||
int m_attributes; // Flag bits (see FOOTPRINT_ATTR_T)
|
int m_attributes; // Flag bits (see FOOTPRINT_ATTR_T)
|
||||||
int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
|
int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
|
||||||
|
@ -888,7 +965,6 @@ private:
|
||||||
LSET m_privateLayers; // Layers visible only in the footprint editor
|
LSET m_privateLayers; // Layers visible only in the footprint editor
|
||||||
|
|
||||||
std::vector<FP_3DMODEL> m_3D_Drawings; // 3D models.
|
std::vector<FP_3DMODEL> m_3D_Drawings; // 3D models.
|
||||||
std::map<wxString, wxString> m_fields;
|
|
||||||
wxArrayString* m_initial_comments; // s-expression comments in the footprint,
|
wxArrayString* m_initial_comments; // s-expression comments in the footprint,
|
||||||
// lazily allocated only if needed for speed
|
// lazily allocated only if needed for speed
|
||||||
|
|
||||||
|
|
|
@ -1293,7 +1293,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, b
|
||||||
footprint->SetAttributes( footprintTranslated );
|
footprint->SetAttributes( footprintTranslated );
|
||||||
|
|
||||||
PCB_LAYER_ID txt_layer;
|
PCB_LAYER_ID txt_layer;
|
||||||
VECTOR2I default_pos;
|
VECTOR2I default_pos;
|
||||||
BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
|
BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
|
||||||
|
|
||||||
footprint->Reference().SetText( settings.m_DefaultFPTextItems[0].m_Text );
|
footprint->Reference().SetText( settings.m_DefaultFPTextItems[0].m_Text );
|
||||||
|
|
|
@ -98,7 +98,8 @@ wxString FP_TEXT_GRID_TABLE::GetColLabelValue( int aCol )
|
||||||
{
|
{
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_TEXT: return _( "Text Items" );
|
case FPT_NAME: return _( "Name" );
|
||||||
|
case FPT_VALUE: return _( "Value" );
|
||||||
case FPT_SHOWN: return _( "Show" );
|
case FPT_SHOWN: return _( "Show" );
|
||||||
case FPT_WIDTH: return _( "Width" );
|
case FPT_WIDTH: return _( "Width" );
|
||||||
case FPT_HEIGHT: return _( "Height" );
|
case FPT_HEIGHT: return _( "Height" );
|
||||||
|
@ -115,22 +116,12 @@ wxString FP_TEXT_GRID_TABLE::GetColLabelValue( int aCol )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString FP_TEXT_GRID_TABLE::GetRowLabelValue( int aRow )
|
|
||||||
{
|
|
||||||
switch( aRow )
|
|
||||||
{
|
|
||||||
case 0: return _( "Reference designator" );
|
|
||||||
case 1: return _( "Value" );
|
|
||||||
default: return wxEmptyString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool FP_TEXT_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
|
bool FP_TEXT_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
|
||||||
{
|
{
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_TEXT:
|
case FPT_NAME:
|
||||||
|
case FPT_VALUE:
|
||||||
case FPT_WIDTH:
|
case FPT_WIDTH:
|
||||||
case FPT_HEIGHT:
|
case FPT_HEIGHT:
|
||||||
case FPT_THICKNESS:
|
case FPT_THICKNESS:
|
||||||
|
@ -165,7 +156,16 @@ wxGridCellAttr* FP_TEXT_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr:
|
||||||
{
|
{
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_TEXT:
|
case FPT_NAME:
|
||||||
|
if( aRow < 2 )
|
||||||
|
{
|
||||||
|
m_readOnlyAttr->IncRef();
|
||||||
|
return m_readOnlyAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
case FPT_VALUE:
|
||||||
case FPT_WIDTH:
|
case FPT_WIDTH:
|
||||||
case FPT_HEIGHT:
|
case FPT_HEIGHT:
|
||||||
case FPT_THICKNESS:
|
case FPT_THICKNESS:
|
||||||
|
@ -198,7 +198,7 @@ wxGridCellAttr* FP_TEXT_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr:
|
||||||
wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
|
wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
|
||||||
{
|
{
|
||||||
wxGrid* grid = GetView();
|
wxGrid* grid = GetView();
|
||||||
const PCB_TEXT& text = this->at( (size_t) aRow );
|
const PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
|
|
||||||
if( grid->GetGridCursorRow() == aRow && grid->GetGridCursorCol() == aCol
|
if( grid->GetGridCursorRow() == aRow && grid->GetGridCursorCol() == aCol
|
||||||
&& grid->IsCellEditControlShown() )
|
&& grid->IsCellEditControlShown() )
|
||||||
|
@ -211,32 +211,35 @@ wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_TEXT:
|
case FPT_NAME:
|
||||||
return text.GetText();
|
return field->GetName();
|
||||||
|
|
||||||
|
case FPT_VALUE:
|
||||||
|
return field->GetText();
|
||||||
|
|
||||||
case FPT_WIDTH:
|
case FPT_WIDTH:
|
||||||
return m_frame->StringFromValue( text.GetTextWidth(), true );
|
return m_frame->StringFromValue( field->GetTextWidth(), true );
|
||||||
|
|
||||||
case FPT_HEIGHT:
|
case FPT_HEIGHT:
|
||||||
return m_frame->StringFromValue( text.GetTextHeight(), true );
|
return m_frame->StringFromValue( field->GetTextHeight(), true );
|
||||||
|
|
||||||
case FPT_THICKNESS:
|
case FPT_THICKNESS:
|
||||||
return m_frame->StringFromValue( text.GetTextThickness(), true );
|
return m_frame->StringFromValue( field->GetTextThickness(), true );
|
||||||
|
|
||||||
case FPT_LAYER:
|
case FPT_LAYER:
|
||||||
return text.GetLayerName();
|
return field->GetLayerName();
|
||||||
|
|
||||||
case FPT_ORIENTATION:
|
case FPT_ORIENTATION:
|
||||||
{
|
{
|
||||||
EDA_ANGLE angle = text.GetTextAngle() - text.GetParentFootprint()->GetOrientation();
|
EDA_ANGLE angle = field->GetTextAngle() - field->GetParentFootprint()->GetOrientation();
|
||||||
return m_frame->StringFromValue( angle, true );
|
return m_frame->StringFromValue( angle, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
case FPT_XOFFSET:
|
case FPT_XOFFSET:
|
||||||
return m_frame->StringFromValue( text.GetFPRelativePosition().x, true );
|
return m_frame->StringFromValue( field->GetFPRelativePosition().x, true );
|
||||||
|
|
||||||
case FPT_YOFFSET:
|
case FPT_YOFFSET:
|
||||||
return m_frame->StringFromValue( text.GetFPRelativePosition().y, true );
|
return m_frame->StringFromValue( field->GetFPRelativePosition().y, true );
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// we can't assert here because wxWidgets sometimes calls this without checking
|
// we can't assert here because wxWidgets sometimes calls this without checking
|
||||||
|
@ -248,14 +251,14 @@ wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
|
||||||
|
|
||||||
bool FP_TEXT_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
|
bool FP_TEXT_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_SHOWN: return text.IsVisible();
|
case FPT_SHOWN: return field->IsVisible();
|
||||||
case FPT_ITALIC: return text.IsItalic();
|
case FPT_ITALIC: return field->IsItalic();
|
||||||
case FPT_UPRIGHT: return text.IsKeepUpright();
|
case FPT_UPRIGHT: return field->IsKeepUpright();
|
||||||
case FPT_KNOCKOUT: return text.IsKnockout();
|
case FPT_KNOCKOUT: return field->IsKnockout();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
|
wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
|
||||||
|
@ -266,11 +269,11 @@ bool FP_TEXT_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
|
||||||
|
|
||||||
long FP_TEXT_GRID_TABLE::GetValueAsLong( int aRow, int aCol )
|
long FP_TEXT_GRID_TABLE::GetValueAsLong( int aRow, int aCol )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_LAYER: return text.GetLayer();
|
case FPT_LAYER: return field->GetLayer();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
|
wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
|
||||||
|
@ -281,7 +284,7 @@ long FP_TEXT_GRID_TABLE::GetValueAsLong( int aRow, int aCol )
|
||||||
|
|
||||||
void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
|
void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
VECTOR2I pos;
|
VECTOR2I pos;
|
||||||
wxString value = aValue;
|
wxString value = aValue;
|
||||||
|
|
||||||
|
@ -308,37 +311,41 @@ void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_TEXT:
|
case FPT_NAME:
|
||||||
text.SetText( value );
|
field->SetName( value );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPT_VALUE:
|
||||||
|
field->SetText( value );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_WIDTH:
|
case FPT_WIDTH:
|
||||||
text.SetTextWidth( m_frame->ValueFromString( value ) );
|
field->SetTextWidth( m_frame->ValueFromString( value ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_HEIGHT:
|
case FPT_HEIGHT:
|
||||||
text.SetTextHeight( m_frame->ValueFromString( value ) );
|
field->SetTextHeight( m_frame->ValueFromString( value ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_THICKNESS:
|
case FPT_THICKNESS:
|
||||||
text.SetTextThickness( m_frame->ValueFromString( value ) );
|
field->SetTextThickness( m_frame->ValueFromString( value ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_ORIENTATION:
|
case FPT_ORIENTATION:
|
||||||
text.SetTextAngle( m_frame->AngleValueFromString( value )
|
field->SetTextAngle( m_frame->AngleValueFromString( value )
|
||||||
+ text.GetParentFootprint()->GetOrientation() );
|
+ field->GetParentFootprint()->GetOrientation() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_XOFFSET:
|
case FPT_XOFFSET:
|
||||||
case FPT_YOFFSET:
|
case FPT_YOFFSET:
|
||||||
pos = text.GetFPRelativePosition();
|
pos = field->GetFPRelativePosition();
|
||||||
|
|
||||||
if( aCol == FPT_XOFFSET )
|
if( aCol == FPT_XOFFSET )
|
||||||
pos.x = m_frame->ValueFromString( value );
|
pos.x = m_frame->ValueFromString( value );
|
||||||
else
|
else
|
||||||
pos.y = m_frame->ValueFromString( value );
|
pos.y = m_frame->ValueFromString( value );
|
||||||
|
|
||||||
text.SetFPRelativePosition( pos );
|
field->SetFPRelativePosition( pos );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -352,24 +359,24 @@ void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
|
||||||
|
|
||||||
void FP_TEXT_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
|
void FP_TEXT_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_SHOWN:
|
case FPT_SHOWN:
|
||||||
text.SetVisible( aValue );
|
field->SetVisible( aValue );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_ITALIC:
|
case FPT_ITALIC:
|
||||||
text.SetItalic( aValue );
|
field->SetItalic( aValue );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_UPRIGHT:
|
case FPT_UPRIGHT:
|
||||||
text.SetKeepUpright( aValue );
|
field->SetKeepUpright( aValue );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPT_KNOCKOUT:
|
case FPT_KNOCKOUT:
|
||||||
text.SetIsKnockout( aValue );
|
field->SetIsKnockout( aValue );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -381,13 +388,13 @@ void FP_TEXT_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
|
||||||
|
|
||||||
void FP_TEXT_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
|
void FP_TEXT_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
|
||||||
{
|
{
|
||||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||||
|
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case FPT_LAYER:
|
case FPT_LAYER:
|
||||||
text.SetLayer( ToLAYER_ID( (int) aValue ) );
|
field->SetLayer( ToLAYER_ID( (int) aValue ) );
|
||||||
text.SetMirrored( IsBackLayer( text.GetLayer() ) );
|
field->SetMirrored( IsBackLayer( field->GetLayer() ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -26,14 +26,15 @@
|
||||||
|
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
#include <grid_tricks.h>
|
#include <grid_tricks.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_field.h>
|
||||||
|
|
||||||
|
|
||||||
class PCB_BASE_FRAME;
|
class PCB_BASE_FRAME;
|
||||||
|
|
||||||
enum FP_TEXT_COL_ORDER
|
enum FP_TEXT_COL_ORDER
|
||||||
{
|
{
|
||||||
FPT_TEXT,
|
FPT_NAME,
|
||||||
|
FPT_VALUE,
|
||||||
FPT_SHOWN,
|
FPT_SHOWN,
|
||||||
FPT_WIDTH,
|
FPT_WIDTH,
|
||||||
FPT_HEIGHT,
|
FPT_HEIGHT,
|
||||||
|
@ -50,7 +51,7 @@ enum FP_TEXT_COL_ORDER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FP_TEXT_GRID_TABLE : public wxGridTableBase, public std::vector<PCB_TEXT>
|
class FP_TEXT_GRID_TABLE : public wxGridTableBase, public std::vector<PCB_FIELD*>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FP_TEXT_GRID_TABLE( PCB_BASE_FRAME* aFrame );
|
FP_TEXT_GRID_TABLE( PCB_BASE_FRAME* aFrame );
|
||||||
|
@ -60,7 +61,6 @@ public:
|
||||||
int GetNumberCols() override { return FPT_COUNT; }
|
int GetNumberCols() override { return FPT_COUNT; }
|
||||||
|
|
||||||
wxString GetColLabelValue( int aCol ) override;
|
wxString GetColLabelValue( int aCol ) override;
|
||||||
wxString GetRowLabelValue( int aRow ) override;
|
|
||||||
|
|
||||||
bool IsEmptyCell( int row, int col ) override
|
bool IsEmptyCell( int row, int col ) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -349,11 +349,16 @@ FOOTPRINT* PCB_BASE_FRAME::loadFootprint( const LIB_ID& aFootprintId )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the footprint is found, clear all net info to be sure there are no broken links to
|
|
||||||
// any netinfo list (should be not needed, but it can be edited from the footprint editor )
|
|
||||||
if( footprint )
|
if( footprint )
|
||||||
|
{
|
||||||
|
// If the footprint is found, clear all net info to be sure there are no broken links to
|
||||||
|
// any netinfo list (should be not needed, but it can be edited from the footprint editor )
|
||||||
footprint->ClearAllNets();
|
footprint->ClearAllNets();
|
||||||
|
|
||||||
|
if( m_pcb )
|
||||||
|
footprint->ApplyDefaultFieldSettings( *m_pcb );
|
||||||
|
}
|
||||||
|
|
||||||
return footprint;
|
return footprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <base_units.h>
|
#include <base_units.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
#include <board_design_settings.h>
|
||||||
#include <netinfo.h>
|
#include <netinfo.h>
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
|
@ -343,7 +344,11 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
||||||
m_reporter->Report( msg, RPT_SEVERITY_ACTION );
|
m_reporter->Report( msg, RPT_SEVERITY_ACTION );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aPcbFootprint->GetFields() != aNetlistComponent->GetFields() )
|
std::map<wxString, wxString> fpFieldsAsMap;
|
||||||
|
for( PCB_FIELD* field : aPcbFootprint->GetFields() )
|
||||||
|
fpFieldsAsMap[field->GetName()] = field->GetText();
|
||||||
|
|
||||||
|
if( fpFieldsAsMap != aNetlistComponent->GetFields() )
|
||||||
{
|
{
|
||||||
if( m_isDryRun )
|
if( m_isDryRun )
|
||||||
{
|
{
|
||||||
|
@ -354,7 +359,24 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
||||||
msg.Printf( _( "Updated %s fields." ), aPcbFootprint->GetReference() );
|
msg.Printf( _( "Updated %s fields." ), aPcbFootprint->GetReference() );
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
aPcbFootprint->SetFields( aNetlistComponent->GetFields() );
|
|
||||||
|
for( auto pair : aNetlistComponent->GetFields() )
|
||||||
|
{
|
||||||
|
if( aPcbFootprint->HasFieldByName( pair.first ) )
|
||||||
|
aPcbFootprint->GetFieldByName( pair.first )->SetText( pair.second );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PCB_FIELD* newField = new PCB_FIELD(
|
||||||
|
aPcbFootprint, aPcbFootprint->GetFieldCount(), pair.first );
|
||||||
|
|
||||||
|
newField->SetText( pair.second );
|
||||||
|
newField->SetVisible( false );
|
||||||
|
newField->SetLayer( aPcbFootprint->GetLayer() == F_Cu ? F_Fab : B_Fab );
|
||||||
|
newField->StyleFromSettings( m_frame->GetDesignSettings() );
|
||||||
|
|
||||||
|
aPcbFootprint->AddField( newField );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_reporter->Report( msg, RPT_SEVERITY_ACTION );
|
m_reporter->Report( msg, RPT_SEVERITY_ACTION );
|
||||||
|
|
|
@ -52,7 +52,6 @@ void COMPONENT::SetFootprint( FOOTPRINT* aFootprint )
|
||||||
aFootprint->SetValue( m_value );
|
aFootprint->SetValue( m_value );
|
||||||
aFootprint->SetFPID( m_fpid );
|
aFootprint->SetFPID( m_fpid );
|
||||||
aFootprint->SetPath( path );
|
aFootprint->SetPath( path );
|
||||||
aFootprint->SetFields( m_properties );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -993,8 +993,10 @@ static void getFieldFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||||
{
|
{
|
||||||
FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
|
FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
|
||||||
|
|
||||||
if( fp->HasField( arg->AsString() ) )
|
PCB_FIELD* field = fp->GetFieldByName( arg->AsString() );
|
||||||
return fp->GetField( arg->AsString() );
|
|
||||||
|
if( field )
|
||||||
|
return field->GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pcb_field.h>
|
#include <pcb_field.h>
|
||||||
|
#include <footprint.h>
|
||||||
|
#include <board_design_settings.h>
|
||||||
|
|
||||||
PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, int aFieldId, const wxString& aName ) :
|
PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, int aFieldId, const wxString& aName ) :
|
||||||
PCB_TEXT( aParent, TEXT_TYPE( aFieldId ) )
|
PCB_TEXT( aParent, TEXT_TYPE( aFieldId ) )
|
||||||
|
@ -39,6 +41,17 @@ PCB_FIELD::PCB_FIELD( const PCB_TEXT& aText, int aFieldId, const wxString& aName
|
||||||
SetId( aFieldId );
|
SetId( aFieldId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_FIELD::StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings )
|
||||||
|
{
|
||||||
|
SetTextSize( settings.GetTextSize( GetLayer() ) );
|
||||||
|
SetTextThickness( settings.GetTextThickness( GetLayer() ) );
|
||||||
|
SetItalic( settings.GetTextItalic( GetLayer() ) );
|
||||||
|
SetKeepUpright( settings.GetTextUpright( GetLayer() ) );
|
||||||
|
SetMirrored( IsBackLayer( GetLayer() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString PCB_FIELD::GetName( bool aUseDefaultName ) const
|
wxString PCB_FIELD::GetName( bool aUseDefaultName ) const
|
||||||
{
|
{
|
||||||
if( m_parent && m_parent->Type() == PCB_FOOTPRINT_T )
|
if( m_parent && m_parent->Type() == PCB_FOOTPRINT_T )
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <template_fieldnames.h>
|
#include <template_fieldnames.h>
|
||||||
|
|
||||||
|
class BOARD_DESIGN_SETTINGS;
|
||||||
|
|
||||||
class PCB_FIELD : public PCB_TEXT
|
class PCB_FIELD : public PCB_TEXT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -44,6 +46,8 @@ public:
|
||||||
*/
|
*/
|
||||||
PCB_FIELD* CloneField() const { return (PCB_FIELD*) Clone(); }
|
PCB_FIELD* CloneField() const { return (PCB_FIELD*) Clone(); }
|
||||||
|
|
||||||
|
void StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the field name (not translated)..
|
* Return the field name (not translated)..
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,8 +95,10 @@ void PlotInteractiveLayer( BOARD* aBoard, PLOTTER* aPlotter, const PCB_PLOT_PARA
|
||||||
_( "Value" ),
|
_( "Value" ),
|
||||||
fp->Value().GetShownText( false ) ) );
|
fp->Value().GetShownText( false ) ) );
|
||||||
|
|
||||||
for( const auto& [name, value] : fp->GetFields() )
|
for( int i = VALUE_FIELD; i < fp->GetFieldCount(); i++ )
|
||||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), name, value ) );
|
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||||
|
fp->GetFields().at( i )->GetName(),
|
||||||
|
fp->GetFields().at( i )->GetText() ) );
|
||||||
|
|
||||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||||
_( "Footprint" ),
|
_( "Footprint" ),
|
||||||
|
|
|
@ -3707,8 +3707,6 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
||||||
|
|
||||||
std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( m_board );
|
std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( m_board );
|
||||||
|
|
||||||
std::map<wxString, wxString> properties;
|
|
||||||
|
|
||||||
footprint->SetInitialComments( aInitialComments );
|
footprint->SetInitialComments( aInitialComments );
|
||||||
|
|
||||||
token = NextTok();
|
token = NextTok();
|
||||||
|
@ -3813,7 +3811,33 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_property:
|
case T_property:
|
||||||
properties.insert( parseProperty() );
|
{
|
||||||
|
std::pair<wxString, wxString> nameAndValue = parseProperty();
|
||||||
|
|
||||||
|
// Skip non-field properties that should be hidden
|
||||||
|
if( nameAndValue.first == "ki_description" ||
|
||||||
|
nameAndValue.first == "ki_keywords" ||
|
||||||
|
nameAndValue.first == "Sheetfile" ||
|
||||||
|
nameAndValue.first == "Sheetname" )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( footprint->HasFieldByName( nameAndValue.first ) )
|
||||||
|
footprint->GetFieldByName( nameAndValue.first )->SetText( nameAndValue.second );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PCB_FIELD* newField = new PCB_FIELD( footprint.get(), footprint->GetFieldCount(),
|
||||||
|
nameAndValue.first );
|
||||||
|
|
||||||
|
newField->SetText( nameAndValue.second );
|
||||||
|
newField->SetVisible( false );
|
||||||
|
newField->SetLayer( footprint->GetLayer() == F_Cu ? F_Fab : B_Fab );
|
||||||
|
newField->StyleFromSettings( m_board->GetDesignSettings() );
|
||||||
|
|
||||||
|
footprint->AddField( newField );
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_path:
|
case T_path:
|
||||||
|
@ -3950,13 +3974,13 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
||||||
switch( text->GetType() )
|
switch( text->GetType() )
|
||||||
{
|
{
|
||||||
case PCB_TEXT::TEXT_is_REFERENCE:
|
case PCB_TEXT::TEXT_is_REFERENCE:
|
||||||
footprint->Reference() = *text;
|
footprint->Reference() = PCB_FIELD( *text, REFERENCE_FIELD );
|
||||||
const_cast<KIID&>( footprint->Reference().m_Uuid ) = text->m_Uuid;
|
const_cast<KIID&>( footprint->Reference().m_Uuid ) = text->m_Uuid;
|
||||||
delete text;
|
delete text;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_TEXT::TEXT_is_VALUE:
|
case PCB_TEXT::TEXT_is_VALUE:
|
||||||
footprint->Value() = *text;
|
footprint->Value() = PCB_FIELD( *text, VALUE_FIELD );
|
||||||
const_cast<KIID&>( footprint->Value().m_Uuid ) = text->m_Uuid;
|
const_cast<KIID&>( footprint->Value().m_Uuid ) = text->m_Uuid;
|
||||||
delete text;
|
delete text;
|
||||||
break;
|
break;
|
||||||
|
@ -4067,7 +4091,6 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
||||||
footprint->SetAttributes( attributes );
|
footprint->SetAttributes( attributes );
|
||||||
|
|
||||||
footprint->SetFPID( fpid );
|
footprint->SetFPID( fpid );
|
||||||
footprint->SetFields( properties );
|
|
||||||
|
|
||||||
return footprint.release();
|
return footprint.release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1118,13 +1118,11 @@ void PCB_PLUGIN::format( const FOOTPRINT* aFootprint, int aNestLevel ) const
|
||||||
m_out->Quotew( aFootprint->GetKeywords() ).c_str() );
|
m_out->Quotew( aFootprint->GetKeywords() ).c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<wxString, wxString>& props = aFootprint->GetFields();
|
for( const PCB_FIELD* field : aFootprint->GetFields() )
|
||||||
|
|
||||||
for( const std::pair<const wxString, wxString>& prop : props )
|
|
||||||
{
|
{
|
||||||
m_out->Print( aNestLevel+1, "(property %s %s)\n",
|
m_out->Print( aNestLevel + 1, "(property %s %s)\n",
|
||||||
m_out->Quotew( prop.first ).c_str(),
|
m_out->Quotew( field->GetCanonicalName() ).c_str(),
|
||||||
m_out->Quotew( prop.second ).c_str() );
|
m_out->Quotew( field->GetText() ).c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !( m_ctl & CTL_OMIT_PATH ) && !aFootprint->GetPath().empty() )
|
if( !( m_ctl & CTL_OMIT_PATH ) && !aFootprint->GetPath().empty() )
|
||||||
|
|
|
@ -1124,6 +1124,9 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
||||||
fp->SetOrientation( ANGLE_0 );
|
fp->SetOrientation( ANGLE_0 );
|
||||||
fp->SetPosition( cursorPos );
|
fp->SetPosition( cursorPos );
|
||||||
|
|
||||||
|
// Fill this in since it won't be synced from a symbol
|
||||||
|
fp->GetField( FOOTPRINT_FIELD )->SetText( UnescapeString( fp->GetFPIDAsString() ) );
|
||||||
|
|
||||||
commit.Add( fp );
|
commit.Add( fp );
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, fp );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, fp );
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ PRIVATE
|
||||||
eeschema_kiface_objects
|
eeschema_kiface_objects
|
||||||
common
|
common
|
||||||
pcbcommon
|
pcbcommon
|
||||||
|
3d-viewer
|
||||||
scripting
|
scripting
|
||||||
kimath
|
kimath
|
||||||
qa_utils
|
qa_utils
|
||||||
|
|
Loading…
Reference in New Issue