70#include <wx/filedlg.h>
72#include <wx/richmsgdlg.h>
73#include <wx/stdpaths.h>
97 if( aFileSet.size() != 1 )
99 msg.Printf(
"Eeschema:%s() takes only a single filename.", __WXFUNCTION__ );
104 wxString fullFileName( aFileSet[0] );
105 wxFileName wx_filename( fullFileName );
108 wxASSERT_MSG( wx_filename.IsAbsolute(), wxS(
"Path is not absolute!" ) );
112 msg.Printf(
_(
"Schematic '%s' is already open by '%s' at '%s'." ), fullFileName,
128 wxFileName pro = fullFileName;
131 bool is_new = !wxFileName::IsFileReadable( fullFileName );
137 msg.Printf(
_(
"Schematic '%s' does not exist. Do you wish to create it?" ),
140 if( !
IsOK(
this, msg ) )
144 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGING );
145 ProcessEventLocally( e );
155 SetStatusText( wxEmptyString );
159 :
_(
"Load Schematic" ), 1,
165 if( differentProject )
167 if( !
Prj().IsNullProject() )
179 wxFileName legacyPro( pro );
184 if( !pro.Exists() && !legacyPro.Exists() && !( aCtl &
KICTL_CREATE ) )
189 std::unique_ptr<SCHEMATIC> newSchematic = std::make_unique<SCHEMATIC>( &
Prj() );
194 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
220 rfn.MakeRelativeTo(
Prj().GetProjectPath() );
230 if( is_new || schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
232 newSchematic->CreateDefaultScreens();
239 if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
241 msg.Printf(
_(
"'%s' is not a KiCad schematic file.\nUse File -> Import for "
242 "non-KiCad schematic files." ),
245 progressReporter.Hide();
251 wxFileName autoSaveFn = fullFileName;
254 autoSaveFn.ClearExt();
270 pi->SetProgressReporter( &progressReporter );
272 bool failedLoad =
false;
280 newSchematic->SetRoot( pi->LoadSchematicFile( fullFileName, newSchematic.get() ) );
284 newSchematic->Root().SetName(
_(
"Root" ) );
286 newSchematic->Root().m_Uuid.AsString() );
289 if( !pi->GetError().IsEmpty() )
292 "occurred attempting to load hierarchical sheets." ),
298 newSchematic->CreateDefaultScreens();
299 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName );
300 progressReporter.Hide();
307 newSchematic->CreateDefaultScreens();
308 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName );
309 progressReporter.Hide();
314 catch(
const std::bad_alloc& )
316 newSchematic->CreateDefaultScreens();
317 msg.Printf(
_(
"Memory exhausted loading schematic '%s'." ), fullFileName );
318 progressReporter.Hide();
338 msg.Printf(
_(
"Failed to load '%s'." ), fullFileName );
355 _(
"An error was found when loading the schematic that has "
356 "been automatically fixed. Please save the schematic to "
357 "repair the broken file or it may not be usable with other "
358 "versions of KiCad." ) );
369 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
374 std::vector<SCH_ITEM*> deleted;
376 for(
SCH_ITEM* item : screen->Items() )
381 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
385 wire->SetEndPoint( entry->
GetEnd() );
387 screen->Append( wire.release() );
388 deleted.push_back( item );
393 screen->Remove( item );
409 wxArrayString libNames;
413 if( !libNames.IsEmpty() )
415 if(
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
417 wxRichMessageDialog invalidLibDlg(
419 _(
"Illegal entry found in project file symbol library list." ),
420 _(
"Project Load Warning" ),
421 wxOK | wxCENTER | wxICON_EXCLAMATION );
422 invalidLibDlg.ShowDetailedText(
423 _(
"Symbol libraries defined in the project file symbol library "
424 "list are no longer supported and will be removed.\n\n"
425 "This may cause broken symbol library links under certain "
427 invalidLibDlg.ShowCheckBox(
_(
"Do not show this dialog again." ) );
428 invalidLibDlg.ShowModal();
430 !invalidLibDlg.IsCheckBoxChecked();
441 editor->RescueSymbolLibTableProject(
false );
451 wxFileName cacheFn = pro;
453 cacheFn.SetName( cacheFn.GetName() +
"-cache" );
456 msg.Printf(
_(
"The project symbol library cache file '%s' was not found." ),
457 cacheFn.GetFullName() );
458 extMsg =
_(
"This can result in a broken schematic under certain conditions. "
459 "If the schematic does not have any missing symbols upon opening, "
460 "save it immediately before making any changes to prevent data "
461 "loss. If there are missing symbols, either manual recovery of "
462 "the schematic or recovery of the symbol cache library file and "
463 "reloading the schematic is required." );
465 wxMessageDialog dlgMissingCache(
this, msg,
_(
"Warning" ),
466 wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
467 dlgMissingCache.SetExtendedMessage( extMsg );
468 dlgMissingCache.SetOKCancelLabels(
469 wxMessageDialog::ButtonLabel(
_(
"Load Without Cache File" ) ),
470 wxMessageDialog::ButtonLabel(
_(
"Abort" ) ) );
472 if( dlgMissingCache.ShowModal() == wxID_CANCEL )
485 m_infoBar->ShowMessage(
_(
"This file was created by an older version of KiCad. "
486 "It will be converted to the new format when saved." ),
494 screen->FixLegacyPowerSymbolMismatches();
505 m_infoBar->ShowMessage(
_(
"This file was created by an older version of KiCad. "
506 "It will be converted to the new format when saved." ),
511 screen->UpdateLocalLibSymbolLinks();
514 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
517 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
520 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
523 screen->FixLegacyPowerSymbolMismatches();
526 screen->MigrateSimModels();
544 if(
Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() > 0 )
553 progressReporter.
Report(
_(
"Updating connections..." ) );
560 m_infoBar->QueueShowMessage(
_(
"This schematic contains symbols that have leading "
561 "and/or trailing white space field names." ),
583 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
593 wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
594 ProcessEventLocally( changedEvt );
598 wxCHECK2( listener,
continue );
602 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
605 win->HandleWindowEvent( e );
607 listener->SafelyProcessEvent( e );
615 if( fn.FileExists() && !fn.IsFileWritable() )
619 m_infoBar->ShowMessage(
_(
"Schematic is read only." ),
638 wxString msg =
_(
"This operation replaces the contents of the current schematic, "
639 "which will be permanently lost.\n\n"
640 "Do you want to proceed?" );
642 if( !
IsOK(
this, msg ) )
648 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
650 wxString fileFiltersStr;
651 wxString allWildcardsStr;
653 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
655 if(
fileType == SCH_IO_MGR::SCH_KICAD ||
fileType == SCH_IO_MGR::SCH_LEGACY )
668 if( !fileFiltersStr.IsEmpty() )
669 fileFiltersStr += wxChar(
'|' );
677 fileFiltersStr =
_(
"All supported formats" ) + wxS(
"|" ) + allWildcardsStr + wxS(
"|" )
680 wxFileDialog dlg(
this,
_(
"Import Schematic" ),
path, wxEmptyString, fileFiltersStr,
681 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
684 dlg.SetCustomizeHook( importOptions );
686 if( dlg.ShowModal() == wxID_CANCEL )
706 wxFileName projectFn( dlg.GetPath() );
711 wxFileName fn = dlg.GetPath();
713 if( !fn.IsFileReadable() )
715 wxLogError(
_(
"Insufficient permissions to read file '%s'." ), fn.GetFullPath() );
719 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
721 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
728 if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
735 if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
737 wxLogError(
_(
"No loader can read the specified file: '%s'." ), fn.GetFullPath() );
752 wxFileName schematicFileName;
753 wxFileName oldFileName;
758 wxCHECK( screen,
false );
761 if( aSavePath.IsEmpty() )
766 oldFileName = schematicFileName;
771 if( !schematicFileName.DirExists() )
773 if( !wxMkdir( schematicFileName.GetPath() ) )
775 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
776 schematicFileName.GetFullPath(),
777 "Could not create directory: %s" + schematicFileName.GetPath() );
787 wxFileName projectFile( schematicFileName );
791 if( projectFile.FileExists() )
799 wxLogTrace(
traceAutoSave, wxS(
"Saving file " ) + schematicFileName.GetFullPath() );
805 schematicFileName.GetFullPath() );
807 if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
808 pluginType = SCH_IO_MGR::SCH_KICAD;
814 pi->SaveSchematicFile( schematicFileName.GetFullPath(), aSheet, &
Schematic() );
819 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
820 schematicFileName.GetFullPath(),
830 wxFileName autoSaveFileName = schematicFileName;
833 if( autoSaveFileName.FileExists() )
836 wxS(
"Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
839 wxRemoveFile( autoSaveFileName.GetFullPath() );
844 msg.Printf(
_(
"File '%s' saved." ), screen->
GetFileName() );
845 SetStatusText( msg, 0 );
853 const wxFileName& aOldRoot,
const wxFileName& aNewRoot,
854 bool aSaveCopy,
bool aCopySubsheets,
bool aIncludeExternSheets,
855 std::unordered_map<SCH_SCREEN*, wxString>& aFilenameMap,
856 wxString& aErrorMsg )
860 for(
size_t i = 0; i < aScreens.
GetCount(); i++ )
864 wxCHECK2( screen,
continue );
871 if( !src.IsAbsolute() )
872 src.MakeAbsolute( aOldRoot.GetPath() );
874 bool internalSheet = src.GetPath().StartsWith( aOldRoot.GetPath() );
876 if( aCopySubsheets && ( internalSheet || aIncludeExternSheets ) )
878 wxFileName dest = src;
880 if( internalSheet && dest.MakeRelativeTo( aOldRoot.GetPath() ) )
881 dest.MakeAbsolute( aNewRoot.GetPath() );
883 dest.Assign( aNewRoot.GetPath(), dest.GetFullName() );
886 wxS(
"Moving schematic from '%s' to '%s'." ),
888 dest.GetFullPath() );
890 if( !dest.DirExists() && !dest.Mkdir() )
892 aErrorMsg.Printf(
_(
"Folder '%s' could not be created.\n\n"
893 "Make sure you have write permissions and try again." ),
899 aFilenameMap[screen] = dest.GetFullPath();
906 aFilenameMap[screen] = wxString();
914 if( !sheet.Last()->IsRootSheet() )
915 sheet.MakeFilePathRelativeToParentSheet();
928 bool updateFileHistory =
false;
929 bool createNewProject =
false;
930 bool copySubsheets =
false;
931 bool includeExternSheets =
false;
935 wxFileName fn = fileName;
939 std::unordered_map<SCH_SCREEN*, wxString> filenameMap;
942 if(
Prj().IsNullProject() || aSaveAs )
945 wxCHECK(
Kiface().IsSingle() || aSaveAs,
false );
947 wxFileName newFileName;
948 wxFileName savePath(
Prj().GetProjectFullName() );
950 if( !savePath.IsOk() || !savePath.IsDirWritable() )
954 if( !savePath.IsOk() || !savePath.IsDirWritable() )
958 if( savePath.HasExt() )
961 savePath.SetName( wxEmptyString );
963 wxFileDialog dlg(
this,
_(
"Schematic Files" ), savePath.GetPath(), savePath.GetFullName(),
965 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
970 if(
Kiface().IsSingle() || aSaveAs )
972 dlg.SetCustomizeHook( newProjectHook );
975 if( dlg.ShowModal() == wxID_CANCEL )
980 if( ( !newFileName.DirExists() && !newFileName.Mkdir() ) ||
981 !newFileName.IsDirWritable() )
983 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
984 "Make sure you have write permissions and try again." ),
985 newFileName.GetPath() );
987 wxMessageDialog dlgBadPath(
this, msg,
_(
"Error" ),
988 wxOK | wxICON_EXCLAMATION | wxCENTER );
990 dlgBadPath.ShowModal();
1005 updateFileHistory =
true;
1013 copySubsheets, includeExternSheets, filenameMap, msg ) )
1015 wxMessageDialog dlgBadFilePath(
this, msg,
_(
"Error" ),
1016 wxOK | wxICON_EXCLAMATION | wxCENTER );
1018 dlgBadFilePath.ShowModal();
1022 else if( !fn.FileExists() )
1025 updateFileHistory =
true;
1036 if( filenameMap.empty() || !saveCopy )
1038 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1043 wxArrayString overwrittenFiles;
1044 wxArrayString lockedFiles;
1046 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1050 wxCHECK2( screen,
continue );
1053 wxFileName tmpFn = filenameMap[screen];
1058 if( tmpFn.FileExists() && !tmpFn.IsFileWritable() )
1059 lockedFiles.Add( tmpFn.GetFullPath() );
1066 if( tmpFn.FileExists() )
1067 overwrittenFiles.Add( tmpFn.GetFullPath() );
1070 if( !lockedFiles.IsEmpty() )
1072 for(
const wxString& lockedFile : lockedFiles )
1077 msg +=
"\n" + lockedFile;
1080 wxRichMessageDialog dlg(
this, wxString::Format(
_(
"Failed to save %s." ),
1082 _(
"Locked File Warning" ),
1083 wxOK | wxICON_WARNING | wxCENTER );
1084 dlg.SetExtendedMessage(
_(
"You do not have write permissions to:\n\n" ) + msg );
1090 if( !overwrittenFiles.IsEmpty() )
1092 for(
const wxString& overwrittenFile : overwrittenFiles )
1095 msg = overwrittenFile;
1097 msg +=
"\n" + overwrittenFile;
1100 wxRichMessageDialog dlg(
this,
_(
"Saving will overwrite existing files." ),
1101 _(
"Save Warning" ),
1102 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER |
1103 wxICON_EXCLAMATION );
1104 dlg.ShowDetailedText(
_(
"The following files will be overwritten:\n\n" ) + msg );
1105 dlg.SetOKCancelLabels( wxMessageDialog::ButtonLabel(
_(
"Overwrite Files" ) ),
1106 wxMessageDialog::ButtonLabel(
_(
"Abort Project Save" ) ) );
1108 if( dlg.ShowModal() == wxID_CANCEL )
1114 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1118 wxCHECK2( screen,
continue );
1121 wxFileName tmpFn = filenameMap[screen];
1125 updateFileHistory =
true;
1133 if( !sheetFileName.IsOk()
1138 sheet->
SetFileName( sheetFileName.GetFullPath() );
1142 filenameMap[screen] = tmpFn.GetFullPath();
1154 if( sheets.size() == 1 )
1160 if( !saveCopy && tmpFn.GetFullPath() != screen->
GetFileName() )
1170 if( !aSaveAs && !success )
1173 if( aSaveAs && success )
1176 if( updateFileHistory )
1187 wxCHECK2( sheet,
continue );
1194 wxCHECK2( screen,
continue );
1198 sheets.emplace_back( std::make_pair( screen->
GetUuid(), wxT(
"Root" ) ) );
1202 sheets.emplace_back( std::make_pair( sheet->
m_Uuid, sheet->
GetName() ) );
1206 wxASSERT( filenameMap.count(
Schematic().RootScreen() ) );
1207 wxFileName projectPath( filenameMap.at(
Schematic().RootScreen() ) );
1210 if(
Prj().IsNullProject() || ( aSaveAs && !saveCopy ) )
1215 else if( saveCopy && createNewProject )
1225 if( !
Kiface().IsSingle() )
1248 wxFileName fn = tmpFileName;
1256 bool autoSaveOk =
true;
1258 if( fn.GetPath().IsEmpty() )
1259 tmp.AssignDir(
Prj().GetProjectPath() );
1261 tmp.AssignDir( fn.GetPath() );
1271 _(
"Could not autosave files to read-only folder: '%s'" ),
1279 wxString title = GetTitle();
1281 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1297 _(
"Could not autosave files to read-only folder: '%s'" ),
1336 const std::map<std::string, UTF8>* aProperties )
1338 wxFileName filename( aFileName );
1339 wxFileName newfilename;
1340 SCH_IO_MGR::SCH_FILE_T
fileType = (SCH_IO_MGR::SCH_FILE_T) aFileType;
1342 wxCommandEvent changingEvt( EDA_EVT_SCHEMATIC_CHANGING );
1343 ProcessEventLocally( changingEvt );
1345 std::unique_ptr<SCHEMATIC> newSchematic = std::make_unique<SCHEMATIC>( &
Prj() );
1349 case SCH_IO_MGR::SCH_ALTIUM:
1350 case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
1351 case SCH_IO_MGR::SCH_EAGLE:
1352 case SCH_IO_MGR::SCH_LTSPICE:
1353 case SCH_IO_MGR::SCH_EASYEDA:
1354 case SCH_IO_MGR::SCH_EASYEDAPRO:
1358 wxCHECK_MSG( aFileName.IsEmpty() || filename.IsAbsolute(),
false,
1359 wxS(
"Import schematic: path is not absolute!" ) );
1370 this, std::placeholders::_1 ) );
1373 if(
eeconfig()->m_System.show_import_issues )
1378 pi->SetProgressReporter( &progressReporter );
1380 SCH_SHEET* loadedSheet = pi->LoadSchematicFile( aFileName, newSchematic.get(),
nullptr,
1401 newfilename.SetPath(
Prj().GetProjectPath() );
1402 newfilename.SetName(
Prj().GetProjectName() );
1411 progressReporter.
Report(
_(
"Updating connections..." ) );
1433 wxString msg = wxString::Format(
_(
"Error loading schematic '%s'." ), aFileName );
1436 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1439 catch(
const std::exception& exc )
1444 wxString msg = wxString::Format(
_(
"Unhandled exception occurred loading schematic "
1445 "'%s'." ), aFileName );
1448 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1461 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGED );
1462 ProcessEventLocally( e );
1466 wxCHECK2( listener,
continue );
1470 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
1473 win->HandleWindowEvent( e );
1475 listener->SafelyProcessEvent( e );
1501 if( simFrame && !simFrame->Close() )
1504 if( screen->IsContentModified() )
1527 if( !autoSaveFileName.IsDirWritable() )
1529 wxLogTrace(
traceAutoSave,
"Insufficient permissions to auto save file '%s'",
1530 autoSaveFileName.GetFullPath() );
1534 wxLogTrace(
traceAutoSave,
"Creating auto save file '%s'", autoSaveFileName.GetFullPath() );
1538 std::vector< wxString > autoSavedFiles;
1540 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1550 autoSavedFiles.emplace_back( fn.GetFullPath() );
1553 wxTextFile autoSaveFile( autoSaveFileName.GetFullPath() );
1555 if( autoSaveFileName.FileExists() && !wxRemoveFile( autoSaveFileName.GetFullPath() ) )
1557 wxLogTrace(
traceAutoSave,
"Error removing auto save file '%s'",
1558 autoSaveFileName.GetFullPath() );
1564 if( autoSavedFiles.empty() )
1567 if( !autoSaveFile.Create() )
1570 for(
const wxString& fileName : autoSavedFiles )
1572 wxLogTrace(
traceAutoSave,
"Adding auto save file '%s' to '%s'",
1573 fileName, autoSaveFileName.GetName() );
1574 autoSaveFile.AddLine( fileName );
1577 if( !autoSaveFile.Write() )
1580 wxLogTrace(
traceAutoSave,
"Auto save file '%s' written", autoSaveFileName.GetFullName() );
1586void removeFile(
const wxString& aFilename, wxArrayString& aUnremoved )
1588 wxLogTrace(
traceAutoSave, wxS(
"Removing auto save file '%s'" ), aFilename );
1590 if( wxFileExists( aFilename ) && !wxRemoveFile( aFilename ) )
1591 aUnremoved.Add( aFilename );
1597 if( !
Pgm().IsGUI() )
1600 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1602 wxLogTrace(
traceAutoSave, wxS(
"Checking for auto save file '%s'" ), aFileName.GetFullPath() );
1604 if( !aFileName.FileExists() )
1607 wxString msg =
_(
"Well this is potentially embarrassing!\n"
1608 "It appears that the last time you were editing one or more of the schematic files\n"
1609 "were not saved properly. Do you wish to restore the last saved edits you made?" );
1611 int response = wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
this );
1613 wxTextFile fileList( aFileName.GetFullPath() );
1615 if( !fileList.Open() )
1617 msg.Printf(
_(
"The file '%s' could not be opened.\n"
1618 "Manual recovery of automatically saved files is required." ),
1619 aFileName.GetFullPath() );
1621 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1625 if( response == wxYES )
1627 wxArrayString unrecoveredFiles;
1629 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1631 wxFileName recoveredFn = fn;
1632 wxString tmp = recoveredFn.GetName();
1636 recoveredFn.SetName( tmp );
1638 wxFileName backupFn = recoveredFn;
1642 wxLogTrace(
traceAutoSave, wxS(
"Recovering auto save file:\n"
1643 " Original file: '%s'\n"
1644 " Backup file: '%s'\n"
1645 " Auto save file: '%s'" ),
1646 recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
1648 if( !wxFileExists( fn ) )
1650 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1654 else if( recoveredFn.Exists()
1655 && !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
1657 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1660 else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
1662 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1666 if( !unrecoveredFiles.IsEmpty() )
1668 msg =
_(
"The following automatically saved file(s) could not be restored\n" );
1670 for(
size_t i = 0; i < unrecoveredFiles.GetCount(); i++ )
1671 msg += unrecoveredFiles[i] + wxS(
"\n" );
1673 msg +=
_(
"Manual recovery will be required to restore the file(s) above." );
1674 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1677 wxArrayString unremovedFiles;
1678 removeFile( aFileName.GetFullPath(), unremovedFiles );
1680 if( !unremovedFiles.IsEmpty() )
1682 msg.Printf(
_(
"The autosave file '%s' could not be removed.\n"
1683 "Manual removal will be required." ),
1684 unremovedFiles[0] );
1686 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1698 if( !
Pgm().IsGUI() )
1701 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1703 if( !aFileName.FileExists() )
1706 wxTextFile fileList( aFileName.GetFullPath() );
1707 wxArrayString unremovedFiles;
1709 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1712 removeFile( aFileName.GetFullPath(), unremovedFiles );
1714 if( !unremovedFiles.IsEmpty() )
1716 wxString msg =
_(
"The following automatically saved file(s) could not be removed\n" );
1718 for(
size_t i = 0; i < unremovedFiles.GetCount(); i++ )
1719 msg += unremovedFiles[i] + wxS(
"\n" );
1721 msg +=
_(
"Manual removal will be required for the file(s) above." );
1722 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1729 static wxString autoSaveFileName( wxS(
"#auto_saved_files#" ) );
1731 return autoSaveFileName;
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static TOOL_ACTION zoomFitScreen
bool IsContentModified() const
void SetVirtualPageNumber(int aPageNumber)
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
void SetContentModified(bool aModified=true)
Class DIALOG_HTML_REPORTER.
WX_HTML_REPORT_BOX * m_Reporter
static std::vector< IMPORT_PROJECT_DESC > RunModal(wxWindow *aParent, const std::vector< IMPORT_PROJECT_DESC > &aProjectDesc)
Create and show a dialog (modal) and returns the data from it after completion.
Handle the graphic items list to draw/plot the frame and title block.
static DS_DATA_MODEL & GetTheInstance()
Return the instance of DS_DATA_MODEL used in the application.
void LoadWindowState(const wxString &aFileName)
bool m_autoSavePermissionError
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
SETTINGS_MANAGER * GetSettingsManager() const
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
wxString GetMruPath() const
bool IsWritable(const wxFileName &aFileName, bool aVerbose=true)
Check if aFileName can be written.
std::unique_ptr< LOCKFILE > m_file_checker
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void RefreshCanvas() override
bool LockFile(const wxString &aFileName)
Mark a schematic file as being in use.
A base class for most all the KiCad significant classes used in schematics and boards.
EE_TYPE OfType(KICAD_T aType) const
bool GetCreateNewProject() const
Gets the selected state of the copy subsheets option.
bool GetCopySubsheets() const
Gets the selected state of the include external sheets option.
bool IsAttachedToDialog() const
bool GetIncludeExternSheets() const
Gets if this hook has attached controls to a dialog box.
bool GetShowIssues() const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
APP_SETTINGS_BASE * KifaceSettings() const
bool IsSingle() const
Is this KIFACE running under single_top?
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
static REPORTER & GetInstance()
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
A small class to help profiling.
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
virtual void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
bool KeepRefreshing(bool aWait=false) override
Update the UI dialog.
Plugin class for import plugins that support choosing a project.
std::vector< FILE_INFO_PAIR > & GetSheets()
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
static SYMBOL_LIBS * SchLibs(PROJECT *aProject)
These are all prefaced with "Sch".
virtual void SetReadOnly(bool aReadOnly=true)
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
virtual void SetElem(PROJECT::ELEM aIndex, _ELEM *aElem)
virtual PROJECT_FILE & GetProjectFile() const
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.
Holds all the data relating to one schematic.
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
void FixupJunctionsAfterImport()
Add junctions to this schematic where required.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
void SetProject(PROJECT *aPrj)
CONNECTION_GRAPH * ConnectionGraph() const
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SyncView()
Mark all items for refresh.
EESCHEMA_SETTINGS * eeconfig() const
Class for a bus to bus entry.
VECTOR2I GetPosition() const override
void DisplaySheet(SCH_SCREEN *aScreen)
bool IsContentModified() const override
Get if the current schematic has been modified but not saved.
const wxString & getAutoSaveFileName() const
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
void SaveProjectLocalSettings() override
Save changes to the project settings to the project (.pro) file.
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl=0) override
Open a project or set of files given by aFileList.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SetScreen(BASE_SCREEN *aScreen) override
bool AskToSaveChanges()
Check if any of the screens has unsaved changes and asks the user whether to save or drop them.
friend class SCH_EDITOR_CONTROL
bool doAutoSave() override
Save the schematic files that have been modified and not yet saved.
std::vector< wxEvtHandler * > m_schematicChangeListeners
void CreateDefaultScreens()
SCH_SHEET_PATH & GetCurrentSheet() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
SCHEMATIC & Schematic() const
void updateTitle()
Set the main window title bar text.
void SetSchematic(SCHEMATIC *aSchematic)
bool saveSchematicFile(SCH_SHEET *aSheet, const wxString &aSavePath)
Save aSheet to a schematic file.
bool LoadProjectSettings()
Load the KiCad project file (*.pro) settings specific to Eeschema.
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
bool updateAutoSaveFile()
void UpdateHierarchyNavigator(bool aRefreshNetNavigator=true, bool aClear=false)
Update the hierarchy navigation tree and history.
bool importFile(const wxString &aFileName, int aFileType, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void LoadDrawingSheet()
Load the drawing sheet file.
virtual void DeleteAutoSaveFile(const wxFileName &aFileName) override
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void ClearRepeatItemsList()
Clear the list of items which are to be repeated with the insert key.
void initScreenZoom()
Initialize the zoom value of the current screen and mark the screen as zoom-initialized.
void OnImportProject(wxCommandEvent &event)
virtual void CheckForAutoSaveFile(const wxFileName &aFileName) override
This overloaded version checks if the auto save master file "#auto_saved_files#" exists and recovers ...
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
wxString GetCurrentFileName() const override
Get the full filename + path of the currently opened file in the frame.
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
bool SaveProject(bool aSaveAs=false)
Save the currently-open schematic (including its hierarchy) and associated project.
void saveProjectSettings() override
Save any design-related project settings associated with this frame.
static SCH_FILE_T GuessPluginTypeFromSchPath(const wxString &aSchematicPath, int aCtl=0)
Return a plugin type given a schematic using the file extension of aSchematicPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
SCH_SCREEN * GetScreen(unsigned int aIndex) const
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
void PruneOrphanedSheetInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
void BuildClientSheetPathList()
Build the list of sheet paths sharing a screen for each screen in use.
bool HasSymbolFieldNamesWithWhiteSpace() const
void PruneOrphanedSymbolInstances(const wxString &aProjectName, const SCH_SHEET_LIST &aValidSheetPaths)
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
SCH_SHEET * GetSheet(unsigned int aIndex) const
int ReplaceDuplicateTimeStamps()
Test all sheet and symbol objects in the schematic for duplicate time stamps and replaces them as nec...
void ClearDrawingState()
Clear the state flags of all the items in the screen.
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
int GetFileFormatVersionAtLoad() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void UpdateSheetInstanceData(const std::vector< SCH_SHEET_INSTANCE > &aSheetInstances)
Update all of the sheet instance information using aSheetInstances.
void SetInitialPageNumbers()
Set initial sheet page numbers.
bool AllSheetPageNumbersEmpty() const
Check all of the sheet instance for empty page numbers.
bool IsModified() const
Check the entire hierarchy for any modifications.
void UpdateSymbolInstanceData(const std::vector< SCH_SYMBOL_INSTANCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
void CheckForMissingSymbolInstances(const wxString &aProjectName)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
SCH_SCREEN * GetScreen() const
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save a copy of the current project under the given path.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Save, unload and unregister the given PROJECT.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Call BackupProject() if a new backup is needed according to the current backup policy.
The SIMULATOR_FRAME holds the main user-interface for running simulations.
A collection of SYMBOL_LIB objects.
static void SetLibNamesAndPaths(PROJECT *aProject, const wxString &aPaths, const wxArrayString &aNames)
static void GetLibNamesAndPaths(PROJECT *aProject, wxString *aPaths, wxArrayString *aNames=nullptr)
Temporarily disable a window, and then re-enable on destruction.
static void ResolvePossibleSymlinks(wxFileName &aFilename)
void Flush()
Build the HTML messages page.
bool HasMessage() const override
Returns true if any messages were reported.
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
A wrapper for reporting to a wxString object.
const wxString & GetMessages() const
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
static bool empty(const wxTextEntryBase *aCtrl)
void removeFile(const wxString &aFilename, wxArrayString &aUnremoved)
bool PrepareSaveAsFiles(SCHEMATIC &aSchematic, SCH_SCREENS &aScreens, const wxFileName &aOldRoot, const wxFileName &aNewRoot, bool aSaveCopy, bool aCopySubsheets, bool aIncludeExternSheets, std::unordered_map< SCH_SCREEN *, wxString > &aFilenameMap, wxString &aErrorMsg)
static const std::string ProjectFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LegacySymbolLibFileExtension
static const std::string BackupFileSuffix
static const std::string AutoSaveFilePrefix
static wxString KiCadSchematicFileWildcard()
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define KICTL_CREATE
caller thinks requested project files may not exist.
#define KICTL_REVERT
reverting to a previously-saved (KiCad) file.
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
PGM_BASE & Pgm()
The global program "get" accessor.
#define SEXPR_SCHEMATIC_FILE_VERSION
Schematic file version.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
bool show_import_issues
Stored value for "show import issues" when importing non-KiCad designs to this application.
bool show_illegal_symbol_lib_dialog
Container that describes file type info.
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
bool m_CanRead
Whether the IO can read this file type.
wxString FileFilter() const
Definition for symbol library class.
wxLogTrace helper definitions.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
Definition of file extensions used in Kicad.