KiCad PCB EDA Suite
eeschema/files-io.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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2013 CERN (www.cern.ch)
7  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <fctsys.h>
28 #include <sch_draw_panel.h>
29 #include <confirm.h>
30 #include <gestfich.h>
31 #include <sch_edit_frame.h>
32 #include <pgm_base.h>
33 #include <kiface_i.h>
34 #include <richio.h>
35 #include <trace_helpers.h>
36 #include <tool/tool_manager.h>
37 #include <id.h>
38 #include <class_library.h>
39 #include <lib_edit_frame.h>
40 #include <sch_sheet.h>
41 #include <sch_sheet_path.h>
42 #include <sch_component.h>
44 #include <project_rescue.h>
45 #include <eeschema_config.h>
46 #include <eeschema_settings.h>
47 #include <sch_legacy_plugin.h>
48 #include <sch_eagle_plugin.h>
49 #include <symbol_lib_table.h>
50 #include <dialog_symbol_remap.h>
51 #include <dialog_migrate_buses.h>
52 #include <ws_data_model.h>
53 #include <connection_graph.h>
54 #include <tool/actions.h>
55 
56 bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
57  bool aCreateBackupFile )
58 {
59  wxString msg;
60  wxFileName schematicFileName;
61  bool success;
62 
63  if( aScreen == NULL )
64  aScreen = GetScreen();
65 
66  // If no name exists in the window yet - save as new.
67  if( aScreen->GetFileName().IsEmpty() )
68  aSaveUnderNewName = true;
69 
70  // Construct the name of the file to be saved
71  schematicFileName = Prj().AbsolutePath( aScreen->GetFileName() );
72 
73  if( aSaveUnderNewName )
74  {
75  wxString wildcards = LegacySchematicFileWildcard();
76 
77  wildcards += "|" + KiCadSchematicFileWildcard();
78 
79  wxFileDialog dlg( this, _( "Schematic Files" ), wxPathOnly( Prj().GetProjectFullName() ),
80  schematicFileName.GetFullName(), wildcards,
81  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
82 
83  if( dlg.ShowModal() == wxID_CANCEL )
84  return false;
85 
86  schematicFileName = dlg.GetPath();
87 
88  if( dlg.GetFilterIndex() == 0
89  && schematicFileName.GetExt() != LegacySchematicFileExtension )
90  schematicFileName.SetExt( LegacySchematicFileExtension );
91  else if( dlg.GetFilterIndex() == 1
92  && schematicFileName.GetExt() != KiCadSchematicFileExtension )
93  schematicFileName.SetExt( KiCadSchematicFileExtension );
94  }
95 
96  if( !IsWritable( schematicFileName ) )
97  return false;
98 
99  // Create backup if requested
100  if( aCreateBackupFile && schematicFileName.FileExists() )
101  {
102  wxFileName backupFileName = schematicFileName;
103 
104  // Rename the old file to a '-bak' suffixed one:
105  backupFileName.SetExt( schematicFileName.GetExt() + GetBackupSuffix() );
106 
107  if( backupFileName.FileExists() )
108  wxRemoveFile( backupFileName.GetFullPath() );
109 
110  if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
111  {
112  msg.Printf( _( "Could not save backup of file \"%s\"" ),
113  GetChars( schematicFileName.GetFullPath() ) );
114  DisplayError( this, msg );
115  }
116  }
117 
118  // Save
119  wxLogTrace( traceAutoSave,
120  wxT( "Saving file <" ) + schematicFileName.GetFullPath() + wxT( ">" ) );
121 
122  SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromSchPath(
123  schematicFileName.GetFullPath() );
124  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( pluginType ) );
125 
126  try
127  {
128  pi->Save( schematicFileName.GetFullPath(), aScreen, &Kiway() );
129  success = true;
130  }
131  catch( const IO_ERROR& ioe )
132  {
133  msg.Printf( _( "Error saving schematic file \"%s\".\n%s" ),
134  GetChars( schematicFileName.GetFullPath() ), GetChars( ioe.What() ) );
135  DisplayError( this, msg );
136 
137  msg.Printf( _( "Failed to save \"%s\"" ), GetChars( schematicFileName.GetFullPath() ) );
138  AppendMsgPanel( wxEmptyString, msg, CYAN );
139 
140  success = false;
141  }
142 
143  if( success )
144  {
145  // Delete auto save file.
146  wxFileName autoSaveFileName = schematicFileName;
147  autoSaveFileName.SetName( GetAutoSaveFilePrefix() + schematicFileName.GetName() );
148 
149  if( autoSaveFileName.FileExists() )
150  {
151  wxLogTrace( traceAutoSave,
152  wxT( "Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
153  wxT( ">" ) );
154 
155  wxRemoveFile( autoSaveFileName.GetFullPath() );
156  }
157 
158  // Update the screen and frame info and reset the lock file.
159  if( aSaveUnderNewName )
160  {
161  aScreen->SetFileName( schematicFileName.GetFullPath() );
162  LockFile( schematicFileName.GetFullPath() );
163  }
164 
165  aScreen->ClrSave();
166  aScreen->ClrModify();
167 
168  msg.Printf( _( "File %s saved" ), GetChars( aScreen->GetFileName() ) );
169  SetStatusText( msg, 0 );
170  }
171  else
172  {
173  DisplayError( this, _( "File write operation failed." ) );
174  }
175 
176  return success;
177 }
178 
179 
180 void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
181 {
182  if( doSaveAs )
183  {
184  if( SaveEEFile( NULL, true ) )
186  }
187  else
188  {
189  SaveEEFile( NULL );
190  }
191 
192  UpdateTitle();
193 }
194 
195 
196 bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
197 {
198  // implement the pseudo code from KIWAY_PLAYER.h:
199 
200  // This is for python:
201  if( aFileSet.size() != 1 )
202  {
203  UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename.", __func__ );
204  DisplayError( this, msg );
205  return false;
206  }
207 
208  wxString fullFileName( aFileSet[0] );
209 
210  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
211  wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
212 
213  if( !LockFile( fullFileName ) )
214  {
215  wxString msg = wxString::Format( _( "Schematic file \"%s\" is already open." ),
216  fullFileName );
217  DisplayError( this, msg );
218  return false;
219  }
220 
221  if( !AskToSaveChanges() )
222  return false;
223 
224  wxFileName pro = fullFileName;
225  pro.SetExt( ProjectFileExtension );
226 
227  bool is_new = !wxFileName::IsFileReadable( fullFileName );
228 
229  // If its a non-existent schematic and caller thinks it exists
230  if( is_new && !( aCtl & KICTL_CREATE ) )
231  {
232  // notify user that fullFileName does not exist, ask if user wants to create it.
233  wxString ask = wxString::Format( _( "Schematic \"%s\" does not exist. Do you wish to create it?" ),
234  fullFileName );
235  if( !IsOK( this, ask ) )
236  return false;
237  }
238 
239  // unload current project file before loading new
240  {
241  SetScreen( nullptr );
242  delete g_RootSheet;
243  if( g_CurrentSheet )
245  g_RootSheet = nullptr;
246 
247  CreateScreens();
248  }
249 
250  GetScreen()->SetFileName( fullFileName );
251  g_RootSheet->SetFileName( fullFileName );
252 
253  SetStatusText( wxEmptyString );
254  ClearMsgPanel();
255 
256  // PROJECT::SetProjectFullName() is an impactful function. It should only be
257  // called under carefully considered circumstances.
258 
259  // The calling code should know not to ask me here to change projects unless
260  // it knows what consequences that will have on other KIFACEs running and using
261  // this same PROJECT. It can be very harmful if that calling code is stupid.
262 
263  // Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
264  // They are already saved in the kiface project object.
265  if( pro.GetFullPath() != Prj().GetProjectFullName()
267  {
268  Prj().SetProjectFullName( pro.GetFullPath() );
269 
270  // load the libraries here, not in SCH_SCREEN::Draw() which is a context
271  // that will not tolerate DisplayError() dialog since we're already in an
272  // event handler in there.
273  // And when a schematic file is loaded, we need these libs to initialize
274  // some parameters (links to PART LIB, dangling ends ...)
276  Prj().SchLibs();
277  }
278 
279  LoadProjectFile();
280 
281  // Load the symbol library table, this will be used forever more.
283  Prj().SchSymbolLibTable();
284 
285  SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) );
286 
287  if( is_new )
288  {
289  // mark new, unsaved file as modified.
290  GetScreen()->SetModify();
291  }
292  else
293  {
294  SetScreen( nullptr );
295  delete g_RootSheet; // Delete the current project.
296  g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
297 
298  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
299 
300  // This will rename the file if there is an autosave and the user want to recover
301  CheckForAutoSaveFile( fullFileName );
302 
303  try
304  {
305  g_RootSheet = pi->Load( fullFileName, &Kiway() );
306 
310 
311  if( !pi->GetError().IsEmpty() )
312  {
313  DisplayErrorMessage( this,
314  _( "The entire schematic could not be loaded. Errors "
315  "occurred attempting to load \nhierarchical sheet "
316  "schematics." ),
317  pi->GetError() );
318  }
319  }
320  catch( const IO_ERROR& ioe )
321  {
322  // Do not leave g_RootSheet == NULL because it is expected to be
323  // a valid sheet. Therefore create a dummy empty root sheet and screen.
324  CreateScreens();
326 
327  wxString msg;
328  msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
329  GetChars( fullFileName ), GetChars( ioe.What() ) );
330  DisplayError( this, msg );
331 
332  msg.Printf( _( "Failed to load \"%s\"" ), GetChars( fullFileName ) );
333  AppendMsgPanel( wxEmptyString, msg, CYAN );
334 
335  return false;
336  }
337 
338  // It's possible the schematic parser fixed errors due to bugs so warn the user
339  // that the schematic has been fixed (modified).
340  SCH_SHEET_LIST sheetList( g_RootSheet );
341 
342  if( sheetList.IsModified() )
343  {
344  DisplayInfoMessage( this,
345  _( "An error was found when loading the schematic that has "
346  "been automatically fixed. Please save the schematic to "
347  "repair the broken file or it may not be usable with other "
348  "versions of KiCad." ) );
349  }
350 
351  UpdateFileHistory( fullFileName );
352 
353  SCH_SCREENS schematic;
354 
355  // Convert old projects over to use symbol library table.
356  if( schematic.HasNoFullyDefinedLibIds() )
357  {
358  DIALOG_SYMBOL_REMAP dlgRemap( this );
359 
360  dlgRemap.ShowQuasiModal();
361  }
362  else
363  {
364  // Double check to ensure no legacy library list entries have been
365  // added to the projec file symbol library list.
366  wxString paths;
367  wxArrayString libNames;
368 
369  PART_LIBS::LibNamesAndPaths( &Prj(), false, &paths, &libNames );
370 
371  if( !libNames.IsEmpty() )
372  {
374  {
375  wxRichMessageDialog invalidLibDlg(
376  this,
377  _( "Illegal entry found in project file symbol library list." ),
378  _( "Project Load Warning" ),
379  wxOK | wxCENTER | wxICON_EXCLAMATION );
380  invalidLibDlg.SetExtendedMessage(
381  _( "Symbol libraries defined in the project file symbol library list "
382  "are no longer supported and will be\nremoved. This may cause "
383  "broken symbol library links under certain conditions." ) );
384  invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
385  invalidLibDlg.ShowModal();
386  m_showIllegalSymbolLibDialog = !invalidLibDlg.IsCheckBoxChecked();
387  }
388 
389  libNames.Clear();
390  paths.Clear();
391  PART_LIBS::LibNamesAndPaths( &Prj(), true, &paths, &libNames );
392  }
393 
394  // Check to see whether some old library parts need to be rescued
395  // Only do this if RescueNeverShow was not set.
396  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
397 
398  if( !cfg->m_RescueNeverShow )
400  }
401 
402  schematic.UpdateSymbolLinks( true ); // Update all symbol library links for all sheets.
406 
407  // Migrate conflicting bus definitions
408  // TODO(JE) This should only run once based on schematic file version
409  if( g_ConnectionGraph->GetBusesNeedingMigration().size() > 0 )
410  {
411  DIALOG_MIGRATE_BUSES dlg( this );
412  dlg.ShowQuasiModal();
413 
414  OnModify();
415  }
416 
417  GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
419 
420  GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
421 
422  GetScreen()->m_Initialized = true;
423  }
424 
428 
429  // re-create junctions if needed. Eeschema optimizes wires by merging
430  // colinear segments. If a schematic is saved without a valid
431  // cache library or missing installed libraries, this can cause connectivity errors
432  // unless junctions are added.
433  FixupJunctions();
434 
435  SyncView();
437 
438  UpdateTitle();
439 
440  return true;
441 }
442 
443 
445 {
446  wxString fullFileName;
447  SCH_SCREEN* screen = GetScreen();
448 
449  if( !screen )
450  {
451  wxLogError( wxT( "Document not ready, cannot import" ) );
452  return false;
453  }
454 
455  // open file chooser dialog
456  wxString path = wxPathOnly( Prj().GetProjectFullName() );
457 
458  wxFileDialog dlg( this, _( "Append Schematic" ), path, wxEmptyString,
459  LegacySchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
460 
461  if( dlg.ShowModal() == wxID_CANCEL )
462  return false;
463 
464  fullFileName = dlg.GetPath();
465 
466  if( !LoadSheetFromFile( GetCurrentSheet().Last(), &GetCurrentSheet(), fullFileName ) )
467  return false;
468 
469  SCH_SCREENS screens( GetCurrentSheet().Last() );
470  screens.TestDanglingEnds();
471 
475 
476  SyncView();
477  HardRedraw(); // Full reinit of the current screen and the display.
478  OnModify();
479 
480  return true;
481 }
482 
483 
484 void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event )
485 {
486  if( GetScreen() && GetScreen()->IsModified() )
487  {
488  wxString msg = _( "This operation cannot be undone.\n\n"
489  "Do you want to save the current document before proceeding?" );
490 
491  if( IsOK( this, msg ) )
492  SaveProject();
493  }
494 
495  AppendSchematic();
496 }
497 
498 
499 void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
500 {
501  if( !AskToSaveChanges() )
502  return;
503 
504  // Set the project location if none is set
505  bool setProject = Prj().GetProjectFullName().IsEmpty();
506  wxString path = wxPathOnly( Prj().GetProjectFullName() );
507 
508  wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString,
509  EagleSchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
510 
511  if( dlg.ShowModal() == wxID_CANCEL )
512  return;
513 
514  if( setProject )
515  {
516  wxFileName projectFn( dlg.GetPath() );
517  projectFn.SetExt( ProjectFileExtension );
518  Prj().SetProjectFullName( projectFn.GetFullPath() );
519  }
520 
521  // For now there is only one import plugin
522  importFile( dlg.GetPath(), SCH_IO_MGR::SCH_EAGLE );
523 }
524 
525 
527 {
528  SCH_SCREEN* screen;
529  SCH_SCREENS screenList;
530  bool success = true;
531 
532  // I want to see it in the debugger, show me the string! Can't do that with wxFileName.
533  wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() );
534  wxFileName fn = fileName;
535 
536  if( !fn.IsDirWritable() )
537  {
538  wxString msg = wxString::Format( _( "Directory \"%s\" is not writable." ), fn.GetPath() );
539  DisplayError( this, msg );
540  return false;
541  }
542 
543  for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
544  success &= SaveEEFile( screen );
545 
547 
548  // Save the sheet name map to the project file
549  wxString configFile = Prj().GetProjectFullName();
550  wxConfigBase* config = new wxFileConfig( wxEmptyString, wxEmptyString, configFile );
551  int index = 1;
552 
553  config->DeleteGroup( GROUP_SHEET_NAMES );
554  config->SetPath( GROUP_SHEET_NAMES );
555 
556  SCH_SHEET_LIST sheetList( g_RootSheet );
557 
558  for( SCH_SHEET_PATH& sheetPath : sheetList )
559  {
560  SCH_SHEET* sheet = sheetPath.Last();
561  config->Write( wxString::Format( "%d", index++ ),
562  wxString::Format( "%s:%s", sheet->m_Uuid.AsString(), sheet->GetName() ) );
563  }
564 
565  config->Flush();
566  delete config;
567 
568  UpdateTitle();
569 
570  return success;
571 }
572 
573 
575 {
576  wxFileName tmpFileName = g_RootSheet->GetFileName();
577  wxFileName fn = tmpFileName;
578  wxFileName tmp;
579  SCH_SCREENS screens;
580 
581  bool autoSaveOk = true;
582 
583  tmp.AssignDir( fn.GetPath() );
584 
585  if( !tmp.IsOk() )
586  return false;
587 
588  if( !IsWritable( tmp ) )
589  return false;
590 
591  for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
592  {
593  // Only create auto save files for the schematics that have been modified.
594  if( !screen->IsSave() )
595  continue;
596 
597  tmpFileName = fn = screen->GetFileName();
598 
599  // Auto save file name is the normal file name prefixed with GetAutoSavePrefix().
600  fn.SetName( GetAutoSaveFilePrefix() + fn.GetName() );
601 
602  screen->SetFileName( fn.GetFullPath() );
603 
604  if( SaveEEFile( screen, false, NO_BACKUP_FILE ) )
605  screen->SetModify();
606  else
607  autoSaveOk = false;
608 
609  screen->SetFileName( tmpFileName.GetFullPath() );
610  }
611 
612  if( autoSaveOk )
613  m_autoSaveState = false;
614 
615  return autoSaveOk;
616 }
617 
618 
619 bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
620 {
621  wxString projectpath;
622  wxFileName newfilename;
623  SCH_SHEET_LIST sheetList( g_RootSheet );
624 
625  switch( (SCH_IO_MGR::SCH_FILE_T) aFileType )
626  {
627  case SCH_IO_MGR::SCH_EAGLE:
628  // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
629  wxASSERT_MSG( wxFileName( aFileName ).IsAbsolute(),
630  wxT( "Import eagle schematic caller didn't send full filename" ) );
631 
632  if( !LockFile( aFileName ) )
633  {
634  wxString msg = wxString::Format( _( "Schematic file \"%s\" is already open." ),
635  aFileName );
636  DisplayError( this, msg );
637  return false;
638  }
639 
640  try
641  {
642  delete g_RootSheet;
643  g_RootSheet = nullptr;
644  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) );
645  g_RootSheet = pi->Load( aFileName, &Kiway() );
646 
647  // Eagle sheets do not use a worksheet frame by default, so set it to an empty one
649  pglayout.SetEmptyLayout();
650 
651  BASE_SCREEN::m_PageLayoutDescrFileName = "empty.kicad_wks";
652  wxFileName layoutfn( Kiway().Prj().GetProjectPath(),
654  wxFile layoutfile;
655 
656  if( layoutfile.Create( layoutfn.GetFullPath() ) )
657  {
658  layoutfile.Write( WS_DATA_MODEL::EmptyLayout() );
659  layoutfile.Close();
660  }
661 
662  projectpath = Kiway().Prj().GetProjectPath();
663  newfilename.SetPath( Prj().GetProjectPath() );
664  newfilename.SetName( Prj().GetProjectName() );
665  newfilename.SetExt( LegacySchematicFileExtension );
666 
670 
671  g_RootSheet->SetFileName( newfilename.GetFullPath() );
672  GetScreen()->SetFileName( newfilename.GetFullPath() );
673  GetScreen()->SetModify();
675 
676  UpdateFileHistory( aFileName );
677  SCH_SCREENS schematic;
678  schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
679 
680  GetScreen()->m_Initialized = true;
681  SCH_SCREENS allScreens;
682 
683  for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
684  {
685  for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
686  {
687  std::vector<wxPoint> pts;
688  SCH_COMPONENT* cmp = static_cast<SCH_COMPONENT*>( item );
689 
690  // Update footprint LIB_ID to point to the imported Eagle library
691  auto fpField = cmp->GetField( FOOTPRINT );
692 
693  if( !fpField->GetText().IsEmpty() )
694  {
695  LIB_ID fpId;
696  fpId.Parse( fpField->GetText(), LIB_ID::ID_SCH, true );
697  fpId.SetLibNickname( newfilename.GetName() );
698  fpField->SetText( fpId.Format() );
699  }
700  }
701  }
702  // Only perform the dangling end test on root sheet.
705 
706  GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
707 
711  SyncView();
712  UpdateTitle();
713  }
714  catch( const IO_ERROR& ioe )
715  {
716  // Do not leave g_RootSheet == NULL because it is expected to be
717  // a valid sheet. Therefore create a dummy empty root sheet and screen.
718  CreateScreens();
720 
721  wxString msg;
722  msg.Printf( _( "Error loading schematic \"%s\".\n%s" ), aFileName, ioe.What() );
723  DisplayError( this, msg );
724 
725  msg.Printf( _( "Failed to load \"%s\"" ), aFileName );
726  AppendMsgPanel( wxEmptyString, msg, CYAN );
727 
728  return false;
729  }
730 
731  return true;
732 
733  default:
734  return false;
735  }
736 }
737 
738 
740 {
741  SCH_SCREENS screenList;
742 
743  // Save any currently open and modified project files.
744  for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
745  {
746  if( screen->IsModify() )
747  {
748  if( !HandleUnsavedChanges( this, _( "The current schematic has been modified. "
749  "Save changes?" ),
750  [&]()->bool { return SaveProject(); } ) )
751  {
752  return false;
753  }
754  }
755  }
756 
757  return true;
758 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
WS_DATA_MODEL handles the graphic items list to draw/plot the frame and title block.
Definition: ws_data_model.h:39
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
SCH_SHEET_LIST.
void Save_File(bool doSaveAs=false)
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:201
bool IsModified()
Function IsModified checks the entire hierarchy for any modifications.
const wxString & GetFileName() const
Definition: sch_screen.h:157
wxString LegacySchematicFileWildcard()
SCH_SCREEN * GetNext()
Definition: sch_screen.cpp:970
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Function OpenProjectFiles is abstract, and opens a project or set of files given by aFileList.
static void LibNamesAndPaths(PROJECT *aProject, bool doSave, wxString *aPaths, wxArrayString *aNames=NULL)
Save or load the names of the currently configured part libraries (without paths).
int StrPrintf(std::string *aResult, const char *aFormat,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:74
void SetShutdownBlockReason(const wxString &reason)
Sets the block reason why the window/application is preventing OS shutdown.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:252
This file is part of the common library TODO brief description.
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
void RecalculateConnections(SCH_CLEANUP_FLAGS aCleanupFlags)
Generates the connection data for the entire schematic hierarchy.
void SaveProjectSettings() override
Save changes to the project settings to the project (.pro) file.
This file is part of the common library.
const std::string ProjectFileExtension
void SetScreen(BASE_SCREEN *aScreen) override
VTBL_ENTRY PROJECT & Prj() const
Function Prj returns the PROJECT associated with this KIWAY.
Definition: kiway.cpp:171
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
#define KICTL_CREATE
caller thinks requested project files may not exist
Definition: kiway_player.h:79
bool AskToSaveChanges()
Checks if any of the screens has unsaved changes and asks the user whether to save or drop them.
wxString KiCadSchematicFileWildcard()
static TOOL_ACTION zoomFitScreen
Definition: actions.h:93
void UpdateTitle()
Set the main window title bar text.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:139
void OnAppendProject(wxCommandEvent &event)
wxString AsString() const
Definition: common.cpp:170
#define GROUP_SHEET_NAMES
Definition: config_params.h:52
VTBL_ENTRY _ELEM * GetElem(ELEM_T aIndex)
Typically wrapped somewhere else in a more meaningful function wrapper.
Definition: project.cpp:232
static wxString EmptyLayout()
Returns a string containing the empty layout shape.
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
#define NO_BACKUP_FILE
CONNECTION_GRAPH * g_ConnectionGraph
This also wants to live in the eventual SCHEMATIC object.
bool importFile(const wxString &aFileName, int aFileType)
Load the given filename but sets the path to the current project path.
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:102
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:413
static WS_DATA_MODEL & GetTheInstance()
static function: returns the instance of WS_DATA_MODEL used in the application
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=NULL)
Update the list of recently opened files.
void OnImportProject(wxCommandEvent &event)
VTBL_ENTRY void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:244
static wxString m_PageLayoutDescrFileName
the name of the page layout descr file, or emty to used the default pagelayout
Definition: base_screen.h:109
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
static SCH_FILE_T GuessPluginTypeFromSchPath(const wxString &aSchematicPath)
Return a plugin type given a schematic using the file extension of aSchematicPath.
Definition: sch_io_mgr.cpp:169
void SetFileName(wxString aFilename)
Definition: sch_sheet.h:497
bool LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, const wxString &aFileName)
Load a the KiCad schematic file aFileName into the sheet aSheet.
Definition: sheet.cpp:102
void CheckForAutoSaveFile(const wxFileName &aFileName)
Check if an auto save file exists for aFileName and takes the appropriate action depending on the use...
wxString GetName() const
Definition: sch_sheet.h:280
#define NULL
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
static wxString GetBackupSuffix()
void HardRedraw() override
Rebuild the GAL and redraw the screen.
void SyncView()
Mark all items for refresh.
bool m_Initialized
Definition: base_screen.h:129
int ShowQuasiModal()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
SCH_SHEET_PATH & GetCurrentSheet()
Definition: colors.h:59
Definition of file extensions used in Kicad.
bool AppendSchematic()
Import a KiCad schematic into the current sheet.
bool SaveEEFile(SCH_SCREEN *aScreen, bool aSaveUnderNewName=false, bool aCreateBackupFile=CREATE_BACKUP_FILE)
Save aScreen to a schematic file.
bool CreateArchiveLibraryCacheFile(bool aUseCurrentSheetFilename=false)
Create a symbol library file with the name of the root document plus the '-cache' suffix,...
Definition: libarch.cpp:42
wxLogTrace helper definitions.
bool LoadProjectFile()
Loads the KiCad project file (*.pro) settings specific to Eeschema.
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
SCH_SHEET_PATH.
VTBL_ENTRY const wxString GetProjectFullName() const
Function GetProjectFullName returns the full path and name of the project.
Definition: project.cpp:96
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:491
virtual void ClearMsgPanel()
Clear all messages from the message panel.
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:64
void clear()
Forwarded method from std::vector.
const std::string LegacySchematicFileExtension
UTF8 Format() const
Definition: lib_id.cpp:237
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:215
bool m_showIllegalSymbolLibDialog
bool doAutoSave() override
Save the schematic files that have been modified and not yet saved.
const KIID m_Uuid
Definition: base_struct.h:169
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:193
static wxString GetAutoSaveFilePrefix()
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:516
void AppendMsgPanel(const wxString &textUpper, const wxString &textLower, COLOR4D color, int pad=6)
Append a message to the message panel.
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:101
see class PGM_BASE
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in the ful...
SCH_SCREEN * LastScreen()
Function LastScreen.
void TestDanglingEnds()
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
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
wxString EagleSchematicFileWildcard()
#define _(s)
Definition: 3d_actions.cpp:33
const std::string KiCadSchematicFileExtension
void ClrModify()
Definition: base_screen.h:225
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:99
bool RescueSymbolLibTableProject(bool aRunningOnDemand)
SCH_SCREEN * GetFirst()
Definition: sch_screen.cpp:959
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
TOOL_MANAGER * m_toolManager
SCH_SHEET * g_RootSheet
void ClearDrawingState()
Clear the state flags of all the items in the screen.
Definition: sch_screen.cpp:642
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:627
void SetFileName(const wxString &aFileName)
Definition: sch_screen.h:155
Definition for part library class.
void SetModify()
Definition: base_screen.h:224
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
int SetGrid(const wxRealPoint &size)
set the current grid size m_Grid.
int Parse(const UTF8 &aId, LIB_ID_TYPE aType, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:122
virtual APP_SETTINGS_BASE * config()
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:267
std::vector< const CONNECTION_SUBGRAPH * > GetBusesNeedingMigration()
Determines which subgraphs have more than one conflicting bus label.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:283
void ClrSave()
Definition: base_screen.h:227
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:491
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
bool TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr)
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:775