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