80#include <wx/filedlg.h>
82#include <wx/richmsgdlg.h>
83#include <wx/stdpaths.h>
108 if( aFileSet.size() != 1 )
110 msg.Printf(
"Eeschema:%s() takes only a single filename.", __WXFUNCTION__ );
115 wxString fullFileName( aFileSet[0] );
116 wxFileName wx_filename( fullFileName );
119 wxASSERT_MSG( wx_filename.IsAbsolute(), wxS(
"Path is not absolute!" ) );
124 if(
Prj().IsLockOverrideGranted() )
130 msg.Printf(
_(
"Schematic '%s' is already open by '%s' at '%s'." ), fullFileName,
147 wxFileName pro = fullFileName;
150 bool is_new = !wxFileName::IsFileReadable( fullFileName );
156 msg.Printf(
_(
"Schematic '%s' does not exist. Do you wish to create it?" ),
159 if( !
IsOK(
this, msg ) )
163 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGING );
164 ProcessEventLocally( e );
174 SetStatusText( wxEmptyString );
178 statusBar->ClearWarningMessages(
"load" );
181 :
_(
"Load Schematic" ), 1,
189 if( differentProject )
191 if( !
Prj().IsNullProject() )
203 wxFileName legacyPro( pro );
208 if( !pro.Exists() && !legacyPro.Exists() && !( aCtl &
KICTL_CREATE ) )
218 std::unique_ptr<SCHEMATIC> newSchematic = std::make_unique<SCHEMATIC>( &
Prj() );
222 bool isNonKicadImport = schFileType != SCH_IO_MGR::SCH_KICAD
223 && schFileType != SCH_IO_MGR::SCH_LEGACY
224 && schFileType != SCH_IO_MGR::SCH_FILE_UNKNOWN;
230 if( isNonKicadImport )
232 progressReporter.Hide();
233 importFile( fullFileName, schFileType,
nullptr );
237 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
259 rfn.MakeRelativeTo(
Prj().GetProjectPath() );
269 if( is_new || schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
271 newSchematic->CreateDefaultScreens();
278 if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
282 msg.Printf(
_(
"'%s' is not a KiCad schematic file.\nUse File -> Import for "
283 "non-KiCad schematic files." ),
289 msg.Printf(
_(
"'%s' is not a recognised schematic format." ), fullFileName );
292 progressReporter.Hide();
302 pi->SetProgressReporter( &progressReporter );
304 bool failedLoad =
false;
314 const std::vector<TOP_LEVEL_SHEET_INFO>& topLevelSheets = projectFile.
GetTopLevelSheets();
316 if( !topLevelSheets.empty() )
318 std::vector<SCH_SHEET*> loadedSheets;
323 wxFileName sheetFileName(
Prj().GetProjectPath(), sheetInfo.filename );
326 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
329 wxString sheetPath = sheetFileName.GetFullPath();
331 if( !wxFileName::FileExists( sheetPath ) )
333 wxLogWarning( wxT(
"Top-level sheet file not found: %s" ), sheetPath );
337 SCH_SHEET* sheet = pi->LoadSchematicFile( sheetPath, newSchematic.get() );
343 if( sheetInfo.uuid !=
niluuid )
345 const_cast<KIID&
>( sheet->
m_Uuid ) = sheetInfo.uuid;
348 sheet->
SetName( sheetInfo.name );
349 loadedSheets.push_back( sheet );
352 wxS(
"Loaded top-level sheet '%s' (UUID %s) from %s" ),
359 if( !loadedSheets.empty() )
361 newSchematic->SetTopLevelSheets( loadedSheets );
366 wxS(
"Loaded multi-root schematic with no top-level sheets!" ) );
367 newSchematic->CreateDefaultScreens();
373 SCH_SHEET* rootSheet = pi->LoadSchematicFile( fullFileName, newSchematic.get() );
377 newSchematic->SetTopLevelSheets( { rootSheet } );
381 if(
SCH_SHEET* topSheet = newSchematic->GetTopLevelSheet() )
382 topSheet->SetName(
_(
"Root" ) );
385 wxS(
"Loaded schematic with root sheet UUID %s" ),
388 "After loading: Current sheet path='%s', size=%zu, empty=%d",
389 newSchematic->CurrentSheet().Path().AsString(),
390 newSchematic->CurrentSheet().size(),
391 newSchematic->CurrentSheet().empty() ? 1 : 0 );
395 newSchematic->CreateDefaultScreens();
401 if( !pi->GetError().IsEmpty() )
404 "occurred attempting to load hierarchical sheets." ),
410 newSchematic->CreateDefaultScreens();
411 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName );
412 progressReporter.Hide();
419 newSchematic->CreateDefaultScreens();
420 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFileName );
421 progressReporter.Hide();
426 catch(
const std::bad_alloc& )
428 newSchematic->CreateDefaultScreens();
429 msg.Printf(
_(
"Memory exhausted loading schematic '%s'." ), fullFileName );
430 progressReporter.Hide();
452 statusBar->AddWarningMessages(
"load", loadReporter.
GetMessages() );
454 msg.Printf(
_(
"Failed to load '%s'." ), fullFileName );
466 bool repairedPageNumbers =
false;
476 if( sheetList.
IsModified() || repairedPageNumbers )
479 _(
"An error was found when loading the schematic that has "
480 "been automatically fixed. Please save the schematic to "
481 "repair the broken file or it may not be usable with other "
482 "versions of KiCad." ) );
488 statusBar->AddWarningMessages(
"load", loadReporter.
GetMessages() );
493 if( schFileType == SCH_IO_MGR::SCH_LEGACY )
496 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
498 std::vector<SCH_ITEM*> deleted;
500 for(
SCH_ITEM* item : screen->Items() )
505 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
509 wire->SetEndPoint( entry->
GetEnd() );
511 screen->Append( wire.release() );
512 deleted.push_back( item );
517 screen->Remove( item );
522 if( schematic.HasNoFullyDefinedLibIds() )
533 wxArrayString libNames;
537 if( !libNames.IsEmpty() )
539 if(
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
541 wxRichMessageDialog invalidLibDlg(
543 _(
"Illegal entry found in project file symbol library list." ),
544 _(
"Project Load Warning" ),
545 wxOK | wxCENTER | wxICON_EXCLAMATION );
546 invalidLibDlg.ShowDetailedText(
547 _(
"Symbol libraries defined in the project file symbol library "
548 "list are no longer supported and will be removed.\n\n"
549 "This may cause broken symbol library links under certain "
551 invalidLibDlg.ShowCheckBox(
_(
"Do not show this dialog again." ) );
552 invalidLibDlg.ShowModal();
554 !invalidLibDlg.IsCheckBoxChecked();
563 wxFileName cacheFn( fullFileName );
564 cacheFn.SetName( cacheFn.GetName() +
"-cache" );
566 bool cacheExists = cacheFn.FileExists();
577 if( !(*table)->HasRow( nickname ) )
581 row.
SetURI( cacheFn.GetFullPath() );
587 std::vector<wxString> cacheSymbols = adapter->
GetSymbolNames( nickname );
588 std::set<wxString> cacheSymbolSet( cacheSymbols.begin(), cacheSymbols.end() );
590 if( !cacheSymbolSet.empty() )
592 std::vector<wxString> loadedLibs;
596 if( libName == nickname )
602 loadedLibs.push_back( libName );
605 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
613 if( cacheSymbolSet.count( fullLibName.
wx_str() ) )
615 bool alreadyExists =
false;
617 for(
const wxString& libName : loadedLibs )
621 alreadyExists =
true;
642 editor->RescueSymbolLibTableProject(
false );
652 wxFileName cacheFn = pro;
654 wxLogTrace(
traceAutoSave,
"[SetName dbg] cacheFn BEFORE path='%s' name='%s' full='%s' arg='%s'",
655 cacheFn.GetPath(), cacheFn.GetName(), cacheFn.GetFullPath(), cacheFn.GetName() +
"-cache" );
656 cacheFn.SetName( cacheFn.GetName() +
"-cache" );
657 wxLogTrace(
traceAutoSave,
"[SetName dbg] cacheFn AFTER path='%s' name='%s' full='%s'",
658 cacheFn.GetPath(), cacheFn.GetName(), cacheFn.GetFullPath() );
661 msg.Printf(
_(
"The project symbol library cache file '%s' was not found." ),
662 cacheFn.GetFullName() );
663 extMsg =
_(
"This can result in a broken schematic under certain conditions. "
664 "If the schematic does not have any missing symbols upon opening, "
665 "save it immediately before making any changes to prevent data "
666 "loss. If there are missing symbols, either manual recovery of "
667 "the schematic or recovery of the symbol cache library file and "
668 "reloading the schematic is required." );
671 wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
672 dlgMissingCache.SetExtendedMessage( extMsg );
673 dlgMissingCache.SetOKCancelLabels( KICAD_MESSAGE_DIALOG::ButtonLabel(
_(
"Load Without Cache File" ) ),
674 KICAD_MESSAGE_DIALOG::ButtonLabel(
_(
"Abort" ) ) );
676 if( dlgMissingCache.ShowModal() == wxID_CANCEL )
685 schematic.UpdateSymbolLinks( &loadReporter );
689 m_infoBar->ShowMessage(
_(
"This file was created by an older version of KiCad. "
690 "It will be converted to the new format when saved." ),
691 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
695 schematic.ReplaceDuplicateTimeStamps();
697 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
698 screen->FixLegacyPowerSymbolMismatches();
705 SCH_SCREEN* first_screen = schematic.GetFirst();
709 first_screen = schematic.GetNext();
715 m_infoBar->ShowMessage(
_(
"This file was created by an older version of KiCad. "
716 "It will be converted to the new format when saved." ),
717 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
720 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
733 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen;
734 screen = schematic.GetNext() )
735 screen->FixLegacyPowerSymbolMismatches();
737 for(
SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
738 screen->MigrateSimModels();
750 "Before CheckForMissingSymbolInstances: Current sheet path='%s', size=%zu",
758 schematic.PruneOrphanedSymbolInstances(
Prj().GetProjectName(), sheetList );
759 schematic.PruneOrphanedSheetInstances(
Prj().GetProjectName(), sheetList );
767 if( repairedPageNumbers )
771 "After SetScreen: Current sheet path='%s', size=%zu",
777 progressReporter.
Report(
_(
"Updating connections..." ) );
789 schFileVersion,
Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() ) )
791 progressReporter.Hide();
801 progressReporter.Show();
807 if( schematic.HasSymbolFieldNamesWithWhiteSpace() )
809 m_infoBar->QueueShowMessage(
_(
"This schematic contains symbols that have leading "
810 "and/or trailing white space field names." ),
838 bool nativeNeedsFixup = schFileType == SCH_IO_MGR::SCH_KICAD
842 if( schFileType == SCH_IO_MGR::SCH_LEGACY || nativeNeedsFixup )
860 wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
861 ProcessEventLocally( changedEvt );
863 if( !differentProject )
874 wxCHECK2( listener,
continue );
878 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
881 win->HandleWindowEvent( e );
883 listener->SafelyProcessEvent( e );
891 if( fn.FileExists() && !fn.IsFileWritable() )
895 m_infoBar->ShowMessage(
_(
"Schematic is read only." ),
896 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
925 wxString msg =
_(
"This operation replaces the contents of the current schematic, "
926 "which will be permanently lost.\n\n"
927 "Do you want to proceed?" );
929 if( !
IsOK(
this, msg ) )
935 wxString
path = wxPathOnly(
Prj().GetProjectFullName() );
937 wxString fileFiltersStr;
938 wxString allWildcardsStr;
940 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
942 if(
fileType == SCH_IO_MGR::SCH_KICAD ||
fileType == SCH_IO_MGR::SCH_LEGACY )
955 if( !fileFiltersStr.IsEmpty() )
956 fileFiltersStr += wxChar(
'|' );
964 fileFiltersStr =
_(
"All supported formats" ) + wxS(
"|" ) + allWildcardsStr + wxS(
"|" )
967 wxFileDialog dlg(
this,
_(
"Import Schematic" ),
path, wxEmptyString, fileFiltersStr,
968 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
971 dlg.SetCustomizeHook( importOptions );
975 if( dlg.ShowModal() == wxID_CANCEL )
995 wxFileName projectFn( dlg.GetPath() );
1000 wxFileName fn = dlg.GetPath();
1002 if( !fn.IsFileReadable() )
1004 wxLogError(
_(
"Insufficient permissions to read file '%s'." ), fn.GetFullPath() );
1008 SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
1010 for(
const SCH_IO_MGR::SCH_FILE_T&
fileType : SCH_IO_MGR::SCH_FILE_T_vector )
1017 if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
1024 if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
1026 wxLogError(
_(
"No loader can read the specified file: '%s'." ), fn.GetFullPath() );
1041 wxFileName schematicFileName;
1042 wxFileName oldFileName;
1047 wxCHECK( screen,
false );
1050 if( aSavePath.IsEmpty() )
1055 oldFileName = schematicFileName;
1060 if( !schematicFileName.DirExists() )
1062 if( !wxMkdir( schematicFileName.GetPath() ) )
1064 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
1065 schematicFileName.GetFullPath(),
1066 "Could not create directory: %s" + schematicFileName.GetPath() );
1076 wxFileName projectFile( schematicFileName );
1080 if( projectFile.FileExists() )
1088 wxLogTrace(
traceAutoSave, wxS(
"Saving file " ) + schematicFileName.GetFullPath() );
1090 if(
m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1094 schematicFileName.GetFullPath() );
1096 if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
1097 pluginType = SCH_IO_MGR::SCH_KICAD;
1103 if( schematicFileName.FileExists() )
1108 pi->SaveSchematicFile( schematicFileName.GetFullPath(), aSheet, &
Schematic() );
1113 msg.Printf(
_(
"Error saving schematic file '%s'.\n%s" ),
1114 schematicFileName.GetFullPath(),
1125 msg.Printf(
_(
"File '%s' saved." ), screen->
GetFileName() );
1126 SetStatusText( msg, 0 );
1134 const wxFileName& aOldRoot,
const wxFileName& aNewRoot,
1135 bool aSaveCopy,
bool aCopySubsheets,
bool aIncludeExternSheets,
1136 std::unordered_map<SCH_SCREEN*, wxString>& aFilenameMap,
1137 wxString& aErrorMsg )
1141 for(
size_t i = 0; i < aScreens.
GetCount(); i++ )
1145 wxCHECK2( screen,
continue );
1152 if( !src.IsAbsolute() )
1153 src.MakeAbsolute( aOldRoot.GetPath() );
1155 bool internalSheet = src.GetPath().StartsWith( aOldRoot.GetPath() );
1157 if( aCopySubsheets && ( internalSheet || aIncludeExternSheets ) )
1159 wxFileName dest = src;
1161 if( internalSheet && dest.MakeRelativeTo( aOldRoot.GetPath() ) )
1162 dest.MakeAbsolute( aNewRoot.GetPath() );
1164 dest.Assign( aNewRoot.GetPath(), dest.GetFullName() );
1167 wxS(
"Moving schematic from '%s' to '%s'." ),
1169 dest.GetFullPath() );
1171 if( !dest.DirExists() && !dest.Mkdir() )
1173 aErrorMsg.Printf(
_(
"Folder '%s' could not be created.\n\n"
1174 "Make sure you have write permissions and try again." ),
1180 aFilenameMap[screen] = dest.GetFullPath();
1187 aFilenameMap[screen] = wxString();
1195 if( !sheet.Last()->IsTopLevelSheet() )
1196 sheet.MakeFilePathRelativeToParentSheet();
1208 bool success =
true;
1209 bool updateFileHistory =
false;
1210 bool createNewProject =
false;
1211 bool copySubsheets =
false;
1212 bool includeExternSheets =
false;
1216 wxFileName fn = fileName;
1220 std::unordered_map<SCH_SCREEN*, wxString> filenameMap;
1223 if(
Prj().IsNullProject() || aSaveAs )
1226 wxCHECK(
Kiface().IsSingle() || aSaveAs,
false );
1228 wxFileName newFileName;
1229 wxFileName savePath(
Prj().GetProjectFullName() );
1231 if( !savePath.IsOk() || !savePath.IsDirWritable() )
1235 if( !savePath.IsOk() || !savePath.IsDirWritable() )
1239 if( savePath.HasExt() )
1242 savePath.SetName( wxEmptyString );
1244 wxFileDialog dlg(
this,
_(
"Schematic Files" ), savePath.GetPath(), savePath.GetFullName(),
1246 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1251 if(
Kiface().IsSingle() || aSaveAs )
1253 dlg.SetCustomizeHook( newProjectHook );
1258 if( dlg.ShowModal() == wxID_CANCEL )
1263 if( ( !newFileName.DirExists() && !newFileName.Mkdir() ) ||
1264 !newFileName.IsDirWritable() )
1266 msg.Printf(
_(
"Folder '%s' could not be created.\n\n"
1267 "Make sure you have write permissions and try again." ),
1268 newFileName.GetPath() );
1271 wxOK | wxICON_EXCLAMATION | wxCENTER );
1273 dlgBadPath.ShowModal();
1288 updateFileHistory =
true;
1296 copySubsheets, includeExternSheets, filenameMap, msg ) )
1299 wxOK | wxICON_EXCLAMATION | wxCENTER );
1301 dlgBadFilePath.ShowModal();
1305 else if( !fn.FileExists() )
1308 updateFileHistory =
true;
1319 if( filenameMap.empty() || !saveCopy )
1321 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1326 wxArrayString overwrittenFiles;
1327 wxArrayString lockedFiles;
1329 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1333 wxCHECK2( screen,
continue );
1336 wxFileName tmpFn = filenameMap[screen];
1341 if( tmpFn.FileExists() && !tmpFn.IsFileWritable() )
1342 lockedFiles.Add( tmpFn.GetFullPath() );
1349 if( tmpFn.FileExists() )
1350 overwrittenFiles.Add( tmpFn.GetFullPath() );
1353 if( !lockedFiles.IsEmpty() )
1355 for(
const wxString& lockedFile : lockedFiles )
1360 msg +=
"\n" + lockedFile;
1363 wxRichMessageDialog dlg(
this, wxString::Format(
_(
"Failed to save %s." ),
1365 _(
"Locked File Warning" ),
1366 wxOK | wxICON_WARNING | wxCENTER );
1367 dlg.SetExtendedMessage(
_(
"You do not have write permissions to:\n\n" ) + msg );
1373 if( !overwrittenFiles.IsEmpty() )
1375 for(
const wxString& overwrittenFile : overwrittenFiles )
1378 msg = overwrittenFile;
1380 msg +=
"\n" + overwrittenFile;
1383 wxRichMessageDialog dlg(
this,
_(
"Saving will overwrite existing files." ),
1384 _(
"Save Warning" ),
1385 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER |
1386 wxICON_EXCLAMATION );
1387 dlg.ShowDetailedText(
_(
"The following files will be overwritten:\n\n" ) + msg );
1388 dlg.SetOKCancelLabels( KICAD_MESSAGE_DIALOG::ButtonLabel(
_(
"Overwrite Files" ) ),
1389 KICAD_MESSAGE_DIALOG::ButtonLabel(
_(
"Abort Project Save" ) ) );
1391 if( dlg.ShowModal() == wxID_CANCEL )
1397 std::vector<wxString> savedSheetPaths;
1399 for(
size_t i = 0; i < screens.
GetCount(); i++ )
1403 wxCHECK2( screen,
continue );
1406 wxFileName tmpFn = filenameMap[screen];
1410 updateFileHistory =
true;
1418 if( !sheetFileName.IsOk()
1423 sheet->
SetFileName( sheetFileName.GetFullPath() );
1427 filenameMap[screen] = tmpFn.GetFullPath();
1439 if( sheets.size() == 1 )
1445 if( !saveCopy && tmpFn.GetFullPath() != screen->
GetFileName() )
1450 if( savedThisSheet )
1451 savedSheetPaths.push_back( tmpFn.GetFullPath() );
1453 success &= savedThisSheet;
1465 if( aSaveAs && success )
1468 if( updateFileHistory )
1479 wxCHECK2( sheet,
continue );
1484 sheets.emplace_back( std::make_pair( sheet->
m_Uuid, sheet->
GetName() ) );
1488 wxASSERT( filenameMap.count(
Schematic().RootScreen() ) );
1489 wxFileName projectPath( filenameMap.at(
Schematic().RootScreen() ) );
1492 if(
Prj().IsNullProject() || ( aSaveAs && !saveCopy ) )
1497 else if( saveCopy && createNewProject )
1510 if( success && !
Prj().IsNullProject() )
1523 if( !
Kiface().IsSingle() )
1536 sheet.LastScreen()->SetVirtualPageNumber( sheet.GetVirtualPageNumber() );
1548 if(
m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
1556 const std::map<std::string, UTF8>* aProperties )
1558 wxFileName filename( aFileName );
1559 wxFileName newfilename;
1560 SCH_IO_MGR::SCH_FILE_T
fileType = (SCH_IO_MGR::SCH_FILE_T) aFileType;
1562 wxCommandEvent changingEvt( EDA_EVT_SCHEMATIC_CHANGING );
1563 ProcessEventLocally( changingEvt );
1566 statusBar->ClearWarningMessages(
"load" );
1571 std::unique_ptr<SCHEMATIC> newSchematic = std::make_unique<SCHEMATIC>( &
Prj() );
1575 case SCH_IO_MGR::SCH_ALTIUM:
1576 case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
1577 case SCH_IO_MGR::SCH_EAGLE:
1578 case SCH_IO_MGR::SCH_LTSPICE:
1579 case SCH_IO_MGR::SCH_EASYEDA:
1580 case SCH_IO_MGR::SCH_EASYEDAPRO:
1581 case SCH_IO_MGR::SCH_EASYEDAPRO_V3:
1582 case SCH_IO_MGR::SCH_PADS:
1583 case SCH_IO_MGR::SCH_GEDA:
1584 case SCH_IO_MGR::SCH_DIPTRACE:
1585 case SCH_IO_MGR::SCH_PCAD:
1586 case SCH_IO_MGR::SCH_ORCAD:
1590 wxCHECK_MSG( aFileName.IsEmpty() || filename.IsAbsolute(),
false,
1591 wxS(
"Import schematic: path is not absolute!" ) );
1602 this, std::placeholders::_1 ) );
1605 if(
eeconfig()->m_System.show_import_issues )
1610 pi->SetProgressReporter( &progressReporter );
1612 SCH_SHEET* loadedSheet = pi->LoadSchematicFile( aFileName, newSchematic.get(),
nullptr,
1620 bool loadedIsTopLevel = std::find( topLevelSheets.begin(), topLevelSheets.end(), loadedSheet )
1621 != topLevelSheets.end();
1622 bool loadedIsVirtualRoot = loadedSheet == &
Schematic().
Root()
1627 if( !loadedIsTopLevel && !loadedIsVirtualRoot )
1637 std::vector<wxString> sourceFpLibs;
1657 newfilename.SetPath(
Prj().GetProjectPath() );
1658 newfilename.SetName(
Prj().GetProjectName() );
1664 topSheet->SetFileName( newfilename.GetFullName() );
1669 progressReporter.
Report(
_(
"Updating connections..." ) );
1691 wxString msg = wxString::Format(
_(
"Error loading schematic '%s'." ), aFileName );
1694 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1697 catch(
const std::exception& exc )
1702 wxString msg = wxString::Format(
_(
"Unhandled exception occurred loading schematic "
1703 "'%s'." ), aFileName );
1706 msg.Printf(
_(
"Failed to load '%s'." ), aFileName );
1730 wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGED );
1731 ProcessEventLocally( e );
1735 wxCHECK2( listener,
continue );
1739 wxWindow* win =
dynamic_cast<wxWindow*
>( listener );
1742 win->HandleWindowEvent( e );
1744 listener->SafelyProcessEvent( e );
1750 statusBar->AddWarningMessages(
"load", loadReporter.
GetMessages() );
1774 if( simFrame && !simFrame->Close() )
1777 if( screen->IsContentModified() )
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static TOOL_ACTION zoomFitScreen
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.
static bool ShouldPrompt(int aFileFormatVersionAtLoad, size_t aBusesNeedingMigration)
Multiple differently-named labels on a single bus subgraph were only permitted before KiCad 6....
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)
void CheckForAutosaveFiles(const wxString &aProjectPath, const std::vector< wxString > &aExtensions)
Check for autosave files newer than their source files for the given project.
virtual void ClearUndoRedoList()
Clear the undo and redo list using ClearUndoORRedoList()
SETTINGS_MANAGER * GetSettingsManager() const
wxTimer * m_autoSaveTimer
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.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
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?
void RefreshDrawingSheetPageInfo()
Update the drawing sheet proxy's page number and first-page flag from the current edit frame state.
wxString AsString() const
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
A collection of #SYMBOL_LIB objects.
static void GetLibNamesAndPaths(PROJECT *aProject, wxString *aPaths, wxArrayString *aNames=nullptr)
static void SetLibNamesAndPaths(PROJECT *aProject, const wxString &aPaths, const wxArrayString &aNames)
std::optional< LIB_STATUS > GetLibraryStatus(const wxString &aNickname) const
Returns the status of a loaded library, or nullopt if the library hasn't been loaded (yet)
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetDescription(const wxString &aDescription)
void SetURI(const wxString &aUri)
A logical library item identifier and consists of various portions much like a URI.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
bool RunRegisteredSaversAndCommit(const wxString &aProjectPath, const wxString &aTitle, const wxString &aTagFileType=wxEmptyString)
Run all registered savers and, if any staged changes differ from HEAD, create a commit.
void RemoveAutosaveFiles(const wxString &aProjectPath) const
Remove every autosave file under the project at aProjectPath regardless of which source it shadowed.
static REPORTER & GetInstance()
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
void PreloadDesignBlockLibraries(KIWAY *aKiway)
Starts a background job to preload the global and project design block libraries.
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.
The backing store for a PROJECT, in JSON format.
std::vector< FILE_INFO_PAIR > & GetSheets()
std::vector< TOP_LEVEL_SHEET_INFO > & GetTopLevelSheets()
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
static LEGACY_SYMBOL_LIBS * LegacySchLibs(PROJECT *aProject)
Returns the list of symbol libraries from a legacy (pre-5.x) design This is only used from the remapp...
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 const wxString GetProjectName() const
Return the short name of the project.
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.
void LoadVariants()
This is a throw away method for variant testing.
int FixupJunctionsAfterImport()
Add junctions to this schematic where required.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
void SetProject(PROJECT *aPrj)
CONNECTION_GRAPH * ConnectionGraph() const
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
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
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void DisplaySheet(SCH_SCREEN *aScreen)
bool IsContentModified() const override
Get if the current schematic has been modified but not saved.
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
void SetCurrentVariant(const wxString &aVariantName)
void UpdateVariantSelectionCtrl(const wxArrayString &aVariantNames)
Update the variant name control on the main toolbar.
std::vector< wxEvtHandler * > m_schematicChangeListeners
void CreateDefaultScreens()
PANEL_REMOTE_SYMBOL * m_remoteSymbolPane
SCHEMATIC * m_schematic
The currently loaded schematic.
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.
void ProjectChanged() override
Notification event that the project has changed.
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 RefreshNetNavigator(const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
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.
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.
wxGenericTreeCtrl * m_netNavigator
void initScreenZoom()
Initialize the zoom value of the current screen and mark the screen as zoom-initialized.
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 const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
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 BuildClientSheetPathList()
Build the list of sheet paths sharing a screen for each screen in use.
SCH_SHEET * GetSheet(unsigned int aIndex) const
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
void UpdateLocalLibSymbolLinks()
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in this schematic with the local projec...
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
const std::vector< SCH_SYMBOL_INSTANCE > & GetSymbolInstances() const
int GetFileFormatVersionAtLoad() const
const std::vector< SCH_SHEET_INSTANCE > & GetSheetInstances() 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.
bool RepairPageNumbers()
Assign valid page numbers to sheet paths whose stored page number is missing or collides with an earl...
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.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
bool IsVirtualRootSheet() const
void SetLibId(const LIB_ID &aName)
const LIB_ID & GetLibId() const override
void SaveProjectAs(const wxString &aFullPath, PROJECT *aProject=nullptr)
Set the currently loaded project path and saves it (pointers remain valid).
bool SaveProject(const wxString &aFullPath=wxEmptyString, PROJECT *aProject=nullptr)
Save a loaded project.
bool SaveProjectCopy(const wxString &aFullPath, PROJECT *aProject=nullptr)
Save a copy of the current project under the given path.
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.
The SIMULATOR_FRAME holds the main user-interface for running simulations.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
std::vector< wxString > GetSymbolNames(const wxString &aNickname, SYMBOL_TYPE aType=SYMBOL_TYPE::ALL_SYMBOLS)
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
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.
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.
#define KICAD_MESSAGE_DIALOG
static bool empty(const wxTextEntryBase *aCtrl)
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 LegacySchematicFileExtension
static const std::string ProjectFileExtension
static const std::string LegacyProjectFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LegacySymbolLibFileExtension
static wxString KiCadSchematicFileWildcard()
const wxChar *const traceSchCurrentSheet
Flag to enable debug output of current sheet tracking in the schematic editor.
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_KICAD_ONLY
chosen file is from KiCad according to user
void ReadFootprintProps(const std::map< std::string, UTF8 > *aProps, wxString &aCacheNickname, std::vector< wxString > &aSourceFpLibs)
Read the footprint-import coordination properties out of a properties map.
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
Implement a participant in the KIWAY alchemy.
virtual void PreloadLibraries(KIWAY *aKiway)
Information about a top-level schematic sheet.
SYMBOL_IMPORT_RECONCILE_RESULT ReconcileImportedSymbols(SCH_IO &aPlugin, SCHEMATIC &aSchematic, PROJECT &aProject, const wxString &aSchematicPath, const std::map< std::string, UTF8 > *aProperties, REPORTER &aReporter)
Reconcile aSchematic against the definitions aPlugin retained while loading it.
wxLogTrace helper definitions.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
Definition of file extensions used in Kicad.