Commit 7183e9f9 authored by Wayne Stambaugh's avatar Wayne Stambaugh
Browse files

Make the new schematic and symbol library file formats the default.

This is a very large and potentially disruptive change so this will be an
unusually long and detailed commit message.

The new file formats are now the default in both the schematic and symbol
library editors.  Existing symbol libraries will be saved in their current
format until new features are added to library symbols.  Once this happens,
both the legacy schematic and symbol file formats will be no longer be
savable and existing libraries will have to be converted.  Saving to the
legacy file formats is still available for round robin testing and should
not be used for normal editing.

When loading the legacy schematic file, it is imperative that the schematic
library symbols are rescued and/or remapped to valid library identifiers.
Otherwise, there will be no way to link to the original library symbol and
the user will be required manually set the library identifier.  The cached
symbol will be saved in the schematic file so the last library symbol in
the cache will still be used but there will be no way to update it from the
original library.

The next save after loading a legacy schematic file will be converted to
the s-expression file format.  Schematics with hierarchical sheets will
automatically have all sheet file name extensions changed to .kicad_sym
and saved to the new format as well.

Appending schematics requires that the schematic to append has already been
converted to the new file format.  This is required to ensure that library
symbols are guaranteed to be valid for the appended schematic.

The schematic symbol library symbol link resolution has been moved out of
the SCH_COMPONENT object and move into the SCH_SCREEN object that owns the
symbol.  This was done to ensure that there is a single place where the
library symbol links get resolved rather than the dozen or so different
code paths that previously existed.  It also removes the necessity of the
SCH_COMPONENT object of requiring any knowledge of the symbol library table
and/or the cache library.

When opening an s-expression schematic, the legacy cache library is not
loaded so any library symbols not rescued cannot be loaded.  Broken library
symbol links will have to be manually resolved by adding the cache library
to the symbol library table and changing the links in the schematic symbol.

Now that the library symbols are embedded in the schematic file, the
SCH_SCREEN object maintains the list of library symbols for the schematic
automatically.  No external manipulation of this library cache should ever
occur.

