KiCad PCB EDA Suite
footprint_libraries_utils.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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <wx/ffile.h>
25 #include <pgm_base.h>
26 #include <kiface_i.h>
27 #include <confirm.h>
28 #include <kicad_string.h>
29 #include <macros.h>
30 #include <pcb_edit_frame.h>
31 #include <dialog_helpers.h>
32 #include <filter_reader.h>
33 #include <fp_lib_table.h>
34 #include <validators.h>
36 #include <tool/tool_manager.h>
37 #include <tools/pcb_actions.h>
38 #include <board.h>
39 #include <footprint.h>
40 #include <board_commit.h>
41 #include <footprint_edit_frame.h>
45 #include <env_paths.h>
46 #include <paths.h>
49 #include "footprint_viewer_frame.h"
50 #include <wx/choicdlg.h>
51 #include <wx/filedlg.h>
52 
53 
54 // unique, "file local" translations:
55 
56 
57 static const wxString INFO_LEGACY_LIB_WARN_EDIT(
58  _( "Writing/modifying legacy libraries (.mod files) is not allowed\n"\
59  "Please save the current library to the new .pretty format\n"\
60  "and update your footprint lib table\n"\
61  "to save your footprint (a .kicad_mod file) in the .pretty library folder" ) );
62 
63 static const wxString INFO_LEGACY_LIB_WARN_DELETE(
64  _( "Modifying legacy libraries (.mod files) is not allowed\n"\
65  "Please save the current library under the new .pretty format\n"\
66  "and update your footprint lib table\n"\
67  "before deleting a footprint" ) );
68 
69 
75 static wxFileName getFootprintFilenameFromUser( wxWindow* aParent, const wxString& aLastPath )
76 {
77  static int lastFilterIndex = 0; // To store the last choice during a session.
78  wxString wildCard;
79 
80  wildCard << KiCadFootprintLibFileWildcard() << wxChar( '|' )
81  << ModLegacyExportFileWildcard() << wxChar( '|' )
82  << GedaPcbFootprintLibFileWildcard() << wxChar( '|' )
83  << AllFilesWildcard();
84 
85  wxFileDialog dlg( aParent, _( "Import Footprint" ), aLastPath, wxEmptyString, wildCard,
86  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
87 
88  dlg.SetFilterIndex( lastFilterIndex );
89 
90  if( dlg.ShowModal() == wxID_CANCEL )
91  return wxFileName();
92 
93  lastFilterIndex = dlg.GetFilterIndex();
94 
95  return wxFileName( dlg.GetPath() );
96 }
97 
98 
105 static IO_MGR::PCB_FILE_T detect_file_type( FILE* aFile, const wxFileName& aFileName,
106  wxString* aName )
107 {
108  FILE_LINE_READER freader( aFile, aFileName.GetFullPath() );
109  WHITESPACE_FILTER_READER reader( freader );
110  IO_MGR::PCB_FILE_T file_type;
111 
112  wxASSERT( aName );
113 
114  reader.ReadLine();
115  char* line = reader.Line();
116 
117  // first .kicad_mod file versions starts by "(module"
118  // recent .kicad_mod file versions starts by "(footprint"
119  if( strncasecmp( line, "(module", strlen( "(module" ) ) == 0
120  || strncasecmp( line, "(footprint", strlen( "(footprint" ) ) == 0 )
121  {
122  file_type = IO_MGR::KICAD_SEXP;
123  *aName = aFileName.GetName();
124  }
125  else if( !strncasecmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) )
126  {
127  file_type = IO_MGR::LEGACY;
128 
129  while( reader.ReadLine() )
130  {
131  if( !strncasecmp( line, "$MODULE", strlen( "$MODULE" ) ) )
132  {
133  *aName = FROM_UTF8( StrPurge( line + strlen( "$MODULE" ) ) );
134  break;
135  }
136  }
137  }
138  else if( !strncasecmp( line, "Element", strlen( "Element" ) ) )
139  {
140  file_type = IO_MGR::GEDA_PCB;
141  *aName = aFileName.GetName();
142  }
143  else
144  {
145  file_type = IO_MGR::FILE_TYPE_NONE;
146  }
147 
148  return file_type;
149 }
150 
151 
158 static FOOTPRINT* parse_footprint_with_plugin( const wxFileName& aFileName,
159  IO_MGR::PCB_FILE_T aFileType,
160  const wxString& aName )
161 {
162  wxString path;
163 
164  switch( aFileType )
165  {
166  case IO_MGR::GEDA_PCB: path = aFileName.GetPath(); break;
167  case IO_MGR::LEGACY: path = aFileName.GetFullPath(); break;
168  default: wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) ); break;
169  }
170 
171  PLUGIN::RELEASER pi( IO_MGR::PluginFind( aFileType ) );
172 
173  return pi->FootprintLoad( path, aName );
174 }
175 
176 
181 static FOOTPRINT* parse_footprint_kicad( const wxFileName& aFileName )
182 {
183  wxString fcontents;
184  PCB_IO pcb_io;
185  wxFFile f( aFileName.GetFullPath() );
186 
187  if( !f.IsOpened() )
188  return nullptr;
189 
190  f.ReadAll( &fcontents );
191 
192  return dynamic_cast<FOOTPRINT*>( pcb_io.Parse( fcontents ) );
193 }
194 
195 
202 FOOTPRINT* try_load_footprint( const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
203  const wxString& aName )
204 {
205  FOOTPRINT* footprint;
206 
207  switch( aFileType )
208  {
209  case IO_MGR::GEDA_PCB:
210  case IO_MGR::LEGACY:
211  footprint = parse_footprint_with_plugin( aFileName, aFileType, aName );
212  break;
213 
214  case IO_MGR::KICAD_SEXP:
215  footprint = parse_footprint_kicad( aFileName );
216  break;
217 
218  default:
219  wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) );
220  footprint = nullptr;
221  }
222 
223  return footprint;
224 }
225 
226 
228 {
229  wxString lastOpenedPathForLoading = m_mruPath;
231 
232  if( !cfg->m_LastImportExportPath.empty() )
233  lastOpenedPathForLoading = cfg->m_LastImportExportPath;
234 
235  wxFileName fn;
236 
237  if( aName != wxT("") )
238  fn = aName;
239  else
240  fn = getFootprintFilenameFromUser( this, lastOpenedPathForLoading );
241 
242  if( !fn.IsOk() )
243  return nullptr;
244 
245  FILE* fp = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
246 
247  if( !fp )
248  {
249  wxString msg = wxString::Format( _( "File \"%s\" not found" ), fn.GetFullPath() );
250  DisplayError( this, msg );
251  return nullptr;
252  }
253 
254  cfg->m_LastImportExportPath = lastOpenedPathForLoading;
255 
256  wxString footprintName;
257  IO_MGR::PCB_FILE_T fileType = detect_file_type( fp, fn.GetFullPath(), &footprintName );
258 
260  {
261  DisplayError( this, _( "Not a footprint file" ) );
262  return nullptr;
263  }
264 
265  FOOTPRINT* footprint = nullptr;
266 
267  try
268  {
269  footprint = try_load_footprint( fn, fileType, footprintName );
270 
271  if( !footprint )
272  {
273  wxString msg = wxString::Format( _( "Unable to load footprint '%s' from '%s'" ),
274  footprintName,
275  fn.GetFullPath() );
276  DisplayError( this, msg );
277  return nullptr;
278  }
279  }
280  catch( const IO_ERROR& ioe )
281  {
282  DisplayError( this, ioe.What() );
283 
284  // if the footprint is not loaded, exit.
285  // However, even if an error happens, it can be loaded, because in KICAD and GPCB format,
286  // a fp library is a set of separate files, and the error(s) are not necessary when
287  // reading the selected file
288 
289  if( !footprint )
290  return nullptr;
291  }
292 
293  footprint->SetFPID( LIB_ID( wxEmptyString, footprintName ) );
294 
295  // Insert footprint in list
296  AddFootprintToBoard( footprint );
297 
298  // Display info :
299  SetMsgPanel( footprint );
300  PlaceFootprint( footprint );
301 
302  footprint->SetPosition( wxPoint( 0, 0 ) );
303 
305  UpdateView();
306 
307  return footprint;
308 }
309 
310 
312 {
313  wxFileName fn;
315 
316  if( !aFootprint )
317  return;
318 
319  fn.SetName( aFootprint->GetFPID().GetLibItemName() );
320 
321  wxString wildcard = KiCadFootprintLibFileWildcard();
322 
323  fn.SetExt( KiCadFootprintFileExtension );
324 
325  if( !cfg->m_LastImportExportPath.empty() )
326  fn.SetPath( cfg->m_LastImportExportPath );
327  else
328  fn.SetPath( m_mruPath );
329 
330  wxFileDialog dlg( this, _( "Export Footprint" ), fn.GetPath(), fn.GetFullName(),
331  wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
332 
333  if( dlg.ShowModal() == wxID_CANCEL )
334  return;
335 
336  fn = dlg.GetPath();
337  cfg->m_LastImportExportPath = fn.GetPath();
338 
339  try
340  {
341  // Export as *.kicad_pcb format, using a strategy which is specifically chosen
342  // as an example on how it could also be used to send it to the system clipboard.
343 
344  PCB_IO pcb_io( CTL_FOR_LIBRARY );
345 
346  /* This footprint should *already* be "normalized" in a way such that
347  orientation is zero, etc., since it came from the Footprint Editor.
348 
349  aFootprint->SetParent( 0 );
350  aFootprint->SetOrientation( 0 );
351  */
352 
353  pcb_io.Format( aFootprint );
354 
355  FILE* fp = wxFopen( dlg.GetPath(), wxT( "wt" ) );
356 
357  if( fp == nullptr )
358  {
359  wxMessageBox( wxString::Format( _( "Unable to create or write file '%s'." ),
360  dlg.GetPath() ) );
361  return;
362  }
363 
364  fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() );
365  fclose( fp );
366  }
367  catch( const IO_ERROR& ioe )
368  {
369  DisplayError( this, ioe.What() );
370  return;
371  }
372 
373  wxString msg = wxString::Format( _( "Footprint exported to file '%s'." ), dlg.GetPath() );
374  DisplayInfoMessage( this, msg );
375 }
376 
377 
378 wxString PCB_BASE_EDIT_FRAME::CreateNewProjectLibrary( const wxString& aLibName,
379  const wxString& aProposedName )
380 {
381  return createNewLibrary( aLibName, aProposedName, Prj().PcbFootprintLibs() );
382 }
383 
384 
385 wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary( const wxString& aLibName,
386  const wxString& aProposedName )
387 {
388  FP_LIB_TABLE* table = selectLibTable();
389 
390  return createNewLibrary( aLibName, aProposedName, table );
391 }
392 
393 
394 wxString PCB_BASE_EDIT_FRAME::createNewLibrary( const wxString& aLibName,
395  const wxString& aProposedName,
396  FP_LIB_TABLE* aTable )
397 {
398  // Kicad cannot write legacy format libraries, only .pretty new format because the legacy
399  // format cannot handle current features.
400  // The footprint library is actually a directory.
401 
402  if( aTable == nullptr )
403  return wxEmptyString;
404 
405  wxString initialPath = aProposedName.IsEmpty() ? Prj().GetProjectPath() : aProposedName;
406  wxFileName fn;
407  bool doAdd = false;
408  bool isGlobal = ( aTable == &GFootprintTable );
409 
410  if( aLibName.IsEmpty() )
411  {
412  fn = initialPath;
413 
415  KiCadFootprintLibPathExtension, false, isGlobal,
417  {
418  return wxEmptyString;
419  }
420 
421  doAdd = true;
422  }
423  else
424  {
425  fn = aLibName;
426 
427  if( !fn.IsAbsolute() )
428  {
429  fn.SetName( aLibName );
430  fn.MakeAbsolute( initialPath );
431  }
432 
433  // Enforce the .pretty extension:
434  fn.SetExt( KiCadFootprintLibPathExtension );
435  }
436 
437  // We can save fp libs only using IO_MGR::KICAD_SEXP format (.pretty libraries)
439  wxString libPath = fn.GetFullPath();
440 
441  try
442  {
443  PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
444 
445  bool writable = false;
446  bool exists = false;
447 
448  try
449  {
450  writable = pi->IsFootprintLibWritable( libPath );
451  exists = true; // no exception was thrown, lib must exist.
452  }
453  catch( const IO_ERROR& )
454  {
455  // best efforts....
456  }
457 
458  if( exists )
459  {
460  if( !writable )
461  {
462  wxString msg = wxString::Format( _( "Library %s is read only." ), libPath );
463  ShowInfoBarError( msg );
464  return wxEmptyString;
465  }
466  else
467  {
468  wxString msg = wxString::Format( _( "Library %s already exists." ), libPath );
469  KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
470  dlg.SetOKLabel( _( "Overwrite" ) );
471  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
472 
473  if( dlg.ShowModal() == wxID_CANCEL )
474  return wxEmptyString;
475 
476  pi->FootprintLibDelete( libPath );
477  }
478  }
479 
480  pi->FootprintLibCreate( libPath );
481  }
482  catch( const IO_ERROR& ioe )
483  {
484  DisplayError( this, ioe.What() );
485  return wxEmptyString;
486  }
487 
488  if( doAdd )
489  AddLibrary( libPath, aTable );
490 
491  return libPath;
492 }
493 
494 
496 {
497  // If no project is loaded, always work with the global table
498  if( Prj().IsNullProject() )
499  {
501 
502  if( aOptional )
503  {
504  wxMessageDialog dlg( this, _( "Add the library to the global library table?" ),
505  _( "Add To Global Library Table" ), wxYES_NO );
506 
507  if( dlg.ShowModal() != wxID_OK )
508  ret = nullptr;
509  }
510 
511  return ret;
512  }
513 
514  wxArrayString libTableNames;
515  libTableNames.Add( _( "Global" ) );
516  libTableNames.Add( _( "Project" ) );
517 
518  wxSingleChoiceDialog dlg( this, _( "Choose the Library Table to add the library to:" ),
519  _( "Add To Library Table" ), libTableNames );
520 
521  if( aOptional )
522  {
523  dlg.FindWindow( wxID_CANCEL )->SetLabel( _( "Skip" ) );
524  dlg.FindWindow( wxID_OK )->SetLabel( _( "Add" ) );
525  }
526 
527  if( dlg.ShowModal() != wxID_OK )
528  return nullptr;
529 
530  switch( dlg.GetSelection() )
531  {
532  case 0: return &GFootprintTable;
533  case 1: return Prj().PcbFootprintLibs();
534  default: return nullptr;
535  }
536 }
537 
538 
539 bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aFilename, FP_LIB_TABLE* aTable )
540 {
541  if( aTable == nullptr )
542  aTable = selectLibTable();
543 
544  if( aTable == nullptr )
545  return wxEmptyString;
546 
547  bool isGlobal = ( aTable == &GFootprintTable );
548 
549  wxFileName fn( aFilename );
550 
551  if( aFilename.IsEmpty() )
552  {
554  KiCadFootprintLibPathExtension, true, isGlobal,
556  {
557  return false;
558  }
559  }
560 
561  wxString libPath = fn.GetFullPath();
562  wxString libName = fn.GetName();
563 
564  if( libName.IsEmpty() )
565  return false;
566 
567  wxString type = IO_MGR::ShowType( IO_MGR::GuessPluginTypeFromLibPath( libPath ) );
568 
569  // try to use path normalized to an environmental variable or project path
570  wxString normalizedPath = NormalizePath( libPath, &Pgm().GetLocalEnvVariables(), &Prj() );
571 
572  if( normalizedPath.IsEmpty() )
573  normalizedPath = libPath;
574 
575  try
576  {
577  FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString );
578  aTable->InsertRow( row );
579 
580  if( isGlobal )
582  else
583  Prj().PcbFootprintLibs()->Save( Prj().FootprintLibTblName() );
584  }
585  catch( const IO_ERROR& ioe )
586  {
587  DisplayError( this, ioe.What() );
588  return false;
589  }
590 
592 
593  if( editor )
594  {
595  LIB_ID libID( libName, wxEmptyString );
596  editor->SyncLibraryTree( true );
597  editor->FocusOnLibID( libID );
598  }
599 
600  auto viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
601 
602  if( viewer )
603  viewer->ReCreateLibraryList();
604 
605  return true;
606 }
607 
608 
609 bool FOOTPRINT_EDIT_FRAME::DeleteFootprintFromLibrary( const LIB_ID& aFPID, bool aConfirm )
610 {
611  if( !aFPID.IsValid() )
612  return false;
613 
614  wxString nickname = aFPID.GetLibNickname();
615  wxString fpname = aFPID.GetLibItemName();
616 
617  // Legacy libraries are readable, but modifying legacy format is not allowed
618  // So prompt the user if he try to delete a footprint from a legacy lib
619  wxString libfullname = Prj().PcbFootprintLibs()->FindRow( nickname )->GetFullURI();
620 
621  if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY )
622  {
624  return false;
625  }
626 
627  if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
628  {
629  wxString msg = wxString::Format( _( "Library '%s' is read only." ), nickname );
630  ShowInfoBarError( msg );
631  return false;
632  }
633 
634  // Confirmation
635  wxString msg = wxString::Format( _( "Delete footprint '%s' from library '%s'?" ),
636  fpname.GetData(),
637  nickname.GetData() );
638 
639  if( aConfirm && !IsOK( this, msg ) )
640  return false;
641 
642  try
643  {
644  Prj().PcbFootprintLibs()->FootprintDelete( nickname, fpname );
645  }
646  catch( const IO_ERROR& ioe )
647  {
648  DisplayError( this, ioe.What() );
649  return false;
650  }
651 
652  msg.Printf( _( "Footprint '%s' deleted from library '%s'" ),
653  fpname.GetData(),
654  nickname.GetData() );
655 
656  SetStatusText( msg );
657 
658  return true;
659 }
660 
661 
662 void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxString& aLibName,
663  wxString* aLibPath )
664 {
665  if( GetBoard()->GetFirstFootprint() == nullptr )
666  {
667  DisplayInfoMessage( this, _( "No footprints to export!" ) );
668  return;
669  }
670 
671  wxString footprintName;
672 
673  auto resetReference =
674  []( FOOTPRINT* aFootprint )
675  {
676  aFootprint->SetReference( "REF**" );
677  };
678 
679  if( !aStoreInNewLib )
680  {
681  // The footprints are saved in an existing .pretty library in the fp lib table
682  PROJECT& prj = Prj();
683  wxString last_nickname = prj.GetRString( PROJECT::PCB_LIB_NICKNAME );
684  wxString nickname = SelectLibrary( last_nickname );
685 
686  if( !nickname ) // Aborted
687  return;
688 
689  prj.SetRString( PROJECT::PCB_LIB_NICKNAME, nickname );
690 
691  for( FOOTPRINT* footprint : GetBoard()->Footprints() )
692  {
693  try
694  {
695  FP_LIB_TABLE* tbl = prj.PcbFootprintLibs();
696 
697  if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
698  {
699  FOOTPRINT* fpCopy = static_cast<FOOTPRINT*>( footprint->Duplicate() );
700 
701  resetReference( fpCopy );
702  tbl->FootprintSave( nickname, fpCopy, true );
703 
704  delete fpCopy;
705  }
706  }
707  catch( const IO_ERROR& ioe )
708  {
709  DisplayError( this, ioe.What() );
710  }
711  }
712  }
713  else
714  {
715  // The footprints are saved in a new .pretty library.
716  // If this library already exists, all previous footprints will be deleted
717  wxString libPath = CreateNewLibrary( aLibName );
718 
719  if( libPath.IsEmpty() ) // Aborted
720  return;
721 
722  if( aLibPath )
723  *aLibPath = libPath;
724 
726  PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
727 
728  for( FOOTPRINT* footprint : GetBoard()->Footprints() )
729  {
730  try
731  {
732  if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
733  {
734  FOOTPRINT* fpCopy = static_cast<FOOTPRINT*>( footprint->Duplicate() );
735 
736  resetReference( fpCopy );
737  pi->FootprintSave( libPath, fpCopy );
738 
739  delete fpCopy;
740  }
741  }
742  catch( const IO_ERROR& ioe )
743  {
744  DisplayError( this, ioe.What() );
745  }
746  }
747  }
748 }
749 
750 
752 {
753  if( !aFootprint ) // Happen if no footprint loaded
754  return false;
755 
756  wxString libraryName = aFootprint->GetFPID().GetLibNickname();
757  wxString footprintName = aFootprint->GetFPID().GetLibItemName();
758  bool nameChanged = m_footprintNameWhenLoaded != footprintName;
759 
760  if( aFootprint->GetLink() != niluuid )
761  {
762  if( SaveFootprintToBoard( false ) )
763  {
764  m_footprintNameWhenLoaded = footprintName;
765  return true;
766  }
767  else
768  {
769  return false;
770  }
771  }
772  else if( libraryName.IsEmpty() || footprintName.IsEmpty() )
773  {
774  if( SaveFootprintAs( aFootprint ) )
775  {
776  m_footprintNameWhenLoaded = footprintName;
777  SyncLibraryTree( true );
778  return true;
779  }
780  else
781  {
782  return false;
783  }
784  }
785 
786  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
787 
788  // Legacy libraries are readable, but modifying legacy format is not allowed
789  // So prompt the user if he try to add/replace a footprint in a legacy lib
790  wxString libfullname = tbl->FindRow( libraryName )->GetFullURI();
791 
792  if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY )
793  {
795  return false;
796  }
797 
798  if( nameChanged )
799  {
800  LIB_ID oldFPID( libraryName, m_footprintNameWhenLoaded );
801  DeleteFootprintFromLibrary( oldFPID, false );
802  }
803 
804  if( !SaveFootprintInLibrary( aFootprint, libraryName ) )
805  return false;
806 
807  if( nameChanged )
808  {
809  m_footprintNameWhenLoaded = footprintName;
810  SyncLibraryTree( true );
811  }
812 
813  return true;
814 }
815 
816 
818  const wxString& aLibraryName )
819 {
820  try
821  {
822  aFootprint->SetFPID( LIB_ID( wxEmptyString, aFootprint->GetFPID().GetLibItemName() ) );
823 
824  Prj().PcbFootprintLibs()->FootprintSave( aLibraryName, aFootprint );
825 
826  aFootprint->SetFPID( LIB_ID( aLibraryName, aFootprint->GetFPID().GetLibItemName() ) );
827  return true;
828  }
829  catch( const IO_ERROR& ioe )
830  {
831  DisplayError( this, ioe.What() );
832 
833  aFootprint->SetFPID( LIB_ID( aLibraryName, aFootprint->GetFPID().GetLibItemName() ) );
834  return false;
835  }
836 }
837 
838 
840 {
841  // update footprint in the current board,
842  // not just add it to the board with total disregard for the netlist...
843  PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB_EDITOR, false );
844 
845  if( pcbframe == nullptr ) // happens when the board editor is not active (or closed)
846  {
847  ShowInfoBarError( _( "No board currently open." ) );
848  return false;
849  }
850 
851  BOARD* mainpcb = pcbframe->GetBoard();
852  FOOTPRINT* sourceFootprint = nullptr;
853  FOOTPRINT* editorFootprint = GetBoard()->GetFirstFootprint();
854 
855  // Search the old footprint (source) if exists
856  // Because this source could be deleted when editing the main board...
857  if( editorFootprint->GetLink() != niluuid ) // this is not a new footprint ...
858  {
859  sourceFootprint = nullptr;
860 
861  for( FOOTPRINT* candidate : mainpcb->Footprints() )
862  {
863  if( editorFootprint->GetLink() == candidate->m_Uuid )
864  {
865  sourceFootprint = candidate;
866  break;
867  }
868  }
869  }
870 
871  if( !aAddNew && sourceFootprint == nullptr ) // source not found
872  {
873  DisplayError( this, _( "Unable to find the footprint on the main board.\nCannot save." ) );
874  return false;
875  }
876 
879  BOARD_COMMIT commit( pcbframe );
880 
881  // Create a copy for the board, first using Clone() to keep existing Uuids, and then either
882  // resetting the uuids to the board values or assigning new Uuids.
883  FOOTPRINT* newFootprint = static_cast<FOOTPRINT*>( editorFootprint->Clone() );
884  newFootprint->SetParent( mainpcb );
885  newFootprint->SetLink( niluuid );
886 
887  auto fixUuid =
888  [&]( KIID& aUuid )
889  {
890  if( editorFootprint->GetLink() != niluuid && m_boardFootprintUuids.count( aUuid ) )
891  aUuid = m_boardFootprintUuids[ aUuid ];
892  else
893  aUuid = KIID();
894  };
895 
896  fixUuid( const_cast<KIID&>( newFootprint->m_Uuid ) );
897  newFootprint->RunOnChildren(
898  [&]( BOARD_ITEM* aChild )
899  {
900  fixUuid( const_cast<KIID&>( aChild->m_Uuid ) );
901  } );
902 
903  if( sourceFootprint ) // this is an update command
904  {
905  // In the main board the new footprint replaces the old one (pos, orient, ref, value,
906  // connections and properties are kept) and the sourceFootprint (old footprint) is
907  // deleted
908  pcbframe->ExchangeFootprint( sourceFootprint, newFootprint, commit );
909  commit.Push( wxT( "Update footprint" ) );
910  }
911  else // This is an insert command
912  {
913  KIGFX::VIEW_CONTROLS* viewControls = pcbframe->GetCanvas()->GetViewControls();
914  VECTOR2D cursorPos = viewControls->GetCursorPosition();
915 
916  commit.Add( newFootprint );
917  viewControls->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
918  pcbframe->PlaceFootprint( newFootprint );
919  newFootprint->SetPosition( wxPoint( 0, 0 ) );
920  viewControls->SetCrossHairCursorPosition( cursorPos, false );
921  const_cast<KIID&>( newFootprint->m_Uuid ) = KIID();
922  commit.Push( wxT( "Insert footprint" ) );
923 
924  pcbframe->Raise();
925  pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
926  }
927 
928  newFootprint->ClearFlags();
929 
930  return true;
931 }
932 
933 
935 {
936  if( aFootprint == nullptr )
937  return false;
938 
939  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
940 
941  SetMsgPanel( aFootprint );
942 
943  wxString libraryName = aFootprint->GetFPID().GetLibNickname();
944  wxString footprintName = aFootprint->GetFPID().GetLibItemName();
945  bool updateValue = aFootprint->GetValue() == footprintName;
946 
947  wxArrayString headers;
948  std::vector<wxArrayString> itemsToDisplay;
949  std::vector<wxString> nicknames = tbl->GetLogicalLibs();
950 
951  headers.Add( _( "Nickname" ) );
952  headers.Add( _( "Description" ) );
953 
954  for( const wxString& nickname : nicknames )
955  {
956  wxArrayString item;
957  item.Add( nickname );
958  item.Add( tbl->GetDescription( nickname ) );
959  itemsToDisplay.push_back( item );
960  }
961 
962  EDA_LIST_DIALOG dlg( this, _( "Save Footprint As" ), headers, itemsToDisplay, libraryName );
963  dlg.SetListLabel( _( "Save in library:" ) );
964  dlg.SetOKLabel( _( "Save" ) );
965 
966  wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
967 
968  wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ),
969  wxDefaultPosition, wxDefaultSize, 0 );
970  bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
971 
972  wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, footprintName,
973  wxDefaultPosition, wxDefaultSize, 0 );
974  bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
975 
976  wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
977  nameValidator.SetCharExcludes( FOOTPRINT::StringLibNameInvalidChars( false ) );
978  nameTextCtrl->SetValidator( nameValidator );
979 
980  wxSizer* mainSizer = dlg.GetSizer();
981  mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
982 
983  // Move nameTextCtrl to the head of the tab-order
984  if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
985  dlg.GetChildren().Insert( nameTextCtrl );
986 
987  dlg.SetInitialFocus( nameTextCtrl );
988 
989  dlg.Layout();
990  mainSizer->Fit( &dlg );
991 
992  if( dlg.ShowModal() != wxID_OK )
993  return false; // canceled by user
994 
995  libraryName = dlg.GetTextSelection();
996 
997  if( libraryName.IsEmpty() )
998  {
999  DisplayError( this, _( "No library specified. Footprint could not be saved." ) );
1000  return false;
1001  }
1002 
1003  footprintName = nameTextCtrl->GetValue();
1004  footprintName.Trim( true );
1005  footprintName.Trim( false );
1006 
1007  if( footprintName.IsEmpty() )
1008  {
1009  DisplayError( this, _( "No footprint name specified. Footprint could not be saved." ) );
1010  return false;
1011  }
1012 
1013  aFootprint->SetFPID( LIB_ID( libraryName, footprintName ) );
1014 
1015  if( updateValue )
1016  aFootprint->SetValue( footprintName );
1017 
1018  // Legacy libraries are readable, but modifying legacy format is not allowed
1019  // So prompt the user if he try to add/replace a footprint in a legacy lib
1020  wxString libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
1022 
1023  if( piType == IO_MGR::LEGACY )
1024  {
1026  return false;
1027  }
1028 
1029  bool footprintExists = tbl->FootprintExists( libraryName, footprintName );
1030 
1031  if( footprintExists )
1032  {
1033  wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ),
1034  footprintName,
1035  libraryName );
1036  KIDIALOG chkdlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
1037  chkdlg.SetOKLabel( _( "Overwrite" ) );
1038 
1039  if( chkdlg.ShowModal() == wxID_CANCEL )
1040  return false;
1041  }
1042 
1043  if( !SaveFootprintInLibrary( aFootprint, libraryName ) )
1044  return false;
1045 
1046  // Once saved-as a board footprint is no longer a board footprint
1047  aFootprint->SetLink( niluuid );
1048 
1049  wxString fmt = footprintExists ? _( "Footprint '%s' replaced in '%s'" )
1050  : _( "Footprint '%s' added to '%s'" );
1051 
1052  wxString msg = wxString::Format( fmt, footprintName.GetData(), libraryName.GetData() );
1053  SetStatusText( msg );
1054  UpdateTitle();
1055  ReCreateHToolbar();
1056 
1057  return true;
1058 }
1059 
1060 
1062 {
1064  {
1065  wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ),
1066  GetLoadedFPID().GetLibItemName().wx_str() );
1067 
1068  if( ConfirmRevertDialog( this, msg ) )
1069  {
1070  Clear_Pcb( false );
1071  AddFootprintToBoard( static_cast<FOOTPRINT*>( m_revertModule->Clone() ) );
1072 
1073  Zoom_Automatique( false );
1074 
1075  Update3DView( true, true );
1076 
1078  GetScreen()->SetContentModified( false );
1079 
1080  UpdateView();
1081  GetCanvas()->Refresh();
1082 
1083  return true;
1084  }
1085  }
1086 
1087  return false;
1088 }
1089 
1090 
1091 FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName )
1092 {
1093  wxString footprintName = aFootprintName;
1094 
1095  // Ask for the new footprint name
1096  if( footprintName.IsEmpty() )
1097  {
1098  WX_TEXT_ENTRY_DIALOG dlg( this, _( "Enter footprint name:" ), _( "New Footprint" ),
1099  footprintName );
1100  dlg.SetTextValidator( FOOTPRINT_NAME_VALIDATOR( &footprintName ) );
1101 
1102  if( dlg.ShowModal() != wxID_OK )
1103  return nullptr; //Aborted by user
1104  }
1105 
1106  footprintName.Trim( true );
1107  footprintName.Trim( false );
1108 
1109  if( footprintName.IsEmpty() )
1110  {
1111  DisplayInfoMessage( this, _( "No footprint name defined." ) );
1112  return nullptr;
1113  }
1114 
1115  // Creates the new footprint and add it to the head of the linked list of footprints
1116  FOOTPRINT* footprint = new FOOTPRINT( GetBoard() );
1117 
1118  // Update parameters: timestamp ...
1119  footprint->SetLastEditTime();
1120 
1121  // Update its name in lib
1122  footprint->SetFPID( LIB_ID( wxEmptyString, footprintName ) );
1123 
1124  PCB_LAYER_ID txt_layer;
1125  wxPoint default_pos;
1127 
1128  footprint->Reference().SetText( settings.m_DefaultFPTextItems[0].m_Text );
1129  footprint->Reference().SetVisible( settings.m_DefaultFPTextItems[0].m_Visible );
1130  txt_layer = (PCB_LAYER_ID) settings.m_DefaultFPTextItems[0].m_Layer;
1131  footprint->Reference().SetLayer( txt_layer );
1132  default_pos.y -= settings.GetTextSize( txt_layer ).y / 2;
1133  footprint->Reference().SetPosition( default_pos );
1134  default_pos.y += settings.GetTextSize( txt_layer ).y;
1135 
1136  footprint->Value().SetText( settings.m_DefaultFPTextItems[1].m_Text );
1137  footprint->Value().SetVisible( settings.m_DefaultFPTextItems[1].m_Visible );
1138  txt_layer = (PCB_LAYER_ID) settings.m_DefaultFPTextItems[1].m_Layer;
1139  footprint->Value().SetLayer( txt_layer );
1140  default_pos.y += settings.GetTextSize( txt_layer ).y / 2;
1141  footprint->Value().SetPosition( default_pos );
1142  default_pos.y += settings.GetTextSize( txt_layer ).y;
1143 
1144  for( size_t i = 2; i < settings.m_DefaultFPTextItems.size(); ++i )
1145  {
1146  FP_TEXT* textItem = new FP_TEXT( footprint );
1147  textItem->SetText( settings.m_DefaultFPTextItems[i].m_Text );
1148  textItem->SetVisible( settings.m_DefaultFPTextItems[i].m_Visible );
1149  txt_layer = (PCB_LAYER_ID) settings.m_DefaultFPTextItems[i].m_Layer;
1150  textItem->SetLayer( txt_layer );
1151  default_pos.y += settings.GetTextSize( txt_layer ).y / 2;
1152  textItem->SetPosition( default_pos );
1153  default_pos.y += settings.GetTextSize( txt_layer ).y;
1154  footprint->GraphicalItems().push_back( textItem );
1155  }
1156 
1157  if( footprint->GetReference().IsEmpty() )
1158  footprint->SetReference( footprintName );
1159 
1160  if( footprint->GetValue().IsEmpty() )
1161  footprint->SetValue( footprintName );
1162 
1163  footprint->RunOnChildren(
1164  [&] ( BOARD_ITEM* aChild )
1165  {
1166  if( aChild->Type() == PCB_FP_TEXT_T )
1167  {
1168  FP_TEXT* textItem = static_cast<FP_TEXT*>( aChild );
1169  PCB_LAYER_ID layer = textItem->GetLayer();
1170 
1171  textItem->SetTextThickness( settings.GetTextThickness( layer ) );
1172  textItem->SetTextSize( settings.GetTextSize( layer ) );
1173  textItem->SetItalic( settings.GetTextItalic( layer ) );
1174  textItem->SetKeepUpright( settings.GetTextUpright( layer ) );
1175  }
1176  } );
1177 
1178  SetMsgPanel( footprint );
1179  return footprint;
1180 }
1181 
1182 
1183 wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
1184 {
1185  wxArrayString headers;
1186 
1187  headers.Add( _( "Nickname" ) );
1188  headers.Add( _( "Description" ) );
1189 
1190  FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
1191 
1192  std::vector< wxArrayString > itemsToDisplay;
1193  std::vector< wxString > nicknames = fptbl->GetLogicalLibs();
1194 
1195  for( const wxString& nickname : nicknames )
1196  {
1197  wxArrayString item;
1198 
1199  item.Add( nickname );
1200  item.Add( fptbl->GetDescription( nickname ) );
1201 
1202  itemsToDisplay.push_back( item );
1203  }
1204 
1205  EDA_LIST_DIALOG dlg( this, _( "Select Library" ), headers, itemsToDisplay, aNicknameExisting );
1206 
1207  if( dlg.ShowModal() != wxID_OK )
1208  return wxEmptyString;
1209 
1210  return dlg.GetTextSelection();
1211 }
void SetReference(const wxString &aReference)
Definition: footprint.h:430
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
void BuildListOfNets()
Definition: board.h:663
std::map< KIID, KIID > m_boardFootprintUuids
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:55
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:196
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
static const wxString INFO_LEGACY_LIB_WARN_EDIT(_("Writing/modifying legacy libraries (.mod files) is not allowed\n" "Please save the current library to the new .pretty format\n" "and update your footprint lib table\n" "to save your footprint (a .kicad_mod file) in the .pretty library folder"))
void ReCreateHToolbar() override
Create the main horizontal toolbar for the footprint editor.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
BOARD_ITEM * Parse(const wxString &aClipboardSourceInput)
std::vector< TEXT_ITEM_INFO > m_DefaultFPTextItems
KIID niluuid(0)
wxString GetTextSelection(int aColumn=0)
Return the selected text from aColumn in the wxListCtrl in the dialog.
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Return a pointer to the #VIEW_CONTROLS instance used in the panel.
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
wxString m_mruPath
virtual void SetPosition(const wxPoint &aPos) override
Definition: fp_text.h:93
FP_LIB_TABLE GFootprintTable
!!!!!!!!!!!!!! This code is obsolete because of the merge into pcbnew, don't bother with it.
Definition: cvpcb.cpp:120
Container for project specific data.
Definition: project.h:62
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
const wxString & GetValue() const
Definition: footprint.h:443
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
Definition: string.cpp:463
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:40
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:192
This file is part of the common library.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
const std::string KiCadFootprintFileExtension
static wxFileName getFootprintFilenameFromUser(wxWindow *aParent, const wxString &aLastPath)
Prompt the user for a footprint file to open.
void SetOKLabel(const wxString &aLabel)
COMMIT & Add(EDA_ITEM *aItem)
Notify observers that aItem has been added.
Definition: commit.h:78
static FOOTPRINT * parse_footprint_kicad(const wxFileName &aFileName)
Parse a KICAD footprint.
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:186
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
bool LibraryFileBrowser(bool doOpen, wxFileName &aFilename, const wxString &wildcard, const wxString &ext, bool isDirectory=false, bool aIsGlobal=false, const wxString &aGlobalPath=wxEmptyString)
Component library viewer main window.
void SetTextValidator(wxTextValidatorStyle style)
void SetVisible(bool aVisible)
Definition: eda_text.h:192
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:373
A dialog which shows:
void SaveFootprintToBoard(wxCommandEvent &event)
bool DeleteFootprintFromLibrary(const LIB_ID &aFPID, bool aConfirm)
Delete the given footprint from its library.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
static const wxString ShowType(PCB_FILE_T aFileType)
Return a brief name for a plugin given aFileType enum.
Definition: io_mgr.cpp:77
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
Return the default text thickness from the layer class for the given layer.
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:168
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:123
wxString AllFilesWildcard()
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
Read lines of text from another LINE_READER but only returns non-comment lines and non-blank lines wi...
Definition: filter_reader.h:68
Geda PCB file formats.
Definition: io_mgr.h:64
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Return a plugin type given a footprint library's libPath.
Definition: io_mgr.cpp:124
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
void PlaceFootprint(FOOTPRINT *aFootprint, bool aRecreateRatsnest=true)
Places aFootprint at the current cursor position and updates footprint coordinates with the new posit...
This file contains miscellaneous commonly used macros and functions.
void ExportFootprintsToLibrary(bool aStoreInNewLib, const wxString &aLibName=wxEmptyString, wxString *aLibPath=NULL)
Save footprints in a library:
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:457
bool GetTextUpright(PCB_LAYER_ID aLayer) const
This class provides a custom wxValidator object for limiting the allowable characters when defining f...
Definition: validators.h:63
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
FP_TEXT & Reference()
Definition: footprint.h:458
bool GetTextItalic(PCB_LAYER_ID aLayer) const
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:555
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
void ExportFootprint(FOOTPRINT *aFootprint)
Create a file containing only one footprint.
void SyncLibraryTree(bool aProgress)
Synchronize the footprint library tree to the current state of the footprint library table.
Definition: kiid.h:44
void ExchangeFootprint(FOOTPRINT *aExisting, FOOTPRINT *aNew, BOARD_COMMIT &aCommit, bool deleteExtraTexts=true, bool resetTextLayers=true, bool resetTextEffects=true, bool resetFabricationAttrs=true, bool reset3DModels=true)
Replace aExisting footprint by aNew footprint using the Existing footprint settings (position,...
static FOOTPRINT * parse_footprint_with_plugin(const wxFileName &aFileName, IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
Parse a footprint using a PLUGIN.
PCB_LAYER_ID
A quick note on layer IDs:
#define FOOTPRINT_LIBRARY_HEADER
Definition: legacy_plugin.h:38
bool Clear_Pcb(bool aQuery)
Delete all and reinitialize the current board.
Definition: initpcb.cpp:97
A LINE_READER that reads from an open file.
Definition: richio.h:172
wxString CreateNewProjectLibrary(const wxString &aLibName=wxEmptyString, const wxString &aProposedName=wxEmptyString)
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:317
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:114
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
std::string GetStringOutput(bool doClear)
const wxString GetDescription(const wxString &aNickname)
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
bool SaveFootprintInLibrary(FOOTPRINT *aFootprint, const wxString &aLibraryName)
wxString CreateNewLibrary(const wxString &aLibName=wxEmptyString, const wxString &aProposedName=wxEmptyString)
If a library name is given, creates a new footprint library in the project folder with the given name...
FOOTPRINTS & Footprints()
Definition: board.h:233
wxString ModLegacyExportFileWildcard()
Definition of file extensions used in Kicad.
Helper dialog and control classes.
An interface for classes handling user events controlling the view behavior such as zooming,...
const wxString & GetReference() const
Definition: footprint.h:421
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:92
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:154
DRAWINGS & GraphicalItems()
Definition: footprint.h:162
const LIB_ID & GetFPID() const
Definition: footprint.h:185
static IO_MGR::PCB_FILE_T detect_file_type(FILE *aFile, const wxFileName &aFileName, wxString *aName)
Read a file to detect the type.
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
bool AddLibrary(const wxString &aLibName=wxEmptyString, FP_LIB_TABLE *aTable=nullptr)
Add an existing library to either the global or project library table.
void SetValue(const wxString &aValue)
Definition: footprint.h:451
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:273
std::unique_ptr< FOOTPRINT > m_revertModule
#define FOOTPRINT_LIBRARY_HEADER_CNT
Definition: legacy_plugin.h:39
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
KIID GetLink() const
Definition: footprint.h:526
virtual void SetRString(RSTRING_T aStringId, const wxString &aString)
Store a "retained string", which is any session and project specific string identified in enum RSTRIN...
Definition: project.cpp:213
const KIID m_Uuid
Definition: eda_item.h:475
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:285
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
FOOTPRINT * CreateNewFootprint(const wxString &aFootprintName)
Creates a new footprint, at position 0,0.
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:186
void SetKeepUpright(bool aKeepUpright)
Definition: fp_text.h:115
void SetLink(const KIID &aLink)
Definition: footprint.h:527
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
virtual const wxString & GetRString(RSTRING_T aStringId)
Return a "retained string", which is any session and project specific string identified in enum RSTRI...
Definition: project.cpp:228
wxString KiCadFootprintLibPathWildcard()
static TOOL_ACTION placeFootprint
Definition: pcb_actions.h:160
static wxString GetDefaultUserFootprintsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:108
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:156
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:55
see class PGM_BASE
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an FP_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back table frag...
FP_LIB_TABLE * selectLibTable(bool aOptional=false)
Prompts a user to select global or project library tables.
LIB_ID GetLoadedFPID() const
Return the LIB_ID of the part being edited.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
FOOTPRINT * try_load_footprint(const wxFileName &aFileName, IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
Try to load a footprint, returning nullptr if the file couldn't be accessed.
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
void SetLastEditTime(timestamp_t aTime)
Definition: footprint.h:325
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
SAVE_T FootprintSave(const wxString &aNickname, const FOOTPRINT *aFootprint, bool aOverwrite=true)
Write aFootprint to an existing library given by aNickname.
The main frame for Pcbnew.
bool SaveFootprintAs(FOOTPRINT *aFootprint)
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Revert the commit by restoring the modified items state.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
static const wxString INFO_LEGACY_LIB_WARN_DELETE(_("Modifying legacy libraries (.mod files) is not allowed\n" "Please save the current library under the new .pretty format\n" "and update your footprint lib table\n" "before deleting a footprint"))
int ShowModal() override
Definition: confirm.cpp:99
FOOTPRINT_EDITOR_SETTINGS * GetSettings()
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction) const
Invoke a function on all BOARD_ITEMs that belong to the footprint (pads, drawings,...
Definition: footprint.cpp:1189
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:166
wxString SelectLibrary(const wxString &aNicknameExisting)
Put up a dialog and allows the user to pick a library, for unspecified use.
void AddFootprintToBoard(FOOTPRINT *aFootprint) override
Override from PCB_BASE_EDIT_FRAME which adds a footprint to the editor's dummy board,...
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1452
void FootprintDelete(const wxString &aNickname, const wxString &aFootprintName)
Delete the aFootprintName from the library given by aNickname.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1183
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:53
bool IsContentModified() const override
Get if any footprints or libraries have been modified but not saved.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:280
bool SaveFootprint(FOOTPRINT *aFootprint)
Save in an existing library a given footprint.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:171
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:296
const std::string KiCadFootprintLibPathExtension
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
wxString KiCadFootprintLibFileWildcard()
Custom text control validator definitions.
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
Test for validity of the name in a library of the footprint ( no spaces, dir separators ....
Definition: footprint.cpp:1334
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Definition: env_paths.cpp:69
bool FootprintExists(const wxString &aNickname, const wxString &aFootprintName)
Indicates whether or not the given footprint already exists in the given library.
static wxString GetGlobalTableFileName()
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
wxString GedaPcbFootprintLibFileWildcard()
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
FOOTPRINT * ImportFootprint(const wxString &aName=wxT(""))
Read a file containing only one footprint.
S-expression Pcbnew file format.
Definition: io_mgr.h:56
Container for design settings for a BOARD object.
wxString createNewLibrary(const wxString &aLibName, const wxString &aProposedName, FP_LIB_TABLE *aTable)
Create a new library in the given table (presumed to be either the global or project library table).
void SetListLabel(const wxString &aLabel)