Eeschema: fix copy and paste bug.
Add required library symbols to new file formatter and parser when copying schematic symbols to prevent missing library symbol when pasting into a different schematic which may not have the same library symbol available. Fix a minor bug where the default schematic symbol reference was not set by the parser when loading. Fixes https://gitlab.com/kicad/code/kicad/issues/4442
This commit is contained in:
parent
733c553606
commit
980aefea4b
|
@ -1937,9 +1937,6 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly,
|
||||||
|
|
||||||
case T_lib_symbols:
|
case T_lib_symbols:
|
||||||
{
|
{
|
||||||
if( aIsCopyableOnly )
|
|
||||||
Unexpected( T_lib_symbols );
|
|
||||||
|
|
||||||
// Dummy map. No derived symbols are allowed in the library cache.
|
// Dummy map. No derived symbols are allowed in the library cache.
|
||||||
LIB_PART_MAP symbolLibMap;
|
LIB_PART_MAP symbolLibMap;
|
||||||
|
|
||||||
|
@ -2032,7 +2029,6 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !aIsCopyableOnly )
|
|
||||||
screen->UpdateLocalLibSymbolLinks();
|
screen->UpdateLocalLibSymbolLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2153,6 +2149,33 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
|
||||||
// the field positions are set.
|
// the field positions are set.
|
||||||
field = parseSchField( symbol.get() );
|
field = parseSchField( symbol.get() );
|
||||||
|
|
||||||
|
// Set the default symbol reference prefix.
|
||||||
|
if( field->GetId() == REFERENCE )
|
||||||
|
{
|
||||||
|
wxString refDesignator = field->GetText();
|
||||||
|
|
||||||
|
refDesignator.Replace( "~", " " );
|
||||||
|
|
||||||
|
wxString prefix = refDesignator;
|
||||||
|
|
||||||
|
while( prefix.Length() )
|
||||||
|
{
|
||||||
|
if( ( prefix.Last() < '0' || prefix.Last() > '9') && prefix.Last() != '?' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
prefix.RemoveLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid a prefix containing trailing/leading spaces
|
||||||
|
prefix.Trim( true );
|
||||||
|
prefix.Trim( false );
|
||||||
|
|
||||||
|
if( prefix.IsEmpty() )
|
||||||
|
symbol->SetPrefix( wxString( "U" ) );
|
||||||
|
else
|
||||||
|
symbol->SetPrefix( prefix );
|
||||||
|
}
|
||||||
|
|
||||||
if( symbol->GetField( field->GetId() ) )
|
if( symbol->GetField( field->GetId() ) )
|
||||||
*symbol->GetField( field->GetId() ) = *field;
|
*symbol->GetField( field->GetId() ) = *field;
|
||||||
else
|
else
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
#include <sch_sexpr_parser.h>
|
#include <sch_sexpr_parser.h>
|
||||||
#include <symbol_lib_table.h> // for PropPowerSymsOnly definintion.
|
#include <symbol_lib_table.h> // for PropPowerSymsOnly definintion.
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <tool/selection.h>
|
#include <ee_selection.h>
|
||||||
#include <default_values.h> // For some default values
|
#include <default_values.h> // For some default values
|
||||||
|
|
||||||
|
|
||||||
|
@ -771,13 +771,54 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SEXPR_PLUGIN::Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatter )
|
void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, OUTPUTFORMATTER* aFormatter )
|
||||||
{
|
{
|
||||||
|
wxCHECK( aSelection && aFormatter, /* void */ );
|
||||||
|
|
||||||
m_out = aFormatter;
|
m_out = aFormatter;
|
||||||
|
|
||||||
for( unsigned i = 0; i < aSelection->GetSize(); ++i )
|
size_t i;
|
||||||
|
SCH_ITEM* item;
|
||||||
|
std::map<wxString, LIB_PART*> libSymbols;
|
||||||
|
SCH_SCREEN* screen = aSelection->GetScreen();
|
||||||
|
|
||||||
|
for( i = 0; i < aSelection->GetSize(); ++i )
|
||||||
{
|
{
|
||||||
SCH_ITEM* item = (SCH_ITEM*) aSelection->GetItem( i );
|
item = dynamic_cast<SCH_ITEM*>( aSelection->GetItem( i ) );
|
||||||
|
|
||||||
|
wxCHECK2( item, continue );
|
||||||
|
|
||||||
|
if( item->Type() != SCH_COMPONENT_T )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SCH_COMPONENT* symbol = dynamic_cast<SCH_COMPONENT*>( item );
|
||||||
|
|
||||||
|
wxCHECK2( symbol, continue );
|
||||||
|
|
||||||
|
wxString libSymbolLookup = symbol->GetLibId().Format().wx_str();
|
||||||
|
|
||||||
|
if( !symbol->UseLibIdLookup() )
|
||||||
|
libSymbolLookup = symbol->GetSchSymbolLibraryName();
|
||||||
|
|
||||||
|
auto it = screen->GetLibSymbols().find( libSymbolLookup );
|
||||||
|
|
||||||
|
if( it != screen->GetLibSymbols().end() )
|
||||||
|
libSymbols[ libSymbolLookup ] = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !libSymbols.empty() )
|
||||||
|
{
|
||||||
|
m_out->Print( 0, "(lib_symbols\n" );
|
||||||
|
|
||||||
|
for( auto libSymbol : libSymbols )
|
||||||
|
SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( libSymbol.second, *m_out, 1, libSymbol.first );
|
||||||
|
|
||||||
|
m_out->Print( 0, ")\n\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i = 0; i < aSelection->GetSize(); ++i )
|
||||||
|
{
|
||||||
|
item = (SCH_ITEM*) aSelection->GetItem( i );
|
||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ class SCH_TEXT;
|
||||||
class SCH_COMPONENT;
|
class SCH_COMPONENT;
|
||||||
class SCH_FIELD;
|
class SCH_FIELD;
|
||||||
class PROPERTIES;
|
class PROPERTIES;
|
||||||
class SELECTION;
|
class EE_SELECTION;
|
||||||
class SCH_SEXPR_PLUGIN_CACHE;
|
class SCH_SEXPR_PLUGIN_CACHE;
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class PART_LIB;
|
class PART_LIB;
|
||||||
|
@ -96,7 +96,7 @@ public:
|
||||||
|
|
||||||
void Format( SCH_SHEET* aSheet );
|
void Format( SCH_SHEET* aSheet );
|
||||||
|
|
||||||
void Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatter );
|
void Format( EE_SELECTION* aSelection, OUTPUTFORMATTER* aFormatter );
|
||||||
|
|
||||||
void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
|
||||||
const wxString& aLibraryPath,
|
const wxString& aLibraryPath,
|
||||||
|
|
|
@ -25,6 +25,13 @@
|
||||||
#include <tools/ee_selection.h>
|
#include <tools/ee_selection.h>
|
||||||
|
|
||||||
|
|
||||||
|
EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) :
|
||||||
|
SELECTION()
|
||||||
|
{
|
||||||
|
m_screen = aScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
|
EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
|
||||||
{
|
{
|
||||||
EDA_ITEM* topLeftItem = nullptr;
|
EDA_ITEM* topLeftItem = nullptr;
|
||||||
|
|
|
@ -25,13 +25,26 @@
|
||||||
#ifndef EE_SELECTION_H
|
#ifndef EE_SELECTION_H
|
||||||
#define EE_SELECTION_H
|
#define EE_SELECTION_H
|
||||||
|
|
||||||
|
class SCH_SCREEN;
|
||||||
|
|
||||||
|
|
||||||
#include <tool/selection.h>
|
#include <tool/selection.h>
|
||||||
|
|
||||||
|
|
||||||
class EE_SELECTION : public SELECTION
|
class EE_SELECTION : public SELECTION
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Screen of selected objects. Used to fetch library symbols for copy.
|
||||||
|
*/
|
||||||
|
SCH_SCREEN* m_screen;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
EE_SELECTION( SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override;
|
EDA_ITEM* GetTopLeftItem( bool onlyModules = false ) const override;
|
||||||
|
|
||||||
|
void SetScreen( SCH_SCREEN* aScreen ) { m_screen = aScreen; }
|
||||||
|
SCH_SCREEN* GetScreen() { return m_screen; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EE_SELECTION_H
|
#endif // EE_SELECTION_H
|
|
@ -1094,6 +1094,7 @@ bool SCH_EDITOR_CONTROL::doCopy()
|
||||||
if( !selection.GetSize() )
|
if( !selection.GetSize() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
selection.SetScreen( m_frame->GetScreen() );
|
||||||
m_supplementaryClipboard.clear();
|
m_supplementaryClipboard.clear();
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
|
|
Loading…
Reference in New Issue