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 The 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
29#include <bitmaps.h>
30#include <board_commit.h>
32#include <confirm.h>
36#include <embedded_files.h>
37#include <filename_resolver.h>
38#include <footprint.h>
42#include <kiplatform/ui.h>
45#include <pgm_base.h>
47#include <tool/tool_manager.h>
49#include <validators.h>
53#include <widgets/wx_grid.h>
54
55#include <fp_lib_table.h>
56
58 m_frame( aFrame )
59{
60 m_layerColAttr = new wxGridCellAttr;
61 m_layerColAttr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_frame ) );
62
63 LSET forbiddenLayers = LSET::AllCuMask() | LSET::AllTechMask();
64 forbiddenLayers.set( Edge_Cuts );
65 forbiddenLayers.set( Margin );
66 m_layerColAttr->SetEditor( new GRID_CELL_LAYER_SELECTOR( m_frame, forbiddenLayers ) );
67}
68
69
71{
72 m_layerColAttr->DecRef();
73}
74
75
76bool PRIVATE_LAYERS_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
77{
78 return aTypeName == wxGRID_VALUE_NUMBER;
79}
80
81
82bool PRIVATE_LAYERS_GRID_TABLE::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
83{
84 return aTypeName == wxGRID_VALUE_NUMBER;
85}
86
87
88wxGridCellAttr* PRIVATE_LAYERS_GRID_TABLE::GetAttr( int aRow, int aCol,
89 wxGridCellAttr::wxAttrKind aKind )
90{
91 m_layerColAttr->IncRef();
92 return enhanceAttr( m_layerColAttr, aRow, aCol, aKind );
93}
94
95
96wxString PRIVATE_LAYERS_GRID_TABLE::GetValue( int aRow, int aCol )
97{
98 return m_frame->GetBoard()->GetLayerName( this->at( (size_t) aRow ) );
99}
100
101
103{
104 return this->at( (size_t) aRow );
105}
106
107
108void PRIVATE_LAYERS_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
109{
110 wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
111}
112
113
114void PRIVATE_LAYERS_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
115{
116 this->at( (size_t) aRow ) = ToLAYER_ID( (int) aValue );
117}
118
119
120// Remember the last open page during session.
121
123
124
126 FOOTPRINT_EDIT_FRAME* aParent,
127 FOOTPRINT* aFootprint ) :
129 m_frame( aParent ),
130 m_footprint( aFootprint ),
131 m_initialized( false ),
132 m_netClearance( aParent, m_NetClearanceLabel, m_NetClearanceCtrl, m_NetClearanceUnits ),
133 m_solderMask( aParent, m_SolderMaskMarginLabel, m_SolderMaskMarginCtrl,
134 m_SolderMaskMarginUnits ),
135 m_solderPaste( aParent, m_SolderPasteMarginLabel, m_SolderPasteMarginCtrl,
136 m_SolderPasteMarginUnits ),
137 m_solderPasteRatio( aParent, m_PasteMarginRatioLabel, m_PasteMarginRatioCtrl,
138 m_PasteMarginRatioUnits ),
139 m_gridSize( 0, 0 ),
140 m_lastRequestedSize( 0, 0 )
141{
142 SetEvtHandlerEnabled( false );
143
144 // Create the extra panels.
147
148 m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
149 m_NoteBook->AddPage( m_embeddedFiles, _( "Embedded Files" ) );
150
153
154 m_delayedErrorMessage = wxEmptyString;
155 m_delayedFocusCtrl = nullptr;
156 m_delayedFocusGrid = nullptr;
159 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
160
161 // Give an icon
162 wxIcon icon;
163 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit ) );
164 SetIcon( icon );
165
166 // Give a bit more room for combobox editors
167 m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
168 m_privateLayersGrid->SetDefaultRowSize( m_privateLayersGrid->GetDefaultRowSize() + 4 );
169
172
173 m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
175 [this]( wxCommandEvent& aEvent )
176 {
177 OnAddLayer( aEvent );
178 } ) );
179 m_padGroupsGrid->PushEventHandler( new GRID_TRICKS( m_padGroupsGrid,
180 [this]( wxCommandEvent& aEvent )
181 {
182 OnAddPadGroup( aEvent );
183 } ) );
184
185 m_itemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
186 m_privateLayersGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
187 m_padGroupsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
188
189 // Show/hide columns according to the user's preference
191
193
194 // Set font sizes
195 wxFont infoFont = KIUI::GetInfoFont( this );
196 infoFont.SetStyle( wxFONTSTYLE_ITALIC );
197 m_staticTextInfoCopper->SetFont( infoFont );
198 m_staticTextInfoPaste->SetFont( infoFont );
199
200 if( static_cast<int>( m_page ) >= 0 )
201 m_NoteBook->SetSelection( (unsigned) m_page );
202
203 if( m_page == NOTEBOOK_PAGES::PAGE_GENERAL )
204 {
208 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
209 }
210 else if( m_page == NOTEBOOK_PAGES::PAGE_CLEARANCES )
211 {
213 }
214
216
217 m_solderPasteRatio.SetUnits( EDA_UNITS::PERCENT );
219
220 // Configure button logos
221 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
222 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
223 m_bpAddLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
224 m_bpDeleteLayer->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
225 m_bpAddPadGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
226 m_bpRemovePadGroup->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
227
229
231 SetEvtHandlerEnabled( true );
232}
233
234
236{
238
239 // Prevents crash bug in wxGrid's d'tor
242
243 // Delete the GRID_TRICKS.
244 m_itemsGrid->PopEventHandler( true );
245 m_privateLayersGrid->PopEventHandler( true );
246 m_padGroupsGrid->PopEventHandler( true );
247
248 m_page = static_cast<NOTEBOOK_PAGES>( m_NoteBook->GetSelection() );
249
250 // the GL canvas on the 3D models page has to be visible before it is destroyed
251 m_NoteBook->SetSelection( static_cast<int>( NOTEBOOK_PAGES::PAGE_3D_MODELS ) );
252}
253
254
256{
257 LIB_ID fpID = m_footprint->GetFPID();
258 wxString footprintName = fpID.GetLibItemName();
259
260 m_FootprintNameCtrl->ChangeValue( footprintName );
261
263 m_KeywordCtrl->SetValue( m_footprint->GetKeywords() );
264
265 if( !wxDialog::TransferDataToWindow() )
266 return false;
267
268 if( !m_PanelGeneral->TransferDataToWindow() )
269 return false;
270
271 // Add the models to the panel
273 return false;
274
276 return false;
277
278 // Footprint Fields
279 for( PCB_FIELD* field : m_footprint->GetFields() )
280 m_fields->push_back( *field );
281
282 // Notify the grid
283 wxGridTableMessage tmsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
285 m_itemsGrid->ProcessTableMessage( tmsg );
286
288 m_componentType->SetSelection( 0 );
289 else if( m_footprint->GetAttributes() & FP_SMD )
290 m_componentType->SetSelection( 1 );
291 else
292 m_componentType->SetSelection( 2 );
293
294 // Private layers
295 for( PCB_LAYER_ID privateLayer : m_footprint->GetPrivateLayers().UIOrder() )
296 m_privateLayers->push_back( privateLayer );
297
298 // Notify the grid
299 wxGridTableMessage gridTableMessagesg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
301 m_privateLayersGrid->ProcessTableMessage( gridTableMessagesg );
302
307 m_cbDNP->SetValue( m_footprint->GetAttributes() & FP_DNP );
308
309 // Local Clearances
310
311 if( m_footprint->GetLocalClearance().has_value() )
313 else
314 m_netClearance.SetValue( wxEmptyString );
315
316 if( m_footprint->GetLocalSolderMaskMargin().has_value() )
318 else
319 m_solderMask.SetValue( wxEmptyString );
320
321 if( m_footprint->GetLocalSolderPasteMargin().has_value() )
323 else
324 m_solderPaste.SetValue( wxEmptyString );
325
328 else
329 m_solderPasteRatio.SetValue( wxEmptyString );
330
332
334 {
335 default:
336 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
337 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
338 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
339 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
340 }
341
342 for( const wxString& group : m_footprint->GetNetTiePadGroups() )
343 {
344 if( !group.IsEmpty() )
345 {
346 m_padGroupsGrid->AppendRows( 1 );
347 m_padGroupsGrid->SetCellValue( m_padGroupsGrid->GetNumberRows() - 1, 0, group );
348 }
349 }
350
351 // Items grid
352 for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
353 {
354 // Adjust min size to the column label size
355 m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false ) );
356 // Adjust the column size.
357 int col_size = m_itemsGrid->GetVisibleWidth( col );
358
359 if( col == PFC_LAYER ) // This one's a drop-down. Check all possible values.
360 {
361 BOARD* board = m_footprint->GetBoard();
362
363 for( PCB_LAYER_ID layer : board->GetEnabledLayers().Seq() )
364 col_size = std::max( col_size, GetTextExtent( board->GetLayerName( layer ) ).x );
365
366 // Swatch and gaps:
367 col_size += KiROUND( 14 * GetDPIScaleFactor() ) + 12;
368 }
369
370 if( m_itemsGrid->IsColShown( col ) )
371 m_itemsGrid->SetColSize( col, col_size );
372 }
373
374 m_itemsGrid->SetRowLabelSize( 0 );
375
376 Layout();
378 m_initialized = true;
379
380 return true;
381}
382
383
385{
386 if( aFootprintName.IsEmpty() )
387 {
388 m_delayedErrorMessage = _( "Footprint must have a name." );
389 return false;
390 }
391 else if( !FOOTPRINT::IsLibNameValid( aFootprintName ) )
392 {
393 m_delayedErrorMessage.Printf( _( "Footprint name may not contain '%s'." ),
395 return false;
396 }
397
398 return true;
399}
400
401
403{
405 return false;
406
407 if( !DIALOG_SHIM::Validate() )
408 return false;
409
410 // First, test for invalid chars in footprint name
411 wxString footprintName = m_FootprintNameCtrl->GetValue();
412
413 if( !checkFootprintName( footprintName ) )
414 {
415 if( m_NoteBook->GetSelection() != 0 )
416 m_NoteBook->SetSelection( 0 );
417
419 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
420
421 return false;
422 }
423
424 // Check for valid field text properties
425 for( size_t i = 0; i < m_fields->size(); ++i )
426 {
427 PCB_FIELD& field = m_fields->at( i );
428
429 // Check for missing field names.
430 if( field.GetName( false ).IsEmpty() )
431 {
433 m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
436
437 return false;
438 }
439
441 int maxSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
442
443 if( field.GetTextWidth() < minSize || field.GetTextWidth() > maxSize )
444 {
446 m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
448 m_frame->StringFromValue( maxSize, true ) );
451
452 return false;
453 }
454
455 if( field.GetTextHeight() < minSize || field.GetTextHeight() > maxSize )
456 {
458 m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
460 m_frame->StringFromValue( maxSize, true ) );
463
464 return false;
465 }
466
467 // Test for acceptable values for thickness and size and clamp if fails
468 int maxPenWidth = ClampTextPenSize( field.GetTextThickness(), field.GetTextSize() );
469
470 if( field.GetTextThickness() > maxPenWidth )
471 {
472 m_itemsGrid->SetCellValue( i, PFC_THICKNESS,
473 m_frame->StringFromValue( maxPenWidth, true ) );
474
476 m_delayedErrorMessage = _( "The text thickness is too large for the text size.\n"
477 "It will be clamped." );
480
481 return false;
482 }
483 }
484
485 if( !m_netClearance.Validate( 0, INT_MAX ) )
486 return false;
487
488 return true;
489}
490
491
493{
494 if( !Validate() )
495 return false;
496
500 {
501 return false;
502 }
503
505 BOARD_COMMIT commit( m_frame );
506 commit.Modify( m_footprint );
507
508 // Must be done inside the commit to capture the undo state
509 // This will call TransferDataToWindow() on the 3D panel and
510 // the embedded files panel.
511 if( !DIALOG_SHIM::TransferDataFromWindow() )
512 return false;
513
514 // Clear out embedded files that are no longer in use
515 std::set<wxString> files;
516 std::set<wxString> files_to_delete;
517
518 // Get the new files from the footprint fields
519 for( size_t ii = 0; ii < m_fields->size(); ++ii )
520 {
521 const wxString& name = m_fields->at( ii ).GetText();
522
523 if( name.StartsWith( FILEEXT::KiCadUriPrefix ) )
524 files.insert( name );
525 }
526
527 // Find any files referenced in the old fields that are not in the new fields
528 for( PCB_FIELD* field : m_footprint->GetFields() )
529 {
530 if( field->GetText().StartsWith( FILEEXT::KiCadUriPrefix ) )
531 {
532 if( files.find( field->GetText() ) == files.end() )
533 files_to_delete.insert( field->GetText() );
534 }
535 }
536
537 for( const wxString& file : files_to_delete )
538 {
539 wxString name = file.Mid( FILEEXT::KiCadUriPrefix.size() + 3 ); // Skip "kicad-embed://"
541 }
542
543 LIB_ID fpID = m_footprint->GetFPID();
544 fpID.SetLibItemName( m_FootprintNameCtrl->GetValue() );
545 m_footprint->SetFPID( fpID );
546
548 m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
549
550 // Update fields
551
552 std::vector<PCB_FIELD*> items_to_remove;
553 size_t i = 0;
554
555 for( PCB_FIELD* field : m_footprint->GetFields() )
556 {
557 // copy grid table entries till we run out, then delete any remaining texts
558 if( i < m_fields->size() )
559 *field = m_fields->at( i++ );
560 else
561 items_to_remove.push_back( field );
562 }
563
564 // Remove text items:
566
567 for( PCB_TEXT* item : items_to_remove )
568 {
569 selTool->RemoveItemFromSel( item );
570 view->Remove( item );
571 item->DeleteStructure();
572 }
573
574 // if there are still grid table entries, create new fields for them
575 while( i < m_fields->size() )
576 view->Add( m_footprint->AddField( m_fields->at( i++ ) ) );
577
578 LSET privateLayers;
579
580 for( PCB_LAYER_ID layer : *m_privateLayers )
581 privateLayers.set( layer );
582
583 m_footprint->SetPrivateLayers( privateLayers );
584
585 int attributes = 0;
586
587 switch( m_componentType->GetSelection() )
588 {
589 case 0: attributes |= FP_THROUGH_HOLE; break;
590 case 1: attributes |= FP_SMD; break;
591 default: break;
592 }
593
594 if( m_boardOnly->GetValue() )
595 attributes |= FP_BOARD_ONLY;
596
597 if( m_excludeFromPosFiles->GetValue() )
598 attributes |= FP_EXCLUDE_FROM_POS_FILES;
599
600 if( m_excludeFromBOM->GetValue() )
601 attributes |= FP_EXCLUDE_FROM_BOM;
602
603 if( m_noCourtyards->GetValue() )
604 attributes |= FP_ALLOW_MISSING_COURTYARD;
605
606 if( m_cbDNP->GetValue() )
607 attributes |= FP_DNP;
608
609 if( m_allowBridges->GetValue() )
610 attributes |= FP_ALLOW_SOLDERMASK_BRIDGES;
611
612 m_footprint->SetAttributes( attributes );
613
614 // Initialize mask clearances
615 if( m_netClearance.IsNull() )
617 else
618 m_footprint->SetLocalClearance( m_netClearance.GetValue() );
619
620 if( m_solderMask.IsNull() )
621 m_footprint->SetLocalSolderMaskMargin( {} );
622 else
623 m_footprint->SetLocalSolderMaskMargin( m_solderMask.GetValue() );
624
625 if( m_solderPaste.IsNull() )
626 m_footprint->SetLocalSolderPasteMargin( {} );
627 else
628 m_footprint->SetLocalSolderPasteMargin( m_solderPaste.GetValue() );
629
630 if( m_solderPasteRatio.IsNull() )
631 m_footprint->SetLocalSolderPasteMarginRatio( {} );
632 else
633 m_footprint->SetLocalSolderPasteMarginRatio( m_solderPasteRatio.GetDoubleValue() / 100.0 );
634
635 switch( m_ZoneConnectionChoice->GetSelection() )
636 {
637 default:
638 case 0: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::INHERITED ); break;
639 case 1: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::FULL ); break;
640 case 2: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::THERMAL ); break;
641 case 3: m_footprint->SetLocalZoneConnection( ZONE_CONNECTION::NONE ); break;
642 }
643
644 m_footprint->ClearNetTiePadGroups();
645
646 for( int ii = 0; ii < m_padGroupsGrid->GetNumberRows(); ++ii )
647 {
648 wxString group = m_padGroupsGrid->GetCellValue( ii, 0 );
649
650 if( !group.IsEmpty() )
651 m_footprint->AddNetTiePadGroup( group );
652 }
653
654 // Copy the models from the panel to the footprint
655 std::vector<FP_3DMODEL>& panelList = m_3dPanel->GetModelList();
656 std::vector<FP_3DMODEL>* fpList = &m_footprint->Models();
657 fpList->clear();
658 fpList->insert( fpList->end(), panelList.begin(), panelList.end() );
659
660 commit.Push( _( "Edit Footprint Properties" ) );
661
662 return true;
663}
664
665
667{
669 return;
670
671 const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
672
675
676 // Set active layer if legal; otherwise copy layer from previous text item
678 newField.SetLayer( m_frame->GetActiveLayer() );
679 else
680 newField.SetLayer( m_fields->at( m_fields->size() - 1 ).GetLayer() );
681
682 newField.SetTextSize( dsnSettings.GetTextSize( newField.GetLayer() ) );
683 newField.SetTextThickness( dsnSettings.GetTextThickness( newField.GetLayer() ) );
684 newField.SetItalic( dsnSettings.GetTextItalic( newField.GetLayer() ) );
685
686 m_fields->push_back( newField );
687
688 // notify the grid
689 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
690 m_itemsGrid->ProcessTableMessage( msg );
691
692 m_itemsGrid->SetFocus();
693 m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
694 m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
695
696 m_itemsGrid->EnableCellEditControl( true );
697 m_itemsGrid->ShowCellEditControl();
698
699 OnModify();
700}
701
702
704{
706 return;
707
708 wxArrayInt selectedRows = m_itemsGrid->GetSelectedRows();
709
710 if( selectedRows.empty() && m_itemsGrid->GetGridCursorRow() >= 0 )
711 selectedRows.push_back( m_itemsGrid->GetGridCursorRow() );
712
713 if( selectedRows.empty() )
714 return;
715
716 for( int row : selectedRows )
717 {
718 if( row < m_fields->GetMandatoryRowCount() )
719 {
720 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
722 return;
723 }
724 }
725
726 m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
727 m_itemsGrid->ClearSelection();
728
729 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
730 selectedRows.Sort( []( int* first, int* second )
731 {
732 return *second - *first;
733 } );
734
735 for( int row : selectedRows )
736 {
737 m_fields->erase( m_fields->begin() + row );
738
739 // notify the grid
740 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
741 m_itemsGrid->ProcessTableMessage( msg );
742
743 if( m_itemsGrid->GetNumberRows() > 0 )
744 {
745 m_itemsGrid->MakeCellVisible( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
746 m_itemsGrid->SetGridCursor( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
747 }
748 }
749
750 OnModify();
751}
752
753
755{
757 return;
758
759 PCB_LAYER_ID nextLayer = User_1;
760
761 while( alg::contains( *m_privateLayers, nextLayer ) && nextLayer < User_45 )
762 nextLayer = ToLAYER_ID( nextLayer + 1 );
763
764 m_privateLayers->push_back( nextLayer );
765
766 // notify the grid
767 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
768 m_privateLayersGrid->ProcessTableMessage( msg );
769
770 m_privateLayersGrid->SetFocus();
771 m_privateLayersGrid->MakeCellVisible( m_privateLayers->size() - 1, 0 );
772 m_privateLayersGrid->SetGridCursor( m_privateLayers->size() - 1, 0 );
773
774 OnModify();
775}
776
777
779{
781 return;
782
783 int curRow = m_privateLayersGrid->GetGridCursorRow();
784
785 if( curRow < 0 )
786 return;
787
788 m_privateLayers->erase( m_privateLayers->begin() + curRow );
789
790 // notify the grid
791 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
792 m_privateLayersGrid->ProcessTableMessage( msg );
793
794 if( m_privateLayersGrid->GetNumberRows() > 0 )
795 {
796 m_privateLayersGrid->MakeCellVisible( std::max( 0, curRow-1 ),
797 m_privateLayersGrid->GetGridCursorCol() );
798 m_privateLayersGrid->SetGridCursor( std::max( 0, curRow-1 ),
799 m_privateLayersGrid->GetGridCursorCol() );
800 }
801
802 OnModify();
803}
804
805
807{
809 return;
810
811 m_padGroupsGrid->AppendRows( 1 );
812
813 m_padGroupsGrid->SetFocus();
814 m_padGroupsGrid->MakeCellVisible( m_padGroupsGrid->GetNumberRows() - 1, 0 );
815 m_padGroupsGrid->SetGridCursor( m_padGroupsGrid->GetNumberRows() - 1, 0 );
816
817 m_padGroupsGrid->EnableCellEditControl( true );
818 m_padGroupsGrid->ShowCellEditControl();
819
820 OnModify();
821}
822
823
825{
827 return;
828
829 wxArrayInt selectedRows = m_padGroupsGrid->GetSelectedRows();
830 int curRow = m_padGroupsGrid->GetGridCursorRow();
831
832 if( selectedRows.empty() && curRow >= 0 && curRow < m_padGroupsGrid->GetNumberRows() )
833 selectedRows.Add( curRow );
834
835 for( int ii = selectedRows.Count() - 1; ii >= 0; --ii )
836 {
837 int row = selectedRows.Item( ii );
838 m_padGroupsGrid->DeleteRows( row, 1 );
839 curRow = std::min( curRow, row );
840 }
841
842 curRow = std::max( 0, curRow - 1 );
843 m_padGroupsGrid->MakeCellVisible( curRow, m_padGroupsGrid->GetGridCursorCol() );
844 m_padGroupsGrid->SetGridCursor( curRow, m_padGroupsGrid->GetGridCursorCol() );
845
846 OnModify();
847}
848
849
851{
852 // Account for scroll bars
854
855 itemsWidth -= m_itemsGrid->GetRowLabelSize();
856
857 for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
858 {
859 if( i == 1 )
860 continue;
861
862 itemsWidth -= m_itemsGrid->GetColSize( i );
863 }
864
865 m_itemsGrid->SetColSize(
866 1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
867
868 // Update the width private layers grid
869 m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
871
872 // Update the width net tie pad groups grid
873 m_padGroupsGrid->SetColSize( 0, std::max( m_padGroupsGrid->GetClientSize().x,
875
876 // Update the width of the 3D panel
878}
879
880
882{
883 // Handle a delayed focus. The delay allows us to:
884 // a) change focus when the error was triggered from within a killFocus handler
885 // b) show the correct notebook page in the background before the error dialog comes up
886 // when triggered from an OK or a notebook page change
887
888 if( static_cast<int>( m_delayedFocusPage ) >= 0 )
889 {
890 if( m_NoteBook->GetSelection() != static_cast<int>( m_delayedFocusPage ) )
891 m_NoteBook->ChangeSelection( static_cast<int>( m_delayedFocusPage ) );
892
893 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
894 }
895
896 if( !m_delayedErrorMessage.IsEmpty() )
897 {
898 // We will re-enter this routine when the error dialog is displayed, so make
899 // sure we don't keep putting up more dialogs.
900 wxString msg = m_delayedErrorMessage;
901 m_delayedErrorMessage = wxEmptyString;
902
903 // Do not use DisplayErrorMessage(); it screws up window order on Mac
904 DisplayError( nullptr, msg );
905 }
906
908 {
909 m_delayedFocusCtrl->SetFocus();
910
911 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
912 textEntry->SelectAll();
913
914 m_delayedFocusCtrl = nullptr;
915 }
916 else if( m_delayedFocusGrid )
917 {
918 m_delayedFocusGrid->SetFocus();
921
922 if( !( m_delayedFocusColumn == 0 && m_delayedFocusRow < m_fields->GetMandatoryRowCount() ) )
923 m_delayedFocusGrid->EnableCellEditControl( true );
924
925 m_delayedFocusGrid->ShowCellEditControl();
926
927 m_delayedFocusGrid = nullptr;
930 }
931}
932
933
935{
936 wxSize new_size = aEvent.GetSize();
937
938 if( ( !m_itemsGrid->IsCellEditControlShown() || m_lastRequestedSize != new_size )
939 && m_gridSize != new_size )
940 {
941 m_gridSize = new_size;
942
943 // A trick to fix a cosmetic issue: when, in m_itemsGrid, a layer selector widget has
944 // the focus (is activated in column 6) when resizing the grid, the widget is not moved.
945 // So just change the widget having the focus in this case
946 if( m_NoteBook->GetSelection() == 0 && !m_itemsGrid->HasFocus() )
947 {
948 int col = m_itemsGrid->GetGridCursorCol();
949
950 if( col == 6 ) // a layer selector widget can be activated
951 m_itemsGrid->SetFocus();
952 }
953
955 }
956
957 // We store this value to check whether the dialog is changing size. This might indicate
958 // that the user is scaling the dialog with an editor shown. Some editors do not close
959 // (at least on GTK) when the user drags a dialog corner
960 m_lastRequestedSize = new_size;
961
962 // Always propagate for a grid repaint (needed if the height changes, as well as width)
963 aEvent.Skip();
964}
965
966
968{
970 aEvent.Veto();
971
973 aEvent.Veto();
974}
975
976
978{
979 if( m_initialized )
980 OnModify();
981}
982
983
985{
986 if( m_initialized )
987 OnModify();
988}
989
990
992{
993 if( m_initialized )
994 OnModify();
995}
const char * name
Definition: DXF_plotter.cpp:59
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
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
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
BASE_SET & set(size_t pos)
Definition: base_set.h:116
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:239
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:290
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:295
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:820
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:616
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
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:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void OnModify()
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:254
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:524
int GetTextWidth() const
Definition: eda_text.h:251
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:282
int GetTextThickness() const
Definition: eda_text.h:126
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition: eda_text.cpp:298
VECTOR2I GetTextSize() const
Definition: eda_text.h:248
void RemoveFile(const wxString &name, bool aErase=true)
Remove a file from the collection and frees the memory.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const override
Return the BOARD_DESIGN_SETTINGS for the open project.
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
Provide a custom wxValidator object for limiting the allowable characters when defining footprint nam...
Definition: validators.h:62
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:247
wxString GetLibDescription() const
Definition: footprint.h:255
ZONE_CONNECTION GetLocalZoneConnection() const
Definition: footprint.h:286
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:2304
PCB_FIELD * AddField(const PCB_FIELD &aField)
Add a field to the symbol.
Definition: footprint.cpp:654
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:259
void SetAttributes(int aAttributes)
Definition: footprint.h:289
std::optional< int > GetLocalSolderPasteMargin() const
Definition: footprint.h:279
int GetNextFieldId() const
Return the next ID for a field for this footprint.
Definition: footprint.h:742
void SetPrivateLayers(LSET aLayers)
Adds an item to the container.
Definition: footprint.h:146
std::optional< int > GetLocalClearance() const
Definition: footprint.h:273
int GetAttributes() const
Definition: footprint.h:288
LSET GetPrivateLayers() const
Definition: footprint.h:145
const std::vector< wxString > & GetNetTiePadGroups() const
Definition: footprint.h:337
const LIB_ID & GetFPID() const
Definition: footprint.h:246
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:282
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
Definition: footprint.cpp:648
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:2315
void SetLibDescription(const wxString &aDesc)
Definition: footprint.h:256
void SetLocalClearance(std::optional< int > aClearance)
Definition: footprint.h:274
std::optional< int > GetLocalSolderMaskMargin() const
Definition: footprint.h:276
wxString GetKeywords() const
Definition: footprint.h:258
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:74
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: lset.h:37
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:699
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:628
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:564
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:297
EMBEDDED_FILES * GetLocalFiles()
bool TransferDataToWindow() override
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
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:92
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
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
void SetValue(int aRow, int aCol, const wxString &aValue) 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:73
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).
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
Definition: wx_grid.cpp:45
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculate the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:778
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:496
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:277
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:451
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:466
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:646
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
This file is part of the common library.
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_MM
Minimum text size (1 micron).
Definition: eda_text.h:47
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition: eda_text.h:48
@ FP_SMD
Definition: footprint.h:80
@ FP_DNP
Definition: footprint.h:87
@ FP_ALLOW_MISSING_COURTYARD
Definition: footprint.h:86
@ FP_EXCLUDE_FROM_POS_FILES
Definition: footprint.h:81
@ FP_BOARD_ONLY
Definition: footprint.h:83
@ FP_EXCLUDE_FROM_BOM
Definition: footprint.h:82
@ FP_THROUGH_HOLE
Definition: footprint.h:79
@ FP_ALLOW_SOLDERMASK_BRIDGES
Definition: footprint.h:85
int ClampTextPenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition: gr_text.cpp:72
static const std::string KiCadUriPrefix
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ User_45
Definition: layer_ids.h:168
@ Edge_Cuts
Definition: layer_ids.h:112
@ Margin
Definition: layer_ids.h:113
@ User_1
Definition: layer_ids.h:124
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:710
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: wxgtk/ui.cpp:252
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:155
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
@ PFC_HEIGHT
@ PFC_THICKNESS
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 mmToIU(double mm) const
Definition: base_units.h:88
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
#define DO_TRANSLATE
Custom text control validator definitions.
@ THERMAL
Use thermal relief for pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper