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 <fctsys.h>
26 #include <pgm_base.h>
27 #include <kiface_i.h>
28 #include <confirm.h>
29 #include <kicad_string.h>
30 #include <pcb_edit_frame.h>
31 #include <dialog_helpers.h>
32 #include <filter_reader.h>
33 #include <macros.h>
34 #include <fp_lib_table.h>
35 #include <validators.h>
36 #include <dialog_text_entry.h>
37 #include <tool/tool_manager.h>
38 #include <tools/pcb_actions.h>
39 #include <class_board.h>
40 #include <class_module.h>
41 #include <board_commit.h>
42 #include <footprint_edit_frame.h>
44 #include <kicad_plugin.h>
45 #include <legacy_plugin.h>
46 #include <env_paths.h>
47 #include "footprint_viewer_frame.h"
48 
49 
50 // unique, "file local" translations:
51 
52 #define FMT_OK_DELETE _( "OK to delete footprint \"%s\" in library \"%s\"" )
53 #define FMT_IMPORT_MODULE _( "Import Footprint" )
54 #define FMT_FILE_NOT_FOUND _( "File \"%s\" not found" )
55 #define FMT_NOT_MODULE _( "Not a footprint file" )
56 #define FMT_MOD_NOT_FOUND _( "Unable to find or load footprint \"%s\" from lib path \"%s\"" )
57 #define FMT_LIB_READ_ONLY _( "Library \"%s\" is read only, not writable" )
58 
59 #define FMT_EXPORT_MODULE _( "Export Footprint" )
60 #define FMT_SAVE_MODULE _( "Save Footprint" )
61 #define FMT_MOD_REF _( "Enter footprint name:" )
62 #define FMT_EXPORTED _( "Footprint exported to file \"%s\"" )
63 #define FMT_MOD_DELETED _( "Footprint \"%s\" deleted from library \"%s\"" )
64 #define FMT_MOD_CREATE _( "New Footprint" )
65 
66 #define FMT_NO_REF_ABORTED _( "No footprint name defined." )
67 #define FMT_SELECT_LIB _( "Select Library" )
68 
69 static const wxString INFO_LEGACY_LIB_WARN_EDIT(
70  _( "Writing/modifying legacy libraries (.mod files) is not allowed\n"\
71  "Please save the current library to the new .pretty format\n"\
72  "and update your footprint lib table\n"\
73  "to save your footprint (a .kicad_mod file) in the .pretty library folder" ) );
74 
75 static const wxString INFO_LEGACY_LIB_WARN_DELETE(
76  _( "Modifying legacy libraries (.mod files) is not allowed\n"\
77  "Please save the current library under the new .pretty format\n"\
78  "and update your footprint lib table\n"\
79  "before deleting a footprint" ) );
80 
81 
82 #define EXPORT_IMPORT_LASTPATH_KEY wxT( "import_last_path" )
83 
84 
90 static wxFileName getFootprintFilenameFromUser( wxWindow* aParent, const wxString& aLastPath )
91 {
92  static int lastFilterIndex = 0; // To store the last choice during a session.
93  wxString wildCard;
94 
95  wildCard << KiCadFootprintLibFileWildcard() << wxChar( '|' )
96  << ModLegacyExportFileWildcard() << wxChar( '|' )
97  << GedaPcbFootprintLibFileWildcard() << wxChar( '|' )
98  << AllFilesWildcard();
99 
100  wxFileDialog dlg( aParent, FMT_IMPORT_MODULE, aLastPath, wxEmptyString, wildCard,
101  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
102 
103  dlg.SetFilterIndex( lastFilterIndex );
104 
105  if( dlg.ShowModal() == wxID_CANCEL )
106  return wxFileName();
107 
108  lastFilterIndex = dlg.GetFilterIndex();
109 
110  return wxFileName( dlg.GetPath() );
111 }
112 
113 
120 static IO_MGR::PCB_FILE_T detect_file_type( FILE* aFile, const wxFileName& aFileName,
121  wxString* aName )
122 {
123  FILE_LINE_READER freader( aFile, aFileName.GetFullPath() );
124  WHITESPACE_FILTER_READER reader( freader );
125  IO_MGR::PCB_FILE_T file_type;
126 
127  wxASSERT( aName );
128 
129  reader.ReadLine();
130  char* line = reader.Line();
131 
132  if( !strncasecmp( line, "(module", strlen( "(module" ) ) )
133  {
134  file_type = IO_MGR::KICAD_SEXP;
135  *aName = aFileName.GetName();
136  }
137  else if( !strncasecmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) )
138  {
139  file_type = IO_MGR::LEGACY;
140 
141  while( reader.ReadLine() )
142  {
143  if( !strncasecmp( line, "$MODULE", strlen( "$MODULE" ) ) )
144  {
145  *aName = FROM_UTF8( StrPurge( line + strlen( "$MODULE" ) ) );
146  break;
147  }
148  }
149  }
150  else if( !strncasecmp( line, "Element", strlen( "Element" ) ) )
151  {
152  file_type = IO_MGR::GEDA_PCB;
153  *aName = aFileName.GetName();
154  }
155  else
156  {
157  file_type = IO_MGR::FILE_TYPE_NONE;
158  }
159 
160  return file_type;
161 }
162 
163 
171  const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
172  const wxString& aName )
173 {
174  wxString path;
175 
176  switch( aFileType )
177  {
178  case IO_MGR::GEDA_PCB:
179  path = aFileName.GetPath();
180  break;
181  case IO_MGR::LEGACY:
182  path = aFileName.GetFullPath();
183  break;
184  default:
185  wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) );
186  }
187 
188  PLUGIN::RELEASER pi( IO_MGR::PluginFind( aFileType ) );
189 
190  return pi->FootprintLoad( path, aName );
191 }
192 
193 
198 static MODULE* parse_module_kicad( const wxFileName& aFileName )
199 {
200  wxString fcontents;
201  PCB_IO pcb_io;
202  wxFFile f( aFileName.GetFullPath() );
203 
204  if( !f.IsOpened() )
205  return NULL;
206 
207  f.ReadAll( &fcontents );
208 
209  return dynamic_cast<MODULE*>( pcb_io.Parse( fcontents ) );
210 }
211 
212 
219 MODULE* try_load_footprint( const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
220  const wxString& aName )
221 {
222  MODULE* module;
223 
224  switch( aFileType )
225  {
226  case IO_MGR::GEDA_PCB:
227  case IO_MGR::LEGACY:
228  module = parse_module_with_plugin( aFileName, aFileType, aName );
229  break;
230 
231  case IO_MGR::KICAD_SEXP:
232  module = parse_module_kicad( aFileName );
233  break;
234 
235  default:
236  wxFAIL_MSG( wxT( "unexpected IO_MGR::PCB_FILE_T" ) );
237  module = NULL;
238  }
239 
240  return module;
241 }
242 
243 
245 {
246  wxString lastOpenedPathForLoading = m_mruPath;
247  wxConfigBase* cfg = Kiface().KifaceSettings();
248 
249  if( cfg )
250  cfg->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
251 
252  wxFileName fn;
253 
254  if( aName != wxT("") )
255  fn = aName;
256  else
257  fn = getFootprintFilenameFromUser( this, lastOpenedPathForLoading );
258 
259  if( !fn.IsOk() )
260  return NULL;
261 
262  FILE* fp = wxFopen( fn.GetFullPath(), wxT( "rt" ) );
263 
264  if( !fp )
265  {
266  wxString msg = wxString::Format( FMT_FILE_NOT_FOUND, GetChars( fn.GetFullPath() ) );
267  DisplayError( this, msg );
268  return NULL;
269  }
270 
271  if( cfg ) // Save file path
272  {
273  lastOpenedPathForLoading = fn.GetPath();
274  cfg->Write( EXPORT_IMPORT_LASTPATH_KEY, lastOpenedPathForLoading );
275  }
276 
277  wxString moduleName;
278  IO_MGR::PCB_FILE_T fileType = detect_file_type( fp, fn.GetFullPath(), &moduleName );
279 
281  {
282  DisplayError( this, FMT_NOT_MODULE );
283  return NULL;
284  }
285 
286  MODULE* module = NULL;
287 
288  try
289  {
290  module = try_load_footprint( fn, fileType, moduleName );
291 
292  if( !module )
293  {
294  wxString msg = wxString::Format(
295  FMT_MOD_NOT_FOUND, GetChars( moduleName ), GetChars( fn.GetFullPath() ) );
296  DisplayError( this, msg );
297  return NULL;
298  }
299  }
300  catch( const IO_ERROR& ioe )
301  {
302  DisplayError( this, ioe.What() );
303 
304  // if the footprint is not loaded, exit.
305  // However, even if an error happens, it can be loaded, because in KICAD and GPCB format,
306  // a fp library is a set of separate files, and the error(s) are not necessary when
307  // reading the selected file
308 
309  if( !module )
310  return NULL;
311  }
312 
313  module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
314 
315  // Insert footprint in list
316  AddModuleToBoard( module );
317 
318  // Display info :
319  SetMsgPanel( module );
320  PlaceModule( module );
321 
322  module->SetPosition( wxPoint( 0, 0 ) );
323 
325  updateView();
326 
327  return module;
328 }
329 
330 
332 {
333  wxFileName fn;
334  wxConfigBase* cfg = Kiface().KifaceSettings();
335 
336  if( !aModule )
337  return;
338 
339  fn.SetName( aModule->GetFPID().GetLibItemName() );
340 
341  wxString wildcard = KiCadFootprintLibFileWildcard();
342 
343  fn.SetExt( KiCadFootprintFileExtension );
344 
345  if( cfg )
346  {
347  wxString path;
348  cfg->Read( EXPORT_IMPORT_LASTPATH_KEY, &path, m_mruPath );
349  fn.SetPath( path );
350  }
351 
352  wxFileDialog dlg( this, FMT_EXPORT_MODULE, fn.GetPath(), fn.GetFullName(),
353  wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
354 
355  if( dlg.ShowModal() == wxID_CANCEL )
356  return;
357 
358  fn = dlg.GetPath();
359 
360  if( cfg ) // Save file path
361  {
362  cfg->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
363  }
364 
365  try
366  {
367  // Export as *.kicad_pcb format, using a strategy which is specifically chosen
368  // as an example on how it could also be used to send it to the system clipboard.
369 
370  PCB_IO pcb_io( CTL_FOR_LIBRARY );
371 
372  /* This module should *already* be "normalized" in a way such that
373  orientation is zero, etc., since it came from module editor.
374 
375  module->SetTimeStamp( 0 );
376  module->SetParent( 0 );
377  module->SetOrientation( 0 );
378  */
379 
380  pcb_io.Format( aModule );
381 
382  FILE* fp = wxFopen( dlg.GetPath(), wxT( "wt" ) );
383 
384  if( fp == NULL )
385  {
386  wxMessageBox( wxString::Format(
387  _( "Unable to create or write file \"%s\"" ),
388  GetChars( dlg.GetPath() ) ) );
389  return;
390  }
391 
392  fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() );
393  fclose( fp );
394  }
395  catch( const IO_ERROR& ioe )
396  {
397  DisplayError( this, ioe.What() );
398  return;
399  }
400 
401  wxString msg = wxString::Format( FMT_EXPORTED, GetChars( dlg.GetPath() ) );
402  DisplayInfoMessage( this, msg );
403 }
404 
405 
406 wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
407 {
408  // Kicad cannot write legacy format libraries, only .pretty new format
409  // because the legacy format cannot handle current features.
410  // The footprint library is actually a directory
411 
412  wxString initialPath = wxPathOnly( Prj().GetProjectFullName() );
413  wxFileName fn;
414  bool doAdd = false;
415 
416  if( aLibName.IsEmpty() )
417  {
418  fn = initialPath;
419 
420  if( !LibraryFileBrowser( false, fn,
422  {
423  return wxEmptyString;
424  }
425 
426  doAdd = true;
427  }
428  else
429  {
430  fn = aLibName;
431 
432  if( !fn.IsAbsolute() )
433  {
434  fn.SetName( aLibName );
435  fn.MakeAbsolute( initialPath );
436  }
437 
438  // Enforce the .pretty extension:
439  fn.SetExt( KiCadFootprintLibPathExtension );
440  }
441 
442  // We can save fp libs only using IO_MGR::KICAD_SEXP format (.pretty libraries)
444  wxString libPath = fn.GetFullPath();
445 
446  try
447  {
448  PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
449 
450  bool writable = false;
451  bool exists = false;
452 
453  try
454  {
455  writable = pi->IsFootprintLibWritable( libPath );
456  exists = true; // no exception was thrown, lib must exist.
457  }
458  catch( const IO_ERROR& )
459  { }
460 
461  if( exists )
462  {
463  if( !writable )
464  {
465  wxString msg = wxString::Format( FMT_LIB_READ_ONLY, libPath );
466  DisplayError( this, msg );
467  return wxEmptyString;
468  }
469  else
470  {
471  wxString msg = wxString::Format( _( "Library %s already exists." ), libPath );
472  KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
473  dlg.SetOKLabel( _( "Overwrite" ) );
474  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
475 
476  if( dlg.ShowModal() == wxID_CANCEL )
477  return wxEmptyString;
478 
479  pi->FootprintLibDelete( libPath );
480  }
481  }
482 
483  pi->FootprintLibCreate( libPath );
484  }
485  catch( const IO_ERROR& ioe )
486  {
487  DisplayError( this, ioe.What() );
488  return wxEmptyString;
489  }
490 
491  if( doAdd )
492  AddLibrary( libPath );
493 
494  return libPath;
495 }
496 
497 
498 bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aFilename )
499 {
500  wxFileName fn( aFilename );
501 
502  if( aFilename.IsEmpty() )
503  {
504  if( !LibraryFileBrowser( true, fn,
506  true ) )
507  {
508  return false;
509  }
510  }
511 
512  wxString libPath = fn.GetFullPath();
513  wxString libName = fn.GetName();
514 
515  if( libName.IsEmpty() )
516  return false;
517 
518  bool saveInGlobalTable = false;
519  bool saveInProjectTable = false;
520  wxArrayString libTableNames;
521 
522  libTableNames.Add( _( "Global" ) );
523  libTableNames.Add( _( "Project" ) );
524 
525  switch( SelectSingleOption( this, _( "Select Library Table" ),
526  _( "Choose the Library Table to add the library to:" ),
527  libTableNames ) )
528  {
529  case 0: saveInGlobalTable = true; break;
530  case 1: saveInProjectTable = true; break;
531  default: return false;
532  }
533 
534  wxString type = IO_MGR::ShowType( IO_MGR::GuessPluginTypeFromLibPath( libPath ) );
535 
536  // try to use path normalized to an environmental variable or project path
537  wxString normalizedPath = NormalizePath( libPath, &Pgm().GetLocalEnvVariables(), &Prj() );
538 
539  if( normalizedPath.IsEmpty() )
540  normalizedPath = libPath;
541 
542  try
543  {
544  if( saveInGlobalTable )
545  {
546  auto row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString );
547  GFootprintTable.InsertRow( row );
549  }
550  else if( saveInProjectTable )
551  {
552  auto row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString );
553  Prj().PcbFootprintLibs()->InsertRow( row );
554  Prj().PcbFootprintLibs()->Save( Prj().FootprintLibTblName() );
555  }
556  }
557  catch( const IO_ERROR& ioe )
558  {
559  DisplayError( this, ioe.What() );
560  return false;
561  }
562 
563  auto editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false );
564 
565  if( editor )
566  {
567  LIB_ID libID( libName, wxEmptyString );
568  editor->SyncLibraryTree( true );
569  editor->FocusOnLibID( libID );
570  }
571 
572  auto viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
573 
574  if( viewer )
575  viewer->ReCreateLibraryList();
576 
577  return true;
578 }
579 
580 
581 bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( const LIB_ID& aFPID, bool aConfirm )
582 {
583  if( !aFPID.IsValid() )
584  return false;
585 
586  wxString nickname = aFPID.GetLibNickname();
587  wxString fpname = aFPID.GetLibItemName();
588 
589  // Legacy libraries are readable, but modifying legacy format is not allowed
590  // So prompt the user if he try to delete a footprint from a legacy lib
591  wxString libfullname = Prj().PcbFootprintLibs()->FindRow( nickname )->GetFullURI();
592 
593  if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY )
594  {
596  return false;
597  }
598 
599  if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
600  {
601  wxString msg = wxString::Format( _( "Library \"%s\" is read only" ), nickname );
602  DisplayError( this, msg );
603  return false;
604  }
605 
606  // Confirmation
607  wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
608 
609  if( aConfirm && !IsOK( this, msg ) )
610  return false;
611 
612  try
613  {
614  Prj().PcbFootprintLibs()->FootprintDelete( nickname, fpname );
615  }
616  catch( const IO_ERROR& ioe )
617  {
618  DisplayError( this, ioe.What() );
619  return false;
620  }
621 
622  msg.Printf( FMT_MOD_DELETED, fpname.GetData(), nickname.GetData() );
623 
624  SetStatusText( msg );
625 
626  return true;
627 }
628 
629 
630 void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib, const wxString& aLibName,
631  wxString* aLibPath )
632 {
633  if( GetBoard()->GetFirstModule() == NULL )
634  {
635  DisplayInfoMessage( this, _( "No footprints to archive!" ) );
636  return;
637  }
638 
639  wxString footprintName;
640 
641  if( !aStoreInNewLib )
642  {
643  // The footprints are saved in an existing .pretty library in the fp lib table
644  PROJECT& prj = Prj();
645  wxString last_nickname = prj.GetRString( PROJECT::PCB_LIB_NICKNAME );
646  wxString nickname = SelectLibrary( last_nickname );
647 
648  if( !nickname ) // Aborted
649  return;
650 
651  prj.SetRString( PROJECT::PCB_LIB_NICKNAME, nickname );
652 
653  try
654  {
655  FP_LIB_TABLE* tbl = prj.PcbFootprintLibs();
656 
657  for( auto curr_fp : GetBoard()->Modules() )
658  {
659  if( !curr_fp->GetFPID().GetLibItemName().empty() ) // Can happen with old boards.
660  tbl->FootprintSave( nickname, curr_fp, false );
661  }
662  }
663  catch( const IO_ERROR& ioe )
664  {
665  DisplayError( this, ioe.What() );
666  }
667  }
668  else
669  {
670  // The footprints are saved in a new .pretty library.
671  // If this library already exists, all previous footprints will be deleted
672  wxString libPath = CreateNewLibrary( aLibName );
673 
674  if( libPath.IsEmpty() ) // Aborted
675  return;
676 
677 
678  if( aLibPath ) *aLibPath = libPath;
679 
681  PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
682 
683  for( auto curr_fp : GetBoard()->Modules() )
684  {
685  try
686  {
687  if( !curr_fp->GetFPID().GetLibItemName().empty() ) // Can happen with old boards.
688  pi->FootprintSave( libPath, curr_fp );
689  }
690  catch( const IO_ERROR& ioe )
691  {
692  DisplayError( this, ioe.What() );
693  }
694  }
695  }
696 }
697 
698 
700 {
701  if( !aModule ) // Happen if no footprint loaded
702  return false;
703 
704  wxString libraryName = aModule->GetFPID().GetLibNickname();
705  wxString footprintName = aModule->GetFPID().GetLibItemName();
706  bool nameChanged = m_footprintNameWhenLoaded != footprintName;
707 
708  if( aModule->GetLink() )
709  {
710  if( SaveFootprintToBoard( false ) )
711  {
712  m_footprintNameWhenLoaded = footprintName;
713  return true;
714  }
715  else
716  return false;
717  }
718  else if( libraryName.IsEmpty() || footprintName.IsEmpty() )
719  {
720  if( SaveFootprintAs( aModule ) )
721  {
722  m_footprintNameWhenLoaded = footprintName;
723  SyncLibraryTree( true );
724  return true;
725  }
726  else
727  return false;
728  }
729 
730  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
731 
732  // Legacy libraries are readable, but modifying legacy format is not allowed
733  // So prompt the user if he try to add/replace a footprint in a legacy lib
734  wxString libfullname = tbl->FindRow( libraryName )->GetFullURI();
735 
736  if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY )
737  {
739  return false;
740  }
741 
742  if( nameChanged )
743  {
744  LIB_ID oldFPID( libraryName, m_footprintNameWhenLoaded );
745  DeleteModuleFromLibrary( oldFPID, false );
746  }
747 
748  if( !SaveFootprintInLibrary( aModule, libraryName ) )
749  return false;
750 
751  if( nameChanged )
752  {
753  m_footprintNameWhenLoaded = footprintName;
754  SyncLibraryTree( true );
755  }
756 
757  return true;
758 }
759 
760 
761 bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( MODULE* aModule, const wxString& aLibraryName )
762 {
763  try
764  {
765  aModule->SetFPID( LIB_ID( wxEmptyString, aModule->GetFPID().GetLibItemName() ) );
766 
767  Prj().PcbFootprintLibs()->FootprintSave( aLibraryName, aModule );
768 
769  aModule->SetFPID( LIB_ID( aLibraryName, aModule->GetFPID().GetLibItemName() ) );
770  return true;
771  }
772  catch( const IO_ERROR& ioe )
773  {
774  DisplayError( this, ioe.What() );
775 
776  aModule->SetFPID( LIB_ID( aLibraryName, aModule->GetFPID().GetLibItemName() ) );
777  return false;
778  }
779 }
780 
781 
783 {
784  // update module in the current board,
785  // not just add it to the board with total disregard for the netlist...
786  PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB_EDITOR, false );
787 
788  if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
789  {
790  DisplayErrorMessage( this, _("No board currently open." ) );
791  return false;
792  }
793 
794  BOARD* mainpcb = pcbframe->GetBoard();
795  MODULE* source_module = NULL;
796  MODULE* module_in_edit = GetBoard()->GetFirstModule();
797 
798  // Search the old module (source) if exists
799  // Because this source could be deleted when editing the main board...
800  if( module_in_edit->GetLink() ) // this is not a new module ...
801  {
802  source_module = nullptr;
803 
804  for( auto mod : mainpcb->Modules() )
805  {
806  if( module_in_edit->GetLink() == mod->GetTimeStamp() )
807  {
808  source_module = mod;
809  break;
810  }
811  }
812  }
813 
814  if( !aAddNew && source_module == NULL ) // source not found
815  {
816  DisplayError( this, _( "Unable to find the footprint on the main board.\nCannot save." ) );
817  return false;
818  }
819 
820  if( aAddNew && source_module != NULL )
821  {
822  DisplayError( this, _( "Footprint already exists on board." ) );
823  return false;
824  }
825 
828  BOARD_COMMIT commit( pcbframe );
829 
830  // Create the "new" module
831  MODULE* newmodule = new MODULE( *module_in_edit );
832  newmodule->SetParent( mainpcb );
833  newmodule->SetLink( 0 );
834 
835  if( source_module ) // this is an update command
836  {
837  // In the main board,
838  // the new module replace the old module (pos, orient, ref, value
839  // and connexions are kept)
840  // and the source_module (old module) is deleted
841  pcbframe->Exchange_Module( source_module, newmodule, commit );
842  newmodule->SetTimeStamp( module_in_edit->GetLink() );
843  commit.Push( wxT( "Update module" ) );
844  }
845  else // This is an insert command
846  {
847  KIGFX::VIEW_CONTROLS* viewControls = pcbframe->GetCanvas()->GetViewControls();
848  VECTOR2D cursorPos = viewControls->GetCursorPosition();
849 
850  commit.Add( newmodule );
851  viewControls->SetCrossHairCursorPosition( VECTOR2D( 0, 0 ), false );
852  pcbframe->PlaceModule( newmodule );
853  newmodule->SetPosition( wxPoint( 0, 0 ) );
854  viewControls->SetCrossHairCursorPosition( cursorPos, false );
855  newmodule->SetTimeStamp( GetNewTimeStamp() );
856  commit.Push( wxT( "Insert module" ) );
857 
858  pcbframe->Raise();
859  pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::placeModule, true, newmodule );
860  }
861 
862  newmodule->ClearFlags();
863 
864  return true;
865 }
866 
867 
869 {
870  if( aModule == NULL )
871  return false;
872 
873  FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
874 
875  SetMsgPanel( aModule );
876 
877  wxString libraryName = aModule->GetFPID().GetLibNickname();
878  wxString footprintName = aModule->GetFPID().GetLibItemName();
879  bool updateValue = ( aModule->GetValue() == footprintName );
880 
881  wxArrayString headers;
882  std::vector<wxArrayString> itemsToDisplay;
883  std::vector<wxString> nicknames = tbl->GetLogicalLibs();
884 
885  headers.Add( _( "Nickname" ) );
886  headers.Add( _( "Description" ) );
887 
888  for( const wxString& nickname : nicknames )
889  {
890  wxArrayString item;
891  item.Add( nickname );
892  item.Add( tbl->GetDescription( nickname ) );
893  itemsToDisplay.push_back( item );
894  }
895 
896  EDA_LIST_DIALOG dlg( this, FMT_SAVE_MODULE, headers, itemsToDisplay, libraryName );
897  dlg.SetListLabel( _( "Save in library:" ) );
898  dlg.SetOKLabel( _( "Save" ) );
899 
900  wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
901 
902  wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ),
903  wxDefaultPosition, wxDefaultSize, 0 );
904  bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
905 
906  wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, footprintName,
907  wxDefaultPosition, wxDefaultSize, 0 );
908  bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
909 
910  wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
911  nameValidator.SetCharExcludes( MODULE::StringLibNameInvalidChars( false ) );
912  nameTextCtrl->SetValidator( nameValidator );
913 
914  wxSizer* mainSizer = dlg.GetSizer();
915  mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
916 
917  // Move nameTextCtrl to the head of the tab-order
918  if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
919  dlg.GetChildren().Insert( nameTextCtrl );
920 
921  dlg.SetInitialFocus( nameTextCtrl );
922 
923  dlg.Layout();
924  mainSizer->Fit( &dlg );
925 
926  if( dlg.ShowModal() != wxID_OK )
927  return false; // canceled by user
928 
929  libraryName = dlg.GetTextSelection();
930 
931  if( libraryName.IsEmpty() )
932  {
933  DisplayError( NULL, _( "No library specified. Footprint could not be saved." ) );
934  return false;
935  }
936 
937  footprintName = nameTextCtrl->GetValue();
938  footprintName.Trim( true );
939  footprintName.Trim( false );
940 
941  if( footprintName.IsEmpty() )
942  {
943  DisplayError( NULL, _( "No footprint name specified. Footprint could not be saved." ) );
944  return false;
945  }
946 
947  aModule->SetFPID( LIB_ID( libraryName, footprintName ) );
948 
949  if( updateValue )
950  aModule->SetValue( footprintName );
951 
952  // Legacy libraries are readable, but modifying legacy format is not allowed
953  // So prompt the user if he try to add/replace a footprint in a legacy lib
954  wxString libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
956 
957  if( piType == IO_MGR::LEGACY )
958  {
960  return false;
961  }
962 
963  bool module_exists = tbl->FootprintExists( libraryName, footprintName );
964 
965  if( module_exists )
966  {
967  wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ),
968  footprintName,
969  libraryName );
970  KIDIALOG chkdlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
971  chkdlg.SetOKLabel( _( "Overwrite" ) );
972 
973  if( chkdlg.ShowModal() == wxID_CANCEL )
974  return false;
975  }
976 
977  if( !SaveFootprintInLibrary( aModule, libraryName ) )
978  return false;
979 
980  // Once saved-as a board footprint is no longer a board footprint
981  aModule->SetLink( 0 );
982 
983  wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) :
984  _( "Component \"%s\" added in \"%s\"" );
985 
986  wxString msg = wxString::Format( fmt, footprintName.GetData(), libraryName.GetData() );
987  SetStatusText( msg );
988  updateTitle();
990 
991  return true;
992 }
993 
994 
996 {
997  if( GetScreen()->IsModify() && m_revertModule )
998  {
999  wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ),
1000  GetChars( GetLoadedFPID().GetLibItemName() ) );
1001 
1002  if( ConfirmRevertDialog( this, msg ) )
1003  {
1004  Clear_Pcb( false );
1005  AddModuleToBoard( (MODULE*) m_revertModule->Clone() );
1006 
1007  Zoom_Automatique( false );
1008 
1009  Update3DView( true );
1010 
1012  GetScreen()->ClrModify();
1013 
1014  updateView();
1015  GetCanvas()->Refresh();
1016 
1017  return true;
1018  }
1019  }
1020 
1021  return false;
1022 }
1023 
1024 
1025 MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName )
1026 {
1027  // Creates a new footprint at position 0,0 which contains the minimal items:
1028  // the reference and the value.
1029  // Value : initialized to the footprint name.
1030  // put on fab layer (front side)
1031  // Reference : initialized to a default value (REF**).
1032  // put on silkscreen layer (front side)
1033 
1034  wxString moduleName = aModuleName;
1035 
1036  // Ask for the new module name
1037  if( moduleName.IsEmpty() )
1038  {
1039  WX_TEXT_ENTRY_DIALOG dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName );
1040  dlg.SetTextValidator( MODULE_NAME_CHAR_VALIDATOR( &moduleName ) );
1041 
1042  if( dlg.ShowModal() != wxID_OK )
1043  return NULL; //Aborted by user
1044  }
1045 
1046  moduleName.Trim( true );
1047  moduleName.Trim( false );
1048 
1049  if( moduleName.IsEmpty() )
1050  {
1052  return NULL;
1053  }
1054 
1055  // Creates the new module and add it to the head of the linked list of modules
1056  MODULE* module = new MODULE( GetBoard() );
1057 
1058  // Update parameters: timestamp ...
1059  module->SetLastEditTime();
1060 
1061  // Update its name in lib
1062  module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
1063 
1064  wxPoint default_pos;
1066 
1067  // Update reference:
1068  if( settings.m_RefDefaultText.IsEmpty() )
1069  module->SetReference( moduleName );
1070  else
1071  module->SetReference( settings.m_RefDefaultText );
1072 
1073  PCB_LAYER_ID layer = ToLAYER_ID( settings.m_RefDefaultlayer );
1074  module->Reference().SetThickness( settings.GetTextThickness( layer ) );
1075  module->Reference().SetTextSize( settings.GetTextSize( layer ) );
1076  module->Reference().SetItalic( settings.GetTextItalic( layer ) );
1077  module->Reference().SetKeepUpright( settings.GetTextUpright( layer ) );
1078  default_pos.y = GetDesignSettings().GetTextSize( layer ).y / 2;
1079  module->Reference().SetPosition( default_pos );
1080  module->Reference().SetLayer( layer );
1081  module->Reference().SetVisible( settings.m_RefDefaultVisibility );
1082 
1083  // Set the value field to a default value
1084  if( settings.m_ValueDefaultText.IsEmpty() )
1085  module->SetValue( moduleName );
1086  else
1087  module->SetValue( settings.m_ValueDefaultText );
1088 
1089  layer = ToLAYER_ID( settings.m_ValueDefaultlayer );
1090  module->Value().SetThickness( settings.GetTextThickness( layer ) );
1091  module->Value().SetTextSize( settings.GetTextSize( layer ) );
1092  module->Value().SetItalic( settings.GetTextItalic( layer ) );
1093  module->Value().SetKeepUpright( settings.GetTextUpright( layer ) );
1094  default_pos.y = -default_pos.y;
1095  module->Value().SetPosition( default_pos );
1096  module->Value().SetLayer( layer );
1097  module->Value().SetVisible( settings.m_ValueDefaultVisibility );
1098 
1099  SetMsgPanel( module );
1100  return module;
1101 }
1102 
1103 
1104 wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
1105 {
1106  wxArrayString headers;
1107 
1108  headers.Add( _( "Nickname" ) );
1109  headers.Add( _( "Description" ) );
1110 
1111  FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
1112 
1113  std::vector< wxArrayString > itemsToDisplay;
1114  std::vector< wxString > nicknames = fptbl->GetLogicalLibs();
1115 
1116  for( unsigned i = 0; i < nicknames.size(); i++ )
1117  {
1118  wxArrayString item;
1119 
1120  item.Add( nicknames[i] );
1121  item.Add( fptbl->GetDescription( nicknames[i] ) );
1122 
1123  itemsToDisplay.push_back( item );
1124  }
1125 
1126  EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting );
1127 
1128  if( dlg.ShowModal() != wxID_OK )
1129  return wxEmptyString;
1130 
1131  wxString nickname = dlg.GetTextSelection();
1132 
1133  wxLogDebug( wxT( "Chose footprint library \"%s\"." ), GetChars( nickname ) );
1134 
1135  return nickname;
1136 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:236
wxString m_RefDefaultText
Default ref text on fp creation.
void BuildListOfNets()
Definition: class_board.h:716
static TOOL_ACTION placeModule
Definition: pcb_actions.h:160
MODULE * try_load_footprint(const wxFileName &aFileName, IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
Try to load a footprint, returning NULL if the file couldn't be accessed.
bool m_ValueDefaultVisibility
Default value text visibility on fp creation.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
void SetKeepUpright(bool aKeepUpright)
TEXTE_MODULE & Reference()
Definition: class_module.h:477
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox
Definition: confirm.cpp:53
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:190
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
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
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:98
BOARD_ITEM * Parse(const wxString &aClipboardSourceInput)
wxString GetTextSelection(int aColumn=0)
Function GetTextSelection return the selected text from aColumn in the wxListCtrl in the dialog.
Definition: displlst.cpp:141
PCB_IO is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Function GetViewControls() Returns a pointer to the VIEW_CONTROLS instance used in the panel.
wxString m_mruPath
PROJECT holds project specific data.
Definition: project.h:58
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
Definition: string.cpp:310
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:249
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:44
FP_LIB_TABLE_ROW.
Definition: fp_lib_table.h:42
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)
Function SetLayer sets the layer this item is on.
bool SaveFootprintToBoard(bool aAddNew)
This file is part of the common library.
const std::string KiCadFootprintFileExtension
static wxFileName getFootprintFilenameFromUser(wxWindow *aParent, const wxString &aLastPath)
Prompt the user for a module file to open.
void SetOKLabel(const wxString &aLabel)
Definition: displlst.cpp:112
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
FP_LIB_TABLE GFootprintTable
!!!!!!!!!!!!!! This code is obsolete because of the merge into pcbnew, don't bother with it.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetItalic(bool isItalic)
Definition: eda_text.h:163
#define EXPORT_IMPORT_LASTPATH_KEY
Component library viewer main window.
void SetTextValidator(wxTextValidatorStyle style)
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
void SetVisible(bool aVisible)
Definition: eda_text.h:169
const wxString GetValue() const
Function GetValue.
Definition: class_module.h:461
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
EDA_LIST_DIALOG.
#define FMT_SELECT_LIB
int m_ValueDefaultlayer
Default value text layer on fp creation.
const LIB_ID & GetFPID() const
Definition: class_module.h:219
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
static const wxChar * StringLibNameInvalidChars(bool aUserReadable)
static function StringLibNameInvalidChars Test for validity of the name in a library of the footprint...
void Exchange_Module(MODULE *aSrc, MODULE *aDest, BOARD_COMMIT &aCommit, bool deleteExtraTexts=true, bool resetTextLayers=true, bool resetTextEffects=true, bool reset3DModels=true)
Function Exchange_Module Replaces OldModule by NewModule, using OldModule settings: position,...
static const wxString ShowType(PCB_FILE_T aFileType)
Function ShowType returns 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
Function GetTextThickness Returns the default text thickness from the layer class for the given layer...
bool IsValid() const
Definition: lib_id.h:171
MODULE * CreateNewModule(const wxString &aModuleName)
Function CreateNewModule Creates a new module or footprint, at position 0,0 The new module contains o...
wxString AllFilesWildcard()
#define FMT_NOT_MODULE
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
bool DeleteModuleFromLibrary(const LIB_ID &aFPID, bool aConfirm)
Delete the given module from its library.
WHITESPACE_FILTER_READER reads lines of text from another LINE_READER, but only returns non-comment l...
Definition: filter_reader.h:71
Geda PCB file formats.
Definition: io_mgr.h:60
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Function GuessPluginTypeFromLibPath returns a plugin type given a footprint library's libPath.
Definition: io_mgr.cpp:124
timestamp_t GetLink() const
Definition: class_module.h:549
This file contains miscellaneous commonly used macros and functions.
bool GetTextUpright(PCB_LAYER_ID aLayer) const
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...
bool GetTextItalic(PCB_LAYER_ID aLayer) const
RELEASER releases a PLUGIN in the context of a potential thrown exception, through its destructor.
Definition: io_mgr.h:577
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 SyncLibraryTree(bool aProgress)
Synchronize the footprint library tree to the current state of the footprint library table.
std::unique_ptr< MODULE > m_revertModule
timestamp_t GetNewTimeStamp()
Definition: common.cpp:215
#define FMT_NO_REF_ABORTED
#define FMT_MOD_DELETED
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:98
FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
#define FMT_MOD_NOT_FOUND
#define NULL
#define FMT_OK_DELETE
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:341
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
MODULES & Modules()
Definition: class_board.h:226
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void SetLink(timestamp_t aLink)
Definition: class_module.h:550
std::string GetStringOutput(bool doClear)
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:216
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:476
const wxString GetDescription(const wxString &aNickname)
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void SetLastEditTime(timestamp_t aTime)
Definition: class_module.h:347
virtual void ClearUndoRedoList()
Function ClearUndoRedoList clear undo and redo list, using ClearUndoORRedoList() picked items are del...
bool AddLibrary(const wxString &aLibName=wxEmptyString)
Function AddLibrary Add an existing library to either the global or project library table.
#define FMT_SAVE_MODULE
This class provides a custom wxValidator object for limiting the allowable characters when defining f...
Definition: validators.h:63
wxString ModLegacyExportFileWildcard()
MODULE * GetFirstModule() const
Gets the first module in the list (used in footprint viewer/editor) or NULL if none.
Definition: class_board.h:275
Definition of file extensions used in Kicad.
Helper dialog and control classes.
bool LibraryFileBrowser(bool doOpen, wxFileName &aFilename, const wxString &wildcard, const wxString &ext, bool isDirectory=false)
VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (such a...
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:446
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 SetPosition(const wxPoint &aPos) override
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Moves the graphic crosshair cursor to the requested position expressed in world coordinates.
#define FMT_FILE_NOT_FOUND
void SetPosition(const wxPoint &aPos) override
wxString m_ValueDefaultText
Default value text on fp creation.
#define FMT_EXPORT_MODULE
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:269
static MODULE * parse_module_kicad(const wxFileName &aFileName)
Parse a KICAD footprint.
static MODULE * parse_module_with_plugin(const wxFileName &aFileName, IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
Parse a footprint using a PLUGIN.
#define FOOTPRINT_LIBRARY_HEADER_CNT
Definition: legacy_plugin.h:39
#define FMT_LIB_READ_ONLY
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...
void Export_Module(MODULE *aModule)
Create a file containing only one footprint.
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
VTBL_ENTRY FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:400
bool SaveFootprintInLibrary(MODULE *aModule, const wxString &aLibraryName)
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName)
Function FindRow.
bool SaveFootprintAs(MODULE *aModule)
void updateTitle()
Updates window title according to getLibNickName().
wxString CreateNewLibrary(const wxString &aLibName=wxEmptyString)
Function CreateNewLibrary If a library name is given, creates a new footprint library in the project ...
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
wxString KiCadFootprintLibPathWildcard()
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:56
see class PGM_BASE
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
void ArchiveModulesOnBoard(bool aStoreInNewLib, const wxString &aLibName=wxEmptyString, wxString *aLibPath=NULL)
Function ArchiveModulesOnBoard Save modules in a library:
LIB_ID GetLoadedFPID() const
Return the LIB_ID of the part being edited.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:160
#define FMT_IMPORT_MODULE
#define _(s)
Definition: 3d_actions.cpp:31
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Function PluginFind returns a PLUGIN which the caller can use to import, export, save,...
Definition: io_mgr.cpp:58
void updateView()
Reloads displayed items and sets view.
bool SaveFootprint(MODULE *aModule)
Save in an existing library a given footprint.
PCB_EDIT_FRAME is the main frame for Pcbnew.
void ClrModify()
Definition: base_screen.h:225
void SetValue(const wxString &aValue)
Function SetValue.
Definition: class_module.h:470
#define FMT_EXPORTED
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
int m_RefDefaultlayer
Default ref text layer on fp creation.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
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:95
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:256
wxString SelectLibrary(const wxString &aNicknameExisting)
Function SelectLibrary puts up a dialog and allows the user to pick a library, for unspecified use.
TOOL_MANAGER * m_toolManager
void AddModuleToBoard(MODULE *module) override
Override from PCB_BASE_EDIT_FRAME which adds a module to the editor's dummy board,...
Module description (excepted pads)
BOARD * GetBoard() const
void PlaceModule(MODULE *aModule, bool aRecreateRatsnest=true)
Function PlaceModule places aModule at the current cursor position and updates module coordinates wit...
void Format(BOARD_ITEM *aItem, int aNestLevel=0) const
Function Format outputs aItem to aFormatter in s-expression format.
virtual void Update3DView(bool aForceReload, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
SAVE_T FootprintSave(const wxString &aNickname, const MODULE *aFootprint, bool aOverwrite=true)
Function FootprintSave.
#define FMT_MOD_CREATE
void FootprintDelete(const wxString &aNickname, const wxString &aFootprintName)
Function FootprintDelete.
int SelectSingleOption(wxWindow *aParent, const wxString &aTitle, const wxString &aMessage, const wxArrayString &aOptions)
Displays a dialog with radioboxes asking the user to select an option.
Definition: confirm.cpp:290
MODULE * Import_Module(const wxString &aName=wxT(""))
Read a file containing only one footprint.
PCB_FILE_T
Enum PCB_FILE_T is a set of file types that the IO_MGR knows about, and for which there has been a pl...
Definition: io_mgr.h:54
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:264
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:280
const std::string KiCadFootprintLibPathExtension
bool m_RefDefaultVisibility
Default ref text visibility on fp creation.
void SetFPID(const LIB_ID &aFPID)
Definition: class_module.h:220
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:823
wxString KiCadFootprintLibFileWildcard()
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.
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalizes a file path to an environmental variable, if possible.
Definition: env_paths.cpp:67
bool FootprintExists(const wxString &aNickname, const wxString &aFootprintName)
Function FootprintExists.
static wxString GetGlobalTableFileName()
Function GetGlobalTableFileName.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
void SetThickness(int aNewThickness)
Set the pen width.
Definition: eda_text.h:143
wxString GedaPcbFootprintLibFileWildcard()
#define FMT_MOD_REF
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
void SetTimeStamp(timestamp_t aNewTimeStamp)
Definition: base_struct.h:212
S-expression Pcbnew file format.
Definition: io_mgr.h:57
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
void SetListLabel(const wxString &aLabel)
Definition: displlst.cpp:105