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_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_delayedFocusGrid = nullptr;
|
||||
|
@ -93,7 +93,7 @@ DIALOG_FOOTPRINT_PROPERTIES::DIALOG_FOOTPRINT_PROPERTIES( PCB_EDIT_FRAME* aParen
|
|||
// Give a bit more room for combobox editors
|
||||
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 ) );
|
||||
|
||||
// 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();
|
||||
|
||||
// Prevents crash bug in wxGrid's d'tor
|
||||
m_itemsGrid->DestroyTable( m_texts );
|
||||
m_itemsGrid->DestroyTable( m_fields );
|
||||
|
||||
// Delete the GRID_TRICKS.
|
||||
m_itemsGrid->PopEventHandler( true );
|
||||
|
@ -244,18 +244,13 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
|
|||
if( !m_3dPanel->TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
// Footprint Texts
|
||||
m_texts->push_back( m_footprint->Reference() );
|
||||
m_texts->push_back( m_footprint->Value() );
|
||||
|
||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
||||
{
|
||||
if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item ) )
|
||||
m_texts->push_back( *textItem );
|
||||
}
|
||||
// Footprint Fields
|
||||
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||
m_fields->push_back( field );
|
||||
|
||||
// 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 );
|
||||
|
||||
// Footprint Properties
|
||||
|
@ -328,7 +323,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataToWindow()
|
|||
m_itemsGrid->SetColSize( col, col_size );
|
||||
}
|
||||
|
||||
m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, false, true, true ) );
|
||||
m_itemsGrid->SetRowLabelSize( 0 );
|
||||
|
||||
Layout();
|
||||
adjustGridColumns();
|
||||
|
@ -346,24 +341,19 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
|
|||
return false;
|
||||
|
||||
// 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() )
|
||||
{
|
||||
if( m_NoteBook->GetSelection() != 0 )
|
||||
m_NoteBook->SetSelection( 0 );
|
||||
m_delayedFocusGrid = m_itemsGrid;
|
||||
m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
|
||||
m_delayedFocusColumn = FPT_NAME;
|
||||
m_delayedFocusRow = i;
|
||||
|
||||
m_delayedFocusGrid = m_itemsGrid;
|
||||
m_delayedErrorMessage = _( "Text items must have some content." );
|
||||
m_delayedFocusColumn = FPT_TEXT;
|
||||
m_delayedFocusRow = i;
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
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 );
|
||||
|
||||
|
@ -470,30 +460,24 @@ bool DIALOG_FOOTPRINT_PROPERTIES::TransferDataFromWindow()
|
|||
BOARD_COMMIT commit( m_frame );
|
||||
commit.Modify( m_footprint );
|
||||
|
||||
// copy reference and value
|
||||
m_footprint->Reference() = m_texts->at( 0 );
|
||||
m_footprint->Value() = m_texts->at( 1 );
|
||||
// Update fields
|
||||
size_t i = 0;
|
||||
|
||||
size_t i = 2;
|
||||
|
||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
||||
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||
{
|
||||
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_texts->size() )
|
||||
*textItem = m_texts->at( i++ );
|
||||
else
|
||||
textItem->DeleteStructure();
|
||||
}
|
||||
// copy grid table entries till we run out, then delete any remaining texts
|
||||
if( i < m_fields->size() )
|
||||
field = m_fields->at( i++ );
|
||||
else
|
||||
field->DeleteStructure();
|
||||
}
|
||||
|
||||
// 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++ ) );
|
||||
m_footprint->Add( newText, ADD_MODE::APPEND );
|
||||
view->Add( newText );
|
||||
PCB_FIELD* newField = m_fields->at( i++ );
|
||||
m_footprint->Add( newField, ADD_MODE::APPEND );
|
||||
view->Add( newField );
|
||||
}
|
||||
|
||||
// Initialize masks clearances
|
||||
|
@ -583,30 +567,21 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnAddField( wxCommandEvent& )
|
|||
if( !m_itemsGrid->CommitPendingChanges() )
|
||||
return;
|
||||
|
||||
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
|
||||
PCB_TEXT textItem( m_footprint, PCB_TEXT::TEXT_is_DIVERS );
|
||||
PCB_FIELD* newField = new PCB_FIELD( m_footprint, m_fields->size() );
|
||||
|
||||
// Set active layer if legal; otherwise copy layer from previous text item
|
||||
if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
|
||||
textItem.SetLayer( m_frame->GetActiveLayer() );
|
||||
else
|
||||
textItem.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
|
||||
newField->SetLayer( m_footprint->GetLayer() == F_Cu ? F_Fab : B_Fab );
|
||||
newField->SetVisible( false );
|
||||
newField->StyleFromSettings( m_frame->GetDesignSettings() );
|
||||
|
||||
textItem.SetTextSize( dsnSettings.GetTextSize( textItem.GetLayer() ) );
|
||||
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 );
|
||||
m_fields->push_back( newField );
|
||||
|
||||
// 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->SetFocus();
|
||||
m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
|
||||
m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
|
||||
m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
|
||||
m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
|
||||
|
||||
m_itemsGrid->EnableCellEditControl( true );
|
||||
m_itemsGrid->ShowCellEditControl();
|
||||
|
@ -628,22 +603,26 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnDeleteField( wxCommandEvent& )
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
|
||||
m_itemsGrid->ClearSelection();
|
||||
|
||||
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
||||
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
||||
|
||||
for( int row : selectedRows )
|
||||
{
|
||||
m_texts->erase( m_texts->begin() + row );
|
||||
m_fields->erase( m_fields->begin() + row );
|
||||
|
||||
// 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 );
|
||||
|
||||
if( m_itemsGrid->GetNumberRows() > 0 )
|
||||
|
@ -662,11 +641,16 @@ void DIALOG_FOOTPRINT_PROPERTIES::adjustGridColumns()
|
|||
|
||||
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
||||
|
||||
for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||
for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||
{
|
||||
if( i == 1 )
|
||||
continue;
|
||||
|
||||
m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
|
||||
m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||
}
|
||||
|
||||
m_itemsGrid->SetColSize(
|
||||
1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||
|
||||
// Update the width of the 3D panel
|
||||
m_3dPanel->AdjustGridColumnWidths();
|
||||
|
@ -710,7 +694,10 @@ void DIALOG_FOOTPRINT_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& )
|
|||
if( !m_initialFocus || grid == m_itemsGrid )
|
||||
{
|
||||
grid->SetGridCursor( row, col );
|
||||
grid->EnableCellEditControl( true );
|
||||
|
||||
if( !( col == 0 && row < MANDATORY_FIELDS ) )
|
||||
grid->EnableCellEditControl( true );
|
||||
|
||||
grid->ShowCellEditControl();
|
||||
|
||||
if( grid == m_itemsGrid && row == 0 && col == 0 )
|
||||
|
|
|
@ -82,7 +82,7 @@ private:
|
|||
|
||||
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_posY;
|
||||
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_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_delayedErrorMessage = wxEmptyString;
|
||||
|
@ -161,7 +161,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(
|
|||
m_itemsGrid->SetDefaultRowSize( m_itemsGrid->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_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();
|
||||
|
||||
// Prevents crash bug in wxGrid's d'tor
|
||||
m_itemsGrid->DestroyTable( m_texts );
|
||||
m_itemsGrid->DestroyTable( m_fields );
|
||||
m_privateLayersGrid->DestroyTable( m_privateLayers );
|
||||
|
||||
// Delete the GRID_TRICKS.
|
||||
|
@ -267,18 +267,13 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::TransferDataToWindow()
|
|||
if( !m_3dPanel->TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
// Footprint Texts
|
||||
m_texts->push_back( m_footprint->Reference() );
|
||||
m_texts->push_back( m_footprint->Value() );
|
||||
|
||||
for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
|
||||
{
|
||||
if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item) )
|
||||
m_texts->push_back( *textItem );
|
||||
}
|
||||
// Footprint Fields
|
||||
for( PCB_FIELD* field : m_footprint->GetFields() )
|
||||
m_fields->push_back( field );
|
||||
|
||||
// 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 );
|
||||
|
||||
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->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
|
||||
m_itemsGrid->SetRowLabelSize( 0 );
|
||||
|
||||
Layout();
|
||||
adjustGridColumns();
|
||||
|
@ -401,19 +396,17 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check for empty texts.
|
||||
for( size_t i = 2; i < m_texts->size(); ++i )
|
||||
// Check for valid field text properties
|
||||
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_delayedFocusColumn = FPT_TEXT;
|
||||
m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
|
||||
m_delayedFocusColumn = FPT_NAME;
|
||||
m_delayedFocusRow = i;
|
||||
|
||||
return false;
|
||||
|
@ -422,7 +415,7 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
|
|||
int minSize = pcbIUScale.MilsToIU( TEXT_MIN_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_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;
|
||||
}
|
||||
|
||||
if( text.GetTextHeight() < minSize || text.GetTextHeight() > maxSize )
|
||||
if( field->GetTextHeight() < minSize || field->GetTextHeight() > maxSize )
|
||||
{
|
||||
m_delayedFocusGrid = m_itemsGrid;
|
||||
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
|
||||
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_frame->StringFromValue( maxPenWidth, true ) );
|
||||
|
@ -502,44 +495,37 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::TransferDataFromWindow()
|
|||
m_footprint->SetDescription( m_DocCtrl->GetValue() );
|
||||
m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
|
||||
|
||||
// copy reference and value
|
||||
m_footprint->Reference() = m_texts->at( 0 );
|
||||
m_footprint->Value() = m_texts->at( 1 );
|
||||
// Update fields
|
||||
|
||||
size_t i = 2;
|
||||
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 );
|
||||
|
||||
if( textItem )
|
||||
{
|
||||
// copy grid table entries till we run out, then delete any remaining texts
|
||||
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 );
|
||||
}
|
||||
// copy grid table entries till we run out, then delete any remaining texts
|
||||
if( i < m_fields->size() )
|
||||
field = m_fields->at( i++ );
|
||||
else
|
||||
items_to_remove.push_back( field );
|
||||
}
|
||||
|
||||
// Remove text items:
|
||||
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 );
|
||||
view->Remove( item );
|
||||
item->DeleteStructure();
|
||||
}
|
||||
|
||||
|
||||
// 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++ ) );
|
||||
m_footprint->Add( newText, ADD_MODE::APPEND );
|
||||
view->Add( newText );
|
||||
PCB_FIELD* field = m_fields->at( i++ );
|
||||
m_footprint->AddField( field );
|
||||
view->Add( field );
|
||||
}
|
||||
|
||||
LSET privateLayers;
|
||||
|
@ -636,27 +622,27 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnAddField( wxCommandEvent& event )
|
|||
return;
|
||||
|
||||
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
|
||||
if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
|
||||
textItem.SetLayer( m_frame->GetActiveLayer() );
|
||||
newField->SetLayer( m_frame->GetActiveLayer() );
|
||||
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() ) );
|
||||
textItem.SetTextThickness( dsnSettings.GetTextThickness( textItem.GetLayer() ) );
|
||||
textItem.SetItalic( dsnSettings.GetTextItalic( textItem.GetLayer() ) );
|
||||
newField->SetTextSize( dsnSettings.GetTextSize( newField->GetLayer() ) );
|
||||
newField->SetTextThickness( dsnSettings.GetTextThickness( newField->GetLayer() ) );
|
||||
newField->SetItalic( dsnSettings.GetTextItalic( newField->GetLayer() ) );
|
||||
|
||||
m_texts->push_back( textItem );
|
||||
m_fields->push_back( newField );
|
||||
|
||||
// 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->SetFocus();
|
||||
m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
|
||||
m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
|
||||
m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
|
||||
m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
|
||||
|
||||
m_itemsGrid->EnableCellEditControl( true );
|
||||
m_itemsGrid->ShowCellEditControl();
|
||||
|
@ -678,22 +664,26 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::OnDeleteField( wxCommandEvent& event
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
|
||||
m_itemsGrid->ClearSelection();
|
||||
|
||||
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
|
||||
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
|
||||
|
||||
for( int row : selectedRows )
|
||||
{
|
||||
m_texts->erase( m_texts->begin() + row );
|
||||
m_fields->erase( m_fields->begin() + row );
|
||||
|
||||
// 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 );
|
||||
|
||||
if( m_itemsGrid->GetNumberRows() > 0 )
|
||||
|
@ -800,11 +790,16 @@ void DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::adjustGridColumns()
|
|||
|
||||
itemsWidth -= m_itemsGrid->GetRowLabelSize();
|
||||
|
||||
for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||
for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
|
||||
{
|
||||
if( i == 1 )
|
||||
continue;
|
||||
|
||||
m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
|
||||
m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||
itemsWidth -= m_itemsGrid->GetColSize( i );
|
||||
}
|
||||
|
||||
m_itemsGrid->SetColSize(
|
||||
1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
|
||||
|
||||
// Update the width private layers grid
|
||||
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->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 = nullptr;
|
||||
|
|
|
@ -102,7 +102,7 @@ private:
|
|||
|
||||
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;
|
||||
|
||||
UNIT_BINDER m_netClearance;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <pcb_dimension.h>
|
||||
#include <pcb_bitmap.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_field.h>
|
||||
#include <footprint.h>
|
||||
#include <zone.h>
|
||||
#include <view/view.h>
|
||||
|
@ -76,9 +77,31 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
|
|||
m_zoneConnection = ZONE_CONNECTION::INHERITED;
|
||||
m_fileFormatVersionAtLoad = 0;
|
||||
|
||||
// These are special and mandatory text fields
|
||||
m_reference = new PCB_TEXT( this, PCB_TEXT::TEXT_is_REFERENCE );
|
||||
m_value = new PCB_TEXT( this, PCB_TEXT::TEXT_is_VALUE );
|
||||
// These are the mandatory fields for the editor to work
|
||||
for( int i = 0; i < MANDATORY_FIELDS; i++ )
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
@ -115,14 +138,13 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
|
|||
|
||||
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
||||
|
||||
// Copy reference and value.
|
||||
m_reference = new PCB_TEXT( *aFootprint.m_reference );
|
||||
m_reference->SetParent( this );
|
||||
ptrMap[ aFootprint.m_reference ] = m_reference;
|
||||
|
||||
m_value = new PCB_TEXT( *aFootprint.m_value );
|
||||
m_value->SetParent( this );
|
||||
ptrMap[ aFootprint.m_value ] = m_value;
|
||||
// Copy fields
|
||||
for( PCB_FIELD* field : aFootprint.Fields() )
|
||||
{
|
||||
PCB_FIELD* newField = static_cast<PCB_FIELD*>( field->Clone() );
|
||||
ptrMap[field] = newField;
|
||||
Add( newField, ADD_MODE::APPEND ); // Append to ensure indexes are identical
|
||||
}
|
||||
|
||||
// Copy pads
|
||||
for( PAD* pad : aFootprint.Pads() )
|
||||
|
@ -180,7 +202,6 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
|
|||
m_3D_Drawings = aFootprint.m_3D_Drawings;
|
||||
m_doc = aFootprint.m_doc;
|
||||
m_keywords = aFootprint.m_keywords;
|
||||
m_fields = aFootprint.m_fields;
|
||||
m_privateLayers = aFootprint.m_privateLayers;
|
||||
|
||||
m_arflag = 0;
|
||||
|
@ -207,10 +228,13 @@ FOOTPRINT::~FOOTPRINT()
|
|||
}
|
||||
|
||||
// Clean up the owned elements
|
||||
delete m_reference;
|
||||
delete m_value;
|
||||
delete m_initial_comments;
|
||||
|
||||
for( PCB_FIELD* f : m_fields )
|
||||
delete f;
|
||||
|
||||
m_fields.clear();
|
||||
|
||||
for( PAD* p : m_pads )
|
||||
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()
|
||||
{
|
||||
// replace null UUIDs if any by a valid uuid
|
||||
std::vector< BOARD_ITEM* > item_list;
|
||||
|
||||
item_list.push_back( m_reference );
|
||||
item_list.push_back( m_value );
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
item_list.push_back( field );
|
||||
|
||||
for( PAD* pad : m_pads )
|
||||
item_list.push_back( pad );
|
||||
|
@ -303,12 +429,11 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
|
|||
m_zoneConnection = aOther.m_zoneConnection;
|
||||
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
||||
|
||||
// Move reference and value
|
||||
m_reference = aOther.m_reference;
|
||||
m_reference->SetParent( this );
|
||||
m_value = aOther.m_value;
|
||||
m_value->SetParent( this );
|
||||
// Move the fields
|
||||
m_fields.clear();
|
||||
|
||||
for( PCB_FIELD* field : aOther.Fields() )
|
||||
Add( field );
|
||||
|
||||
// Move the pads
|
||||
m_pads.clear();
|
||||
|
@ -354,17 +479,15 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
|
|||
m_3D_Drawings = aOther.m_3D_Drawings;
|
||||
m_doc = aOther.m_doc;
|
||||
m_keywords = aOther.m_keywords;
|
||||
m_fields = aOther.m_fields;
|
||||
m_privateLayers = aOther.m_privateLayers;
|
||||
|
||||
m_initial_comments = aOther.m_initial_comments;
|
||||
|
||||
// Clear the other item's containers since this is a move
|
||||
aOther.Fields().clear();
|
||||
aOther.Pads().clear();
|
||||
aOther.Zones().clear();
|
||||
aOther.GraphicalItems().clear();
|
||||
aOther.m_value = nullptr;
|
||||
aOther.m_reference = nullptr;
|
||||
aOther.m_initial_comments = nullptr;
|
||||
|
||||
return *this;
|
||||
|
@ -400,14 +523,18 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
|
|||
m_zoneConnection = aOther.m_zoneConnection;
|
||||
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;
|
||||
|
||||
// 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
|
||||
m_pads.clear();
|
||||
|
||||
|
@ -462,7 +589,6 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
|
|||
m_3D_Drawings = aOther.m_3D_Drawings;
|
||||
m_doc = aOther.m_doc;
|
||||
m_keywords = aOther.m_keywords;
|
||||
m_fields = aOther.m_fields;
|
||||
m_privateLayers = aOther.m_privateLayers;
|
||||
|
||||
m_initial_comments = aOther.m_initial_comments ?
|
||||
|
@ -498,12 +624,12 @@ bool FOOTPRINT::ResolveTextVar( wxString* token, int aDepth ) const
|
|||
|
||||
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
||||
{
|
||||
*token = m_reference->GetShownText( false, aDepth + 1 );
|
||||
*token = Reference().GetShownText( false, aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "VALUE" ) ) )
|
||||
{
|
||||
*token = m_value->GetShownText( false, aDepth + 1 );
|
||||
*token = Value().GetShownText( false, aDepth + 1 );
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -570,8 +696,22 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv
|
|||
switch( aBoardItem->Type() )
|
||||
{
|
||||
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;
|
||||
|
||||
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.
|
||||
wxCHECK_RET( static_cast<PCB_TEXT*>( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS,
|
||||
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;
|
||||
|
||||
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
|
||||
// footprint text can also be turned off via the GAL meta-layers, so the 2nd and
|
||||
// 3rd "&&" conditionals handle that.
|
||||
valueLayerIsVisible = board->IsLayerVisible( m_value->GetLayer() )
|
||||
valueLayerIsVisible = board->IsLayerVisible( Value().GetLayer() )
|
||||
&& board->IsElementVisible( LAYER_MOD_VALUES )
|
||||
&& 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_TEXT );
|
||||
}
|
||||
|
||||
|
||||
if( ( m_value->IsVisible() && valueLayerIsVisible )
|
||||
if( ( Value().IsVisible() && valueLayerIsVisible )
|
||||
|| aIncludeInvisibleText
|
||||
|| noDrawItems )
|
||||
{
|
||||
bbox.Merge( m_value->GetBoundingBox() );
|
||||
bbox.Merge( Value().GetBoundingBox() );
|
||||
}
|
||||
|
||||
if( ( m_reference->IsVisible() && refLayerIsVisible )
|
||||
if( ( Reference().IsVisible() && refLayerIsVisible )
|
||||
|| aIncludeInvisibleText
|
||||
|| 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;
|
||||
|
||||
// Don't use GetShownText(); we want to see the variable references here
|
||||
aList.emplace_back( UnescapeString( m_reference->GetText() ),
|
||||
UnescapeString( m_value->GetText() ) );
|
||||
aList.emplace_back( UnescapeString( Reference().GetText() ),
|
||||
UnescapeString( Value().GetText() ) );
|
||||
|
||||
if( aFrame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| aFrame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||
|
@ -1112,6 +1260,12 @@ bool FOOTPRINT::IsOnLayer( PCB_LAYER_ID aLayer, bool aIncludeCourtyards ) const
|
|||
return false;
|
||||
}
|
||||
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
{
|
||||
if( !field->IsOnLayer( aLayer ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
if( !item->IsOnLayer( aLayer ) )
|
||||
|
@ -1161,6 +1315,12 @@ bool FOOTPRINT::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
|
|||
return true;
|
||||
}
|
||||
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
{
|
||||
if( field->HitTest( arect, false, 0 ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_zones )
|
||||
{
|
||||
if( zone->HitTest( arect, false, 0 ) )
|
||||
|
@ -1319,10 +1479,10 @@ INSPECT_RESULT FOOTPRINT::Visit( INSPECTOR inspector, void* testData,
|
|||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
if( inspector( m_reference, testData ) == INSPECT_RESULT::QUIT )
|
||||
if( inspector( &Reference(), testData ) == 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;
|
||||
|
||||
// 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
|
||||
{
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
aFunction( static_cast<PCB_FIELD*>( field ) );
|
||||
|
||||
for( PAD* pad : m_pads )
|
||||
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 )
|
||||
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& )
|
||||
{
|
||||
|
@ -1567,8 +1727,8 @@ void FOOTPRINT::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
|
|||
SetPosition( newpos );
|
||||
SetOrientation( newOrientation );
|
||||
|
||||
m_reference->KeepUpright( orientation, newOrientation );
|
||||
m_value->KeepUpright( orientation, newOrientation );
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
field->KeepUpright( orientation, newOrientation );
|
||||
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
|
@ -1619,6 +1779,10 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
|||
newOrientation.Normalize180();
|
||||
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.
|
||||
for( PAD* pad : m_pads )
|
||||
pad->Flip( m_pos, false );
|
||||
|
@ -1630,10 +1794,6 @@ void FOOTPRINT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
|||
for( ZONE* zone : m_zones )
|
||||
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.
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
item->Flip( m_pos, false );
|
||||
|
@ -1659,8 +1819,8 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos )
|
|||
|
||||
m_pos += delta;
|
||||
|
||||
m_reference->EDA_TEXT::Offset( delta );
|
||||
m_value->EDA_TEXT::Offset( delta );
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
field->EDA_TEXT::Offset( delta );
|
||||
|
||||
for( PAD* pad : m_pads )
|
||||
pad->SetPosition( pad->GetPosition() + delta );
|
||||
|
@ -1695,9 +1855,9 @@ void FOOTPRINT::MoveAnchorPosition( const VECTOR2I& aMoveVector )
|
|||
VECTOR2I moveVector = aMoveVector;
|
||||
RotatePoint( moveVector, -GetOrientation() );
|
||||
|
||||
// Update of the reference and value.
|
||||
m_reference->Move( moveVector );
|
||||
m_value->Move( moveVector );
|
||||
// Update field local coordinates
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
field->Move( moveVector );
|
||||
|
||||
// Update the pad local coordinates.
|
||||
for( PAD* pad : m_pads )
|
||||
|
@ -1732,16 +1892,15 @@ void FOOTPRINT::SetOrientation( const EDA_ANGLE& aNewAngle )
|
|||
m_orient = aNewAngle;
|
||||
m_orient.Normalize180();
|
||||
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
field->Rotate( GetPosition(), angleChange );
|
||||
|
||||
for( PAD* pad : m_pads )
|
||||
pad->Rotate( GetPosition(), angleChange );
|
||||
|
||||
for( ZONE* zone : m_zones )
|
||||
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 )
|
||||
item->Rotate( GetPosition(), angleChange );
|
||||
|
||||
|
@ -2436,11 +2595,11 @@ void FOOTPRINT::CheckNetTies( const std::function<void( const BOARD_ITEM* aItem,
|
|||
copperItems.push_back( zone );
|
||||
}
|
||||
|
||||
if( m_reference->IsOnCopperLayer() )
|
||||
copperItems.push_back( m_reference );
|
||||
|
||||
if( m_value->IsOnCopperLayer() )
|
||||
copperItems.push_back( m_value );
|
||||
for( PCB_FIELD* field : m_fields )
|
||||
{
|
||||
if( field->IsOnCopperLayer() )
|
||||
copperItems.push_back( field );
|
||||
}
|
||||
|
||||
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 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() )
|
||||
{
|
||||
|
@ -2753,11 +2912,11 @@ void FOOTPRINT::TransformFPShapesToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_I
|
|||
|
||||
if( aIncludeText )
|
||||
{
|
||||
if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
|
||||
texts.push_back( &Reference() );
|
||||
|
||||
if( Value().GetLayer() == aLayer && Value().IsVisible() )
|
||||
texts.push_back( &Value() );
|
||||
for( const PCB_FIELD* field : m_fields )
|
||||
{
|
||||
if( field->GetLayer() == aLayer && field->IsVisible() )
|
||||
texts.push_back( field );
|
||||
}
|
||||
}
|
||||
|
||||
for( const PCB_TEXT* text : texts )
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <deque>
|
||||
|
||||
#include <template_fieldnames.h>
|
||||
|
||||
#include <board_item_container.h>
|
||||
#include <board_item.h>
|
||||
#include <collectors.h>
|
||||
|
@ -38,6 +40,7 @@
|
|||
#include <convert_shape_list_to_polygon.h>
|
||||
#include <pcb_item_containers.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_field.h>
|
||||
#include <functional>
|
||||
#include <math/vector3.h>
|
||||
|
||||
|
@ -169,6 +172,9 @@ public:
|
|||
const BOX2I GetBoundingBox() const override;
|
||||
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; }
|
||||
const PADS& Pads() const { return m_pads; }
|
||||
|
||||
|
@ -518,19 +524,13 @@ public:
|
|||
/**
|
||||
* @return reference designator text.
|
||||
*/
|
||||
const wxString& GetReference() const
|
||||
{
|
||||
return m_reference->GetText();
|
||||
}
|
||||
const wxString& GetReference() const { return Reference().GetText(); }
|
||||
|
||||
/**
|
||||
* @param aReference A reference to a wxString object containing the reference designator
|
||||
* text.
|
||||
*/
|
||||
void SetReference( const wxString& aReference )
|
||||
{
|
||||
m_reference->SetText( aReference );
|
||||
}
|
||||
void SetReference( const wxString& aReference ) { Reference().SetText( aReference ); }
|
||||
|
||||
// Property system doesn't like const references
|
||||
wxString GetReferenceAsString() const
|
||||
|
@ -546,18 +546,12 @@ public:
|
|||
/**
|
||||
* @return the value text.
|
||||
*/
|
||||
const wxString& GetValue() const
|
||||
{
|
||||
return m_value->GetText();
|
||||
}
|
||||
const wxString& GetValue() const { return Value().GetText(); }
|
||||
|
||||
/**
|
||||
* @param aValue A reference to a wxString object containing the value text.
|
||||
*/
|
||||
void SetValue( const wxString& aValue )
|
||||
{
|
||||
m_value->SetText( aValue );
|
||||
}
|
||||
void SetValue( const wxString& aValue ) { Value().SetText( aValue ); }
|
||||
|
||||
// Property system doesn't like const references
|
||||
wxString GetValueAsString() const
|
||||
|
@ -566,21 +560,105 @@ public:
|
|||
}
|
||||
|
||||
/// read/write accessors:
|
||||
PCB_TEXT& Value() { return *m_value; }
|
||||
PCB_TEXT& Reference() { return *m_reference; }
|
||||
PCB_FIELD& Value() { return *GetField( VALUE_FIELD ); }
|
||||
PCB_FIELD& Reference() { return *GetField( REFERENCE_FIELD ); }
|
||||
|
||||
/// The const versions to keep the compiler happy.
|
||||
PCB_TEXT& Value() const { return *m_value; }
|
||||
PCB_TEXT& Reference() const { return *m_reference; }
|
||||
const PCB_FIELD& Value() const { return *GetField( VALUE_FIELD ); }
|
||||
const PCB_FIELD& Reference() const { return *GetField( REFERENCE_FIELD ); }
|
||||
|
||||
const std::map<wxString, wxString>& GetFields() const { return m_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 m_fields.find( aKey ) != m_fields.end();
|
||||
}
|
||||
void SetField( const wxString& aKey, const wxString& aVal ) { m_fields[ aKey ] = aVal; }
|
||||
//-----<Fields>-----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return a mandatory field in this symbol.
|
||||
*
|
||||
* @note If you need to fetch a user field, use GetFieldById.
|
||||
*
|
||||
* @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; }
|
||||
void SetBoardOnly( bool aIsBoardOnly = true )
|
||||
|
@ -836,6 +914,7 @@ protected:
|
|||
virtual void swapData( BOARD_ITEM* aImage ) override;
|
||||
|
||||
private:
|
||||
PCB_FIELDS m_fields;
|
||||
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
|
||||
PADS m_pads; // PAD items, owned by pointer
|
||||
ZONES m_zones; // PCB_ZONE items, owned by pointer
|
||||
|
@ -843,8 +922,6 @@ private:
|
|||
|
||||
EDA_ANGLE m_orient; // Orientation
|
||||
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.
|
||||
int m_attributes; // Flag bits (see FOOTPRINT_ATTR_T)
|
||||
int m_fpStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED)
|
||||
|
@ -888,7 +965,6 @@ private:
|
|||
LSET m_privateLayers; // Layers visible only in the footprint editor
|
||||
|
||||
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,
|
||||
// lazily allocated only if needed for speed
|
||||
|
||||
|
|
|
@ -1293,7 +1293,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, b
|
|||
footprint->SetAttributes( footprintTranslated );
|
||||
|
||||
PCB_LAYER_ID txt_layer;
|
||||
VECTOR2I default_pos;
|
||||
VECTOR2I default_pos;
|
||||
BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();
|
||||
|
||||
footprint->Reference().SetText( settings.m_DefaultFPTextItems[0].m_Text );
|
||||
|
|
|
@ -98,7 +98,8 @@ wxString FP_TEXT_GRID_TABLE::GetColLabelValue( int 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_WIDTH: return _( "Width" );
|
||||
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 )
|
||||
{
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_TEXT:
|
||||
case FPT_NAME:
|
||||
case FPT_VALUE:
|
||||
case FPT_WIDTH:
|
||||
case FPT_HEIGHT:
|
||||
case FPT_THICKNESS:
|
||||
|
@ -165,7 +156,16 @@ wxGridCellAttr* FP_TEXT_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr:
|
|||
{
|
||||
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_HEIGHT:
|
||||
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 )
|
||||
{
|
||||
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
|
||||
&& grid->IsCellEditControlShown() )
|
||||
|
@ -211,32 +211,35 @@ wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
|
|||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_TEXT:
|
||||
return text.GetText();
|
||||
case FPT_NAME:
|
||||
return field->GetName();
|
||||
|
||||
case FPT_VALUE:
|
||||
return field->GetText();
|
||||
|
||||
case FPT_WIDTH:
|
||||
return m_frame->StringFromValue( text.GetTextWidth(), true );
|
||||
return m_frame->StringFromValue( field->GetTextWidth(), true );
|
||||
|
||||
case FPT_HEIGHT:
|
||||
return m_frame->StringFromValue( text.GetTextHeight(), true );
|
||||
return m_frame->StringFromValue( field->GetTextHeight(), true );
|
||||
|
||||
case FPT_THICKNESS:
|
||||
return m_frame->StringFromValue( text.GetTextThickness(), true );
|
||||
return m_frame->StringFromValue( field->GetTextThickness(), true );
|
||||
|
||||
case FPT_LAYER:
|
||||
return text.GetLayerName();
|
||||
return field->GetLayerName();
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
case FPT_XOFFSET:
|
||||
return m_frame->StringFromValue( text.GetFPRelativePosition().x, true );
|
||||
return m_frame->StringFromValue( field->GetFPRelativePosition().x, true );
|
||||
|
||||
case FPT_YOFFSET:
|
||||
return m_frame->StringFromValue( text.GetFPRelativePosition().y, true );
|
||||
return m_frame->StringFromValue( field->GetFPRelativePosition().y, true );
|
||||
|
||||
default:
|
||||
// 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 )
|
||||
{
|
||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
||||
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_SHOWN: return text.IsVisible();
|
||||
case FPT_ITALIC: return text.IsItalic();
|
||||
case FPT_UPRIGHT: return text.IsKeepUpright();
|
||||
case FPT_KNOCKOUT: return text.IsKnockout();
|
||||
case FPT_SHOWN: return field->IsVisible();
|
||||
case FPT_ITALIC: return field->IsItalic();
|
||||
case FPT_UPRIGHT: return field->IsKeepUpright();
|
||||
case FPT_KNOCKOUT: return field->IsKnockout();
|
||||
|
||||
default:
|
||||
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 )
|
||||
{
|
||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
||||
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_LAYER: return text.GetLayer();
|
||||
case FPT_LAYER: return field->GetLayer();
|
||||
|
||||
default:
|
||||
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 )
|
||||
{
|
||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
||||
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||
VECTOR2I pos;
|
||||
wxString value = aValue;
|
||||
|
||||
|
@ -308,37 +311,41 @@ void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
|
|||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_TEXT:
|
||||
text.SetText( value );
|
||||
case FPT_NAME:
|
||||
field->SetName( value );
|
||||
break;
|
||||
|
||||
case FPT_VALUE:
|
||||
field->SetText( value );
|
||||
break;
|
||||
|
||||
case FPT_WIDTH:
|
||||
text.SetTextWidth( m_frame->ValueFromString( value ) );
|
||||
field->SetTextWidth( m_frame->ValueFromString( value ) );
|
||||
break;
|
||||
|
||||
case FPT_HEIGHT:
|
||||
text.SetTextHeight( m_frame->ValueFromString( value ) );
|
||||
field->SetTextHeight( m_frame->ValueFromString( value ) );
|
||||
break;
|
||||
|
||||
case FPT_THICKNESS:
|
||||
text.SetTextThickness( m_frame->ValueFromString( value ) );
|
||||
field->SetTextThickness( m_frame->ValueFromString( value ) );
|
||||
break;
|
||||
|
||||
case FPT_ORIENTATION:
|
||||
text.SetTextAngle( m_frame->AngleValueFromString( value )
|
||||
+ text.GetParentFootprint()->GetOrientation() );
|
||||
field->SetTextAngle( m_frame->AngleValueFromString( value )
|
||||
+ field->GetParentFootprint()->GetOrientation() );
|
||||
break;
|
||||
|
||||
case FPT_XOFFSET:
|
||||
case FPT_YOFFSET:
|
||||
pos = text.GetFPRelativePosition();
|
||||
pos = field->GetFPRelativePosition();
|
||||
|
||||
if( aCol == FPT_XOFFSET )
|
||||
pos.x = m_frame->ValueFromString( value );
|
||||
else
|
||||
pos.y = m_frame->ValueFromString( value );
|
||||
|
||||
text.SetFPRelativePosition( pos );
|
||||
field->SetFPRelativePosition( pos );
|
||||
break;
|
||||
|
||||
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 )
|
||||
{
|
||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
||||
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_SHOWN:
|
||||
text.SetVisible( aValue );
|
||||
field->SetVisible( aValue );
|
||||
break;
|
||||
|
||||
case FPT_ITALIC:
|
||||
text.SetItalic( aValue );
|
||||
field->SetItalic( aValue );
|
||||
break;
|
||||
|
||||
case FPT_UPRIGHT:
|
||||
text.SetKeepUpright( aValue );
|
||||
field->SetKeepUpright( aValue );
|
||||
break;
|
||||
|
||||
case FPT_KNOCKOUT:
|
||||
text.SetIsKnockout( aValue );
|
||||
field->SetIsKnockout( aValue );
|
||||
break;
|
||||
|
||||
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 )
|
||||
{
|
||||
PCB_TEXT& text = this->at( (size_t) aRow );
|
||||
PCB_FIELD* field = this->at( (size_t) aRow );
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case FPT_LAYER:
|
||||
text.SetLayer( ToLAYER_ID( (int) aValue ) );
|
||||
text.SetMirrored( IsBackLayer( text.GetLayer() ) );
|
||||
field->SetLayer( ToLAYER_ID( (int) aValue ) );
|
||||
field->SetMirrored( IsBackLayer( field->GetLayer() ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -26,14 +26,15 @@
|
|||
|
||||
#include <wx/grid.h>
|
||||
#include <grid_tricks.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_field.h>
|
||||
|
||||
|
||||
class PCB_BASE_FRAME;
|
||||
|
||||
enum FP_TEXT_COL_ORDER
|
||||
{
|
||||
FPT_TEXT,
|
||||
FPT_NAME,
|
||||
FPT_VALUE,
|
||||
FPT_SHOWN,
|
||||
FPT_WIDTH,
|
||||
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:
|
||||
FP_TEXT_GRID_TABLE( PCB_BASE_FRAME* aFrame );
|
||||
|
@ -60,7 +61,6 @@ public:
|
|||
int GetNumberCols() override { return FPT_COUNT; }
|
||||
|
||||
wxString GetColLabelValue( int aCol ) override;
|
||||
wxString GetRowLabelValue( int aRow ) 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 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();
|
||||
|
||||
if( m_pcb )
|
||||
footprint->ApplyDefaultFieldSettings( *m_pcb );
|
||||
}
|
||||
|
||||
return footprint;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <base_units.h>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <netinfo.h>
|
||||
#include <footprint.h>
|
||||
#include <pad.h>
|
||||
|
@ -343,7 +344,11 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
|||
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 )
|
||||
{
|
||||
|
@ -354,7 +359,24 @@ bool BOARD_NETLIST_UPDATER::updateFootprintParameters( FOOTPRINT* aPcbFootprint,
|
|||
msg.Printf( _( "Updated %s fields." ), aPcbFootprint->GetReference() );
|
||||
|
||||
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 );
|
||||
|
|
|
@ -52,7 +52,6 @@ void COMPONENT::SetFootprint( FOOTPRINT* aFootprint )
|
|||
aFootprint->SetValue( m_value );
|
||||
aFootprint->SetFPID( m_fpid );
|
||||
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 );
|
||||
|
||||
if( fp->HasField( arg->AsString() ) )
|
||||
return fp->GetField( arg->AsString() );
|
||||
PCB_FIELD* field = fp->GetFieldByName( arg->AsString() );
|
||||
|
||||
if( field )
|
||||
return field->GetText();
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
|
||||
#include <pcb_field.h>
|
||||
#include <footprint.h>
|
||||
#include <board_design_settings.h>
|
||||
|
||||
PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, int aFieldId, const wxString& aName ) :
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
if( m_parent && m_parent->Type() == PCB_FOOTPRINT_T )
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <pcb_text.h>
|
||||
#include <template_fieldnames.h>
|
||||
|
||||
class BOARD_DESIGN_SETTINGS;
|
||||
|
||||
class PCB_FIELD : public PCB_TEXT
|
||||
{
|
||||
public:
|
||||
|
@ -44,6 +46,8 @@ public:
|
|||
*/
|
||||
PCB_FIELD* CloneField() const { return (PCB_FIELD*) Clone(); }
|
||||
|
||||
void StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings );
|
||||
|
||||
/**
|
||||
* Return the field name (not translated)..
|
||||
*
|
||||
|
|
|
@ -95,8 +95,10 @@ void PlotInteractiveLayer( BOARD* aBoard, PLOTTER* aPlotter, const PCB_PLOT_PARA
|
|||
_( "Value" ),
|
||||
fp->Value().GetShownText( false ) ) );
|
||||
|
||||
for( const auto& [name, value] : fp->GetFields() )
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), name, value ) );
|
||||
for( int i = VALUE_FIELD; i < fp->GetFieldCount(); i++ )
|
||||
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" ),
|
||||
_( "Footprint" ),
|
||||
|
|
|
@ -3707,8 +3707,6 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||
|
||||
std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( m_board );
|
||||
|
||||
std::map<wxString, wxString> properties;
|
||||
|
||||
footprint->SetInitialComments( aInitialComments );
|
||||
|
||||
token = NextTok();
|
||||
|
@ -3813,7 +3811,33 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||
break;
|
||||
|
||||
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;
|
||||
|
||||
case T_path:
|
||||
|
@ -3950,13 +3974,13 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||
switch( text->GetType() )
|
||||
{
|
||||
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;
|
||||
delete text;
|
||||
break;
|
||||
|
||||
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;
|
||||
delete text;
|
||||
break;
|
||||
|
@ -4067,7 +4091,6 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||
footprint->SetAttributes( attributes );
|
||||
|
||||
footprint->SetFPID( fpid );
|
||||
footprint->SetFields( properties );
|
||||
|
||||
return footprint.release();
|
||||
}
|
||||
|
|
|
@ -1118,13 +1118,11 @@ void PCB_PLUGIN::format( const FOOTPRINT* aFootprint, int aNestLevel ) const
|
|||
m_out->Quotew( aFootprint->GetKeywords() ).c_str() );
|
||||
}
|
||||
|
||||
const std::map<wxString, wxString>& props = aFootprint->GetFields();
|
||||
|
||||
for( const std::pair<const wxString, wxString>& prop : props )
|
||||
for( const PCB_FIELD* field : aFootprint->GetFields() )
|
||||
{
|
||||
m_out->Print( aNestLevel+1, "(property %s %s)\n",
|
||||
m_out->Quotew( prop.first ).c_str(),
|
||||
m_out->Quotew( prop.second ).c_str() );
|
||||
m_out->Print( aNestLevel + 1, "(property %s %s)\n",
|
||||
m_out->Quotew( field->GetCanonicalName() ).c_str(),
|
||||
m_out->Quotew( field->GetText() ).c_str() );
|
||||
}
|
||||
|
||||
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->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 );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, fp );
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ PRIVATE
|
|||
eeschema_kiface_objects
|
||||
common
|
||||
pcbcommon
|
||||
3d-viewer
|
||||
scripting
|
||||
kimath
|
||||
qa_utils
|
||||
|
|
Loading…
Reference in New Issue