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 <confirm.h>
27 #include <core/arraydim.h>
28 #include <kicad_string.h>
29 #include <gestfich.h>
30 #include <pcb_edit_frame.h>
32 #include <pgm_base.h>
33 #include <widgets/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 <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 #include <project/net_settings.h>
57 
58 
59 //#define USE_INSTRUMENTATION 1
60 #define USE_INSTRUMENTATION 0
61 
62 
75 bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bool aKicadFilesOnly )
76 {
77  // This is a subset of all PLUGINs which are trusted to be able to
78  // load a BOARD. User may occasionally use the wrong plugin to load a
79  // *.brd file (since both legacy and eagle use *.brd extension),
80  // but eventually *.kicad_pcb will be more common than legacy *.brd files.
81 
82  // clang-format off
83  static const struct
84  {
85  const wxString& filter;
86  IO_MGR::PCB_FILE_T pluginType;
87  } loaders[] =
88  {
89  { PcbFileWildcard(), IO_MGR::KICAD_SEXP }, // Current Kicad board files
90  { LegacyPcbFileWildcard(), IO_MGR::LEGACY }, // Old Kicad board files
91  { AltiumCircuitMakerPcbFileWildcard(), IO_MGR::ALTIUM_CIRCUIT_MAKER }, // Import Altium Circuit Maker board files
92  { AltiumCircuitStudioPcbFileWildcard(), IO_MGR::ALTIUM_CIRCUIT_STUDIO }, // Import Altium Circuit Studio board files
93  { AltiumDesignerPcbFileWildcard(), IO_MGR::ALTIUM_DESIGNER }, // Import Altium Designer board files
94  { CadstarPcbArchiveFileWildcard(), IO_MGR::CADSTAR_PCB_ARCHIVE }, // Import Cadstar PCB Archive board files
95  { EaglePcbFileWildcard(), IO_MGR::EAGLE }, // Import Eagle board files
96  { PCadPcbFileWildcard(), IO_MGR::PCAD } // Import PCAD board files
97  };
98  // clang-format on
99 
100  wxFileName fileName( *aFileName );
101  wxString fileFilters;
102 
103  if( aKicadFilesOnly )
104  {
105  std::vector<std::string> fileExtensions;
106 
107  for( unsigned ii = 0; ii < 2; ++ii )
108  {
109  if( !fileFilters.IsEmpty() )
110  fileFilters += wxChar( '|' );
111 
112  fileFilters += wxGetTranslation( loaders[ii].filter );
113 
114  PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
115  wxCHECK( plugin, false );
116  fileExtensions.push_back( plugin->GetFileExtension().ToStdString() );
117  }
118 
119  fileFilters = _( "All KiCad Board Files" ) + AddFileExtListToFilter( fileExtensions ) + "|"
120  + fileFilters;
121  }
122  else
123  {
124  wxString allWildcards;
125 
126  for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
127  {
128  if( !fileFilters.IsEmpty() )
129  fileFilters += wxChar( '|' );
130 
131  fileFilters += wxGetTranslation( loaders[ii].filter );
132 
133  PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
134  wxCHECK( plugin, false );
135  allWildcards += "*." + formatWildcardExt( plugin->GetFileExtension() ) + ";";
136  }
137 
138  fileFilters = _( "All supported formats|" ) + allWildcards + "|" + fileFilters;
139  }
140 
141 
142  wxString path;
143  wxString name;
144 
145  if( fileName.FileExists() )
146  {
147  path = fileName.GetPath();
148  name = fileName.GetFullName();
149  }
150  else
151  {
152  path = wxStandardPaths::Get().GetDocumentsDir();
153  // leave name empty
154  }
155 
156  wxFileDialog dlg( aParent,
157  aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
158  path, name, fileFilters,
159  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
160 
161  if( dlg.ShowModal() == wxID_OK )
162  {
163  // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
164  // It's the only special case because of the duplicate use of the *.brd file extension.
165  // Other cases are clear because of unique file extensions.
166  *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
167  *aFileName = dlg.GetPath();
168  return true;
169  }
170  else
171  return false;
172 }
173 
174 
176 class CREATE_PROJECT_CHECKBOX : public wxPanel
177 {
178 public:
179  CREATE_PROJECT_CHECKBOX( wxWindow* aParent )
180  : wxPanel( aParent )
181  {
182  m_cbCreateProject = new wxCheckBox( this, wxID_ANY,
183  _( "Create a new project for this board" ) );
184  m_cbCreateProject->SetValue( false );
185  m_cbCreateProject->SetToolTip( _( "Creating a project will enable features such as "
186  "design rules, net classes, and layer presets" ) );
187 
188  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
189  sizer->Add( m_cbCreateProject, 0, wxALL, 8 );
190 
191  SetSizerAndFit( sizer );
192  }
193 
194  bool GetValue() const
195  {
196  return m_cbCreateProject->GetValue();
197  }
198 
199  static wxWindow* Create( wxWindow* aParent )
200  {
201  return new CREATE_PROJECT_CHECKBOX( aParent );
202  }
203 
204 protected:
205  wxCheckBox* m_cbCreateProject;
206 };
207 
208 
219 bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
220 {
221  wxString wildcard = PcbFileWildcard();
222  wxFileName fn = *aFileName;
223 
224  fn.SetExt( KiCadPcbFileExtension );
225 
226  wxFileDialog dlg( aParent,
227  _( "Save Board File As" ),
228  fn.GetPath(),
229  fn.GetFullName(),
230  wildcard,
231  wxFD_SAVE | wxFD_OVERWRITE_PROMPT
232  );
233 
234  // Add a "Create a project" checkbox in standalone mode and one isn't loaded
235  if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
236  dlg.SetExtraControlCreator( &CREATE_PROJECT_CHECKBOX::Create );
237 
238  if( dlg.ShowModal() != wxID_OK )
239  return false;
240 
241  fn = dlg.GetPath();
242 
243  // always enforce filename extension, user may not have entered it.
244  fn.SetExt( KiCadPcbFileExtension );
245 
246  *aFileName = fn.GetFullPath();
247 
248  if( wxWindow* extraControl = dlg.GetExtraControl() )
249  *aCreateProject = static_cast<CREATE_PROJECT_CHECKBOX*>( extraControl )->GetValue();
250 
251  return true;
252 }
253 
254 
255 void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
256 {
257  wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
258 
259  if( !!fn )
260  {
261  int open_ctl = 0;
262 
263  if( !wxFileName::IsFileReadable( fn ) )
264  {
265  if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
266  return;
267  }
268 
269  OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
270  }
271 }
272 
273 
274 void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
275 {
277 }
278 
279 
280 void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
281 {
282  int id = event.GetId();
283  Files_io_from_id( id );
284 }
285 
286 
288 {
289  wxString msg;
290 
291  switch( id )
292  {
293  case ID_LOAD_FILE:
294  {
295  int open_ctl = 0;
296  wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
297 
298  return AskLoadBoardFileName( this, &open_ctl, &fileName, true )
299  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
300  }
301 
303  {
304  int open_ctl = 1;
305  wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
306 
307  return AskLoadBoardFileName( this, &open_ctl, &fileName, false )
308  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
309  }
310 
312  {
313  wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
314  wxFileName fn = currfn;
315 
316  wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
317  fn.SetName( rec_name );
318 
319  if( !fn.FileExists() )
320  {
321  msg.Printf( _( "Recovery file \"%s\" not found." ), fn.GetFullPath() );
322  DisplayInfoMessage( this, msg );
323  return false;
324  }
325 
326  msg.Printf( _( "OK to load recovery file \"%s\"" ), fn.GetFullPath() );
327 
328  if( !IsOK( this, msg ) )
329  return false;
330 
331  GetScreen()->ClrModify(); // do not prompt the user for changes
332 
333  if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
334  {
335  // Re-set the name since name or extension was changed
336  GetBoard()->SetFileName( currfn.GetFullPath() );
337  UpdateTitle();
338  return true;
339  }
340  return false;
341  }
342 
343  case ID_NEW_BOARD:
344  {
345  if( IsContentModified() )
346  {
347  wxFileName fileName = GetBoard()->GetFileName();
348  wxString saveMsg =
349  _( "Current board will be closed, save changes to \"%s\" before continuing?" );
350 
351  if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
352  [&]()->bool { return Files_io_from_id( ID_SAVE_BOARD ); } ) )
353  return false;
354  }
355  else if( !GetBoard()->IsEmpty() )
356  {
357  if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
358  return false;
359  }
360 
362 
363  GetBoard()->ClearProject();
364 
366 
367  mgr->SaveProject( mgr->Prj().GetProjectFullName() );
368  mgr->UnloadProject( &mgr->Prj() );
369 
370  if( !Clear_Pcb( false ) )
371  return false;
372 
373  onBoardLoaded();
374 
376 
377  OnModify();
378  return true;
379  }
380 
381  case ID_SAVE_BOARD:
382  if( !GetBoard()->GetFileName().IsEmpty() )
383  return SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
384 
386 
387  case ID_COPY_BOARD_AS:
388  case ID_SAVE_BOARD_AS:
389  {
390  bool addToHistory = false;
391  wxString orig_name;
392  wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name,
393  nullptr );
394 
395  if( orig_name.IsEmpty() )
396  {
397  addToHistory = true;
398  orig_name = _( "noname" );
399  }
400 
401  wxFileName savePath( Prj().GetProjectFullName() );
402 
403  if( !savePath.IsOk() || !savePath.IsDirWritable() )
404  {
405  savePath = GetMruPath();
406 
407  if( !savePath.IsOk() || !savePath.IsDirWritable() )
408  savePath = wxStandardPaths::Get().GetDocumentsDir();
409  }
410 
411  wxFileName fn( savePath.GetPath(), orig_name, KiCadPcbFileExtension );
412  wxString filename = fn.GetFullPath();
413 
414  bool createProject = false;
415 
416  if( AskSaveBoardFileName( this, &filename, &createProject ) )
417  {
418  if( id == ID_COPY_BOARD_AS )
419  return SavePcbCopy( filename, createProject );
420  else
421  return SavePcbFile( filename, addToHistory, createProject );
422  }
423  return false;
424  }
425 
426  default:
427  return false;
428  }
429 }
430 
431 
432 // The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
433 // determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
434 // bit flag.
435 IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
436 {
437  IO_MGR::PCB_FILE_T pluginType;
438 
439  wxFileName fn = aFileName;
440 
441  // Note: file extensions are expected to be in lower case.
442  // This is not always true, especially when importing files, so the string
443  // comparisons are case insensitive to try to find the suitable plugin.
444 
445  if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
446  {
447  // both legacy and eagle share a common file extension.
448  pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
449  }
450  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
451  {
452  pluginType = IO_MGR::PCAD;
453  }
454  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
455  {
456  pluginType = IO_MGR::ALTIUM_DESIGNER;
457  }
458  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
459  {
460  pluginType = IO_MGR::ALTIUM_CIRCUIT_STUDIO;
461  }
462  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
463  {
464  pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
465  }
466  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
467  {
468  pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
469  }
470  else
471  {
472  pluginType = IO_MGR::KICAD_SEXP;
473  }
474 
475  return pluginType;
476 }
477 
478 
480 {
481  PCB_LAYER_COLLECTOR collector;
482 
483  collector.SetLayerId( Edge_Cuts );
484  collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
485 
486  int edgeWidth = -1;
487  bool mixed = false;
488 
489  for( int i = 0; i < collector.GetCount(); i++ )
490  {
491  if( collector[i]->Type() == PCB_SHAPE_T )
492  {
493  int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
494 
495  if( edgeWidth != -1 && edgeWidth != itemWidth )
496  {
497  mixed = true;
498  edgeWidth = std::max( edgeWidth, itemWidth );
499  }
500  else
501  {
502  edgeWidth = itemWidth;
503  }
504  }
505  }
506 
507  if( mixed )
508  {
509  // If they had different widths then we can't ensure that fills will be the same.
510  wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance "
511  "setting will be used (see Board Setup > Design Rules).\n"
512  "This may result in different fills from previous Kicad versions which "
513  "used the line thicknesses of the board boundary on the Edge Cuts layer." ),
514  _( "Edge Clearance Warning" ), wxOK|wxICON_WARNING, this );
515  }
516 
517  return std::max( 0, edgeWidth / 2 );
518 }
519 
520 
521 bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
522 {
523  // This is for python:
524  if( aFileSet.size() != 1 )
525  {
526  UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ );
527  DisplayError( this, msg );
528  return false;
529  }
530 
531  wxString fullFileName( aFileSet[0] );
532 
533  if( Kiface().IsSingle() )
534  {
536  }
537 
538  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
539  wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
540 
541  std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName );
542 
543  if( !lockFile )
544  {
545  wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName );
546  DisplayError( this, msg );
547  return false;
548  }
549 
550  if( IsContentModified() )
551  {
552  if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
553  [&]()->bool { return SavePcbFile( GetBoard()->GetFileName() ); } ) )
554  {
555  return false;
556  }
557  }
558 
559  // Release the lock file, until the new file is actually loaded
560  ReleaseFile();
561 
562  wxFileName pro = fullFileName;
563  pro.SetExt( ProjectFileExtension );
564 
565  bool is_new = !wxFileName::IsFileReadable( fullFileName );
566 
567  // If its a non-existent schematic and caller thinks it exists
568  if( is_new && !( aCtl & KICTL_CREATE ) )
569  {
570  // notify user that fullFileName does not exist, ask if user wants to create it.
571  wxString ask = wxString::Format( _( "PCB \"%s\" does not exist. Do you wish to create it?" ),
572  fullFileName );
573  if( !IsOK( this, ask ) )
574  return false;
575  }
576 
577  // Unlink the old project if needed
578  GetBoard()->ClearProject();
579 
580  // No save prompt (we already prompted above), and only reset to a new blank board if new
581  Clear_Pcb( false, !is_new );
582 
583  IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
584 
585  bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
586 
587  if( !converted )
588  {
589  // Loading a project should only be done under carefully considered circumstances.
590 
591  // The calling code should know not to ask me here to change projects unless
592  // it knows what consequences that will have on other KIFACEs running and using
593  // this same PROJECT. It can be very harmful if that calling code is stupid.
595 
596  if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
597  {
598  // calls SaveProject
600 
601  mgr->UnloadProject( &mgr->Prj() );
602 
603  mgr->LoadProject( pro.GetFullPath() );
604 
605  // Do not allow saving a project if one doesn't exist. This normally happens if we are
606  // standalone and opening a board that has been moved from its project folder.
607  if( !pro.Exists() )
608  Prj().SetReadOnly();
609  }
610  }
611 
612  if( is_new )
613  {
614  // Link the existing blank board to the new project
615  GetBoard()->SetProject( &Prj() );
616 
617  GetBoard()->SetFileName( fullFileName );
618 
619  OnModify();
620  }
621  else
622  {
623  BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK
624 
625  PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
626 
627  LAYER_REMAPPABLE_PLUGIN* layerRemappable =
628  dynamic_cast< LAYER_REMAPPABLE_PLUGIN* >( (PLUGIN*) pi );
629  if ( layerRemappable )
630  {
631  using namespace std::placeholders;
632  layerRemappable->RegisterLayerMappingCallback(
633  std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, _1 ) );
634  }
635 
636  // This will rename the file if there is an autosave and the user want to recover
637  CheckForAutoSaveFile( fullFileName );
638 
639  try
640  {
641  PROPERTIES props;
642  char xbuf[30];
643  char ybuf[30];
644 
645  // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
646  sprintf( xbuf, "%d", GetPageSizeIU().x );
647  sprintf( ybuf, "%d", GetPageSizeIU().y );
648 
649  props["page_width"] = xbuf;
650  props["page_height"] = ybuf;
651 
652 #if USE_INSTRUMENTATION
653  // measure the time to load a BOARD.
654  unsigned startTime = GetRunningMicroSecs();
655 #endif
656 
657  loadedBoard = pi->Load( fullFileName, NULL, &props );
658 
659 #if USE_INSTRUMENTATION
660  unsigned stopTime = GetRunningMicroSecs();
661  printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
662 #endif
663  }
664  catch( const IO_ERROR& ioe )
665  {
666  if( ioe.Problem() != wxT( "CANCEL" ) )
667  {
668  wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
669  fullFileName );
670  DisplayErrorMessage( this, msg, ioe.What() );
671  }
672 
673  // We didn't create a new blank board above, so do that now
674  Clear_Pcb( false );
675 
676  return false;
677  }
678 
679  SetBoard( loadedBoard );
680 
681  if( loadedBoard->m_LegacyDesignSettingsLoaded )
682  {
684 
685  // Before we had a copper edge clearance setting, the edge line widths could be used
686  // as a kludge to control them. So if there's no setting then infer it from the
687  // edge widths.
688  if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
689  {
690  int edgeClearance = inferLegacyEdgeClearance( loadedBoard );
691  loadedBoard->GetDesignSettings().SetCopperEdgeClearance( edgeClearance );
692  }
693 
694  // On save; design settings will be removed from the board
695  loadedBoard->SetModified();
696  }
697 
698  // Move legacy view settings to local project settings
699  if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
700  {
702  loadedBoard->SetModified();
703  }
704 
705  if( !loadedBoard->m_LegacyVisibleItems.test( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) ) )
706  {
708  loadedBoard->SetModified();
709  }
710 
711  // we should not ask PLUGINs to do these items:
712  loadedBoard->BuildListOfNets();
714 
715  if( loadedBoard->IsModified() )
716  OnModify();
717  else
718  GetScreen()->ClrModify();
719 
720  if( pluginType == IO_MGR::LEGACY &&
721  loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION )
722  {
723  DisplayInfoMessage( this,
724  _( "This file was created by an older version of Pcbnew.\n"
725  "It will be stored in the new file format when you save this file again." ) );
726  }
727  }
728 
729  {
730  wxFileName fn = fullFileName;
731 
732  if( converted )
733  fn.SetExt( PcbFileExtension );
734 
735  wxString fname = fn.GetFullPath();
736 
737  fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
738 
739  GetBoard()->SetFileName( fname );
740  }
741 
742  // Lock the file newly opened:
743  m_file_checker.reset( lockFile.release() );
744 
745  if( !converted )
746  UpdateFileHistory( GetBoard()->GetFileName() );
747 
748  // Rebuild list of nets (full ratsnest rebuild)
750  Compile_Ratsnest( true );
751 
752  // Load project settings after setting up board; some of them depend on the nets list
754 
755  // Syncs the UI (appearance panel, etc) with the loaded board and project
756  onBoardLoaded();
757 
758  // Refresh the 3D view, if any
759  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
760 
761  if( draw3DFrame )
762  draw3DFrame->NewDisplay();
763 
764 #if 0 && defined(DEBUG)
765  // Output the board object tree to stdout, but please run from command prompt:
766  GetBoard()->Show( 0, std::cout );
767 #endif
768 
769  // from EDA_APPL which was first loaded BOARD only:
770  {
771  /* For an obscure reason the focus is lost after loading a board file
772  * when starting up the process.
773  * (seems due to the recreation of the layer manager after loading the file)
774  * Give focus to main window and Drawpanel
775  * must be done for these 2 windows (for an obscure reason ...)
776  * Linux specific
777  * This is more a workaround than a fix.
778  */
779  SetFocus();
780  GetCanvas()->SetFocus();
781  }
782 
783  return true;
784 }
785 
786 
787 bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
788  bool aChangeProject )
789 {
790  // please, keep it simple. prompting goes elsewhere.
791 
792  wxFileName pcbFileName = aFileName;
793 
794  if( pcbFileName.GetExt() == LegacyPcbFileExtension )
795  pcbFileName.SetExt( KiCadPcbFileExtension );
796 
797  if( !IsWritable( pcbFileName ) )
798  {
799  wxString msg = wxString::Format( _(
800  "No access rights to write to file \"%s\"" ),
801  pcbFileName.GetFullPath() );
802 
803  DisplayError( this, msg );
804  return false;
805  }
806 
807  // TODO: this will break if we ever go multi-board
808  wxFileName projectFile( pcbFileName );
809  bool projectFileExists = false;
810 
811  projectFile.SetExt( ProjectFileExtension );
812  projectFileExists = projectFile.FileExists();
813 
814  if( aChangeProject && !projectFileExists )
815  {
816  // If this is a new board, project filename won't be set yet
817  if( projectFile.GetFullPath() != Prj().GetProjectFullName() )
818  {
819  GetBoard()->ClearProject();
820 
822 
823  mgr->SaveProject( Prj().GetProjectFullName() );
824  mgr->UnloadProject( &Prj() );
825 
826  // If no project to load then initialize project text vars with board properties
827  if( !mgr->LoadProject( projectFile.GetFullPath() ) )
829 
830  GetBoard()->SetProject( &Prj() );
831  }
832  }
833 
834  if( projectFileExists )
836 
837  wxFileName tempFile( aFileName );
838  tempFile.SetName( wxT( "." ) + tempFile.GetName() );
839  tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
840 
842 
843  // Save various DRC parameters, such as violation severities (which may have been
844  // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
846 
848 
849  ClearMsgPanel();
850 
851  wxString upperTxt;
852  wxString lowerTxt;
853 
854  try
855  {
857 
858  wxASSERT( tempFile.IsAbsolute() );
859 
860  pi->Save( tempFile.GetFullPath(), GetBoard(), NULL );
861  }
862  catch( const IO_ERROR& ioe )
863  {
864  wxString msg = wxString::Format( _(
865  "Error saving board file \"%s\".\n%s" ),
866  pcbFileName.GetFullPath(), ioe.What()
867  );
868  DisplayError( this, msg );
869 
870  lowerTxt.Printf( _( "Failed to create temporary file \"%s\"" ), tempFile.GetFullPath() );
871 
872  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
873 
874  // In case we started a file but didn't fully write it, clean up
875  wxRemoveFile( tempFile.GetFullPath() );
876 
877  return false;
878  }
879 
880  // If save succeeded, replace the original with what we just wrote
881  if( !wxRenameFile( tempFile.GetFullPath(), pcbFileName.GetFullPath() ) )
882  {
883  wxString msg = wxString::Format( _(
884  "Error saving board file \"%s\".\nFailed to rename temporary file \"%s\"" ),
885  pcbFileName.GetFullPath(), tempFile.GetFullPath()
886  );
887  DisplayError( this, msg );
888 
889  lowerTxt.Printf( _( "Failed to rename temporary file \"%s\"" ), tempFile.GetFullPath() );
890 
891  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
892 
893  return false;
894  }
895 
896  if( !Kiface().IsSingle() )
897  {
898  WX_STRING_REPORTER backupReporter( &upperTxt );
899 
900  if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
901  upperTxt.clear();
902  }
903 
904  GetBoard()->SetFileName( pcbFileName.GetFullPath() );
905  UpdateTitle();
906 
907  // Put the saved file in File History if requested
908  if( addToHistory )
909  UpdateFileHistory( GetBoard()->GetFileName() );
910 
911  // Delete auto save file on successful save.
912  wxFileName autoSaveFileName = pcbFileName;
913 
914  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
915 
916  if( autoSaveFileName.FileExists() )
917  wxRemoveFile( autoSaveFileName.GetFullPath() );
918 
919  lowerTxt.Printf( _( "Wrote board file: \"%s\"" ), pcbFileName.GetFullPath() );
920 
921  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
922 
923  GetScreen()->ClrModify();
924  GetScreen()->ClrSave();
925  return true;
926 }
927 
928 
929 bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
930 {
931  wxFileName pcbFileName = aFileName;
932 
933  // Ensure the file ext is the right ext:
934  pcbFileName.SetExt( KiCadPcbFileExtension );
935 
936  if( !IsWritable( pcbFileName ) )
937  {
938  wxString msg = wxString::Format( _(
939  "No access rights to write to file \"%s\"" ),
940  pcbFileName.GetFullPath() );
941 
942  DisplayError( this, msg );
943  return false;
944  }
945 
947 
948  try
949  {
951 
952  wxASSERT( pcbFileName.IsAbsolute() );
953 
954  pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
955  }
956  catch( const IO_ERROR& ioe )
957  {
958  wxString msg = wxString::Format( _(
959  "Error saving board file \"%s\".\n%s" ),
960  pcbFileName.GetFullPath(), ioe.What()
961  );
962  DisplayError( this, msg );
963 
964  return false;
965  }
966 
967  if( aCreateProject )
968  {
969  wxFileName projectFile( pcbFileName );
970  projectFile.SetExt( ProjectFileExtension );
971 
972  if( !projectFile.FileExists() )
973  {
974  wxString currentProject = Prj().GetProjectFullName();
975 
977 
978  GetBoard()->ClearProject();
979 
980  mgr->SaveProject( currentProject );
981  mgr->UnloadProject( &Prj() );
982 
983  mgr->LoadProject( projectFile.GetFullPath() );
984  mgr->SaveProject();
985 
986  mgr->UnloadProject( &Prj() );
987  mgr->LoadProject( currentProject );
988 
989  // If no project to load then initialize project text vars with board properties
990  if( !mgr->LoadProject( currentProject ) )
992 
993  GetBoard()->SetProject( &Prj() );
994  }
995  }
996 
997  DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n\"%s\"" ),
998  pcbFileName.GetFullPath() ) );
999 
1000  return true;
1001 }
1002 
1003 
1005 {
1006  wxFileName tmpFileName;
1007 
1008  if( GetBoard()->GetFileName().IsEmpty() )
1009  {
1010  tmpFileName = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
1012  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1013  }
1014  else
1015  {
1016  tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1017  }
1018 
1019  wxFileName autoSaveFileName = tmpFileName;
1020 
1021  // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1022  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
1023 
1024  if( !autoSaveFileName.IsOk() )
1025  return false;
1026 
1027  // If the board file path is not writable, try writing to a platform specific temp file
1028  // path. If that path isn't writabe, give up.
1029  if( !autoSaveFileName.IsDirWritable() )
1030  {
1031  autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1032 
1033  if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1034  return false;
1035  }
1036 
1037  wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" );
1038 
1039  if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1040  {
1041  GetScreen()->SetModify();
1042  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1043  UpdateTitle();
1044  m_autoSaveState = false;
1045 
1046  if( !Kiface().IsSingle() &&
1047  GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1048  {
1050  }
1051 
1052  return true;
1053  }
1054 
1055  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1056 
1057  return false;
1058 }
1059 
1060 
1061 bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1062 {
1063  switch( (IO_MGR::PCB_FILE_T) aFileType )
1064  {
1066  case IO_MGR::EAGLE:
1067  if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_EAGLE_BRD ) )
1068  {
1069  wxString projectpath = Kiway().Prj().GetProjectPath();
1070  wxFileName newfilename;
1071 
1072  newfilename.SetPath( Prj().GetProjectPath() );
1073  newfilename.SetName( Prj().GetProjectName() );
1074  newfilename.SetExt( KiCadPcbFileExtension );
1075 
1076  GetBoard()->SetFileName( newfilename.GetFullPath() );
1077  UpdateTitle();
1078  OnModify();
1079 
1080  // Extract a footprint library from the design and add it to the fp-lib-table
1081  wxString newLibPath;
1082  ExportFootprintsToLibrary( true, newfilename.GetName(), &newLibPath );
1083 
1084  if( newLibPath.Length() > 0 )
1085  {
1086  FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
1087  const wxString& project_env = PROJECT_VAR_NAME;
1088  wxString rel_path, env_path;
1089 
1090  wxGetEnv( project_env, &env_path );
1091 
1092  wxString result( newLibPath );
1093  rel_path = result.Replace( env_path,
1094  wxString( "$(" + project_env + ")" ) ) ? result : "" ;
1095 
1096  if( !rel_path.IsEmpty() )
1097  newLibPath = rel_path;
1098 
1099  FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(),
1100  newLibPath, wxT( "KiCad" ), wxEmptyString );
1101  prjlibtable->InsertRow( row );
1102  }
1103 
1104  if( !GetBoard()->GetFileName().IsEmpty() )
1105  {
1106  wxString tblName = Prj().FootprintLibTblName();
1107 
1108  try
1109  {
1110  Prj().PcbFootprintLibs()->Save( tblName );
1111  }
1112  catch( const IO_ERROR& ioe )
1113  {
1114  wxString msg = wxString::Format( _(
1115  "Error occurred saving project specific footprint library "
1116  "table:\n\n%s" ), ioe.What() );
1117  wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
1118  }
1119  }
1120 
1121 
1122  // Update footprint LIB_IDs to point to the just imported Eagle library
1123  for( FOOTPRINT* footprint : GetBoard()->Footprints() )
1124  {
1125  LIB_ID libId = footprint->GetFPID();
1126 
1127  if( libId.GetLibItemName().empty() )
1128  continue;
1129 
1130  libId.SetLibNickname( newfilename.GetName() );
1131  footprint->SetFPID( libId );
1132  }
1133 
1134 
1135  // Store net names for all pads, to create net remap information
1136  std::unordered_map<PAD*, wxString> netMap;
1137 
1138  for( const auto& pad : GetBoard()->GetPads() )
1139  {
1140  NETINFO_ITEM* netinfo = pad->GetNet();
1141 
1142  if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() )
1143  netMap[pad] = netinfo->GetNetname();
1144  }
1145 
1146  // Two stage netlist update:
1147  // - first, assign valid timestamps to footprints (no reannotation)
1148  // - second, perform schematic annotation and update footprint references
1149  // based on timestamps
1150  NETLIST netlist;
1152  DoUpdatePCBFromNetlist( netlist, false );
1154  DoUpdatePCBFromNetlist( netlist, true );
1155 
1156  std::unordered_map<wxString, wxString> netRemap;
1157 
1158  // Compare the old net names with the new net names and create a net map
1159  for( const auto& pad : GetBoard()->GetPads() )
1160  {
1161  auto it = netMap.find( pad );
1162 
1163  if( it == netMap.end() )
1164  continue;
1165 
1166  NETINFO_ITEM* netinfo = pad->GetNet();
1167 
1168  // Net name has changed, create a remap entry
1169  if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() )
1170  netRemap[netMap[pad]] = netinfo->GetNetname();
1171  }
1172 
1173  if( !netRemap.empty() )
1174  fixEagleNets( netRemap );
1175 
1176  return true;
1177  }
1178 
1179  return false;
1180 
1181  default:
1182  return false;
1183  }
1184 
1185  return false;
1186 }
1187 
1188 
1189 bool PCB_EDIT_FRAME::fixEagleNets( const std::unordered_map<wxString, wxString>& aRemap )
1190 {
1191  bool result = true;
1192  BOARD* board = GetBoard();
1193 
1194  // perform netlist matching to prevent orphaned zones.
1195  for( auto zone : board->Zones() )
1196  {
1197  auto it = aRemap.find( zone->GetNet()->GetNetname() );
1198 
1199  if( it != aRemap.end() )
1200  {
1201  NETINFO_ITEM* net = board->FindNet( it->second );
1202 
1203  if( !net )
1204  {
1205  wxFAIL;
1206  result = false;
1207  continue;
1208  }
1209 
1210  zone->SetNet( net );
1211  }
1212  }
1213 
1214 
1215  // perform netlist matching to prevent orphaned tracks/vias.
1216  for( auto track : board->Tracks() )
1217  {
1218  auto it = aRemap.find( track->GetNet()->GetNetname() );
1219 
1220  if( it != aRemap.end() )
1221  {
1222  NETINFO_ITEM* net = board->FindNet( it->second );
1223 
1224  if( !net )
1225  {
1226  wxFAIL;
1227  result = false;
1228  continue;
1229  }
1230 
1231  track->SetNet( net );
1232  }
1233  }
1234 
1235  return result;
1236 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:240
void UpdateTitle()
Function UpdateTitle sets the main window title bar text.
Plugin class for import plugins that support remappable layers.
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
Search for a net with the given netcode.
Definition: board.cpp:1234
void BuildListOfNets()
Definition: board.h:700
void SetModified()
Definition: eda_item.cpp:79
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:202
void SetCopperEdgeClearance(int aDistance)
Function SetCopperEdgeClearance.
VTBL_ENTRY std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:78
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()
Pcbnew PLUGIN for CADSTAR PCB Archive (*.cpa) format: an ASCII format based on S-expressions.
static const KICAD_T AllBoardItems[]
A scan list for all editable board items.
Definition: collectors.h:268
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:316
ZONES & Zones()
Definition: board.h:289
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:253
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: eda_item.h:186
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:149
#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:174
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:81
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:617
CREATE_PROJECT_CHECKBOX(wxWindow *aParent)
NET_SETTINGS & NetSettings()
Definition: project_file.h:92
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:559
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:83
#define KICTL_EAGLE_BRD
chosen *.brd file is Eagle according to user.
Definition: kiway_player.h:80
This is the end of the layers used for visibility bit masks in Pcbnew There can be at most 32 layers ...
int inferLegacyEdgeClearance(BOARD *aBoard)
wxString AltiumCircuitMakerPcbFileWildcard()
Collect all BOARD_ITEM objects on a given layer.
Definition: collectors.h:641
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
PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
const wxString & GetFileName() const
Definition: board.h:278
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:122
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:651
virtual void RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
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:270
void ExportFootprintsToLibrary(bool aStoreInNewLib, const wxString &aLibName=wxEmptyString, wxString *aLibPath=NULL)
Function ExportFootprintsToLibrary Save footprints in a library:
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:78
bool m_LegacyCopperEdgeClearanceLoaded
Definition: board.h:317
RELEASER releases a PLUGIN in the context of a potential thrown exception, through its destructor.
Definition: io_mgr.h:575
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:306
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:104
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1379
void OnClearFileHistory(wxCommandEvent &aEvent)
wxString GetMruPath() const
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 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.
VTBL_ENTRY PROJECT_FILE & GetProjectFile() const
Definition: project.h:143
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
void ResolveNetClassAssignments(bool aRebuildFromScratch=false)
Explodes the list of netclass assignments to include atomic members of composite labels (buses).
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()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1372
Definition of file extensions used in Kicad.
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:231
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
Definition: color4d.h:59
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
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...
Definition: board.cpp:133
void SetFileName(const wxString &aFileName)
Definition: board.h:276
VTBL_ENTRY const wxString GetProjectFullName() const
Function GetProjectFullName returns the full path and name of the project.
Definition: project.cpp:116
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:134
wxString AltiumDesignerPcbFileWildcard()
wxCheckBox * m_cbCreateProject
void ClearProject()
Definition: board.cpp:165
int GetFileFormatVersionAtLoad() const
Definition: board.h:337
WX_STRING_REPORTER is a wrapper for reporting to a wxString object.
Definition: reporter.h:161
VTBL_ENTRY FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:284
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.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
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.
Definition: board.cpp:139
Helper widget to select whether a new project should be created for a file when saving
static std::map< wxString, PCB_LAYER_ID > GetMapModal(wxWindow *aParent, const std::vector< INPUT_LAYER_DESC > &aLayerDesc)
Creates and shows a dialog (modal) and returns the data from it after completion.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
void OnFileHistory(wxCommandEvent &event)
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:59
void DoUpdatePCBFromNetlist(NETLIST &aNetlist, bool aUseTimestamps)
Function DoUpdatePCBFromNetlist An automated version of UpdatePCBFromNetlist which skips the UI dialo...
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:186
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:57
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
PLUGIN is a base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:269
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:121
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:120
wxString CadstarPcbArchiveFileWildcard()
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:268
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:91
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:42
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:284
bool IsEmpty() const
Definition: board.h:329
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: board.h:312
void ClrSave()
Definition: base_screen.h:123
bool FetchNetlistFromSchematic(NETLIST &aNetlist, FETCH_NETLIST_MODE aMode)
VTBL_ENTRY void SetReadOnly(bool aReadOnly=true)
Definition: project.h:124
TRACKS & Tracks()
Definition: board.h:280
VTBL_ENTRY const wxString FootprintLibTblName() const
Function FootprintLibTblName returns the path and filename of this project's fp-lib-table,...
Definition: project.cpp:146
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
bool empty() const
Definition: utf8.h:108
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
virtual BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=NULL)
Function Load loads information from some input file format that this PLUGIN implementation knows abo...
Definition: plugin.cpp:47
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:108
void AppendMsgPanel(const wxString &aTextUpper, const wxString &aTextLower, int aPadding=6)
Append a message to the message panel.
GAL_SET m_LegacyVisibleItems
Definition: board.h:313