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