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.
This commit is contained in:
parent
12d1d3a844
commit
7183e9f97e
|
@ -579,6 +579,7 @@ public:
|
||||||
|
|
||||||
bool operator==( const LIB_PART* aPart ) const { return this == aPart; }
|
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; }
|
||||||
|
bool operator!=( const LIB_PART& aPart ) const { return Compare( aPart ) != 0; }
|
||||||
|
|
||||||
const LIB_PART& operator=( const LIB_PART& aPart );
|
const LIB_PART& operator=( const LIB_PART& aPart );
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
// save old cmp in undo list if not already in edit, or moving ...
|
// save old cmp in undo list if not already in edit, or moving ...
|
||||||
if( m_cmp->GetEditFlags() == 0 )
|
if( m_cmp->GetEditFlags() == 0 )
|
||||||
GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED );
|
GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED );
|
||||||
|
@ -407,8 +409,27 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
|
||||||
|
|
||||||
// Library symbol identifier
|
// Library symbol identifier
|
||||||
LIB_ID id;
|
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:
|
// For symbols with multiple shapes (De Morgan representation) Set the selected shape:
|
||||||
if( m_cbAlternateSymbol->IsEnabled() && m_cbAlternateSymbol->GetValue() )
|
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,
|
// grid needs to be notified about the size change,
|
||||||
// as it still accesses the data on close (size event)
|
// as it still accesses the data on close (size event)
|
||||||
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, i, 1 );
|
wxGridTableMessage gridMsg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, i, 1 );
|
||||||
m_grid->ProcessTableMessage( msg );
|
m_grid->ProcessTableMessage( gridMsg );
|
||||||
i--;
|
i--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -622,8 +643,10 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnMoveDown( wxCommandEvent& event )
|
||||||
m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
|
m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFieldsFromLibrary( wxCommandEvent& event )
|
void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFieldsFromLibrary( wxCommandEvent& event )
|
||||||
|
@ -631,12 +654,33 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFieldsFromLibrary( wxCommandEvent
|
||||||
if( !m_grid->CommitPendingChanges() )
|
if( !m_grid->CommitPendingChanges() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
LIB_ID id;
|
||||||
|
wxString msg;
|
||||||
SCH_COMPONENT copy( *m_cmp );
|
SCH_COMPONENT copy( *m_cmp );
|
||||||
|
|
||||||
copy.SetFields( *m_fields );
|
copy.SetFields( *m_fields );
|
||||||
|
|
||||||
LIB_ID id;
|
|
||||||
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
|
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
|
// Update the requested fields in the component copy
|
||||||
std::list<SCH_COMPONENT*> components;
|
std::list<SCH_COMPONENT*> components;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright 2017 Jean-Pierre Charras, jp.charras@wanadoo.fr
|
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -774,7 +774,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::TransferDataFromWindow()
|
||||||
{
|
{
|
||||||
m_isModified = true;
|
m_isModified = true;
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
schematic.UpdateSymbolLinks( true );
|
schematic.UpdateSymbolLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -807,7 +807,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::revertChanges()
|
||||||
if( change )
|
if( change )
|
||||||
{
|
{
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
schematic.UpdateSymbolLinks( true );
|
schematic.UpdateSymbolLinks();
|
||||||
m_parent->GetCanvas()->Refresh();
|
m_parent->GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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 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
|
* 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
|
* 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 );
|
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() );
|
id.SetLibNickname( row->GetNickName() );
|
||||||
|
|
||||||
// Don't resolve symbol library links now.
|
// Don't resolve symbol library links now.
|
||||||
aSymbol->SetLibId( id, nullptr, nullptr );
|
aSymbol->SetLibId( id );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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 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
|
* 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
|
* 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;
|
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_KICAD ) );
|
||||||
|
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
|
||||||
|
|
||||||
populateEnvironReadOnlyTable();
|
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 )
|
if( schEditor )
|
||||||
schEditor->SyncView();
|
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_params.emplace_back( new PARAM<bool>( "appearance.show_page_limits",
|
||||||
&m_Appearance.show_page_limits, true ) );
|
&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_Appearance.show_sheet_filename_case_sensitivity_dialog, true ) );
|
||||||
|
|
||||||
m_params.emplace_back( new PARAM<bool>( "autoplace_fields.enable",
|
m_params.emplace_back( new PARAM<bool>( "autoplace_fields.enable",
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
bool show_hidden_fields;
|
bool show_hidden_fields;
|
||||||
bool show_illegal_symbol_lib_dialog;
|
bool show_illegal_symbol_lib_dialog;
|
||||||
bool show_page_limits;
|
bool show_page_limits;
|
||||||
|
bool show_sexpr_file_convert_warning;
|
||||||
bool show_sheet_filename_case_sensitivity_dialog;
|
bool show_sheet_filename_case_sensitivity_dialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include <tool/actions.h>
|
#include <tool/actions.h>
|
||||||
#include <netlist.h>
|
#include <netlist.h>
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
bool aCreateBackupFile )
|
bool aCreateBackupFile )
|
||||||
{
|
{
|
||||||
|
@ -73,9 +74,9 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
|
|
||||||
if( aSaveUnderNewName )
|
if( aSaveUnderNewName )
|
||||||
{
|
{
|
||||||
wxString wildcards = LegacySchematicFileWildcard();
|
wxString wildcards = KiCadSchematicFileWildcard();
|
||||||
|
|
||||||
wildcards += "|" + KiCadSchematicFileWildcard();
|
wildcards += "|" + LegacySchematicFileWildcard();
|
||||||
|
|
||||||
wxFileDialog dlg( this, _( "Schematic Files" ), wxPathOnly( Prj().GetProjectFullName() ),
|
wxFileDialog dlg( this, _( "Schematic Files" ), wxPathOnly( Prj().GetProjectFullName() ),
|
||||||
schematicFileName.GetFullName(), wildcards,
|
schematicFileName.GetFullName(), wildcards,
|
||||||
|
@ -86,10 +87,10 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
|
|
||||||
schematicFileName = dlg.GetPath();
|
schematicFileName = dlg.GetPath();
|
||||||
|
|
||||||
if( dlg.GetFilterIndex() == 0
|
if( dlg.GetFilterIndex() == 1
|
||||||
&& schematicFileName.GetExt() != LegacySchematicFileExtension )
|
&& schematicFileName.GetExt() != LegacySchematicFileExtension )
|
||||||
schematicFileName.SetExt( LegacySchematicFileExtension );
|
schematicFileName.SetExt( LegacySchematicFileExtension );
|
||||||
else if( dlg.GetFilterIndex() == 1
|
else if( dlg.GetFilterIndex() == 0
|
||||||
&& schematicFileName.GetExt() != KiCadSchematicFileExtension )
|
&& schematicFileName.GetExt() != KiCadSchematicFileExtension )
|
||||||
schematicFileName.SetExt( KiCadSchematicFileExtension );
|
schematicFileName.SetExt( KiCadSchematicFileExtension );
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
|
if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Could not save backup of file \"%s\"" ),
|
msg.Printf( _( "Could not save backup of file \"%s\"" ),
|
||||||
GetChars( schematicFileName.GetFullPath() ) );
|
schematicFileName.GetFullPath() );
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,10 +133,10 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Error saving schematic file \"%s\".\n%s" ),
|
msg.Printf( _( "Error saving schematic file \"%s\".\n%s" ),
|
||||||
GetChars( schematicFileName.GetFullPath() ), GetChars( ioe.What() ) );
|
schematicFileName.GetFullPath(), ioe.What() );
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
|
|
||||||
msg.Printf( _( "Failed to save \"%s\"" ), GetChars( schematicFileName.GetFullPath() ) );
|
msg.Printf( _( "Failed to save \"%s\"" ), schematicFileName.GetFullPath() );
|
||||||
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
||||||
|
|
||||||
success = false;
|
success = false;
|
||||||
|
@ -166,7 +167,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
aScreen->ClrSave();
|
aScreen->ClrSave();
|
||||||
aScreen->ClrModify();
|
aScreen->ClrModify();
|
||||||
|
|
||||||
msg.Printf( _( "File %s saved" ), GetChars( aScreen->GetFileName() ) );
|
msg.Printf( _( "File %s saved" ), aScreen->GetFileName() );
|
||||||
SetStatusText( msg, 0 );
|
SetStatusText( msg, 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -183,8 +184,17 @@ void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
|
||||||
if( doSaveAs )
|
if( doSaveAs )
|
||||||
{
|
{
|
||||||
if( SaveEEFile( NULL, true ) )
|
if( SaveEEFile( NULL, true ) )
|
||||||
|
{
|
||||||
|
SCH_SCREEN* screen = GetScreen();
|
||||||
|
|
||||||
|
wxCHECK( screen, /* void */ );
|
||||||
|
|
||||||
|
wxFileName fn = screen->GetFileName();
|
||||||
|
|
||||||
|
if( fn.GetExt() == LegacySchematicFileExtension )
|
||||||
CreateArchiveLibraryCacheFile( true );
|
CreateArchiveLibraryCacheFile( true );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SaveEEFile( NULL );
|
SaveEEFile( NULL );
|
||||||
|
@ -197,9 +207,10 @@ void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
|
||||||
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
|
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
|
||||||
{
|
{
|
||||||
// implement the pseudo code from KIWAY_PLAYER.h:
|
// implement the pseudo code from KIWAY_PLAYER.h:
|
||||||
|
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
|
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||||
|
|
||||||
// This is for python:
|
// This is for python:
|
||||||
if( aFileSet.size() != 1 )
|
if( aFileSet.size() != 1 )
|
||||||
{
|
{
|
||||||
|
@ -258,6 +269,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
SetStatusText( wxEmptyString );
|
SetStatusText( wxEmptyString );
|
||||||
ClearMsgPanel();
|
ClearMsgPanel();
|
||||||
|
|
||||||
|
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
|
||||||
|
|
||||||
// PROJECT::SetProjectFullName() is an impactful function. It should only be
|
// PROJECT::SetProjectFullName() is an impactful function. It should only be
|
||||||
// called under carefully considered circumstances.
|
// called under carefully considered circumstances.
|
||||||
|
|
||||||
|
@ -265,6 +278,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
// it knows what consequences that will have on other KIFACEs running and using
|
// 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.
|
// this same PROJECT. It can be very harmful if that calling code is stupid.
|
||||||
|
|
||||||
|
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
||||||
|
{
|
||||||
// Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
|
// Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
|
||||||
// They are already saved in the kiface project object.
|
// They are already saved in the kiface project object.
|
||||||
if( pro.GetFullPath() != Prj().GetProjectFullName()
|
if( pro.GetFullPath() != Prj().GetProjectFullName()
|
||||||
|
@ -280,6 +295,12 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
|
Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
|
||||||
Prj().SchLibs();
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
LoadProjectFile();
|
LoadProjectFile();
|
||||||
|
|
||||||
|
@ -300,7 +321,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
delete g_RootSheet; // Delete the current project.
|
delete g_RootSheet; // Delete the current project.
|
||||||
g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
|
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* plugin = SCH_IO_MGR::FindPlugin( schFileType );
|
||||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin );
|
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 );
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
|
||||||
|
|
||||||
msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
|
msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
|
||||||
GetChars( fullFileName ), GetChars( ioe.What() ) );
|
fullFileName, ioe.What() );
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
|
|
||||||
msg.Printf( _( "Failed to load \"%s\"" ), GetChars( fullFileName ) );
|
msg.Printf( _( "Failed to load \"%s\"" ), fullFileName );
|
||||||
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -358,6 +378,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
|
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
|
// LIB_ID checks and symbol rescue only apply to the legacy file formats.
|
||||||
|
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
||||||
|
{
|
||||||
// Convert old projects over to use symbol library table.
|
// Convert old projects over to use symbol library table.
|
||||||
if( schematic.HasNoFullyDefinedLibIds() )
|
if( schematic.HasNoFullyDefinedLibIds() )
|
||||||
{
|
{
|
||||||
|
@ -383,13 +406,12 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
_( "Illegal entry found in project file symbol library list." ),
|
_( "Illegal entry found in project file symbol library list." ),
|
||||||
_( "Project Load Warning" ),
|
_( "Project Load Warning" ),
|
||||||
wxOK | wxCENTER | wxICON_EXCLAMATION );
|
wxOK | wxCENTER | wxICON_EXCLAMATION );
|
||||||
invalidLibDlg.SetExtendedMessage(
|
invalidLibDlg.ShowDetailedText(
|
||||||
_( "Symbol libraries defined in the project file symbol library list "
|
_( "Symbol libraries defined in the project file symbol library "
|
||||||
"are no longer supported and will be\nremoved. This may cause "
|
"list are no longer supported and will be\nremoved. This may "
|
||||||
"broken symbol library links under certain conditions." ) );
|
"cause broken symbol library links under certain conditions." ) );
|
||||||
invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
|
invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
|
||||||
invalidLibDlg.ShowModal();
|
invalidLibDlg.ShowModal();
|
||||||
|
|
||||||
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog =
|
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog =
|
||||||
!invalidLibDlg.IsCheckBoxChecked();
|
!invalidLibDlg.IsCheckBoxChecked();
|
||||||
}
|
}
|
||||||
|
@ -399,19 +421,40 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
PART_LIBS::LibNamesAndPaths( &Prj(), true, &paths, &libNames );
|
PART_LIBS::LibNamesAndPaths( &Prj(), true, &paths, &libNames );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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() );
|
|
||||||
|
|
||||||
if( !cfg || !cfg->m_RescueNeverShow )
|
if( !cfg || !cfg->m_RescueNeverShow )
|
||||||
RescueSymbolLibTableProject( false );
|
RescueSymbolLibTableProject( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ConnectionGraph->Reset();
|
|
||||||
|
|
||||||
// Update all symbol library links for all sheets.
|
// Update all symbol library links for all sheets.
|
||||||
// NOTE: calls RecalculateConnections( GLOBAL_CLEANUP )
|
schematic.UpdateSymbolLinks();
|
||||||
schematic.UpdateSymbolLinks( true ); // Update all symbol library links for all sheets.
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
SetScreen( g_CurrentSheet->LastScreen() );
|
SetScreen( g_CurrentSheet->LastScreen() );
|
||||||
|
|
||||||
|
@ -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.
|
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
||||||
|
RecalculateConnections( GLOBAL_CLEANUP );
|
||||||
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
||||||
|
|
||||||
GetScreen()->m_Initialized = true;
|
GetScreen()->m_Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +519,7 @@ bool SCH_EDIT_FRAME::AppendSchematic()
|
||||||
wxString path = wxPathOnly( Prj().GetProjectFullName() );
|
wxString path = wxPathOnly( Prj().GetProjectFullName() );
|
||||||
|
|
||||||
wxFileDialog dlg( this, _( "Append Schematic" ), path, wxEmptyString,
|
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 )
|
if( dlg.ShowModal() == wxID_CANCEL )
|
||||||
return false;
|
return false;
|
||||||
|
@ -548,6 +591,7 @@ bool SCH_EDIT_FRAME::SaveProject()
|
||||||
SCH_SCREEN* screen;
|
SCH_SCREEN* screen;
|
||||||
SCH_SCREENS screenList;
|
SCH_SCREENS screenList;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
bool updateFileType = false;
|
||||||
|
|
||||||
// I want to see it in the debugger, show me the string! Can't do that with wxFileName.
|
// 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() );
|
wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() );
|
||||||
|
@ -561,9 +605,35 @@ bool SCH_EDIT_FRAME::SaveProject()
|
||||||
}
|
}
|
||||||
|
|
||||||
for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
|
for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
|
||||||
success &= SaveEEFile( screen );
|
{
|
||||||
|
// Convert legacy schematics file name extensions for the new format.
|
||||||
|
wxFileName tmpFn = screen->GetFileName();
|
||||||
|
|
||||||
CreateArchiveLibraryCacheFile();
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( updateFileType )
|
||||||
|
UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() );
|
||||||
|
|
||||||
// Save the sheet name map to the project file
|
// Save the sheet name map to the project file
|
||||||
wxString configFile = Prj().GetProjectFullName();
|
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 )
|
if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_Convert != aOther.m_Convert )
|
||||||
return m_Convert - m_Convert;
|
return m_Convert - m_Convert;
|
||||||
|
|
||||||
|
if( m_Fill != aOther.m_Fill )
|
||||||
|
return m_Fill - aOther.m_Fill;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -786,7 +786,7 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
||||||
{
|
{
|
||||||
wxFileName fn;
|
wxFileName fn;
|
||||||
wxString msg;
|
wxString msg;
|
||||||
SCH_IO_MGR::SCH_FILE_T aFileType = SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY;
|
SCH_IO_MGR::SCH_FILE_T fileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
|
||||||
PROJECT& prj = Prj();
|
PROJECT& prj = Prj();
|
||||||
|
|
||||||
m_toolManager->RunAction( ACTIONS::cancelInteractive, true );
|
m_toolManager->RunAction( ACTIONS::cancelInteractive, true );
|
||||||
|
@ -808,10 +808,10 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
||||||
default_path = search->LastVisitedPath();
|
default_path = search->LastVisitedPath();
|
||||||
|
|
||||||
fn.SetName( aLibrary );
|
fn.SetName( aLibrary );
|
||||||
fn.SetExt( SchematicLibraryFileExtension );
|
fn.SetExt( KiCadSymbolLibFileExtension );
|
||||||
|
|
||||||
wxString wildcards = SchematicLibraryFileWildcard();
|
wxString wildcards = KiCadSymbolLibFileWildcard();
|
||||||
wildcards += "|" + KiCadSymbolLibFileWildcard();
|
wildcards += "|" + SchematicLibraryFileWildcard();
|
||||||
|
|
||||||
wxFileDialog dlg( this, wxString::Format( _( "Save Library \"%s\" As..." ), aLibrary ),
|
wxFileDialog dlg( this, wxString::Format( _( "Save Library \"%s\" As..." ), aLibrary ),
|
||||||
default_path, fn.GetFullName(), wildcards,
|
default_path, fn.GetFullName(), wildcards,
|
||||||
|
@ -823,19 +823,20 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
||||||
fn = dlg.GetPath();
|
fn = dlg.GetPath();
|
||||||
|
|
||||||
// Update the file extension and plugin if a different library type was selected.
|
// Update the file extension and plugin if a different library type was selected.
|
||||||
if( dlg.GetFilterIndex() == 0 )
|
if( dlg.GetFilterIndex() == 1 )
|
||||||
{
|
{
|
||||||
fn.SetExt( SchematicLibraryFileExtension );
|
fn.SetExt( SchematicLibraryFileExtension );
|
||||||
|
fileType = SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fn.SetExt( KiCadSymbolLibFileExtension );
|
fn.SetExt( KiCadSymbolLibFileExtension );
|
||||||
aFileType = SCH_IO_MGR::SCH_FILE_T::SCH_KICAD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
|
fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
|
||||||
|
fileType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFileName docFileName = fn;
|
wxFileName docFileName = fn;
|
||||||
|
@ -855,7 +856,7 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
||||||
if( !backupFile( docFileName, "bck" ) )
|
if( !backupFile( docFileName, "bck" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), aFileType ) )
|
if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath(), fileType ) )
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Failed to save changes to symbol library file \"%s\"" ),
|
msg.Printf( _( "Failed to save changes to symbol library file \"%s\"" ),
|
||||||
fn.GetFullPath() );
|
fn.GetFullPath() );
|
||||||
|
|
|
@ -573,8 +573,7 @@ bool SCH_EDIT_FRAME::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
|
||||||
{
|
{
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks( true );
|
schematic.UpdateSymbolLinks();
|
||||||
|
|
||||||
g_ConnectionGraph->Reset();
|
g_ConnectionGraph->Reset();
|
||||||
RecalculateConnections( GLOBAL_CLEANUP );
|
RecalculateConnections( GLOBAL_CLEANUP );
|
||||||
}
|
}
|
||||||
|
@ -885,7 +884,7 @@ bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( wxWindow *aParent )
|
||||||
// Update the schematic symbol library links since the library list has changed.
|
// Update the schematic symbol library links since the library list has changed.
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks( true );
|
schematic.UpdateSymbolLinks();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,28 +23,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <pgm_base.h>
|
|
||||||
#include <sch_draw_panel.h>
|
|
||||||
#include <gr_basic.h>
|
#include <gr_basic.h>
|
||||||
#include <kicad_string.h>
|
#include <kicad_string.h>
|
||||||
#include <richio.h>
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <plotter.h>
|
#include <plotter.h>
|
||||||
#include <msgpanel.h>
|
#include <msgpanel.h>
|
||||||
#include <bitmaps.h>
|
#include <bitmaps.h>
|
||||||
|
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
#include <class_library.h>
|
|
||||||
#include <lib_rectangle.h>
|
#include <lib_rectangle.h>
|
||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
#include <lib_text.h>
|
#include <lib_text.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <sch_sheet_path.h>
|
#include <sch_sheet_path.h>
|
||||||
#include <sch_legacy_plugin.h>
|
|
||||||
#include <netlist_object.h>
|
#include <netlist_object.h>
|
||||||
#include <lib_item.h>
|
#include <lib_item.h>
|
||||||
#include <symbol_lib_table.h>
|
|
||||||
|
|
||||||
#include <dialogs/dialog_schematic_find.h>
|
#include <dialogs/dialog_schematic_find.h>
|
||||||
|
|
||||||
|
@ -134,14 +128,11 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
|
||||||
|
|
||||||
part = aPart.Flatten();
|
part = aPart.Flatten();
|
||||||
part->SetParent();
|
part->SetParent();
|
||||||
m_part.reset( part.release() );
|
SetLibSymbol( part.release() );
|
||||||
|
|
||||||
// Copy fields from the library component
|
// Copy fields from the library component
|
||||||
UpdateFields( true, true );
|
UpdateFields( true, true );
|
||||||
|
|
||||||
// Update the pin locations
|
|
||||||
UpdatePins();
|
|
||||||
|
|
||||||
// Update the reference -- just the prefix for now.
|
// Update the reference -- just the prefix for now.
|
||||||
if( sheet )
|
if( sheet )
|
||||||
SetRef( sheet, aPart.GetReferenceField().GetText() + wxT( "?" ) );
|
SetRef( sheet, aPart.GetReferenceField().GetText() + wxT( "?" ) );
|
||||||
|
@ -149,6 +140,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
|
||||||
m_prefix = aPart.GetReferenceField().GetText() + wxT( "?" );
|
m_prefix = aPart.GetReferenceField().GetText() + wxT( "?" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_COMPONENT::SCH_COMPONENT(
|
SCH_COMPONENT::SCH_COMPONENT(
|
||||||
LIB_PART& aPart, SCH_SHEET_PATH* aSheet, COMPONENT_SELECTION& aSel, const wxPoint& pos )
|
LIB_PART& aPart, SCH_SHEET_PATH* aSheet, COMPONENT_SELECTION& aSel, const wxPoint& pos )
|
||||||
: SCH_COMPONENT( aPart, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
|
: SCH_COMPONENT( aPart, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
|
||||||
|
@ -175,7 +167,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
|
||||||
m_isInNetlist = aComponent.m_isInNetlist;
|
m_isInNetlist = aComponent.m_isInNetlist;
|
||||||
|
|
||||||
if( aComponent.m_part )
|
if( aComponent.m_part )
|
||||||
m_part.reset( new LIB_PART( *aComponent.m_part.get() ) );
|
SetLibSymbol( new LIB_PART( *aComponent.m_part.get() ) );
|
||||||
|
|
||||||
const_cast<KIID&>( m_Uuid ) = aComponent.m_Uuid;
|
const_cast<KIID&>( m_Uuid ) = aComponent.m_Uuid;
|
||||||
|
|
||||||
|
@ -188,8 +180,6 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
|
||||||
for( SCH_FIELD& field : m_Fields )
|
for( SCH_FIELD& field : m_Fields )
|
||||||
field.SetParent( this );
|
field.SetParent( this );
|
||||||
|
|
||||||
UpdatePins();
|
|
||||||
|
|
||||||
m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced;
|
m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,61 +226,28 @@ void SCH_COMPONENT::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, PART_LIBS* aLibs )
|
void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId )
|
||||||
{
|
{
|
||||||
if( m_lib_id != aLibId )
|
if( m_lib_id != aLibId )
|
||||||
{
|
{
|
||||||
m_lib_id = aLibId;
|
m_lib_id = aLibId;
|
||||||
SetModified();
|
SetModified();
|
||||||
|
|
||||||
if( aLibs )
|
|
||||||
{
|
|
||||||
Resolve( aLibs );
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString SCH_COMPONENT::GetSchSymbolLibraryName() const
|
||||||
|
{
|
||||||
|
if( !m_schLibSymbolName.IsEmpty() )
|
||||||
|
return m_schLibSymbolName;
|
||||||
else
|
else
|
||||||
|
return m_lib_id.Format().wx_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_COMPONENT::SetLibSymbol( LIB_PART* aLibSymbol )
|
||||||
{
|
{
|
||||||
m_part.reset();
|
m_part.reset( aLibSymbol );
|
||||||
m_pins.clear();
|
|
||||||
m_pinMap.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable,
|
|
||||||
PART_LIB* aCacheLib )
|
|
||||||
{
|
|
||||||
if( m_lib_id == aLibId )
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_lib_id = aLibId;
|
|
||||||
SetModified();
|
|
||||||
|
|
||||||
std::unique_ptr< LIB_PART > symbol;
|
|
||||||
|
|
||||||
if( aSymLibTable && aSymLibTable->HasLibrary( m_lib_id.GetLibNickname() ) )
|
|
||||||
{
|
|
||||||
LIB_PART* tmp = aSymLibTable->LoadSymbol( m_lib_id );
|
|
||||||
|
|
||||||
if( tmp )
|
|
||||||
{
|
|
||||||
symbol = tmp->Flatten();
|
|
||||||
symbol->SetParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !symbol && aCacheLib )
|
|
||||||
{
|
|
||||||
LIB_PART* tmp = aCacheLib->FindPart( m_lib_id.Format().wx_str() );
|
|
||||||
|
|
||||||
if( tmp )
|
|
||||||
{
|
|
||||||
symbol = tmp->Flatten();
|
|
||||||
symbol->SetParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_part.reset( symbol.release() );
|
|
||||||
UpdatePins();
|
UpdatePins();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,138 +274,6 @@ wxString SCH_COMPONENT::GetDatasheet() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs )
|
|
||||||
{
|
|
||||||
// I've never been happy that the actual individual PART_LIB is left up to
|
|
||||||
// flimsy search path ordering. None-the-less find a part based on that design:
|
|
||||||
if( LIB_PART* part = aLibs->FindLibPart( m_lib_id ) )
|
|
||||||
{
|
|
||||||
std::unique_ptr< LIB_PART > flattenedPart = part->Flatten();
|
|
||||||
flattenedPart->SetParent();
|
|
||||||
m_part.reset( flattenedPart.release() );
|
|
||||||
UpdatePins();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
|
|
||||||
{
|
|
||||||
std::unique_ptr< LIB_PART > part;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// We want a full symbol not just the top level child symbol.
|
|
||||||
PROPERTIES props;
|
|
||||||
|
|
||||||
props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
|
|
||||||
|
|
||||||
// LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
|
|
||||||
// is not found in the table so check if the library still exists in the table
|
|
||||||
// before attempting to load the symbol.
|
|
||||||
if( m_lib_id.IsValid() && aLibTable.HasLibrary( m_lib_id.GetLibNickname() ) )
|
|
||||||
{
|
|
||||||
LIB_PART* tmp = aLibTable.LoadSymbol( m_lib_id );
|
|
||||||
|
|
||||||
if( tmp )
|
|
||||||
{
|
|
||||||
part = tmp->Flatten();
|
|
||||||
part->SetParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back to cache library. This is temporary until the new schematic file
|
|
||||||
// format is implemented.
|
|
||||||
if( !part && aCacheLib )
|
|
||||||
{
|
|
||||||
wxString libId = m_lib_id.Format().wx_str();
|
|
||||||
libId.Replace( ":", "_" );
|
|
||||||
wxLogTrace( traceSymbolResolver,
|
|
||||||
"Library symbol %s not found falling back to cache library.",
|
|
||||||
m_lib_id.Format().wx_str() );
|
|
||||||
LIB_PART* tmp = aCacheLib->FindPart( libId );
|
|
||||||
|
|
||||||
if( tmp )
|
|
||||||
{
|
|
||||||
part = tmp->Flatten();
|
|
||||||
part->SetParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( part )
|
|
||||||
{
|
|
||||||
m_part.reset( part.release() );
|
|
||||||
UpdatePins();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& ioe )
|
|
||||||
{
|
|
||||||
wxLogTrace( traceSymbolResolver, "I/O error %s resolving library symbol %s", ioe.What(),
|
|
||||||
m_lib_id.Format().wx_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxLogTrace( traceSymbolResolver, "Cannot resolve library symbol %s",
|
|
||||||
m_lib_id.Format().wx_str() );
|
|
||||||
|
|
||||||
m_part.reset();
|
|
||||||
UpdatePins(); // This will clear the pin map and library symbol pin pointers.
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Helper sort function, used in SCH_COMPONENT::ResolveAll, to sort sch component by lib_id
|
|
||||||
static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp )
|
|
||||||
{
|
|
||||||
if( ref->GetLibId() == cmp->GetLibId() )
|
|
||||||
{
|
|
||||||
if( ref->GetUnit() == cmp->GetUnit() )
|
|
||||||
return ref->GetConvert() < cmp->GetConvert();
|
|
||||||
|
|
||||||
return ref->GetUnit() < cmp->GetUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ref->GetLibId() < cmp->GetLibId();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::ResolveAll(
|
|
||||||
std::vector<SCH_COMPONENT*>& aComponents, SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
|
|
||||||
{
|
|
||||||
// sort it by lib part. Cmp will be grouped by same lib part.
|
|
||||||
std::sort( aComponents.begin(), aComponents.end(), sort_by_libid );
|
|
||||||
|
|
||||||
LIB_ID curr_libid;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aComponents.size(); ++ii )
|
|
||||||
{
|
|
||||||
SCH_COMPONENT* cmp = aComponents[ii];
|
|
||||||
curr_libid = cmp->m_lib_id;
|
|
||||||
cmp->Resolve( aLibTable, aCacheLib );
|
|
||||||
cmp->UpdatePins();
|
|
||||||
|
|
||||||
// Propagate the m_part pointer to other members using the same lib_id
|
|
||||||
for( unsigned jj = ii + 1; jj < aComponents.size(); ++jj )
|
|
||||||
{
|
|
||||||
SCH_COMPONENT* next_cmp = aComponents[jj];
|
|
||||||
|
|
||||||
if( curr_libid != next_cmp->m_lib_id )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( cmp->m_part )
|
|
||||||
next_cmp->m_part.reset( new LIB_PART( *cmp->m_part.get() ) );
|
|
||||||
|
|
||||||
next_cmp->UpdatePins();
|
|
||||||
|
|
||||||
ii = jj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::UpdatePins()
|
void SCH_COMPONENT::UpdatePins()
|
||||||
{
|
{
|
||||||
m_pins.clear();
|
m_pins.clear();
|
||||||
|
@ -1140,7 +965,7 @@ void SCH_COMPONENT::SetOrientation( int aOrientation )
|
||||||
|
|
||||||
default:
|
default:
|
||||||
transform = false;
|
transform = false;
|
||||||
wxMessageBox( wxT( "SetRotateMiroir() error: ill value" ) );
|
wxFAIL_MSG( "Invalid schematic symbol orientation type." );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,7 +1022,7 @@ int SCH_COMPONENT::GetOrientation()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error: orientation not found in list (should not happen)
|
// Error: orientation not found in list (should not happen)
|
||||||
wxMessageBox( wxT( "Component orientation matrix internal error" ) );
|
wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
|
||||||
m_transform = transform;
|
m_transform = transform;
|
||||||
|
|
||||||
return CMP_NORMAL;
|
return CMP_NORMAL;
|
||||||
|
@ -1313,15 +1138,15 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aL
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), msg, BROWN ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), msg, BROWN ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_part->GetLib() && m_part->GetLib()->IsCache() )
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Library" ),
|
|
||||||
m_part->GetLib()->GetLogicalName(), RED ) );
|
|
||||||
else if( !m_lib_id.GetLibNickname().empty() )
|
else if( !m_lib_id.GetLibNickname().empty() )
|
||||||
|
{
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
|
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
|
||||||
BROWN ) );
|
BROWN ) );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ), RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ), RED ) );
|
||||||
|
}
|
||||||
|
|
||||||
// Display the current associated footprint, if exists.
|
// Display the current associated footprint, if exists.
|
||||||
if( !GetField( FOOTPRINT )->IsVoid() )
|
if( !GetField( FOOTPRINT )->IsVoid() )
|
||||||
|
|
|
@ -93,8 +93,7 @@ struct COMPONENT_INSTANCE_REFERENCE
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SCH_COMPONENT
|
* Schematic symbol object.
|
||||||
* describes a real schematic component
|
|
||||||
*/
|
*/
|
||||||
class SCH_COMPONENT : public SCH_ITEM
|
class SCH_COMPONENT : public SCH_ITEM
|
||||||
{
|
{
|
||||||
|
@ -115,6 +114,17 @@ private:
|
||||||
///< what the component is. Determined, upon placement, from the
|
///< what the component is. Determined, upon placement, from the
|
||||||
///< library component. Created upon file load, by the first
|
///< library component. Created upon file load, by the first
|
||||||
///< non-digits in the reference fields.
|
///< non-digits in the reference fields.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name used to look up a symbol in the symbol library embedded in a schematic.
|
||||||
|
*
|
||||||
|
* By default this is the same as #LIB_ID::GetLibItemName(). However, schematics
|
||||||
|
* allow for multiple variants of the same library symbol. Set this member In order
|
||||||
|
* to preserve the link to the original symbol library. If empty, the return of
|
||||||
|
* #LIB_ID::GetLibItemName() should be used.
|
||||||
|
*/
|
||||||
|
wxString m_schLibSymbolName;
|
||||||
|
|
||||||
TRANSFORM m_transform; ///< The rotation/mirror transformation matrix.
|
TRANSFORM m_transform; ///< The rotation/mirror transformation matrix.
|
||||||
SCH_FIELDS m_Fields; ///< Variable length list of fields.
|
SCH_FIELDS m_Fields; ///< Variable length list of fields.
|
||||||
|
|
||||||
|
@ -199,13 +209,42 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsMovableFromAnchorPoint() override { return true; }
|
bool IsMovableFromAnchorPoint() override { return true; }
|
||||||
|
|
||||||
void SetLibId( const LIB_ID& aName, PART_LIBS* aLibs=NULL );
|
void SetLibId( const LIB_ID& aName );
|
||||||
void SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable, PART_LIB* aCacheLib );
|
|
||||||
|
|
||||||
const LIB_ID& GetLibId() const { return m_lib_id; }
|
const LIB_ID& GetLibId() const { return m_lib_id; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the symbol in the schematic library symbol list.
|
||||||
|
*
|
||||||
|
* @note See #SCH_SCREEN::m_libSymbols
|
||||||
|
*
|
||||||
|
* The name of the schematic symbol list entry can vary from the item name in the #LIB_ID
|
||||||
|
* object because the library symbol may have changed so a new name has to be generated
|
||||||
|
* but the original symbol library link has to be preserved in order to update it from
|
||||||
|
* the library at some point in the future. If this name is empty, then the library item
|
||||||
|
* name from #LIB_ID is used.
|
||||||
|
*/
|
||||||
|
void SetSchSymbolLibraryName( const wxString& aName ) { m_schLibSymbolName = aName; }
|
||||||
|
wxString GetSchSymbolLibraryName() const;
|
||||||
|
bool UseLibIdLookup() const { return m_schLibSymbolName.IsEmpty(); }
|
||||||
|
|
||||||
std::unique_ptr< LIB_PART >& GetPartRef() { return m_part; }
|
std::unique_ptr< LIB_PART >& GetPartRef() { return m_part; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this schematic symbol library symbol reference to \a aLibSymbol
|
||||||
|
*
|
||||||
|
* The schematic symbol object owns \a aLibSymbol and the pin list will be updated
|
||||||
|
* accordingly. The #LIB_ID object must be valid ( have both a library nickname and
|
||||||
|
* symbol name ) in order to set the schematic symbol #LIB_ID. Otherwise an assertion
|
||||||
|
* will be raised in debug builds and the library symbol will be cleared. The new file
|
||||||
|
* format will no longer require a cache library so all library symbols must be valid.
|
||||||
|
*
|
||||||
|
* @note This is the only way to publicly set the library symbol for a schematic
|
||||||
|
* symbol except for the ctors that take a LIB_PART reference. All previous
|
||||||
|
* public resolvers have been deprecated.
|
||||||
|
*/
|
||||||
|
void SetLibSymbol( LIB_PART* aLibSymbol );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return information about the aliased parts
|
* Return information about the aliased parts
|
||||||
*/
|
*/
|
||||||
|
@ -216,18 +255,6 @@ public:
|
||||||
*/
|
*/
|
||||||
wxString GetDatasheet() const;
|
wxString GetDatasheet() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns the current #LIB_PART from \a aLibs which this symbol is based on.
|
|
||||||
*
|
|
||||||
* @param aLibs is the current set of LIB_PARTs to choose from.
|
|
||||||
*/
|
|
||||||
bool Resolve( PART_LIBS* aLibs );
|
|
||||||
|
|
||||||
bool Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib = NULL );
|
|
||||||
|
|
||||||
static void ResolveAll( std::vector<SCH_COMPONENT*>& aComponents, SYMBOL_LIB_TABLE& aLibTable,
|
|
||||||
PART_LIB* aCacheLib = NULL );
|
|
||||||
|
|
||||||
int GetUnit() const { return m_unit; }
|
int GetUnit() const { return m_unit; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 CERN
|
* Copyright (C) 2017 CERN
|
||||||
* Copyright (C) 2017-2019 Kicad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2017-2020 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
|
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
@ -1275,17 +1275,20 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
|
||||||
component->GetField( REFERENCE )->SetVisible( false );
|
component->GetField( REFERENCE )->SetVisible( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Save the pin positions
|
// Save the pin positions
|
||||||
auto& schLibTable = *m_kiway->Prj().SchSymbolLibTable();
|
SYMBOL_LIB_TABLE& schLibTable = *m_kiway->Prj().SchSymbolLibTable();
|
||||||
wxCHECK( component->Resolve( schLibTable ), /*void*/ );
|
LIB_PART* libSymbol = schLibTable.LoadSymbol( component->GetLibId() );
|
||||||
|
|
||||||
|
wxCHECK( libSymbol, /*void*/ );
|
||||||
|
|
||||||
|
component->SetLibSymbol( libSymbol );
|
||||||
|
|
||||||
std::vector<LIB_PIN*> pins;
|
std::vector<LIB_PIN*> pins;
|
||||||
component->GetPins( pins );
|
component->GetPins( pins );
|
||||||
|
|
||||||
for( const auto& pin : pins )
|
for( const auto& pin : pins )
|
||||||
m_connPoints[component->GetPinPhysicalPosition( pin )].emplace( pin );
|
m_connPoints[component->GetPinPhysicalPosition( pin )].emplace( pin );
|
||||||
|
|
||||||
|
|
||||||
component->ClearFlags();
|
component->ClearFlags();
|
||||||
|
|
||||||
screen->Append( component.release() );
|
screen->Append( component.release() );
|
||||||
|
|
|
@ -768,7 +768,7 @@ void SCH_EDIT_FRAME::NewProject()
|
||||||
{
|
{
|
||||||
// Enforce the extension, wxFileDialog is inept.
|
// Enforce the extension, wxFileDialog is inept.
|
||||||
wxFileName create_me = dlg.GetPath();
|
wxFileName create_me = dlg.GetPath();
|
||||||
create_me.SetExt( LegacySchematicFileExtension );
|
create_me.SetExt( KiCadSchematicFileExtension );
|
||||||
|
|
||||||
if( create_me.FileExists() )
|
if( create_me.FileExists() )
|
||||||
{
|
{
|
||||||
|
@ -790,9 +790,9 @@ void SCH_EDIT_FRAME::NewProject()
|
||||||
void SCH_EDIT_FRAME::LoadProject()
|
void SCH_EDIT_FRAME::LoadProject()
|
||||||
{
|
{
|
||||||
wxString pro_dir = m_mruPath;
|
wxString pro_dir = m_mruPath;
|
||||||
wxString wildcards = LegacySchematicFileWildcard();
|
wxString wildcards = KiCadSchematicFileWildcard();
|
||||||
|
|
||||||
wildcards += "|" + KiCadSchematicFileWildcard();
|
wildcards += "|" + LegacySchematicFileWildcard();
|
||||||
|
|
||||||
wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir, wxEmptyString,
|
wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir, wxEmptyString,
|
||||||
wildcards, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
|
wildcards, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
|
||||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -63,6 +63,7 @@ class wxFindReplaceData;
|
||||||
class RESCUER;
|
class RESCUER;
|
||||||
class HIERARCHY_NAVIG_DLG;
|
class HIERARCHY_NAVIG_DLG;
|
||||||
|
|
||||||
|
// @todo Move this to transform alone with all of the transform manipulation code.
|
||||||
/// enum used in RotationMiroir()
|
/// enum used in RotationMiroir()
|
||||||
enum COMPONENT_ORIENTATION_T {
|
enum COMPONENT_ORIENTATION_T {
|
||||||
CMP_NORMAL, // Normal orientation, no rotation or mirror
|
CMP_NORMAL, // Normal orientation, no rotation or mirror
|
||||||
|
|
|
@ -150,7 +150,7 @@ const wxString SCH_IO_MGR::GetLibraryFileExtension( SCH_FILE_T aFileType )
|
||||||
|
|
||||||
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
|
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
|
||||||
{
|
{
|
||||||
SCH_FILE_T ret = SCH_LEGACY; // default guess, unless detected otherwise.
|
SCH_FILE_T ret = SCH_KICAD; // default guess, unless detected otherwise.
|
||||||
wxFileName fn( aLibPath );
|
wxFileName fn( aLibPath );
|
||||||
|
|
||||||
if( fn.GetExt() == SchematicLibraryFileExtension )
|
if( fn.GetExt() == SchematicLibraryFileExtension )
|
||||||
|
@ -168,7 +168,7 @@ SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromLibPath( const wxString& a
|
||||||
|
|
||||||
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& aSchematicPath )
|
SCH_IO_MGR::SCH_FILE_T SCH_IO_MGR::GuessPluginTypeFromSchPath( const wxString& aSchematicPath )
|
||||||
{
|
{
|
||||||
SCH_FILE_T ret = SCH_LEGACY; // default guess, unless detected otherwise.
|
SCH_FILE_T ret = SCH_KICAD; // default guess, unless detected otherwise.
|
||||||
wxFileName fn( aSchematicPath );
|
wxFileName fn( aSchematicPath );
|
||||||
|
|
||||||
if( fn.GetExt() == LegacySchematicFileExtension )
|
if( fn.GetExt() == LegacySchematicFileExtension )
|
||||||
|
|
|
@ -39,11 +39,13 @@
|
||||||
#include <pgm_base.h>
|
#include <pgm_base.h>
|
||||||
#include <plotter.h>
|
#include <plotter.h>
|
||||||
#include <project.h>
|
#include <project.h>
|
||||||
|
#include <reporter.h>
|
||||||
#include <sch_draw_panel.h>
|
#include <sch_draw_panel.h>
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <sch_item.h>
|
#include <sch_item.h>
|
||||||
|
|
||||||
#include <class_library.h>
|
#include <class_library.h>
|
||||||
|
#include <class_libentry.h>
|
||||||
#include <connection_graph.h>
|
#include <connection_graph.h>
|
||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
#include <netlist_object.h>
|
#include <netlist_object.h>
|
||||||
|
@ -146,11 +148,21 @@ SCH_SCREEN::SCH_SCREEN( KIWAY* aKiway ) :
|
||||||
|
|
||||||
SCH_SCREEN::~SCH_SCREEN()
|
SCH_SCREEN::~SCH_SCREEN()
|
||||||
{
|
{
|
||||||
|
clearLibSymbols();
|
||||||
ClearUndoRedoList();
|
ClearUndoRedoList();
|
||||||
FreeDrawList();
|
FreeDrawList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREEN::clearLibSymbols()
|
||||||
|
{
|
||||||
|
for( auto libSymbol : m_libSymbols )
|
||||||
|
delete libSymbol.second;
|
||||||
|
|
||||||
|
m_libSymbols.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREEN::IncRefCount()
|
void SCH_SCREEN::IncRefCount()
|
||||||
{
|
{
|
||||||
m_refCount++;
|
m_refCount++;
|
||||||
|
@ -169,6 +181,47 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
|
if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
|
||||||
{
|
{
|
||||||
|
if( aItem->Type() == SCH_COMPONENT_T )
|
||||||
|
{
|
||||||
|
SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( aItem );
|
||||||
|
|
||||||
|
if( symbol->GetPartRef() )
|
||||||
|
{
|
||||||
|
auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
|
||||||
|
|
||||||
|
if( it == m_libSymbols.end() )
|
||||||
|
{
|
||||||
|
m_libSymbols[symbol->GetSchSymbolLibraryName()] =
|
||||||
|
new LIB_PART( *symbol->GetPartRef() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The original library symbol may have changed since the last time
|
||||||
|
// it was added to the schematic. If it has changed, then a new name
|
||||||
|
// must be created for the library symbol list to prevent all of the
|
||||||
|
// other schematic symbols referencing that library symbol from changing.
|
||||||
|
LIB_PART* foundSymbol = it->second;
|
||||||
|
|
||||||
|
if( *foundSymbol != *symbol->GetPartRef() )
|
||||||
|
{
|
||||||
|
int cnt = 1;
|
||||||
|
wxString newName;
|
||||||
|
|
||||||
|
newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
|
||||||
|
|
||||||
|
while( m_libSymbols.find( newName ) != m_libSymbols.end() )
|
||||||
|
{
|
||||||
|
cnt += 1;
|
||||||
|
newName.Printf( "%s_%d", symbol->GetLibId().Format().wx_str(), cnt );
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol->SetSchSymbolLibraryName( newName );
|
||||||
|
m_libSymbols[newName] = new LIB_PART( *symbol->GetPartRef() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_rtree.insert( aItem );
|
m_rtree.insert( aItem );
|
||||||
--m_modification_sync;
|
--m_modification_sync;
|
||||||
}
|
}
|
||||||
|
@ -191,9 +244,14 @@ void SCH_SCREEN::Append( SCH_SCREEN* aScreen )
|
||||||
void SCH_SCREEN::Clear( bool aFree )
|
void SCH_SCREEN::Clear( bool aFree )
|
||||||
{
|
{
|
||||||
if( aFree )
|
if( aFree )
|
||||||
|
{
|
||||||
FreeDrawList();
|
FreeDrawList();
|
||||||
|
clearLibSymbols();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_rtree.clear();
|
m_rtree.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Clear the project settings
|
// Clear the project settings
|
||||||
m_ScreenNumber = m_NumberOfScreens = 1;
|
m_ScreenNumber = m_NumberOfScreens = 1;
|
||||||
|
@ -230,7 +288,39 @@ void SCH_SCREEN::Update( SCH_ITEM* aItem )
|
||||||
|
|
||||||
bool SCH_SCREEN::Remove( SCH_ITEM* aItem )
|
bool SCH_SCREEN::Remove( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
return m_rtree.remove( aItem );
|
bool retv = m_rtree.remove( aItem );
|
||||||
|
|
||||||
|
// Check if the library symbol for the removed schematic symbol is still required.
|
||||||
|
if( retv && aItem->Type() == SCH_COMPONENT_T )
|
||||||
|
{
|
||||||
|
SCH_COMPONENT* removedSymbol = static_cast<SCH_COMPONENT*>( aItem );
|
||||||
|
|
||||||
|
bool removeUnusedLibSymbol = true;
|
||||||
|
|
||||||
|
for( SCH_ITEM* item : Items().OfType( SCH_COMPONENT_T ) )
|
||||||
|
{
|
||||||
|
SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
|
||||||
|
|
||||||
|
if( removedSymbol->GetSchSymbolLibraryName() == symbol->GetSchSymbolLibraryName() )
|
||||||
|
{
|
||||||
|
removeUnusedLibSymbol = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( removeUnusedLibSymbol )
|
||||||
|
{
|
||||||
|
auto it = m_libSymbols.find( removedSymbol->GetSchSymbolLibraryName() );
|
||||||
|
|
||||||
|
if( it != m_libSymbols.end() )
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
m_libSymbols.erase( it );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,11 +340,9 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
|
||||||
sheet->RemovePin( sheetPin );
|
sheet->RemovePin( sheetPin );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
delete aItem;
|
delete aItem;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem )
|
bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem )
|
||||||
|
@ -481,42 +569,174 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
|
void SCH_SCREEN::UpdateSymbolLinks( REPORTER* aReporter )
|
||||||
{
|
{
|
||||||
// Initialize or reinitialize the pointer to the LIB_PART for each component
|
wxString msg;
|
||||||
// found in m_drawList, but only if needed (change in lib or schematic)
|
std::unique_ptr< LIB_PART > libSymbol;
|
||||||
// therefore the calculation time is usually very low.
|
std::vector<SCH_COMPONENT*> symbols;
|
||||||
if( !IsEmpty() )
|
|
||||||
{
|
|
||||||
std::vector<SCH_COMPONENT*> cmps;
|
|
||||||
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
|
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
|
||||||
int mod_hash = libs->GetModifyHash();
|
|
||||||
|
|
||||||
for( SCH_ITEM* aItem : Items().OfType( SCH_COMPONENT_T ) )
|
// This will be a nullptr if an s-expression schematic is loaded.
|
||||||
cmps.push_back( static_cast<SCH_COMPONENT*>( aItem ) );
|
PART_LIBS* legacyLibs = Prj().SchLibs();
|
||||||
|
|
||||||
for( SCH_COMPONENT* cmp : cmps )
|
for( auto item : Items().OfType( SCH_COMPONENT_T ) )
|
||||||
Remove( cmp );
|
symbols.push_back( static_cast<SCH_COMPONENT*>( item ) );
|
||||||
|
|
||||||
// Must we resolve?
|
// Remove them from the R tree. There bounding box size may change.
|
||||||
if( (m_modification_sync != mod_hash) || aForce )
|
for( auto symbol : symbols )
|
||||||
|
Remove( symbol );
|
||||||
|
|
||||||
|
// Clear all existing symbol links.
|
||||||
|
clearLibSymbols();
|
||||||
|
|
||||||
|
for( auto symbol : symbols )
|
||||||
{
|
{
|
||||||
SCH_COMPONENT::ResolveAll( cmps, *libs, Prj().SchLibs()->GetCacheLibrary() );
|
LIB_PART* tmp = nullptr;
|
||||||
|
libSymbol.reset();
|
||||||
|
|
||||||
m_modification_sync = mod_hash; // note the last mod_hash
|
// If the symbol is already in the internal library, map the symbol to it.
|
||||||
|
auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
|
||||||
|
|
||||||
|
if( ( it != m_libSymbols.end() ) )
|
||||||
|
{
|
||||||
|
if( aReporter )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Setting schematic symbol '%s %s' library identifier "
|
||||||
|
"to '%s'. " ),
|
||||||
|
symbol->GetField( REFERENCE )->GetText(),
|
||||||
|
symbol->GetField( VALUE )->GetText(),
|
||||||
|
symbol->GetLibId().Format().wx_str() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal library symbols are flattens so just make a copy.
|
||||||
|
symbol->GetPartRef().reset( new LIB_PART( *it->second ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !symbol->GetLibId().IsValid() )
|
||||||
|
{
|
||||||
|
if( aReporter )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Schematic symbol reference '%s' library identifier is not "
|
||||||
|
"valid. Unable to link library symbol." ),
|
||||||
|
symbol->GetLibId().Format().wx_str() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
|
||||||
|
// is not found in the table so check if the library still exists in the table
|
||||||
|
// before attempting to load the symbol.
|
||||||
|
if( !libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) && !legacyLibs )
|
||||||
|
{
|
||||||
|
if( aReporter )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Symbol library '%s' not found and no fallback cache "
|
||||||
|
"library avaiable. Unable to link library symbol." ),
|
||||||
|
symbol->GetLibId().GetLibNickname().wx_str() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( libs->HasLibrary( symbol->GetLibId().GetLibNickname() ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tmp = libs->LoadSymbol( symbol->GetLibId() );
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "I/O error %s resolving library symbol %s" ), ioe.What(),
|
||||||
|
symbol->GetLibId().Format().wx_str() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !tmp && legacyLibs )
|
||||||
|
{
|
||||||
|
// If here, only the cache library should be loaded if the loaded schematic
|
||||||
|
// is the legacy file format.
|
||||||
|
wxCHECK2( legacyLibs->GetLibraryCount() == 1, continue );
|
||||||
|
|
||||||
|
PART_LIB& legacyCacheLib = legacyLibs->at( 0 );
|
||||||
|
|
||||||
|
// ...and it better be the cache library.
|
||||||
|
wxCHECK2( legacyCacheLib.IsCache(), continue );
|
||||||
|
|
||||||
|
wxString id = symbol->GetLibId().Format();
|
||||||
|
|
||||||
|
id.Replace( ':', '_' );
|
||||||
|
|
||||||
|
if( aReporter )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Falling back to cache to set symbol '%s:%s' link '%s'." ),
|
||||||
|
symbol->GetField( REFERENCE )->GetText(),
|
||||||
|
symbol->GetField( VALUE )->GetText(),
|
||||||
|
id );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_WARNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = legacyCacheLib.FindPart( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tmp )
|
||||||
|
{
|
||||||
|
// We want a full symbol not just the top level child symbol.
|
||||||
|
libSymbol = tmp->Flatten();
|
||||||
|
libSymbol->SetParent();
|
||||||
|
|
||||||
|
m_libSymbols.insert( { symbol->GetSchSymbolLibraryName(),
|
||||||
|
new LIB_PART( *libSymbol.get() ) } );
|
||||||
|
|
||||||
|
if( aReporter )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Setting schematic symbol '%s %s' library identifier to '%s'. " ),
|
||||||
|
symbol->GetField( REFERENCE )->GetText(),
|
||||||
|
symbol->GetField( VALUE )->GetText(),
|
||||||
|
symbol->GetLibId().Format().wx_str() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_INFO );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Resolving will update the pin caches but we must ensure that this happens
|
|
||||||
// even if the libraries don't change.
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( SCH_COMPONENT* cmp : cmps )
|
if( aReporter )
|
||||||
cmp->UpdatePins();
|
{
|
||||||
|
msg.Printf( _( "No library symbol found for schematic symbol '%s %s'. " ),
|
||||||
|
symbol->GetField( REFERENCE )->GetText(),
|
||||||
|
symbol->GetField( VALUE )->GetText() );
|
||||||
|
aReporter->ReportTail( msg, RPT_SEVERITY_ERROR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol->SetLibSymbol( libSymbol.release() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changing the symbol may adjust the bbox of the symbol. This re-inserts the
|
// Changing the symbol may adjust the bbox of the symbol. This re-inserts the
|
||||||
// item with the new bbox
|
// item with the new bbox
|
||||||
for( SCH_COMPONENT* cmp : cmps )
|
for( auto symbol : symbols )
|
||||||
Append( cmp );
|
Append( symbol );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREEN::UpdateLocalLibSymbolLinks()
|
||||||
|
{
|
||||||
|
for( auto item : Items().OfType( SCH_COMPONENT_T ) )
|
||||||
|
{
|
||||||
|
SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
|
||||||
|
|
||||||
|
auto it = m_libSymbols.find( symbol->GetSchSymbolLibraryName() );
|
||||||
|
|
||||||
|
LIB_PART* libSymbol = nullptr;
|
||||||
|
|
||||||
|
if( it != m_libSymbols.end() )
|
||||||
|
libSymbol = new LIB_PART( *it->second );
|
||||||
|
|
||||||
|
symbol->SetLibSymbol( libSymbol );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,6 +1152,24 @@ bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxStri
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREEN::AddLibSymbol( LIB_PART* aLibSymbol )
|
||||||
|
{
|
||||||
|
wxCHECK( aLibSymbol, /* void */ );
|
||||||
|
|
||||||
|
wxString libSymbolName = aLibSymbol->GetLibId().Format().wx_str();
|
||||||
|
|
||||||
|
auto it = m_libSymbols.find( libSymbolName );
|
||||||
|
|
||||||
|
if( it != m_libSymbols.end() )
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
m_libSymbols.erase( it );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_libSymbols[libSymbolName] = aLibSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
|
void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
|
||||||
{
|
{
|
||||||
m_aliases.insert( aAlias );
|
m_aliases.insert( aAlias );
|
||||||
|
@ -1185,10 +1423,10 @@ void SCH_SCREENS::DeleteAllMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREENS::UpdateSymbolLinks( bool aForce )
|
void SCH_SCREENS::UpdateSymbolLinks( REPORTER* aReporter )
|
||||||
{
|
{
|
||||||
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
||||||
screen->UpdateSymbolLinks( aForce );
|
screen->UpdateSymbolLinks( aReporter );
|
||||||
|
|
||||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -51,11 +51,13 @@
|
||||||
|
|
||||||
class BUS_ALIAS;
|
class BUS_ALIAS;
|
||||||
|
|
||||||
|
class LIB_PART;
|
||||||
class LIB_PIN;
|
class LIB_PIN;
|
||||||
class SCH_COMPONENT;
|
class SCH_COMPONENT;
|
||||||
class SCH_LINE;
|
class SCH_LINE;
|
||||||
class SCH_TEXT;
|
class SCH_TEXT;
|
||||||
class PLOTTER;
|
class PLOTTER;
|
||||||
|
class REPORTER;
|
||||||
class SCH_SHEET_LIST;
|
class SCH_SHEET_LIST;
|
||||||
|
|
||||||
enum SCH_LINE_TEST_T
|
enum SCH_LINE_TEST_T
|
||||||
|
@ -115,6 +117,11 @@ private:
|
||||||
/// List of bus aliases stored in this screen
|
/// List of bus aliases stored in this screen
|
||||||
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases;
|
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases;
|
||||||
|
|
||||||
|
/// Library symbols required for this schematic.
|
||||||
|
std::map<wxString, LIB_PART*> m_libSymbols;
|
||||||
|
|
||||||
|
void clearLibSymbols();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,19 +228,27 @@ public:
|
||||||
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
|
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize or reinitialize the weak reference to the #LIB_PART for each #SCH_COMPONENT
|
* Initialize the #LIB_PART reference for each #SCH_COMPONENT found in this schematic
|
||||||
* found in m_drawList.
|
* from the project #SYMBOL_LIB_TABLE.
|
||||||
*
|
*
|
||||||
* It must be called from:
|
* Symbol library links are set using the symbol library table and will fall back to
|
||||||
* - Draw function
|
* the cache only if the cache is loaded. The cache should only be loaded when opening
|
||||||
* - when loading a schematic file
|
* legacy schematic files.
|
||||||
* - before creating a netlist (in case a library is modified)
|
|
||||||
* - whenever a symbol library is modified
|
|
||||||
* - whenever the symbol library table is modified.
|
|
||||||
*
|
*
|
||||||
* @param aForce true forces a refresh even if the library modification has hasn't changed.
|
* @note This should only be called when the user specifically requests all library symbol
|
||||||
|
* links to be updated or when the legacy schematic is opened for the last time. All
|
||||||
|
* subsequent schematic loads with the new s-expression will contain the library
|
||||||
|
* symbols and should call #UpdateLocalLibSymbolLinks.
|
||||||
|
*
|
||||||
|
* @param aReporter Optional #REPORTER object to write status and error messages into.
|
||||||
*/
|
*/
|
||||||
void UpdateSymbolLinks( bool aForce = false );
|
void UpdateSymbolLinks( REPORTER* aReporter = nullptr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the #LIB_PART reference for each #SCH_COMPONENT found in this schematic
|
||||||
|
* with the local project library symbols
|
||||||
|
*/
|
||||||
|
void UpdateLocalLibSymbolLinks();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print all the items in the screen to \a aDC.
|
* Print all the items in the screen to \a aDC.
|
||||||
|
@ -449,6 +464,25 @@ public:
|
||||||
bool SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
|
bool SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxString& aReference,
|
||||||
const wxString& aFootPrint, bool aSetVisible );
|
const wxString& aFootPrint, bool aSetVisible );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a list of unique #LIB_PART object pointers required to properly render each
|
||||||
|
* #SCH_COMPONENT in this schematic.
|
||||||
|
*
|
||||||
|
* @return The list of unique #LIB_PART object pointers.
|
||||||
|
*/
|
||||||
|
std::map<wxString, LIB_PART*>& GetLibSymbols() { return m_libSymbols; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add \a aLibSymbol to the the library symbol map.
|
||||||
|
*
|
||||||
|
* The symbol is mapped to the result of #LIB_ID::Format(). If a symbol is already
|
||||||
|
* mapped, the existing symbol is replaced with \a aLibSymbol. The screen object takes
|
||||||
|
* ownership of the pointer.
|
||||||
|
*
|
||||||
|
* @param aLibSymbol A pointer the #LIB_PART to be added to the symbol map.
|
||||||
|
*/
|
||||||
|
void AddLibSymbol( LIB_PART* aLibSymbol );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a bus alias definition (and transfers ownership of the pointer)
|
* Adds a bus alias definition (and transfers ownership of the pointer)
|
||||||
*/
|
*/
|
||||||
|
@ -548,17 +582,17 @@ public:
|
||||||
void DeleteMarker( SCH_MARKER* aMarker );
|
void DeleteMarker( SCH_MARKER* aMarker );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize or reinitialize the weak reference to the #LIB_PART for each #SCH_COMPONENT
|
* Initialize the #LIB_PART reference for each #SCH_COMPONENT found in the full schematic.
|
||||||
* found in the full schematic.
|
|
||||||
*
|
*
|
||||||
* It must be called from:
|
* @note This should only be called when the user specifically requests all library symbol
|
||||||
* - draw functions
|
* links to be update or when the legacy schematic is opened for the last time. All
|
||||||
* - when loading a schematic file
|
* subsequent schematic loads with the new s-expression will contain the library
|
||||||
* - before creating a netlist (in case a library is modified)
|
* symbols.
|
||||||
* - whenever any of the libraries are modified.
|
*
|
||||||
* - whenever the symbol library table is modified.
|
* @param aReporter An optional #REPORTER object pointer to write warning and error
|
||||||
|
* messages into.
|
||||||
*/
|
*/
|
||||||
void UpdateSymbolLinks( bool aForce = false );
|
void UpdateSymbolLinks( REPORTER* aReporter = nullptr );
|
||||||
|
|
||||||
void TestDanglingEnds();
|
void TestDanglingEnds();
|
||||||
|
|
||||||
|
|
|
@ -106,15 +106,15 @@ void SCH_SEXPR_PARSER::ParseLib( LIB_PART_MAP& aSymbolLibMap )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap )
|
LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap, bool aIsSchematicLib )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( CurTok() == T_symbol, nullptr,
|
wxCHECK_MSG( CurTok() == T_symbol, nullptr,
|
||||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
|
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
|
||||||
|
|
||||||
T token;
|
T token;
|
||||||
long tmp;
|
long tmp;
|
||||||
wxString error;
|
|
||||||
wxString name;
|
wxString name;
|
||||||
|
wxString error;
|
||||||
LIB_ITEM* item;
|
LIB_ITEM* item;
|
||||||
std::unique_ptr<LIB_PART> symbol( new LIB_PART( wxEmptyString ) );
|
std::unique_ptr<LIB_PART> symbol( new LIB_PART( wxEmptyString ) );
|
||||||
|
|
||||||
|
@ -133,15 +133,18 @@ LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap )
|
||||||
|
|
||||||
name = FromUTF8();
|
name = FromUTF8();
|
||||||
|
|
||||||
if( name.IsEmpty() )
|
LIB_ID id;
|
||||||
|
|
||||||
|
if( id.Parse( name, LIB_ID::ID_SCH ) >= 0 )
|
||||||
{
|
{
|
||||||
error.Printf( _( "Empty symbol name in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
error.Printf( _( "Invalid library identifier in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
||||||
CurSource().c_str(), CurLineNumber(), CurOffset() );
|
CurSource().c_str(), CurLineNumber(), CurOffset() );
|
||||||
THROW_IO_ERROR( error );
|
THROW_IO_ERROR( error );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_symbolName = name;
|
m_symbolName = id.GetLibItemName().wx_str();
|
||||||
symbol->SetName( name );
|
symbol->SetName( m_symbolName );
|
||||||
|
symbol->SetLibId( id );
|
||||||
|
|
||||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||||
{
|
{
|
||||||
|
@ -152,6 +155,11 @@ LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap )
|
||||||
|
|
||||||
switch( token )
|
switch( token )
|
||||||
{
|
{
|
||||||
|
case T_power:
|
||||||
|
symbol->SetPower();
|
||||||
|
NeedRIGHT();
|
||||||
|
break;
|
||||||
|
|
||||||
case T_pin_names:
|
case T_pin_names:
|
||||||
parsePinNames( symbol );
|
parsePinNames( symbol );
|
||||||
break;
|
break;
|
||||||
|
@ -215,7 +223,8 @@ LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap )
|
||||||
if( !name.StartsWith( m_symbolName ) )
|
if( !name.StartsWith( m_symbolName ) )
|
||||||
{
|
{
|
||||||
error.Printf(
|
error.Printf(
|
||||||
_( "Invalid symbol unit name prefix %s in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
_( "Invalid symbol unit name prefix %s in\nfile: \"%s\"\n"
|
||||||
|
"line: %d\noffset: %d" ),
|
||||||
name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
|
name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
|
||||||
THROW_IO_ERROR( error );
|
THROW_IO_ERROR( error );
|
||||||
}
|
}
|
||||||
|
@ -227,7 +236,8 @@ LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap )
|
||||||
if( tokenizer.CountTokens() != 2 )
|
if( tokenizer.CountTokens() != 2 )
|
||||||
{
|
{
|
||||||
error.Printf(
|
error.Printf(
|
||||||
_( "Invalid symbol unit name suffix %s in\nfile: \"%s\"\nline: %d\noffset: %d" ),
|
_( "Invalid symbol unit name suffix %s in\nfile: \"%s\"\n"
|
||||||
|
"line: %d\noffset: %d" ),
|
||||||
name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
|
name.c_str(), CurSource().c_str(), CurLineNumber(), CurOffset() );
|
||||||
THROW_IO_ERROR( error );
|
THROW_IO_ERROR( error );
|
||||||
}
|
}
|
||||||
|
@ -1615,7 +1625,7 @@ void SCH_SEXPR_PARSER::parseTITLE_BLOCK( TITLE_BLOCK& aTitleBlock )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_FIELD* SCH_SEXPR_PARSER::parseSchField()
|
SCH_FIELD* SCH_SEXPR_PARSER::parseSchField( SCH_COMPONENT* aParentSymbol )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( CurTok() == T_property, nullptr,
|
wxCHECK_MSG( CurTok() == T_property, nullptr,
|
||||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
|
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
|
||||||
|
@ -1656,7 +1666,7 @@ SCH_FIELD* SCH_SEXPR_PARSER::parseSchField()
|
||||||
value = FromUTF8();
|
value = FromUTF8();
|
||||||
|
|
||||||
std::unique_ptr<SCH_FIELD> field( new SCH_FIELD( wxDefaultPosition, MANDATORY_FIELDS,
|
std::unique_ptr<SCH_FIELD> field( new SCH_FIELD( wxDefaultPosition, MANDATORY_FIELDS,
|
||||||
nullptr, name ) );
|
aParentSymbol, name ) );
|
||||||
|
|
||||||
field->SetText( value );
|
field->SetText( value );
|
||||||
field->SetVisible( true );
|
field->SetVisible( true );
|
||||||
|
@ -1882,6 +1892,32 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SCREEN* aScreen )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_lib_symbols:
|
||||||
|
{
|
||||||
|
// Dummy map. No derived symbols are allowed in the library cache.
|
||||||
|
LIB_PART_MAP symbolLibMap;
|
||||||
|
|
||||||
|
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||||
|
{
|
||||||
|
if( token != T_LEFT )
|
||||||
|
Expecting( T_LEFT );
|
||||||
|
|
||||||
|
token = NextTok();
|
||||||
|
|
||||||
|
switch( token )
|
||||||
|
{
|
||||||
|
case T_symbol:
|
||||||
|
aScreen->AddLibSymbol( ParseSymbol( symbolLibMap, true ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Expecting( "symbol" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case T_symbol:
|
case T_symbol:
|
||||||
aScreen->Append( static_cast<SCH_ITEM*>( parseSchematicSymbol() ) );
|
aScreen->Append( static_cast<SCH_ITEM*>( parseSchematicSymbol() ) );
|
||||||
break;
|
break;
|
||||||
|
@ -1924,6 +1960,8 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SCREEN* aScreen )
|
||||||
"bus, text, label, global_label, or hierarchical_label" );
|
"bus, text, label, global_label, or hierarchical_label" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aScreen->UpdateLocalLibSymbolLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1933,10 +1971,12 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
|
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
|
||||||
|
|
||||||
T token;
|
T token;
|
||||||
int orientation = CMP_ORIENT_0;
|
|
||||||
wxString tmp;
|
wxString tmp;
|
||||||
|
wxString error;
|
||||||
|
wxString libName;
|
||||||
SCH_FIELD* field;
|
SCH_FIELD* field;
|
||||||
std::unique_ptr<SCH_COMPONENT> symbol( new SCH_COMPONENT() );
|
std::unique_ptr<SCH_COMPONENT> symbol( new SCH_COMPONENT() );
|
||||||
|
TRANSFORM transform;
|
||||||
|
|
||||||
m_fieldId = MANDATORY_FIELDS;
|
m_fieldId = MANDATORY_FIELDS;
|
||||||
|
|
||||||
|
@ -1949,6 +1989,25 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
|
|
||||||
switch( token )
|
switch( token )
|
||||||
{
|
{
|
||||||
|
case T_lib_name:
|
||||||
|
{
|
||||||
|
LIB_ID libId;
|
||||||
|
|
||||||
|
token = NextTok();
|
||||||
|
|
||||||
|
if( !IsSymbol( token ) )
|
||||||
|
{
|
||||||
|
error.Printf( _( "Invalid symbol library name in\nfile: \"%s\"\n"
|
||||||
|
"line: %d\noffset: %d" ),
|
||||||
|
CurSource().c_str(), CurLineNumber(), CurOffset() );
|
||||||
|
THROW_IO_ERROR( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
libName = FromUTF8();
|
||||||
|
NeedRIGHT();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case T_lib_id:
|
case T_lib_id:
|
||||||
{
|
{
|
||||||
token = NextTok();
|
token = NextTok();
|
||||||
|
@ -1956,18 +2015,17 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
if( !IsSymbol( token ) && token != T_NUMBER )
|
if( !IsSymbol( token ) && token != T_NUMBER )
|
||||||
Expecting( "symbol|number" );
|
Expecting( "symbol|number" );
|
||||||
|
|
||||||
LIB_ID id;
|
LIB_ID libId;
|
||||||
wxString text = FromUTF8();
|
|
||||||
|
|
||||||
if( !text.IsEmpty() && id.Parse( text, LIB_ID::ID_SCH, true ) >= 0 )
|
if( libId.Parse( FromUTF8(), LIB_ID::ID_SCH ) >= 0 )
|
||||||
{
|
{
|
||||||
tmp.Printf( _( "Invalid symbol library ID in\nfile: \"%s\"\nline: %d\n"
|
error.Printf( _( "Invalid symbol library ID in\nfile: \"%s\"\nline: %d\n"
|
||||||
"offset: %d" ),
|
"offset: %d" ),
|
||||||
GetChars( CurSource() ), CurLineNumber(), CurOffset() );
|
GetChars( CurSource() ), CurLineNumber(), CurOffset() );
|
||||||
THROW_IO_ERROR( tmp );
|
THROW_IO_ERROR( error );
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol->SetLibId( id );
|
symbol->SetLibId( libId );
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1977,13 +2035,14 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
|
|
||||||
switch( static_cast<int>( parseDouble( "symbol orientation" ) ) )
|
switch( static_cast<int>( parseDouble( "symbol orientation" ) ) )
|
||||||
{
|
{
|
||||||
case 0: orientation = CMP_ORIENT_0; break;
|
case 0: transform = TRANSFORM(); break;
|
||||||
case 90: orientation = CMP_ORIENT_90; break;
|
case 90: transform = TRANSFORM( 0, -1, -1, 0 ); break;
|
||||||
case 180: orientation = CMP_ORIENT_180; break;
|
case 180: transform = TRANSFORM( -1, 0, 0, 1 ); break;
|
||||||
case 270: orientation = CMP_ORIENT_270; break;
|
case 270: transform = TRANSFORM( 0, 1, 1, 0 ); break;
|
||||||
default: Expecting( "0, 90, 180, or 270" );
|
default: Expecting( "0, 90, 180, or 270" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbol->SetTransform( transform );
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1991,9 +2050,9 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
token = NextTok();
|
token = NextTok();
|
||||||
|
|
||||||
if( token == T_x )
|
if( token == T_x )
|
||||||
orientation |= CMP_MIRROR_X;
|
symbol->SetOrientation( CMP_MIRROR_X );
|
||||||
else if( token == T_y )
|
else if( token == T_y )
|
||||||
orientation |= CMP_MIRROR_Y;
|
symbol->SetOrientation( CMP_MIRROR_Y );
|
||||||
else
|
else
|
||||||
Expecting( "x or y" );
|
Expecting( "x or y" );
|
||||||
|
|
||||||
|
@ -2013,8 +2072,9 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
|
|
||||||
case T_property:
|
case T_property:
|
||||||
{
|
{
|
||||||
field = parseSchField();
|
// The field parent symbol must be set and it's orientation must be set before
|
||||||
field->SetParent( symbol.get() );
|
// the field positions are set.
|
||||||
|
field = parseSchField( symbol.get() );
|
||||||
|
|
||||||
if( field->GetId() == REFERENCE )
|
if( field->GetId() == REFERENCE )
|
||||||
{
|
{
|
||||||
|
@ -2039,11 +2099,12 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Expecting( "lib_id, at, mirror, uuid, property, or instances" );
|
Expecting( "lib_id, lib_name, at, mirror, uuid, property, or instances" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol->SetOrientation( orientation );
|
if( !libName.IsEmpty() && ( symbol->GetLibId().Format().wx_str() != libName ) )
|
||||||
|
symbol->SetSchSymbolLibraryName( libName );
|
||||||
|
|
||||||
return symbol.release();
|
return symbol.release();
|
||||||
}
|
}
|
||||||
|
@ -2167,7 +2228,7 @@ SCH_SHEET* SCH_SEXPR_PARSER::parseSheet()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_property:
|
case T_property:
|
||||||
field = parseSchField();
|
field = parseSchField( nullptr );
|
||||||
|
|
||||||
if( field->GetName() == "ki_sheet_name" )
|
if( field->GetName() == "ki_sheet_name" )
|
||||||
{
|
{
|
||||||
|
|
|
@ -206,7 +206,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
|
||||||
void parseSchSymbolInstances( std::unique_ptr<SCH_COMPONENT>& aSymbol );
|
void parseSchSymbolInstances( std::unique_ptr<SCH_COMPONENT>& aSymbol );
|
||||||
|
|
||||||
SCH_SHEET_PIN* parseSchSheetPin( SCH_SHEET* aSheet );
|
SCH_SHEET_PIN* parseSchSheetPin( SCH_SHEET* aSheet );
|
||||||
SCH_FIELD* parseSchField();
|
SCH_FIELD* parseSchField( SCH_COMPONENT* aParentSymbol );
|
||||||
SCH_COMPONENT* parseSchematicSymbol();
|
SCH_COMPONENT* parseSchematicSymbol();
|
||||||
SCH_BITMAP* parseImage();
|
SCH_BITMAP* parseImage();
|
||||||
SCH_SHEET* parseSheet();
|
SCH_SHEET* parseSheet();
|
||||||
|
@ -221,7 +221,7 @@ public:
|
||||||
|
|
||||||
void ParseLib( LIB_PART_MAP& aSymbolLibMap );
|
void ParseLib( LIB_PART_MAP& aSymbolLibMap );
|
||||||
|
|
||||||
LIB_PART* ParseSymbol( LIB_PART_MAP& aSymbolLibMap );
|
LIB_PART* ParseSymbol( LIB_PART_MAP& aSymbolLibMap, bool aIsSchematicLib = false );
|
||||||
|
|
||||||
LIB_ITEM* ParseDrawItem();
|
LIB_ITEM* ParseDrawItem();
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,7 @@ public:
|
||||||
static LIB_PART* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion,
|
static LIB_PART* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion,
|
||||||
LIB_PART_MAP* aMap = nullptr );
|
LIB_PART_MAP* aMap = nullptr );
|
||||||
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
||||||
int aNestLevel = 0, LIB_PART_MAP* aMap = nullptr );
|
int aNestLevel = 0, const wxString& aLibName = wxEmptyString );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,12 +604,18 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SCREEN* aScreen )
|
||||||
SEXPR_SCHEMATIC_FILE_VERSION,
|
SEXPR_SCHEMATIC_FILE_VERSION,
|
||||||
m_out->Quotew( GetBuildVersion() ).c_str() );
|
m_out->Quotew( GetBuildVersion() ).c_str() );
|
||||||
|
|
||||||
// @todo save cache library here.
|
|
||||||
|
|
||||||
aScreen->GetPageSettings().Format( m_out, 1, 0 );
|
aScreen->GetPageSettings().Format( m_out, 1, 0 );
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
aScreen->GetTitleBlock().Format( m_out, 1, 0 );
|
aScreen->GetTitleBlock().Format( m_out, 1, 0 );
|
||||||
|
|
||||||
|
// Save cache library.
|
||||||
|
m_out->Print( 1, "(lib_symbols\n" );
|
||||||
|
|
||||||
|
for( auto libSymbol : aScreen->GetLibSymbols() )
|
||||||
|
SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( libSymbol.second, *m_out, 2, libSymbol.first );
|
||||||
|
|
||||||
|
m_out->Print( 1, ")\n\n" );
|
||||||
|
|
||||||
// @todo save schematic instance information (page #).
|
// @todo save schematic instance information (page #).
|
||||||
|
|
||||||
for( const auto& alias : aScreen->GetBusAliases() )
|
for( const auto& alias : aScreen->GetBusAliases() )
|
||||||
|
@ -786,8 +792,14 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_COMPONENT* aSymbol, int aNestLevel )
|
||||||
else
|
else
|
||||||
angle = 0.0;
|
angle = 0.0;
|
||||||
|
|
||||||
m_out->Print( aNestLevel, "(symbol (lib_id %s) (at %s %s %s)",
|
m_out->Print( aNestLevel, "(symbol" );
|
||||||
m_out->Quotew( libName ).c_str(),
|
|
||||||
|
if( !aSymbol->UseLibIdLookup() )
|
||||||
|
m_out->Print( 0, " (lib_name %s)",
|
||||||
|
m_out->Quotew( aSymbol->GetSchSymbolLibraryName() ).c_str() );
|
||||||
|
|
||||||
|
m_out->Print( 0, " (lib_id %s) (at %s %s %s)",
|
||||||
|
m_out->Quotew( aSymbol->GetLibId().Format().wx_str() ).c_str(),
|
||||||
FormatInternalUnits( aSymbol->GetPosition().x ).c_str(),
|
FormatInternalUnits( aSymbol->GetPosition().x ).c_str(),
|
||||||
FormatInternalUnits( aSymbol->GetPosition().y ).c_str(),
|
FormatInternalUnits( aSymbol->GetPosition().y ).c_str(),
|
||||||
FormatAngle( angle * 10.0 ).c_str() );
|
FormatAngle( angle * 10.0 ).c_str() );
|
||||||
|
@ -875,13 +887,14 @@ void SCH_SEXPR_PLUGIN::saveField( SCH_FIELD* aField, int aNestLevel )
|
||||||
// For some reason (bug in legacy parser?) the field ID for non-mandatory fields is -1 so
|
// For some reason (bug in legacy parser?) the field ID for non-mandatory fields is -1 so
|
||||||
// check for this in order to correctly use the field name.
|
// check for this in order to correctly use the field name.
|
||||||
if( aField->GetId() >= 0 && aField->GetId() < MANDATORY_FIELDS )
|
if( aField->GetId() >= 0 && aField->GetId() < MANDATORY_FIELDS )
|
||||||
fieldName = "ki_" + TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId() ).Lower();
|
fieldName = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId() );
|
||||||
else
|
else
|
||||||
fieldName = aField->GetName();
|
fieldName = aField->GetName();
|
||||||
|
|
||||||
m_out->Print( aNestLevel, "(property %s %s (at %s %s %s)",
|
m_out->Print( aNestLevel, "(property %s %s (id %d) (at %s %s %s)",
|
||||||
m_out->Quotew( fieldName ).c_str(),
|
m_out->Quotew( fieldName ).c_str(),
|
||||||
m_out->Quotew( aField->GetText() ).c_str(),
|
m_out->Quotew( aField->GetText() ).c_str(),
|
||||||
|
aField->GetId(),
|
||||||
FormatInternalUnits( aField->GetPosition().x ).c_str(),
|
FormatInternalUnits( aField->GetPosition().x ).c_str(),
|
||||||
FormatInternalUnits( aField->GetPosition().y ).c_str(),
|
FormatInternalUnits( aField->GetPosition().y ).c_str(),
|
||||||
FormatAngle( aField->GetTextAngleDegrees() * 10.0 ).c_str() );
|
FormatAngle( aField->GetTextAngleDegrees() * 10.0 ).c_str() );
|
||||||
|
@ -1130,7 +1143,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
|
||||||
|| ( aText->GetTextHeight() != Mils2iu( DEFAULT_SIZE_TEXT ) ) )
|
|| ( aText->GetTextHeight() != Mils2iu( DEFAULT_SIZE_TEXT ) ) )
|
||||||
{
|
{
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
aText->Format( m_out, aNestLevel + 1, 0 );
|
aText->Format( m_out, aNestLevel, 0 );
|
||||||
m_out->Print( aNestLevel, ")\n" ); // Closes text token with font effects.
|
m_out->Print( aNestLevel, ")\n" ); // Closes text token with font effects.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1394,17 +1407,30 @@ void SCH_SEXPR_PLUGIN_CACHE::Save()
|
||||||
|
|
||||||
|
|
||||||
void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
||||||
int aNestLevel, LIB_PART_MAP* aMap )
|
int aNestLevel, const wxString& aLibName )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( aSymbol, "Invalid LIB_PART pointer." );
|
wxCHECK_RET( aSymbol, "Invalid LIB_PART pointer." );
|
||||||
|
|
||||||
|
std::string name = aFormatter.Quotew( aSymbol->GetLibId().Format().wx_str() );
|
||||||
|
std::string unitName = aSymbol->GetLibId().GetLibItemName();
|
||||||
|
|
||||||
|
if( !aLibName.IsEmpty() )
|
||||||
|
{
|
||||||
|
name = aFormatter.Quotew( aLibName );
|
||||||
|
|
||||||
|
LIB_ID unitId;
|
||||||
|
|
||||||
|
wxCHECK2( unitId.Parse( aLibName, LIB_ID::ID_SCH ) < 0, /* do nothing */ );
|
||||||
|
|
||||||
|
unitName = unitId.GetLibItemName();
|
||||||
|
}
|
||||||
|
|
||||||
if( aSymbol->IsRoot() )
|
if( aSymbol->IsRoot() )
|
||||||
{
|
{
|
||||||
aFormatter.Print( aNestLevel, "(symbol %s",
|
aFormatter.Print( aNestLevel, "(symbol %s", name.c_str() );
|
||||||
aFormatter.Quotew( aSymbol->GetName() ).c_str() );
|
|
||||||
|
|
||||||
if( aSymbol->IsPower() )
|
if( aSymbol->IsPower() )
|
||||||
aFormatter.Print( 0, " power" );
|
aFormatter.Print( 0, " (power)" );
|
||||||
|
|
||||||
// TODO: add uuid token here.
|
// TODO: add uuid token here.
|
||||||
|
|
||||||
|
@ -1461,8 +1487,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
|
||||||
for( auto unit : units )
|
for( auto unit : units )
|
||||||
{
|
{
|
||||||
aFormatter.Print( aNestLevel + 1, "(symbol \"%s_%d_%d\"\n",
|
aFormatter.Print( aNestLevel + 1, "(symbol \"%s_%d_%d\"\n",
|
||||||
TO_UTF8( aSymbol->GetName() ),
|
unitName.c_str(), unit.m_unit, unit.m_convert );
|
||||||
unit.m_unit, unit.m_convert );
|
|
||||||
|
|
||||||
for( auto item : unit.m_items )
|
for( auto item : unit.m_items )
|
||||||
saveSymbolDrawItem( item, aFormatter, aNestLevel + 2 );
|
saveSymbolDrawItem( item, aFormatter, aNestLevel + 2 );
|
||||||
|
@ -1477,7 +1502,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
|
||||||
wxASSERT( parent );
|
wxASSERT( parent );
|
||||||
|
|
||||||
aFormatter.Print( aNestLevel, "(symbol %s (extends %s)\n",
|
aFormatter.Print( aNestLevel, "(symbol %s (extends %s)\n",
|
||||||
aFormatter.Quotew( aSymbol->GetName() ).c_str(),
|
name.c_str(),
|
||||||
aFormatter.Quotew( parent->GetName() ).c_str() );
|
aFormatter.Quotew( parent->GetName() ).c_str() );
|
||||||
|
|
||||||
LIB_FIELD tmp = parent->GetValueField();
|
LIB_FIELD tmp = parent->GetValueField();
|
||||||
|
|
|
@ -51,6 +51,8 @@ label
|
||||||
left
|
left
|
||||||
length
|
length
|
||||||
lib_id
|
lib_id
|
||||||
|
lib_name
|
||||||
|
lib_symbols
|
||||||
line
|
line
|
||||||
mid
|
mid
|
||||||
mirror
|
mirror
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2004-2020 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -111,7 +111,8 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||||
wxFileName currentSheetFileName;
|
wxFileName currentSheetFileName;
|
||||||
bool libTableChanged = false;
|
bool libTableChanged = false;
|
||||||
SCH_SCREEN* currentScreen = aHierarchy->LastScreen();
|
SCH_SCREEN* currentScreen = aHierarchy->LastScreen();
|
||||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( aFileName );
|
||||||
|
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( schFileType ) );
|
||||||
std::unique_ptr< SCH_SHEET> newSheet( new SCH_SHEET );
|
std::unique_ptr< SCH_SHEET> newSheet( new SCH_SHEET );
|
||||||
|
|
||||||
wxFileName fileName( aFileName );
|
wxFileName fileName( aFileName );
|
||||||
|
@ -469,9 +470,6 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||||
SCH_SCREENS allScreens;
|
SCH_SCREENS allScreens;
|
||||||
allScreens.ReplaceDuplicateTimeStamps();
|
allScreens.ReplaceDuplicateTimeStamps();
|
||||||
|
|
||||||
SCH_SCREENS screens( aSheet );
|
|
||||||
screens.UpdateSymbolLinks( true );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -440,10 +440,9 @@ int LIB_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_COMPONENT* comp = new SCH_COMPONENT( *part, libId, g_CurrentSheet, unit, convert );
|
wxCHECK( part->GetLibId().IsValid(), 0 );
|
||||||
|
|
||||||
// Be sure the link to the corresponding LIB_PART is OK:
|
SCH_COMPONENT* comp = new SCH_COMPONENT( *part, libId, g_CurrentSheet, unit, convert );
|
||||||
comp->Resolve( *m_frame->Prj().SchSymbolLibTable() );
|
|
||||||
|
|
||||||
if( schframe->eeconfig()->m_AutoplaceFields.enable )
|
if( schframe->eeconfig()->m_AutoplaceFields.enable )
|
||||||
comp->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
|
comp->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -174,9 +174,6 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
|
||||||
component = new SCH_COMPONENT( *part, g_CurrentSheet, sel, (wxPoint) cursorPos );
|
component = new SCH_COMPONENT( *part, g_CurrentSheet, sel, (wxPoint) cursorPos );
|
||||||
component->SetFlags( IS_NEW | IS_MOVED );
|
component->SetFlags( IS_NEW | IS_MOVED );
|
||||||
|
|
||||||
// Be sure the link to the corresponding LIB_PART is OK:
|
|
||||||
component->Resolve( *m_frame->Prj().SchSymbolLibTable() );
|
|
||||||
|
|
||||||
if( m_frame->eeconfig()->m_AutoplaceFields.enable )
|
if( m_frame->eeconfig()->m_AutoplaceFields.enable )
|
||||||
component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
|
component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -1174,9 +1174,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
paste_screen.Clear( false );
|
paste_screen.Clear( false );
|
||||||
|
|
||||||
// Now we can resolve the components and add everything to the screen, view, etc.
|
// Now we can resolve the components and add everything to the screen, view, etc.
|
||||||
//
|
|
||||||
SYMBOL_LIB_TABLE* symLibTable = m_frame->Prj().SchSymbolLibTable();
|
SYMBOL_LIB_TABLE* symLibTable = m_frame->Prj().SchSymbolLibTable();
|
||||||
PART_LIB* partLib = m_frame->Prj().SchLibs()->GetCacheLibrary();
|
|
||||||
|
|
||||||
for( unsigned i = 0; i < loadedItems.size(); ++i )
|
for( unsigned i = 0; i < loadedItems.size(); ++i )
|
||||||
{
|
{
|
||||||
|
@ -1196,8 +1194,19 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
component->SetUnit( unit );
|
component->SetUnit( unit );
|
||||||
}
|
}
|
||||||
|
|
||||||
component->Resolve( *symLibTable, partLib );
|
LIB_PART* libSymbol = symLibTable->LoadSymbol( component->GetLibId() );
|
||||||
component->UpdatePins();
|
|
||||||
|
if( libSymbol )
|
||||||
|
{
|
||||||
|
component->SetLibSymbol( libSymbol );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayError( m_frame,
|
||||||
|
wxString::Format( _( "Symbol '%s' not found in library '%s'." ),
|
||||||
|
component->GetLibId().GetLibItemName().wx_str(),
|
||||||
|
component->GetLibId().GetLibNickname().wx_str() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,6 +225,15 @@ const wxString KICAD_MANAGER_FRAME::SchFileName()
|
||||||
{
|
{
|
||||||
wxFileName fn( GetProjectFileName() );
|
wxFileName fn( GetProjectFileName() );
|
||||||
|
|
||||||
|
fn.SetExt( KiCadSchematicFileExtension );
|
||||||
|
return fn.GetFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wxString KICAD_MANAGER_FRAME::SchLegacyFileName()
|
||||||
|
{
|
||||||
|
wxFileName fn( GetProjectFileName() );
|
||||||
|
|
||||||
fn.SetExt( LegacySchematicFileExtension );
|
fn.SetExt( LegacySchematicFileExtension );
|
||||||
return fn.GetFullPath();
|
return fn.GetFullPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN (www.cern.ch)
|
* Copyright (C) 2013 CERN (www.cern.ch)
|
||||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -156,6 +156,7 @@ public:
|
||||||
|
|
||||||
// read only accessors
|
// read only accessors
|
||||||
const wxString SchFileName();
|
const wxString SchFileName();
|
||||||
|
const wxString SchLegacyFileName();
|
||||||
const wxString PcbFileName();
|
const wxString PcbFileName();
|
||||||
const wxString PcbLegacyFileName();
|
const wxString PcbLegacyFileName();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
@ -612,7 +612,13 @@ int KICAD_MANAGER_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( playerType == FRAME_SCH )
|
if( playerType == FRAME_SCH )
|
||||||
{
|
{
|
||||||
filepath = m_frame->SchFileName();
|
wxFileName kicad_schematic( m_frame->SchFileName() );
|
||||||
|
wxFileName legacy_schematic( m_frame->SchLegacyFileName() );
|
||||||
|
|
||||||
|
if( !legacy_schematic.FileExists() || kicad_schematic.FileExists() )
|
||||||
|
filepath = kicad_schematic.GetFullPath();
|
||||||
|
else
|
||||||
|
filepath = legacy_schematic.GetFullPath();
|
||||||
}
|
}
|
||||||
else if( playerType == FRAME_PCB_EDITOR )
|
else if( playerType == FRAME_PCB_EDITOR )
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@ set( QA_EESCHEMA_SRCS
|
||||||
test_sch_rtree.cpp
|
test_sch_rtree.cpp
|
||||||
test_sch_sheet.cpp
|
test_sch_sheet.cpp
|
||||||
test_sch_sheet_path.cpp
|
test_sch_sheet_path.cpp
|
||||||
|
test_sch_symbol.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 KiCad Developers, see CHANGELOG.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 Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Test suite for SCH_COMPONENT object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unit_test_utils/unit_test_utils.h>
|
||||||
|
|
||||||
|
// Code under test
|
||||||
|
#include <sch_component.h>
|
||||||
|
|
||||||
|
#include <sch_edit_frame.h>
|
||||||
|
|
||||||
|
class TEST_SCH_SYMBOL_FIXTURE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TEST_SCH_SYMBOL_FIXTURE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///> #SCH_COMPONENT object with no extra data set.
|
||||||
|
SCH_COMPONENT m_symbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare the test suite
|
||||||
|
*/
|
||||||
|
BOOST_FIXTURE_TEST_SUITE( SchSymbol, TEST_SCH_SYMBOL_FIXTURE )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that we can get the default properties as expected.
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( DefaultProperties )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the orientation tranform changes.
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Orientation )
|
||||||
|
{
|
||||||
|
TRANSFORM t = m_symbol.GetTransform();
|
||||||
|
|
||||||
|
wxLogDebug( "Angle 0: x1 = %d, y1 = %d, x2 = %d, y2 = %d", t.x1, t.y1, t.x2, t.y2 );
|
||||||
|
m_symbol.SetOrientation( CMP_ORIENT_90 );
|
||||||
|
t = m_symbol.GetTransform();
|
||||||
|
wxLogDebug( "Angle 90: x1 = %d, y1 = %d, x2 = %d, y2 = %d", t.x1, t.y1, t.x2, t.y2 );
|
||||||
|
m_symbol.SetTransform( TRANSFORM() );
|
||||||
|
m_symbol.SetOrientation( CMP_ORIENT_180 );
|
||||||
|
t = m_symbol.GetTransform();
|
||||||
|
wxLogDebug( "Angle 180: x1 = %d, y1 = %d, x2 = %d, y2 = %d", t.x1, t.y1, t.x2, t.y2 );
|
||||||
|
m_symbol.SetTransform( TRANSFORM() );
|
||||||
|
m_symbol.SetOrientation( CMP_ORIENT_270 );
|
||||||
|
t = m_symbol.GetTransform();
|
||||||
|
wxLogDebug( "Angle 270: x1 = %d, y1 = %d, x2 = %d, y2 = %d", t.x1, t.y1, t.x2, t.y2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue