Eeschema: implement s-expression schematic file format parser.

Fix a few issues with the s-expression schematic file formatter.
This commit is contained in:
Wayne Stambaugh 2020-03-25 11:27:15 -04:00
parent 9b4b85bb7d
commit 2f682b6c5f
10 changed files with 1313 additions and 311 deletions

View File

@ -22,7 +22,6 @@ F0 "#PWR" 0 -40 30 H I C CNN
F1 "video_schlib_+3.3V" 0 110 30 H V C CNN F1 "video_schlib_+3.3V" 0 110 30 H V C CNN
F2 "" 0 0 60 H V C CNN F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN F3 "" 0 0 60 H V C CNN
ALIAS +3,3V
DRAW DRAW
C 0 60 20 0 1 0 N C 0 60 20 0 1 0 N
P 3 0 1 0 0 0 0 40 0 40 N P 3 0 1 0 0 0 0 40 0 40 N
@ -65,7 +64,6 @@ F0 "U" 150 350 60 H V C CNN
F1 "video_schlib_24C16" 200 -350 60 H V C CNN F1 "video_schlib_24C16" 200 -350 60 H V C CNN
F2 "" 0 0 60 H V C CNN F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN F3 "" 0 0 60 H V C CNN
ALIAS 24C512
DRAW DRAW
S -400 -300 400 300 1 1 0 N S -400 -300 400 300 1 1 0 N
X GND 4 0 -500 200 U 60 60 0 0 W X GND 4 0 -500 200 U 60 60 0 0 W
@ -118,7 +116,6 @@ F0 "U" 100 575 50 H V L BNN
F1 "video_schlib_74LS245" 50 -575 50 H V L TNN F1 "video_schlib_74LS245" 50 -575 50 H V L TNN
F2 "" 50 -650 30 H V L CNN F2 "" 50 -650 30 H V L CNN
F3 "" 100 575 30 H V C CNN F3 "" 100 575 30 H V C CNN
ALIAS 74HC245
DRAW DRAW
S -400 550 400 -550 0 1 0 N S -400 550 400 -550 0 1 0 N
P 3 0 1 0 50 100 0 -100 -100 -100 N P 3 0 1 0 50 100 0 -100 -100 -100 N
@ -188,7 +185,6 @@ F0 "U" 0 100 70 H V C CNN
F1 "video_schlib_BT253" 0 -100 70 H V C CNN F1 "video_schlib_BT253" 0 -100 70 H V C CNN
F2 "" 0 0 60 H V C CNN F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN F3 "" 0 0 60 H V C CNN
ALIAS BT254
DRAW DRAW
S -750 -2600 750 2600 0 1 0 N S -750 -2600 750 2600 0 1 0 N
X VAA 1 -50 2900 300 D 60 60 1 1 I X VAA 1 -50 2900 300 D 60 60 1 1 I
@ -510,135 +506,6 @@ X D6 99 -2050 -1800 300 R 60 60 1 1 T
ENDDRAW ENDDRAW
ENDDEF ENDDEF
# #
# video_schlib_BUSPCI-5V
#
DEF video_schlib_BUSPCI-5V J 0 30 Y Y 1 F N
F0 "J" 0 3200 60 H V C CNN
F1 "video_schlib_BUSPCI-5V" 0 -3200 60 H V C CNN
F2 "" 0 0 60 H V C CNN
F3 "" 0 0 60 H V C CNN
ALIAS BUSPCI-5V
DRAW
S -750 3150 750 -3150 0 1 0 N
X TRST# A1 1100 3050 350 L 60 60 1 1 O I
X VIO A10 1100 2150 350 L 60 60 1 1 W
X RESERVED A11 1100 2050 350 L 60 60 1 1 P
X 3.3VAUX A14 1100 1750 350 L 60 60 1 1 P
X RST# A15 1100 1650 350 L 60 60 1 1 O I
X VIO A16 1100 1550 350 L 60 60 1 1 W
X GNT# A17 1100 1450 350 L 60 60 1 1 B I
X GND A18 1100 1350 350 L 60 60 1 1 W
X PME# A19 1100 1250 350 L 60 60 1 1 P
X +12V A2 1100 2950 350 L 60 60 1 1 W
X AD[30] A20 1100 1150 350 L 60 60 1 1 B
X +3.3V A21 1100 1050 350 L 60 60 1 1 W
X AD[28] A22 1100 950 350 L 60 60 1 1 B
X AD[26] A23 1100 850 350 L 60 60 1 1 B
X GND A24 1100 750 350 L 60 60 1 1 W
X AD[24] A25 1100 650 350 L 60 60 1 1 B
X IDSEL A26 1100 550 350 L 60 60 1 1 O
X +3.3V A27 1100 450 350 L 60 60 1 1 W
X AD[22] A28 1100 350 350 L 60 60 1 1 B
X AD[20] A29 1100 250 350 L 60 60 1 1 B
X TMS A3 1100 2850 350 L 60 60 1 1 O
X GND A30 1100 150 350 L 60 60 1 1 W
X AD[18] A31 1100 50 350 L 60 60 1 1 B
X AD[16] A32 1100 -50 350 L 60 60 1 1 B
X +3.3V A33 1100 -150 350 L 60 60 1 1 W
X FRAME# A34 1100 -250 350 L 60 60 1 1 B I
X GND A35 1100 -350 350 L 60 60 1 1 W
X TRDY# A36 1100 -450 350 L 60 60 1 1 B I
X GND A37 1100 -550 350 L 60 60 1 1 W
X STOP# A38 1100 -650 350 L 60 60 1 1 B I
X +3.3V A39 1100 -750 350 L 60 60 1 1 W
X TDI A4 1100 2750 350 L 60 60 1 1 O
X RESERVED A40 1100 -850 350 L 60 60 1 1 B
X RESERVED A41 1100 -950 350 L 60 60 1 1 B
X GND A42 1100 -1050 350 L 60 60 1 1 W
X PAR A43 1100 -1150 350 L 60 60 1 1 B
X AD[15] A44 1100 -1250 350 L 60 60 1 1 B
X +3.3V A45 1100 -1350 350 L 60 60 1 1 W
X AD[13] A46 1100 -1450 350 L 60 60 1 1 B
X AD[11] A47 1100 -1550 350 L 60 60 1 1 B
X GND A48 1100 -1650 350 L 60 60 1 1 W
X AD[09] A49 1100 -1750 350 L 60 60 1 1 B
X +5V A5 1100 2650 350 L 60 60 1 1 W
X C/BE#[0] A52 1100 -2050 350 L 60 60 1 1 B I
X +3.3V A53 1100 -2150 350 L 60 60 1 1 W
X AD[06] A54 1100 -2250 350 L 60 60 1 1 B
X AD[04] A55 1100 -2350 350 L 60 60 1 1 B
X GND A56 1100 -2450 350 L 60 60 1 1 W
X AD[02] A57 1100 -2550 350 L 60 60 1 1 B
X AD[00] A58 1100 -2650 350 L 60 60 1 1 B
X VIO A59 1100 -2750 350 L 60 60 1 1 W
X INTA# A6 1100 2550 350 L 60 60 1 1 I I
X REQ64# A60 1100 -2850 350 L 60 60 1 1 B I
X +5V A61 1100 -2950 350 L 60 60 1 1 W
X +5V A62 1100 -3050 350 L 60 60 1 1 W
X INTC# A7 1100 2450 350 L 60 60 1 1 I I
X +5V A8 1100 2350 350 L 60 60 1 1 W
X RESERVED A9 1100 2250 350 L 60 60 1 1 P
X -12V B1 -1100 3050 350 R 60 60 1 1 W
X RESERVED B10 -1100 2150 350 R 60 60 1 1 P
X PRSNT2# B11 -1100 2050 350 R 60 60 1 1 I I
X RESERVED B14 -1100 1750 350 R 60 60 1 1 P
X GND B15 -1100 1650 350 R 60 60 1 1 W
X CLK B16 -1100 1550 350 R 60 60 1 1 O
X GND B17 -1100 1450 350 R 60 60 1 1 W
X REQ# B18 -1100 1350 350 R 60 60 1 1 B I
X VIO B19 -1100 1250 350 R 60 60 1 1 W
X TCK B2 -1100 2950 350 R 60 60 1 1 O
X AD[31] B20 -1100 1150 350 R 60 60 1 1 B
X AD[29] B21 -1100 1050 350 R 60 60 1 1 B
X GND B22 -1100 950 350 R 60 60 1 1 W
X AD[27] B23 -1100 850 350 R 60 60 1 1 B
X AD[25] B24 -1100 750 350 R 60 60 1 1 B
X +3.3V B25 -1100 650 350 R 60 60 1 1 W
X C/BE#[3] B26 -1100 550 350 R 60 60 1 1 B
X AD[23] B27 -1100 450 350 R 60 60 1 1 B
X GND B28 -1100 350 350 R 60 60 1 1 W
X AD[21] B29 -1100 250 350 R 60 60 1 1 B
X GND B3 -1100 2850 350 R 60 60 1 1 I
X AD[19] B30 -1100 150 350 R 60 60 1 1 B
X +3.3V B31 -1100 50 350 R 60 60 1 1 W
X AD[17] B32 -1100 -50 350 R 60 60 1 1 B
X C/BE#[2] B33 -1100 -150 350 R 60 60 1 1 B I
X GND B34 -1100 -250 350 R 60 60 1 1 W
X IRDY# B35 -1100 -350 350 R 60 60 1 1 B I
X +3.3V B36 -1100 -450 350 R 60 60 1 1 W
X DEVSEL# B37 -1100 -550 350 R 60 60 1 1 B I
X GND B38 -1100 -650 350 R 60 60 1 1 W
X LOCK# B39 -1100 -750 350 R 60 60 1 1 B I
X TDO B4 -1100 2750 350 R 60 60 1 1 I
X PERR# B40 -1100 -850 350 R 60 60 1 1 B I
X +3.3V B41 -1100 -950 350 R 60 60 1 1 W
X SERR# B42 -1100 -1050 350 R 60 60 1 1 I I
X +3.3V B43 -1100 -1150 350 R 60 60 1 1 W
X C/BE#[1] B44 -1100 -1250 350 R 60 60 1 1 B I
X AD[14] B45 -1100 -1350 350 R 60 60 1 1 B
X GND B46 -1100 -1450 350 R 60 60 1 1 W
X AD[12] B47 -1100 -1550 350 R 60 60 1 1 B
X AD[10] B48 -1100 -1650 350 R 60 60 1 1 B
X M66EN B49 -1100 -1750 350 R 60 60 1 1 W
X +5V B5 -1100 2650 350 R 60 60 1 1 W
X AD[08] B52 -1100 -2050 350 R 60 60 1 1 B
X AD[07] B53 -1100 -2150 350 R 60 60 1 1 B
X +3.3V B54 -1100 -2250 350 R 60 60 1 1 I
X AD[05] B55 -1100 -2350 350 R 60 60 1 1 B
X AD[03] B56 -1100 -2450 350 R 60 60 1 1 B
X GND B57 -1100 -2550 350 R 60 60 1 1 W
X AD[01] B58 -1100 -2650 350 R 60 60 1 1 B
X VIO B59 -1100 -2750 350 R 60 60 1 1 W
X +5V B6 -1100 2550 350 R 60 60 1 1 W
X ACK64# B60 -1100 -2850 350 R 60 60 1 1 B I
X +5V B61 -1100 -2950 350 R 60 60 1 1 W
X +5V B62 -1100 -3050 350 R 60 60 1 1 W
X INTB# B7 -1100 2450 350 R 60 60 1 1 I I
X INTD# B8 -1100 2350 350 R 60 60 1 1 I I
X PRSNT1# B9 -1100 2250 350 R 60 60 1 1 I I
ENDDRAW
ENDDEF
#
# video_schlib_C # video_schlib_C
# #
DEF video_schlib_C C 0 10 N Y 1 F N DEF video_schlib_C C 0 10 N Y 1 F N
@ -711,7 +578,6 @@ F0 "C" 50 100 40 H V L CNN
F1 "video_schlib_CP" 50 -100 40 H V L CNN F1 "video_schlib_CP" 50 -100 40 H V L CNN
F2 "" 100 -150 30 H V C CNN F2 "" 100 -150 30 H V C CNN
F3 "" 50 100 30 H V C CNN F3 "" 50 100 30 H V C CNN
ALIAS CAPAPOL
$FPLIST $FPLIST
CP* CP*
SM* SM*

