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-2017 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 
31 #include <fctsys.h>
32 #include <class_drawpanel.h>
33 #include <confirm.h>
34 #include <kicad_string.h>
35 #include <gestfich.h>
36 #include <wxPcbStruct.h>
37 #include <macros.h>
39 #include <richio.h>
40 #include <filter_reader.h>
41 #include <pgm_base.h>
42 #include <msgpanel.h>
43 #include <fp_lib_table.h>
44 #include <ratsnest_data.h>
45 #include <kiway.h>
46 #include <kiway_player.h>
47 
48 #include <pcbnew.h>
49 #include <pcbnew_id.h>
50 #include <io_mgr.h>
52 
53 #include <class_board.h>
54 #include <build_version.h> // LEGACY_BOARD_FILE_VERSION
55 #include <module_editor_frame.h>
56 #include <modview_frame.h>
57 
58 #include <wx/stdpaths.h>
59 
60 
61 //#define USE_INSTRUMENTATION 1
62 #define USE_INSTRUMENTATION 0
63 
64 
65 static const wxChar backupSuffix[] = wxT( "-bak" );
66 static const wxChar autosavePrefix[] = wxT( "_autosave-" );
67 
68 
70 {
71  return wxString( autosavePrefix );
72 }
73 
74 
87 bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bool aKicadFilesOnly )
88 {
89  // This is a subset of all PLUGINs which are trusted to be able to
90  // load a BOARD. User may occasionally use the wrong plugin to load a
91  // *.brd file (since both legacy and eagle use *.brd extension),
92  // but eventually *.kicad_pcb will be more common than legacy *.brd files.
93  static const struct
94  {
95  const wxString& filter;
96  IO_MGR::PCB_FILE_T pluginType;
97  } loaders[] =
98  {
99  { PcbFileWildcard(), IO_MGR::KICAD_SEXP }, // Current Kicad board files
100  { LegacyPcbFileWildcard(), IO_MGR::LEGACY }, // Old Kicad board files
101  { EaglePcbFileWildcard(), IO_MGR::EAGLE }, // Import board files
102  { PCadPcbFileWildcard(), IO_MGR::PCAD }, // Import board files
103  };
104 
105  wxFileName fileName( *aFileName );
106  wxString fileFilters;
107 
108  if( aKicadFilesOnly )
109  {
110  for( unsigned ii = 0; ii < 2; ++ii )
111  {
112  if( !fileFilters.IsEmpty() )
113  fileFilters += wxChar( '|' );
114 
115  fileFilters += wxGetTranslation( loaders[ii].filter );
116  }
117  }
118  else
119  {
120  for( unsigned ii = 2; ii < DIM( loaders ); ++ii )
121  {
122  if( !fileFilters.IsEmpty() )
123  fileFilters += wxChar( '|' );
124 
125  fileFilters += wxGetTranslation( loaders[ii].filter );
126  }
127  }
128 
129  wxString path;
130  wxString name;
131 
132  if( fileName.FileExists() )
133  {
134  path = fileName.GetPath();
135  name = fileName.GetFullName();
136  }
137  else
138  {
139  path = wxStandardPaths::Get().GetDocumentsDir();
140  // leave name empty
141  }
142 
143  wxFileDialog dlg( aParent,
144  aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
145  path, name, fileFilters,
146  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
147 
148  if( dlg.ShowModal() == wxID_OK )
149  {
150  // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
151  // It's the only special case because of the duplicate use of the *.brd file extension.
152  // Other cases are clear because of unique file extensions.
153  *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
154  *aFileName = dlg.GetPath();
155  return true;
156  }
157  else
158  return false;
159 }
160 
161 
172 bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName )
173 {
174  wxString wildcard = PcbFileWildcard();
175  wxFileName fn = *aFileName;
176 
177  fn.SetExt( KiCadPcbFileExtension );
178 
179  wxFileDialog dlg( aParent,
180  _( "Save Board File As" ),
181  fn.GetPath(),
182  fn.GetFullName(),
183  wildcard,
184  wxFD_SAVE | wxFD_OVERWRITE_PROMPT
185  );
186 
187  if( dlg.ShowModal() != wxID_OK )
188  return false;
189 
190  fn = dlg.GetPath();
191 
192  // always enforce filename extension, user may not have entered it.
193  fn.SetExt( KiCadPcbFileExtension );
194 
195  *aFileName = fn.GetFullPath();
196 
197  return true;
198 }
199 
200 
201 void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event )
202 {
203  wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) );
204 
205  if( !!fn )
206  {
207  int open_ctl = 0;
208 
210 
211  if( !wxFileName::IsFileReadable( fn ) )
212  {
213  if( !AskLoadBoardFileName( this, &open_ctl, &fn, true ) )
214  return;
215  }
216 
217  OpenProjectFiles( std::vector<wxString>( 1, fn ), open_ctl );
218  }
219 }
220 
221 
222 void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event )
223 {
224  int id = event.GetId();
225  Files_io_from_id( id );
226 }
227 
229 {
230  wxString msg;
231 
232  // If an edition is in progress, stop it.
233  // For something else than save, get rid of current tool.
234  if( id == ID_SAVE_BOARD )
236  else
238 
239  switch( id )
240  {
241  case ID_LOAD_FILE:
242  {
243  int open_ctl = 0;
244  wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
245 
246  if( !AskLoadBoardFileName( this, &open_ctl, &fileName, true ) )
247  return;
248 
249  OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
250  }
251  break;
252 
254  {
255  int open_ctl = 1;
256  wxString fileName;// = Prj().AbsolutePath( GetBoard()->GetFileName() );
257 
258  if( !AskLoadBoardFileName( this, &open_ctl, &fileName, false ) )
259  return;
260 
261  OpenProjectFiles( std::vector<wxString>( 1, fileName ), open_ctl );
262  }
263  break;
264 
267  {
268  wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() );
269  wxFileName fn = currfn;
270 
272  {
273  wxString rec_name = wxString( autosavePrefix ) + fn.GetName();
274  fn.SetName( rec_name );
275  }
276  else
277  {
278  wxString backup_ext = fn.GetExt()+ backupSuffix;
279  fn.SetExt( backup_ext );
280  }
281 
282  if( !fn.FileExists() )
283  {
284  msg.Printf( _( "Recovery file '%s' not found." ),
285  GetChars( fn.GetFullPath() ) );
286  DisplayInfoMessage( this, msg );
287  break;
288  }
289 
290  msg.Printf( _( "OK to load recovery or backup file '%s'" ),
291  GetChars(fn.GetFullPath() ) );
292 
293  if( !IsOK( this, msg ) )
294  break;
295 
296  GetScreen()->ClrModify(); // do not prompt the user for changes
297 
298  // LoadOnePcbFile( fn.GetFullPath(), aAppend=false, aForceFileDialog=false );
299  OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
300 
301  // Re-set the name since name or extension was changed
302  GetBoard()->SetFileName( currfn.GetFullPath() );
303  UpdateTitle();
304  }
305  break;
306 
307  case ID_APPEND_FILE:
308  {
309  int open_ctl;
310  wxString fileName;
311 
312  if( !AskLoadBoardFileName( this, &open_ctl, &fileName, true ) )
313  break;
314 
315  AppendBoardFile( fileName, open_ctl );
316 
317  m_canvas->Refresh();
318  }
319  break;
320 
321  case ID_NEW_BOARD:
322  {
323  if( !Clear_Pcb( true ) )
324  break;
325 
326  wxFileName fn( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
328 
329  Prj().SetProjectFullName( fn.GetFullPath() );
330 
331  fn.SetExt( PcbFileExtension );
332 
333  GetBoard()->SetFileName( fn.GetFullPath() );
334  UpdateTitle();
336  OnModify();
337  break;
338  }
339 
340  case ID_SAVE_BOARD:
341  if( ! GetBoard()->GetFileName().IsEmpty() )
342  {
343  SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) );
344  break;
345  }
346  // Fall through
347  case ID_COPY_BOARD_AS:
348  case ID_SAVE_BOARD_AS:
349  {
350  wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
351  wxFileName fn( pro_dir, _( "noname" ), KiCadPcbFileExtension );
352  wxString filename = fn.GetFullPath();
353 
354  if( AskSaveBoardFileName( this, &filename ) )
355  {
356  if( id == ID_COPY_BOARD_AS )
357  SavePcbCopy( filename );
358  else
359  SavePcbFile( filename, NO_BACKUP_FILE );
360  }
361  }
362  break;
363 
364  default:
365  DisplayError( this, wxT( "File_io Internal Error" ) );
366  break;
367  }
368 }
369 
370 
371 // The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so
372 // determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD
373 // bit flag.
374 IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
375 {
376  IO_MGR::PCB_FILE_T pluginType;
377 
378  wxFileName fn = aFileName;
379 
380  // Note: file extensions are expected to be in ower case.
381  // This is not always true, especially when importing files, so the string
382  // comparisons are case insensitive to try to find the suitable plugin.
383 
384  if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
385  {
386  // both legacy and eagle share a common file extension.
387  pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY;
388  }
389  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) + backupSuffix ) == 0 )
390  {
391  pluginType = IO_MGR::LEGACY;
392  }
393  else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
394  {
395  pluginType = IO_MGR::PCAD;
396  }
397  else
398  {
399  pluginType = IO_MGR::KICAD_SEXP;
400  }
401 
402  return pluginType;
403 }
404 
405 
406 bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
407 {
408  // This is for python:
409  if( aFileSet.size() != 1 )
410  {
411  UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ );
412  DisplayError( this, msg );
413  return false;
414  }
415 
416  wxString fullFileName( aFileSet[0] );
417 
418  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
419  wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
420  wxT( "bug in single_top.cpp or project manager." ) );
421 
422  if( !LockFile( fullFileName ) )
423  {
424  wxString msg = wxString::Format( _(
425  "PCB file '%s' is already open." ),
426  GetChars( fullFileName )
427  );
428  DisplayError( this, msg );
429  return false;
430  }
431 
432  if( GetScreen()->IsModify() )
433  {
434  int response = YesNoCancelDialog( this, _(
435  "The current board has been modified. Do you wish to save the changes?" ),
436  wxEmptyString,
437  _( "Save and Load" ),
438  _( "Load Without Saving" )
439  );
440 
441  if( response == wxID_CANCEL )
442  return false;
443  else if( response == wxID_YES )
444  SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE );
445  else
446  {
447  // response == wxID_NO, fall thru
448  }
449  }
450 
451  wxFileName pro = fullFileName;
452  pro.SetExt( ProjectFileExtension );
453 
454  bool is_new = !wxFileName::IsFileReadable( fullFileName );
455 
456  // If its a non-existent schematic and caller thinks it exists
457  if( is_new && !( aCtl & KICTL_CREATE ) )
458  {
459  // notify user that fullFileName does not exist, ask if user wants to create it.
460  wxString ask = wxString::Format( _(
461  "Board '%s' does not exist. Do you wish to create it?" ),
462  GetChars( fullFileName )
463  );
464  if( !IsOK( this, ask ) )
465  return false;
466  }
467 
468  Clear_Pcb( false ); // pass false since we prompted above for a modified board
469 
470  IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
471 
472  bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
473 
474  if( !converted )
475  {
476  // PROJECT::SetProjectFullName() is an impactful function. It should only be
477  // called under carefully considered circumstances.
478 
479  // The calling code should know not to ask me here to change projects unless
480  // it knows what consequences that will have on other KIFACEs running and using
481  // this same PROJECT. It can be very harmful if that calling code is stupid.
482  Prj().SetProjectFullName( pro.GetFullPath() );
483 
484  // load project settings before BOARD
486  }
487 
488  if( is_new )
489  {
490  OnModify();
491  }
492  else
493  {
494  BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK
495 
496  PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
497 
498  try
499  {
500  PROPERTIES props;
501  char xbuf[30];
502  char ybuf[30];
503 
504  // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
505  sprintf( xbuf, "%d", GetPageSizeIU().x );
506  sprintf( ybuf, "%d", GetPageSizeIU().y );
507 
508  props["page_width"] = xbuf;
509  props["page_height"] = ybuf;
510 
511 #if USE_INSTRUMENTATION
512  // measure the time to load a BOARD.
513  unsigned startTime = GetRunningMicroSecs();
514 #endif
515 
516  loadedBoard = pi->Load( fullFileName, NULL, &props );
517 
518 #if USE_INSTRUMENTATION
519  unsigned stopTime = GetRunningMicroSecs();
520  printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime );
521 #endif
522  }
523  catch( const IO_ERROR& ioe )
524  {
525  DisplayErrorMessage( this,
526  wxString::Format( _( "Error loading board file:\n%s" ), fullFileName ),
527  ioe.What() );
528  return false;
529  }
530 
531  SetBoard( loadedBoard );
532 
533  // we should not ask PLUGINs to do these items:
534  loadedBoard->BuildListOfNets();
535  loadedBoard->SynchronizeNetsAndNetClasses();
536 
537  SetStatusText( wxEmptyString );
538  BestZoom();
539 
540  // update the layer names in the listbox
541  ReCreateLayerBox( false );
542 
543  GetScreen()->ClrModify();
544 
545  {
546  wxFileName fn = fullFileName;
547  CheckForAutoSaveFile( fullFileName, fn.GetExt() );
548  }
549 
550  if( pluginType == IO_MGR::LEGACY &&
551  loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION )
552  {
553  DisplayInfoMessage( this,
554  _( "This file was created by an older version of Pcbnew.\n"
555  "It will be stored in the new file format when you save this file again." ) );
556  }
557  }
558 
559  {
560  wxFileName fn = fullFileName;
561 
562  if( converted )
563  fn.SetExt( PcbFileExtension );
564 
565  wxString fname = fn.GetFullPath();
566 
567  fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
568 
569  GetBoard()->SetFileName( fname );
570  }
571 
572  UpdateTitle();
573 
574  if( !converted )
575  UpdateFileHistory( GetBoard()->GetFileName() );
576 
577  // Rebuild the new pad list (for drc and ratsnet control ...)
578  GetBoard()->m_Status_Pcb = 0;
579 
580  // Select netclass Default as current netclass (it always exists)
582 
583  // Rebuild list of nets (full ratsnest rebuild)
584  Compile_Ratsnest( NULL, true );
586 
587  // Update info shown by the horizontal toolbars
590 
591  // upate the layer widget to match board visibility states, both layers and render columns.
595 
596  // Update the tracks / vias available sizes list:
598 
599  // Update the RATSNEST items, which were not loaded at the time
600  // BOARD::SetVisibleElements() was called from within any PLUGIN.
601  // See case LAYER_RATSNEST: in BOARD::SetElementVisibility()
602  GetBoard()->SetVisibleElements( GetBoard()->GetVisibleElements() );
603 
604  // Display the loaded board:
605  Zoom_Automatique( false );
606 
607  SetMsgPanel( GetBoard() );
608 
609  // Refresh the 3D view, if any
610  EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
611 
612  if( draw3DFrame )
613  draw3DFrame->NewDisplay();
614 
615 #if 0 && defined(DEBUG)
616  // Output the board object tree to stdout, but please run from command prompt:
617  GetBoard()->Show( 0, std::cout );
618 #endif
619 
620  // from EDA_APPL which was first loaded BOARD only:
621  {
622  /* For an obscure reason the focus is lost after loading a board file
623  * when starting up the process.
624  * (seems due to the recreation of the layer manager after loading the file)
625  * Give focus to main window and Drawpanel
626  * must be done for these 2 windows (for an obscure reason ...)
627  * Linux specific
628  * This is more a workaround than a fix.
629  */
630  SetFocus();
631  GetCanvas()->SetFocus();
632  }
633 
634  return true;
635 }
636 
637 
638 static wxString create_backup_file( const wxString& aFileName )
639 {
640  wxFileName fn = aFileName;
641  wxFileName backupFileName = aFileName;
642 
643  backupFileName.SetExt( fn.GetExt() + backupSuffix );
644 
645  // If an old backup file exists, delete it. If an old board file exists,
646  // rename it to the backup file name.
647  if( fn.FileExists() )
648  {
649  // Remove the old file xxx.000 if it exists.
650  if( backupFileName.FileExists() )
651  wxRemoveFile( backupFileName.GetFullPath() );
652 
653  // Rename the current file from <xxx>.kicad_pcb to <xxx>.kicad_pcb-bak
654  if( !wxRenameFile( fn.GetFullPath(), backupFileName.GetFullPath() ) )
655  {
656  wxString msg = wxString::Format( _(
657  "Warning: unable to create backup file '%s'" ),
658  GetChars( backupFileName.GetFullPath() )
659  );
660  DisplayError( NULL, msg );
661  }
662  }
663  else
664  {
665  backupFileName.Clear();
666  }
667 
668  return backupFileName.GetFullPath();
669 }
670 
671 
672 bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupFile )
673 {
674  // please, keep it simple. prompting goes elsewhere.
675 
676  wxFileName pcbFileName = aFileName;
677 
678  if( pcbFileName.GetExt() == LegacyPcbFileExtension )
679  pcbFileName.SetExt( KiCadPcbFileExtension );
680 
681  if( !IsWritable( pcbFileName ) )
682  {
683  wxString msg = wxString::Format( _(
684  "No access rights to write to file '%s'" ),
685  GetChars( pcbFileName.GetFullPath() )
686  );
687 
688  DisplayError( this, msg );
689  return false;
690  }
691 
692  wxString backupFileName;
693 
694  // aCreateBackupFile == false is mainly used to write autosave files
695  // or new files in save as... command
696  if( aCreateBackupFile )
697  {
698  backupFileName = create_backup_file( aFileName );
699  }
700 
702 
703  // Select default Netclass before writing file.
704  // Useful to save default values in headers
706 
707  ClearMsgPanel();
708 
709  wxString upperTxt;
710  wxString lowerTxt;
711 
712  try
713  {
715 
716  wxASSERT( pcbFileName.IsAbsolute() );
717 
718  pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
719  }
720  catch( const IO_ERROR& ioe )
721  {
722  wxString msg = wxString::Format( _(
723  "Error saving board file '%s'.\n%s" ),
724  GetChars( pcbFileName.GetFullPath() ),
725  GetChars( ioe.What() )
726  );
727  DisplayError( this, msg );
728 
729  lowerTxt.Printf( _( "Failed to create '%s'" ), GetChars( pcbFileName.GetFullPath() ) );
730 
731  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
732 
733  return false;
734  }
735 
736  GetBoard()->SetFileName( pcbFileName.GetFullPath() );
737  UpdateTitle();
738 
739  // Put the saved file in File History, unless aCreateBackupFile
740  // is false.
741  // aCreateBackupFile == false is mainly used to write autosave files
742  // and not need to have an autosave file in file history
743  if( aCreateBackupFile )
744  UpdateFileHistory( GetBoard()->GetFileName() );
745 
746  // Delete auto save file on successful save.
747  wxFileName autoSaveFileName = pcbFileName;
748 
749  autoSaveFileName.SetName( wxString( autosavePrefix ) + pcbFileName.GetName() );
750 
751  if( autoSaveFileName.FileExists() )
752  wxRemoveFile( autoSaveFileName.GetFullPath() );
753 
754  if( !!backupFileName )
755  upperTxt.Printf( _( "Backup file: '%s'" ), GetChars( backupFileName ) );
756 
757  lowerTxt.Printf( _( "Wrote board file: '%s'" ), GetChars( pcbFileName.GetFullPath() ) );
758 
759  AppendMsgPanel( upperTxt, lowerTxt, CYAN );
760 
761  GetScreen()->ClrModify();
762  GetScreen()->ClrSave();
763  return true;
764 }
765 
766 
767 bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName )
768 {
769  wxFileName pcbFileName = aFileName;
770 
771  // Ensure the file ext is the right ext:
772  pcbFileName.SetExt( KiCadPcbFileExtension );
773 
774  if( !IsWritable( pcbFileName ) )
775  {
776  wxString msg = wxString::Format( _(
777  "No access rights to write to file '%s'" ),
778  GetChars( pcbFileName.GetFullPath() )
779  );
780 
781  DisplayError( this, msg );
782  return false;
783  }
784 
786 
787  // Select default Netclass before writing file.
788  // Useful to save default values in headers
790 
791  try
792  {
794 
795  wxASSERT( pcbFileName.IsAbsolute() );
796 
797  pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
798  }
799  catch( const IO_ERROR& ioe )
800  {
801  wxString msg = wxString::Format( _(
802  "Error saving board file '%s'.\n%s" ),
803  GetChars( pcbFileName.GetFullPath() ),
804  GetChars( ioe.What() )
805  );
806  DisplayError( this, msg );
807 
808  return false;
809  }
810 
811  DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n'%s'" ),
812  GetChars( pcbFileName.GetFullPath() ) ) );
813 
814  return true;
815 }
816 
817 
819 {
820  wxFileName tmpFileName;
821 
822  if( GetBoard()->GetFileName().IsEmpty() )
823  {
824  tmpFileName = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
826  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
827  }
828  else
829  {
830  tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() );
831  }
832 
833  wxFileName autoSaveFileName = tmpFileName;
834 
835  // Auto save file name is the board file name prepended with autosaveFilePrefix string.
836  autoSaveFileName.SetName( wxString( autosavePrefix ) + autoSaveFileName.GetName() );
837 
838  if( !autoSaveFileName.IsOk() )
839  return false;
840 
841  // If the board file path is not writable, try writing to a platform specific temp file
842  // path. If that path isn't writabe, give up.
843  if( !autoSaveFileName.IsDirWritable() )
844  {
845  autoSaveFileName.SetPath( wxFileName::GetTempDir() );
846 
847  if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() )
848  return false;
849  }
850 
851  wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" );
852 
853  if( SavePcbFile( autoSaveFileName.GetFullPath(), NO_BACKUP_FILE ) )
854  {
855  GetScreen()->SetModify();
856  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
857  UpdateTitle();
858  m_autoSaveState = false;
859  return true;
860  }
861 
862  GetBoard()->SetFileName( tmpFileName.GetFullPath() );
863 
864  return false;
865 }
866 
867 
868 bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
869 {
870  switch( (IO_MGR::PCB_FILE_T) aFileType )
871  {
872  case IO_MGR::EAGLE:
873  if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
874  KICTL_EAGLE_BRD ) )
875  {
876  wxString projectpath = Kiway().Prj().GetProjectPath();
877  wxFileName newfilename = Prj().AbsolutePath( Prj().GetProjectName() );
878 
879  newfilename.SetExt( KiCadPcbFileExtension );
880 
881  GetBoard()->SetFileName( newfilename.GetFullPath() );
882  UpdateTitle();
883 
884  ArchiveModulesOnBoard( true, newfilename.GetName() );
885 
886  return true;
887  }
888 
889  return false;
890 
891  default:
892  return false;
893  }
894 
895  return false;
896 }
void syncRenderStates()
Function syncRenderStates updates the "Render" checkboxes in the layer widget according to current to...
Definition: pcbframe.cpp:914
void CheckForAutoSaveFile(const wxFileName &aFileName, const wxString &aBackupFileExtension)
Function CheckForAutoSaveFile checks if an auto save file exists for aFileName and takes the appropri...
Definition: basicframe.cpp:597
void UpdateTitle()
Function UpdateTitle sets the main window title bar text.
Definition: pcbframe.cpp:1033
Class UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion supp...
Definition: utf8.h:73
#define DIM(x)
of elements in an array
Definition: macros.h:98
bool m_autoSaveState
Flag to indicate the last auto save state.
Definition: wxstruct.h:155
void BuildListOfNets()
Definition: class_board.h:722
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
Definition: pcbframe.cpp:1001
Definition of class FOOTPRINT_EDIT_FRAME.
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
wxString EaglePcbFileWildcard()
void syncLayerWidgetLayer()
Function syncLayerWidgetLayer updates the currently layer "selection" within the PCB_LAYER_WIDGET.
Definition: pcbframe.cpp:907
virtual void Save(const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=NULL)
Function Save will write aBoard to a storage file in a format that this PLUGIN implementation knows a...
Definition: plugin.cpp:54
static wxString GetAutoSaveFilePrefix()
Function GetAutoSaveFilePrefix.
This file is part of the common library TODO brief description.
IO_MGR::PCB_FILE_T plugin_type(const wxString &aFileName, int aCtl)
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:325
void SetVisibleElements(int aMask)
Function SetVisibleElements is a proxy function that calls the correspondent function in m_BoardSetti...
This file is part of the common library.
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:337
bool SavePcbCopy(const wxString &aFileName)
Function SavePcbCopy writes the board data structures to a aFileName but unlike SavePcbFile, does not make anything else (no backup, borad fliename change, no flag changes ...) Used under a project mgr to save under a new name the current board.
static wxString create_backup_file(const wxString &aFileName)
const wxString ProjectFileExtension
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
virtual bool doAutoSave() override
Function doAutoSave performs auto save when the board has been modified and not saved within the auto...
#define KICTL_CREATE
caller thinks requested project files may not exist
Definition: kiway_player.h:131
Class BOARD to handle a board.
const wxString LegacyPcbFileExtension
Class that computes missing connections on a PCB.
bool Clear_Pcb(bool aQuery)
Function Clear_Pcb delete all and reinitialize the current board.
Definition: initpcb.cpp:39
#define NO_BACKUP_FILE
Definition: wxstruct.h:60
void EndMouseCapture(int aId=-1, int aCursorId=-1, const wxString &aTitle=wxEmptyString, bool aCallEndFunc=true)
Function EndMouseCapture ends mouse a capture.
bool LoadProjectSettings()
Load the current project's file configuration settings which are pertinent to this PCB_EDIT_FRAME ins...
void ReCreateLayerBox(bool aForceResizeToolbar=true)
Re create the layer Box by clearing the old list, and building le new one, from the new layers names ...
Definition: tool_pcb.cpp:714
BOARD * GetBoard() const
#define KICTL_EAGLE_BRD
chosen *.brd file is Eagle according to user.
Definition: kiway_player.h:130
void syncLayerVisibilities()
Function syncLayerVisibilities updates each "Layer" checkbox in the layer widget according to each la...
Definition: pcbframe.cpp:920
bool IsWritable(const wxFileName &aFileName)
Function IsWritable checks if aFileName can be written.
Definition: basicframe.cpp:553
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
Definition: pcbframe.cpp:1163
Class PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
void UpdateFileHistory(const wxString &FullFileName, wxFileHistory *aFileHistory=NULL)
Function UpdateFileHistory Updates the list of recently opened files.
Definition: basicframe.cpp:407
This file contains miscellaneous commonly used macros and functions.
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
Class RELEASER releases a PLUGIN in the context of a potential thrown exception, through its destruct...
Definition: io_mgr.h:546
bool AppendBoardFile(const wxString &aFullFileName, int aCtl)
Function AppendBoardFile appends a board file onto the current one, creating God knows what...
void SynchronizeNetsAndNetClasses()
Function SynchronizeNetsAndNetClasses copies NETCLASS info to each NET, based on NET membership in a ...
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
static const struct @14 fileFilters[FILTER_COUNT]
void Zoom_Automatique(bool aWarpPointer)
Function Zoom_Automatique redraws the screen with best zoom level and the best centering that shows a...
Definition: zoom.cpp:77
wxString LegacyPcbFileWildcard()
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:87
void ArchiveModulesOnBoard(bool aStoreInNewLib, const wxString &aLibName=wxEmptyString)
Function ArchiveModulesOnBoard Save modules in a library:
Definition: librairi.cpp:591
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:784
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Function OpenProjectFiles (was LoadOnePcbFile) loads a KiCad board (.kicad_pcb) from aFileName...
static const char Default[]
the name of the default NETCLASS
VTBL_ENTRY PROJECT & Prj() const
Function Prj returns the PROJECT associated with this KIWAY.
Definition: kiway.cpp:144
bool AskLoadBoardFileName(wxWindow *aParent, int *aCtl, wxString *aFileName, bool aKicadFilesOnly)
Function AskLoadBoardFileName puts up a wxFileDialog asking for a BOARD filename to open...
Definition: colors.h:59
VTBL_ENTRY const wxString AbsolutePath(const wxString &aFileName) const
Function AbsolutePath fixes up aFileName if it is relative to the project's directory to be an absolu...
Definition: project.cpp:382
The common library.
static const wxChar backupSuffix[]
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:104
#define PcbFileExtension
void BuildConnectivity()
Builds or rebuilds the board connectivity database for the board, especially the list of connected it...
void SetFileName(const wxString &aFileName)
Definition: class_board.h:232
VTBL_ENTRY void SetProjectFullName(const wxString &aFullPathAndName)
Function SetProjectFullName sets the: 1) full directory, 2) basename, and 3) extension of the project...
Definition: project.cpp:65
int GetFileFormatVersionAtLoad() const
Definition: class_board.h:277
virtual double BestZoom() override
Function BestZoom.
void Compile_Ratsnest(wxDC *aDC, bool aDisplayStatus)
Function Compile_Ratsnest Create the entire board ratsnest.
Definition: ratsnest.cpp:56
static const wxChar autosavePrefix[]
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
void AppendMsgPanel(const wxString &textUpper, const wxString &textLower, COLOR4D color, int pad=6)
Append a message to the message panel.
Definition: draw_frame.cpp:764
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
void OnFileHistory(wxCommandEvent &event)
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:53
see class PGM_BASE
void SetBoard(BOARD *aBoard) override
>
Definition: pcbframe.cpp:503
Declaration of the eda_3d_viewer class.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
void Files_io(wxCommandEvent &event)
Function Files_io.
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Function PluginFind returns a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
#define CREATE_BACKUP_FILE
Definition: wxstruct.h:59
bool AskSaveBoardFileName(wxWindow *aParent, wxString *aFileName)
Function AskSaveBoardFileName puts up a wxFileDialog asking for a BOARD filename to save...
wxString GetFileFromHistory(int cmdId, const wxString &type, wxFileHistory *aFileHistory=NULL)
Function GetFileFromHistory fetches the file name from the file history list.
Definition: basicframe.cpp:419
bool ImportFile(const wxString &aFileName, int aFileType) override
Function ImportFile load the given filename but sets the path to the current project path...
wxString PcbFileWildcard()
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:102
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
const char * name
const wxSize GetPageSizeIU() const override
Function GetPageSizeIU works off of GetPageSettings() to return the size of the paper page in the int...
const wxString KiCadPcbFileExtension
Class EDA_3D_VIEWER Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard...
Definition: eda_3d_viewer.h:50
void ReFillLayerWidget()
Function ReFillLayerWidget changes out all the layers in m_Layers and may be called upon loading a ne...
Definition: pcbframe.cpp:578
void Files_io_from_id(int aId)
Function Files_io_from_id Read and write board files.
Message panel definition file.
int GetDefaultCursor() const
Function GetDefaultCursor.
PCB_FILE_T
Enum PCB_FILE_T is a set of file types that the IO_MGR knows about, and for which there has been a pl...
Definition: io_mgr.h:51
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
wxString PCadPcbFileWildcard()
EDA_3D_VIEWER * Get3DViewerFrame()
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:73
bool SavePcbFile(const wxString &aFileName, bool aCreateBackupFile=CREATE_BACKUP_FILE)
Function SavePcbFile writes the board data structures to a aFileName Creates backup when requested an...
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
int YesNoCancelDialog(wxWindow *aParent, const wxString &aPrimaryMessage, const wxString &aSecondaryMessage, const wxString &aYesButtonText, const wxString &aNoButtonText, const wxString &aCancelButtonText)
Function YesNoCancelDialog displays a yes/no/cancel dialog with aMessage and returns the user respons...
Definition: confirm.cpp:168
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:131
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:775
void ReCreateAuxiliaryToolbar() override
Definition: tool_pcb.cpp:546
bool LockFile(const wxString &aFileName)
Function LockFile marks a schematic file as being in use.
Definition: draw_frame.cpp:246
virtual BOARD * Load(const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=NULL)
Function Load loads information from some input file format that this PLUGIN implementation knows abo...
Definition: plugin.cpp:47
S-expression Pcbnew file format.
Definition: io_mgr.h:54
static const wxString GetFileExtension(PCB_FILE_T aFileType)
Function GetFileExtension returns the file extension for aFileType.
Definition: io_mgr.cpp:117
const wxChar traceAutoSave[]
Flag to enable auto save feature debug tracing.
Definition: basicframe.cpp:53
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237