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 ),
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 percent
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  for( int col = 0; col < m_itemsGrid->GetNumberCols(); col++ )
297  {
298  // Adjust min size to the column label size
299  m_itemsGrid->SetColMinimalWidth( col, m_itemsGrid->GetVisibleWidth( col, true, false, false ) );
300  // Adjust the column size. The column 6 has a small bitmap, so its width must be taken in account
301  int col_size = m_itemsGrid->GetVisibleWidth( col, true, true, false );
302 
303  if( col == 6 )
304  col_size += 20;
305 
306  if( m_itemsGrid->IsColShown( col ) )
307  m_itemsGrid->SetColSize( col, col_size );
308  }
309 
310  m_itemsGrid->SetRowLabelSize( m_itemsGrid->GetVisibleWidth( -1, true, true, true ) );
311  m_modelsGrid->SetColSize( 1, m_modelsGrid->GetVisibleWidth( 1, true, false, false ) );
312 
313  Layout();
314  adjustGridColumns( m_itemsGrid->GetRect().GetWidth());
315 
316  return true;
317 }
318 
319 
321 {
322  m_inSelect = true;
323 
324  aModelIdx = std::max( 0, aModelIdx );
325  aModelIdx = std::min( aModelIdx, m_modelsGrid->GetNumberRows() - 1 );
326 
327  if( m_modelsGrid->GetNumberRows() )
328  {
329  m_modelsGrid->SelectRow( aModelIdx );
330  m_modelsGrid->SetGridCursor( aModelIdx, 0 );
331  }
332 
333  m_PreviewPane->SetSelectedModel( aModelIdx );
334 
335  m_inSelect = false;
336 }
337 
338 
340 {
341  if( !m_inSelect )
342  select3DModel( aEvent.GetRow() );
343 }
344 
345 
347 {
348  if( aEvent.GetCol() == 0 )
349  {
350  bool hasAlias = false;
351  FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
352  wxString filename = m_modelsGrid->GetCellValue( aEvent.GetRow(), 0 );
353 
354  if( filename.empty() || !res->ValidateFileName( filename, hasAlias ) )
355  {
356  m_delayedErrorMessage = wxString::Format( _( "Invalid filename: %s" ), filename );
358  m_delayedFocusRow = aEvent.GetRow();
359  m_delayedFocusColumn = aEvent.GetCol();
360  m_delayedFocusPage = 2;
361  aEvent.Veto();
362  }
363 
364  // if the user has specified an alias in the name then prepend ':'
365  if( hasAlias )
366  filename.insert( 0, wxT( ":" ) );
367 
368 #ifdef __WINDOWS__
369  // In Kicad files, filenames and paths are stored using Unix notation
370  filename.Replace( wxT( "\\" ), wxT( "/" ) );
371 #endif
372 
373  m_shapes3D_list[ aEvent.GetRow() ].m_Filename = filename;
374  }
375  else if( aEvent.GetCol() == 1 )
376  {
377  wxString previewValue = m_modelsGrid->GetCellValue( aEvent.GetRow(), 1 );
378 
379  m_shapes3D_list[ aEvent.GetRow() ].m_Preview = previewValue == wxT( "1" );
380  }
381 
383 }
384 
385 
387 {
389  return;
390 
391  int idx = m_modelsGrid->GetGridCursorRow();
392 
393  if( idx >= 0 )
394  {
395  m_shapes3D_list.erase( m_shapes3D_list.begin() + idx );
396  m_modelsGrid->DeleteRows( idx );
397 
398  select3DModel( idx-1 ); // will clamp idx within bounds
400  }
401 }
402 
403 
405 {
407  return;
408 
409  PROJECT& prj = Prj();
410  MODULE_3D_SETTINGS model;
411 
412  wxString initialpath = prj.GetRString( PROJECT::VIEWER_3D_PATH );
413  wxString sidx = prj.GetRString( PROJECT::VIEWER_3D_FILTER_INDEX );
414  int filter = 0;
415 
416  // If the PROJECT::VIEWER_3D_PATH hasn't been set yet, use the KISYS3DMOD environment
417  // varaible and fall back to the project path if necessary.
418  if( initialpath.IsEmpty() )
419  {
420  if( !wxGetEnv( "KISYS3DMOD", &initialpath ) || initialpath.IsEmpty() )
421  initialpath = prj.GetProjectPath();
422  }
423 
424  if( !sidx.empty() )
425  {
426  long tmp;
427  sidx.ToLong( &tmp );
428 
429  if( tmp > 0 && tmp <= INT_MAX )
430  filter = (int) tmp;
431  }
432 
433  if( !S3D::Select3DModel( this, Prj().Get3DCacheManager(), initialpath, filter, &model )
434  || model.m_Filename.empty() )
435  {
436  return;
437  }
438 
439  prj.SetRString( PROJECT::VIEWER_3D_PATH, initialpath );
440  sidx = wxString::Format( wxT( "%i" ), filter );
442  FILENAME_RESOLVER* res = Prj().Get3DCacheManager()->GetResolver();
443  wxString alias;
444  wxString shortPath;
445  wxString filename = model.m_Filename;
446 
447  if( res && res->SplitAlias( filename, alias, shortPath ) )
448  filename = alias + wxT( ":" ) + shortPath;
449 
450 #ifdef __WINDOWS__
451  // In Kicad files, filenames and paths are stored using Unix notation
452  model.m_Filename.Replace( "\\", "/" );
453 #endif
454 
455  model.m_Preview = true;
456  m_shapes3D_list.push_back( model );
457 
458  int idx = m_modelsGrid->GetNumberRows();
459  m_modelsGrid->AppendRows( 1 );
460  m_modelsGrid->SetCellValue( idx, 0, filename );
461  m_modelsGrid->SetCellValue( idx, 1, wxT( "1" ) );
462 
464 }
465 
466 
468 {
470  return;
471 
472  MODULE_3D_SETTINGS model;
473 
474  model.m_Preview = true;
475  m_shapes3D_list.push_back( model );
476 
477  int row = m_modelsGrid->GetNumberRows();
478  m_modelsGrid->AppendRows( 1 );
479  m_modelsGrid->SetCellValue( row, 1, wxT( "1" ) );
480 
481  m_modelsGrid->SetFocus();
482  m_modelsGrid->MakeCellVisible( row, 0 );
483  m_modelsGrid->SetGridCursor( row, 0 );
484 
485  m_modelsGrid->EnableCellEditControl( true );
486  m_modelsGrid->ShowCellEditControl();
487 }
488 
489 
490 bool DIALOG_FOOTPRINT_FP_EDITOR::checkFootprintName( const wxString& aFootprintName )
491 {
492  if( aFootprintName.IsEmpty() || !MODULE::IsLibNameValid( aFootprintName ) )
493  {
494  if( aFootprintName.IsEmpty() )
495  m_delayedErrorMessage = _( "Footprint must have a name." );
496  else
497  m_delayedErrorMessage.Printf( _( "Footprint name may not contain \"%s\"." ),
499 
500  return false;
501  }
502 
503  return true;
504 }
505 
506 
508 {
510  return false;
511 
512  if( !DIALOG_SHIM::Validate() )
513  return false;
514 
515  // First, test for invalid chars in module name
516  wxString footprintName = m_FootprintNameCtrl->GetValue();
517 
518  if( !checkFootprintName( footprintName ) )
519  {
520  if( m_NoteBook->GetSelection() != 0 )
521  m_NoteBook->SetSelection( 0 );
522 
524  m_delayedFocusPage = 0;
525 
526  return false;
527  }
528 
529  // Check for empty texts.
530  for( size_t i = 2; i < m_texts->size(); ++i )
531  {
532  TEXTE_MODULE& text = m_texts->at( i );
533 
534  if( text.GetText().IsEmpty() )
535  {
536  if( m_NoteBook->GetSelection() != 0 )
537  m_NoteBook->SetSelection( 0 );
538 
539  m_delayedErrorMessage = _( "Text items must have some content." );
543 
544  return false;
545  }
546  }
547 
548  if( !m_netClearance.Validate( 0, INT_MAX ) )
549  return false;
550 
551  return true;
552 }
553 
554 
556 {
557  if( !Validate() )
558  return false;
559 
560  if( !DIALOG_SHIM::TransferDataFromWindow() )
561  return false;
562 
563  if( !m_PanelGeneral->TransferDataFromWindow() )
564  return false;
565 
566  if( !m_Panel3D->TransferDataFromWindow() )
567  return false;
568 
569  auto view = m_frame->GetGalCanvas()->GetView();
570  BOARD_COMMIT commit( m_frame );
571  commit.Modify( m_footprint );
572 
573  LIB_ID fpID = m_footprint->GetFPID();
574  fpID.SetLibItemName( m_FootprintNameCtrl->GetValue(), false );
575  m_footprint->SetFPID( fpID );
576 
577  m_footprint->SetDescription( m_DocCtrl->GetValue() );
578  m_footprint->SetKeywords( m_KeywordCtrl->GetValue() );
579 
580  // copy reference and value
581  m_footprint->Reference() = m_texts->at( 0 );
582  m_footprint->Value() = m_texts->at( 1 );
583 
584  size_t i = 2;
585  for( BOARD_ITEM* item = m_footprint->GraphicalItemsList().GetFirst(); item; item = item->Next() )
586  {
587  TEXTE_MODULE* textModule = dyn_cast<TEXTE_MODULE*>( item );
588 
589  if( textModule )
590  {
591  // copy grid table entries till we run out, then delete any remaining texts
592  if( i < m_texts->size() )
593  *textModule = m_texts->at( i++ );
594  else
595  textModule->DeleteStructure();
596  }
597  }
598 
599  // if there are still grid table entries, create new texts for them
600  while( i < m_texts->size() )
601  {
602  auto newText = new TEXTE_MODULE( m_texts->at( i++ ) );
603  m_footprint->Add( newText, ADD_APPEND );
604  view->Add( newText );
605  }
606 
607  m_footprint->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
608 
609  switch( m_AttributsCtrl->GetSelection() )
610  {
611  case 0: m_footprint->SetAttributes( 0 ); break;
612  case 1: m_footprint->SetAttributes( MOD_CMS ); break;
613  case 2: m_footprint->SetAttributes( MOD_VIRTUAL ); break;
614  default: wxFAIL;
615  }
616 
619 
620  // Initialize masks clearances
624 
625  double dtmp = 0.0;
626  wxString msg = m_SolderPasteMarginRatioCtrl->GetValue();
627  msg.ToDouble( &dtmp );
628 
629  // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
630  if( dtmp < -50.0 )
631  dtmp = -50.0;
632  // A margin ratio is always <= 0
633  // 0 means use full pad copper area
634  if( dtmp > 0.0 )
635  dtmp = 0.0;
636 
638 
639  std::list<MODULE_3D_SETTINGS>* draw3D = &m_footprint->Models();
640  draw3D->clear();
641  draw3D->insert( draw3D->end(), m_shapes3D_list.begin(), m_shapes3D_list.end() );
642 
644 
645  commit.Push( _( "Modify module properties" ) );
646 
647  return true;
648 }
649 
650 
651 static bool footprintIsFromBoard( MODULE* aFootprint )
652 {
653  return aFootprint->GetLink() != 0;
654 }
655 
656 
658 {
659  if( event.GetRow() == 1 && event.GetCol() == TMC_TEXT )
660  {
661  if( !checkFootprintName( event.GetString() ) )
662  {
663  event.Veto();
664 
665  if( m_NoteBook->GetSelection() != 0 )
666  m_NoteBook->SetSelection( 0 );
667 
669  m_delayedFocusRow = event.GetRow();
670  m_delayedFocusColumn = event.GetCol();
671  m_delayedFocusPage = 0;
672  }
673  else if( !footprintIsFromBoard( m_footprint ) )
674  {
675  // Keep Name and Value of footprints in library in sync
676  m_FootprintNameCtrl->ChangeValue( event.GetString() );
677  }
678  }
679 }
680 
681 
683 {
685  {
686  // Keep Name and Value of footprints in library in sync
687  m_itemsGrid->SetCellValue( 1, TMC_TEXT, m_FootprintNameCtrl->GetValue() );
688  }
689 }
690 
691 
693 {
695  {
697  m_delayedFocusPage = 0;
698  }
699 
700  event.Skip();
701 }
702 
703 
704 void DIALOG_FOOTPRINT_FP_EDITOR::OnAddField( wxCommandEvent& event )
705 {
707  return;
708 
709  const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
710  TEXTE_MODULE textMod( m_footprint );
711 
712  // Set active layer if legal; otherwise copy layer from previous text item
713  if( LSET::AllTechMask().test( m_frame->GetActiveLayer() ) )
714  textMod.SetLayer( m_frame->GetActiveLayer() );
715  else
716  textMod.SetLayer( m_texts->at( m_texts->size() - 1 ).GetLayer() );
717 
718  textMod.SetTextSize( dsnSettings.GetTextSize( textMod.GetLayer() ) );
719  textMod.SetThickness( dsnSettings.GetTextThickness( textMod.GetLayer() ) );
720  textMod.SetItalic( dsnSettings.GetTextItalic( textMod.GetLayer() ) );
721 
722  m_texts->push_back( textMod );
723 
724  // notify the grid
725  wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
726  m_itemsGrid->ProcessTableMessage( msg );
727 
728  m_itemsGrid->SetFocus();
729  m_itemsGrid->MakeCellVisible( m_texts->size() - 1, 0 );
730  m_itemsGrid->SetGridCursor( m_texts->size() - 1, 0 );
731 
732  m_itemsGrid->EnableCellEditControl( true );
733  m_itemsGrid->ShowCellEditControl();
734 }
735 
736 
737 void DIALOG_FOOTPRINT_FP_EDITOR::OnDeleteField( wxCommandEvent& event )
738 {
740  return;
741 
742  int curRow = m_itemsGrid->GetGridCursorRow();
743 
744  if( curRow < 0 )
745  return;
746  else if( curRow < 2 )
747  {
748  DisplayError( nullptr, _( "Reference and value are mandatory." ) );
749  return;
750  }
751 
752  m_texts->erase( m_texts->begin() + curRow );
753 
754  // notify the grid
755  wxGridTableMessage msg( m_texts, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
756  m_itemsGrid->ProcessTableMessage( msg );
757 
758  if( m_itemsGrid->GetNumberRows() > 0 )
759  {
760  m_itemsGrid->MakeCellVisible( std::max( 0, curRow-1 ), m_itemsGrid->GetGridCursorCol() );
761  m_itemsGrid->SetGridCursor( std::max( 0, curRow-1 ), m_itemsGrid->GetGridCursorCol() );
762  }
763 }
764 
765 
766 void DIALOG_FOOTPRINT_FP_EDITOR::Cfg3DPath( wxCommandEvent& event )
767 {
768  if( S3D::Configure3DPaths( this, Prj().Get3DCacheManager()->GetResolver() ) )
770 }
771 
772 
774 {
775  // Account for scroll bars
776  int itemsWidth = aWidth - ( m_itemsGrid->GetSize().x - m_itemsGrid->GetClientSize().x );
777  int modelsWidth = aWidth - ( m_modelsGrid->GetSize().x - m_modelsGrid->GetClientSize().x );
778 
779  itemsWidth -= m_itemsGrid->GetRowLabelSize();
780 
781  for( int i = 1; i < m_itemsGrid->GetNumberCols(); i++ )
782  itemsWidth -= m_itemsGrid->GetColSize( i );
783 
784  if( itemsWidth > 0 )
785  m_itemsGrid->SetColSize( 0, std::max( itemsWidth,
786  m_itemsGrid->GetVisibleWidth( 0, true, false, false ) ) );
787 
788  m_modelsGrid->SetColSize( 0, modelsWidth - m_modelsGrid->GetColSize( 1 ) - 5 );
789 }
790 
791 
792 void DIALOG_FOOTPRINT_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
793 {
794  if( !m_itemsGrid->IsCellEditControlShown() && !m_modelsGrid->IsCellEditControlShown() )
795  adjustGridColumns( m_itemsGrid->GetRect().GetWidth());
796 
797  if( m_itemsGrid->IsCellEditControlShown() )
798  {
799  int row = m_itemsGrid->GetGridCursorRow();
800  int col = m_itemsGrid->GetGridCursorCol();
801 
802  if( row == 1 && col == TMC_TEXT )
803  {
804  wxGridCellEditor* editor = m_itemsGrid->GetCellEditor( row, col );
805  m_FootprintNameCtrl->ChangeValue( editor->GetValue() );
806  editor->DecRef();
807  }
808  }
809 
810  // Handle a delayed focus. The delay allows us to:
811  // a) change focus when the error was triggered from within a killFocus handler
812  // b) show the correct notebook page in the background before the error dialog comes up
813  // when triggered from an OK or a notebook page change
814 
815  if( m_delayedFocusPage >= 0 )
816  {
817  if( m_NoteBook->GetSelection() != m_delayedFocusPage )
818  m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
819 
820  m_delayedFocusPage = -1;
821  }
822 
823  if( !m_delayedErrorMessage.IsEmpty() )
824  {
825  // We will re-enter this routine when the error dialog is displayed, so make
826  // sure we don't keep putting up more dialogs.
827  wxString msg = m_delayedErrorMessage;
828  m_delayedErrorMessage = wxEmptyString;
829 
830  // Do not use DisplayErrorMessage(); it screws up window order on Mac
831  DisplayError( nullptr, msg );
832  }
833 
834  if( m_delayedFocusCtrl )
835  {
836  m_delayedFocusCtrl->SetFocus();
837 
838  if( dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
839  dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl )->SelectAll();
840 
841  m_delayedFocusCtrl = nullptr;
842  }
843  else if( m_delayedFocusGrid )
844  {
845  m_delayedFocusGrid->SetFocus();
848 
849  m_delayedFocusGrid->EnableCellEditControl( true );
850  m_delayedFocusGrid->ShowCellEditControl();
851 
852  m_delayedFocusGrid = nullptr;
853  m_delayedFocusRow = -1;
855  }
856 }
857 
858 
859 void DIALOG_FOOTPRINT_FP_EDITOR::OnGridSize( wxSizeEvent& event )
860 {
861  adjustGridColumns( event.GetSize().GetX());
862 
863  event.Skip();
864 }
void Cfg3DPath(wxCommandEvent &event) override
void SetPlacementCost90(int aCost)
Definition: class_module.h:574
int GetAttributes() const
Definition: class_module.h:225
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
int GetPlacementCost90() const
Definition: class_module.h:573
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
TEXTE_MODULE & Reference()
Definition: class_module.h:503
Class PROJECT holds project specific data.
Definition: project.h:57
void SetLocalClearance(int aClearance)
Definition: class_module.h:208
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:571
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,...
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.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:935
virtual bool Validate(int aMin, int aMax, bool setFocusOnError=true)
Function Validate Validates the control against the given range, informing the user of any errors fou...
void SetItalic(bool isItalic)
Definition: eda_text.h:182
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
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 mouse and command handling (such as cut, copy, and paste) to a WX_GR...
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:76
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
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:192
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...
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
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:746
void OnAdd3DModel(wxCommandEvent &event) override
int GetLocalSolderMaskMargin() const
Definition: class_module.h:204
Definition of class FOOTPRINT_EDIT_FRAME.
bool m_Preview
Include module in 3D preview.
Definition: class_module.h:103
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:214
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:116
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
timestamp_t GetLink() const
Definition: class_module.h:567
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:223
Class FILE_NAME_CHAR_VALIDATOR.
Definition: validators.h:63
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
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:79
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...
int GetLocalClearance() const
Definition: class_module.h:207
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:502
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
#define KISYS3DMOD
A variable name whose value holds the path of 3D shape files.
Definition: 3d_viewer.h:38
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:167
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
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:267
const wxString & GetKeywords() const
Definition: class_module.h:198
#define LibFootprintTextShownColumnsKey
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_module.h:205
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:210
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:102
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
int GetPlacementCost180() const
Definition: class_module.h:570
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:101
void OnAdd3DRow(wxCommandEvent &event) override
const wxString & GetDescription() const
Definition: class_module.h:195
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_module.h:211
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
double GetLocalSolderPasteMarginRatio() const
Definition: class_module.h:213
std::list< MODULE_3D_SETTINGS > & Models()
Definition: class_module.h:178
bool Configure3DPaths(wxWindow *aParent, FILENAME_RESOLVER *aResolver)
see class PGM_BASE
BOARD_ITEM * Next() const
void SetLocked(bool isLocked) override
Function SetLocked sets the MODULE_is_LOCKED bit in the m_ModuleStatus.
Definition: class_module.h:277
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 max(a, b)
Definition: auxiliary.h:86
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
Virtual component: when created by copper shapes on board (Like edge card connectors,...
Definition: class_module.h:78
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
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:199
void OnDeleteField(wxCommandEvent &event) override
DIALOG_FOOTPRINT_FP_EDITOR(FOOTPRINT_EDIT_FRAME *aParent, MODULE *aModule)
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:165
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:173
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 DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:243
void SetFPID(const LIB_ID &aFPID)
Definition: class_module.h:193
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.
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:226
#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:196
std::vector< MODULE_3D_SETTINGS > m_shapes3D_list