View File

@ -485,7 +485,7 @@ make_lexer(
schematic.keywords schematic.keywords
schematic_lexer.h schematic_lexer.h
schematic_keywords.cpp schematic_keywords.cpp
TSYMBOL_LIB_T TSCHEMATIC_T
) )
add_subdirectory( plugins ) add_subdirectory( plugins )

View File

@ -197,10 +197,12 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{ {
// implement the pseudo code from KIWAY_PLAYER.h: // implement the pseudo code from KIWAY_PLAYER.h:
wxString msg;
// This is for python: // This is for python:
if( aFileSet.size() != 1 ) if( aFileSet.size() != 1 )
{ {
UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename.", __func__ ); msg.Printf( "Eeschema:%s() takes only a single filename.", __WXFUNCTION__ );
DisplayError( this, msg ); DisplayError( this, msg );
return false; return false;
} }
@ -212,8 +214,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( !LockFile( fullFileName ) ) if( !LockFile( fullFileName ) )
{ {
wxString msg = wxString::Format( _( "Schematic file \"%s\" is already open." ), msg.Printf( _( "Schematic file \"%s\" is already open." ), fullFileName );
fullFileName );
DisplayError( this, msg ); DisplayError( this, msg );
return false; return false;
} }
@ -230,9 +231,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
if( is_new && !( aCtl & KICTL_CREATE ) ) if( is_new && !( aCtl & KICTL_CREATE ) )
{ {
// notify user that fullFileName does not exist, ask if user wants to create it. // notify user that fullFileName does not exist, ask if user wants to create it.
wxString ask = wxString::Format( _( "Schematic \"%s\" does not exist. Do you wish to create it?" ), msg.Printf( _( "Schematic \"%s\" does not exist. Do you wish to create it?" ),
fullFileName ); fullFileName );
if( !IsOK( this, ask ) )
if( !IsOK( this, msg ) )
return false; return false;
} }
@ -240,8 +242,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{ {
SetScreen( nullptr ); SetScreen( nullptr );
delete g_RootSheet; delete g_RootSheet;
if( g_CurrentSheet ) if( g_CurrentSheet )
g_CurrentSheet->clear(); g_CurrentSheet->clear();
g_RootSheet = nullptr; g_RootSheet = nullptr;
CreateScreens(); CreateScreens();
@ -295,7 +299,9 @@ 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_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( fullFileName );
SCH_PLUGIN* plugin = SCH_IO_MGR::FindPlugin( schFileType );
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin );
// This will rename the file if there is an autosave and the user want to recover // This will rename the file if there is an autosave and the user want to recover
CheckForAutoSaveFile( fullFileName ); CheckForAutoSaveFile( fullFileName );
@ -324,7 +330,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
CreateScreens(); CreateScreens();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true ); m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
wxString msg;
msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ), msg.Printf( _( "Error loading schematic file \"%s\".\n%s" ),
GetChars( fullFileName ), GetChars( ioe.What() ) ); GetChars( fullFileName ), GetChars( ioe.What() ) );
DisplayError( this, msg ); DisplayError( this, msg );

View File

@ -780,9 +780,12 @@ 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();
wildcards += "|" + KiCadSchematicFileWildcard();
wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir, wxEmptyString, wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir, wxEmptyString,
LegacySchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST ); wildcards, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( dlg.ShowModal() != wxID_CANCEL ) if( dlg.ShowModal() != wxID_CANCEL )
{ {

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@
#include <math/util.h> // KiROUND, Clamp #include <math/util.h> // KiROUND, Clamp
#include <class_library.h> #include <class_library.h>
#include <general.h>
#include <schematic_lexer.h> #include <schematic_lexer.h>
@ -45,8 +46,45 @@ class LIB_ITEM;
class LIB_PIN; class LIB_PIN;
class LIB_POLYLINE; class LIB_POLYLINE;
class LIB_TEXT; class LIB_TEXT;
class PAGE_INFO;
class SCH_BITMAP;
class SCH_BUS_WIRE_ENTRY;
class SCH_COMPONENT;
class SCH_FIELD;
class SCH_JUNCTION;
class SCH_LINE;
class SCH_NO_CONNECT;
class SCH_SCREEN;
class SCH_SHEET;
class SCH_SHEET_PIN;
class SCH_TEXT;
class TITLE_BLOCK;
/**
* Simple container to manage line stroke parameters.
*/
class STROKE_PARAMS
{
public:
int m_Width;
PLOT_DASH_TYPE m_Type;
COLOR4D m_Color;
STROKE_PARAMS( int aWidth = GetDefaultLineThickness(),
PLOT_DASH_TYPE aType = PLOT_DASH_TYPE::DEFAULT,
const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) :
m_Width( aWidth ),
m_Type( aType ),
m_Color( aColor )
{
}
};
/**
* Object to parser s-expression symbol library and schematic file formats.
*/
class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
{ {
int m_requiredVersion; ///< Set to the symbol library file version required. int m_requiredVersion; ///< Set to the symbol library file version required.
@ -55,7 +93,13 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
int m_convert; ///< The current body style being parsed. int m_convert; ///< The current body style being parsed.
wxString m_symbolName; ///< The current symbol name. wxString m_symbolName; ///< The current symbol name.
void parseHeader(); void parseHeader( TSCHEMATIC_T::T aHeaderType, int aFileVersion );
inline long parseHex()
{
NextTok();
return strtol( CurText(), NULL, 16 );
}
inline int parseInt() inline int parseInt()
{ {
@ -83,7 +127,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
return parseDouble(); return parseDouble();
} }
inline double parseDouble( TSYMBOL_LIB_T::T aToken ) inline double parseDouble( TSCHEMATIC_T::T aToken )
{ {
return parseDouble( GetTokenText( aToken ) ); return parseDouble( GetTokenText( aToken ) );
} }
@ -109,7 +153,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) ); return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
} }
inline int parseInternalUnits( TSYMBOL_LIB_T::T aToken ) inline int parseInternalUnits( TSCHEMATIC_T::T aToken )
{ {
return parseInternalUnits( GetTokenText( aToken ) ); return parseInternalUnits( GetTokenText( aToken ) );
} }
@ -124,6 +168,13 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
return xy; return xy;
} }
/**
* Parse stroke definition \a aStroke.
*
* @param aStrokeDef A reference to the #STROKE_PARAMS structure to write to.
*/
void parseStroke( STROKE_PARAMS& aStroke );
FILL_T parseFillMode(); FILL_T parseFillMode();
void parseEDA_TEXT( EDA_TEXT* aText ); void parseEDA_TEXT( EDA_TEXT* aText );
@ -139,6 +190,21 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
LIB_RECTANGLE* parseRectangle(); LIB_RECTANGLE* parseRectangle();
LIB_TEXT* parseText(); LIB_TEXT* parseText();
void parsePAGE_INFO( PAGE_INFO& aPageInfo );
void parseTITLE_BLOCK( TITLE_BLOCK& aTitleBlock );
void parseSchSymbolInstances( std::unique_ptr<SCH_COMPONENT>& aSymbol );
SCH_SHEET_PIN* parseSchSheetPin( SCH_SHEET* aSheet );
SCH_FIELD* parseSchField();
SCH_COMPONENT* parseSchematicSymbol();
SCH_BITMAP* parseImage();
SCH_SHEET* parseSheet();
SCH_JUNCTION* parseJunction();
SCH_NO_CONNECT* parseNoConnect();
SCH_BUS_WIRE_ENTRY* parseBusEntry();
SCH_LINE* parseLine();
SCH_TEXT* parseSchText();
public: public:
SCH_SEXPR_PARSER( LINE_READER* aLineReader = nullptr ); SCH_SEXPR_PARSER( LINE_READER* aLineReader = nullptr );
@ -148,6 +214,15 @@ public:
LIB_ITEM* ParseDrawItem(); LIB_ITEM* ParseDrawItem();
/**
* Parse a single schematic file into \a aScreen.
*
* @note This does not load any sub-sheets or decent complex sheet hierarchies.
*
* @param aScreen The #SCH_SCREEN object to store the parsed schematic file.
*/
void ParseSchematic( SCH_SCREEN* aScreen );
/** /**
* Return whether a version number, if any was parsed, was too recent * Return whether a version number, if any was parsed, was too recent
*/ */

