KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_footprint_properties_fp_editor.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 Dick Hollenbeck, [email protected]
6 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 2004-2024 KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <confirm.h>
30#include <validators.h>
32#include <board_commit.h>
33#include <bitmaps.h>
34#include <kiplatform/ui.h>
36#include <widgets/wx_grid.h>
39#include <footprint.h>
45#include "filename_resolver.h"
46#include <pgm_base.h>
50#include <tool/tool_manager.h>
53
54#include <fp_lib_table.h>
55
57 m_frame( aFrame )
58{
59 m_layerColAttr = new wxGridCellAttr;
60 m_layerColAttr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_frame ) );
61
62 LSET forbiddenLayers = LSET::AllCuMask() | LSET::AllTechMask();
63 forbiddenLayers.set( Edge_Cuts );
64 forbiddenLayers.set( Margin );
65 m_layerColAttr->SetEditor( new GRID_CELL_LAYER_SELECTOR( m_frame, forbiddenLayers ) );
66}
67
68
70{
71 m_layerColAttr->DecRef();
72}
73
74
75bool PRIVATE_LAYERS_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
76{
77 return aTypeName == wxGRID_VALUE_NUMBER;
78}
79
80
81bool PRIVATE_LAYERS_GRID_TABLE::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
82{
83 return aTypeName == wxGRID_VALUE_NUMBER;
84}
85
86
87wxGridCellAttr* PRIVATE_LAYERS_GRID_TABLE::GetAttr( int aRow, int aCol,
88 wxGridCellAttr::wxAttrKind )
89{
90 m_layerColAttr->IncRef();
91 return m_layerColAttr;
92}
93
94
95wxString PRIVATE_LAYERS_GRID_TABLE::GetValue( int aRow, int aCol )
96{
97 return m_frame->GetBoard()->GetLayerName( this->at( (size_t) aRow ) );
98}
99
100
102{
103 return this->at( (size_t) aRow );
104}
105
106
107void PRIVATE_LAYERS_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
108{
109 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
110}
111
112
113void PRIVATE_LAYERS_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
114{
115 this->at( (size_t) aRow ) = ToLAYER_ID( (int) aValue );
116}
117
118
119// Remember the last open page during session.
120
122
123
125 FOOTPRINT_EDIT_FRAME* aParent,
126 FOOTPRINT* aFootprint ) :
128 m_frame( aParent ),
129 m_footprint( aFootprint ),
130 m_netClearance( aParent, m_NetClearanceLabel, m_NetClearanceCtrl, m_NetClearanceUnits ),
131 m_solderMask( aParent, m_SolderMaskMarginLabel, m_SolderMaskMarginCtrl,
132 m_SolderMaskMarginUnits ),
133 m_solderPaste( aParent, m_SolderPasteMarginLabel, m_SolderPasteMarginCtrl,
134 m_SolderPasteMarginUnits ),
135 m_solderPasteRatio( aParent, m_PasteMarginRatioLabel, m_PasteMarginRatioCtrl,
136 m_PasteMarginRatioUnits ),
137 m_gridSize( 0, 0 ),
138 m_lastRequestedSize( 0, 0 )
139{
140 SetEvtHandlerEnabled( false );
141 // Create the 3D models page
143 m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
144
145 m_fields = new FP_TEXT_GRID_TABLE( m_frame, this );
147
148 m_delayedErrorMessage = wxEmptyString;
149 m_delayedFocusCtrl = nullptr;
150 m_delayedFocusGrid = nullptr;
153 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
154
155 // Give an icon
156 wxIcon icon;
157 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit ) );
158 SetIcon( icon );
159
160 // Give a bit more room for combobox editors
161 m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
162 m_privateLayersGrid->SetDefaultRowSize( m_privateLayersGrid->GetDefaultRowSize() + 4 );
163
166
167 m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
169 [this]( wxCommandEvent& aEvent )
170 {
171 OnAddLayer( aEvent );
172 } ) );
173 m_padGroupsGrid->PushEventHandler( new GRID_TRICKS( m_padGroupsGrid,
174 [this]( wxCommandEvent& aEvent )
175 {
176 OnAddPadGroup( aEvent );
177 } ) );
178
179 m_itemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
180 m_privateLayersGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
181 m_padGroupsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
182
183 // Show/hide columns according to the user's preference
185
187
188 // Set font sizes
189 wxFont infoFont = KIUI::GetInfoFont( this );
190 infoFont.SetStyle( wxFONTSTYLE_ITALIC );
191 m_staticTextInfoCopper->SetFont( infoFont );
192 m_staticTextInfoPaste->SetFont( infoFont );
193
194 if( static_cast<int>( m_page ) >= 0 )
195 m_NoteBook->SetSelection( (unsigned) m_page );
196
197 if( m_page == NOTEBOOK_PAGES::PAGE_GENERAL )
198 {
202 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
203 }
204 else if( m_page == NOTEBOOK_PAGES::PAGE_CLEARANCES )
205 {
207 }
208
210
211 m_solderPasteRatio.SetUnits( EDA_UNITS::PERCENT );
213
214 // Configure button logos
215 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
216 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
217 m_bpAddLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
218 m_bpDeleteLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
219 m_bpAddPadGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
220 m_bpRemovePadGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
221
223
225 SetEvtHandlerEnabled( true );
226}
227
228
230{
231 PCBNEW_SETTINGS* cfg = nullptr;
232
233 try
234 {
235 cfg = m_frame->GetPcbNewSettings();
236 }
237 catch( const std::runtime_error& e )
238 {
239 wxFAIL_MSG( e.what() );
240 }
241
242 if( cfg )
243 {
245 }
246
247 // Prevents crash bug in wxGrid's d'tor
250
251 // Delete the GRID_TRICKS.
252 m_itemsGrid->PopEventHandler( true );
253 m_privateLayersGrid->PopEventHandler( true );
254 m_padGroupsGrid->PopEventHandler( true );
255
256 m_page = static_cast<NOTEBOOK_PAGES>( m_NoteBook->GetSelection() );
257
258 // the GL canvas on the 3D models page has to be visible before it is destroyed
259 m_NoteBook->SetSelection( static_cast<int>( NOTEBOOK_PAGES::PAGE_3D_MODELS ) );
260}
261
262
264{
265 LIB_ID fpID = m_footprint->GetFPID();
266 wxString footprintName = fpID.GetLibItemName();
267
268 m_FootprintNameCtrl->ChangeValue( footprintName );
269
271 m_KeywordCtrl->SetValue( m_footprint->GetKeywords() );
272
273 if( !wxDialog::TransferDataToWindow() )
274 return false;
275
276 if( !m_PanelGeneral->TransferDataToWindow() )
277 return false;
278
279 // Add the models to the panel
281 return false;
282
283 // Footprint Fields
284 for( PCB_FIELD* field : m_footprint->GetFields() )
285 m_fields->push_back( *field );
286
287 // Notify the grid
288 wxGridTableMessage tmsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
290 m_itemsGrid->ProcessTableMessage( tmsg );
291
293 m_componentType->SetSelection( 0 );
294 else if( m_footprint->GetAttributes() & FP_SMD )
295 m_componentType->SetSelection( 1 );
296 else
297 m_componentType->SetSelection( 2 );
298
299 // Private layers
300 for( PCB_LAYER_ID privateLayer : m_footprint->GetPrivateLayers().UIOrder() )
301 m_privateLayers->push_back( privateLayer );
302
303 // Notify the grid
304 wxGridTableMessage gridTableMessagesg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
306 m_privateLayersGrid->ProcessTableMessage( gridTableMessagesg );
307
312 m_cbDNP->SetValue( m_footprint->GetAttributes() & FP_DNP );
313
314 // Local Clearances
315
316 if( m_footprint->GetLocalClearance().has_value() )
318 else
319 m_netClearance.SetValue( wxEmptyString );
320
321 if( m_footprint->GetLocalSolderMaskMargin().has_value() )
323 else
324 m_solderMask.SetValue( wxEmptyString );
325
326 if( m_footprint->GetLocalSolderPasteMargin().has_value() )
328 else
329 m_solderPaste.SetValue( wxEmptyString );
330
333 else
334 m_solderPasteRatio.SetValue( wxEmptyString );
335
337
339 {
340 default:
341 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
342 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
343 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
344 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
345 }
346
347 for( const wxString& group : m_footprint->GetNetTiePadGroups() )
348 {
349 if( !group.IsEmpty() )
350 {
351 m_padGroupsGrid->AppendRows( 1 );
352 m_padGroupsGrid->SetCellValue( m_padGroupsGrid->GetNumberRows() - 1, 0, group );
353 }
354 }
355
356 // Items grid
357 for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
358 {
359 // Adjust min size to the column label size
360 m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false ) );
361 // Adjust the column size.
362 int col_size = m_itemsGrid->GetVisibleWidth( col );
363
364 if( col == FPT_LAYER ) // This one's a drop-down. Check all possible values.
365 {
366 BOARD* board = m_footprint->GetBoard();
367
368 for( PCB_LAYER_ID layer : board->GetEnabledLayers().Seq() )
369 col_size = std::max( col_size, GetTextExtent( board->GetLayerName( layer ) ).x );
370
371 // And the swatch:
372 col_size += 20;
373 }
374
375 if( m_itemsGrid->IsColShown( col ) )
376 m_itemsGrid->SetColSize( col, col_size );
377 }
378
379 m_itemsGrid->SetRowLabelSize( 0 );
380
381 Layout();
383
384 return true;
385}
386
387
389{
390 if( aFootprintName.IsEmpty() )
391 {
392 m_delayedErrorMessage = _( "Footprint must have a name." );
393 return false;
394 }
395 else if( !FOOTPRINT::IsLibNameValid( aFootprintName ) )
396 {
397 m_delayedErrorMessage.Printf( _( "Footprint name may not contain '%s'." ),
399 return false;
400 }
401
402 return true;
403}
404
405
407{
409 return false;
410
411 if( !DIALOG_SHIM::Validate() )
412 return false;
413
414 // First, test for invalid chars in footprint name
415 wxString footprintName = m_FootprintNameCtrl->GetValue();
416
417 if( !checkFootprintName( footprintName ) )
418 {
419 if( m_NoteBook->GetSelection() != 0 )
420 m_NoteBook->SetSelection( 0 );
421
423 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
424
425 return false;
426 }
427
428 // Check for valid field text properties
429 for( size_t i = 0; i < m_fields->size(); ++i )
430 {
431 PCB_FIELD& field = m_fields->at( i );
432
433 // Check for missing field names.
434 if( field.GetName( false ).IsEmpty() )
435 {
437 m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
440
441 return false;
442 }
443
445 int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
446
447 if( field.GetTextWidth() < minSize || field.GetTextWidth() > maxSize )
448 {
450 m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
452 m_frame->StringFromValue( maxSize, true ) );
455
456 return false;
457 }
458
459 if( field.GetTextHeight() < minSize || field.GetTextHeight() > maxSize )
460 {
462 m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
464 m_frame->StringFromValue( maxSize, true ) );
467
468 return false;
469 }
470
471 // Test for acceptable values for thickness and size and clamp if fails
472 int maxPenWidth = Clamp_Text_PenSize( field.GetTextThickness(), field.GetTextSize() );
473
474 if( field.GetTextThickness() > maxPenWidth )
475 {
476 m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
477 m_frame->StringFromValue( maxPenWidth, true ) );
478
480 m_delayedErrorMessage = _( "The text thickness is too large for the text size.\n"
481 "It will be clamped." );
484
485 return false;
486 }
487 }
488
489 if( !m_netClearance.Validate( 0, INT_MAX ) )
490 return false;
491
492 return true;
493}
494
495
497{
498 if( !Validate() )
499 return false;
500
501 if( !DIALOG_SHIM::TransferDataFromWindow() )
502 return false;
503
507 {
508 return false;
509 }
510
511 // This only commits the editor, model updating is done below so it is inside
512 // the commit
514 return false;
515
517 BOARD_COMMIT commit( m_frame );
518 commit.Modify( m_footprint );
519
520 LIB_ID fpID = m_footprint->GetFPID();
521 fpID.SetLibItemName( m_FootprintNameCtrl->GetValue() );
522 m_footprint->SetFPID( fpID );
523
525 m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
526
527 // Update fields
528
529 std::vector<PCB_FIELD*> items_to_remove;
530 size_t i = 0;
531
532 for( PCB_FIELD* field : m_footprint->GetFields() )
533 {
534 // copy grid table entries till we run out, then delete any remaining texts
535 if( i < m_fields->size() )
536 *field = m_fields->at( i++ );
537 else
538 items_to_remove.push_back( field );
539 }
540
541 // Remove text items:
543
544 for( PCB_TEXT* item : items_to_remove )
545 {
546 selTool->RemoveItemFromSel( item );
547 view->Remove( item );
548 item->DeleteStructure();
549 }
550
551
552 // if there are still grid table entries, create new fields for them
553 while( i < m_fields->size() )
554 {
555 view->Add( m_footprint->AddField( m_fields->at( i++ ) ) );
556 }
557
558 LSET privateLayers;
559
560 for( PCB_LAYER_ID layer : *m_privateLayers )
561 privateLayers.set( layer );
562
563 m_footprint->SetPrivateLayers( privateLayers );
564
565 int attributes = 0;
566
567 switch( m_componentType->GetSelection() )
568 {
569 case 0: attributes |= FP_THROUGH_HOLE; break;
570 case 1: attributes |= FP_SMD; break;
571 default: break;
572 }
573
574 if( m_boardOnly->GetValue() )
575 attributes |= FP_BOARD_ONLY;
576
577 if( m_excludeFromPosFiles->GetValue() )
578 attributes |= FP_EXCLUDE_FROM_POS_FILES;
579
580 if( m_excludeFromBOM->GetValue() )
581 attributes |= FP_EXCLUDE_FROM_BOM;
582
583 if( m_noCourtyards->GetValue() )
584 attributes |= FP_ALLOW_MISSING_COURTYARD;
585
586 if( m_cbDNP->GetValue() )
587 attributes |= FP_DNP;
588
589 if( m_allowBridges->GetValue() )
590 attributes |= FP_ALLOW_SOLDERMASK_BRIDGES;
591
592 m_footprint->SetAttributes( attributes );
593
594 // Initialize mask clearances
595 if( m_netClearance.IsNull() )
597 else
598 m_footprint->SetLocalClearance( m_netClearance.GetValue() );
599
600 if( m_solderMask.IsNull() )
601 m_footprint->SetLocalSolderMaskMargin( {} );
602 else
603 m_footprint->SetLocalSolderMaskMargin( m_solderMask.GetValue() );
604
605 if( m_solderPaste.IsNull() )
606 m_footprint->SetLocalSolderPasteMargin( {} );
607 else
608 m_footprint->SetLocalSolderPasteMargin( m_solderPaste.GetValue() );
609
610 if( m_solderPasteRatio.IsNull() )
611 m_footprint->SetLocalSolderPasteMarginRatio( {} );
612 else
613 m_footprint->SetLocalSolderPasteMarginRatio( m_solderPasteRatio.GetDoubleValue() / 100.0 );
614
615 switch( m_ZoneConnectionChoice->GetSelection() )
616 {
617 default:
618 case 0: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::INHERITED ); break;
619 case 1: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::FULL ); break;
620 case 2: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::THERMAL ); break;
621 case 3: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::NONE ); break;
622 }
623
624 m_footprint->ClearNetTiePadGroups();
625
626 for( int ii = 0; ii < m_padGroupsGrid->GetNumberRows(); ++ii )
627 {
628 wxString group = m_padGroupsGrid->GetCellValue( ii, 0 );
629
630 if( !group.IsEmpty() )
631 m_footprint->AddNetTiePadGroup( group );
632 }
633
634 // Copy the models from the panel to the footprint
635 std::vector<FP_3DMODEL>& panelList = m_3dPanel->GetModelList();
636 std::vector<FP_3DMODEL>* fpList = &m_footprint->Models();
637 fpList->clear();
638 fpList->insert( fpList->end(), panelList.begin(), panelList.end() );
639
640 commit.Push( _( "Edit Footprint Properties" ) );
641
642 return true;
643}
644
645
646static bool footprintIsFromBoard( FOOTPRINT* aFootprint )
647{
648 return aFootprint->GetLink() != niluuid;
649}
650
651
653{
655 {
656 // Currently: nothing to do
657 }
658}
659
660
662{
664 return;
665
666 int fieldId = (int) m_fields->size();
667 const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
668 PCB_FIELD newField =
671
672 // Set active layer if legal; otherwise copy layer from previous text item
674 newField.SetLayer( m_frame->GetActiveLayer() );
675 else
676 newField.SetLayer( m_fields->at( m_fields->size() - 1 ).GetLayer() );
677
678 newField.SetTextSize( dsnSettings.GetTextSize( newField.GetLayer() ) );
679 newField.SetTextThickness( dsnSettings.GetTextThickness( newField.GetLayer() ) );
680 newField.SetItalic( dsnSettings.GetTextItalic( newField.GetLayer() ) );
681
682 m_fields->push_back( newField );
683
684 // notify the grid
685 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
686 m_itemsGrid->ProcessTableMessage( msg );
687
688 m_itemsGrid->SetFocus();
689 m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
690 m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
691
692 m_itemsGrid->EnableCellEditControl( true );
693 m_itemsGrid->ShowCellEditControl();
694}
695
696
698{
700 return;
701
702 wxArrayInt selectedRows = m_itemsGrid->GetSelectedRows();
703
704 if( selectedRows.empty() && m_itemsGrid->GetGridCursorRow() >= 0 )
705 selectedRows.push_back( m_itemsGrid->GetGridCursorRow() );
706
707 if( selectedRows.empty() )
708 return;
709
710 for( int row : selectedRows )
711 {
712 if( row < MANDATORY_FIELDS )
713 {
714 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
716 return;
717 }
718 }
719
720 m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
721 m_itemsGrid->ClearSelection();
722
723 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
724 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
725
726 for( int row : selectedRows )
727 {
728 m_fields->erase( m_fields->begin() + row );
729
730 // notify the grid
731 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
732 m_itemsGrid->ProcessTableMessage( msg );
733
734 if( m_itemsGrid->GetNumberRows() > 0 )
735 {
736 m_itemsGrid->MakeCellVisible( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
737 m_itemsGrid->SetGridCursor( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
738 }
739 }
740}
741
742
744{
746 return;
747
748 PCB_LAYER_ID nextLayer = User_1;
749
750 while( alg::contains( *m_privateLayers, nextLayer ) && nextLayer < User_9 )
751 nextLayer = ToLAYER_ID( nextLayer + 1 );
752
753 m_privateLayers->push_back( nextLayer );
754
755 // notify the grid
756 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
757 m_privateLayersGrid->ProcessTableMessage( msg );
758
759 m_privateLayersGrid->SetFocus();
760 m_privateLayersGrid->MakeCellVisible( m_privateLayers->size() - 1, 0 );
761 m_privateLayersGrid->SetGridCursor( m_privateLayers->size() - 1, 0 );
762}
763
764
766{
768 return;
769
770 int curRow = m_privateLayersGrid->GetGridCursorRow();
771
772 if( curRow < 0 )
773 return;
774
775 m_privateLayers->erase( m_privateLayers->begin() + curRow );
776
777 // notify the grid
778 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
779 m_privateLayersGrid->ProcessTableMessage( msg );
780
781 if( m_privateLayersGrid->GetNumberRows() > 0 )
782 {
783 m_privateLayersGrid->MakeCellVisible( std::max( 0, curRow-1 ),
784 m_privateLayersGrid->GetGridCursorCol() );
785 m_privateLayersGrid->SetGridCursor( std::max( 0, curRow-1 ),
786 m_privateLayersGrid->GetGridCursorCol() );
787 }
788}
789
790
792{
794 return;
795
796 m_padGroupsGrid->AppendRows( 1 );
797
798 m_padGroupsGrid->SetFocus();
799 m_padGroupsGrid->MakeCellVisible( m_padGroupsGrid->GetNumberRows() - 1, 0 );
800 m_padGroupsGrid->SetGridCursor( m_padGroupsGrid->GetNumberRows() - 1, 0 );
801
802 m_padGroupsGrid->EnableCellEditControl( true );
803 m_padGroupsGrid->ShowCellEditControl();
804}
805
806
808{
810 return;
811
812 wxArrayInt selectedRows = m_padGroupsGrid->GetSelectedRows();
813 int curRow = m_padGroupsGrid->GetGridCursorRow();
814
815 if( selectedRows.empty() && curRow >= 0 && curRow < m_padGroupsGrid->GetNumberRows() )
816 selectedRows.Add( curRow );
817
818 for( int ii = selectedRows.Count() - 1; ii >= 0; --ii )
819 {
820 int row = selectedRows.Item( ii );
821 m_padGroupsGrid->DeleteRows( row, 1 );
822 curRow = std::min( curRow, row );
823 }
824
825 curRow = std::max( 0, curRow - 1 );
826 m_padGroupsGrid->MakeCellVisible( curRow, m_padGroupsGrid->GetGridCursorCol() );
827 m_padGroupsGrid->SetGridCursor( curRow, m_padGroupsGrid->GetGridCursorCol() );
828}
829
830
832{
833 // Account for scroll bars
835
836 itemsWidth -= m_itemsGrid->GetRowLabelSize();
837
838 for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
839 {
840 if( i == 1 )
841 continue;
842
843 itemsWidth -= m_itemsGrid->GetColSize( i );
844 }
845
846 m_itemsGrid->SetColSize(
847 1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
848
849 // Update the width private layers grid
850 m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
852
853 // Update the width net tie pad groups grid
854 m_padGroupsGrid->SetColSize( 0, std::max( m_padGroupsGrid->GetClientSize().x,
856
857 // Update the width of the 3D panel
859}
860
861
863{
864 // Handle a delayed focus. The delay allows us to:
865 // a) change focus when the error was triggered from within a killFocus handler
866 // b) show the correct notebook page in the background before the error dialog comes up
867 // when triggered from an OK or a notebook page change
868
869 if( static_cast<int>( m_delayedFocusPage ) >= 0 )
870 {
871 if( m_NoteBook->GetSelection() != static_cast<int>( m_delayedFocusPage ) )
872 m_NoteBook->ChangeSelection( static_cast<int>( m_delayedFocusPage ) );
873
874 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
875 }
876
877 if( !m_delayedErrorMessage.IsEmpty() )
878 {
879 // We will re-enter this routine when the error dialog is displayed, so make
880 // sure we don't keep putting up more dialogs.
881 wxString msg = m_delayedErrorMessage;
882 m_delayedErrorMessage = wxEmptyString;
883
884 // Do not use DisplayErrorMessage(); it screws up window order on Mac
885 DisplayError( nullptr, msg );
886 }
887
889 {
890 m_delayedFocusCtrl->SetFocus();
891
892 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
893 textEntry->SelectAll();
894
895 m_delayedFocusCtrl = nullptr;
896 }
897 else if( m_delayedFocusGrid )
898 {
899 m_delayedFocusGrid->SetFocus();
902
904 m_delayedFocusGrid->EnableCellEditControl( true );
905
906 m_delayedFocusGrid->ShowCellEditControl();
907
908 m_delayedFocusGrid = nullptr;
911 }
912}
913
914
916{
917 wxSize new_size = aEvent.GetSize();
918
919 if( ( !m_itemsGrid->IsCellEditControlShown() || m_lastRequestedSize != new_size )
920 && m_gridSize != new_size )
921 {
922 m_gridSize = new_size;
923
924 // A trick to fix a cosmetic issue: when, in m_itemsGrid, a layer selector widget has
925 // the focus (is activated in column 6) when resizing the grid, the widget is not moved.
926 // So just change the widget having the focus in this case
927 if( m_NoteBook->GetSelection() == 0 && !m_itemsGrid->HasFocus() )
928 {
929 int col = m_itemsGrid->GetGridCursorCol();
930
931 if( col == 6 ) // a layer selector widget can be activated
932 m_itemsGrid->SetFocus();
933 }
934
936 }
937
938 // We store this value to check whether the dialog is changing size. This might indicate
939 // that the user is scaling the dialog with an editor shown. Some editors do not close
940 // (at least on GTK) when the user drags a dialog corner
941 m_lastRequestedSize = new_size;
942
943 // Always propagate for a grid repaint (needed if the height changes, as well as width)
944 aEvent.Skip();
945}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
Container for design settings for a BOARD object.
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
bool GetTextItalic(PCB_LAYER_ID aLayer) const
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:226
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:260
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:689
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:576
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
Class DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR_BASE.
DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(FOOTPRINT_EDIT_FRAME *aParent, FOOTPRINT *aFootprint)
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int GetTextHeight() const
Definition: eda_text.h:225
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:374
int GetTextWidth() const
Definition: eda_text.h:222
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
int GetTextThickness() const
Definition: eda_text.h:123
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
VECTOR2I GetTextSize() const
Definition: eda_text.h:219
BOARD_DESIGN_SETTINGS & GetDesignSettings() const override
Returns the BOARD_DESIGN_SETTINGS for the open project.
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
This class provides a custom wxValidator object for limiting the allowable characters when defining f...
Definition: validators.h:77
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:231
wxString GetLibDescription() const
Definition: footprint.h:236
ZONE_CONNECTION GetLocalZoneConnection() const
Definition: footprint.h:267
static bool IsLibNameValid(const wxString &aName)
Test for validity of a name of a footprint to be used in a footprint library ( no spaces,...
Definition: footprint.cpp:1920
PCB_FIELD * AddField(const PCB_FIELD &aField)
Add a field to the symbol.
Definition: footprint.cpp:332
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:240
void SetAttributes(int aAttributes)
Definition: footprint.h:270
std::optional< int > GetLocalSolderPasteMargin() const
Definition: footprint.h:260
void SetPrivateLayers(LSET aLayers)
Adds an item to the container.
Definition: footprint.h:126
std::optional< int > GetLocalClearance() const
Definition: footprint.h:254
int GetAttributes() const
Definition: footprint.h:269
LSET GetPrivateLayers() const
Definition: footprint.h:125
const std::vector< wxString > & GetNetTiePadGroups() const
Definition: footprint.h:318
const LIB_ID & GetFPID() const
Definition: footprint.h:230
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with PCB_TEXTs.
Definition: footprint.cpp:317
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:263
KIID GetLink() const
Definition: footprint.h:828
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
Test for validity of the name in a library of the footprint ( no spaces, dir separators ....
Definition: footprint.cpp:1931
void SetLibDescription(const wxString &aDesc)
Definition: footprint.h:237
void SetLocalClearance(std::optional< int > aClearance)
Definition: footprint.h:255
std::optional< int > GetLocalSolderMaskMargin() const
Definition: footprint.h:257
wxString GetKeywords() const
Definition: footprint.h:239
int GetNumberRows() override
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition: pcb_view.cpp:57
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:66
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:110
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:573
LSEQ UIOrder() const
Definition: lset.cpp:1012
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:418
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:931
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:863
wxString m_FootprintTextShownColumns
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual PCB_LAYER_ID GetActiveLayer() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: pcb_field.cpp:47
The selection tool: currently supports:
wxString GetValue(int aRow, int aCol) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
long GetValueAsLong(int aRow, int aCol) override
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) override
void SetValueAsLong(int aRow, int aCol, long aValue) override
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
void SetBitmap(const wxBitmapBundle &aBmp)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual void SetNegativeZero()
Definition: unit_binder.h:71
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
bool IsNull() const
Return true if the control holds no value (ie: empty string, not 0).
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculates the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:559
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:312
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:156
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:268
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:282
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:462
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
This file is part of the common library.
static bool footprintIsFromBoard(FOOTPRINT *aFootprint)
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
Declaration of the eda_3d_viewer class.
#define TEXT_MIN_SIZE_MILS
Minimum text size in mils.
Definition: eda_text.h:42
#define TEXT_MAX_SIZE_MILS
Maximum text size in mils (10 inches)
Definition: eda_text.h:43
@ FP_SMD
Definition: footprint.h:73
@ FP_DNP
Definition: footprint.h:80
@ FP_ALLOW_MISSING_COURTYARD
Definition: footprint.h:79
@ FP_EXCLUDE_FROM_POS_FILES
Definition: footprint.h:74
@ FP_BOARD_ONLY
Definition: footprint.h:76
@ FP_EXCLUDE_FROM_BOM
Definition: footprint.h:75
@ FP_THROUGH_HOLE
Definition: footprint.h:72
@ FP_ALLOW_SOLDERMASK_BRIDGES
Definition: footprint.h:78
@ FPT_LAYER
@ FPT_WIDTH
@ FPT_HEIGHT
@ FPT_THICKNESS
@ FPT_NAME
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition: gr_text.cpp:87
KIID niluuid(0)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Edge_Cuts
Definition: layer_ids.h:114
@ User_9
Definition: layer_ids.h:132
@ Margin
Definition: layer_ids.h:115
@ User_1
Definition: layer_ids.h:124
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:1022
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:195
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:151
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
see class PGM_BASE
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LINE
Definition: string_utils.h:59
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
#define DO_TRANSLATE
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
Custom text control validator definitions.
@ THERMAL
Use thermal relief for pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper