KiCad PCB EDA Suite
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-2022 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>
47#include <pcbnew.h>
51#include <tool/tool_manager.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 )
90{
91 m_layerColAttr->IncRef();
92 return m_layerColAttr;
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_netClearance( aParent, m_NetClearanceLabel, m_NetClearanceCtrl, m_NetClearanceUnits ),
132 m_solderMask( aParent, m_SolderMaskMarginLabel, m_SolderMaskMarginCtrl,
133 m_SolderMaskMarginUnits ),
134 m_solderPaste( aParent, m_SolderPasteMarginLabel, m_SolderPasteMarginCtrl,
135 m_SolderPasteMarginUnits ),
136 m_solderPasteRatio( aParent, m_PasteMarginRatioLabel, m_PasteMarginRatioCtrl,
137 m_PasteMarginRatioUnits ),
138 m_gridSize( 0, 0 ),
139 m_lastRequestedSize( 0, 0 )
140{
141 SetEvtHandlerEnabled( false );
142 // Create the 3D models page
144 m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
145
148
149 m_delayedErrorMessage = wxEmptyString;
150 m_delayedFocusCtrl = nullptr;
151 m_delayedFocusGrid = nullptr;
155
156 // Give an icon
157 wxIcon icon;
158 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_modedit ) );
159 SetIcon( icon );
160
161 // Give a bit more room for combobox editors
162 m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
163 m_privateLayersGrid->SetDefaultRowSize( m_privateLayersGrid->GetDefaultRowSize() + 4 );
164
167
168 m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
170 [this]( wxCommandEvent& aEvent )
171 {
172 OnAddLayer( aEvent );
173 } ) );
174 m_padGroupsGrid->PushEventHandler( new GRID_TRICKS( m_padGroupsGrid,
175 [this]( wxCommandEvent& aEvent )
176 {
177 OnAddPadGroup( aEvent );
178 } ) );
179
180 m_itemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
181 m_privateLayersGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
182 m_padGroupsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
183
184 // Show/hide columns according to the user's preference
186
188
189 // Set font sizes
190 wxFont infoFont = KIUI::GetInfoFont( this );
191 infoFont.SetStyle( wxFONTSTYLE_ITALIC );
192 m_staticTextInfoCopper->SetFont( infoFont );
193 m_staticTextInfoPaste->SetFont( infoFont );
194
195 if( static_cast<int>( m_page ) >= 0 )
196 m_NoteBook->SetSelection( (unsigned) m_page );
197
199 {
204 }
206 {
208 }
209
211
214
215 // Configure button logos
222
224
226 SetEvtHandlerEnabled( true );
227}
228
229
231{
233 m_itemsGrid->GetShownColumns().ToStdString();
234
235 // Prevents crash bug in wxGrid's d'tor
238
239 // Delete the GRID_TRICKS.
240 m_itemsGrid->PopEventHandler( true );
241 m_privateLayersGrid->PopEventHandler( true );
242 m_padGroupsGrid->PopEventHandler( true );
243
244 m_page = static_cast<NOTEBOOK_PAGES>( m_NoteBook->GetSelection() );
245
246 // the GL canvas on the 3D models page has to be visible before it is destroyed
247 m_NoteBook->SetSelection( static_cast<int>( NOTEBOOK_PAGES::PAGE_3D_MODELS ) );
248}
249
250
252{
253 LIB_ID fpID = m_footprint->GetFPID();
254 wxString footprintName = fpID.GetLibItemName();
255
256 m_FootprintNameCtrl->ChangeValue( footprintName );
257
258 m_DocCtrl->SetValue( m_footprint->GetDescription() );
259 m_KeywordCtrl->SetValue( m_footprint->GetKeywords() );
260
261 if( !wxDialog::TransferDataToWindow() )
262 return false;
263
264 if( !m_PanelGeneral->TransferDataToWindow() )
265 return false;
266
267 // Add the models to the panel
269 return false;
270
271 // Footprint Texts
272 m_texts->push_back( m_footprint->Reference() );
273 m_texts->push_back( m_footprint->Value() );
274
275 for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
276 {
277 FP_TEXT* textItem = dyn_cast<FP_TEXT*>( item );
278
279 if( textItem )
280 m_texts->push_back( *textItem );
281 }
282
283 // Notify the grid
284 wxGridTableMessage tmsg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_texts->GetNumberRows() );
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
308 // Local Clearances
309
315
316 switch( m_footprint->GetZoneConnection() )
317 {
318 default:
319 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
320 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
321 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
322 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
323 }
324
325 for( const wxString& group : m_footprint->GetNetTiePadGroups() )
326 {
327 if( !group.IsEmpty() )
328 {
329 m_padGroupsGrid->AppendRows( 1 );
330 m_padGroupsGrid->SetCellValue( m_padGroupsGrid->GetNumberRows() - 1, 0, group );
331 }
332 }
333
334 // Items grid
335 for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
336 {
337 // Adjust min size to the column label size
338 m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false ) );
339 // Adjust the column size.
340 int col_size = m_itemsGrid->GetVisibleWidth( col );
341
342 if( col == FPT_LAYER ) // This one's a drop-down. Check all possible values.
343 {
344 BOARD* board = m_footprint->GetBoard();
345
346 for( PCB_LAYER_ID layer : board->GetEnabledLayers().Seq() )
347 col_size = std::max( col_size, GetTextExtent( board->GetLayerName( layer ) ).x );
348
349 // And the swatch:
350 col_size += 20;
351 }
352
353 if( m_itemsGrid->IsColShown( col ) )
354 m_itemsGrid->SetColSize( col, col_size );
355 }
356
357 m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
358
359 Layout();
361
362 return true;
363}
364
365
367{
368 if( aFootprintName.IsEmpty() )
369 {
370 m_delayedErrorMessage = _( "Footprint must have a name." );
371 return false;
372 }
373 else if( !FOOTPRINT::IsLibNameValid( aFootprintName ) )
374 {
375 m_delayedErrorMessage.Printf( _( "Footprint name may not contain '%s'." ),
377 return false;
378 }
379
380 return true;
381}
382
383
385{
387 return false;
388
389 if( !DIALOG_SHIM::Validate() )
390 return false;
391
392 // First, test for invalid chars in footprint name
393 wxString footprintName = m_FootprintNameCtrl->GetValue();
394
395 if( !checkFootprintName( footprintName ) )
396 {
397 if( m_NoteBook->GetSelection() != 0 )
398 m_NoteBook->SetSelection( 0 );
399
402
403 return false;
404 }
405
406 // Check for empty texts.
407 for( size_t i = 2; i < m_texts->size(); ++i )
408 {
409 FP_TEXT& text = m_texts->at( i );
410
411 if( text.GetText().IsEmpty() )
412 {
413 if( m_NoteBook->GetSelection() != 0 )
414 m_NoteBook->SetSelection( 0 );
415
416 m_delayedErrorMessage = _( "Text items must have some content." );
420
421 return false;
422 }
423
424 if( text.GetTextWidth() < TEXTS_MIN_SIZE || text.GetTextWidth() > TEXTS_MAX_SIZE )
425 {
427 m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
432
433 return false;
434 }
435
436 if( text.GetTextHeight() < TEXTS_MIN_SIZE || text.GetTextHeight() > TEXTS_MAX_SIZE )
437 {
439 m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
444
445 return false;
446 }
447
448 // Test for acceptable values for thickness and size and clamp if fails
449 int maxPenWidth = Clamp_Text_PenSize( text.GetTextThickness(), text.GetTextSize() );
450
451 if( text.GetTextThickness() > maxPenWidth )
452 {
453 m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
454 m_frame->StringFromValue( maxPenWidth, true ) );
455
457 m_delayedErrorMessage = _( "The text thickness is too large for the text size.\n"
458 "It will be clamped." );
461
462 return false;
463 }
464 }
465
466 if( !m_netClearance.Validate( 0, INT_MAX ) )
467 return false;
468
469 return true;
470}
471
472
474{
475 if( !Validate() )
476 return false;
477
478 if( !DIALOG_SHIM::TransferDataFromWindow() )
479 return false;
480
484 {
485 return false;
486 }
487
488 // This only commits the editor, model updating is done below so it is inside
489 // the commit
491 return false;
492
494 BOARD_COMMIT commit( m_frame );
495 commit.Modify( m_footprint );
496
497 LIB_ID fpID = m_footprint->GetFPID();
498 fpID.SetLibItemName( m_FootprintNameCtrl->GetValue() );
499 m_footprint->SetFPID( fpID );
500
501 m_footprint->SetDescription( m_DocCtrl->GetValue() );
502 m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
503
504 // copy reference and value
505 m_footprint->Reference() = m_texts->at( 0 );
506 m_footprint->Value() = m_texts->at( 1 );
507
508 size_t i = 2;
509 std::vector<FP_TEXT*> items_to_remove;
510
511 for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
512 {
513 FP_TEXT* textItem = dynamic_cast<FP_TEXT*>( item );
514
515 if( textItem )
516 {
517 // copy grid table entries till we run out, then delete any remaining texts
518 if( i < m_texts->size() )
519 *textItem = m_texts->at( i++ );
520 else // store this item to remove and delete it later,
521 // after the graphic list is explored:
522 items_to_remove.push_back( textItem );
523 }
524 }
525
526 // Remove text items:
528
529 for( FP_TEXT* item: items_to_remove )
530 {
531 selTool->RemoveItemFromSel( item );
532 view->Remove( item );
533 item->DeleteStructure();
534 }
535
536 // if there are still grid table entries, create new texts for them
537 while( i < m_texts->size() )
538 {
539 FP_TEXT* newText = new FP_TEXT( m_texts->at( i++ ) );
540 m_footprint->Add( newText, ADD_MODE::APPEND );
541 view->Add( newText );
542 }
543
544 LSET privateLayers;
545
546 for( PCB_LAYER_ID layer : *m_privateLayers )
547 privateLayers.set( layer );
548
549 m_footprint->SetPrivateLayers( privateLayers );
550
551 int attributes = 0;
552
553 switch( m_componentType->GetSelection() )
554 {
555 case 0: attributes |= FP_THROUGH_HOLE; break;
556 case 1: attributes |= FP_SMD; break;
557 default: break;
558 }
559
560 if( m_boardOnly->GetValue() )
561 attributes |= FP_BOARD_ONLY;
562
563 if( m_excludeFromPosFiles->GetValue() )
564 attributes |= FP_EXCLUDE_FROM_POS_FILES;
565
566 if( m_excludeFromBOM->GetValue() )
567 attributes |= FP_EXCLUDE_FROM_BOM;
568
569 if( m_noCourtyards->GetValue() )
570 attributes |= FP_ALLOW_MISSING_COURTYARD;
571
572 if( m_allowBridges->GetValue() )
573 attributes |= FP_ALLOW_SOLDERMASK_BRIDGES;
574
575 m_footprint->SetAttributes( attributes );
576
577 // Initialize masks clearances
582
583 switch( m_ZoneConnectionChoice->GetSelection() )
584 {
585 default:
590 }
591
593
594 for( int ii = 0; ii < m_padGroupsGrid->GetNumberRows(); ++ii )
595 {
596 wxString group = m_padGroupsGrid->GetCellValue( ii, 0 );
597
598 if( !group.IsEmpty() )
600 }
601
602 // Copy the models from the panel to the footprint
603 std::vector<FP_3DMODEL>& panelList = m_3dPanel->GetModelList();
604 std::vector<FP_3DMODEL>* fpList = &m_footprint->Models();
605 fpList->clear();
606 fpList->insert( fpList->end(), panelList.begin(), panelList.end() );
607
608 commit.Push( _( "Modify footprint properties" ) );
609
610 return true;
611}
612
613
614static bool footprintIsFromBoard( FOOTPRINT* aFootprint )
615{
616 return aFootprint->GetLink() != niluuid;
617}
618
619
621{
623 {
624 // Currently: nothing to do
625 }
626}
627
628
630{
632 return;
633
634 const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
635 FP_TEXT textItem( m_footprint );
636
637 // Set active layer if legal; otherwise copy layer from previous text item
639 textItem.SetLayer( m_frame->GetActiveLayer() );
640 else
641 textItem.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
642
643 textItem.SetTextSize( dsnSettings.GetTextSize( textItem.GetLayer() ) );
644 textItem.SetTextThickness( dsnSettings.GetTextThickness( textItem.GetLayer() ) );
645 textItem.SetItalic( dsnSettings.GetTextItalic( textItem.GetLayer() ) );
646
647 m_texts->push_back( textItem );
648
649 // notify the grid
650 wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
651 m_itemsGrid->ProcessTableMessage( msg );
652
653 m_itemsGrid->SetFocus();
654 m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
655 m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
656
657 m_itemsGrid->EnableCellEditControl( true );
658 m_itemsGrid->ShowCellEditControl();
659}
660
661
663{
665 return;
666
667 wxArrayInt selectedRows = m_itemsGrid->GetSelectedRows();
668
669 if( selectedRows.empty() && m_itemsGrid->GetGridCursorRow() >= 0 )
670 selectedRows.push_back( m_itemsGrid->GetGridCursorRow() );
671
672 if( selectedRows.empty() )
673 return;
674
675 for( int row : selectedRows )
676 {
677 if( row < 2 )
678 {
679 DisplayError( nullptr, _( "Reference and value are mandatory." ) );
680 return;
681 }
682 }
683
684 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
685 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
686
687 for( int row : selectedRows )
688 {
689 m_texts->erase( m_texts->begin() + row );
690
691 // notify the grid
692 wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
693 m_itemsGrid->ProcessTableMessage( msg );
694
695 if( m_itemsGrid->GetNumberRows() > 0 )
696 {
697 m_itemsGrid->MakeCellVisible( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
698 m_itemsGrid->SetGridCursor( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
699 }
700 }
701}
702
703
705{
707 return;
708
709 PCB_LAYER_ID nextLayer = User_1;
710
711 while( alg::contains( *m_privateLayers, nextLayer ) && nextLayer < User_9 )
712 nextLayer = ToLAYER_ID( nextLayer + 1 );
713
714 m_privateLayers->push_back( nextLayer );
715
716 // notify the grid
717 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
718 m_privateLayersGrid->ProcessTableMessage( msg );
719
720 m_privateLayersGrid->SetFocus();
721 m_privateLayersGrid->MakeCellVisible( m_privateLayers->size() - 1, 0 );
722 m_privateLayersGrid->SetGridCursor( m_privateLayers->size() - 1, 0 );
723}
724
725
727{
729 return;
730
731 int curRow = m_privateLayersGrid->GetGridCursorRow();
732
733 if( curRow < 0 )
734 return;
735
736 m_privateLayers->erase( m_privateLayers->begin() + curRow );
737
738 // notify the grid
739 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
740 m_privateLayersGrid->ProcessTableMessage( msg );
741
742 if( m_privateLayersGrid->GetNumberRows() > 0 )
743 {
744 m_privateLayersGrid->MakeCellVisible( std::max( 0, curRow-1 ),
745 m_privateLayersGrid->GetGridCursorCol() );
746 m_privateLayersGrid->SetGridCursor( std::max( 0, curRow-1 ),
747 m_privateLayersGrid->GetGridCursorCol() );
748 }
749}
750
751
753{
755 return;
756
757 m_padGroupsGrid->AppendRows( 1 );
758
759 m_padGroupsGrid->SetFocus();
760 m_padGroupsGrid->MakeCellVisible( m_padGroupsGrid->GetNumberRows() - 1, 0 );
761 m_padGroupsGrid->SetGridCursor( m_padGroupsGrid->GetNumberRows() - 1, 0 );
762
763 m_padGroupsGrid->EnableCellEditControl( true );
764 m_padGroupsGrid->ShowCellEditControl();
765}
766
767
769{
771 return;
772
773 wxArrayInt selectedRows = m_padGroupsGrid->GetSelectedRows();
774 int curRow = m_padGroupsGrid->GetGridCursorRow();
775
776 if( selectedRows.empty() && curRow >= 0 && curRow < m_padGroupsGrid->GetNumberRows() )
777 selectedRows.Add( curRow );
778
779 for( int ii = selectedRows.Count() - 1; ii >= 0; --ii )
780 {
781 int row = selectedRows.Item( ii );
782 m_padGroupsGrid->DeleteRows( row, 1 );
783 curRow = std::min( curRow, row );
784 }
785
786 curRow = std::max( 0, curRow - 1 );
787 m_padGroupsGrid->MakeCellVisible( curRow, m_padGroupsGrid->GetGridCursorCol() );
788 m_padGroupsGrid->SetGridCursor( curRow, m_padGroupsGrid->GetGridCursorCol() );
789}
790
791
793{
794 // Account for scroll bars
796
797 itemsWidth -= m_itemsGrid->GetRowLabelSize();
798
799 for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
800 itemsWidth -= m_itemsGrid->GetColSize( i );
801
802 m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
803 m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
804
805 // Update the width private layers grid
806 m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
808
809 // Update the width net tie pad groups grid
810 m_padGroupsGrid->SetColSize( 0, std::max( m_padGroupsGrid->GetClientSize().x,
812
813 // Update the width of the 3D panel
815}
816
817
819{
820 // Handle a delayed focus. The delay allows us to:
821 // a) change focus when the error was triggered from within a killFocus handler
822 // b) show the correct notebook page in the background before the error dialog comes up
823 // when triggered from an OK or a notebook page change
824
825 if( static_cast<int>( m_delayedFocusPage ) >= 0 )
826 {
827 if( m_NoteBook->GetSelection() != static_cast<int>( m_delayedFocusPage ) )
828 m_NoteBook->ChangeSelection( static_cast<int>( m_delayedFocusPage ) );
829
831 }
832
833 if( !m_delayedErrorMessage.IsEmpty() )
834 {
835 // We will re-enter this routine when the error dialog is displayed, so make
836 // sure we don't keep putting up more dialogs.
837 wxString msg = m_delayedErrorMessage;
838 m_delayedErrorMessage = wxEmptyString;
839
840 // Do not use DisplayErrorMessage(); it screws up window order on Mac
841 DisplayError( nullptr, msg );
842 }
843
845 {
846 m_delayedFocusCtrl->SetFocus();
847
848 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
849 textEntry->SelectAll();
850
851 m_delayedFocusCtrl = nullptr;
852 }
853 else if( m_delayedFocusGrid )
854 {
855 m_delayedFocusGrid->SetFocus();
858
859 m_delayedFocusGrid->EnableCellEditControl( true );
860 m_delayedFocusGrid->ShowCellEditControl();
861
862 m_delayedFocusGrid = nullptr;
865 }
866}
867
868
870{
871 wxSize new_size = aEvent.GetSize();
872
873 if( ( !m_itemsGrid->IsCellEditControlShown() || m_lastRequestedSize != new_size )
874 && m_gridSize != new_size )
875 {
876 m_gridSize = new_size;
877
878 // A trick to fix a cosmetic issue: when, in m_itemsGrid, a layer selector widget has
879 // the focus (is activated in column 6) when resizing the grid, the widget is not moved.
880 // So just change the widget having the focus in this case
881 if( m_NoteBook->GetSelection() == 0 && !m_itemsGrid->HasFocus() )
882 {
883 int col = m_itemsGrid->GetGridCursorCol();
884
885 if( col == 6 ) // a layer selector widget can be activated
886 m_itemsGrid->SetFocus();
887 }
888
890 }
891
892 // We store this value to check whether the dialog is changing size. This might indicate
893 // that the user is scaling the dialog with an editor shown. Some editors do not close
894 // (at least on GTK) when the user drags a dialog corner
895 m_lastRequestedSize = new_size;
896
897 // Always propagate for a grid repaint (needed if the height changes, as well as width)
898 aEvent.Skip();
899}
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:105
@ icon_modedit
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Container for design settings for a BOARD object.
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
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
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:214
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:565
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:452
COMMIT & Modify(EDA_ITEM *aItem)
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...
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
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:64
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:213
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:1516
void SetDescription(const wxString &aDoc)
Definition: footprint.h:219
int GetLocalClearance() const
Definition: footprint.h:230
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:222
void SetAttributes(int aAttributes)
Definition: footprint.h:251
wxString GetDescription() const
Definition: footprint.h:218
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:244
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: footprint.h:245
void SetPrivateLayers(LSET aLayers)
Adds an item to the container.
Definition: footprint.h:121
void SetLocalSolderPasteMargin(int aMargin)
Definition: footprint.h:242
int GetAttributes() const
Definition: footprint.h:250
void ClearNetTiePadGroups()
Definition: footprint.h:274
LSET GetPrivateLayers() const
Definition: footprint.h:120
int GetLocalSolderPasteMargin() const
Definition: footprint.h:241
const std::vector< wxString > & GetNetTiePadGroups() const
Definition: footprint.h:272
void SetLocalClearance(int aClearance)
Definition: footprint.h:231
const LIB_ID & GetFPID() const
Definition: footprint.h:212
void SetLocalSolderMaskMargin(int aMargin)
Definition: footprint.h:228
void AddNetTiePadGroup(const wxString &aGroup)
Definition: footprint.h:279
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:567
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:567
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: footprint.h:247
KIID GetLink() const
Definition: footprint.h:680
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:184
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:1527
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:248
wxString GetKeywords() const
Definition: footprint.h:221
DRAWINGS & GraphicalItems()
Definition: footprint.h:173
FP_TEXT & Reference()
Definition: footprint.h:568
int GetLocalSolderMaskMargin() const
Definition: footprint.h:227
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:58
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:75
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:109
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
LSEQ UIOrder() const
Definition: lset.cpp:922
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:411
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:841
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
std::vector< FP_3DMODEL > & GetModelList()
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.
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 wxBitmap &aBmp)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
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:520
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:295
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:164
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:262
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:276
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:423
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
This file is part of the common library.
static bool footprintIsFromBoard(FOOTPRINT *aFootprint)
#define _(s)
@ FP_SMD
Definition: footprint.h:69
@ FP_ALLOW_MISSING_COURTYARD
Definition: footprint.h:75
@ FP_EXCLUDE_FROM_POS_FILES
Definition: footprint.h:70
@ FP_BOARD_ONLY
Definition: footprint.h:72
@ FP_EXCLUDE_FROM_BOM
Definition: footprint.h:71
@ FP_THROUGH_HOLE
Definition: footprint.h:68
@ FP_ALLOW_SOLDERMASK_BRIDGES
Definition: footprint.h:74
@ FPT_LAYER
@ FPT_WIDTH
@ FPT_HEIGHT
@ FPT_TEXT
@ FPT_THICKNESS
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:75
KIID niluuid(0)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ Edge_Cuts
Definition: layer_ids.h:113
@ User_9
Definition: layer_ids.h:131
@ Margin
Definition: layer_ids.h:114
@ User_1
Definition: layer_ids.h:123
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:126
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:99
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:32
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:31
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Custom text control validator definitions.
@ THERMAL
Use thermal relief for pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper