70#include <wx/filedlg.h>
72#include <wx/richmsgdlg.h>
73#include <wx/stdpaths.h>
84#include "widgets/filedlg_hook_save_project.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 );
156 SetStatusText( wxEmptyString );
160 :
_(
"Loading Schematic" ), 1 );
164 if( differentProject )
166 if( !
Prj().IsNullProject() )
177 wxFileName legacyPro( pro );
182 if( !pro.Exists() && !legacyPro.Exists() && !( aCtl &
KICTL_CREATE ) )
190 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 )
236 if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
238 msg.Printf(
_(
"'%s' is not a KiCad schematic file.\nUse File -> Import for "
239 "non-KiCad schematic files." ),
242 progressReporter.Hide();
248 wxFileName autoSaveFn = fullFileName;
251 autoSaveFn.ClearExt();
267 pi->SetProgressReporter( &progressReporter );
269 bool failedLoad =
false;
284 if( !pi->GetError().IsEmpty() )
287 "occurred attempting to load hierarchical sheets." ),
293 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName);
294 progressReporter.Hide();
301 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName);
302 progressReporter.Hide();
307 catch(
const std::bad_alloc& )
309 msg.Printf(
_(
"Memory exhausted loading schematic '%s'." ), fullFileName );
310 progressReporter.Hide();
328 msg.Printf(
_(
"Failed to load '%s'." ), fullFileName );
341 _(
"An error was found when loading the schematic that has "
342 "been automatically fixed. Please save the schematic to "
343 "repair the broken file or it may not be usable with other "
344 "versions of KiCad." ) );
355 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
360 std::vector<SCH_ITEM*> deleted;
362 for(
SCH_ITEM* item : screen->Items() )
367 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
371 wire->SetEndPoint( entry->
GetEnd() );
373 screen->Append( wire.release() );
374 deleted.push_back( item );
379 screen->Remove( item );
395 wxArrayString libNames;
399 if( !libNames.IsEmpty() )
401 if(
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
403 wxRichMessageDialog invalidLibDlg(
405 _(
"Illegal entry found in project file symbol library list." ),
406 _(
"Project Load Warning" ),
407 wxOK | wxCENTER | wxICON_EXCLAMATION );
408 invalidLibDlg.ShowDetailedText(
409 _(
"Symbol libraries defined in the project file symbol library "
410 "list are no longer supported and will be removed.\n\n"
411 "This may cause broken symbol library links under certain "
413 invalidLibDlg.ShowCheckBox(
_(
"Do not show this dialog again." ) );
414 invalidLibDlg.ShowModal();
416 !invalidLibDlg.IsCheckBoxChecked();
427 editor->RescueSymbolLibTableProject(
false );
437 wxFileName cacheFn = pro;
439 cacheFn.SetName( cacheFn.GetName() +
"-cache" );
442 msg.Printf(
_(
"The project symbol library cache file '%s' was not found." ),
443 cacheFn.GetFullName() );
444 extMsg =
_(
"This can result in a broken schematic under certain conditions. "
445 "If the schematic does not have any missing symbols upon opening, "
446 "save it immediately before making any changes to prevent data "
447 "loss. If there are missing symbols, either manual recovery of "
448 "the schematic or recovery of the symbol cache library file and "
449 "reloading the schematic is required." );
451 wxMessageDialog dlgMissingCache(
this, msg,
_(
"Warning" ),
452 wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
453 dlgMissingCache.SetExtendedMessage( extMsg );
454 dlgMissingCache.SetOKCancelLabels(
455 wxMessageDialog::ButtonLabel(
_(
"Load Without Cache File" ) ),
456 wxMessageDialog::ButtonLabel(
_(
"Abort" ) ) );
458 if( dlgMissingCache.ShowModal() == wxID_CANCEL )
472 "It will be converted to the new format when saved." ),
480 screen->FixLegacyPowerSymbolMismatches();
492 "It will be converted to the new format when saved." ),
497 screen->UpdateLocalLibSymbolLinks();
500 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
503 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
506 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
508 screen->FixLegacyPowerSymbolMismatches();
511 screen->MigrateSimModels();
534 if(
Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() > 0 )
563 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
573 wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
574 ProcessEventLocally( changedEvt );
578 wxCHECK2( listener,
continue );
582 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
585 win->HandleWindowEvent( e );
587 listener->SafelyProcessEvent( e );
595 if( fn.FileExists() && !fn.IsFileWritable() )
618 wxCHECK( screen,
false );
621 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
623 wxFileDialog dlg(
this,
_(
"Insert Schematic" ),
path, wxEmptyString,
626 if( dlg.ShowModal() == wxID_CANCEL )
653 bool selected =
false;
678 commit.
Push(
_(
"Import Schematic Sheet Content..." ) );
690 wxString msg =
_(
"This operation cannot be undone.\n\n"
691 "Do you want to save the current document before proceeding?" );
693 if(
IsOK(
this, msg ) )
705 wxString msg =
_(
"This operation replaces the contents of the current schematic, "
706 "which will be permanently lost.\n\n"
707 "Do you want to proceed?" );
709 if( !
IsOK(
this, msg ) )
715 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
717 wxString fileFiltersStr;
718 wxString allWildcardsStr;
720 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
722 if(
fileType == SCH_IO_MGR::SCH_KICAD ||
fileType == SCH_IO_MGR::SCH_LEGACY )
735 if( !fileFiltersStr.IsEmpty() )
736 fileFiltersStr += wxChar(
'|' );
744 fileFiltersStr =
_(
"All supported formats" ) + wxS(
"|" ) + allWildcardsStr + wxS(
"|" )
747 wxFileDialog dlg(
this,
_(
"Import Schematic" ),
path, wxEmptyString, fileFiltersStr,
748 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
751 dlg.SetCustomizeHook( importOptions );
753 if( dlg.ShowModal() == wxID_CANCEL )
773 wxFileName projectFn( dlg.GetPath() );
780 wxFileName fn = dlg.GetPath();
782 if( !fn.IsFileReadable() )
784 wxLogError(
_(
"Insufficient permissions to read file '%s'." ), fn.GetFullPath() );
788 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
790 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
797 if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
804 if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
806 wxLogError(
_(
"No loader can read the specified file: '%s'." ), fn.GetFullPath() );
821 wxFileName schematicFileName;
822 wxFileName oldFileName;
827 wxCHECK( screen,
false );
830 if( aSavePath.IsEmpty() )
835 oldFileName = schematicFileName;
843 wxFileName projectFile( schematicFileName );
847 if( projectFile.FileExists() )
854 wxString tempFile = wxFileName::CreateTempFileName( wxS(
"eeschema" ) );
857 wxLogTrace(
traceAutoSave, wxS(
"Saving file " ) + schematicFileName.GetFullPath() );
863 schematicFileName.GetFullPath() );
865 if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
866 pluginType = SCH_IO_MGR::SCH_KICAD;
872 pi->SaveSchematicFile( tempFile, aSheet, &
Schematic() );
877 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
878 schematicFileName.GetFullPath(),
882 msg.Printf(
_(
"Failed to create temporary file '%s'." ),
887 wxRemoveFile( tempFile );
898 success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
902 msg.Printf(
_(
"Error saving schematic file '%s'.\n"
903 "Failed to rename temporary file '%s'." ),
904 schematicFileName.GetFullPath(),
908 msg.Printf(
_(
"Failed to rename temporary file '%s'." ),
917 wxFileName autoSaveFileName = schematicFileName;
920 if( autoSaveFileName.FileExists() )
923 wxS(
"Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
926 wxRemoveFile( autoSaveFileName.GetFullPath() );
931 msg.Printf(
_(
"File '%s' saved." ), screen->
GetFileName() );
932 SetStatusText( msg, 0 );
950 bool updateFileHistory =
false;
951 bool createNewProject =
false;
955 wxFileName fn = fileName;
959 std::unordered_map<SCH_SCREEN*, wxString> filenameMap;
962 if(
Prj().IsNullProject() || aSaveAs )
965 wxCHECK(
Kiface().IsSingle() || aSaveAs,
false );
967 wxFileName newFileName;
968 wxFileName savePath(
Prj().GetProjectFullName() );
970 if( !savePath.IsOk() || !savePath.IsDirWritable() )
974 if( !savePath.IsOk() || !savePath.IsDirWritable() )
978 if( savePath.HasExt() )
981 savePath.SetName( wxEmptyString );
983 wxFileDialog dlg(
this,
_(
"Schematic Files" ), savePath.GetPath(), savePath.GetFullName(),
985 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
990 if(
Kiface().IsSingle() || aSaveAs )
992 dlg.SetCustomizeHook( newProjectHook );
995 if( dlg.ShowModal() == wxID_CANCEL )
1000 if( ( !newFileName.DirExists() && !newFileName.Mkdir() ) ||
1001 !newFileName.IsDirWritable() )
1003 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
1004 "Make sure you have write permissions and try again." ),
1005 newFileName.GetPath() );
1007 wxMessageDialog dlgBadPath(
this, msg,
_(
"Error" ),
1008 wxOK | wxICON_EXCLAMATION | wxCENTER );
1010 dlgBadPath.ShowModal();
1021 updateFileHistory =
true;
1029 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1033 wxCHECK2( screen,
continue );
1036 if( screen ==
Schematic().RootScreen() )
1044 if( tmp.FileExists() )
1047 if( tmp.GetPath().IsEmpty() )
1049 tmp.SetPath( newFileName.GetPath() );
1051 else if( tmp.GetPath() == fn.GetPath() )
1053 tmp.SetPath( newFileName.GetPath() );
1055 else if( tmp.GetPath().StartsWith( fn.GetPath() ) )
1059 wxString newPath = newFileName.GetPath();
1060 newPath += tmp.GetPath().Right( fn.GetPath().Length() );
1061 tmp.SetPath( newPath );
1065 wxS(
"Moving schematic from '%s' to '%s'." ),
1067 tmp.GetFullPath() );
1069 if( !tmp.DirExists() && !tmp.Mkdir() )
1071 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
1072 "Make sure you have write permissions and try again." ),
1073 newFileName.GetPath() );
1075 wxMessageDialog dlgBadFilePath(
this, msg,
_(
"Error" ),
1076 wxOK | wxICON_EXCLAMATION | wxCENTER );
1078 dlgBadFilePath.ShowModal();
1083 filenameMap[screen] = tmp.GetFullPath();
1091 if( !sheet.Last()->IsRootSheet() )
1092 sheet.MakeFilePathRelativeToParentSheet();
1095 else if( !fn.FileExists() )
1098 updateFileHistory =
true;
1105 if( filenameMap.empty() || !saveCopy )
1107 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1112 wxArrayString overwrittenFiles;
1113 wxArrayString lockedFiles;
1115 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1119 wxCHECK2( screen,
continue );
1122 wxFileName tmpFn = filenameMap[screen];
1127 if( tmpFn.FileExists() && !tmpFn.IsFileWritable() )
1128 lockedFiles.Add( tmpFn.GetFullPath() );
1135 if( tmpFn.FileExists() )
1136 overwrittenFiles.Add( tmpFn.GetFullPath() );
1139 if( !lockedFiles.IsEmpty() )
1141 for(
const wxString& lockedFile : lockedFiles )
1146 msg +=
"\n" + lockedFile;
1149 wxRichMessageDialog dlg(
this, wxString::Format(
_(
"Failed to save %s." ),
1151 _(
"Locked File Warning" ),
1152 wxOK | wxICON_WARNING | wxCENTER );
1153 dlg.SetExtendedMessage(
_(
"You do not have write permissions to:\n\n" ) + msg );
1159 if( !overwrittenFiles.IsEmpty() )
1161 for(
const wxString& overwrittenFile : overwrittenFiles )
1164 msg = overwrittenFile;
1166 msg +=
"\n" + overwrittenFile;
1169 wxRichMessageDialog dlg(
this,
_(
"Saving will overwrite existing files." ),
1170 _(
"Save Warning" ),
1171 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER |
1172 wxICON_EXCLAMATION );
1173 dlg.ShowDetailedText(
_(
"The following files will be overwritten:\n\n" ) + msg );
1174 dlg.SetOKCancelLabels( wxMessageDialog::ButtonLabel(
_(
"Overwrite Files" ) ),
1175 wxMessageDialog::ButtonLabel(
_(
"Abort Project Save" ) ) );
1177 if( dlg.ShowModal() == wxID_CANCEL )
1183 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1187 wxCHECK2( screen,
continue );
1190 wxFileName tmpFn = filenameMap[screen];
1194 updateFileHistory =
true;
1202 if( !sheetFileName.IsOk()
1207 sheet->
SetFileName( sheetFileName.GetFullPath() );
1211 filenameMap[screen] = tmpFn.GetFullPath();
1223 if( sheets.size() == 1 )
1229 if( !saveCopy && tmpFn.GetFullPath() != screen->
GetFileName() )
1239 if( !aSaveAs && !success )
1242 if( aSaveAs && success )
1245 if( updateFileHistory )
1256 wxCHECK2( sheet,
continue );
1263 wxCHECK2( screen,
continue );
1265 sheets.emplace_back( std::make_pair( screen->
GetUuid(), sheet->
GetName() ) );
1269 sheets.emplace_back( std::make_pair( sheet->
m_Uuid, sheet->
GetName() ) );
1273 wxASSERT( filenameMap.count(
Schematic().RootScreen() ) );
1274 wxFileName projectPath( filenameMap.at(
Schematic().RootScreen() ) );
1277 if(
Prj().IsNullProject() || ( aSaveAs && !saveCopy ) )
1282 else if( saveCopy && createNewProject )
1292 if( !
Kiface().IsSingle() )
1297 SetStatusText( msg, 0 );
1312 wxFileName fn = tmpFileName;
1320 bool autoSaveOk =
true;
1322 if( fn.GetPath().IsEmpty() )
1323 tmp.AssignDir(
Prj().GetProjectPath() );
1325 tmp.AssignDir( fn.GetPath() );
1333 wxString title = GetTitle();
1335 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1378 wxFileName filename( aFileName );
1379 wxFileName newfilename;
1380 SCH_IO_MGR::SCH_FILE_T
fileType = (SCH_IO_MGR::SCH_FILE_T) aFileType;
1382 wxCommandEvent changingEvt( EDA_EVT_SCHEMATIC_CHANGING );
1383 ProcessEventLocally( changingEvt );
1387 case SCH_IO_MGR::SCH_ALTIUM:
1388 case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
1389 case SCH_IO_MGR::SCH_EAGLE:
1390 case SCH_IO_MGR::SCH_LTSPICE:
1391 case SCH_IO_MGR::SCH_EASYEDA:
1392 case SCH_IO_MGR::SCH_EASYEDAPRO:
1395 wxCHECK_MSG( filename.IsAbsolute(),
false,
1396 wxS(
"Import schematic: path is not absolute!" ) );
1407 this, std::placeholders::_1 ) );
1410 if(
eeconfig()->m_System.show_import_issues )
1415 pi->SetProgressReporter( &progressReporter );
1427 errorReporter.ShowModal();
1436 newfilename.SetPath(
Prj().GetProjectPath() );
1437 newfilename.SetName(
Prj().GetProjectName() );
1463 wxString msg = wxString::Format(
_(
"Error loading schematic '%s'." ), aFileName );
1466 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1469 catch(
const std::exception& exc )
1474 wxString msg = wxString::Format(
_(
"Unhandled exception occurred loading schematic "
1475 "'%s'." ), aFileName );
1478 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1491 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGED );
1492 ProcessEventLocally( e );
1496 wxCHECK2( listener,
continue );
1500 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
1503 win->HandleWindowEvent( e );
1505 listener->SafelyProcessEvent( e );
1531 if( simFrame && !simFrame->Close() )
1534 if( screen->IsContentModified() )
1557 wxLogTrace(
traceAutoSave,
"Creating auto save file %s", autoSaveFileName.GetFullPath() );
1559 wxCHECK( autoSaveFileName.IsDirWritable(),
false );
1563 std::vector< wxString > autoSavedFiles;
1565 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1575 autoSavedFiles.emplace_back( fn.GetFullPath() );
1578 wxTextFile autoSaveFile( autoSaveFileName.GetFullPath() );
1580 if( autoSaveFileName.FileExists() && !wxRemoveFile( autoSaveFileName.GetFullPath() ) )
1582 wxLogTrace(
traceAutoSave,
"Error removing auto save file %s",
1583 autoSaveFileName.GetFullPath() );
1589 if( autoSavedFiles.empty() )
1592 if( !autoSaveFile.Create() )
1595 for(
const wxString& fileName : autoSavedFiles )
1597 wxLogTrace(
traceAutoSave,
"Adding auto save file %s to %s",
1598 fileName, autoSaveFileName.GetName() );
1599 autoSaveFile.AddLine( fileName );
1602 if( !autoSaveFile.Write() )
1605 wxLogTrace(
traceAutoSave,
"Auto save file '%s' written", autoSaveFileName.GetFullName() );
1611void removeFile(
const wxString& aFilename, wxArrayString& aUnremoved )
1613 wxLogTrace(
traceAutoSave, wxS(
"Removing auto save file " ) + aFilename );
1615 if( wxFileExists( aFilename ) && !wxRemoveFile( aFilename ) )
1616 aUnremoved.Add( aFilename );
1622 if( !
Pgm().IsGUI() )
1625 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1628 wxS(
"Checking for auto save file " ) + aFileName.GetFullPath() );
1630 if( !aFileName.FileExists() )
1634 "Well this is potentially embarrassing!\n"
1635 "It appears that the last time you were editing one or more of the schematic files\n"
1636 "were not saved properly. Do you wish to restore the last saved edits you made?" );
1638 int response = wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
1641 wxTextFile fileList( aFileName.GetFullPath() );
1643 if( !fileList.Open() )
1645 msg.Printf(
_(
"The file '%s' could not be opened.\n"
1646 "Manual recovery of automatically saved files is required." ),
1647 aFileName.GetFullPath() );
1649 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1653 if( response == wxYES )
1655 wxArrayString unrecoveredFiles;
1657 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1659 wxFileName recoveredFn = fn;
1660 wxString tmp = recoveredFn.GetName();
1664 recoveredFn.SetName( tmp );
1666 wxFileName backupFn = recoveredFn;
1670 wxLogTrace(
traceAutoSave, wxS(
"Recovering auto save file:\n"
1671 " Original file: '%s'\n"
1672 " Backup file: '%s'\n"
1673 " Auto save file: '%s'" ),
1674 recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
1676 if( !wxFileExists( fn ) )
1678 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1682 else if( recoveredFn.Exists()
1683 && !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
1685 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1688 else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
1690 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1694 if( !unrecoveredFiles.IsEmpty() )
1696 msg =
_(
"The following automatically saved file(s) could not be restored\n" );
1698 for(
size_t i = 0; i < unrecoveredFiles.GetCount(); i++ )
1699 msg += unrecoveredFiles[i] + wxS(
"\n" );
1701 msg +=
_(
"Manual recovery will be required to restore the file(s) above." );
1702 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
1706 wxArrayString unremovedFiles;
1707 removeFile( aFileName.GetFullPath(), unremovedFiles );
1709 if( !unremovedFiles.IsEmpty() )
1711 msg.Printf(
_(
"The autosave file '%s' could not be removed.\n"
1712 "Manual removal will be required." ),
1713 unremovedFiles[0] );
1715 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1727 if( !
Pgm().IsGUI() )
1730 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1732 if( !aFileName.FileExists() )
1735 wxTextFile fileList( aFileName.GetFullPath() );
1736 wxArrayString unremovedFiles;
1738 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1741 removeFile( aFileName.GetFullPath(), unremovedFiles );
1743 if( !unremovedFiles.IsEmpty() )
1745 wxString msg =
_(
"The following automatically saved file(s) could not be removed\n" );
1747 for(
size_t i = 0; i < unremovedFiles.GetCount(); i++ )
1748 msg += unremovedFiles[i] + wxS(
"\n" );
1750 msg +=
_(
"Manual removal will be required for the file(s) above." );
1751 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1758 static wxString autoSaveFileName( wxS(
"#auto_saved_files#" ) );
1760 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)
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
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()
static function: returns the instance of DS_DATA_MODEL used in the application
void LoadWindowState(const wxString &aFileName)
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)
Checks 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
static const TOOL_EVENT SelectedEvent
bool GetCreateNewProject() const
Gets if this hook has attached controls to a dialog box.
bool IsAttachedToDialog() const
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.
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)
virtual void SetReadOnly(bool aReadOnly=true)
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
virtual PROJECT_FILE & GetProjectFile() const
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
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.
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
CONNECTION_GRAPH * ConnectionGraph() const override
void FixupJunctions()
Add junctions to this schematic where required.
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
void SetProject(PROJECT *aPrj)
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const override
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
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
virtual void Revert() override
void DisplaySheet(SCH_SCREEN *aScreen)
Handle actions specific to the schematic editor.
bool LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet, const wxString &aFileName)
Load a the KiCad schematic file aFileName into the sheet aSheet.
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.
bool doAutoSave() override
Save the schematic files that have been modified and not yet saved.
bool importFile(const wxString &aFileName, int aFileType, const STRING_UTF8_MAP *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void UpdateHierarchyNavigator(bool aRefreshNetNavigator=true)
Update the hierarchy navigation tree and history.
std::vector< wxEvtHandler * > m_schematicChangeListeners
void HardRedraw() override
Rebuild the GAL and redraw the screen.
void OnAppendProject(wxCommandEvent &event)
SCH_SHEET_PATH & GetCurrentSheet() const
SCHEMATIC & Schematic() const
void updateTitle()
Set the main window title bar text.
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 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.
bool AddSheetAndUpdateDisplay(const wxString aFullFileName)
Add a sheet file into the current sheet and updates display.
void ClearRepeatItemsList()
Clear the list of items which are to be repeated with the insert key.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
void initScreenZoom()
Initialize the zoom value of the current screen and mark the screen as zoom-initialized.
void OnImportProject(wxCommandEvent &event)
bool AppendSchematic()
Import a KiCad schematic into the current sheet.
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
Saves 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()
built the list of sheet paths sharing a screen for each screen in use
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()
Gets 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.
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.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Sets the currently loaded project path and saves it (pointers remain valid) Note that this will not m...
void SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Saves a copy of the current project under the given path.
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Saves a loaded project.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Loads a project or sets up a new project with a specified path.
bool UnloadProject(PROJECT *aProject, bool aSave=true)
Saves, unloads and unregisters the given PROJECT.
bool TriggerBackupIfNeeded(REPORTER &aReporter) const
Calls 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 name/value tuple with unique names and optional values.
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)
static void ResolvePossibleSymlinks(wxFileName &aFilename)
void Flush()
Build the HTML messages page.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
void AddCloseButton(const wxString &aTooltip=_("Hide this message."))
Add the default close button to the infobar on the right side.
MESSAGE_TYPE GetMessageType() const
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
A wrapper for reporting to a wxString object.
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 DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
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.
This file is part of the common library.
static bool empty(const wxTextEntryBase *aCtrl)
#define ENDPOINT
ends. (Used to support dragging.)
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define STARTPOINT
When a line is selected, these flags indicate which.
void removeFile(const wxString &aFilename, wxArrayString &aUnremoved)
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 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.