KiCad PCB EDA Suite
dialog_edit_footprint_for_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, dick@softplc.com
6  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
7  * Copyright (C) 2004-2019 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 <fctsys.h>
28 #include <confirm.h>
29 #include <dialog_text_entry.h>
30 #include <pcbnew.h>
31 #include <kiface_i.h>
33 #include <pcb_edit_frame.h>
34 #include <validators.h>
35 #include <board_design_settings.h>
36 #include <board_commit.h>
37 #include <bitmaps.h>
38 #include <widgets/wx_grid.h>
39 #include <widgets/text_ctrl_eval.h>
40 #include <class_module.h>
41 #include <footprint_edit_frame.h>
44 #include "filename_resolver.h"
45 #include <pgm_base.h>
48 
49 #include <fp_lib_table.h>
50 
51 
52 int DIALOG_FOOTPRINT_FP_EDITOR::m_page = 0; // remember the last open page during session
53 
54 
56  MODULE* aModule ) :
58  m_netClearance( aParent, m_NetClearanceLabel, m_NetClearanceCtrl, m_NetClearanceUnits, true ),
59  m_solderMask( aParent, m_SolderMaskMarginLabel, m_SolderMaskMarginCtrl, m_SolderMaskMarginUnits ),
60  m_solderPaste( aParent, m_SolderPasteMarginLabel, m_SolderPasteMarginCtrl, m_SolderPasteMarginUnits ),
61  m_inSelect( false )
62 {
63  m_frame = aParent;
64  m_footprint = aModule;
65 
67 
68  m_delayedErrorMessage = wxEmptyString;
69  m_delayedFocusCtrl = nullptr;
70  m_delayedFocusGrid = nullptr;
71  m_delayedFocusRow = -1;
73  m_delayedFocusPage = -1;
74 
75  // Give an icon
76  wxIcon icon;
77  icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
78  SetIcon( icon );
79 
80  // Give a bit more room for combobox editors
81  m_itemsGrid->SetDefaultRowSize( m_itemsGrid->GetDefaultRowSize() + 4 );
82  m_modelsGrid->SetDefaultRowSize( m_modelsGrid->GetDefaultRowSize() + 4 );
83 
85  m_itemsGrid->PushEventHandler( new GRID_TRICKS( m_itemsGrid ) );
86  m_modelsGrid->PushEventHandler( new GRID_TRICKS( m_modelsGrid ) );
87 
88  // Show/hide columns according to the user's preference
90 
91  // Set up the 3D models grid
92  wxGridCellAttr* attr = new wxGridCellAttr;
93  attr->SetRenderer( new wxGridCellBoolRenderer() );
94  attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
95  attr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
96  m_modelsGrid->SetColAttr( 1, attr );
97  m_modelsGrid->SetWindowStyleFlag( m_modelsGrid->GetWindowStyle() & ~wxHSCROLL );
98 
99  aParent->Prj().Get3DCacheManager()->GetResolver()->SetProgramBase( &Pgm() );
100 
102 
103  bLowerSizer3D->Add( m_PreviewPane, 1, wxEXPAND, 5 );
104 
106 
107  // Set font sizes
108  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
109  infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
110  m_allow90Label->SetFont( infoFont );
111  m_allow180Label->SetFont( infoFont );
112  m_staticTextInfoCopper->SetFont( infoFont );
113  m_staticTextInfoPaste->SetFont( infoFont );
114 
115  infoFont.SetStyle( wxFONTSTYLE_ITALIC );
116  m_staticTextInfoValNeg->SetFont( infoFont );
117  m_staticTextInfoValPos->SetFont( infoFont );
118 
119  if( m_page >= 0 )
120  m_NoteBook->SetSelection( (unsigned) m_page );
121 
122  if( m_page == 0 )
123  {
125  m_delayedFocusRow = 0;
127  m_delayedFocusPage = 0;
128  }
129  else if ( m_page == 1 )
131  else
132  {
134  m_delayedFocusRow = 0;
136  m_delayedFocusPage = 2;
137  }
138 
139  m_sdbSizerStdButtonsOK->SetDefault();
140 
141  // Configure button logos
142  m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
143  m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) );
144  m_button3DShapeAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
145  m_button3DShapeBrowse->SetBitmap( KiBitmap( folder_xpm ) );
146  m_button3DShapeRemove->SetBitmap( KiBitmap( trash_xpm ) );
147 
148  // wxFormBuilder doesn't include this event...
149  m_itemsGrid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR::OnGridCellChanging ), NULL, this );
150 
152 }
153 
154 
156 {
158  m_itemsGrid->GetShownColumns().ToStdString();
159 
160  // Prevents crash bug in wxGrid's d'tor
162 
163  m_itemsGrid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR::OnGridCellChanging ), NULL, this );
164 
165  // Delete the GRID_TRICKS.
166  m_itemsGrid->PopEventHandler( true );
167  m_modelsGrid->PopEventHandler( true );
168 
169  // free the memory used by all models, otherwise models which were
170  // browsed but not used would consume memory
171  Prj().Get3DCacheManager()->FlushCache( false );
172 
173  // the GL canvas has to be visible before it is destroyed
174  m_page = m_NoteBook->GetSelection();
175  m_NoteBook->SetSelection( 1 );
176 
177  delete m_PreviewPane;
178 }
179 
180 
182 {
183  LIB_ID fpID = m_footprint->GetFPID();
184  wxString footprintName = fpID.GetLibItemName();
185 
186  m_FootprintNameCtrl->ChangeValue( footprintName );
187 
188  m_DocCtrl->SetValue( m_footprint->GetDescription() );
189  m_KeywordCtrl->SetValue( m_footprint->GetKeywords() );
190 
191  if( !wxDialog::TransferDataToWindow() )
192  return false;
193 
194  if( !m_PanelGeneral->TransferDataToWindow() )
195  return false;
196 
197  if( !m_Panel3D->TransferDataToWindow() )
198  return false;
199 
200  // Module Texts
201 
202  m_texts->push_back( m_footprint->Reference() );
203  m_texts->push_back( m_footprint->Value() );
204 
205  for( auto item : m_footprint->GraphicalItems() )
206  {
207  auto textModule = dyn_cast<TEXTE_MODULE*>( item );
208 
209  if( textModule )
210  m_texts->push_back( *textModule );
211  }
212 
213  // notify the grid
214  wxGridTableMessage tmsg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_texts->GetNumberRows() );
215  m_itemsGrid->ProcessTableMessage( tmsg );
216 
217  // Module Properties
218 
219  m_AutoPlaceCtrl->SetSelection( (m_footprint->IsLocked()) ? 1 : 0 );
220  m_AutoPlaceCtrl->SetItemToolTip( 0, _( "Enable hotkey move commands and Auto Placement" ) );
221  m_AutoPlaceCtrl->SetItemToolTip( 1, _( "Disable hotkey move commands and Auto Placement" ) );
222 
225 
226  m_AttributsCtrl->SetItemToolTip( 0, _( "Use this attribute for most non SMD footprints\n"
227  "Footprints with this option are not put in the footprint position list file" ) );
228  m_AttributsCtrl->SetItemToolTip( 1, _( "Use this attribute for SMD footprints.\n"
229  "Only footprints with this option are put in the footprint position list file" ) );
230  m_AttributsCtrl->SetItemToolTip( 2, _( "Use this attribute for \"virtual\" footprints drawn on board\n"
231  "such as an edge connector (old ISA PC bus for instance)" ) );
232 
233  switch( m_footprint->GetAttributes() & 255 )
234  {
235  case MOD_CMS: m_AttributsCtrl->SetSelection( 1 ); break;
236  case MOD_VIRTUAL: m_AttributsCtrl->SetSelection( 2 ); break;
237  case 0:
238  default: m_AttributsCtrl->SetSelection( 0 ); break;
239  }
240 
241  // Local Clearances
242 
246 
247  // Prefer "-0" to "0" for normally negative values
249  m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
250 
251  // Add solder paste margin ratio in percent
252  // for the usual default value 0.0, display -0.0 (or -0,0 in some countries)
253  wxString msg;
254  msg.Printf( wxT( "%f" ), m_footprint->GetLocalSolderPasteMarginRatio() * 100.0 );
255 
257  msg[0] == '0') // Sometimes Printf adds a sign if the value is very small (0.0)
258  m_SolderPasteMarginRatioCtrl->SetValue( wxT("-") + msg );
259  else
261 
262  switch( m_footprint->GetZoneConnection() )
263  {
264  default:
266  m_ZoneConnectionChoice->SetSelection( 0 );
267  break;
269  m_ZoneConnectionChoice->SetSelection( 1 );
270  break;
272  m_ZoneConnectionChoice->SetSelection( 2 );
273  break;
275  m_ZoneConnectionChoice->SetSelection( 3 );
276  break;
277  }
278 
279  // 3D Settings
280 
281  wxString default_path;
282  wxGetEnv( KISYS3DMOD, &default_path );
283 #ifdef __WINDOWS__
284  default_path.Replace( wxT( "/" ), wxT( "\\" ) );
285 #endif
286 
287  m_shapes3D_list.clear();
288  m_modelsGrid->DeleteRows( 0, m_modelsGrid->GetNumberRows() );
289 
290  wxString origPath, alias, shortPath;
291  FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
292 
293  for( const MODULE_3D_SETTINGS& model : m_footprint->Models() )
294  {
295  m_shapes3D_list.push_back( model );
296  origPath = model.m_Filename;
297 
298  if( res && res->SplitAlias( origPath, alias, shortPath ) )
299  origPath = alias + wxT( ":" ) + shortPath;
300 
301  m_modelsGrid->AppendRows( 1 );
302  int row = m_modelsGrid->GetNumberRows() - 1;
303  m_modelsGrid->SetCellValue( row, 0, origPath );
304  m_modelsGrid->SetCellValue( row, 1, model.m_Preview ? wxT( "1" ) : wxT( "0" ) );
305  }
306 
307  select3DModel( 0 ); // will clamp idx within bounds
308 
309  for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
310  {
311  // Adjust min size to the column label size
312  m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false, false ) );
313  // Adjust the column size. The column 6 has a small bitmap, so its width must be taken in account
314  int col_size = m_itemsGrid->GetVisibleWidth( col, true, true, false );
315 
316  if( col == 6 )
317  col_size += 20;
318 
319  if( m_itemsGrid->IsColShown( col ) )
320  m_itemsGrid->SetColSize( col, col_size );
321  }
322 
323  m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
324  m_modelsGrid->SetColSize( 1, m_modelsGrid->GetVisibleWidth( 1, true, false, false ) );
325 
326  Layout();
327  adjustGridColumns( m_itemsGrid->GetRect().GetWidth());
328 
329  return true;
330 }
331 
332 
334 {
335  m_inSelect = true;
336 
337  aModelIdx = std::max( 0, aModelIdx );
338  aModelIdx = std::min( aModelIdx, m_modelsGrid->GetNumberRows() - 1 );
339 
340  if( m_modelsGrid->GetNumberRows() )
341  {
342  m_modelsGrid->SelectRow( aModelIdx );
343  m_modelsGrid->SetGridCursor( aModelIdx, 0 );
344  }
345 
346  m_PreviewPane->SetSelectedModel( aModelIdx );
347 
348  m_inSelect = false;
349 }
350 
351 
353 {
354  if( !m_inSelect )
355  select3DModel( aEvent.GetRow() );
356 }
357 
358 
360 {
361  if( aEvent.GetCol() == 0 )
362  {
363  bool hasAlias = false;
364  FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
365  wxString filename = m_modelsGrid->GetCellValue( aEvent.GetRow(), 0 );
366 
367  filename.Replace( "\n", "" );
368  filename.Replace( "\r", "" );
369  filename.Replace( "\t", "" );
370 
371  if( filename.empty() || !res->ValidateFileName( filename, hasAlias ) )
372  {
373  m_delayedErrorMessage = wxString::Format( _( "Invalid filename: %s" ), filename );
375  m_delayedFocusRow = aEvent.GetRow();
376  m_delayedFocusColumn = aEvent.GetCol();
377  m_delayedFocusPage = 2;
378  aEvent.Veto();
379  }
380 
381  // if the user has specified an alias in the name then prepend ':'
382  if( hasAlias )
383  filename.insert( 0, wxT( ":" ) );
384 
385 #ifdef __WINDOWS__
386  // In Kicad files, filenames and paths are stored using Unix notation
387  filename.Replace( wxT( "\\" ), wxT( "/" ) );
388 #endif
389 
390  m_shapes3D_list[ aEvent.GetRow() ].m_Filename = filename;
391  m_modelsGrid->SetCellValue( aEvent.GetRow(), 0, filename );
392  }
393  else if( aEvent.GetCol() == 1 )
394  {
395  wxString previewValue = m_modelsGrid->GetCellValue( aEvent.GetRow(), 1 );
396 
397  m_shapes3D_list[ aEvent.GetRow() ].m_Preview = previewValue == wxT( "1" );
398  }
399 
401 }
402 
403 
405 {
407  return;
408 
409  int idx = m_modelsGrid->GetGridCursorRow();
410 
411  if( idx >= 0 && m_modelsGrid->GetNumberRows() && !m_shapes3D_list.empty() )
412  {
413  m_shapes3D_list.erase( m_shapes3D_list.begin() + idx );
414  m_modelsGrid->DeleteRows( idx );
415 
416  select3DModel( idx-1 ); // will clamp idx within bounds
418  }
419 }
420 
421 
423 {
425  return;
426 
427  PROJECT& prj = Prj();
428  MODULE_3D_SETTINGS model;
429 
430  wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
431  wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );
432  int filter = 0;
433 
434  // If the PROJECT::VIEWER_3D_PATH hasn't been set yet, use the KISYS3DMOD environment
435  // varaible and fall back to the project path if necessary.
436  if( initialpath.IsEmpty() )
437  {
438  if( !wxGetEnv( "KISYS3DMOD", &initialpath ) || initialpath.IsEmpty() )
439  initialpath = prj.GetProjectPath();
440  }
441 
442  if( !sidx.empty() )
443  {
444  long tmp;
445  sidx.ToLong( &tmp );
446 
447  if( tmp > 0 && tmp <= INT_MAX )
448  filter = (int) tmp;
449  }
450 
451  if( !S3D::Select3DModel( this, Prj().Get3DCacheManager(), initialpath, filter, &model )
452  || model.m_Filename.empty() )
453  {
454  return;
455  }
456 
457  prj.SetRString( PROJECT::VIEWER_3D_PATH, initialpath );
458  sidx = wxString::Format( wxT( "%i" ), filter );
460  FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
461  wxString alias;
462  wxString shortPath;
463  wxString filename = model.m_Filename;
464 
465  if( res && res->SplitAlias( filename, alias, shortPath ) )
466  filename = alias + wxT( ":" ) + shortPath;
467 
468 #ifdef __WINDOWS__
469  // In Kicad files, filenames and paths are stored using Unix notation
470  model.m_Filename.Replace( "\\", "/" );
471 #endif
472 
473  model.m_Preview = true;
474  m_shapes3D_list.push_back( model );
475 
476  int idx = m_modelsGrid->GetNumberRows();
477  m_modelsGrid->AppendRows( 1 );
478  m_modelsGrid->SetCellValue( idx, 0, filename );
479  m_modelsGrid->SetCellValue( idx, 1, wxT( "1" ) );
480 
482 }
483 
484 
486 {
488  return;
489 
490  MODULE_3D_SETTINGS model;
491 
492  model.m_Preview = true;
493  m_shapes3D_list.push_back( model );
494 
495  int row = m_modelsGrid->GetNumberRows();
496  m_modelsGrid->AppendRows( 1 );
497  m_modelsGrid->SetCellValue( row, 1, wxT( "1" ) );
498 
499  m_modelsGrid->SetFocus();
500  m_modelsGrid->MakeCellVisible( row, 0 );
501  m_modelsGrid->SetGridCursor( row, 0 );
502 
503  m_modelsGrid->EnableCellEditControl( true );
504  m_modelsGrid->ShowCellEditControl();
505 }
506 
507 
508 bool DIALOG_FOOTPRINT_FP_EDITOR::checkFootprintName( const wxString& aFootprintName )
509 {
510  if( aFootprintName.IsEmpty() )
511  {
512  m_delayedErrorMessage = _( "Footprint must have a name." );
513  return false;
514  }
515  else if( !MODULE::IsLibNameValid( aFootprintName ) )
516  {
517  m_delayedErrorMessage.Printf( _( "Footprint name may not contain \"%s\"." ),
519  return false;
520  }
521 
522  return true;
523 }
524 
525 
527 {
529  return false;
530 
531  if( !DIALOG_SHIM::Validate() )
532  return false;
533 
534  // First, test for invalid chars in module name
535  wxString footprintName = m_FootprintNameCtrl->GetValue();
536 
537  if( !checkFootprintName( footprintName ) )
538  {
539  if( m_NoteBook->GetSelection() != 0 )
540  m_NoteBook->SetSelection( 0 );
541 
543  m_delayedFocusPage = 0;
544 
545  return false;
546  }
547 
548  // Check for empty texts.
549  for( size_t i = 2; i < m_texts->size(); ++i )
550  {
551  TEXTE_MODULE& text = m_texts->at( i );
552 
553  if( text.GetText().IsEmpty() )
554  {
555  if( m_NoteBook->GetSelection() != 0 )
556  m_NoteBook->SetSelection( 0 );
557 
558  m_delayedErrorMessage = _( "Text items must have some content." );
561  m_delayedFocusRow = i;
562 
563  return false;
564  }
565  }
566 
567  if( !m_netClearance.Validate( 0, INT_MAX ) )
568  return false;
569 
570  return true;
571 }
572 
573 
575 {
576  if( !Validate() )
577  return false;
578 
579  if( !DIALOG_SHIM::TransferDataFromWindow() )
580  return false;
581 
582  if( !m_PanelGeneral->TransferDataFromWindow() )
583  return false;
584 
585  if( !m_Panel3D->TransferDataFromWindow() )
586  return false;
587 
588  auto view = m_frame->GetCanvas()->GetView();
589  BOARD_COMMIT commit( m_frame );
590  commit.Modify( m_footprint );
591 
592  LIB_ID fpID = m_footprint->GetFPID();
593  fpID.SetLibItemName( m_FootprintNameCtrl->GetValue(), false );
594  m_footprint->SetFPID( fpID );
595 
596  m_footprint->SetDescription( m_DocCtrl->GetValue() );
597  m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
598 
599  // copy reference and value
600  m_footprint->Reference() = m_texts->at( 0 );
601  m_footprint->Value() = m_texts->at( 1 );
602 
603  size_t i = 2;
604  for( auto item : m_footprint->GraphicalItems() )
605  {
606  TEXTE_MODULE* textModule = dyn_cast<TEXTE_MODULE*>( item );
607 
608  if( textModule )
609  {
610  // copy grid table entries till we run out, then delete any remaining texts
611  if( i < m_texts->size() )
612  *textModule = m_texts->at( i++ );
613  else
614  textModule->DeleteStructure();
615  }
616  }
617 
618  // if there are still grid table entries, create new texts for them
619  while( i < m_texts->size() )
620  {
621  auto newText = new TEXTE_MODULE( m_texts->at( i++ ) );
622  m_footprint->Add( newText, ADD_MODE::APPEND );
623  view->Add( newText );
624  }
625 
626  m_footprint->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
627 
628  switch( m_AttributsCtrl->GetSelection() )
629  {
630  case 0: m_footprint->SetAttributes( 0 ); break;
631  case 1: m_footprint->SetAttributes( MOD_CMS ); break;
632  case 2: m_footprint->SetAttributes( MOD_VIRTUAL ); break;
633  default: wxFAIL;
634  }
635 
638 
639  // Initialize masks clearances
643 
644  double dtmp = 0.0;
645  wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
646  msg.ToDouble( &dtmp );
647 
648  // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
649  if( dtmp < -50.0 )
650  dtmp = -50.0;
651  // A margin ratio is always <= 0
652  // 0 means use full pad copper area
653  if( dtmp > 0.0 )
654  dtmp = 0.0;
655 
657 
658  switch( m_ZoneConnectionChoice->GetSelection() )
659  {
660  default:
661  case 0:
663  break;
664  case 1:
666  break;
667  case 2:
669  break;
670  case 3:
672  break;
673  }
674 
675  std::list<MODULE_3D_SETTINGS>* draw3D = &m_footprint->Models();
676  draw3D->clear();
677  draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() );
678 
680 
681  commit.Push( _( "Modify module properties" ) );
682 
683  return true;
684 }
685 
686 
687 static bool footprintIsFromBoard( MODULE* aFootprint )
688 {
689  return aFootprint->GetLink() != niluuid;
690 }
691 
692 
694 {
695  // Currently: nothing to do
696 }
697 
698 
700 {
702  {
703  // Currently: nothing to do
704  }
705 }
706 
707 
708 void DIALOG_FOOTPRINT_FP_EDITOR::OnAddField( wxCommandEvent& event )
709 {
711  return;
712 
713  const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
714  TEXTE_MODULE textMod( m_footprint );
715 
716  // Set active layer if legal; otherwise copy layer from previous text item
717  if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
718  textMod.SetLayer( m_frame->GetActiveLayer() );
719  else
720  textMod.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
721 
722  textMod.SetTextSize( dsnSettings.GetTextSize( textMod.GetLayer() ) );
723  textMod.SetThickness( dsnSettings.GetTextThickness( textMod.GetLayer() ) );
724  textMod.SetItalic( dsnSettings.GetTextItalic( textMod.GetLayer() ) );
725 
726  m_texts->push_back( textMod );
727 
728  // notify the grid
729  wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
730  m_itemsGrid->ProcessTableMessage( msg );
731 
732  m_itemsGrid->SetFocus();
733  m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
734  m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
735 
736  m_itemsGrid->EnableCellEditControl( true );
737  m_itemsGrid->ShowCellEditControl();
738 }
739 
740 
741 void DIALOG_FOOTPRINT_FP_EDITOR::OnDeleteField( wxCommandEvent& event )
742 {
744  return;
745 
746  int curRow = m_itemsGrid->GetGridCursorRow();
747 
748  if( curRow < 0 )
749  return;
750  else if( curRow < 2 )
751  {
752  DisplayError( nullptr, _( "Reference and value are mandatory." ) );
753  return;
754  }
755 
756  m_texts->erase( m_texts->begin() + curRow );
757 
758  // notify the grid
759  wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
760  m_itemsGrid->ProcessTableMessage( msg );
761 
762  if( m_itemsGrid->GetNumberRows() > 0 )
763  {
764  m_itemsGrid->MakeCellVisible( std::max( 0, curRow-1 ), m_itemsGrid->GetGridCursorCol() );
765  m_itemsGrid->SetGridCursor( std::max( 0, curRow-1 ), m_itemsGrid->GetGridCursorCol() );
766  }
767 }
768 
769 
770 void DIALOG_FOOTPRINT_FP_EDITOR::Cfg3DPath( wxCommandEvent& event )
771 {
772  if( S3D::Configure3DPaths( this, Prj().Get3DCacheManager()->GetResolver() ) )
774 }
775 
776 
778 {
779  // Account for scroll bars
780  int itemsWidth = aWidth - ( m_itemsGrid->GetSize().x - m_itemsGrid->GetClientSize().x );
781  int modelsWidth = aWidth - ( m_modelsGrid->GetSize().x - m_modelsGrid->GetClientSize().x );
782 
783  itemsWidth -= m_itemsGrid->GetRowLabelSize();
784 
785  for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
786  itemsWidth -= m_itemsGrid->GetColSize( i );
787 
788  if( itemsWidth > 0 )
789  m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
790  m_itemsGrid->GetVisibleWidth( 0, true, false, false ) ) );
791 
792  m_modelsGrid->SetColSize( 0, modelsWidth - m_modelsGrid->GetColSize( 1 ) - 5 );
793 }
794 
795 
796 void DIALOG_FOOTPRINT_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
797 {
798  if( !m_itemsGrid->IsCellEditControlShown() && !m_modelsGrid->IsCellEditControlShown() )
799  adjustGridColumns( m_itemsGrid->GetRect().GetWidth());
800 
801  if( m_itemsGrid->IsCellEditControlShown() )
802  {
803  // Currently: nonthing to do
804  }
805 
806  // Handle a delayed focus. The delay allows us to:
807  // a) change focus when the error was triggered from within a killFocus handler
808  // b) show the correct notebook page in the background before the error dialog comes up
809  // when triggered from an OK or a notebook page change
810 
811  if( m_delayedFocusPage >= 0 )
812  {
813  if( m_NoteBook->GetSelection() != m_delayedFocusPage )
814  m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
815 
816  m_delayedFocusPage = -1;
817  }
818 
819  if( !m_delayedErrorMessage.IsEmpty() )
820  {
821  // We will re-enter this routine when the error dialog is displayed, so make
822  // sure we don't keep putting up more dialogs.
823  wxString msg = m_delayedErrorMessage;
824  m_delayedErrorMessage = wxEmptyString;
825 
826  // Do not use DisplayErrorMessage(); it screws up window order on Mac
827  DisplayError( nullptr, msg );
828  }
829 
830  if( m_delayedFocusCtrl )
831  {
832  m_delayedFocusCtrl->SetFocus();
833 
834  if( auto textEntry = dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
835  textEntry->SelectAll();
836 
837  m_delayedFocusCtrl = nullptr;
838  }
839  else if( m_delayedFocusGrid )
840  {
841  m_delayedFocusGrid->SetFocus();
844 
845  m_delayedFocusGrid->EnableCellEditControl( true );
846  m_delayedFocusGrid->ShowCellEditControl();
847 
848  m_delayedFocusGrid = nullptr;
849  m_delayedFocusRow = -1;
851  }
852 
853  m_button3DShapeRemove->Enable( m_modelsGrid->GetNumberRows() > 0 );
854 }
855 
856 
857 void DIALOG_FOOTPRINT_FP_EDITOR::OnGridSize( wxSizeEvent& event )
858 {
859  adjustGridColumns( event.GetSize().GetX());
860 
861  event.Skip();
862 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
const BITMAP_OPAQUE trash_xpm[1]
Definition: trash.cpp:46
void Cfg3DPath(wxCommandEvent &event) override
void SetPlacementCost90(int aCost)
Definition: class_module.h:556
const BITMAP_OPAQUE folder_xpm[1]
Definition: folder.cpp:20
int GetAttributes() const
Definition: class_module.h:259
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
int GetPlacementCost90() const
Definition: class_module.h:555
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
TEXTE_MODULE & Reference()
Definition: class_module.h:477
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:103
PROJECT holds project specific data.
Definition: project.h:59
void SetLocalClearance(int aClearance)
Definition: class_module.h:235
BOARD_DESIGN_SETTINGS & GetDesignSettings() const override
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetPlacementCost180(int aCost)
Definition: class_module.h:553
This file is part of the common library.
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:119
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetItalic(bool isItalic)
Definition: eda_text.h:163
ZONE_CONNECTION GetZoneConnection() const
Definition: class_module.h:248
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
GRID_TRICKS is used to add mouse and command handling (such as cut, copy, and paste) to a WX_GRID ins...
Definition: grid_tricks.h:51
provides an extensible class to resolve 3D model paths.
Set for modules listed in the automatic insertion list (usually SMD footprints)
Definition: class_module.h:74
void DeleteStructure()
Function DeleteStructure deletes this object after removing from its parent if it has one.
void OnFootprintNameText(wxCommandEvent &event) override
void UpdateDummyModule(bool aRelaodRequired=true)
UpdateModelInfoList - copy shapes from the current shape list which are flagged for preview to the co...
const LIB_ID & GetFPID() const
Definition: class_module.h:219
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
#define KISYS3DMOD
A variable name whose value holds the path of 3D shape files.
Definition: eda_3d_viewer.h:44
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
static function StringLibNameInvalidChars Test for validity of the name in a library of the footprint...
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:57
DRAWINGS & GraphicalItems()
Definition: class_module.h:183
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
int GetTextThickness(PCB_LAYER_ID aLayer) const
Function GetTextThickness Returns the default text thickness from the layer class for the given layer...
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:756
void OnAdd3DModel(wxCommandEvent &event) override
int GetLocalSolderMaskMargin() const
Definition: class_module.h:231
bool m_Preview
Include module in 3D preview.
Definition: class_module.h:101
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:102
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_module.h:241
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
void SetValue(const wxString &aValue) override
Set a new value in evaluator buffer, and display it in the wxTextCtrl.
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=false, bool aKeep=true)
Calculates the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:228
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:88
bool GetTextItalic(PCB_LAYER_ID aLayer) const
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
void OnAddField(wxCommandEvent &event) override
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:80
bool SplitAlias(const wxString &aFileName, wxString &anAlias, wxString &aRelPath)
Function SplitAlias returns true if the given name contains an alias and populates the string anAlias...
void On3DModelCellChanged(wxGridEvent &aEvent) override
pads are covered by copper
void OnUpdateUI(wxUpdateUIEvent &event) override
Defines a panel which is to be added to a wxFileDialog via SetExtraControl(); The panel shows a previ...
int GetLocalClearance() const
Definition: class_module.h:234
#define NULL
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:476
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIID niluuid(0)
This class provides a custom wxValidator object for limiting the allowable characters when defining f...
Definition: validators.h:63
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:172
virtual bool Validate(long long int aMin, long long int aMax, bool setFocusOnError=true)
Function Validate Validates the control against the given range, informing the user of any errors fou...
void SetSelectedModel(int idx)
SetModelDataIdx - Sets the currently selected index in the model list so that the scale/rotation/offs...
bool IsLocked() const override
Function IsLocked.
Definition: class_module.h:301
virtual KIGFX::PCB_VIEW * GetView() const override
Function GetView() Returns a pointer to the VIEW instance used in the panel.
const wxString & GetKeywords() const
Definition: class_module.h:225
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_module.h:232
int SetLibItemName(const UTF8 &aLibItemName, bool aTestForRev=true)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:206
int GetLocalSolderPasteMargin() const
Definition: class_module.h:237
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
const BITMAP_OPAQUE icon_modedit_xpm[1]
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:100
VTBL_ENTRY void SetRString(RSTRING_T aStringId, const wxString &aString)
Function SetRString stores a "retained string", which is any session and project specific string iden...
Definition: project.cpp:198
int GetPlacementCost180() const
Definition: class_module.h:552
EDA_UNITS m_units
Definition: dialog_shim.h:196
void OnGridSize(wxSizeEvent &event) override
static bool IsLibNameValid(const wxString &aName)
static function IsLibNameValid Test for validity of a name of a footprint to be used in a footprint l...
Use thermal relief for pads.
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:101
void OnAdd3DRow(wxCommandEvent &event) override
const wxString & GetDescription() const
Definition: class_module.h:222
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_module.h:238
VTBL_ENTRY const wxString & GetRString(RSTRING_T aStringId)
Function GetRString returns a "retained string", which is any session and project specific string ide...
Definition: project.cpp:213
void OnRemove3DModel(wxCommandEvent &event) override
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:240
std::list< MODULE_3D_SETTINGS > & Models()
Definition: class_module.h:205
bool Configure3DPaths(wxWindow *aParent, FILENAME_RESOLVER *aResolver)
see class PGM_BASE
Declaration of the eda_3d_viewer class.
void SetLocked(bool isLocked) override
Function SetLocked sets the MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: class_module.h:311
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
Virtual component: when created by copper shapes on board (Like edge card connectors,...
Definition: class_module.h:76
void SetZoneConnection(ZONE_CONNECTION aType)
Definition: class_module.h:243
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
Pads are not covered.
KIID GetLink() const
Definition: class_module.h:549
virtual long long int GetValue()
Function GetValue Returns the current value in Internal Units.
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
void SetKeywords(const wxString &aKeywords)
Definition: class_module.h:226
void OnDeleteField(wxCommandEvent &event) override
DIALOG_FOOTPRINT_FP_EDITOR(FOOTPRINT_EDIT_FRAME *aParent, MODULE *aModule)
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
static bool footprintIsFromBoard(MODULE *aFootprint)
bool Select3DModel(wxWindow *aParent, S3D_CACHE *aCache, wxString &prevModelSelectDir, int &prevModelWildcard, MODULE_3D_SETTINGS *aModel)
Module description (excepted pads)
bool ValidateFileName(const wxString &aFileName, bool &hasAlias)
Function ValidateName returns true if the given path is a valid aliased relative path.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetFPID(const LIB_ID &aFPID)
Definition: class_module.h:220
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
const BITMAP_OPAQUE small_plus_xpm[1]
Definition: small_plus.cpp:20
Custom text control validator definitions.
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Function GetTextSize Returns the default text size from the layer class for the given layer.
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143
void SetAttributes(int aAttributes)
Definition: class_module.h:260
int GetNumberRows() override
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
bool checkFootprintName(const wxString &aFootprintName)
void SetDescription(const wxString &aDoc)
Definition: class_module.h:223
std::vector< MODULE_3D_SETTINGS > m_shapes3D_list