ADDED: S-expression schematic and symbol library file formats.
parent 12d1d3a8
......@@ -579,6 +579,7 @@ public:
bool operator==( const LIB_PART* aPart ) const { return this == aPart; }
bool operator==( const LIB_PART& aPart ) const { return Compare( aPart ) == 0; }
bool operator!=( const LIB_PART& aPart ) const { return Compare( aPart ) != 0; }
const LIB_PART& operator=( const LIB_PART& aPart );
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -398,6 +398,8 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
return false;
wxString msg;
// save old cmp in undo list if not already in edit, or moving ...
if( m_cmp->GetEditFlags() == 0 )
GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED );
......@@ -407,8 +409,27 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
// Library symbol identifier
LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() );
if( id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true ) >= 0 )
{
msg.Printf( _( "'%s' is not a valid library indentifier." ),
m_libraryNameTextCtrl->GetValue() );
DisplayError( this, msg );
return false;
}
LIB_PART* libSymbol = Prj().SchSymbolLibTable()->LoadSymbol( id );
if( !libSymbol )
{
msg.Printf( _( "Symbol '%s' not found in symbol library '%s'." ),
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
DisplayError( this, msg );
return false;
}
m_cmp->SetLibSymbol( new LIB_PART( *libSymbol ) );
m_cmp->SetLibId( id );
// For symbols with multiple shapes (De Morgan representation) Set the selected shape:
if( m_cbAlternateSymbol->IsEnabled() && m_cbAlternateSymbol->GetValue() )
......@@ -466,8 +487,8 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
// grid needs to be notified about the size change,
// as it still accesses the data on close (size event)
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, i, 1 );
m_grid->ProcessTableMessage( msg );
wxGridTableMessage gridMsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, i, 1 );
m_grid->ProcessTableMessage( gridMsg );
i--;
break;
}
......@@ -622,7 +643,9 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveDown( wxCommandEvent& event )
m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
}
else
{
wxBell();
}
}
......@@ -631,12 +654,33 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFieldsFromLibrary( wxCommandEvent
if( !m_grid->CommitPendingChanges() )
return;
LIB_ID id;
wxString msg;
SCH_COMPONENT copy( *m_cmp );
copy.SetFields( *m_fields );
LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
copy.SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() );
if( id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true ) >= 0 )
{
msg.Printf( _( "'%s' is not a valid library indentifier." ),
m_libraryNameTextCtrl->GetValue() );
DisplayError( this, msg );
return;
}
LIB_PART* libSymbol = Prj().SchSymbolLibTable()->LoadSymbol( id );
if( !libSymbol )
{
msg.Printf( _( "Symbol '%s' not found in symbol library '%s'." ),
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
DisplayError( this, msg );
return;
}
m_cmp->SetLibSymbol( new LIB_PART( *libSymbol ) );
// Update the requested fields in the component copy
std::list<SCH_COMPONENT*> components;
......
......@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright 2017 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -774,7 +774,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::TransferDataFromWindow()
{
m_isModified = true;
SCH_SCREENS schematic;
schematic.UpdateSymbolLinks( true );
schematic.UpdateSymbolLinks();
}
return true;
......@@ -807,7 +807,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::revertChanges()
if( change )
{
SCH_SCREENS schematic;
schematic.UpdateSymbolLinks( true );
schematic.UpdateSymbolLinks();
m_parent->GetCanvas()->Refresh();
}
}
......
......@@ -6,7 +6,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -269,7 +269,7 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter )
}
aReporter.Report( _( "Symbol library table mapping complete!" ), RPT_SEVERITY_INFO );
schematic.UpdateSymbolLinks( true );
schematic.UpdateSymbolLinks();
}
......@@ -308,7 +308,7 @@ bool DIALOG_SYMBOL_REMAP::remapSymbolToLibTable( SCH_COMPONENT* aSymbol )
id.SetLibNickname( row->GetNickName() );
// Don't resolve symbol library links now.
aSymbol->SetLibId( id, nullptr, nullptr );
aSymbol->SetLibId( id );
return true;
}
}
......
......@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
......@@ -243,8 +243,8 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
wxArrayString pluginChoices;
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) );
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
populateEnvironReadOnlyTable();
......@@ -840,10 +840,6 @@ void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
}
}
SCH_SCREENS schematic;
schematic.UpdateSymbolLinks( true ); // Update all symbol library links for all sheets.
if( schEditor )
schEditor->SyncView();
......
......@@ -68,7 +68,11 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() : APP_SETTINGS_BASE( "eeschema", eeschema
m_params.emplace_back( new PARAM<bool>( "appearance.show_page_limits",
&m_Appearance.show_page_limits, true ) );
m_params.emplace_back( new PARAM<bool>( "appearance.show_sheet_filename_case_sensitivity_dialog",
m_params.emplace_back( new PARAM<bool>( "appearance.show_sexpr_file_convert_warning",
&m_Appearance.show_sexpr_file_convert_warning, true ) );
m_params.emplace_back(
new PARAM<bool>( "appearance.show_sheet_filename_case_sensitivity_dialog",
&m_Appearance.show_sheet_filename_case_sensitivity_dialog, true ) );
m_params.emplace_back( new PARAM<bool>( "autoplace_fields.enable",
......@@ -529,4 +533,4 @@ bool EESCHEMA_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
libedit->Load();
return ret;
}
\ No newline at end of file
}
......@@ -46,6 +46,7 @@ public:
bool show_hidden_fields;
bool show_illegal_symbol_lib_dialog;
bool show_page_limits;
bool show_sexpr_file_convert_warning;
bool show_sheet_filename_case_sensitivity_dialog;
};
......
......@@ -54,6 +54,7 @@
#include <tool/actions.h>
#include <netlist.h>
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
bool aCreateBackupFile )
{
......@@ -73,9 +74,9 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
if( aSaveUnderNewName )
{
wxString wildcards = LegacySchematicFileWildcard();
wxString wildcards = KiCadSchematicFileWildcard();
wildcards += "|" + KiCadSchematicFileWildcard();
wildcards += "|" + LegacySchematicFileWildcard();
wxFileDialog dlg( this, _( "Schematic Files" ), wxPathOnly( Prj().GetProjectFullName() ),
schematicFileName.GetFullName(), wildcards,
......@@ -86,10 +87,10 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
schematicFileName = dlg.GetPath();
if( dlg.GetFilterIndex() == 0
if( dlg.GetFilterIndex() == 1
&& schematicFileName.GetExt() != LegacySchematicFileExtension )
schematicFileName.SetExt( LegacySchematicFileExtension );
else if( dlg.GetFilterIndex() == 1
else if( dlg.GetFilterIndex() == 0
&& schematicFileName.GetExt() != KiCadSchematicFileExtension )
schematicFileName.SetExt( KiCadSchematicFileExtension );
}
......@@ -111,7 +112,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
{
msg.Printf( _( "Could not save backup of file \"%s\"" ),
GetChars( schematicFileName.GetFullPath() ) );
schematicFileName.GetFullPath() );
DisplayError( this, msg );
}
}
......@@ -132,10 +133,10 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error saving schematic file \"%s\".\n%s" ),
GetChars( schematicFileName.GetFullPath() ), GetChars( ioe.What() ) );
schematicFileName.GetFullPath(), ioe.What() );
DisplayError( this, msg );
msg.Printf( _( "Failed to save \"%s\"" ), GetChars( schematicFileName.GetFullPath() ) );
msg.Printf( _( "Failed to save \"%s\"" ), schematicFileName.GetFullPath() );
AppendMsgPanel( wxEmptyString, msg, CYAN );
success = false;
......@@ -166,7 +167,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
aScreen->ClrSave();
aScreen->ClrModify();
msg.Printf( _( "File %s saved" ), GetChars( aScreen->GetFileName() ) );
msg.Printf( _( "File %s saved" ), aScreen->GetFileName() );
SetStatusText( msg, 0 );
}
else
......@@ -183,7 +184,16 @@ void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
if( doSaveAs )
{
if( SaveEEFile( NULL, true ) )
CreateArchiveLibraryCacheFile( true );
{
SCH_SCREEN* screen = GetScreen();
wxCHECK( screen, /* void */ );
wxFileName fn = screen->GetFileName();
if( fn.GetExt() == LegacySchematicFileExtension )
CreateArchiveLibraryCacheFile( true );
}
}
else
{
......@@ -197,9 +207,10 @@ void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
{
// implement the pseudo code from KIWAY_PLAYER.h:
wxString msg;
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
// This is for python:
if( aFileSet.size() != 1 )
{
......@@ -208,7 +219,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
return false;
}
wxString fullFileName( aFileSet[0] );
wxString fullFileName( aFileSet[0] );
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) );
......@@ -258,6 +269,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
SetStatusText( wxEmptyString );
ClearMsgPanel();
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
// PROJECT::SetProjectFullName() is an impactful function. It should only be
// called under carefully considered circumstances.
......@@ -265,20 +278,28 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// it knows what consequences that will have on other KIFACEs running and using
// this same PROJECT. It can be very harmful if that calling code is stupid.
// Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
// They are already saved in the kiface project object.
if( pro.GetFullPath() != Prj().GetProjectFullName()
|| !Prj().GetElem( PROJECT::ELEM_SCH_PART_LIBS ) )
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
{
Prj().SetProjectFullName( pro.GetFullPath() );
// load the libraries here, not in SCH_SCREEN::Draw() which is a context
// that will not tolerate DisplayError() dialog since we're already in an
// event handler in there.
// And when a schematic file is loaded, we need these libs to initialize
// some parameters (links to PART LIB, dangling ends ...)
// Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
// They are already saved in the kiface project object.
if( pro.GetFullPath() != Prj().GetProjectFullName()
|| !Prj().GetElem( PROJECT::ELEM_SCH_PART_LIBS ) )
{
Prj().SetProjectFullName( pro.GetFullPath() );
// load the libraries here, not in SCH_SCREEN::Draw() which is a context
// that will not tolerate DisplayError() dialog since we're already in an
// event handler in there.
// And when a schematic file is loaded, we need these libs to initialize
// some parameters (links to PART LIB, dangling ends ...)
Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
Prj().SchLibs();
}
}
else
{
// No legacy symbol libraries including the cache are loaded with the new file format.
Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
Prj().SchLibs();
}
LoadProjectFile();
......@@ -300,7 +321,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
delete g_RootSheet; // Delete the current project.
g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
SCH_PLUGIN* plugin = SCH_IO_MGR::FindPlugin( schFileType );
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin );
......@@ -332,10 +352,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
GetChars( fullFileName ), GetChars( ioe.What() ) );
fullFileName, ioe.What() );
DisplayError( this, msg );
msg.Printf( _( "Failed to load \"%s\"" ), GetChars( fullFileName ) );
msg.Printf( _( "Failed to load \"%s\"" ), fullFileName );
AppendMsgPanel( wxEmptyString, msg, CYAN );
return false;
......@@ -358,61 +378,84 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
SCH_SCREENS schematic;
// Convert old projects over to use symbol library table.
if( schematic.HasNoFullyDefinedLibIds() )
// LIB_ID checks and symbol rescue only apply to the legacy file formats.
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
{
DIALOG_SYMBOL_REMAP dlgRemap( this );
// Convert old projects over to use symbol library table.
if( schematic.HasNoFullyDefinedLibIds() )
{
DIALOG_SYMBOL_REMAP dlgRemap( this );
dlgRemap.ShowQuasiModal();
}
else
{
// Double check to ensure no legacy library list entries have been
// added to the projec file symbol library list.
wxString paths;
wxArrayString libNames;
dlgRemap.ShowQuasiModal();
}
else
{
// Double check to ensure no legacy library list entries have been
// added to the projec file symbol library list.
wxString paths;
wxArrayString libNames;
PART_LIBS::LibNamesAndPaths( &Prj(), false, &paths, &libNames );
PART_LIBS::LibNamesAndPaths( &Prj(), false, &paths, &libNames );
if( !libNames.IsEmpty() )
{
if( eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
if( !libNames.IsEmpty() )
{
wxRichMessageDialog invalidLibDlg(
this,
_( "Illegal entry found in project file symbol library list." ),
_( "Project Load Warning" ),
wxOK | wxCENTER | wxICON_EXCLAMATION );
invalidLibDlg.SetExtendedMessage(
_( "Symbol libraries defined in the project file symbol library list "
"are no longer supported and will be\nremoved. This may cause "
"broken symbol library links under certain conditions." ) );
invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
invalidLibDlg.ShowModal();
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog =
!invalidLibDlg.IsCheckBoxChecked();
if( eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
{
wxRichMessageDialog invalidLibDlg(
this,
_( "Illegal entry found in project file symbol library list." ),
_( "Project Load Warning" ),
wxOK | wxCENTER | wxICON_EXCLAMATION );
invalidLibDlg.ShowDetailedText(
_( "Symbol libraries defined in the project file symbol library "
"list are no longer supported and will be\nremoved. This may "
"cause broken symbol library links under certain conditions." ) );
invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
invalidLibDlg.ShowModal();
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog =
!invalidLibDlg.IsCheckBoxChecked();
}
libNames.Clear();
paths.Clear();
PART_LIBS::LibNamesAndPaths( &Prj(), true, &paths, &libNames );
}
libNames.Clear();
paths.Clear();
PART_LIBS::LibNamesAndPaths( &Prj(), true, &paths, &libNames );
if( !cfg || !cfg->m_RescueNeverShow )
RescueSymbolLibTableProject( false );
}
// Check to see whether some old library parts need to be rescued
// Only do this if RescueNeverShow was not set.
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
// Update all symbol library links for all sheets.
schematic.UpdateSymbolLinks();
if( !cfg || cfg->m_Appearance.show_sexpr_file_convert_warning )
{
wxRichMessageDialog newFileFormatDlg(
this,
_( "The schematic file will be converted to the new file format on save." ),
_( "Project Load Warning" ),
wxOK | wxCENTER | wxICON_EXCLAMATION );
newFileFormatDlg.ShowDetailedText(
_( "This schematic was saved in the legacy file format which is no "
"longer supported and will be saved\nusing the new file format. The "
"new file format cannot be opened with previous versions of KiCad." ) );
newFileFormatDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
newFileFormatDlg.ShowModal();
cfg->m_Appearance.show_sexpr_file_convert_warning =
!newFileFormatDlg.IsCheckBoxChecked();
}
if( !cfg || !cfg->m_RescueNeverShow )
RescueSymbolLibTableProject( false );
// Allow the schematic to be saved to new file format without making any edits.
OnModify();
}
else // S-expression schematic.
{
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
screen->UpdateLocalLibSymbolLinks();
}
g_ConnectionGraph->Reset();
// Update all symbol library links for all sheets.
// NOTE: calls RecalculateConnections( GLOBAL_CLEANUP )
schematic.UpdateSymbolLinks( true ); // Update all symbol library links for all sheets.
SetScreen( g_CurrentSheet->LastScreen() );
// Migrate conflicting bus definitions
......@@ -426,8 +469,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
}
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
RecalculateConnections( GLOBAL_CLEANUP );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->m_Initialized = true;
}
......@@ -476,7 +519,7 @@ bool SCH_EDIT_FRAME::AppendSchematic()
wxString path = wxPathOnly( Prj().GetProjectFullName() );
wxFileDialog dlg( this, _( "Append Schematic" ), path, wxEmptyString,
LegacySchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
KiCadSchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() == wxID_CANCEL )
return false;
......@@ -548,6 +591,7 @@ bool SCH_EDIT_FRAME::SaveProject()
SCH_SCREEN* screen;
SCH_SCREENS screenList;
bool success = true;
bool updateFileType = false;
// I want to see it in the debugger, show me the string! Can't do that with wxFileName.
wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() );
......@@ -561,9 +605,35 @@ bool SCH_EDIT_FRAME::SaveProject()
}
for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
{
// Convert legacy schematics file name extensions for the new format.
wxFileName tmpFn = screen->GetFileName();
if( tmpFn.GetExt() != KiCadSchematicFileExtension )
{
updateFileType = true;
tmpFn.SetExt( KiCadSchematicFileExtension );
for( auto item : screen->Items().OfType( SCH_SHEET_T ) )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
wxFileName sheetFileName = sheet->GetFileName();
if( sheetFileName.GetExt() == KiCadSchematicFileExtension )
continue;
sheetFileName.SetExt( KiCadSchematicFileExtension );
sheet->SetFileName( sheetFileName.GetFullPath() );
}
screen->SetFileName( tmpFn.GetFullPath() );
}
success &= SaveEEFile( screen );
}
CreateArchiveLibraryCacheFile();
if( updateFileType )
UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() );
// Save the sheet name map to the project file
wxString configFile = Prj().GetProjectFullName();
......
......@@ -85,6 +85,9 @@ int LIB_ITEM::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareF
if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_Convert != aOther.m_Convert )
return m_Convert - m_Convert;
if( m_Fill != aOther.m_Fill )
return m_Fill - aOther.m_Fill;
return 0;
}
......
......@@ -786,7 +786,7 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
{
wxFileName fn;
wxString msg