69#include <wx/filedlg.h>
71#include <wx/stdpaths.h>
82#include "widgets/filedlg_hook_save_project.h"
95 if( aFileSet.size() != 1 )
97 msg.Printf(
"Eeschema:%s() takes only a single filename.", __WXFUNCTION__ );
102 wxString fullFileName( aFileSet[0] );
103 wxFileName wx_filename( fullFileName );
106 wxASSERT_MSG( wx_filename.IsAbsolute(), wxS(
"Path is not absolute!" ) );
110 msg.Printf(
_(
"Schematic '%s' is already open by '%s' at '%s'." ), fullFileName,
126 wxFileName pro = fullFileName;
129 bool is_new = !wxFileName::IsFileReadable( fullFileName );
135 msg.Printf(
_(
"Schematic '%s' does not exist. Do you wish to create it?" ),
138 if( !
IsOK(
this, msg ) )
142 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGING );
143 ProcessEventLocally( e );
153 SetStatusText( wxEmptyString );
157 :
_(
"Loading Schematic" ), 1 );
161 if( differentProject )
163 if( !
Prj().IsNullProject() )
174 wxFileName legacyPro( pro );
179 if( !pro.Exists() && !legacyPro.Exists() && !( aCtl &
KICTL_CREATE ) )
187 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
217 rfn.MakeRelativeTo(
Prj().GetProjectPath() );
227 if( is_new || schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
233 if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
235 msg.Printf(
_(
"Unsupported schematic file '%s'." ), fullFileName );
236 progressReporter.Hide();
242 wxFileName autoSaveFn = fullFileName;
245 autoSaveFn.ClearExt();
261 pi->SetProgressReporter( &progressReporter );
263 bool failedLoad =
false;
273 wxLogDebug(
"Loaded schematic with root sheet UUID %s",
Schematic().Root().m_Uuid.AsString() );
276 if( !pi->GetError().IsEmpty() )
279 "occurred attempting to load hierarchical sheets." ),
285 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName);
286 progressReporter.Hide();
293 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName);
294 progressReporter.Hide();
299 catch(
const std::bad_alloc& )
301 msg.Printf(
_(
"Memory exhausted loading schematic '%s'." ), fullFileName );
302 progressReporter.Hide();
320 msg.Printf(
_(
"Failed to load '%s'." ), fullFileName );
333 _(
"An error was found when loading the schematic that has "
334 "been automatically fixed. Please save the schematic to "
335 "repair the broken file or it may not be usable with other "
336 "versions of KiCad." ) );
347 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
352 std::vector<SCH_ITEM*> deleted;
354 for(
SCH_ITEM* item : screen->Items() )
359 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
363 wire->SetEndPoint( entry->
GetEnd() );
365 screen->Append( wire.release() );
366 deleted.push_back( item );
371 screen->Remove( item );
387 wxArrayString libNames;
391 if( !libNames.IsEmpty() )
393 if(
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
395 wxRichMessageDialog invalidLibDlg(
397 _(
"Illegal entry found in project file symbol library list." ),
398 _(
"Project Load Warning" ),
399 wxOK | wxCENTER | wxICON_EXCLAMATION );
400 invalidLibDlg.ShowDetailedText(
401 _(
"Symbol libraries defined in the project file symbol library "
402 "list are no longer supported and will be removed.\n\n"
403 "This may cause broken symbol library links under certain "
405 invalidLibDlg.ShowCheckBox(
_(
"Do not show this dialog again." ) );
406 invalidLibDlg.ShowModal();
408 !invalidLibDlg.IsCheckBoxChecked();
419 editor->RescueSymbolLibTableProject(
false );
429 wxFileName cacheFn = pro;
431 cacheFn.SetName( cacheFn.GetName() +
"-cache" );
434 msg.Printf(
_(
"The project symbol library cache file '%s' was not found." ),
435 cacheFn.GetFullName() );
436 extMsg =
_(
"This can result in a broken schematic under certain conditions. "
437 "If the schematic does not have any missing symbols upon opening, "
438 "save it immediately before making any changes to prevent data "
439 "loss. If there are missing symbols, either manual recovery of "
440 "the schematic or recovery of the symbol cache library file and "
441 "reloading the schematic is required." );
443 wxMessageDialog dlgMissingCache(
this, msg,
_(
"Warning" ),
444 wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
445 dlgMissingCache.SetExtendedMessage( extMsg );
446 dlgMissingCache.SetOKCancelLabels(
447 wxMessageDialog::ButtonLabel(
_(
"Load Without Cache File" ) ),
448 wxMessageDialog::ButtonLabel(
_(
"Abort" ) ) );
450 if( dlgMissingCache.ShowModal() == wxID_CANCEL )
464 "It will be converted to the new format when saved." ),
472 screen->FixLegacyPowerSymbolMismatches();
484 "It will be converted to the new format when saved." ),
489 screen->UpdateLocalLibSymbolLinks();
492 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
495 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
498 if(
Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
500 screen->FixLegacyPowerSymbolMismatches();
503 screen->MigrateSimModels();
521 if(
Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() > 0 )
550 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
560 wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
561 ProcessEventLocally( changedEvt );
565 wxCHECK2( listener,
continue );
569 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
572 win->HandleWindowEvent( e );
574 listener->SafelyProcessEvent( e );
582 if( fn.FileExists() && !fn.IsFileWritable() )
607 wxLogError( wxS(
"Document not ready, cannot import" ) );
612 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
614 wxFileDialog dlg(
this,
_(
"Insert Schematic" ),
path, wxEmptyString,
617 if( dlg.ShowModal() == wxID_CANCEL )
664 commit.
Push(
_(
"Import Schematic Sheet Content..." ) );
676 wxString msg =
_(
"This operation cannot be undone.\n\n"
677 "Do you want to save the current document before proceeding?" );
679 if(
IsOK(
this, msg ) )
691 wxString msg =
_(
"This operation replaces the contents of the current schematic, "
692 "which will be permanently lost.\n\n"
693 "Do you want to proceed?" );
695 if( !
IsOK(
this, msg ) )
701 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
703 wxString fileFiltersStr;
704 wxString allWildcardsStr;
706 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
708 if(
fileType == SCH_IO_MGR::SCH_KICAD ||
fileType == SCH_IO_MGR::SCH_LEGACY )
721 if( !fileFiltersStr.IsEmpty() )
722 fileFiltersStr += wxChar(
'|' );
730 fileFiltersStr =
_(
"All supported formats" ) + wxS(
"|" ) + allWildcardsStr + wxS(
"|" )
733 wxFileDialog dlg(
this,
_(
"Import Schematic" ),
path, wxEmptyString, fileFiltersStr,
734 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
736 if( dlg.ShowModal() == wxID_CANCEL )
753 wxFileName projectFn( dlg.GetPath() );
760 wxFileName fn = dlg.GetPath();
762 if( !fn.IsFileReadable() )
764 wxLogError(
_(
"Insufficient permissions to read file '%s'." ), fn.GetFullPath() );
768 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
770 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
777 if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
784 if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
786 wxLogError(
_(
"No loader can read the specified file: '%s'." ), fn.GetFullPath() );
801 wxFileName schematicFileName;
802 wxFileName oldFileName;
807 wxCHECK( screen,
false );
810 wxCHECK( !aSavePath.IsEmpty(),
false );
814 oldFileName = schematicFileName;
822 wxFileName projectFile( schematicFileName );
826 if( projectFile.FileExists() )
833 wxString tempFile = wxFileName::CreateTempFileName( wxS(
"eeschema" ) );
836 wxLogTrace(
traceAutoSave, wxS(
"Saving file " ) + schematicFileName.GetFullPath() );
842 schematicFileName.GetFullPath() );
844 if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
845 pluginType = SCH_IO_MGR::SCH_KICAD;
851 pi->SaveSchematicFile( tempFile, aSheet, &
Schematic() );
856 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
857 schematicFileName.GetFullPath(),
861 msg.Printf(
_(
"Failed to create temporary file '%s'." ),
866 wxRemoveFile( tempFile );
877 success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
881 msg.Printf(
_(
"Error saving schematic file '%s'.\n"
882 "Failed to rename temporary file '%s'." ),
883 schematicFileName.GetFullPath(),
887 msg.Printf(
_(
"Failed to rename temporary file '%s'." ),
896 wxFileName autoSaveFileName = schematicFileName;
899 if( autoSaveFileName.FileExists() )
902 wxS(
"Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
905 wxRemoveFile( autoSaveFileName.GetFullPath() );
910 msg.Printf(
_(
"File '%s' saved." ), screen->
GetFileName() );
911 SetStatusText( msg, 0 );
929 bool updateFileHistory =
false;
930 bool createNewProject =
false;
934 wxFileName fn = fileName;
938 std::unordered_map<SCH_SCREEN*, wxString> filenameMap;
941 if(
Prj().IsNullProject() || aSaveAs )
944 wxCHECK(
Kiface().IsSingle() || aSaveAs,
false );
946 wxFileName newFileName;
947 wxFileName savePath(
Prj().GetProjectFullName() );
949 if( !savePath.IsOk() || !savePath.IsDirWritable() )
953 if( !savePath.IsOk() || !savePath.IsDirWritable() )
957 if( savePath.HasExt() )
960 savePath.SetName( wxEmptyString );
962 wxFileDialog dlg(
this,
_(
"Schematic Files" ), savePath.GetPath(), savePath.GetFullName(),
964 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
969 if(
Kiface().IsSingle() || aSaveAs )
971 dlg.SetCustomizeHook( newProjectHook );
974 if( dlg.ShowModal() == wxID_CANCEL )
979 if( ( !newFileName.DirExists() && !newFileName.Mkdir() ) ||
980 !newFileName.IsDirWritable() )
982 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
983 "Make sure you have write permissions and try again." ),
984 newFileName.GetPath() );
986 wxMessageDialog dlgBadPath(
this, msg,
_(
"Error" ),
987 wxOK | wxICON_EXCLAMATION | wxCENTER );
989 dlgBadPath.ShowModal();
1000 updateFileHistory =
true;
1008 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1012 wxCHECK2( screen,
continue );
1015 if( screen ==
Schematic().RootScreen() )
1023 if( tmp.FileExists() )
1026 if( tmp.GetPath().IsEmpty() )
1028 tmp.SetPath( newFileName.GetPath() );
1030 else if( tmp.GetPath() == fn.GetPath() )
1032 tmp.SetPath( newFileName.GetPath() );
1034 else if( tmp.GetPath().StartsWith( fn.GetPath() ) )
1038 wxString newPath = newFileName.GetPath();
1039 newPath += tmp.GetPath().Right( fn.GetPath().Length() );
1040 tmp.SetPath( newPath );
1044 wxS(
"Moving schematic from '%s' to '%s'." ),
1046 tmp.GetFullPath() );
1048 if( !tmp.DirExists() && !tmp.Mkdir() )
1050 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
1051 "Make sure you have write permissions and try again." ),
1052 newFileName.GetPath() );
1054 wxMessageDialog dlgBadFilePath(
this, msg,
_(
"Error" ),
1055 wxOK | wxICON_EXCLAMATION | wxCENTER );
1057 dlgBadFilePath.ShowModal();
1062 filenameMap[screen] = tmp.GetFullPath();
1072 if( sheet.Last()->IsRootSheet() )
1075 sheet.MakeFilePathRelativeToParentSheet();
1078 else if( !fn.FileExists() )
1081 updateFileHistory =
true;
1083 else if( !
Schematic().GetSheets().IsModified() )
1088 if( filenameMap.empty() || !saveCopy )
1090 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1095 wxArrayString overwrittenFiles;
1096 wxArrayString lockedFiles;
1098 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1102 wxCHECK2( screen,
continue );
1105 wxFileName tmpFn = filenameMap[screen];
1110 if( tmpFn.FileExists() && !tmpFn.IsFileWritable() )
1111 lockedFiles.Add( tmpFn.GetFullPath() );
1118 if( tmpFn.FileExists() )
1119 overwrittenFiles.Add( tmpFn.GetFullPath() );
1122 if( !lockedFiles.IsEmpty() )
1124 for(
const wxString& lockedFile : lockedFiles )
1129 msg +=
"\n" + lockedFile;
1132 wxRichMessageDialog dlg(
this, wxString::Format(
_(
"Failed to save %s." ),
1134 _(
"Locked File Warning" ),
1135 wxOK | wxICON_WARNING | wxCENTER );
1136 dlg.SetExtendedMessage(
_(
"You do not have write permissions to:\n\n" ) + msg );
1142 if( !overwrittenFiles.IsEmpty() )
1144 for(
const wxString& overwrittenFile : overwrittenFiles )
1147 msg = overwrittenFile;
1149 msg +=
"\n" + overwrittenFile;
1152 wxRichMessageDialog dlg(
this,
_(
"Saving will overwrite existing files." ),
1153 _(
"Save Warning" ),
1154 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER |
1155 wxICON_EXCLAMATION );
1156 dlg.ShowDetailedText(
_(
"The following files will be overwritten:\n\n" ) + msg );
1157 dlg.SetOKCancelLabels( wxMessageDialog::ButtonLabel(
_(
"Overwrite Files" ) ),
1158 wxMessageDialog::ButtonLabel(
_(
"Abort Project Save" ) ) );
1160 if( dlg.ShowModal() == wxID_CANCEL )
1166 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1170 wxCHECK2( screen,
continue );
1173 wxFileName tmpFn = filenameMap[screen];
1177 updateFileHistory =
true;
1185 if( !sheetFileName.IsOk()
1190 sheet->
SetFileName( sheetFileName.GetFullPath() );
1194 filenameMap[screen] = tmpFn.GetFullPath();
1206 if( sheets.size() == 1 )
1212 if( !saveCopy && tmpFn.GetFullPath() != screen->
GetFileName() )
1222 if( !aSaveAs && !success )
1225 if( aSaveAs && success )
1228 if( updateFileHistory )
1239 wxCHECK2( sheet,
continue );
1246 wxCHECK2( screen,
continue );
1248 sheets.emplace_back( std::make_pair( screen->
GetUuid(), sheet->
GetName() ) );
1252 sheets.emplace_back( std::make_pair( sheet->
m_Uuid, sheet->
GetName() ) );
1256 wxASSERT( filenameMap.count(
Schematic().RootScreen() ) );
1257 wxFileName projectPath( filenameMap.at(
Schematic().RootScreen() ) );
1260 if(
Prj().IsNullProject() || ( aSaveAs && !saveCopy ) )
1265 else if( saveCopy && createNewProject )
1275 if( !
Kiface().IsSingle() )
1280 SetStatusText( msg, 0 );
1295 wxFileName fn = tmpFileName;
1303 bool autoSaveOk =
true;
1305 if( fn.GetPath().IsEmpty() )
1306 tmp.AssignDir(
Prj().GetProjectPath() );
1308 tmp.AssignDir( fn.GetPath() );
1316 wxString title = GetTitle();
1318 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1361 wxFileName filename( aFileName );
1362 wxFileName newfilename;
1364 SCH_IO_MGR::SCH_FILE_T
fileType = (SCH_IO_MGR::SCH_FILE_T) aFileType;
1366 wxCommandEvent changingEvt( EDA_EVT_SCHEMATIC_CHANGING );
1367 ProcessEventLocally( changingEvt );
1371 case SCH_IO_MGR::SCH_ALTIUM:
1372 case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
1373 case SCH_IO_MGR::SCH_EAGLE:
1374 case SCH_IO_MGR::SCH_LTSPICE:
1375 case SCH_IO_MGR::SCH_EASYEDA:
1376 case SCH_IO_MGR::SCH_EASYEDAPRO:
1379 wxCHECK_MSG( filename.IsAbsolute(),
false,
1380 wxS(
"Import schematic: path is not absolute!" ) );
1391 if( projectChooserPlugin )
1395 std::placeholders::_1 ) );
1399 pi->SetProgressReporter( &progressReporter );
1402 pi->LoadSchematicFile( aFileName, &
Schematic(),
nullptr, aProperties );
1411 errorReporter.ShowModal();
1420 newfilename.SetPath(
Prj().GetProjectPath() );
1421 newfilename.SetName(
Prj().GetProjectName() );
1447 wxString msg = wxString::Format(
_(
"Error loading schematic '%s'." ), aFileName );
1450 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1453 catch(
const std::exception& exc )
1458 wxString msg = wxString::Format(
_(
"Unhandled exception occurred loading schematic "
1459 "'%s'." ), aFileName );
1462 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1474 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGED );
1475 ProcessEventLocally( e );
1479 wxCHECK2( listener,
continue );
1483 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
1486 win->HandleWindowEvent( e );
1488 listener->SafelyProcessEvent( e );
1514 if( simFrame && !simFrame->Close() )
1517 if( screen->IsContentModified() )
1540 wxLogTrace(
traceAutoSave,
"Creating auto save file %s", autoSaveFileName.GetFullPath() );
1542 wxCHECK( autoSaveFileName.IsDirWritable(),
false );
1546 std::vector< wxString > autoSavedFiles;
1548 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1558 autoSavedFiles.emplace_back( fn.GetFullPath() );
1561 wxTextFile autoSaveFile( autoSaveFileName.GetFullPath() );
1563 if( autoSaveFileName.FileExists() && !wxRemoveFile( autoSaveFileName.GetFullPath() ) )
1565 wxLogTrace(
traceAutoSave,
"Error removing auto save file %s",
1566 autoSaveFileName.GetFullPath() );
1572 if( autoSavedFiles.empty() )
1575 if( !autoSaveFile.Create() )
1578 for(
const wxString& fileName : autoSavedFiles )
1580 wxLogTrace(
traceAutoSave,
"Adding auto save file %s to %s",
1581 fileName, autoSaveFileName.GetName() );
1582 autoSaveFile.AddLine( fileName );
1585 if( !autoSaveFile.Write() )
1588 wxLogTrace(
traceAutoSave,
"Auto save file '%s' written", autoSaveFileName.GetFullName() );
1594void removeFile(
const wxString& aFilename, wxArrayString& aUnremoved )
1596 wxLogTrace(
traceAutoSave, wxS(
"Removing auto save file " ) + aFilename );
1598 if( wxFileExists( aFilename ) && !wxRemoveFile( aFilename ) )
1599 aUnremoved.Add( aFilename );
1605 if( !
Pgm().IsGUI() )
1608 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1611 wxS(
"Checking for auto save file " ) + aFileName.GetFullPath() );
1613 if( !aFileName.FileExists() )
1617 "Well this is potentially embarrassing!\n"
1618 "It appears that the last time you were editing one or more of the schematic files\n"
1619 "were not saved properly. Do you wish to restore the last saved edits you made?" );
1621 int response = wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
1624 wxTextFile fileList( aFileName.GetFullPath() );
1626 if( !fileList.Open() )
1628 msg.Printf(
_(
"The file '%s' could not be opened.\n"
1629 "Manual recovery of automatically saved files is required." ),
1630 aFileName.GetFullPath() );
1632 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1636 if( response == wxYES )
1638 wxArrayString unrecoveredFiles;
1640 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1642 wxFileName recoveredFn = fn;
1643 wxString tmp = recoveredFn.GetName();
1647 recoveredFn.SetName( tmp );
1649 wxFileName backupFn = recoveredFn;
1653 wxLogTrace(
traceAutoSave, wxS(
"Recovering auto save file:\n"
1654 " Original file: '%s'\n"
1655 " Backup file: '%s'\n"
1656 " Auto save file: '%s'" ),
1657 recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
1659 if( !wxFileExists( fn ) )
1661 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1665 else if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
1667 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1670 else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
1672 unrecoveredFiles.Add( recoveredFn.GetFullPath() );
1676 if( !unrecoveredFiles.IsEmpty() )
1678 msg =
_(
"The following automatically saved file(s) could not be restored\n" );
1680 for(
size_t i = 0; i < unrecoveredFiles.GetCount(); i++ )
1681 msg += unrecoveredFiles[i] + wxS(
"\n" );
1683 msg +=
_(
"Manual recovery will be required to restore the file(s) above." );
1684 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
1688 wxArrayString unremovedFiles;
1689 removeFile( aFileName.GetFullPath(), unremovedFiles );
1691 if( !unremovedFiles.IsEmpty() )
1693 msg.Printf(
_(
"The autosave file '%s' could not be removed.\n"
1694 "Manual removal will be required." ),
1695 unremovedFiles[0] );
1697 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1709 if( !
Pgm().IsGUI() )
1712 wxCHECK_RET( aFileName.IsOk(), wxS(
"Invalid file name!" ) );
1714 if( !aFileName.FileExists() )
1717 wxTextFile fileList( aFileName.GetFullPath() );
1718 wxArrayString unremovedFiles;
1720 for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
1723 removeFile( aFileName.GetFullPath(), unremovedFiles );
1725 if( !unremovedFiles.IsEmpty() )
1727 wxString msg =
_(
"The following automatically saved file(s) could not be removed\n" );
1729 for(
size_t i = 0; i < unremovedFiles.GetCount(); i++ )
1730 msg += unremovedFiles[i] + wxS(
"\n" );
1732 msg +=
_(
"Manual removal will be required for the file(s) above." );
1733 wxMessageBox( msg,
Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
this );
1740 static wxString autoSaveFileName( wxS(
"#auto_saved_files#" ) );
1742 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 > GetSelectionsModal(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
bool GetCreateNewProject() const
Gets if this hook has attached controls to a dialog box.
bool IsAttachedToDialog() 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.
virtual void RegisterChooseProjectCallback(CHOOSE_PROJECT_HANDLER aChooseProjectHandler)
Register a different handler to be called when a non-KiCad project contains multiple PCB+Schematic co...
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.
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
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_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()
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 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.
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_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.