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-2023 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
321
322 switch( m_footprint->GetZoneConnection() )
323 {
324 default:
325 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
326 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
327 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
328 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
329 }
330
331 for( const wxString& group : m_footprint->GetNetTiePadGroups() )
332 {
333 if( !group.IsEmpty() )
334 {
335 m_padGroupsGrid->AppendRows( 1 );
336 m_padGroupsGrid->SetCellValue( m_padGroupsGrid->GetNumberRows() - 1, 0, group );
337 }
338 }
339
340 // Items grid
341 for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
342 {
343 // Adjust min size to the column label size
344 m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false ) );
345 // Adjust the column size.
346 int col_size = m_itemsGrid->GetVisibleWidth( col );
347
348 if( col == FPT_LAYER ) // This one's a drop-down. Check all possible values.
349 {
350 BOARD* board = m_footprint->GetBoard();
351
352 for( PCB_LAYER_ID layer : board->GetEnabledLayers().Seq() )
353 col_size = std::max( col_size, GetTextExtent( board->GetLayerName( layer ) ).x );
354
355 // And the swatch:
356 col_size += 20;
357 }
358
359 if( m_itemsGrid->IsColShown( col ) )
360 m_itemsGrid->SetColSize( col, col_size );
361 }
362
363 m_itemsGrid->SetRowLabelSize( 0 );
364
365 Layout();
367
368 return true;
369}
370
371
373{
374 if( aFootprintName.IsEmpty() )
375 {
376 m_delayedErrorMessage = _( "Footprint must have a name." );
377 return false;
378 }
379 else if( !FOOTPRINT::IsLibNameValid( aFootprintName ) )
380 {
381 m_delayedErrorMessage.Printf( _( "Footprint name may not contain '%s'." ),
383 return false;
384 }
385
386 return true;
387}
388
389
391{
393 return false;
394
395 if( !DIALOG_SHIM::Validate() )
396 return false;
397
398 // First, test for invalid chars in footprint name
399 wxString footprintName = m_FootprintNameCtrl->GetValue();
400
401 if( !checkFootprintName( footprintName ) )
402 {
403 if( m_NoteBook->GetSelection() != 0 )
404 m_NoteBook->SetSelection( 0 );
405
407 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
408
409 return false;
410 }
411
412 // Check for valid field text properties
413 for( size_t i = 0; i < m_fields->size(); ++i )
414 {
415 PCB_FIELD* field = m_fields->at( i );
416
417 // Check for missing field names.
418 if( field->GetName( false ).IsEmpty() )
419 {
421 m_delayedErrorMessage = wxString::Format( _( "Fields must have a name." ) );
424
425 return false;
426 }
427
429 int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
430
431 if( field->GetTextWidth() < minSize || field->GetTextWidth() > maxSize )
432 {
434 m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
436 m_frame->StringFromValue( maxSize, true ) );
439
440 return false;
441 }
442
443 if( field->GetTextHeight() < minSize || field->GetTextHeight() > maxSize )
444 {
446 m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
448 m_frame->StringFromValue( maxSize, true ) );
451
452 return false;
453 }
454
455 // Test for acceptable values for thickness and size and clamp if fails
456 int maxPenWidth = Clamp_Text_PenSize( field->GetTextThickness(), field->GetTextSize() );
457
458 if( field->GetTextThickness() > maxPenWidth )
459 {
460 m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
461 m_frame->StringFromValue( maxPenWidth, true ) );
462
464 m_delayedErrorMessage = _( "The text thickness is too large for the text size.\n"
465 "It will be clamped." );
468
469 return false;
470 }
471 }
472
473 if( !m_netClearance.Validate( 0, INT_MAX ) )
474 return false;
475
476 return true;
477}
478
479
481{
482 if( !Validate() )
483 return false;
484
485 if( !DIALOG_SHIM::TransferDataFromWindow() )
486 return false;
487
491 {
492 return false;
493 }
494
495 // This only commits the editor, model updating is done below so it is inside
496 // the commit
498 return false;
499
501 BOARD_COMMIT commit( m_frame );
502 commit.Modify( m_footprint );
503
504 LIB_ID fpID = m_footprint->GetFPID();
505 fpID.SetLibItemName( m_FootprintNameCtrl->GetValue() );
506 m_footprint->SetFPID( fpID );
507
509 m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
510
511 // Update fields
512
513 std::vector<PCB_TEXT*> items_to_remove;
514 size_t i = 0;
515
516 for( PCB_FIELD* field : m_footprint->GetFields() )
517 {
518 // copy grid table entries till we run out, then delete any remaining texts
519 if( i < m_fields->size() )
520 field = m_fields->at( i++ );
521 else
522 items_to_remove.push_back( field );
523 }
524
525 // Remove text items:
527
528 for( PCB_TEXT* item : items_to_remove )
529 {
530 selTool->RemoveItemFromSel( item );
531 view->Remove( item );
532 item->DeleteStructure();
533 }
534
535
536 // if there are still grid table entries, create new fields for them
537 while( i < m_fields->size() )
538 {
539 view->Add( m_footprint->AddField( *m_fields->at( i++ ) ) );
540 }
541
542 LSET privateLayers;
543
544 for( PCB_LAYER_ID layer : *m_privateLayers )
545 privateLayers.set( layer );
546
547 m_footprint->SetPrivateLayers( privateLayers );
548
549 int attributes = 0;
550
551 switch( m_componentType->GetSelection() )
552 {
553 case 0: attributes |= FP_THROUGH_HOLE; break;
554 case 1: attributes |= FP_SMD; break;
555 default: break;
556 }
557
558 if( m_boardOnly->GetValue() )
559 attributes |= FP_BOARD_ONLY;
560
561 if( m_excludeFromPosFiles->GetValue() )
562 attributes |= FP_EXCLUDE_FROM_POS_FILES;
563
564 if( m_excludeFromBOM->GetValue() )
565 attributes |= FP_EXCLUDE_FROM_BOM;
566
567 if( m_noCourtyards->GetValue() )
568 attributes |= FP_ALLOW_MISSING_COURTYARD;
569
570 if( m_cbDNP->GetValue() )
571 attributes |= FP_DNP;
572
573 if( m_allowBridges->GetValue() )
574 attributes |= FP_ALLOW_SOLDERMASK_BRIDGES;
575
576 m_footprint->SetAttributes( attributes );
577
578 // Initialize masks clearances
583
584 switch( m_ZoneConnectionChoice->GetSelection() )
585 {
586 default:
587 case 0: m_footprint->SetZoneConnection( ZONE_CONNECTION::INHERITED ); break;
588 case 1: m_footprint->SetZoneConnection( ZONE_CONNECTION::FULL ); break;
589 case 2: m_footprint->SetZoneConnection( ZONE_CONNECTION::THERMAL ); break;
590 case 3: m_footprint->SetZoneConnection( ZONE_CONNECTION::NONE ); break;
591 }
592
594
595 for( int ii = 0; ii < m_padGroupsGrid->GetNumberRows(); ++ii )
596 {
597 wxString group = m_padGroupsGrid->GetCellValue( ii, 0 );
598
599 if( !group.IsEmpty() )
601 }
602
603 // Copy the models from the panel to the footprint
604 std::vector<FP_3DMODEL>& panelList = m_3dPanel->GetModelList();
605 std::vector<FP_3DMODEL>* fpList = &m_footprint->Models();
606 fpList->clear();
607 fpList->insert( fpList->end(), panelList.begin(), panelList.end() );
608
609 commit.Push( _( "Modify footprint properties" ) );
610
611 return true;
612}
613
614
615static bool footprintIsFromBoard( FOOTPRINT* aFootprint )
616{
617 return aFootprint->GetLink() != niluuid;
618}
619
620
622{
624 {
625 // Currently: nothing to do
626 }
627}
628
629
631{
633 return;
634
635 int fieldId = (int) m_fields->size();
636 const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
637 PCB_FIELD* newField =
638 new PCB_FIELD( m_footprint, m_fields->size(),
640
641 // Set active layer if legal; otherwise copy layer from previous text item
643 newField->SetLayer( m_frame->GetActiveLayer() );
644 else
645 newField->SetLayer( m_fields->at( m_fields->size() - 1 )->GetLayer() );
646
647 newField->SetTextSize( dsnSettings.GetTextSize( newField->GetLayer() ) );
648 newField->SetTextThickness( dsnSettings.GetTextThickness( newField->GetLayer() ) );
649 newField->SetItalic( dsnSettings.GetTextItalic( newField->GetLayer() ) );
650
651 m_fields->push_back( newField );
652
653 // notify the grid
654 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
655 m_itemsGrid->ProcessTableMessage( msg );
656
657 m_itemsGrid->SetFocus();
658 m_itemsGrid->MakeCellVisible( m_fields->size() - 1, 0 );
659 m_itemsGrid->SetGridCursor( m_fields->size() - 1, 0 );
660
661 m_itemsGrid->EnableCellEditControl( true );
662 m_itemsGrid->ShowCellEditControl();
663}
664
665
667{
669 return;
670
671 wxArrayInt selectedRows = m_itemsGrid->GetSelectedRows();
672
673 if( selectedRows.empty() && m_itemsGrid->GetGridCursorRow() >= 0 )
674 selectedRows.push_back( m_itemsGrid->GetGridCursorRow() );
675
676 if( selectedRows.empty() )
677 return;
678
679 for( int row : selectedRows )
680 {
681 if( row < MANDATORY_FIELDS )
682 {
683 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
685 return;
686 }
687 }
688
689 m_itemsGrid->CommitPendingChanges( true /* quiet mode */ );
690 m_itemsGrid->ClearSelection();
691
692 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
693 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
694
695 for( int row : selectedRows )
696 {
697 m_fields->erase( m_fields->begin() + row );
698
699 // notify the grid
700 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
701 m_itemsGrid->ProcessTableMessage( msg );
702
703 if( m_itemsGrid->GetNumberRows() > 0 )
704 {
705 m_itemsGrid->MakeCellVisible( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
706 m_itemsGrid->SetGridCursor( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
707 }
708 }
709}
710
711
713{
715 return;
716
717 PCB_LAYER_ID nextLayer = User_1;
718
719 while( alg::contains( *m_privateLayers, nextLayer ) && nextLayer < User_9 )
720 nextLayer = ToLAYER_ID( nextLayer + 1 );
721
722 m_privateLayers->push_back( nextLayer );
723
724 // notify the grid
725 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
726 m_privateLayersGrid->ProcessTableMessage( msg );
727
728 m_privateLayersGrid->SetFocus();
729 m_privateLayersGrid->MakeCellVisible( m_privateLayers->size() - 1, 0 );
730 m_privateLayersGrid->SetGridCursor( m_privateLayers->size() - 1, 0 );
731}
732
733
735{
737 return;
738
739 int curRow = m_privateLayersGrid->GetGridCursorRow();
740
741 if( curRow < 0 )
742 return;
743
744 m_privateLayers->erase( m_privateLayers->begin() + curRow );
745
746 // notify the grid
747 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
748 m_privateLayersGrid->ProcessTableMessage( msg );
749
750 if( m_privateLayersGrid->GetNumberRows() > 0 )
751 {
752 m_privateLayersGrid->MakeCellVisible( std::max( 0, curRow-1 ),
753 m_privateLayersGrid->GetGridCursorCol() );
754 m_privateLayersGrid->SetGridCursor( std::max( 0, curRow-1 ),
755 m_privateLayersGrid->GetGridCursorCol() );
756 }
757}
758
759
761{
763 return;
764
765 m_padGroupsGrid->AppendRows( 1 );
766
767 m_padGroupsGrid->SetFocus();
768 m_padGroupsGrid->MakeCellVisible( m_padGroupsGrid->GetNumberRows() - 1, 0 );
769 m_padGroupsGrid->SetGridCursor( m_padGroupsGrid->GetNumberRows() - 1, 0 );
770
771 m_padGroupsGrid->EnableCellEditControl( true );
772 m_padGroupsGrid->ShowCellEditControl();
773}
774
775
777{
779 return;
780
781 wxArrayInt selectedRows = m_padGroupsGrid->GetSelectedRows();
782 int curRow = m_padGroupsGrid->GetGridCursorRow();
783
784 if( selectedRows.empty() && curRow >= 0 && curRow < m_padGroupsGrid->GetNumberRows() )
785 selectedRows.Add( curRow );
786
787 for( int ii = selectedRows.Count() - 1; ii >= 0; --ii )
788 {
789 int row = selectedRows.Item( ii );
790 m_padGroupsGrid->DeleteRows( row, 1 );
791 curRow = std::min( curRow, row );
792 }
793
794 curRow = std::max( 0, curRow - 1 );
795 m_padGroupsGrid->MakeCellVisible( curRow, m_padGroupsGrid->GetGridCursorCol() );
796 m_padGroupsGrid->SetGridCursor( curRow, m_padGroupsGrid->GetGridCursorCol() );
797}
798
799
801{
802 // Account for scroll bars
804
805 itemsWidth -= m_itemsGrid->GetRowLabelSize();
806
807 for( int i = 0; i < m_itemsGrid->GetNumberCols(); i++ )
808 {
809 if( i == 1 )
810 continue;
811
812 itemsWidth -= m_itemsGrid->GetColSize( i );
813 }
814
815 m_itemsGrid->SetColSize(
816 1, std::max( itemsWidth, m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
817
818 // Update the width private layers grid
819 m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
821
822 // Update the width net tie pad groups grid
823 m_padGroupsGrid->SetColSize( 0, std::max( m_padGroupsGrid->GetClientSize().x,
825
826 // Update the width of the 3D panel
828}
829
830
832{
833 // Handle a delayed focus. The delay allows us to:
834 // a) change focus when the error was triggered from within a killFocus handler
835 // b) show the correct notebook page in the background before the error dialog comes up
836 // when triggered from an OK or a notebook page change
837
838 if( static_cast<int>( m_delayedFocusPage ) >= 0 )
839 {
840 if( m_NoteBook->GetSelection() != static_cast<int>( m_delayedFocusPage ) )
841 m_NoteBook->ChangeSelection( static_cast<int>( m_delayedFocusPage ) );
842
843 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
844 }
845
846 if( !m_delayedErrorMessage.IsEmpty() )
847 {
848 // We will re-enter this routine when the error dialog is displayed, so make
849 // sure we don't keep putting up more dialogs.
850 wxString msg = m_delayedErrorMessage;
851 m_delayedErrorMessage = wxEmptyString;
852
853 // Do not use DisplayErrorMessage(); it screws up window order on Mac
854 DisplayError( nullptr, msg );
855 }
856
858 {
859 m_delayedFocusCtrl->SetFocus();
860
861 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
862 textEntry->SelectAll();
863
864 m_delayedFocusCtrl = nullptr;
865 }
866 else if( m_delayedFocusGrid )
867 {
868 m_delayedFocusGrid->SetFocus();
871
873 m_delayedFocusGrid->EnableCellEditControl( true );
874
875 m_delayedFocusGrid->ShowCellEditControl();
876
877 m_delayedFocusGrid = nullptr;
880 }
881}
882
883
885{
886 wxSize new_size = aEvent.GetSize();
887
888 if( ( !m_itemsGrid->IsCellEditControlShown() || m_lastRequestedSize != new_size )
889 && m_gridSize != new_size )
890 {
891 m_gridSize = new_size;
892
893 // A trick to fix a cosmetic issue: when, in m_itemsGrid, a layer selector widget has
894 // the focus (is activated in column 6) when resizing the grid, the widget is not moved.
895 // So just change the widget having the focus in this case
896 if( m_NoteBook->GetSelection() == 0 && !m_itemsGrid->HasFocus() )
897 {
898 int col = m_itemsGrid->GetGridCursorCol();
899
900 if( col == 6 ) // a layer selector widget can be activated
901 m_itemsGrid->SetFocus();
902 }
903
905 }
906
907 // We store this value to check whether the dialog is changing size. This might indicate
908 // that the user is scaling the dialog with an editor shown. Some editors do not close
909 // (at least on GTK) when the user drags a dialog corner
910 m_lastRequestedSize = new_size;
911
912 // Always propagate for a grid repaint (needed if the height changes, as well as width)
913 aEvent.Skip();
914}
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
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
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:225
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:259
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:45
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:649
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:536
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
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:224
void SetTextSize(VECTOR2I aNewSize)
Definition: eda_text.cpp:358
int GetTextWidth() const
Definition: eda_text.h:221
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:218
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
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:1867
PCB_FIELD * AddField(const PCB_FIELD &aField)
Add a field to the symbol.
Definition: footprint.cpp:336
int GetLocalClearance() const
Definition: footprint.h:257
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:240
void SetAttributes(int aAttributes)
Definition: footprint.h:278
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:271
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: footprint.h:272
void SetPrivateLayers(LSET aLayers)
Adds an item to the container.
Definition: footprint.h:126
void SetLocalSolderPasteMargin(int aMargin)
Definition: footprint.h:269
int GetAttributes() const
Definition: footprint.h:277
void ClearNetTiePadGroups()
Definition: footprint.h:301
LSET GetPrivateLayers() const
Definition: footprint.h:125
int GetLocalSolderPasteMargin() const
Definition: footprint.h:268
const std::vector< wxString > & GetNetTiePadGroups() const
Definition: footprint.h:299
void SetLocalClearance(int aClearance)
Definition: footprint.h:258
const LIB_ID & GetFPID() const
Definition: footprint.h:230
void SetLocalSolderMaskMargin(int aMargin)
Definition: footprint.h:255
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with PCB_TEXTs.
Definition: footprint.cpp:321
void AddNetTiePadGroup(const wxString &aGroup)
Definition: footprint.h:306
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: footprint.h:274
KIID GetLink() const
Definition: footprint.h:797
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:202
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:1878
void SetLibDescription(const wxString &aDesc)
Definition: footprint.h:237
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:275
wxString GetKeywords() const
Definition: footprint.h:239
int GetLocalSolderMaskMargin() const
Definition: footprint.h:254
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:59
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:68
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:556
LSEQ UIOrder() const
Definition: lset.cpp:931
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:850
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:782
std::vector< FP_3DMODEL > & GetModelList()
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 long long int GetValue()
Return the current value in Internal Units.
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 double GetDoubleValue()
Return the current value in Internal Units.
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.
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:545
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:298
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:254
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:268
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:448
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:941
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.