KiCad PCB EDA Suite
pcbnew/files.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) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <fctsys.h>
27 #include <confirm.h>
28 #include <kicad_string.h>
29 #include <gestfich.h>
30 #include <pcb_edit_frame.h>
32 #include <pgm_base.h>
33 #include <msgpanel.h>
34 #include <fp_lib_table.h>
35 #include <kiface_i.h>
36 #include <trace_helpers.h>
37 #include <lockfile.cpp>
39 #include <pcbnew_id.h>
40 #include <io_mgr.h>
42 #include <tool/tool_manager.h>
43 #include <class_board.h>
44 #include <wx/stdpaths.h>
45 #include <ratsnest/ratsnest_data.h>
46 #include <kiplatform/app.h>
48 #include <wx/wupdlock.h>
51 #include <project/project_file.h>
53 
54 
55 //#define USE_INSTRUMENTATION 1
56 #define USE_INSTRUMENTATION 0
57 
58 
71 bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bool aKicadFilesOnly )
72 {
73  // This is a subset of all PLUGINs which are trusted to be able to
74  // load a BOARD. User may occasionally use the wrong plugin to load a
75  // *.brd file (since both legacy and eagle use *.brd extension),
76  // but eventually *.kicad_pcb will be more common than legacy *.brd files.
77 
78  // clang-format off
79  static const struct
80  {
81  const wxString& filter;
82  IO_MGR::PCB_FILE_T pluginType;
83  } loaders[] =
84  {
85  { PcbFileWildcard(), IO_MGR::KICAD_SEXP }, // Current Kicad board files
86  { LegacyPcbFileWildcard(), IO_MGR::LEGACY }, // Old Kicad board files
87  { EaglePcbFileWildcard(), IO_MGR::EAGLE }, // Import Eagle board files
88  { PCadPcbFileWildcard(), IO_MGR::PCAD }, // Import PCAD board files
89  { AltiumDesignerPcbFileWildcard(), IO_MGR::ALTIUM_DESIGNER }, // Import Altium Designer board files
90  { AltiumCircuitStudioPcbFileWildcard(), IO_MGR::ALTIUM_CIRCUIT_STUDIO }, // Import Altium Circuit Studio board files
91  { AltiumCircuitMakerPcbFileWildcard(), IO_MGR::ALTIUM_CIRCUIT_MAKER }, // Import Altium Circuit Maker board files
92  { CadstarPcbArchiveFileWildcard(), IO_MGR::CADSTAR_PCB_ARCHIVE }, // Import Cadstar PCB Archive board files
93  };
94  // clang-format on
95 
96  wxFileName fileName( *aFileName );
97  wxString fileFilters;
98 
99  if( aKicadFilesOnly )
100  {
101  for( unsigned ii = 0; ii < 2; ++ii )
102  {
103  if( !fileFilters.IsEmpty() )
104  fileFilters += wxChar( '|' );
105 
106  fileFilters += wxGetTranslation( loaders[ii].filter );
107  }
108  }
109  else
110  {
111  for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
112  {
113  if( !fileFilters.IsEmpty() )
114  fileFilters += wxChar( '|' );
115 
116  fileFilters += wxGetTranslation( loaders[ii].filter );
117  }
118  }
119 
120  wxString path;
121  wxString name;
122 
123  if( fileName.FileExists() )
124  {
125  path = fileName.GetPath();
126  name = fileName.GetFullName();
127  }
128  else
129  {
130  path = wxStandardPaths::Get().GetDocumentsDir();
131  // leave name empty
132  }
133 
134  wxFileDialog dlg( aParent,
135  aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
136  path, name, fileFilters,
137  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
138 
139  if( dlg.ShowModal() == wxID_OK )
140  {
141  // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
142  // It's the only special case because of the duplicate use of the *.brd file extension.
143  // Other cases are clear because of unique file extensions.
144  *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
145  *aFileName = dlg.GetPath();
146  return true;
147  }
148  else
149  return false;
150 }
151 
152 
154 class CREATE_PROJECT_CHECKBOX : public wxPanel
155 {
156 public:
157  CREATE_PROJECT_CHECKBOX( wxWindow* aParent )
158  : wxPanel( aParent )
159  {
160  m_cbCreateProject = new wxCheckBox( this, wxID_ANY,
161  _( "Create a new project for this board" ) );
162  m_cbCreateProject->SetValue( false );
163  m_cbCreateProject->SetToolTip( _( "Creating a project will enable features such as "
164  "design rules, net classes, and layer presets" ) );
165 
166  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
167  sizer->Add( m_cbCreateProject, 0, wxALL, 8 );
168 
169  SetSizerAndFit( sizer );
170  }
171 
172  bool GetValue() const
173  {
174  return m_cbCreateProject->GetValue();
175  }
176 
177  static wxWindow* Create( wxWindow* aParent )
178  {
179  return new CREATE_PROJECT_CHECKBOX( aParent );
180  }
181 
182 protected:
183  wxCheckBox* m_cbCreateProject;
184 };
185 
186 
196 bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
197 {
198  wxString wildcard = PcbFileWildcard();
199  wxFileName fn = *aFileName;
200 
201  fn.SetExt( KiCadPcbFileExtension );
202 
203  wxFileDialog dlg( aParent,
204  _( "Save Board File As" ),
205  fn.GetPath(),
206  fn.GetFullName(),
207  wildcard,
208  wxFD_SAVE | wxFD_OVERWRITE_PROMPT
209  );
210 
211  // Add a "Create a project" checkbox in standalone mode and one isn't loaded
212  if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
213  dlg.SetExtraControlCreator( &CREATE_PROJECT_CHECKBOX::Create );
214 
215  if( dlg.ShowModal() != wxID_OK )
216  return false;
217 
218  fn = dlg.GetPath();
219 
220  // always enforce filename extension, user may not have entered it.
221  fn.SetExt( KiCadPcbFileExtension );
222 
223  *aFileName = fn.GetFullPath();
224  *aCreateProject = static_cast<CREATE_PROJECT_CHECKBOX*>( dlg.GetExtraControl() )->GetValue();
225 
226  return true;
227 }
228 
229 
230 void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
231 {
232  wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
233 
234  if( !!fn )
235  {
236  int open_ctl = 0;
237 
238  if( !wxFileName::IsFileReadable( fn ) )
239  {
240  if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
241  return;
242  }
243 
244  OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
245  }
246 }
247 
248 
249 void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
250 {
252 }
253 
254 
255 void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
256 {
257  int id = event.GetId();
258  Files_io_from_id( id );
259 }
260 
261 
263 {
264  wxString msg;
265 
266  switch( id )
267  {
268  case ID_LOAD_FILE:
269  {
270  int open_ctl = 0;
271  wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
272 
273  return AskLoadBoardFileName( this, &open_ctl, &fileName, true )
274  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
275  }
276 
278  {
279  int open_ctl = 1;
280  wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
281 
282  return AskLoadBoardFileName( this, &open_ctl, &fileName, false )
283  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
284  }
285 
287  {
288  wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
289  wxFileName fn = currfn;
290 
291  wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
292  fn.SetName( rec_name );
293 
294  if( !fn.FileExists() )
295  {
296  msg.Printf( _( "Recovery file \"%s\" not found." ), fn.GetFullPath() );
297  DisplayInfoMessage( this, msg );
298  return false;
299  }
300 
301  msg.Printf( _( "OK to load recovery file \"%s\"" ), fn.GetFullPath() );
302 
303  if( !IsOK( this, msg ) )
304  return false;
305 
306  GetScreen()->ClrModify(); // do not prompt the user for changes
307 
308  if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
309  {
310  // Re-set the name since name or extension was changed
311  GetBoard()->SetFileName( currfn.GetFullPath() );
312  UpdateTitle();
313  return true;
314  }
315  return false;
316  }
317 
318  case ID_NEW_BOARD:
319  {
320  if( IsContentModified() )
321  {
322  wxFileName fileName = GetBoard()->GetFileName();
323  wxString saveMsg =
324  _( "Current board will be closed, save changes to \"%s\" before continuing?" );
325 
326  if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
327  [&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
328  return false;
329  }
330  else if( !GetBoard()->IsEmpty() )
331  {
332  if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
333  return false;
334  }
335 
337 
338  GetBoard()->ClearProject();
339 
341 
342  mgr->SaveProject( mgr->Prj().GetProjectFullName() );
343  mgr->UnloadProject( &mgr->Prj() );
344 
345  if( !Clear_Pcb( false ) )
346  return false;
347 
348  onBoardLoaded();
349 
351 
352  OnModify();
353  return true;
354  }
355 
356  case ID_SAVE_BOARD:
357  if( !GetBoard()->GetFileName().IsEmpty() )
358  return SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
359 
361 
362  case ID_COPY_BOARD_AS:
363  case ID_SAVE_BOARD_AS:
364  {
365  bool addToHistory = false;
366  wxString orig_name;
367  wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name,
368  nullptr );
369 
370  if( orig_name.IsEmpty() )
371  {
372  addToHistory = true;
373  orig_name = _( "noname" );
374  }
375 
376  wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
377  wxFileName fn( pro_dir, orig_name, KiCadPcbFileExtension );
378  wxString filename = fn.GetFullPath();
379 
380  bool createProject = false;
381 
382  if( AskSaveBoardFileName( this, &filename, &createProject ) )
383  {
384  if( id == ID_COPY_BOARD_AS )
385  return SavePcbCopy( filename, createProject );
386  else
387  return SavePcbFile( filename, addToHistory, createProject );
388  }
389  return false;
390  }
391 
392  default:
393  return false;
394  }
395 }
396 
397 
398 // The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
399 // determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
400 // bit flag.
401 IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
402 {
403  IO_MGR::PCB_FILE_T pluginType;
404 
405  wxFileName fn = aFileName;
406 
407  // Note: file extensions are expected to be in lower case.
408  // This is not always true, especially when importing files, so the string
409  // comparisons are case insensitive to try to find the suitable plugin.
410 
411  if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
412  {
413  // both legacy and eagle share a common file extension.
414  pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
415  }
416  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
417  {
418  pluginType = IO_MGR::PCAD;
419  }
420  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
421  {
422  pluginType = IO_MGR::ALTIUM_DESIGNER;
423  }
424  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
425  {
426  pluginType = IO_MGR::ALTIUM_CIRCUIT_STUDIO;
427  }
428  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
429  {
430  pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
431  }
432  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
433  {
434  pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
435  }
436  else
437  {
438  pluginType = IO_MGR::KICAD_SEXP;
439  }
440 
441  return pluginType;
442 }
443 
444 
446 {
447  PCB_LAYER_COLLECTOR collector;
448 
449  collector.SetLayerId( Edge_Cuts );
450  collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
451 
452  int edgeWidth = -1;
453  bool mixed = false;
454 
455  for( int i = 0; i < collector.GetCount(); i++ )
456  {
457  if( collector[i]->Type() == PCB_LINE_T )
458  {
459  int itemWidth = static_cast<DRAWSEGMENT*>( collector[i] )->GetWidth();
460 
461  if( edgeWidth != -1 && edgeWidth != itemWidth )
462  {
463  mixed = true;
464  edgeWidth = std::max( edgeWidth, itemWidth );
465  }
466  else
467  {
468  edgeWidth = itemWidth;
469  }
470  }
471  }
472 
473  if( mixed )
474  {
475  // If they had different widths then we can't ensure that fills will be the same.
476  wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance\n"
477  "setting will be used (see Board Setup > Design Rules). This may\n"
478  "result in different fills from previous Kicad versions which used\n"
479  "the line thickness of the board boundary on the Edge Cuts layer." ),
480  _( "Edge Clearance Warning" ), wxOK|wxICON_WARNING, this );
481  }
482 
483  return std::max( 0, edgeWidth / 2 );
484 }
485 
486 
487 bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
488 {
489  // This is for python:
490  if( aFileSet.size() != 1 )
491  {
492  UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ );
493  DisplayError( this, msg );
494  return false;
495  }
496 
497  wxString fullFileName( aFileSet[0] );
498 
499  if( Kiface().IsSingle() )
500  {
502  }
503 
504  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
505  wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
506 
507  std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName );
508 
509  if( !lockFile )
510  {
511  wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName );
512  DisplayError( this, msg );
513  return false;
514  }
515 
516  if( IsContentModified() )
517  {
518  if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
519  [&]()->bool { return SavePcbFile( GetBoard()->GetFileName() ); } ) )
520  {
521  return false;
522  }
523  }
524 
525  // Release the lock file, until the new file is actually loaded
526  ReleaseFile();
527 
528  wxFileName pro = fullFileName;
529  pro.SetExt( ProjectFileExtension );
530 
531  bool is_new = !wxFileName::IsFileReadable( fullFileName );
532 
533  // If its a non-existent schematic and caller thinks it exists
534  if( is_new && !( aCtl & KICTL_CREATE ) )
535  {
536  // notify user that fullFileName does not exist, ask if user wants to create it.
537  wxString ask = wxString::Format( _( "PCB \"%s\" does not exist. Do you wish to create it?" ),
538  fullFileName );
539  if( !IsOK( this, ask ) )
540  return false;
541  }
542 
543  // Unlink the old project if needed
544  GetBoard()->ClearProject();
545 
546  // No save prompt (we already prompted above), and only reset to a new blank board if new
547  Clear_Pcb( false, !is_new );
548 
549  IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
550 
551  bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
552 
553  if( !converted )
554  {
555  // Loading a project should only be done under carefully considered circumstances.
556 
557  // The calling code should know not to ask me here to change projects unless
558  // it knows what consequences that will have on other KIFACEs running and using
559  // this same PROJECT. It can be very harmful if that calling code is stupid.
561 
562  if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
563  {
564  // calls SaveProject
566 
567  mgr->UnloadProject( &mgr->Prj() );
568 
569  mgr->LoadProject( pro.GetFullPath() );
570 
571  // Do not allow saving a project if one doesn't exist. This normally happens if we are
572  // standalone and opening a board that has been moved from its project folder.
573  if( !pro.Exists() )
574  Prj().SetReadOnly();
575  }
576  }
577 
578  if( is_new )
579  {
580  OnModify();
581  }
582  else
583  {
584  BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK
585 
586  PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
587 
588  // This will rename the file if there is an autosave and the user want to recover
589  CheckForAutoSaveFile( fullFileName );
590 
591  try
592  {
593  PROPERTIES props;
594  char xbuf[30];
595  char ybuf[30];
596 
597  // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
598  sprintf( xbuf, "%d", GetPageSizeIU().x );
599  sprintf( ybuf, "%d", GetPageSizeIU().y );
600 
601  props["page_width"] = xbuf;
602  props["page_height"] = ybuf;
603 
604 #if USE_INSTRUMENTATION
605  // measure the time to load a BOARD.
606  unsigned startTime = GetRunningMicroSecs();
607 #endif
608 
609  loadedBoard = pi->Load( fullFileName, NULL, &props );
610 
611 #if USE_INSTRUMENTATION
612  unsigned stopTime = GetRunningMicroSecs();
613  printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
614 #endif
615  }
616  catch( const IO_ERROR& ioe )
617  {
618  if( ioe.Problem() != wxT( "CANCEL" ) )
619  {
620  wxString msg = wxString::Format( _( "Error loading board file:\n%s" ), fullFileName );
621  DisplayErrorMessage( this, msg, ioe.What() );
622  }
623 
624  // We didn't create a new blank board above, so do that now
625  Clear_Pcb( false );
626 
627  return false;
628  }
629 
630  SetBoard( loadedBoard );
631 
632  // On save; design settings will be removed from the board
633  if( loadedBoard->m_LegacyDesignSettingsLoaded )
634  loadedBoard->SetModified();
635 
636  // Move legacy view settings to local project settings
637  if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
638  {
640  loadedBoard->SetModified();
641  }
642 
643  if( !loadedBoard->m_LegacyVisibleItems.test( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) ) )
644  {
646  loadedBoard->SetModified();
647  }
648 
649  // we should not ask PLUGINs to do these items:
650  loadedBoard->BuildListOfNets();
652 
653  if( loadedBoard->IsModified() )
654  OnModify();
655  else
656  GetScreen()->ClrModify();
657 
658  if( pluginType == IO_MGR::LEGACY &&
659  loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION )
660  {
661  DisplayInfoMessage( this,
662  _( "This file was created by an older version of Pcbnew.\n"
663  "It will be stored in the new file format when you save this file again." ) );
664  }
665  }
666 
667  {
668  wxFileName fn = fullFileName;
669 
670  if( converted )
671  fn.SetExt( PcbFileExtension );
672 
673  wxString fname = fn.GetFullPath();
674 
675  fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
676 
677  GetBoard()->SetFileName( fname );
678  }
679 
680  // Lock the file newly opened:
681  m_file_checker.reset( lockFile.release() );
682 
683  if( !converted )
684  UpdateFileHistory( GetBoard()->GetFileName() );
685 
686  // Select netclass Default as current netclass (it always exists)
688 
689  // Rebuild list of nets (full ratsnest rebuild)
691  Compile_Ratsnest( true );
692 
693  // Load project settings after setting up board; some of them depend on the nets list
695 
696  // Syncs the UI (appearance panel, etc) with the loaded board and project
697  onBoardLoaded();
698 
699  // Refresh the 3D view, if any
700  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
701 
702  if( draw3DFrame )
703  draw3DFrame->NewDisplay();
704 
705 #if 0 && defined(DEBUG)
706  // Output the board object tree to stdout, but please run from command prompt:
707  GetBoard()->Show( 0, std::cout );
708 #endif
709 
710  // from EDA_APPL which was first loaded BOARD only:
711  {
712  /* For an obscure reason the focus is lost after loading a board file
713  * when starting up the process.
714  * (seems due to the recreation of the layer manager after loading the file)
715  * Give focus to main window and Drawpanel
716  * must be done for these 2 windows (for an obscure reason ...)
717  * Linux specific
718  * This is more a workaround than a fix.
719  */
720  SetFocus();
721  GetCanvas()->SetFocus();
722  }
723 
724  return true;
725 }
726 
727 
728 bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
729  bool aChangeProject )
730 {
731  // please, keep it simple. prompting goes elsewhere.
732 
733  wxFileName pcbFileName = aFileName;
734 
735  if( pcbFileName.GetExt() == LegacyPcbFileExtension )
736  pcbFileName.SetExt( KiCadPcbFileExtension );
737 
738  if( !IsWritable( pcbFileName ) )
739  {
740  wxString msg = wxString::Format( _(
741  "No access rights to write to file \"%s\"" ),
742  pcbFileName.GetFullPath() );
743 
744  DisplayError( this, msg );
745  return false;
746  }
747 
748  // TODO: this will break if we ever go multi-board
749  wxFileName projectFile( pcbFileName );
750  bool projectFileExists = false;
751 
752  projectFile.SetExt( ProjectFileExtension );
753  projectFileExists = projectFile.FileExists();
754 
755  if( aChangeProject && !projectFileExists )
756  {
757  // If this is a new board, project filename won't be set yet
758  if( projectFile.GetFullPath() != Prj().GetProjectFullName() )
759  {
760  GetBoard()->ClearProject();
761 
763 
764  mgr->SaveProject( Prj().GetProjectFullName() );
765  mgr->UnloadProject( &Prj() );
766 
767  // If no project to load then initialize project text vars with board properties
768  if( !mgr->LoadProject( projectFile.GetFullPath() ) )
770 
771  GetBoard()->SetProject( &Prj() );
772  }
773  }
774 
775  if( projectFileExists )
777 
778  wxFileName tempFile( aFileName );
779  tempFile.SetName( wxT( "." ) + tempFile.GetName() );
780  tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
781 
783 
784  // Select default Netclass before writing file. Useful to save default values in headers.
786 
787  // Save various DRC parameters, such as violation severities (which may have been
788  // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
790 
792 
793  ClearMsgPanel();
794 
795  wxString upperTxt;
796  wxString lowerTxt;
797 
798  try
799  {
801 
802  wxASSERT( tempFile.IsAbsolute() );
803 
804  pi->Save( tempFile.GetFullPath(), GetBoard(), NULL );
805  }
806  catch( const IO_ERROR& ioe )
807  {
808  wxString msg = wxString::Format( _(
809  "Error saving board file \"%s\".\n%s" ),
810  pcbFileName.GetFullPath(), ioe.What()
811  );
812  DisplayError( this, msg );
813 
814  lowerTxt.Printf( _( "Failed to create temporary file \"%s\"" ), tempFile.GetFullPath() );
815 
816  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
817 
818  // In case we started a file but didn't fully write it, clean up
819  wxRemoveFile( tempFile.GetFullPath() );
820 
821  return false;
822  }
823 
824  // If save succeeded, replace the original with what we just wrote
825  if( !wxRenameFile( tempFile.GetFullPath(), pcbFileName.GetFullPath() ) )
826  {
827  wxString msg = wxString::Format( _(
828  "Error saving board file \"%s\".\nFailed to rename temporary file \"%s\"" ),
829  pcbFileName.GetFullPath(), tempFile.GetFullPath()
830  );
831  DisplayError( this, msg );
832 
833  lowerTxt.Printf( _( "Failed to rename temporary file \"%s\"" ), tempFile.GetFullPath() );
834 
835  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
836 
837  return false;
838  }
839 
840  if( !Kiface().IsSingle() )
841  {
842  WX_STRING_REPORTER backupReporter( &upperTxt );
843 
844  if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
845  upperTxt.clear();
846  }
847 
848  GetBoard()->SetFileName( pcbFileName.GetFullPath() );
849  UpdateTitle();
850 
851  // Put the saved file in File History if requested
852  if( addToHistory )
853  UpdateFileHistory( GetBoard()->GetFileName() );
854 
855  // Delete auto save file on successful save.
856  wxFileName autoSaveFileName = pcbFileName;
857 
858  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
859 
860  if( autoSaveFileName.FileExists() )
861  wxRemoveFile( autoSaveFileName.GetFullPath() );
862 
863  lowerTxt.Printf( _( "Wrote board file: \"%s\"" ), pcbFileName.GetFullPath() );
864 
865  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
866 
867  GetScreen()->ClrModify();
868  GetScreen()->ClrSave();
869  return true;
870 }
871 
872 
873 bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
874 {
875  wxFileName pcbFileName = aFileName;
876 
877  // Ensure the file ext is the right ext:
878  pcbFileName.SetExt( KiCadPcbFileExtension );
879 
880  if( !IsWritable( pcbFileName ) )
881  {
882  wxString msg = wxString::Format( _(
883  "No access rights to write to file \"%s\"" ),
884  pcbFileName.GetFullPath() );
885 
886  DisplayError( this, msg );
887  return false;
888  }
889 
891 
892  // Select default Netclass before writing file.
893  // Useful to save default values in headers
895 
896  try
897  {
899 
900  wxASSERT( pcbFileName.IsAbsolute() );
901 
902  pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
903  }
904  catch( const IO_ERROR& ioe )
905  {
906  wxString msg = wxString::Format( _(
907  "Error saving board file \"%s\".\n%s" ),
908  pcbFileName.GetFullPath(), ioe.What()
909  );
910  DisplayError( this, msg );
911 
912  return false;
913  }
914 
915  if( aCreateProject )
916  {
917  wxFileName projectFile( pcbFileName );
918  projectFile.SetExt( ProjectFileExtension );
919 
920  if( !projectFile.FileExists() )
921  {
922  wxString currentProject = Prj().GetProjectFullName();
923 
925 
926  GetBoard()->ClearProject();
927 
928  mgr->SaveProject( currentProject );
929  mgr->UnloadProject( &Prj() );
930 
931  mgr->LoadProject( projectFile.GetFullPath() );
932  mgr->SaveProject();
933 
934  mgr->UnloadProject( &Prj() );
935  mgr->LoadProject( currentProject );
936 
937  // If no project to load then initialize project text vars with board properties
938  if( !mgr->LoadProject( currentProject ) )
940 
941  GetBoard()->SetProject( &Prj() );
942  }
943  }
944 
945  DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n\"%s\"" ),
946  pcbFileName.GetFullPath() ) );
947 
948  return true;
949 }
950 
951 
953 {
954  wxFileName tmpFileName;
955 
956  if( GetBoard()->GetFileName().IsEmpty() )
957  {
958  tmpFileName = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
960  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
961  }
962  else
963  {
964  tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
965  }
966 
967  wxFileName autoSaveFileName = tmpFileName;
968 
969  // Auto save file name is the board file name prepended with autosaveFilePrefix string.
970  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
971 
972  if( !autoSaveFileName.IsOk() )
973  return false;
974 
975  // If the board file path is not writable, try writing to a platform specific temp file
976  // path. If that path isn't writabe, give up.
977  if( !autoSaveFileName.IsDirWritable() )
978  {
979  autoSaveFileName.SetPath( wxFileName::GetTempDir() );
980 
981  if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
982  return false;
983  }
984 
985  wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" );
986 
987  if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
988  {
989  GetScreen()->SetModify();
990  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
991  UpdateTitle();
992  m_autoSaveState = false;
993 
994  if( !Kiface().IsSingle() &&
995  GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
996  {
998  }
999 
1000  return true;
1001  }
1002 
1003  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1004 
1005  return false;
1006 }
1007 
1008 
1009 bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1010 {
1011  switch( (IO_MGR::PCB_FILE_T) aFileType )
1012  {
1013  case IO_MGR::EAGLE:
1014  if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_EAGLE_BRD ) )
1015  {
1016  wxString projectpath = Kiway().Prj().GetProjectPath();
1017  wxFileName newfilename;
1018 
1019  newfilename.SetPath( Prj().GetProjectPath() );
1020  newfilename.SetName( Prj().GetProjectName() );
1021  newfilename.SetExt( KiCadPcbFileExtension );
1022 
1023  GetBoard()->SetFileName( newfilename.GetFullPath() );
1024  UpdateTitle();
1025  OnModify();
1026 
1027  // Extract a footprint library from the design and add it to the fp-lib-table
1028  wxString newLibPath;
1029  ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath );
1030 
1031  if( newLibPath.Length() > 0 )
1032  {
1033  FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
1034  const wxString& project_env = PROJECT_VAR_NAME;
1035  wxString rel_path, env_path;
1036 
1037  wxGetEnv( project_env, &env_path );
1038 
1039  wxString result( newLibPath );
1040  rel_path = result.Replace( env_path,
1041  wxString( "$(" + project_env + ")" ) ) ? result : "" ;
1042 
1043  if( !rel_path.IsEmpty() )
1044  newLibPath = rel_path;
1045 
1046  FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(),
1047  newLibPath, wxT( "KiCad" ), wxEmptyString );
1048  prjlibtable->InsertRow( row );
1049  }
1050 
1051  if( !GetBoard()->GetFileName().IsEmpty() )
1052  {
1053  wxString tblName = Prj().FootprintLibTblName();
1054 
1055  try
1056  {
1057  Prj().PcbFootprintLibs()->Save( tblName );
1058  }
1059  catch( const IO_ERROR& ioe )
1060  {
1061  wxString msg = wxString::Format( _(
1062  "Error occurred saving project specific footprint library "
1063  "table:\n\n%s" ), ioe.What() );
1064  wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
1065  }
1066  }
1067 
1068 
1069  // Update module LIB_IDs to point to the just imported Eagle library
1070  for( MODULE* module : GetBoard()->Modules() )
1071  {
1072  LIB_ID libId = module->GetFPID();
1073 
1074  if( libId.GetLibItemName().empty() )
1075  continue;
1076 
1077  libId.SetLibNickname( newfilename.GetName() );
1078  module->SetFPID( libId );
1079  }
1080 
1081 
1082  // Store net names for all pads, to create net remap information
1083  std::unordered_map<D_PAD*, wxString> netMap;
1084 
1085  for( const auto& pad : GetBoard()->GetPads() )
1086  {
1087  NETINFO_ITEM* netinfo = pad->GetNet();
1088 
1089  if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() )
1090  netMap[pad] = netinfo->GetNetname();
1091  }
1092 
1093  // Two stage netlist update:
1094  // - first, assign valid timestamps to footprints (no reannotation)
1095  // - second, perform schematic annotation and update footprint references
1096  // based on timestamps
1097  NETLIST netlist;
1099  DoUpdatePCBFromNetlist( netlist, false );
1101  DoUpdatePCBFromNetlist( netlist, true );
1102 
1103  std::unordered_map<wxString, wxString> netRemap;
1104 
1105  // Compare the old net names with the new net names and create a net map
1106  for( const auto& pad : GetBoard()->GetPads() )
1107  {
1108  auto it = netMap.find( pad );
1109 
1110  if( it == netMap.end() )
1111  continue;
1112 
1113  NETINFO_ITEM* netinfo = pad->GetNet();
1114 
1115  // Net name has changed, create a remap entry
1116  if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() )
1117  netRemap[netMap[pad]] = netinfo->GetNetname();
1118  }
1119 
1120  if( !netRemap.empty() )
1121  fixEagleNets( netRemap );
1122 
1123  return true;
1124  }
1125 
1126  return false;
1127 
1128  default:
1129  return false;
1130  }
1131 
1132  return false;
1133 }
1134 
1135 
1136 bool PCB_EDIT_FRAME::fixEagleNets( const std::unordered_map<wxString, wxString>& aRemap )
1137 {
1138  bool result = true;
1139  BOARD* board = GetBoard();
1140 
1141  // perform netlist matching to prevent orphaned zones.
1142  for( auto zone : board->Zones() )
1143  {
1144  auto it = aRemap.find( zone->GetNet()->GetNetname() );
1145 
1146  if( it != aRemap.end() )
1147  {
1148  NETINFO_ITEM* net = board->FindNet( it->second );
1149 
1150  if( !net )
1151  {
1152  wxFAIL;
1153  result = false;
1154  continue;
1155  }
1156 
1157  zone->SetNet( net );
1158  }
1159  }
1160 
1161 
1162  // perform netlist matching to prevent orphaned tracks/vias.
1163  for( auto track : board->Tracks() )
1164  {
1165  auto it = aRemap.find( track->GetNet()->GetNetname() );
1166 
1167  if( it != aRemap.end() )
1168  {
1169  NETINFO_ITEM* net = board->FindNet( it->second );
1170 
1171  if( !net )
1172  {
1173  wxFAIL;
1174  result = false;
1175  continue;
1176  }
1177 
1178  track->SetNet( net );
1179  }
1180  }
1181 
1182  return result;
1183 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
void UpdateTitle()
Function UpdateTitle sets the main window title bar text.
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
LSET m_VisibleLayers
Board settings.
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void BuildListOfNets()
Definition: class_board.h:692
void SetModified()
Definition: base_struct.cpp:87
void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:201
VTBL_ENTRY std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:80
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
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
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
wxString EaglePcbFileWildcard()
static const KICAD_T AllBoardItems[]
A scan list for all editable board items.
Definition: collectors.h:267
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: class_board.h:281
bool importFile(const wxString &aFileName, int aFileType)
Load the given filename but sets the path to the current project path.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:252
This file is part of the common library TODO brief description.
IO_MGR::PCB_FILE_T plugin_type(const wxString &aFileName, int aCtl)
SETTINGS_MANAGER * GetSettingsManager() const
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
bool IsModified() const
Definition: base_struct.h:198
FP_LIB_TABLE_ROW.
Definition: fp_lib_table.h:42
void Compile_Ratsnest(bool aDisplayStatus)
Function Compile_Ratsnest Create the entire board ratsnest.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
This file is part of the common library.
const std::string ProjectFileExtension
const std::string LegacyPcbFileExtension
VTBL_ENTRY PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:147
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
VTBL_ENTRY PROJECT & Prj() const
Function Prj returns the PROJECT associated with this KIWAY.
Definition: kiway.cpp:173
bool doAutoSave() override
Function doAutoSave performs auto save when the board has been modified and not saved within the auto...
#define KICTL_CREATE
caller thinks requested project files may not exist
Definition: kiway_player.h:79
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Class that computes missing connections on a PCB.
void ResolveDRCExclusions()
Update markers to match recorded exclusions.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:38
bool LoadProjectSettings()
Load the current project's file configuration settings which are pertinent to this PCB_EDIT_FRAME ins...
void ReleaseFile()
Release the current file marked in use.
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Tests a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:637
CREATE_PROJECT_CHECKBOX(wxWindow *aParent)
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false)
Function SavePcbCopy writes the board data structures to a aFileName but unlike SavePcbFile,...
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:88
#define KICTL_EAGLE_BRD
chosen *.brd file is Eagle according to user.
Definition: kiway_player.h:78
This is the end of the layers used for visibility bitmasks in Pcbnew There can be at most 32 layers a...
int inferLegacyEdgeClearance(BOARD *aBoard)
Use the existing edge_cut line thicknesses to infer the edge clearace.
wxString AltiumCircuitMakerPcbFileWildcard()
Collect all BOARD_ITEM objects on a given layer.
Definition: collectors.h:655
const std::string KiCadPcbFileExtension
bool IsWritable(const wxFileName &aFileName)
Checks if aFileName can be written.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
const wxString & GetFileName() const
Definition: class_board.h:244
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:45
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:124
bool fixEagleNets(const std::unordered_map< wxString, wxString > &aRemap)
Rematch orphaned zones and vias to schematic nets.
std::unique_ptr< wxSingleInstanceChecker > m_file_checker
prevents opening same file multiple times.
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
void SetLayerId(PCB_LAYER_ID aLayerId)
Definition: collectors.h:665
VTBL_ENTRY const wxString AbsolutePath(const wxString &aFileName) const
Function AbsolutePath fixes up aFileName if it is relative to the project's directory to be an absolu...
Definition: project.cpp:272
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetches the file name from the file history list.
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
RELEASER releases a PLUGIN in the context of a potential thrown exception, through its destructor.
Definition: io_mgr.h:580
const std::map< wxString, wxString > & GetProperties() const
Definition: class_board.h:271
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:101
void SynchronizeNetsAndNetClasses()
Function SynchronizeNetsAndNetClasses copies NETCLASS info to each NET, based on NET membership in a ...
void OnClearFileHistory(wxCommandEvent &aEvent)
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Puts up a wxFileDialog asking for a BOARD filename to save.
wxString LegacyPcbFileWildcard()
GAL_SET m_VisibleItems
The GAL layers (aka items) that are turned on for viewing (.
void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
NETLIST stores all of information read from a netlist along with the flags used to update the NETLIST...
Definition: pcb_netlist.h:194
#define NULL
bool IsSingle() const
Function IsSingle is this KIFACE_I running under single_top?
Definition: kiface_i.h:117
bool IsContentModified() override
Get if the current board has been modified but not saved.
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Function OpenProjectFiles (was LoadOnePcbFile) loads a KiCad board (.kicad_pcb) from aFileName.
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:80
static wxWindow * Create(wxWindow *aParent)
#define GAL_LAYER_INDEX(x)
Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS.
void onBoardLoaded()
Updates the state of the GUI after a new board is loaded or created.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Calls BackupProject if a new backup is needed according to the current backup policy.
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
bool AskLoadBoardFileName(wxWindow *aParent, int *aCtl, wxString *aFileName, bool aKicadFilesOnly)
Function AskLoadBoardFileName puts up a wxFileDialog asking for a BOARD filename to open.
void SaveProjectSettings() override
Function SaveProjectSettings saves changes to the project settings to the project (....
void SynchronizeProperties()
Function SynchronizeProperties copies the current project's text variables into the boards property c...
Definition of file extensions used in Kicad.
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:231
Definition: color4d.h:58
wxLogTrace helper definitions.
virtual void SetFocus() override
#define PcbFileExtension
void BuildConnectivity()
Builds or rebuilds the board connectivity database for the board, especially the list of connected it...
void SetFileName(const wxString &aFileName)
Definition: class_board.h:242
VTBL_ENTRY const wxString GetProjectFullName() const
Function GetProjectFullName returns the full path and name of the project.
Definition: project.cpp:118
virtual void ClearMsgPanel()
Clear all messages from the message panel.
VTBL_ENTRY bool IsNullProject() const
Checks if this project is a null project (i.e.
Definition: project.cpp:136
wxString AltiumDesignerPcbFileWildcard()
wxCheckBox * m_cbCreateProject
void ClearProject()
int GetFileFormatVersionAtLoad() const
Definition: class_board.h:300
WX_STRING_REPORTER is a wrapper for reporting to a wxString object.
Definition: reporter.h:161
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:160
VTBL_ENTRY FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:286
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
void ClearFileHistory(FILE_HISTORY *aFileHistory=nullptr)
Removes all files from the file history.
static wxString GetAutoSaveFilePrefix()
wxString AltiumCircuitStudioPcbFileWildcard()
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
void SetProject(PROJECT *aProject)
Links a board to a given project.
Helper widget to select whether a new project should be created for a file when saving
void AppendMsgPanel(const wxString &textUpper, const wxString &textLower, COLOR4D color, int pad=6)
Append a message to the message panel.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
void OnFileHistory(wxCommandEvent &event)
ZONE_CONTAINERS & Zones()
Definition: class_board.h:254
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:56
see class PGM_BASE
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Function SavePcbFile writes the board data structures to a aFileName Creates backup when requested an...
void SetBoard(BOARD *aBoard) override
Declaration of the eda_3d_viewer class.
const char * name
Definition: DXF_plotter.cpp:60
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:201
void DoUpdatePCBFromNetlist(NETLIST &aNetlist, bool aUseTimestamps)
Function DoUpdatePCBFromNetlist An automated version of UpdatePCBFromNetlist which skips the UI dialo...
void ArchiveModulesOnBoard(bool aStoreInNewLib, const wxString &aLibName=wxEmptyString, wxString *aLibPath=NULL)
Function ArchiveModulesOnBoard Save modules in a library:
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:178
void Files_io(wxCommandEvent &event)
Function Files_io.
#define _(s)
Definition: 3d_actions.cpp:33
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
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:62
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
bool SaveProject(const wxString &aFullPath=wxEmptyString)
Saves a loaded project.
PCB_EDIT_FRAME is the main frame for Pcbnew.
void ClrModify()
Definition: base_screen.h:101
wxString PcbFileWildcard()
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
const wxSize GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
bool Files_io_from_id(int aId)
Function Files_io_from_id Read and write board files.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
Definition: eda_3d_viewer.h:65
static REPORTER & GetInstance()
Definition: reporter.cpp:105
BOARD * GetBoard() const
void SetModify()
Definition: base_screen.h:100
wxString CadstarPcbArchiveFileWildcard()
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
Message panel definition file.
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:267
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
wxString PCadPcbFileWildcard()
EDA_3D_VIEWER * Get3DViewerFrame()
bool Clear_Pcb(bool aQuery, bool aFinal=false)
Function Clear_Pcb delete all and reinitialize the current board.
Definition: initpcb.cpp:43
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:283
bool IsEmpty() const
Definition: class_board.h:292
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: class_board.h:277
void ClrSave()
Definition: base_screen.h:103
bool FetchNetlistFromSchematic(NETLIST &aNetlist, FETCH_NETLIST_MODE aMode)
VTBL_ENTRY void SetReadOnly(bool aReadOnly=true)
Definition: project.h:122
TRACKS & Tracks()
Definition: class_board.h:246
VTBL_ENTRY const wxString FootprintLibTblName() const
Function FootprintLibTblName returns the path and filename of this project's fp-lib-table,...
Definition: project.cpp:148
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
bool empty() const
Definition: utf8.h:108
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition: gtk/app.cpp:26
S-expression Pcbnew file format.
Definition: io_mgr.h:57
static const wxString GetFileExtension(PCB_FILE_T aFileType)
Function GetFileExtension returns the file extension for aFileType.
Definition: io_mgr.cpp:113
GAL_SET m_LegacyVisibleItems
Definition: class_board.h:278