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