Use new file formats for copy and paste in schematic and symbol editors.
This commit is contained in:
parent
3a9746c657
commit
ad88874adf
|
@ -48,7 +48,6 @@
|
|||
#include <sch_component.h>
|
||||
#include <sch_edit_frame.h> // CMP_ORIENT_XXX
|
||||
#include <sch_field.h>
|
||||
#include <sch_file_versions.h>
|
||||
#include <sch_line.h>
|
||||
#include <sch_junction.h>
|
||||
#include <sch_no_connect.h>
|
||||
|
@ -95,7 +94,7 @@ void SCH_SEXPR_PARSER::ParseLib( LIB_PART_MAP& aSymbolLibMap )
|
|||
{
|
||||
m_unit = 1;
|
||||
m_convert = 1;
|
||||
LIB_PART* symbol = ParseSymbol( aSymbolLibMap );
|
||||
LIB_PART* symbol = ParseSymbol( aSymbolLibMap, m_requiredVersion );
|
||||
aSymbolLibMap[symbol->GetName()] = symbol;
|
||||
}
|
||||
else
|
||||
|
@ -106,7 +105,7 @@ void SCH_SEXPR_PARSER::ParseLib( LIB_PART_MAP& aSymbolLibMap )
|
|||
}
|
||||
|
||||
|
||||
LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap, bool aIsSchematicLib )
|
||||
LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap, int aFileVersion )
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_symbol, nullptr,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a symbol." ) );
|
||||
|
@ -118,6 +117,7 @@ LIB_PART* SCH_SEXPR_PARSER::ParseSymbol( LIB_PART_MAP& aSymbolLibMap, bool aIsSc
|
|||
LIB_ITEM* item;
|
||||
std::unique_ptr<LIB_PART> symbol( new LIB_PART( wxEmptyString ) );
|
||||
|
||||
m_requiredVersion = aFileVersion;
|
||||
symbol->SetUnitCount( 1 );
|
||||
|
||||
m_fieldId = MANDATORY_FIELDS;
|
||||
|
@ -1861,7 +1861,7 @@ void SCH_SEXPR_PARSER::parseSchSymbolInstances( SCH_SCREEN* aScreen )
|
|||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
||||
void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly, int aFileVersion )
|
||||
{
|
||||
wxCHECK( aSheet != nullptr, /* void */ );
|
||||
|
||||
|
@ -1869,30 +1869,42 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
|
||||
wxCHECK( screen != nullptr, /* void */ );
|
||||
|
||||
if( aIsCopyableOnly )
|
||||
m_requiredVersion = aFileVersion;
|
||||
|
||||
T token;
|
||||
|
||||
NeedLEFT();
|
||||
NextTok();
|
||||
if( !aIsCopyableOnly )
|
||||
{
|
||||
NeedLEFT();
|
||||
NextTok();
|
||||
|
||||
if( CurTok() != T_kicad_sch )
|
||||
Expecting( "kicad_sch" );
|
||||
if( CurTok() != T_kicad_sch )
|
||||
Expecting( "kicad_sch" );
|
||||
|
||||
parseHeader( T_kicad_sch, SEXPR_SCHEMATIC_FILE_VERSION );
|
||||
parseHeader( T_kicad_sch, SEXPR_SCHEMATIC_FILE_VERSION );
|
||||
}
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( aIsCopyableOnly && token == T_EOF )
|
||||
break;
|
||||
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
if( token == T_page && m_requiredVersion <= 20200506 )
|
||||
if( !aIsCopyableOnly && token == T_page && m_requiredVersion <= 20200506 )
|
||||
token = T_paper;
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_paper:
|
||||
{
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_paper );
|
||||
|
||||
PAGE_INFO pageInfo;
|
||||
parsePAGE_INFO( pageInfo );
|
||||
screen->SetPageSettings( pageInfo );
|
||||
|
@ -1901,6 +1913,9 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
|
||||
case T_page:
|
||||
{
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_page );
|
||||
|
||||
// Only saved for top-level sniffing in Kicad Manager frame and other external
|
||||
// tool usage with flat hierarchies
|
||||
NeedSYMBOLorNUMBER();
|
||||
|
@ -1911,6 +1926,9 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
|
||||
case T_title_block:
|
||||
{
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_title_block );
|
||||
|
||||
TITLE_BLOCK tb;
|
||||
parseTITLE_BLOCK( tb );
|
||||
screen->SetTitleBlock( tb );
|
||||
|
@ -1919,6 +1937,9 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
|
||||
case T_lib_symbols:
|
||||
{
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_lib_symbols );
|
||||
|
||||
// Dummy map. No derived symbols are allowed in the library cache.
|
||||
LIB_PART_MAP symbolLibMap;
|
||||
|
||||
|
@ -1932,7 +1953,7 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
switch( token )
|
||||
{
|
||||
case T_symbol:
|
||||
screen->AddLibSymbol( ParseSymbol( symbolLibMap, true ) );
|
||||
screen->AddLibSymbol( ParseSymbol( symbolLibMap ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1991,10 +2012,16 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
break;
|
||||
|
||||
case T_symbol_instances:
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_symbol_instances );
|
||||
|
||||
parseSchSymbolInstances( screen );
|
||||
break;
|
||||
|
||||
case T_bus_alias:
|
||||
if( aIsCopyableOnly )
|
||||
Unexpected( T_bus_alias );
|
||||
|
||||
parseBusAlias( screen );
|
||||
break;
|
||||
|
||||
|
@ -2005,7 +2032,8 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet )
|
|||
}
|
||||
}
|
||||
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
if( !aIsCopyableOnly )
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <class_library.h>
|
||||
#include <schematic_lexer.h>
|
||||
#include <sch_file_versions.h>
|
||||
#include <default_values.h> // For some default values
|
||||
|
||||
|
||||
|
@ -222,18 +223,30 @@ public:
|
|||
|
||||
void ParseLib( LIB_PART_MAP& aSymbolLibMap );
|
||||
|
||||
LIB_PART* ParseSymbol( LIB_PART_MAP& aSymbolLibMap, bool aIsSchematicLib = false );
|
||||
LIB_PART* ParseSymbol( LIB_PART_MAP& aSymbolLibMap,
|
||||
int aFileVersion = SEXPR_SYMBOL_LIB_FILE_VERSION );
|
||||
|
||||
LIB_ITEM* ParseDrawItem();
|
||||
|
||||
/**
|
||||
* Parse a single schematic file into \a aSheet.
|
||||
* Parse the internal #LINE_READER object into \a aSheet.
|
||||
*
|
||||
* When \a aIsCopyableOnly is true, only schematic objects that are viewable on the canvas
|
||||
* for copy and paste purposes are parsed. Other schematic content such as bus definitions
|
||||
* or instance data will throw an #IO_ERROR exception.
|
||||
*
|
||||
* When \a aIsCopyableOnly is false, full schematic file parsing is performed.
|
||||
*
|
||||
* @note This does not load any sub-sheets or decent complex sheet hierarchies.
|
||||
*
|
||||
* @param aSheet The #SCH_SHEET object to store the parsed schematic file.
|
||||
* @param aIsCopyableOnly Load only the schematic objects that can be copied into \a aSheet
|
||||
* if true. Otherwise, load the full schematic file format.
|
||||
* @param aFileVersion The schematic file version to parser. Defaults to the schematic
|
||||
* file being parsed when \a aIsCopyableOnly is false.
|
||||
*/
|
||||
void ParseSchematic( SCH_SHEET* aSheet );
|
||||
void ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyablyOnly = false,
|
||||
int aFileVersion = SEXPR_SCHEMATIC_FILE_VERSION );
|
||||
|
||||
/**
|
||||
* Return whether a version number, if any was parsed, was too recent
|
||||
|
|
|
@ -389,10 +389,8 @@ public:
|
|||
|
||||
wxString GetFileName() const { return m_libFileName.GetFullPath(); }
|
||||
|
||||
static LIB_PART* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion,
|
||||
LIB_PART_MAP* aMap = nullptr );
|
||||
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
||||
int aNestLevel = 0, const wxString& aLibName = wxEmptyString );
|
||||
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
|
||||
int aNestLevel = 0, const wxString& aLibName = wxEmptyString );
|
||||
};
|
||||
|
||||
|
||||
|
@ -569,6 +567,16 @@ void SCH_SEXPR_PLUGIN::loadFile( const wxString& aFileName, SCH_SHEET* aSheet )
|
|||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SHEET* aSheet, int aFileVersion )
|
||||
{
|
||||
wxCHECK( aSheet, /* void */ );
|
||||
|
||||
SCH_SEXPR_PARSER parser( &aReader );
|
||||
|
||||
parser.ParseSchematic( aSheet, true, aFileVersion );
|
||||
}
|
||||
|
||||
|
||||
void SCH_SEXPR_PLUGIN::Save( const wxString& aFileName, SCH_SHEET* aSheet, KIWAY* aKiway,
|
||||
const PROPERTIES* aProperties )
|
||||
{
|
||||
|
@ -1390,16 +1398,6 @@ void SCH_SEXPR_PLUGIN_CACHE::Load()
|
|||
}
|
||||
|
||||
|
||||
LIB_PART* SCH_SEXPR_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorVersion,
|
||||
int aMinorVersion, LIB_PART_MAP* aMap )
|
||||
{
|
||||
std::unique_ptr< LIB_PART > part( new LIB_PART( wxEmptyString ) );
|
||||
|
||||
return part.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SCH_SEXPR_PLUGIN_CACHE::Save()
|
||||
{
|
||||
if( !m_isModified )
|
||||
|
@ -2285,10 +2283,15 @@ bool SCH_SEXPR_PLUGIN::IsSymbolLibWritable( const wxString& aLibraryPath )
|
|||
}
|
||||
|
||||
|
||||
LIB_PART* SCH_SEXPR_PLUGIN::ParsePart( LINE_READER& reader, int aMajorVersion,
|
||||
int aMinorVersion )
|
||||
LIB_PART* SCH_SEXPR_PLUGIN::ParsePart( LINE_READER& aReader, int aFileVersion )
|
||||
{
|
||||
return SCH_SEXPR_PLUGIN_CACHE::LoadPart( reader, aMajorVersion, aMinorVersion );
|
||||
LIB_PART_MAP map;
|
||||
SCH_SEXPR_PARSER parser( &aReader );
|
||||
|
||||
parser.NeedLEFT();
|
||||
parser.NextTok();
|
||||
|
||||
return parser.ParseSymbol( map, aFileVersion );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <sch_io_mgr.h>
|
||||
#include <sch_file_versions.h>
|
||||
#include <stack>
|
||||
|
||||
|
||||
|
@ -87,8 +88,8 @@ public:
|
|||
SCH_SHEET* aAppendToMe = nullptr,
|
||||
const PROPERTIES* aProperties = nullptr ) override;
|
||||
|
||||
void LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
|
||||
int version = EESCHEMA_VERSION );
|
||||
void LoadContent( LINE_READER& aReader, SCH_SHEET* aSheet,
|
||||
int aVersion = SEXPR_SCHEMATIC_FILE_VERSION );
|
||||
|
||||
void Save( const wxString& aFileName, SCH_SHEET* aSheet, KIWAY* aKiway,
|
||||
const PROPERTIES* aProperties = nullptr ) override;
|
||||
|
@ -121,7 +122,8 @@ public:
|
|||
|
||||
const wxString& GetError() const override { return m_error; }
|
||||
|
||||
static LIB_PART* ParsePart( LINE_READER& aReader, int majorVersion = 0, int minorVersion = 0 );
|
||||
static LIB_PART* ParsePart( LINE_READER& aReader,
|
||||
int aVersion = SEXPR_SCHEMATIC_FILE_VERSION );
|
||||
static void FormatPart( LIB_PART* aPart, OUTPUTFORMATTER& aFormatter );
|
||||
|
||||
private:
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <dialogs/dialog_edit_one_field.h>
|
||||
#include <dialogs/dialog_edit_component_in_lib.h>
|
||||
#include <dialogs/dialog_lib_edit_pin_table.h>
|
||||
#include <sch_legacy_plugin.h>
|
||||
#include <sch_sexpr_plugin.h>
|
||||
#include <lib_text.h>
|
||||
#include "lib_edit_tool.h"
|
||||
#include <math/util.h> // for KiROUND
|
||||
|
@ -627,7 +627,7 @@ int LIB_EDIT_TOOL::Copy( const TOOL_EVENT& aEvent )
|
|||
LIB_PART* partCopy = new LIB_PART( *part );
|
||||
|
||||
STRING_FORMATTER formatter;
|
||||
SCH_LEGACY_PLUGIN::FormatPart( partCopy, formatter );
|
||||
SCH_SEXPR_PLUGIN::FormatPart( partCopy, formatter );
|
||||
|
||||
delete partCopy;
|
||||
|
||||
|
@ -654,8 +654,7 @@ int LIB_EDIT_TOOL::Paste( const TOOL_EVENT& aEvent )
|
|||
|
||||
try
|
||||
{
|
||||
reader.ReadLine();
|
||||
newPart = SCH_LEGACY_PLUGIN::ParsePart( reader );
|
||||
newPart = SCH_SEXPR_PLUGIN::ParsePart( reader );
|
||||
}
|
||||
catch( IO_ERROR& )
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <netlist_exporters/netlist_exporter_pspice.h>
|
||||
#include <netlist_object.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_legacy_plugin.h>
|
||||
#include <sch_sexpr_plugin.h>
|
||||
#include <sch_line.h>
|
||||
#include <sch_painter.h>
|
||||
#include <sch_sheet.h>
|
||||
|
@ -1106,7 +1106,7 @@ bool SCH_EDITOR_CONTROL::doCopy()
|
|||
}
|
||||
|
||||
STRING_FORMATTER formatter;
|
||||
SCH_LEGACY_PLUGIN plugin;
|
||||
SCH_SEXPR_PLUGIN plugin;
|
||||
|
||||
plugin.Format( &selection, &formatter );
|
||||
|
||||
|
@ -1177,18 +1177,22 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
|
||||
STRING_LINE_READER reader( text, "Clipboard" );
|
||||
SCH_LEGACY_PLUGIN plugin;
|
||||
SCH_SEXPR_PLUGIN plugin;
|
||||
|
||||
SCH_SCREEN paste_screen( &m_frame->GetScreen()->Kiway() );
|
||||
SCH_SHEET paste_sheet;
|
||||
SCH_SCREEN* paste_screen = new SCH_SCREEN( &m_frame->GetScreen()->Kiway() );
|
||||
|
||||
// Screen object on heap is owned by the sheet.
|
||||
paste_sheet.SetScreen( paste_screen );
|
||||
|
||||
try
|
||||
{
|
||||
plugin.LoadContent( reader, &paste_screen );
|
||||
plugin.LoadContent( reader, &paste_sheet );
|
||||
}
|
||||
catch( IO_ERROR& )
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
// If it wasn't content, then paste as text
|
||||
paste_screen.Append( new SCH_TEXT( wxPoint( 0, 0 ), text ) );
|
||||
paste_screen->Append( new SCH_TEXT( wxPoint( 0, 0 ), text ) );
|
||||
}
|
||||
|
||||
bool forceKeepAnnotations = false;
|
||||
|
@ -1206,7 +1210,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
if( forceDropAnnotations )
|
||||
dropAnnotations = true;
|
||||
|
||||
// SCH_LEGACY_PLUGIN added the items to the paste screen, but not to the view or anything
|
||||
// SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything
|
||||
// else. Pull them back out to start with.
|
||||
//
|
||||
EDA_ITEMS loadedItems;
|
||||
|
@ -1217,7 +1221,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
if( destFn.IsRelative() )
|
||||
destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
|
||||
|
||||
for( SCH_ITEM* item : paste_screen.Items() )
|
||||
for( SCH_ITEM* item : paste_screen->Items() )
|
||||
{
|
||||
loadedItems.push_back( item );
|
||||
|
||||
|
@ -1258,10 +1262,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
// Remove the references from our temporary screen to prevent freeing on the DTOR
|
||||
paste_screen.Clear( false );
|
||||
|
||||
// Now we can resolve the components and add everything to the screen, view, etc.
|
||||
SYMBOL_LIB_TABLE* symLibTable = m_frame->Prj().SchSymbolLibTable();
|
||||
paste_screen->Clear( false );
|
||||
|
||||
for( unsigned i = 0; i < loadedItems.size(); ++i )
|
||||
{
|
||||
|
@ -1271,6 +1272,19 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
|
||||
|
||||
// The library symbol gets set from the cached library symbols in the current
|
||||
// schematic not the symbol libraries. The cached library symbol may have
|
||||
// changed from the original library symbol which would cause the copy to
|
||||
// be incorrect.
|
||||
SCH_SCREEN* currentScreen = m_frame->GetScreen();
|
||||
|
||||
wxCHECK2( currentScreen, continue );
|
||||
|
||||
auto it = currentScreen->GetLibSymbols().find( component->GetSchSymbolLibraryName() );
|
||||
|
||||
if( it != currentScreen->GetLibSymbols().end() )
|
||||
component->SetLibSymbol( new LIB_PART( *it->second ) );
|
||||
|
||||
if( dropAnnotations )
|
||||
{
|
||||
const_cast<KIID&>( component->m_Uuid ) = KIID();
|
||||
|
@ -1280,20 +1294,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
component->ClearAnnotation( nullptr );
|
||||
component->SetUnit( unit );
|
||||
}
|
||||
|
||||
LIB_PART* libSymbol = symLibTable->LoadSymbol( component->GetLibId() );
|
||||
|
||||
if( libSymbol )
|
||||
{
|
||||
component->SetLibSymbol( new LIB_PART( *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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue