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-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;
154 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
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
198 if( m_page == NOTEBOOK_PAGES::PAGE_GENERAL )
199 {
203 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
204 }
205 else if( m_page == NOTEBOOK_PAGES::PAGE_CLEARANCES )
206 {
208 }
209
211
212 m_solderPasteRatio.SetUnits( EDA_UNITS::PERCENT );
214
215 // Configure button logos
216 m_bpAdd->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
217 m_bpDelete->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
218 m_bpAddLayer->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
219 m_bpDeleteLayer->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
220 m_bpAddPadGroup->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
221 m_bpRemovePadGroup->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
222
224
226 SetEvtHandlerEnabled( true );
227}
228
229
231{
233 cfg->m_FootprintTextShownColumns = m_itemsGrid->GetShownColumnsAsString();
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 if( PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item) )
278 m_texts->push_back( *textItem );
279 }
280
281 // Notify the grid
282 wxGridTableMessage tmsg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_texts->GetNumberRows() );
283 m_itemsGrid->ProcessTableMessage( tmsg );
284
286 m_componentType->SetSelection( 0 );
287 else if( m_footprint->GetAttributes() & FP_SMD )
288 m_componentType->SetSelection( 1 );
289 else
290 m_componentType->SetSelection( 2 );
291
292 // Private layers
293 for( PCB_LAYER_ID privateLayer : m_footprint->GetPrivateLayers().UIOrder() )
294 m_privateLayers->push_back( privateLayer );
295
296 // Notify the grid
297 wxGridTableMessage gridTableMessagesg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
299 m_privateLayersGrid->ProcessTableMessage( gridTableMessagesg );
300
305 m_cbDNP->SetValue( m_footprint->GetAttributes() & FP_DNP );
306
307 // Local Clearances
308
314
315 switch( m_footprint->GetZoneConnection() )
316 {
317 default:
318 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
319 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
320 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
321 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
322 }
323
324 for( const wxString& group : m_footprint->GetNetTiePadGroups() )
325 {
326 if( !group.IsEmpty() )
327 {
328 m_padGroupsGrid->AppendRows( 1 );
329 m_padGroupsGrid->SetCellValue( m_padGroupsGrid->GetNumberRows() - 1, 0, group );
330 }
331 }
332
333 // Items grid
334 for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
335 {
336 // Adjust min size to the column label size
337 m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false ) );
338 // Adjust the column size.
339 int col_size = m_itemsGrid->GetVisibleWidth( col );
340
341 if( col == FPT_LAYER ) // This one's a drop-down. Check all possible values.
342 {
343 BOARD* board = m_footprint->GetBoard();
344
345 for( PCB_LAYER_ID layer : board->GetEnabledLayers().Seq() )
346 col_size = std::max( col_size, GetTextExtent( board->GetLayerName( layer ) ).x );
347
348 // And the swatch:
349 col_size += 20;
350 }
351
352 if( m_itemsGrid->IsColShown( col ) )
353 m_itemsGrid->SetColSize( col, col_size );
354 }
355
356 m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
357
358 Layout();
360
361 return true;
362}
363
364
366{
367 if( aFootprintName.IsEmpty() )
368 {
369 m_delayedErrorMessage = _( "Footprint must have a name." );
370 return false;
371 }
372 else if( !FOOTPRINT::IsLibNameValid( aFootprintName ) )
373 {
374 m_delayedErrorMessage.Printf( _( "Footprint name may not contain '%s'." ),
376 return false;
377 }
378
379 return true;
380}
381
382
384{
386 return false;
387
388 if( !DIALOG_SHIM::Validate() )
389 return false;
390
391 // First, test for invalid chars in footprint name
392 wxString footprintName = m_FootprintNameCtrl->GetValue();
393
394 if( !checkFootprintName( footprintName ) )
395 {
396 if( m_NoteBook->GetSelection() != 0 )
397 m_NoteBook->SetSelection( 0 );
398
400 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_GENERAL;
401
402 return false;
403 }
404
405 // Check for empty texts.
406 for( size_t i = 2; i < m_texts->size(); ++i )
407 {
408 PCB_TEXT& text = m_texts->at( i );
409
410 if( text.GetText().IsEmpty() )
411 {
412 if( m_NoteBook->GetSelection() != 0 )
413 m_NoteBook->SetSelection( 0 );
414
415 m_delayedErrorMessage = _( "Text items must have some content." );
419
420 return false;
421 }
422
423 if( text.GetTextWidth() < TEXTS_MIN_SIZE || text.GetTextWidth() > TEXTS_MAX_SIZE )
424 {
426 m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
431
432 return false;
433 }
434
435 if( text.GetTextHeight() < TEXTS_MIN_SIZE || text.GetTextHeight() > TEXTS_MAX_SIZE )
436 {
438 m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
443
444 return false;
445 }
446
447 // Test for acceptable values for thickness and size and clamp if fails
448 int maxPenWidth = Clamp_Text_PenSize( text.GetTextThickness(), text.GetTextSize() );
449
450 if( text.GetTextThickness() > maxPenWidth )
451 {
452 m_itemsGrid->SetCellValue( i, FPT_THICKNESS,
453 m_frame->StringFromValue( maxPenWidth, true ) );
454
456 m_delayedErrorMessage = _( "The text thickness is too large for the text size.\n"
457 "It will be clamped." );
460
461 return false;
462 }
463 }
464
465 if( !m_netClearance.Validate( 0, INT_MAX ) )
466 return false;
467
468 return true;
469}
470
471
473{
474 if( !Validate() )
475 return false;
476
477 if( !DIALOG_SHIM::TransferDataFromWindow() )
478 return false;
479
483 {
484 return false;
485 }
486
487 // This only commits the editor, model updating is done below so it is inside
488 // the commit
490 return false;
491
493 BOARD_COMMIT commit( m_frame );
494 commit.Modify( m_footprint );
495
496 LIB_ID fpID = m_footprint->GetFPID();
497 fpID.SetLibItemName( m_FootprintNameCtrl->GetValue() );
498 m_footprint->SetFPID( fpID );
499
500 m_footprint->SetDescription( m_DocCtrl->GetValue() );
501 m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
502
503 // copy reference and value
504 m_footprint->Reference() = m_texts->at( 0 );
505 m_footprint->Value() = m_texts->at( 1 );
506
507 size_t i = 2;
508 std::vector<PCB_TEXT*> items_to_remove;
509
510 for( BOARD_ITEM* item : m_footprint->GraphicalItems() )
511 {
512 PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item );
513
514 if( textItem )
515 {
516 // copy grid table entries till we run out, then delete any remaining texts
517 if( i < m_texts->size() )
518 *textItem = m_texts->at( i++ );
519 else // store this item to remove and delete it later,
520 // after the graphic list is explored:
521 items_to_remove.push_back( textItem );
522 }
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 // if there are still grid table entries, create new texts for them
536 while( i < m_texts->size() )
537 {
538 PCB_TEXT* newText = new PCB_TEXT( m_texts->at( i++ ) );
539 m_footprint->Add( newText, ADD_MODE::APPEND );
540 view->Add( newText );
541 }
542
543 LSET privateLayers;
544
545 for( PCB_LAYER_ID layer : *m_privateLayers )
546 privateLayers.set( layer );
547
548 m_footprint->SetPrivateLayers( privateLayers );
549
550 int attributes = 0;
551
552 switch( m_componentType->GetSelection() )
553 {
554 case 0: attributes |= FP_THROUGH_HOLE; break;
555 case 1: attributes |= FP_SMD; break;
556 default: break;
557 }
558
559 if( m_boardOnly->GetValue() )
560 attributes |= FP_BOARD_ONLY;
561
562 if( m_excludeFromPosFiles->GetValue() )
563 attributes |= FP_EXCLUDE_FROM_POS_FILES;
564
565 if( m_excludeFromBOM->GetValue() )
566 attributes |= FP_EXCLUDE_FROM_BOM;
567
568 if( m_noCourtyards->GetValue() )
569 attributes |= FP_ALLOW_MISSING_COURTYARD;
570
571 if( m_cbDNP->GetValue() )
572 attributes |= FP_DNP;
573
574 if( m_allowBridges->GetValue() )
575 attributes |= FP_ALLOW_SOLDERMASK_BRIDGES;
576
577 m_footprint->SetAttributes( attributes );
578
579 // Initialize masks clearances
584
585 switch( m_ZoneConnectionChoice->GetSelection() )
586 {
587 default:
588 case 0: m_footprint->SetZoneConnection( ZONE_CONNECTION::INHERITED ); break;
589 case 1: m_footprint->SetZoneConnection( ZONE_CONNECTION::FULL ); break;
590 case 2: m_footprint->SetZoneConnection( ZONE_CONNECTION::THERMAL ); break;
591 case 3: m_footprint->SetZoneConnection( ZONE_CONNECTION::NONE ); break;
592 }
593
595
596 for( int ii = 0; ii < m_padGroupsGrid->GetNumberRows(); ++ii )
597 {
598 wxString group = m_padGroupsGrid->GetCellValue( ii, 0 );
599
600 if( !group.IsEmpty() )
602 }
603
604 // Copy the models from the panel to the footprint
605 std::vector<FP_3DMODEL>& panelList = m_3dPanel->GetModelList();
606 std::vector<FP_3DMODEL>* fpList = &m_footprint->Models();
607 fpList->clear();
608 fpList->insert( fpList->end(), panelList.begin(), panelList.end() );
609
610 commit.Push( _( "Modify footprint properties" ) );
611
612 return true;
613}
614
615
616static bool footprintIsFromBoard( FOOTPRINT* aFootprint )
617{
618 return aFootprint->GetLink() != niluuid;
619}
620
621
623{
625 {
626 // Currently: nothing to do
627 }
628}
629
630
632{
634 return;
635
636 const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
637 PCB_TEXT textItem( m_footprint );
638
639 // Set active layer if legal; otherwise copy layer from previous text item
641 textItem.SetLayer( m_frame->GetActiveLayer() );
642 else
643 textItem.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
644
645 textItem.SetTextSize( dsnSettings.GetTextSize( textItem.GetLayer() ) );
646 textItem.SetTextThickness( dsnSettings.GetTextThickness( textItem.GetLayer() ) );
647 textItem.SetItalic( dsnSettings.GetTextItalic( textItem.GetLayer() ) );
648
649 m_texts->push_back( textItem );
650
651 // notify the grid
652 wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
653 m_itemsGrid->ProcessTableMessage( msg );
654
655 m_itemsGrid->SetFocus();
656 m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
657 m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
658
659 m_itemsGrid->EnableCellEditControl( true );
660 m_itemsGrid->ShowCellEditControl();
661}
662
663
665{
667 return;
668
669 wxArrayInt selectedRows = m_itemsGrid->GetSelectedRows();
670
671 if( selectedRows.empty() && m_itemsGrid->GetGridCursorRow() >= 0 )
672 selectedRows.push_back( m_itemsGrid->GetGridCursorRow() );
673
674 if( selectedRows.empty() )
675 return;
676
677 for( int row : selectedRows )
678 {
679 if( row < 2 )
680 {
681 DisplayError( nullptr, _( "Reference and value are mandatory." ) );
682 return;
683 }
684 }
685
686 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
687 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
688
689 for( int row : selectedRows )
690 {
691 m_texts->erase( m_texts->begin() + row );
692
693 // notify the grid
694 wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
695 m_itemsGrid->ProcessTableMessage( msg );
696
697 if( m_itemsGrid->GetNumberRows() > 0 )
698 {
699 m_itemsGrid->MakeCellVisible( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
700 m_itemsGrid->SetGridCursor( std::max( 0, row-1 ), m_itemsGrid->GetGridCursorCol() );
701 }
702 }
703}
704
705
707{
709 return;
710
711 PCB_LAYER_ID nextLayer = User_1;
712
713 while( alg::contains( *m_privateLayers, nextLayer ) && nextLayer < User_9 )
714 nextLayer = ToLAYER_ID( nextLayer + 1 );
715
716 m_privateLayers->push_back( nextLayer );
717
718 // notify the grid
719 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
720 m_privateLayersGrid->ProcessTableMessage( msg );
721
722 m_privateLayersGrid->SetFocus();
723 m_privateLayersGrid->MakeCellVisible( m_privateLayers->size() - 1, 0 );
724 m_privateLayersGrid->SetGridCursor( m_privateLayers->size() - 1, 0 );
725}
726
727
729{
731 return;
732
733 int curRow = m_privateLayersGrid->GetGridCursorRow();
734
735 if( curRow < 0 )
736 return;
737
738 m_privateLayers->erase( m_privateLayers->begin() + curRow );
739
740 // notify the grid
741 wxGridTableMessage msg( m_privateLayers, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
742 m_privateLayersGrid->ProcessTableMessage( msg );
743
744 if( m_privateLayersGrid->GetNumberRows() > 0 )
745 {
746 m_privateLayersGrid->MakeCellVisible( std::max( 0, curRow-1 ),
747 m_privateLayersGrid->GetGridCursorCol() );
748 m_privateLayersGrid->SetGridCursor( std::max( 0, curRow-1 ),
749 m_privateLayersGrid->GetGridCursorCol() );
750 }
751}
752
753
755{
757 return;
758
759 m_padGroupsGrid->AppendRows( 1 );
760
761 m_padGroupsGrid->SetFocus();
762 m_padGroupsGrid->MakeCellVisible( m_padGroupsGrid->GetNumberRows() - 1, 0 );
763 m_padGroupsGrid->SetGridCursor( m_padGroupsGrid->GetNumberRows() - 1, 0 );
764
765 m_padGroupsGrid->EnableCellEditControl( true );
766 m_padGroupsGrid->ShowCellEditControl();
767}
768
769
771{
773 return;
774
775 wxArrayInt selectedRows = m_padGroupsGrid->GetSelectedRows();
776 int curRow = m_padGroupsGrid->GetGridCursorRow();
777
778 if( selectedRows.empty() && curRow >= 0 && curRow < m_padGroupsGrid->GetNumberRows() )
779 selectedRows.Add( curRow );
780
781 for( int ii = selectedRows.Count() - 1; ii >= 0; --ii )
782 {
783 int row = selectedRows.Item( ii );
784 m_padGroupsGrid->DeleteRows( row, 1 );
785 curRow = std::min( curRow, row );
786 }
787
788 curRow = std::max( 0, curRow - 1 );
789 m_padGroupsGrid->MakeCellVisible( curRow, m_padGroupsGrid->GetGridCursorCol() );
790 m_padGroupsGrid->SetGridCursor( curRow, m_padGroupsGrid->GetGridCursorCol() );
791}
792
793
795{
796 // Account for scroll bars
798
799 itemsWidth -= m_itemsGrid->GetRowLabelSize();
800
801 for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
802 itemsWidth -= m_itemsGrid->GetColSize( i );
803
804 m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
805 m_itemsGrid->GetVisibleWidth( 0, true, false ) ) );
806
807 // Update the width private layers grid
808 m_privateLayersGrid->SetColSize( 0, std::max( m_privateLayersGrid->GetClientSize().x,
810
811 // Update the width net tie pad groups grid
812 m_padGroupsGrid->SetColSize( 0, std::max( m_padGroupsGrid->GetClientSize().x,
814
815 // Update the width of the 3D panel
817}
818
819
821{
822 // Handle a delayed focus. The delay allows us to:
823 // a) change focus when the error was triggered from within a killFocus handler
824 // b) show the correct notebook page in the background before the error dialog comes up
825 // when triggered from an OK or a notebook page change
826
827 if( static_cast<int>( m_delayedFocusPage ) >= 0 )
828 {
829 if( m_NoteBook->GetSelection() != static_cast<int>( m_delayedFocusPage ) )
830 m_NoteBook->ChangeSelection( static_cast<int>( m_delayedFocusPage ) );
831
832 m_delayedFocusPage = NOTEBOOK_PAGES::PAGE_UNKNOWN;
833 }
834
835 if( !m_delayedErrorMessage.IsEmpty() )
836 {
837 // We will re-enter this routine when the error dialog is displayed, so make
838 // sure we don't keep putting up more dialogs.
839 wxString msg = m_delayedErrorMessage;
840 m_delayedErrorMessage = wxEmptyString;
841
842 // Do not use DisplayErrorMessage(); it screws up window order on Mac
843 DisplayError( nullptr, msg );
844 }
845
847 {
848 m_delayedFocusCtrl->SetFocus();
849
850 if( wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
851 textEntry->SelectAll();
852
853 m_delayedFocusCtrl = nullptr;
854 }
855 else if( m_delayedFocusGrid )
856 {
857 m_delayedFocusGrid->SetFocus();
860
861 m_delayedFocusGrid->EnableCellEditControl( true );
862 m_delayedFocusGrid->ShowCellEditControl();
863
864 m_delayedFocusGrid = nullptr;
867 }
868}
869
870
872{
873 wxSize new_size = aEvent.GetSize();
874
875 if( ( !m_itemsGrid->IsCellEditControlShown() || m_lastRequestedSize != new_size )
876 && m_gridSize != new_size )
877 {
878 m_gridSize = new_size;
879
880 // A trick to fix a cosmetic issue: when, in m_itemsGrid, a layer selector widget has
881 // the focus (is activated in column 6) when resizing the grid, the widget is not moved.
882 // So just change the widget having the focus in this case
883 if( m_NoteBook->GetSelection() == 0 && !m_itemsGrid->HasFocus() )
884 {
885 int col = m_itemsGrid->GetGridCursorCol();
886
887 if( col == 6 ) // a layer selector widget can be activated
888 m_itemsGrid->SetFocus();
889 }
890
892 }
893
894 // We store this value to check whether the dialog is changing size. This might indicate
895 // that the user is scaling the dialog with an editor shown. Some editors do not close
896 // (at least on GTK) when the user drags a dialog corner
897 m_lastRequestedSize = new_size;
898
899 // Always propagate for a grid repaint (needed if the height changes, as well as width)
900 aEvent.Skip();
901}
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:106
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.
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.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:71
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:196
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:230
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:44
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:270
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:611
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:498
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:104
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:197
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:359
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
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:66
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:215
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:1526
void SetDescription(const wxString &aDoc)
Definition: footprint.h:221
int GetLocalClearance() const
Definition: footprint.h:232
void SetKeywords(const wxString &aKeywords)
Definition: footprint.h:224
PCB_TEXT & Value()
read/write accessors:
Definition: footprint.h:569
void SetAttributes(int aAttributes)
Definition: footprint.h:253
wxString GetDescription() const
Definition: footprint.h:220
double GetLocalSolderPasteMarginRatio() const
Definition: footprint.h:246
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: footprint.h:247
void SetPrivateLayers(LSET aLayers)
Adds an item to the container.
Definition: footprint.h:123
void SetLocalSolderPasteMargin(int aMargin)
Definition: footprint.h:244
int GetAttributes() const
Definition: footprint.h:252
void ClearNetTiePadGroups()
Definition: footprint.h:276
LSET GetPrivateLayers() const
Definition: footprint.h:122
int GetLocalSolderPasteMargin() const
Definition: footprint.h:243
const std::vector< wxString > & GetNetTiePadGroups() const
Definition: footprint.h:274
void SetLocalClearance(int aClearance)
Definition: footprint.h:233
const LIB_ID & GetFPID() const
Definition: footprint.h:214
void SetLocalSolderMaskMargin(int aMargin)
Definition: footprint.h:230
void AddNetTiePadGroup(const wxString &aGroup)
Definition: footprint.h:281
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: footprint.cpp:568
PCB_TEXT & Reference()
Definition: footprint.h:570
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: footprint.h:249
KIID GetLink() const
Definition: footprint.h:691
std::vector< FP_3DMODEL > & Models()
Definition: footprint.h:186
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:1537
ZONE_CONNECTION GetZoneConnection() const
Definition: footprint.h:250
wxString GetKeywords() const
Definition: footprint.h:223
DRAWINGS & GraphicalItems()
Definition: footprint.h:175
int GetLocalSolderMaskMargin() const
Definition: footprint.h:229
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:536
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:571
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:306
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 GetShownColumnsAsString()
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:474
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:283
This file is part of the common library.
static bool footprintIsFromBoard(FOOTPRINT *aFootprint)
#define _(s)
Declaration of the eda_3d_viewer class.
@ FP_SMD
Definition: footprint.h:70
@ FP_DNP
Definition: footprint.h:77
@ FP_ALLOW_MISSING_COURTYARD
Definition: footprint.h:76
@ FP_EXCLUDE_FROM_POS_FILES
Definition: footprint.h:71
@ FP_BOARD_ONLY
Definition: footprint.h:73
@ FP_EXCLUDE_FROM_BOM
Definition: footprint.h:72
@ FP_THROUGH_HOLE
Definition: footprint.h:69
@ FP_ALLOW_SOLDERMASK_BRIDGES
Definition: footprint.h:75
@ 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:87
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:172
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
Custom text control validator definitions.