View File

@ -75,7 +75,7 @@
#include <confirm.h> #include <confirm.h>
#include <tool/selection.h> #include <tool/selection.h>
using namespace TSYMBOL_LIB_T; using namespace TSCHEMATIC_T;
#define SCH_PARSE_ERROR( text, reader, pos ) \ #define SCH_PARSE_ERROR( text, reader, pos ) \
@ -560,105 +560,9 @@ void SCH_SEXPR_PLUGIN::loadFile( const wxString& aFileName, SCH_SCREEN* aScreen
{ {
FILE_LINE_READER reader( aFileName ); FILE_LINE_READER reader( aFileName );
loadHeader( reader, aScreen ); SCH_SEXPR_PARSER parser( &reader );
LoadContent( reader, aScreen, m_version ); parser.ParseSchematic( aScreen );
}
void SCH_SEXPR_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen, int version )
{
m_version = version;
}
void SCH_SEXPR_PLUGIN::loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen )
{
}
void SCH_SEXPR_PLUGIN::loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScreen )
{
wxASSERT( aScreen != NULL );
wxString buf;
PAGE_INFO pageInfo;
TITLE_BLOCK tb;
}
SCH_SHEET* SCH_SEXPR_PLUGIN::loadSheet( LINE_READER& aReader )
{
std::unique_ptr< SCH_SHEET > sheet( new SCH_SHEET() );
// Timesheet time stamps are now automatically generated.
return sheet.release();
}
SCH_BITMAP* SCH_SEXPR_PLUGIN::loadBitmap( LINE_READER& aReader )
{
std::unique_ptr< SCH_BITMAP > bitmap( new SCH_BITMAP );
return bitmap.release();
}
SCH_JUNCTION* SCH_SEXPR_PLUGIN::loadJunction( LINE_READER& aReader )
{
std::unique_ptr< SCH_JUNCTION > junction( new SCH_JUNCTION );
return junction.release();
}
SCH_NO_CONNECT* SCH_SEXPR_PLUGIN::loadNoConnect( LINE_READER& aReader )
{
std::unique_ptr< SCH_NO_CONNECT > no_connect( new SCH_NO_CONNECT );
return no_connect.release();
}
SCH_LINE* SCH_SEXPR_PLUGIN::loadWire( LINE_READER& aReader )
{
std::unique_ptr< SCH_LINE > wire( new SCH_LINE );
return wire.release();
}
SCH_BUS_ENTRY_BASE* SCH_SEXPR_PLUGIN::loadBusEntry( LINE_READER& aReader )
{
std::unique_ptr< SCH_BUS_ENTRY_BASE > busEntry;
return busEntry.release();
}
SCH_TEXT* SCH_SEXPR_PLUGIN::loadText( LINE_READER& aReader )
{
std::unique_ptr< SCH_TEXT> text;
return text.release();
}
SCH_COMPONENT* SCH_SEXPR_PLUGIN::loadComponent( LINE_READER& aReader )
{
std::unique_ptr< SCH_COMPONENT > component( new SCH_COMPONENT() );
return component.release();
}
std::shared_ptr<BUS_ALIAS> SCH_SEXPR_PLUGIN::loadBusAlias( LINE_READER& aReader,
SCH_SCREEN* aScreen )
{
auto busAlias = std::make_shared< BUS_ALIAS >( aScreen );
return busAlias;
} }
@ -716,8 +620,9 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SCREEN* aScreen )
save_map.insert( item ); save_map.insert( item );
KICAD_T itemType = TYPE_NOT_INIT; KICAD_T itemType = TYPE_NOT_INIT;
SCH_LAYER_ID layer = SCH_LAYER_ID_START;
for( auto& item : save_map ) for( SCH_ITEM* item : save_map )
{ {
if( itemType != item->Type() ) if( itemType != item->Type() )
{ {
@ -735,32 +640,53 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SCREEN* aScreen )
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
saveSymbol( static_cast<SCH_COMPONENT*>( item ), 1 ); saveSymbol( static_cast<SCH_COMPONENT*>( item ), 1 );
break; break;
case SCH_BITMAP_T: case SCH_BITMAP_T:
saveBitmap( static_cast<SCH_BITMAP*>( item ), 1 ); saveBitmap( static_cast<SCH_BITMAP*>( item ), 1 );
break; break;
case SCH_SHEET_T: case SCH_SHEET_T:
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
saveSheet( static_cast<SCH_SHEET*>( item ), 1 ); saveSheet( static_cast<SCH_SHEET*>( item ), 1 );
break; break;
case SCH_JUNCTION_T: case SCH_JUNCTION_T:
saveJunction( static_cast<SCH_JUNCTION*>( item ), 1 ); saveJunction( static_cast<SCH_JUNCTION*>( item ), 1 );
break; break;
case SCH_NO_CONNECT_T: case SCH_NO_CONNECT_T:
saveNoConnect( static_cast<SCH_NO_CONNECT*>( item ), 1 ); saveNoConnect( static_cast<SCH_NO_CONNECT*>( item ), 1 );
break; break;
case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T:
case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_BUS_ENTRY_T:
saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ), 1 ); saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ), 1 );
break; break;
case SCH_LINE_T: case SCH_LINE_T:
if( layer != item->GetLayer() )
{
if( layer == SCH_LAYER_ID_START )
{
layer = item->GetLayer();
}
else
{
layer = item->GetLayer();
m_out->Print( 0, "\n" );
}
}
saveLine( static_cast<SCH_LINE*>( item ), 1 ); saveLine( static_cast<SCH_LINE*>( item ), 1 );
break; break;
case SCH_TEXT_T: case SCH_TEXT_T:
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T: case SCH_HIER_LABEL_T:
saveText( static_cast<SCH_TEXT*>( item ), 1 ); saveText( static_cast<SCH_TEXT*>( item ), 1 );
break; break;
default: default:
wxASSERT( "Unexpected schematic object type in SCH_SEXPR_PLUGIN::Format()" ); wxASSERT( "Unexpected schematic object type in SCH_SEXPR_PLUGIN::Format()" );
} }
@ -783,31 +709,39 @@ void SCH_SEXPR_PLUGIN::Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatte
case SCH_COMPONENT_T: case SCH_COMPONENT_T:
saveSymbol( static_cast< SCH_COMPONENT* >( item ), 0 ); saveSymbol( static_cast< SCH_COMPONENT* >( item ), 0 );
break; break;
case SCH_BITMAP_T: case SCH_BITMAP_T:
saveBitmap( static_cast< SCH_BITMAP* >( item ), 0 ); saveBitmap( static_cast< SCH_BITMAP* >( item ), 0 );
break; break;
case SCH_SHEET_T: case SCH_SHEET_T:
saveSheet( static_cast< SCH_SHEET* >( item ), 0 ); saveSheet( static_cast< SCH_SHEET* >( item ), 0 );
break; break;
case SCH_JUNCTION_T: case SCH_JUNCTION_T:
saveJunction( static_cast< SCH_JUNCTION* >( item ), 0 ); saveJunction( static_cast< SCH_JUNCTION* >( item ), 0 );
break; break;
case SCH_NO_CONNECT_T: case SCH_NO_CONNECT_T:
saveNoConnect( static_cast< SCH_NO_CONNECT* >( item ), 0 ); saveNoConnect( static_cast< SCH_NO_CONNECT* >( item ), 0 );
break; break;
case SCH_BUS_WIRE_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T:
case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_BUS_ENTRY_T:
saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ), 0 ); saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ), 0 );
break; break;
case SCH_LINE_T: case SCH_LINE_T:
saveLine( static_cast< SCH_LINE* >( item ), 0 ); saveLine( static_cast< SCH_LINE* >( item ), 0 );
break; break;
case SCH_TEXT_T: case SCH_TEXT_T:
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T: case SCH_HIER_LABEL_T:
saveText( static_cast< SCH_TEXT* >( item ), 0 ); saveText( static_cast< SCH_TEXT* >( item ), 0 );
break; break;
default: default:
wxASSERT( "Unexpected schematic object type in SCH_SEXPR_PLUGIN::Format()" ); wxASSERT( "Unexpected schematic object type in SCH_SEXPR_PLUGIN::Format()" );
} }
@ -819,35 +753,20 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_COMPONENT* aSymbol, int aNestLevel )
{ {
wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" ); wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" );
std::string name1; std::string libName;
std::string name2;
wxArrayString reference_fields; wxArrayString reference_fields;
static wxString delimiters( wxT( " " ) ); static wxString delimiters( wxT( " " ) );
// This is redundant with the AR entries below, but it makes the files backwards-compatible.
if( aSymbol->GetInstanceReferences().size() > 0 )
{
const COMPONENT_INSTANCE_REFERENCE& instance = aSymbol->GetInstanceReferences()[0];
name1 = toUTFTildaText( instance.m_Reference );
}
else
{
if( aSymbol->GetField( REFERENCE )->GetText().IsEmpty() )
name1 = toUTFTildaText( aSymbol->GetPrefix() );
else
name1 = toUTFTildaText( aSymbol->GetField( REFERENCE )->GetText() );
}
wxString part_name = aSymbol->GetLibId().Format(); wxString part_name = aSymbol->GetLibId().Format();
if( part_name.size() ) if( part_name.size() )
{ {
name2 = toUTFTildaText( part_name ); libName = toUTFTildaText( part_name );
} }
else else
{ {
name2 = "_NONAME_"; libName = "_NONAME_";
} }
double angle; double angle;
@ -858,20 +777,22 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_COMPONENT* aSymbol, int aNestLevel )
else if( orientation == CMP_ORIENT_180 ) else if( orientation == CMP_ORIENT_180 )
angle = 180.0; angle = 180.0;
else if( orientation == CMP_ORIENT_270 ) else if( orientation == CMP_ORIENT_270 )
angle = 270; angle = 270.0;
else else
angle = 0.0; angle = 0.0;
m_out->Print( aNestLevel, "(symbol %s is %s (at %d %d %g)", m_out->Print( aNestLevel, "(symbol (lib_id %s) (at %s %s %s)",
m_out->Quotew( name1 ).c_str(), m_out->Quotew( name2 ).c_str(), m_out->Quotew( libName ).c_str(),
aSymbol->GetPosition().x, aSymbol->GetPosition().y, angle ); FormatInternalUnits( aSymbol->GetPosition().x ).c_str(),
FormatInternalUnits( aSymbol->GetPosition().y ).c_str(),
FormatAngle( angle * 10.0 ).c_str() );
bool mirrorX = aSymbol->GetOrientation() & CMP_MIRROR_X; bool mirrorX = aSymbol->GetOrientation() & CMP_MIRROR_X;
bool mirrorY = aSymbol->GetOrientation() & CMP_MIRROR_Y; bool mirrorY = aSymbol->GetOrientation() & CMP_MIRROR_Y;
if( mirrorX || mirrorY ) if( mirrorX || mirrorY )
{ {
m_out->Print( 0, "(mirror" ); m_out->Print( 0, " (mirror" );
if( mirrorX ) if( mirrorX )
m_out->Print( 0, " x" ); m_out->Print( 0, " x" );
@ -879,12 +800,13 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_COMPONENT* aSymbol, int aNestLevel )
if( mirrorY ) if( mirrorY )
m_out->Print( 0, " y" ); m_out->Print( 0, " y" );
m_out->Print( 0, ")\n" ); m_out->Print( 0, ")" );
} }
if( !( aSymbol->GetInstanceReferences().size() > 1 ) )
m_out->Print( 0, " (unit %d)\n", aSymbol->GetUnit() );
else else
{
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
}
// @todo Convert to full UUID if current UUID is a legacy time stamp. // @todo Convert to full UUID if current UUID is a legacy time stamp.
m_out->Print( aNestLevel + 1, "(uuid %s)\n", m_out->Print( aNestLevel + 1, "(uuid %s)\n",
@ -945,18 +867,21 @@ void SCH_SEXPR_PLUGIN::saveField( SCH_FIELD* aField, int aNestLevel )
wxString fieldName; wxString fieldName;
// 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.
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 = "ki_" + TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId() ).Lower();
else else
fieldName = aField->GetName(); fieldName = aField->GetName();
m_out->Print( aNestLevel, "(property %s %s (at %d %d %g)", m_out->Print( aNestLevel, "(property %s %s (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->GetPosition().x, aField->GetPosition().y, FormatInternalUnits( aField->GetPosition().x ).c_str(),
aField->GetTextAngleDegrees() ); FormatInternalUnits( aField->GetPosition().y ).c_str(),
FormatAngle( aField->GetTextAngleDegrees() * 10.0 ).c_str() );
if( !aField->IsDefaultFormatting() ) if( !aField->IsDefaultFormatting() || ( aField->GetTextHeight() != GetDefaultTextSize() ) )
{ {
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
aField->Format( m_out, aNestLevel, 0 ); aField->Format( m_out, aNestLevel, 0 );
@ -977,8 +902,9 @@ void SCH_SEXPR_PLUGIN::saveBitmap( SCH_BITMAP* aBitmap, int aNestLevel )
wxCHECK_RET( image != NULL, "wxImage* is NULL" ); wxCHECK_RET( image != NULL, "wxImage* is NULL" );
m_out->Print( aNestLevel, "(image (at %d %d)", m_out->Print( aNestLevel, "(image (at %s %s)",
aBitmap->GetPosition().x, aBitmap->GetPosition().y ); FormatInternalUnits( aBitmap->GetPosition().x ).c_str(),
FormatInternalUnits( aBitmap->GetPosition().y ).c_str() );
if( aBitmap->GetImage()->GetScale() != 1.0 ) if( aBitmap->GetImage()->GetScale() != 1.0 )
m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() ); m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() );
@ -996,19 +922,20 @@ void SCH_SEXPR_PLUGIN::saveBitmap( SCH_BITMAP* aBitmap, int aNestLevel )
for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ ) for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
{ {
if( ii % 32 ) if( ii % 16 )
{ {
m_out->Print( 0, " %2.2X ", *begin & 0xFF ); m_out->Print( 0, " 0x%2.2X", *begin & 0xFF );
} }
else else
{ {
ii = 0; ii = 0;
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
m_out->Print( aNestLevel + 2, "%2.2X ", *begin & 0xFF ); m_out->Print( aNestLevel + 2, "0x%2.2X", *begin & 0xFF );
} }
} }
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token. m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token.
m_out->Print( aNestLevel, ")\n" ); // Closes image token. m_out->Print( aNestLevel, ")\n" ); // Closes image token.
} }
@ -1018,13 +945,13 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
{ {
wxCHECK_RET( aSheet != nullptr && m_out != nullptr, "" ); wxCHECK_RET( aSheet != nullptr && m_out != nullptr, "" );
m_out->Print( aNestLevel, "(sheet (start %s %s) (end %s %s)", m_out->Print( aNestLevel, "(sheet (at %s %s) (size %s %s)",
FormatInternalUnits( aSheet->GetPosition().x ).c_str(), FormatInternalUnits( aSheet->GetPosition().x ).c_str(),
FormatInternalUnits( aSheet->GetPosition().y ).c_str(), FormatInternalUnits( aSheet->GetPosition().y ).c_str(),
FormatInternalUnits( aSheet->GetSize().GetWidth() ).c_str(), FormatInternalUnits( aSheet->GetSize().GetWidth() ).c_str(),
FormatInternalUnits( aSheet->GetSize().GetHeight() ).c_str() ); FormatInternalUnits( aSheet->GetSize().GetHeight() ).c_str() );
if( aSheet->UsesDefaultStroke() ) if( !aSheet->UsesDefaultStroke() )
{ {
m_out->Print( 0, " " ); m_out->Print( 0, " " );
formatStroke( m_out, 0, aSheet->GetBorderWidth(), PLOT_DASH_TYPE::SOLID, formatStroke( m_out, 0, aSheet->GetBorderWidth(), PLOT_DASH_TYPE::SOLID,
@ -1037,19 +964,26 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
for( auto field : aSheet->GetFields() ) for( auto field : aSheet->GetFields() )
{ {
saveField( &field, aNestLevel + 1 ); SCH_FIELD tmp = field;
if( field.GetId() == SHEETNAME )
tmp.SetName( "ki_sheet_name" );
else if( field.GetId() == SHEETFILENAME )
tmp.SetName( "ki_sheet_file" );
saveField( &tmp, aNestLevel + 1 );
} }
for( const auto pin : aSheet->GetPins() ) for( const auto pin : aSheet->GetPins() )
{ {
m_out->Print( aNestLevel + 1, "(pin %s %s at( %s %s %g)", m_out->Print( aNestLevel + 1, "(pin %s %s (at %s %s %s)",
EscapedUTF8( pin->GetText() ).c_str(), EscapedUTF8( pin->GetText() ).c_str(),
getSheetPinShapeToken( pin->GetShape() ), getSheetPinShapeToken( pin->GetShape() ),
FormatInternalUnits( pin->GetPosition().x ).c_str(), FormatInternalUnits( pin->GetPosition().x ).c_str(),
FormatInternalUnits( pin->GetPosition().y ).c_str(), FormatInternalUnits( pin->GetPosition().y ).c_str(),
getSheetPinAngle( pin->GetEdge() ) ); FormatAngle( getSheetPinAngle( pin->GetEdge() ) * 10.0 ).c_str() );
if( !pin->IsDefaultFormatting() ) if( !pin->IsDefaultFormatting() || ( pin->GetTextHeight() != GetDefaultTextSize() ) )
{ {
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
pin->Format( m_out, aNestLevel + 1, 0 ); pin->Format( m_out, aNestLevel + 1, 0 );
@ -1099,11 +1033,11 @@ void SCH_SEXPR_PLUGIN::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLev
} }
else else
{ {
m_out->Print( aNestLevel, "(bus_entry (start %s %s) (end %s %s))\n", m_out->Print( aNestLevel, "(bus_entry (at %s %s) (size %s %s))\n",
FormatInternalUnits( aBusEntry->GetPosition().x ).c_str(), FormatInternalUnits( aBusEntry->GetPosition().x ).c_str(),
FormatInternalUnits( aBusEntry->GetPosition().y ).c_str(), FormatInternalUnits( aBusEntry->GetPosition().y ).c_str(),
FormatInternalUnits( aBusEntry->m_End().x ).c_str(), FormatInternalUnits( aBusEntry->GetSize().GetWidth() ).c_str(),
FormatInternalUnits( aBusEntry->m_End().y ).c_str() ); FormatInternalUnits( aBusEntry->GetSize().GetHeight() ).c_str() );
} }
} }
@ -1144,19 +1078,30 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
{ {
wxCHECK_RET( aText != nullptr && m_out != nullptr, "" ); wxCHECK_RET( aText != nullptr && m_out != nullptr, "" );
double angle;
switch( aText->GetLabelSpinStyle() )
{
case LABEL_SPIN_STYLE::RIGHT: angle = 0.0; break;
case LABEL_SPIN_STYLE::UP: angle = 90.0; break;
case LABEL_SPIN_STYLE::LEFT: angle = 180.0; break;
case LABEL_SPIN_STYLE::BOTTOM: angle = 270.0; break;
default: wxFAIL; angle = 0.0; break;
}
m_out->Print( aNestLevel, "(%s %s", m_out->Print( aNestLevel, "(%s %s",
getTextTypeToken( aText->Type() ), getTextTypeToken( aText->Type() ),
m_out->Quotew( aText->GetText() ).c_str() ); m_out->Quotew( aText->GetText() ).c_str() );
if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) || ( aText->Type() == SCH_HIER_LABEL_T ) ) if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) || ( aText->Type() == SCH_HIER_LABEL_T ) )
m_out->Print( 0, " %s", getSheetPinShapeToken( aText->GetShape() ) ); m_out->Print( 0, " (shape %s)", getSheetPinShapeToken( aText->GetShape() ) );
if( aText->GetText().Length() < 50 ) if( aText->GetText().Length() < 50 )
{ {
m_out->Print( 0, " (at %s %s %s)", m_out->Print( 0, " (at %s %s %s)",
FormatInternalUnits( aText->GetPosition().x ).c_str(), FormatInternalUnits( aText->GetPosition().x ).c_str(),
FormatInternalUnits( aText->GetPosition().y ).c_str(), FormatInternalUnits( aText->GetPosition().y ).c_str(),
FormatAngle( aText->GetTextAngle() ).c_str() ); FormatAngle( angle * 10.0 ).c_str() );
} }
else else
{ {
@ -1167,7 +1112,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
FormatAngle( aText->GetTextAngle() ).c_str() ); FormatAngle( aText->GetTextAngle() ).c_str() );
} }
if( !aText->IsDefaultFormatting() ) if( !aText->IsDefaultFormatting() || ( aText->GetTextHeight() != GetDefaultTextSize() ) )
{ {
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
aText->Format( m_out, aNestLevel + 1, 0 ); aText->Format( m_out, aNestLevel + 1, 0 );

View File

@ -127,18 +127,7 @@ public:
private: private:
void loadHierarchy( SCH_SHEET* aSheet ); void loadHierarchy( SCH_SHEET* aSheet );
void loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadFile( const wxString& aFileName, SCH_SCREEN* aScreen ); void loadFile( const wxString& aFileName, SCH_SCREEN* aScreen );
SCH_SHEET* loadSheet( LINE_READER& aReader );
SCH_BITMAP* loadBitmap( LINE_READER& aReader );
SCH_JUNCTION* loadJunction( LINE_READER& aReader );
SCH_NO_CONNECT* loadNoConnect( LINE_READER& aReader );
SCH_LINE* loadWire( LINE_READER& aReader );
SCH_BUS_ENTRY_BASE* loadBusEntry( LINE_READER& aReader );
SCH_TEXT* loadText( LINE_READER& aReader );
SCH_COMPONENT* loadComponent( LINE_READER& aReader );
std::shared_ptr<BUS_ALIAS> loadBusAlias( LINE_READER& aReader, SCH_SCREEN* aScreen );
void saveSymbol( SCH_COMPONENT* aComponent, int aNestLevel ); void saveSymbol( SCH_COMPONENT* aComponent, int aNestLevel );
void saveField( SCH_FIELD* aField, int aNestLevel ); void saveField( SCH_FIELD* aField, int aNestLevel );

View File

@ -228,6 +228,7 @@ void SCH_SHEET::AddPin( SCH_SHEET_PIN* aSheetPin )
wxASSERT( aSheetPin != NULL ); wxASSERT( aSheetPin != NULL );
wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T ); wxASSERT( aSheetPin->Type() == SCH_SHEET_PIN_T );
aSheetPin->SetParent( this );
m_pins.push_back( aSheetPin ); m_pins.push_back( aSheetPin );
renumberPins(); renumberPins();
} }

View File

@ -7,13 +7,23 @@ atomic
background background
bezier bezier
bidirectional bidirectional
bitmap
bold bold
bottom bottom
bus
bus_entry
center center
circle circle
clock clock
clock_low clock_low
color color
comment
company
dash
dash_dot
data
date
dot
edge_clock_high edge_clock_high
effects effects
end end
@ -25,21 +35,26 @@ hide
hierarchical_label hierarchical_label
hint_alt_swap hint_alt_swap
hint_pin_swap hint_pin_swap
image
input input
input_low input_low
instances
inverted inverted
inverted_clock inverted_clock
italic italic
junction
justify justify
kicad_sch kicad_sch
kicad_symbol_lib kicad_symbol_lib
label label
left left
length length
lib_id
line line
mid mid
mirror mirror
name name
no_connect
non_logic non_logic
none none
number number
@ -50,7 +65,9 @@ outline
output_low output_low
unconnected unconnected
output output
page
passive passive
path
pin pin
pin_del pin_del
pin_names pin_names
@ -58,6 +75,7 @@ pin_numbers
pin_merge pin_merge
pin_rename pin_rename
polyline polyline
portrait
power power
power_in power_in
power_out power_out
@ -66,20 +84,31 @@ property_del
pts pts
radius radius
rectangle rectangle
reference
required required
rev
right right
scale
shape shape
sheet
size size
solid
start start
stroke stroke
symbol symbol
text text
thickness thickness
title
title_block
top top
tri_state tri_state
type type
unit
unspecified unspecified
uuid uuid
version version
width width
wire
xy xy
x
y