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-2021 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 <gestfich.h>
29 #include <pcb_edit_frame.h>
30 #include <board_design_settings.h>
32 #include <widgets/msgpanel.h>
33 #include <fp_lib_table.h>
34 #include <kiface_i.h>
35 #include <macros.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/checkbox.h>
45 #include <wx/stdpaths.h>
46 #include <ratsnest/ratsnest_data.h>
47 #include <kiplatform/app.h>
49 #include <widgets/infobar.h>
52 #include <paths.h>
53 #include <project/project_file.h>
55 #include <project/net_settings.h>
59 #include <tools/pcb_actions.h>
60 #include "footprint_info_impl.h"
61 #include <wx_filename.h> // For ::ResolvePossibleSymlinks()
62 
63 #include <wx/wupdlock.h>
64 #include <wx/filedlg.h>
65 
66 
67 
68 //#define USE_INSTRUMENTATION 1
69 #define USE_INSTRUMENTATION 0
70 
71 
81 bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, int* aCtl, wxString* aFileName,
82  bool aKicadFilesOnly )
83 {
84  // This is a subset of all PLUGINs which are trusted to be able to
85  // load a BOARD. User may occasionally use the wrong plugin to load a
86  // *.brd file (since both legacy and eagle use *.brd extension),
87  // but eventually *.kicad_pcb will be more common than legacy *.brd files.
88 
89  // clang-format off
90  static const struct
91  {
92  const wxString& filter;
93  IO_MGR::PCB_FILE_T pluginType;
94  } loaders[] =
95  {
96  // Current Kicad board files.
98 
99  // Old Kicad board files.
101 
102  // Import Altium Circuit Maker board files.
104 
105  // Import Altium Circuit Studio board files.
107 
108  // Import Altium Designer board files.
110 
111  // Import Cadstar PCB Archive board files.
113 
114  // Import Eagle board files.
116 
117  // Import PCAD board files.
119 
120  // Import Fabmaster board files.
122  };
123  // clang-format on
124 
125  wxFileName fileName( *aFileName );
126  wxString fileFilters;
127 
128  if( aKicadFilesOnly )
129  {
130  std::vector<std::string> fileExtensions;
131 
132  for( unsigned ii = 0; ii < 2; ++ii )
133  {
134  if( !fileFilters.IsEmpty() )
135  fileFilters += wxChar( '|' );
136 
137  fileFilters += wxGetTranslation( loaders[ii].filter );
138 
139  PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
140  wxCHECK( plugin, false );
141  fileExtensions.push_back( plugin->GetFileExtension().ToStdString() );
142  }
143 
144  fileFilters = _( "All KiCad Board Files" ) + AddFileExtListToFilter( fileExtensions ) + "|"
145  + fileFilters;
146  }
147  else
148  {
149  wxString allWildcards;
150 
151  for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
152  {
153  if( !fileFilters.IsEmpty() )
154  fileFilters += wxChar( '|' );
155 
156  fileFilters += wxGetTranslation( loaders[ii].filter );
157 
158  PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
159  wxCHECK( plugin, false );
160  allWildcards += "*." + formatWildcardExt( plugin->GetFileExtension() ) + ";";
161  }
162 
163  fileFilters = _( "All supported formats|" ) + allWildcards + "|" + fileFilters;
164  }
165 
166 
167  wxString path;
168  wxString name;
169 
170  if( fileName.FileExists() )
171  {
172  path = fileName.GetPath();
173  name = fileName.GetFullName();
174  }
175  else
176  {
177  path = aParent->GetMruPath();
178 
179  if( path.IsEmpty() )
181  // leave name empty
182  }
183 
184  wxFileDialog dlg( aParent,
185  aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
186  path, name, fileFilters,
187  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
188 
189  if( dlg.ShowModal() == wxID_OK )
190  {
191  // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
192  // It's the only special case because of the duplicate use of the *.brd file extension.
193  // Other cases are clear because of unique file extensions.
194  *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
195  *aFileName = dlg.GetPath();
196  aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
197  return true;
198  }
199  else
200  return false;
201 }
202 
203 
205 class CREATE_PROJECT_CHECKBOX : public wxPanel
206 {
207 public:
208  CREATE_PROJECT_CHECKBOX( wxWindow* aParent )
209  : wxPanel( aParent )
210  {
211  m_cbCreateProject = new wxCheckBox( this, wxID_ANY,
212  _( "Create a new project for this board" ) );
213  m_cbCreateProject->SetValue( false );
214  m_cbCreateProject->SetToolTip( _( "Creating a project will enable features such as "
215  "design rules, net classes, and layer presets" ) );
216 
217  wxBoxSizer* sizer = new wxBoxSizer( wxHORIZONTAL );
218  sizer->Add( m_cbCreateProject, 0, wxALL, 8 );
219 
220  SetSizerAndFit( sizer );
221  }
222 
223  bool GetValue() const
224  {
225  return m_cbCreateProject->GetValue();
226  }
227 
228  static wxWindow* Create( wxWindow* aParent )
229  {
230  return new CREATE_PROJECT_CHECKBOX( aParent );
231  }
232 
233 protected:
234  wxCheckBox* m_cbCreateProject;
235 };
236 
237 
247 bool AskSaveBoardFileName( PCB_EDIT_FRAME* aParent, wxString* aFileName, bool* aCreateProject )
248 {
249  wxString wildcard = PcbFileWildcard();
250  wxFileName fn = *aFileName;
251 
252  fn.SetExt( KiCadPcbFileExtension );
253 
254  wxFileDialog dlg( aParent, _( "Save Board File As" ), fn.GetPath(), fn.GetFullName(), wildcard,
255  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
256 
257  // Add a "Create a project" checkbox in standalone mode and one isn't loaded
258  if( Kiface().IsSingle() && aParent->Prj().IsNullProject() )
259  dlg.SetExtraControlCreator( &CREATE_PROJECT_CHECKBOX::Create );
260 
261  if( dlg.ShowModal() != wxID_OK )
262  return false;
263 
264  fn = dlg.GetPath();
265 
266  // always enforce filename extension, user may not have entered it.
267  fn.SetExt( KiCadPcbFileExtension );
268 
269  *aFileName = fn.GetFullPath();
270 
271  if( wxWindow* extraControl = dlg.GetExtraControl() )
272  *aCreateProject = static_cast<CREATE_PROJECT_CHECKBOX*>( extraControl )->GetValue();
273  else if( !aParent->Prj().IsNullProject() )
274  *aCreateProject = true;
275 
276  return true;
277 }
278 
279 
280 void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
281 {
282  wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
283 
284  if( !!fn )
285  {
286  int open_ctl = 0;
287 
288  if( !wxFileName::IsFileReadable( fn ) )
289  {
290  if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
291  return;
292  }
293 
294  OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
295  }
296 }
297 
298 
299 void PCB_EDIT_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
300 {
302 }
303 
304 
305 void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
306 {
307  int id = event.GetId();
308  Files_io_from_id( id );
309 }
310 
311 
313 {
314  wxString msg;
315 
316  switch( id )
317  {
318  case ID_LOAD_FILE:
319  {
320  int open_ctl = 0;
321  wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
322 
323  return AskLoadBoardFileName( this, &open_ctl, &fileName, true )
324  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
325  }
326 
328  {
329  int open_ctl = 1;
330  wxString fileName; // = Prj().AbsolutePath( GetBoard()->GetFileName() );
331 
332  return AskLoadBoardFileName( this, &open_ctl, &fileName, false )
333  && OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
334  }
335 
337  {
338  wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
339  wxFileName fn = currfn;
340 
341  wxString rec_name = GetAutoSaveFilePrefix() + fn.GetName();
342  fn.SetName( rec_name );
343 
344  if( !fn.FileExists() )
345  {
346  msg.Printf( _( "Recovery file '%s' not found." ), fn.GetFullPath() );
347  DisplayInfoMessage( this, msg );
348  return false;
349  }
350 
351  msg.Printf( _( "OK to load recovery file '%s'?" ), fn.GetFullPath() );
352 
353  if( !IsOK( this, msg ) )
354  return false;
355 
356  GetScreen()->SetContentModified( false ); // do not prompt the user for changes
357 
358  if( OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ) )
359  {
360  // Re-set the name since name or extension was changed
361  GetBoard()->SetFileName( currfn.GetFullPath() );
362  UpdateTitle();
363  return true;
364  }
365 
366  return false;
367  }
368 
369  case ID_NEW_BOARD:
370  {
371  if( IsContentModified() )
372  {
373  wxFileName fileName = GetBoard()->GetFileName();
374  wxString saveMsg = _( "Current board will be closed, save changes to '%s' before "
375  "continuing?" );
376 
377  if( !HandleUnsavedChanges( this, wxString::Format( saveMsg, fileName.GetFullName() ),
378  [&]()->bool
379  {
381  } ) )
382  {
383  return false;
384  }
385  }
386  else if( !GetBoard()->IsEmpty() )
387  {
388  if( !IsOK( this, _( "Current Board will be closed. Continue?" ) ) )
389  return false;
390  }
391 
393 
394  GetBoard()->ClearProject();
395 
397 
398  mgr->SaveProject( mgr->Prj().GetProjectFullName() );
399  mgr->UnloadProject( &mgr->Prj() );
400 
401  if( !Clear_Pcb( false ) )
402  return false;
403 
405 
406  onBoardLoaded();
407 
408  OnModify();
409  return true;
410  }
411 
412  case ID_SAVE_BOARD:
413  if( !GetBoard()->GetFileName().IsEmpty() )
414  return SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
415 
417 
418  case ID_COPY_BOARD_AS:
419  case ID_SAVE_BOARD_AS:
420  {
421  bool addToHistory = ( id == ID_SAVE_BOARD_AS );
422  wxString orig_name;
423 
424  wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name, nullptr );
425 
426  if( orig_name.IsEmpty() )
427  orig_name = NAMELESS_PROJECT;
428 
429  wxFileName savePath( Prj().GetProjectFullName() );
430 
431  if( !savePath.IsOk() || !savePath.IsDirWritable() )
432  {
433  savePath = GetMruPath();
434 
435  if( !savePath.IsOk() || !savePath.IsDirWritable() )
437  }
438 
439  wxFileName fn( savePath.GetPath(), orig_name, KiCadPcbFileExtension );
440  wxString filename = fn.GetFullPath();
441  bool createProject = false;
442 
443  if( AskSaveBoardFileName( this, &filename, &createProject ) )
444  {
445  if( id == ID_COPY_BOARD_AS )
446  return SavePcbCopy( filename, createProject );
447  else
448  return SavePcbFile( filename, addToHistory, createProject );
449  }
450 
451  return false;
452  }
453 
454  default:
455  return false;
456  }
457 }
458 
459 
460 // The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
461 // determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
462 // bit flag.
463 IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
464 {
465  IO_MGR::PCB_FILE_T pluginType;
466 
467  wxFileName fn = aFileName;
468 
469  // Note: file extensions are expected to be in lower case.
470  // This is not always true, especially when importing files, so the string
471  // comparisons are case insensitive to try to find the suitable plugin.
472 
473  if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
474  {
475  // both legacy and eagle share a common file extension.
476  pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
477  }
478  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
479  {
480  pluginType = IO_MGR::PCAD;
481  }
482  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
483  {
484  pluginType = IO_MGR::ALTIUM_DESIGNER;
485  }
486  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
487  {
488  pluginType = IO_MGR::ALTIUM_CIRCUIT_STUDIO;
489  }
490  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
491  {
492  pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
493  }
494  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
495  {
496  pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
497  }
498  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::FABMASTER ) ) == 0 )
499  {
500  pluginType = IO_MGR::FABMASTER;
501  }
502  else
503  {
504  pluginType = IO_MGR::KICAD_SEXP;
505  }
506 
507  return pluginType;
508 }
509 
510 
512 {
513  PCB_LAYER_COLLECTOR collector;
514 
515  collector.SetLayerId( Edge_Cuts );
516  collector.Collect( aBoard, GENERAL_COLLECTOR::AllBoardItems );
517 
518  int edgeWidth = -1;
519  bool mixed = false;
520 
521  for( int i = 0; i < collector.GetCount(); i++ )
522  {
523  if( collector[i]->Type() == PCB_SHAPE_T )
524  {
525  int itemWidth = static_cast<PCB_SHAPE*>( collector[i] )->GetWidth();
526 
527  if( edgeWidth != -1 && edgeWidth != itemWidth )
528  {
529  mixed = true;
530  edgeWidth = std::max( edgeWidth, itemWidth );
531  }
532  else
533  {
534  edgeWidth = itemWidth;
535  }
536  }
537  }
538 
539  if( mixed )
540  {
541  // If they had different widths then we can't ensure that fills will be the same.
542  wxMessageBox( _( "If the zones on this board are refilled the Copper Edge Clearance "
543  "setting will be used (see Board Setup > Design Rules > Constraints).\n"
544  "This may result in different fills from previous KiCad versions which "
545  "used the line thicknesses of the board boundary on the Edge Cuts "
546  "layer." ),
547  _( "Edge Clearance Warning" ), wxOK | wxICON_WARNING, this );
548  }
549 
550  return std::max( 0, edgeWidth / 2 );
551 }
552 
553 
554 bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
555 {
556  // This is for python:
557  if( aFileSet.size() != 1 )
558  {
559  UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ );
560  DisplayError( this, msg );
561  return false;
562  }
563 
564  wxString fullFileName( aFileSet[0] );
565 
566  if( Kiface().IsSingle() )
567  {
569  }
570 
571  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
572  wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
573 
574  std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName );
575 
576  if( !lockFile )
577  {
578  wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName );
579  DisplayError( this, msg );
580  return false;
581  }
582 
583  if( IsContentModified() )
584  {
585  if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ),
586  [&]()->bool { return SavePcbFile( GetBoard()->GetFileName() ); } ) )
587  {
588  return false;
589  }
590  }
591 
592  // Release the lock file, until the new file is actually loaded
593  ReleaseFile();
594 
595  wxFileName pro = fullFileName;
596  pro.SetExt( ProjectFileExtension );
597 
598  bool is_new = !wxFileName::IsFileReadable( fullFileName );
599 
600  // If its a non-existent schematic and caller thinks it exists
601  if( is_new && !( aCtl & KICTL_CREATE ) )
602  {
603  // notify user that fullFileName does not exist, ask if user wants to create it.
604  wxString ask = wxString::Format( _( "PCB '%s' does not exist. Do you wish to create it?" ),
605  fullFileName );
606  if( !IsOK( this, ask ) )
607  return false;
608  }
609 
610  // Get rid of any existing warnings about the old board
611  GetInfoBar()->Dismiss();
612 
613  // Loading a complex project and build data can be time
614  // consuming, so display a busy cursor
615  wxBusyCursor dummy;
616 
617  // No save prompt (we already prompted above), and only reset to a new blank board if new
618  Clear_Pcb( false, !is_new );
619 
620  IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
621 
622  bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
623 
624  // Loading a project should only be done under carefully considered circumstances.
625 
626  // The calling code should know not to ask me here to change projects unless
627  // it knows what consequences that will have on other KIFACEs running and using
628  // this same PROJECT. It can be very harmful if that calling code is stupid.
630 
631  if( pro.GetFullPath() != mgr->Prj().GetProjectFullName() )
632  {
633  // calls SaveProject
635 
636  GetBoard()->ClearProject();
637  mgr->UnloadProject( &mgr->Prj() );
638 
639  mgr->LoadProject( pro.GetFullPath() );
640 
641  // Do not allow saving a project if one doesn't exist. This normally happens if we are
642  // standalone and opening a board that has been moved from its project folder.
643  // For converted projects, we don't want to set the read-only flag because we want a project
644  // to be saved for the new file in case things like netclasses got migrated.
645  Prj().SetReadOnly( !pro.Exists() && !converted );
646  }
647 
648  // Clear the cache footprint list which may be project specific
650 
651  if( is_new )
652  {
653  // Link the existing blank board to the new project
654  GetBoard()->SetProject( &Prj() );
655 
656  GetBoard()->SetFileName( fullFileName );
657 
658  OnModify();
659  }
660  else
661  {
662  BOARD* loadedBoard = nullptr; // it will be set to non-NULL if loaded OK
663 
664  PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
665 
666  LAYER_REMAPPABLE_PLUGIN* layerRemappable =
667  dynamic_cast< LAYER_REMAPPABLE_PLUGIN* >( (PLUGIN*) pi );
668  if ( layerRemappable )
669  {
670  using namespace std::placeholders;
671  layerRemappable->RegisterLayerMappingCallback(
672  std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, _1 ) );
673  }
674 
675  // This will rename the file if there is an autosave and the user want to recover
676  CheckForAutoSaveFile( fullFileName );
677 
678  bool failedLoad = false;
679 
680  try
681  {
682  PROPERTIES props;
683  char xbuf[30];
684  char ybuf[30];
685 
686  // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
687  sprintf( xbuf, "%d", GetPageSizeIU().x );
688  sprintf( ybuf, "%d", GetPageSizeIU().y );
689 
690  props["page_width"] = xbuf;
691  props["page_height"] = ybuf;
692 
693  WX_PROGRESS_REPORTER progressReporter( this, _( "Loading PCB" ), 1 );
694 #if USE_INSTRUMENTATION
695  // measure the time to load a BOARD.
696  unsigned startTime = GetRunningMicroSecs();
697 #endif
698 
699  loadedBoard = pi->Load( fullFileName, NULL, &props, &Prj(), &progressReporter );
700 
701 #if USE_INSTRUMENTATION
702  unsigned stopTime = GetRunningMicroSecs();
703  printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
704 #endif
705  }
706  catch( const IO_ERROR& ioe )
707  {
708  if( ioe.Problem() != wxT( "CANCEL" ) )
709  {
710  wxString msg = wxString::Format( _( "Error loading board file:\n%s" ),
711  fullFileName );
712  DisplayErrorMessage( this, msg, ioe.What() );
713  }
714 
715  failedLoad = true;
716  }
717  catch( const std::bad_alloc& )
718  {
719  wxString msg = wxString::Format( _( "Memory exhausted loading board file:\n%s" ), fullFileName );
720  DisplayErrorMessage( this, msg );
721 
722  failedLoad = true;
723  }
724 
725  if( failedLoad )
726  {
727  // We didn't create a new blank board above, so do that now
728  Clear_Pcb( false );
729 
730  return false;
731  }
732 
733  SetBoard( loadedBoard );
734 
735  if( GFootprintList.GetCount() == 0 )
736  {
737  GFootprintList.ReadCacheFromFile( Prj().GetProjectPath() + "fp-info-cache" );
738  }
739 
740  if( loadedBoard->m_LegacyDesignSettingsLoaded )
741  {
742  Prj().SetReadOnly( false );
743 
745 
746  // Before we had a copper edge clearance setting, the edge line widths could be used
747  // as a kludge to control them. So if there's no setting then infer it from the
748  // edge widths.
749  if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded )
750  {
751  int edgeClearance = inferLegacyEdgeClearance( loadedBoard );
752  loadedBoard->GetDesignSettings().SetCopperEdgeClearance( edgeClearance );
753  }
754 
755  // On save; design settings will be removed from the board
756  loadedBoard->SetModified();
757  }
758 
759  // Move legacy view settings to local project settings
760  if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
761  {
763  loadedBoard->SetModified();
764  }
765 
766  if( !loadedBoard->m_LegacyVisibleItems.test( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) ) )
767  {
769  loadedBoard->SetModified();
770  }
771 
772  // we should not ask PLUGINs to do these items:
773  loadedBoard->BuildListOfNets();
776 
777  if( loadedBoard->IsModified() )
778  OnModify();
779  else
780  GetScreen()->SetContentModified( false );
781 
782  if( ( pluginType == IO_MGR::LEGACY )
783  || ( pluginType == IO_MGR::KICAD_SEXP
785  && loadedBoard->GetGenerator().Lower() != "gerbview" ) )
786  {
789  m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
790  "It will be converted to the new format when saved." ),
791  wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
792  }
793 
794  // Import footprints into a project-specific library
795  //==================================================
796  // TODO: This should be refactored out of here into somewhere specific to the Project Import
797  // E.g. KICAD_MANAGER_FRAME::ImportNonKiCadProject
798  if( aCtl & KICTL_IMPORT_LIB )
799  {
800  wxFileName loadedBoardFn( fullFileName );
801  wxString libNickName = loadedBoardFn.GetName();
802 
803  // Extract a footprint library from the design and add it to the fp-lib-table
804  // The footprints are saved in a new .pretty library.
805  // If this library already exists, all previous footprints will be deleted
806  std::vector<FOOTPRINT*> loadedFootprints = pi->GetImportedCachedLibraryFootprints();
807  wxString newLibPath = CreateNewProjectLibrary( libNickName );
808 
809  // Only create the new library if CreateNewLibrary succeeded (note that this fails if
810  // the library already exists and the user aborts after seeing the warning message
811  // which prompts the user to continue with overwrite or abort)
812  if( newLibPath.Length() > 0 )
813  {
815 
816  for( FOOTPRINT* footprint : loadedFootprints )
817  {
818  try
819  {
820  if( !footprint->GetFPID().GetLibItemName().empty() ) // Handle old boards.
821  {
822  footprint->SetReference( "REF**" );
823  piSexpr->FootprintSave( newLibPath, footprint );
824  delete footprint;
825  }
826  }
827  catch( const IO_ERROR& ioe )
828  {
829  wxLogError( wxString::Format( _( "Error occurred when saving footprint "
830  "'%s' to the project specific footprint "
831  "library: %s" ),
832  footprint->GetFPID().GetUniStringLibItemName(),
833  ioe.What() ) );
834  }
835  }
836 
837  FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
838  const wxString& project_env = PROJECT_VAR_NAME;
839  wxString rel_path, env_path;
840 
841  wxASSERT_MSG( wxGetEnv( project_env, &env_path ), "There is no project variable?" );
842 
843  wxString result( newLibPath );
844  rel_path = result.Replace( env_path, wxString( "$(" + project_env + ")" ) ) ? result
845  : "";
846 
847  FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( libNickName, rel_path,
848  wxT( "KiCad" ), wxEmptyString );
849  prjlibtable->InsertRow( row );
850 
851  wxString tblName = Prj().FootprintLibTblName();
852 
853  try
854  {
855  Prj().PcbFootprintLibs()->Save( tblName );
856  }
857  catch( const IO_ERROR& ioe )
858  {
859  wxLogError( wxString::Format( _( "Error occurred saving the project specific "
860  "footprint library table: %s" ),
861  ioe.What() ) );
862  }
863 
864  // Update footprint LIB_IDs to point to the just imported library
865  for( FOOTPRINT* footprint : GetBoard()->Footprints() )
866  {
867  LIB_ID libId = footprint->GetFPID();
868 
869  if( libId.GetLibItemName().empty() )
870  continue;
871 
872  libId.SetLibNickname( libNickName );
873  footprint->SetFPID( libId );
874  }
875  }
876  }
877  }
878 
879  {
880  wxFileName fn = fullFileName;
881 
882  if( converted )
883  fn.SetExt( PcbFileExtension );
884 
885  wxString fname = fn.GetFullPath();
886 
887  fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
888 
889  GetBoard()->SetFileName( fname );
890  }
891 
892  // Lock the file newly opened:
893  m_file_checker.reset( lockFile.release() );
894 
895  if( !converted )
896  UpdateFileHistory( GetBoard()->GetFileName() );
897 
898  // Rebuild list of nets (full ratsnest rebuild)
900  Compile_Ratsnest( true );
901 
902  // Load project settings after setting up board; some of them depend on the nets list
904 
905  // Syncs the UI (appearance panel, etc) with the loaded board and project
906  onBoardLoaded();
907 
908  // Refresh the 3D view, if any
909  EDA_3D_VIEWER_FRAME* draw3DFrame = Get3DViewerFrame();
910 
911  if( draw3DFrame )
912  draw3DFrame->NewDisplay();
913 
914 #if 0 && defined(DEBUG)
915  // Output the board object tree to stdout, but please run from command prompt:
916  GetBoard()->Show( 0, std::cout );
917 #endif
918 
919  // from EDA_APPL which was first loaded BOARD only:
920  {
921  /* For an obscure reason the focus is lost after loading a board file
922  * when starting up the process.
923  * (seems due to the recreation of the layer manager after loading the file)
924  * Give focus to main window and Drawpanel
925  * must be done for these 2 windows (for an obscure reason ...)
926  * Linux specific
927  * This is more a workaround than a fix.
928  */
929  SetFocus();
930  GetCanvas()->SetFocus();
931  }
932 
933  return true;
934 }
935 
936 
937 bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
938  bool aChangeProject )
939 {
940  // please, keep it simple. prompting goes elsewhere.
941  wxFileName pcbFileName = aFileName;
942 
943  if( pcbFileName.GetExt() == LegacyPcbFileExtension )
944  pcbFileName.SetExt( KiCadPcbFileExtension );
945 
946  // Write through symlinks, don't replace them
948 
949  if( !IsWritable( pcbFileName ) )
950  {
951  wxString msg = wxString::Format( _( "No access rights to write to file \"%s\"" ),
952  pcbFileName.GetFullPath() );
953 
954  DisplayError( this, msg );
955  return false;
956  }
957 
958  // TODO: these will break if we ever go multi-board
959  wxFileName projectFile( pcbFileName );
960  wxFileName rulesFile( pcbFileName );
961  wxString msg;
962 
963  projectFile.SetExt( ProjectFileExtension );
964  rulesFile.SetExt( DesignRulesFileExtension );
965 
966  if( !projectFile.FileExists() && aChangeProject )
967  {
968  Prj().SetReadOnly( false );
969  GetSettingsManager()->SaveProjectAs( projectFile.GetFullPath() );
970  }
971 
972  wxFileName currentRules( GetDesignRulesPath() );
973 
974  if( currentRules.FileExists() && !rulesFile.FileExists() && aChangeProject )
975  KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
976 
977  if( !msg.IsEmpty() )
978  {
979  DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
980  rulesFile.GetFullPath() ) );
981  }
982 
983  if( projectFile.FileExists() )
984  {
985  // Save various DRC parameters, such as violation severities (which may have been
986  // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
988 
991  }
992 
993  wxFileName tempFile( aFileName );
994  wxString upperTxt;
995  wxString lowerTxt;
996 
997  tempFile.SetName( wxT( "." ) + tempFile.GetName() );
998  tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
999 
1000  try
1001  {
1003 
1004  wxASSERT( tempFile.IsAbsolute() );
1005 
1006  pi->Save( tempFile.GetFullPath(), GetBoard(), NULL );
1007  }
1008  catch( const IO_ERROR& ioe )
1009  {
1010  DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1011  pcbFileName.GetFullPath(),
1012  ioe.What() ) );
1013 
1014  lowerTxt.Printf( _( "Failed to create temporary file '%s'." ), tempFile.GetFullPath() );
1015 
1016  SetMsgPanel( upperTxt, lowerTxt );
1017 
1018  // In case we started a file but didn't fully write it, clean up
1019  wxRemoveFile( tempFile.GetFullPath() );
1020 
1021  return false;
1022  }
1023 
1024  // If save succeeded, replace the original with what we just wrote
1025  if( !wxRenameFile( tempFile.GetFullPath(), pcbFileName.GetFullPath() ) )
1026  {
1027  DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n"
1028  "Failed to rename temporary file '%s." ),
1029  pcbFileName.GetFullPath(),
1030  tempFile.GetFullPath() ) );
1031 
1032  lowerTxt.Printf( _( "Failed to rename temporary file '%s'." ),
1033  tempFile.GetFullPath() );
1034 
1035  SetMsgPanel( upperTxt, lowerTxt );
1036 
1037  return false;
1038  }
1039 
1040  if( !Kiface().IsSingle() )
1041  {
1042  WX_STRING_REPORTER backupReporter( &upperTxt );
1043 
1044  if( GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
1045  upperTxt.clear();
1046  }
1047 
1048  GetBoard()->SetFileName( pcbFileName.GetFullPath() );
1049 
1050  // Update the lock in case it was a Save As
1051  LockFile( pcbFileName.GetFullPath() );
1052 
1053  // Put the saved file in File History if requested
1054  if( addToHistory )
1055  UpdateFileHistory( GetBoard()->GetFileName() );
1056 
1057  // Delete auto save file on successful save.
1058  wxFileName autoSaveFileName = pcbFileName;
1059 
1060  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + pcbFileName.GetName() );
1061 
1062  if( autoSaveFileName.FileExists() )
1063  wxRemoveFile( autoSaveFileName.GetFullPath() );
1064 
1065  lowerTxt.Printf( _( "File '%s' saved." ), pcbFileName.GetFullPath() );
1066 
1067  SetStatusText( lowerTxt, 0 );
1068 
1069  // Get rid of the old version conversion warning, or any other dismissable warning :)
1071 
1072  if( m_infoBar->IsShown() && m_infoBar->HasCloseButton() )
1073  m_infoBar->Dismiss();
1074 
1075  GetScreen()->SetContentModified( false );
1076  UpdateTitle();
1077  return true;
1078 }
1079 
1080 
1081 bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName, bool aCreateProject )
1082 {
1083  wxFileName pcbFileName = aFileName;
1084 
1085  // Ensure the file ext is the right ext:
1086  pcbFileName.SetExt( KiCadPcbFileExtension );
1087 
1088  if( !IsWritable( pcbFileName ) )
1089  {
1090  DisplayError( this, wxString::Format( _( "No access rights to write to file '%s'." ),
1091  pcbFileName.GetFullPath() ) );
1092  return false;
1093  }
1094 
1095  // Save various DRC parameters, such as violation severities (which may have been
1096  // edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
1098 
1100 
1101  try
1102  {
1104 
1105  wxASSERT( pcbFileName.IsAbsolute() );
1106 
1107  pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
1108  }
1109  catch( const IO_ERROR& ioe )
1110  {
1111  DisplayError( this, wxString::Format( _( "Error saving board file '%s'.\n%s" ),
1112  pcbFileName.GetFullPath(),
1113  ioe.What() ) );
1114 
1115  return false;
1116  }
1117 
1118  wxFileName projectFile( pcbFileName );
1119  wxFileName rulesFile( pcbFileName );
1120  wxString msg;
1121 
1122  projectFile.SetExt( ProjectFileExtension );
1123  rulesFile.SetExt( DesignRulesFileExtension );
1124 
1125  if( aCreateProject && !projectFile.FileExists() )
1126  GetSettingsManager()->SaveProjectCopy( projectFile.GetFullPath() );
1127 
1128  wxFileName currentRules( GetDesignRulesPath() );
1129 
1130  if( aCreateProject && currentRules.FileExists() && !rulesFile.FileExists() )
1131  KiCopyFile( currentRules.GetFullPath(), rulesFile.GetFullPath(), msg );
1132 
1133  if( !msg.IsEmpty() )
1134  {
1135  DisplayError( this, wxString::Format( _( "Error saving custom rules file '%s'." ),
1136  rulesFile.GetFullPath() ) );
1137  }
1138 
1139  DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n\"%s\"" ),
1140  pcbFileName.GetFullPath() ) );
1141 
1142  return true;
1143 }
1144 
1145 
1147 {
1148  wxFileName tmpFileName;
1149 
1150  // Don't run autosave if content has not been modified
1151  if( !IsContentModified() )
1152  return true;
1153 
1154  wxString title = GetTitle(); // Save frame title, that can be modified by the save process
1155 
1156  if( GetBoard()->GetFileName().IsEmpty() )
1157  {
1158  tmpFileName = wxFileName( PATHS::GetDefaultUserProjectsPath(), NAMELESS_PROJECT,
1160  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1161  }
1162  else
1163  {
1164  tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
1165  }
1166 
1167  wxFileName autoSaveFileName = tmpFileName;
1168 
1169  // Auto save file name is the board file name prepended with autosaveFilePrefix string.
1170  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + autoSaveFileName.GetName() );
1171 
1172  if( !autoSaveFileName.IsOk() )
1173  return false;
1174 
1175  // If the board file path is not writable, try writing to a platform specific temp file
1176  // path. If that path isn't writable, give up.
1177  if( !autoSaveFileName.IsDirWritable() )
1178  {
1179  autoSaveFileName.SetPath( wxFileName::GetTempDir() );
1180 
1181  if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
1182  return false;
1183  }
1184 
1185  wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" );
1186 
1187  if( SavePcbFile( autoSaveFileName.GetFullPath(), false, false ) )
1188  {
1190  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1191  UpdateTitle();
1192  m_autoSaveState = false;
1193 
1194  if( !Kiface().IsSingle() &&
1195  GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
1196  {
1198  }
1199 
1200  SetTitle( title ); // Restore initial frame title
1201 
1202  return true;
1203  }
1204 
1205  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
1206 
1207  SetTitle( title ); // Restore initial frame title
1208 
1209  return false;
1210 }
1211 
1212 
1213 bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
1214 {
1215  switch( (IO_MGR::PCB_FILE_T) aFileType )
1216  {
1218  case IO_MGR::EAGLE:
1219  return OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
1221 
1222  default:
1223  return false;
1224  }
1225 
1226  return false;
1227 }
1228 
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
void UpdateTitle()
Set the main window title bar text.
Plugin class for import plugins that support remappable layers.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
LSET m_VisibleLayers
Board settings.
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: infobar.cpp:134
void BuildListOfNets()
Definition: board.h:663
void SetModified()
Definition: eda_item.cpp:65
void OnModify() override
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:207
void SetCopperEdgeClearance(int aDistance)
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
#define KICTL_IMPORT_LIB
import all footprints into a project library.
Definition: kiway_player.h:83
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:267
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
Definition: board.h:268
void SetMruPath(const wxString &aPath)
bool importFile(const wxString &aFileName, int aFileType)
Load the given filename but sets the path to the current project path.
bool IsContentModified() const override
Get if the current board has been modified but not saved.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
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:118
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
EDA_3D_VIEWER_FRAME * Get3DViewerFrame()
Hold a record identifying a library accessed by the appropriate footprint library PLUGIN object in th...
Definition: fp_lib_table.h:40
void Compile_Ratsnest(bool aDisplayStatus)
Create the entire board ratsnest.
Definition: ratsnest.cpp:40
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.
void SaveProjectAs(const wxString &aFullPath)
Sets the currently loaded project path and saves it (pointers remain valid) Note that this will not m...
const std::string ProjectFileExtension
const std::string LegacyPcbFileExtension
virtual BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Load information from some input file format that this PLUGIN implementation knows about into either ...
Definition: plugin.cpp:46
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
bool doAutoSave() override
Perform auto save when the board has been modified and not saved within the auto save interval.
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:145
#define KICTL_CREATE
caller thinks requested project files may not exist.
Definition: kiway_player.h:82
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.
const std::string DesignRulesFileExtension
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
Definition: project.h:38
FOOTPRINT_LIST_IMPL GFootprintList
The global footprint info table.
Definition: pcbnew.cpp:227
bool LoadProjectSettings()
Load the current project's file configuration settings which are pertinent to this PCB_EDIT_FRAME ins...
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition: gestfich.cpp:363
void ReleaseFile()
Release the current file marked in use.
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Test a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:624
CREATE_PROJECT_CHECKBOX(wxWindow *aParent)
NET_SETTINGS & NetSettings()
Definition: project_file.h:94
bool SavePcbCopy(const wxString &aFileName, bool aCreateProject=false)
Write the board data structures to aFileName.
#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:81
This is the end of the layers used for visibility bit masks in Pcbnew.
const wxString & GetGenerator() const
Definition: board.h:292
int inferLegacyEdgeClearance(BOARD *aBoard)
wxString AltiumCircuitMakerPcbFileWildcard()
Collect all BOARD_ITEM objects on a given layer.
Definition: collectors.h:642
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
A name/value tuple with unique names and optional values.
Definition: properties.h:33
const wxString & GetFileName() const
Definition: board.h:228
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:588
std::unique_ptr< wxSingleInstanceChecker > m_file_checker
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:650
virtual void RegisterLayerMappingCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:271
This file contains miscellaneous commonly used macros and functions.
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
Definition: project.h:151
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetches the file name from the file history list.
bool HasCloseButton() const
Definition: infobar.cpp:311
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
Definition: richio.cpp:78
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:70
bool m_LegacyCopperEdgeClearanceLoaded
Definition: board.h:269
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:555
wxString FabmasterPcbFileWildcard()
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1488
void OnClearFileHistory(wxCommandEvent &aEvent)
wxString GetMruPath() const
virtual std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints()
Return a container with the cached library footprints generated in the last call to Load.
Definition: plugin.cpp:54
bool AskSaveBoardFileName(PCB_EDIT_FRAME *aParent, wxString *aFileName, bool *aCreateProject)
Put up a wxFileDialog asking for a BOARD filename to save.
wxString LegacyPcbFileWildcard()
unsigned GetCount() const
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: infobar.cpp:176
Multi-thread safe progress reporter dialog, intended for use of tasks that paralleize reporting back ...
void SaveProjectCopy(const wxString &aFullPath)
Saves a copy of the current project under the given path.
wxString CreateNewProjectLibrary(const wxString &aLibName=wxEmptyString, const wxString &aProposedName=wxEmptyString)
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...
bool AskLoadBoardFileName(PCB_EDIT_FRAME *aParent, int *aCtl, wxString *aFileName, bool aKicadFilesOnly)
Show a wxFileDialog asking for a BOARD filename to open.
#define NULL
bool IsSingle() const
Is this KIFACE_I running under single_top?
Definition: kiface_i.h:104
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Load a KiCad board (.kicad_pcb) from aFileName.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
Definition: eda_3d_viewer.h:62
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()
Update 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
Return a reference to the PROJECT associated with this KIWAY.
void ResolveNetClassAssignments(bool aRebuildFromScratch=false)
Explode the list of netclass assignments to include atomic members of composite labels (buses).
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void SaveProjectSettings() override
Save changes to the project settings to the project (.pro) file.
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Definition: wx_filename.cpp:85
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:1481
Definition of file extensions used in Kicad.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
#define _(s)
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()
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:136
void SetFileName(const wxString &aFileName)
Definition: board.h:226
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:117
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:135
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:287
wxString AltiumDesignerPcbFileWildcard()
wxCheckBox * m_cbCreateProject
void ClearProject()
Definition: board.cpp:172
int GetFileFormatVersionAtLoad() const
Definition: board.h:289
A wrapper for reporting to a wxString object.
Definition: reporter.h:159
void DismissOutdatedSave()
Dismisses the infobar for outdated save warnings and updates the containing layout and AUI manager (i...
Definition: infobar.cpp:167
virtual FP_LIB_TABLE * PcbFootprintLibs(KIWAY &aKiway)
Return the table of footprint libraries.
Definition: project.cpp:285
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)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
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)
Link a board to a given project.
Definition: board.cpp:142
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:130
static std::map< wxString, PCB_LAYER_ID > GetMapModal(wxWindow *aParent, const std::vector< INPUT_LAYER_DESC > &aLayerDesc)
Create and show a dialog (modal) and returns the data from it after completion.
void OnFileHistory(wxCommandEvent &event)
virtual void SetReadOnly(bool aReadOnly=true)
Definition: project.h:126
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:156
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:55
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Write the board data structures to a aFileName.
void SetBoard(BOARD *aBoard) override
Declaration of the eda_3d_viewer class.
const char * name
Definition: DXF_plotter.cpp:59
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
WX_INFOBAR * m_infoBar
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
void Files_io(wxCommandEvent &event)
Call Files_io_from_id with the wxCommandEvent id.
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapset time (in microsecondes) to class PROF_COUNTER.
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
static TOOL_ACTION repairBoard
Definition: pcb_actions.h:443
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
A base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:269
#define NAMELESS_PROJECT
default name for nameless projects
Definition: project.h:41
bool SaveProject(const wxString &aFullPath=wxEmptyString)
Saves a loaded project.
The main frame for Pcbnew.
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.
OUTDATED_SAVE Messages that should be cleared on save.
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)
Read and write board files according to aId.
WX_INFOBAR * GetInfoBar()
void ReadCacheFromFile(const wxString &aFilePath) override
static REPORTER & GetInstance()
Definition: reporter.cpp:108
BOARD * GetBoard() const
wxString CadstarPcbArchiveFileWildcard()
Message panel definition file.
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:53
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:280
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
wxString PCadPcbFileWildcard()
bool Clear_Pcb(bool aQuery, bool aFinal=false)
Delete all and reinitialize the current board.
Definition: initpcb.cpp:43
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:296
bool IsEmpty() const
Definition: board.h:281
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
Definition: board.h:264
virtual const wxString FootprintLibTblName() const
Returns the path and filename of this project's footprint library table.
Definition: project.cpp:147
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
bool empty() const
Definition: utf8.h:103
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
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:58
S-expression Pcbnew file format.
Definition: io_mgr.h:56
static const wxString GetFileExtension(PCB_FILE_T aFileType)
Return the file extension for aFileType.
Definition: io_mgr.cpp:109
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
Definition: infobar.cpp:277
GAL_SET m_LegacyVisibleItems
Definition: board.h:265