Work in progress

- !! Eeschema uses Eagle plugin for loading schematics (i.e. it does not
use KiCad format anymore)
- Fixed build errors
- Fixed a few crashes
- Code formatting
This commit is contained in:
Maciej Suminski 2017-05-08 17:11:14 +02:00
parent f5b2a2ea57
commit c727423979
9 changed files with 150 additions and 81 deletions

View File

@ -601,7 +601,9 @@ NODE_MAP MapChildren( wxXmlNode* currentNode )
NODE_MAP nodesMap; NODE_MAP nodesMap;
// Loop through all children mapping them in nodesMap // Loop through all children mapping them in nodesMap
currentNode = currentNode->GetChildren(); if( currentNode )
currentNode = currentNode->GetChildren();
while( currentNode ) while( currentNode )
{ {
// Create a new pair in the map // Create a new pair in the map

View File

@ -71,7 +71,7 @@ const wxString GedaPcbFootprintLibFileExtension( wxT( "fp" ) );
const wxString SchematicSymbolFileWildcard( _( "KiCad drawing symbol file (*.sym)|*.sym" ) ); const wxString SchematicSymbolFileWildcard( _( "KiCad drawing symbol file (*.sym)|*.sym" ) );
const wxString SchematicLibraryFileWildcard( _( "KiCad component library file (*.lib)|*.lib" ) ); const wxString SchematicLibraryFileWildcard( _( "KiCad component library file (*.lib)|*.lib" ) );
const wxString ProjectFileWildcard( _( "KiCad project files (*.pro)|*.pro" ) ); const wxString ProjectFileWildcard( _( "KiCad project files (*.pro)|*.pro" ) );
const wxString SchematicFileWildcard( _( "KiCad schematic files (*.sch)|*.sch" ) ); const wxString SchematicFileWildcard( _( "KiCad schematic files (*.sch)|*.sch|Eagle 6.x XML schematic file (*.sch)|*.sch" ) );
const wxString NetlistFileWildcard( _( "KiCad netlist files (*.net)|*.net" ) ); const wxString NetlistFileWildcard( _( "KiCad netlist files (*.net)|*.net" ) );
const wxString GerberFileWildcard( _( "Gerber files (*.pho)|*.pho" ) ); const wxString GerberFileWildcard( _( "Gerber files (*.pho)|*.pho" ) );
const wxString LegacyPcbFileWildcard( _( "KiCad printed circuit board files (*.brd)|*.brd" ) ); const wxString LegacyPcbFileWildcard( _( "KiCad printed circuit board files (*.brd)|*.brd" ) );

View File

@ -300,7 +300,7 @@ target_link_libraries( eeschema
) )
# the DSO (KIFACE) housing the main eeschema code: # the DSO (KIFACE) housing the main eeschema code:
add_library( eeschema_kiface STATIC add_library( eeschema_kiface SHARED
${EESCHEMA_SRCS} ${EESCHEMA_SRCS}
${EESCHEMA_COMMON_SRCS} ${EESCHEMA_COMMON_SRCS}
) )

View File

@ -315,7 +315,7 @@ 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_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) );
try try
{ {

View File

@ -21,7 +21,7 @@
# or you may write to the Free Software Foundation, Inc., # or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
find_package(Boost COMPONENTS unit_test_framework REQUIRED) find_package( Boost COMPONENTS unit_test_framework REQUIRED )
include_directories( BEFORE ${INC_BEFORE} ) include_directories( BEFORE ${INC_BEFORE} )
include_directories( include_directories(
@ -32,7 +32,7 @@ include_directories(
add_executable( qa_eagle_plugin add_executable( qa_eagle_plugin
test_module.cpp test_module.cpp
test_basic.cpp test_basic.cpp
) )
add_dependencies( qa_eagle_plugin common eeschema_kiface ) add_dependencies( qa_eagle_plugin common eeschema_kiface )
@ -41,4 +41,4 @@ target_link_libraries( qa_eagle_plugin
eeschema_kiface eeschema_kiface
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
${wxWidgets_LIBRARIES} ${wxWidgets_LIBRARIES}
) )

View File

@ -28,6 +28,12 @@
#include <sch_sheet.h> #include <sch_sheet.h>
#include <sch_eagle_plugin.h> #include <sch_eagle_plugin.h>
#include <class_sch_screen.h>
#include <class_libentry.h>
#include <lib_circle.h>
#include <lib_rectangle.h>
#include <lib_polyline.h>
#include <eagle_parser.h> #include <eagle_parser.h>
using namespace std; using namespace std;
@ -75,15 +81,15 @@ void kicadLayer( int aEagleLayer )
switch( aEagleLayer ) switch( aEagleLayer )
{ {
case 90: break; case 90: break;
case 91: break; case 91: break;
case 92: break; case 92: break;
case 93: break; case 93: break;
case 94: break; case 94: break;
case 95: break; case 95: break;
case 96: break; case 96: break;
case 97: break; case 97: break;
case 98: break; case 98: break;
} }
} }
@ -136,7 +142,7 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway,
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ), fn.GetFullPath() ) ); THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ), fn.GetFullPath() ) );
// Delete on exception, if I own m_rootSheet, according to aAppendToMe // Delete on exception, if I own m_rootSheet, according to aAppendToMe
unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet ); unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
if( aAppendToMe ) if( aAppendToMe )
{ {
@ -148,6 +154,14 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway,
m_rootSheet->SetFileName( aFileName ); m_rootSheet->SetFileName( aFileName );
} }
// TODO change to loadSheet, so it can handle multiple sheets
if( !m_rootSheet->GetScreen() )
{
SCH_SCREEN* screen = new SCH_SCREEN( aKiway );
screen->SetFileName( aFileName );
m_rootSheet->SetScreen( screen );
}
// Retrieve the root as current node // Retrieve the root as current node
wxXmlNode* currentNode = xmlDocument.GetRoot(); wxXmlNode* currentNode = xmlDocument.GetRoot();
@ -250,7 +264,7 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
// From the DTD: "Buses receive names which determine which signals they include. // From the DTD: "Buses receive names which determine which signals they include.
// A bus is a drawing object. It does not create any electrical connections. // A bus is a drawing object. It does not create any electrical connections.
// These are always created by means of the nets and their names." // These are always created by means of the nets and their names."
wxXmlNode* busNode = sheetChildren["busses"]->GetChildren(); wxXmlNode* busNode = getChildrenNodes( sheetChildren, "busses" );
while( busNode ) while( busNode )
{ {
@ -266,7 +280,7 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
// Loop through all nets // Loop through all nets
// From the DTD: "Net is an electrical connection in a schematic." // From the DTD: "Net is an electrical connection in a schematic."
wxXmlNode* netNode = sheetChildren["nets"]->GetChildren(); wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
while( netNode ) while( netNode )
{ {
@ -282,7 +296,7 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
} }
// Loop through all instances // Loop through all instances
wxXmlNode* instanceNode = sheetChildren["instances"]->GetChildren(); wxXmlNode* instanceNode = getChildrenNodes( sheetChildren, "instances" );
while( instanceNode ) while( instanceNode )
{ {
@ -291,7 +305,7 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
} }
// Loop through all moduleinsts // Loop through all moduleinsts
wxXmlNode* moduleinstNode = sheetChildren["moduleinsts"]->GetChildren(); wxXmlNode* moduleinstNode = getChildrenNodes( sheetChildren, "moduleinsts" );
while( moduleinstNode ) while( moduleinstNode )
{ {
@ -305,7 +319,13 @@ void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
// wxString description = description->GetNodeContent(); // wxString description = description->GetNodeContent();
// TODO: do something with the plain // TODO: do something with the plain
// wxXmlNode* plain = sheetChildren["plain"]; wxXmlNode* plainNode = sheetChildren["plain"];
while( plainNode )
{
loadSegments( plainNode );
plainNode = plainNode->GetNext();
}
} }
@ -313,6 +333,8 @@ void SCH_EAGLE_PLUGIN::loadSegments( wxXmlNode* aSegmentsNode )
{ {
// Loop through all segments // Loop through all segments
wxXmlNode* currentSegment = aSegmentsNode->GetChildren(); wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
SCH_SCREEN* screen = m_rootSheet->GetScreen();
//wxCHECK( screen, [>void<] );
while( currentSegment ) while( currentSegment )
{ {
@ -356,11 +378,21 @@ void SCH_EAGLE_PLUGIN::loadSegments( wxXmlNode* aSegmentsNode )
} }
else if( nodeName == "wire" ) else if( nodeName == "wire" )
{ {
loadWire( segmentAttribute ); screen->Append( loadWire( segmentAttribute ) );
}
else if( nodeName == "segment" )
{
loadSegments( segmentAttribute );
}
else if( nodeName == "text" )
{
// TODO
//loadSegments( segmentAttribute );
} }
else // DEFAULT else // DEFAULT
{ {
THROW_IO_ERROR( wxString::Format( _( "XML node '%s' unknown" ), nodeName ) ); // TODO uncomment
//THROW_IO_ERROR( wxString::Format( _( "XML node '%s' unknown" ), nodeName ) );
} }
// Get next segment attribute // Get next segment attribute
@ -374,24 +406,15 @@ void SCH_EAGLE_PLUGIN::loadSegments( wxXmlNode* aSegmentsNode )
SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode ) SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode )
{ {
std::unique_ptr< SCH_LINE > wire( new SCH_LINE ); std::unique_ptr<SCH_LINE> wire( new SCH_LINE );
wxString layer = aWireNode->GetAttribute( "layer" ); // REQUIRED auto ewire = EWIRE( aWireNode );
wxString width = aWireNode->GetAttribute( "width" ); // REQUIRED
wxString x1 = aWireNode->GetAttribute( "x1" ); // REQUIRED
wxString x2 = aWireNode->GetAttribute( "x2" ); // REQUIRED
wxString y1 = aWireNode->GetAttribute( "y1" ); // REQUIRED
wxString y2 = aWireNode->GetAttribute( "y2" ); // REQUIRED
wxString cap = aWireNode->GetAttribute( "cap", "round" ); // Defaults to "round"
wxString curve = aWireNode->GetAttribute( "curve", "0" ); // Defaults to "0"
wxString style = aWireNode->GetAttribute( "style", "continuous" ); // Defaults to "continuous"
// wxString extent = aWireNode->GetAttribute( "extent" ); // Non-required, defaults to NOTHING
// TODO: layer map? // TODO: layer map?
// wire->SetLayer( layerMap( layer ) ); // wire->SetLayer( layerMap( layer ) );
// if( strCompare( "Wire", line, &line ) ) // if( strCompare( "Wire", line, &line ) )
// wire->SetLayer( LAYER_WIRE ); wire->SetLayer( LAYER_WIRE );
// else if( strCompare( "Bus", line, &line ) ) // else if( strCompare( "Bus", line, &line ) )
// wire->SetLayer( LAYER_BUS ); // wire->SetLayer( LAYER_BUS );
// else if( strCompare( "Notes", line, &line ) ) // else if( strCompare( "Notes", line, &line ) )
@ -401,16 +424,15 @@ SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode )
wxPoint begin, end; wxPoint begin, end;
begin.x = wxAtoi( x1 ); begin.x = ewire.x1;
begin.y = wxAtoi( y1 ); begin.y = ewire.y1;
end.x = wxAtoi( x2 ); end.x = ewire.x2;
end.y = wxAtoi( y2 ); end.y = ewire.y2;
wire->SetStartPoint( begin ); wire->SetStartPoint( begin );
wire->SetEndPoint( end ); wire->SetEndPoint( end );
return wire.release(); return wire.release();
} }
@ -477,39 +499,39 @@ LIB_PART* SCH_EAGLE_PLUGIN::loadSymbol( wxXmlNode* aSymbolNode )
if( nodeName == "description" ) if( nodeName == "description" )
{ {
// TODO // TODO
wxASSERT_MSG( false, "'description' nodes are not implemented yet" ); //wxASSERT_MSG( false, "'description' nodes are not implemented yet" );
} }
else if( nodeName == "dimension" ) else if( nodeName == "dimension" )
{ {
// TODO // TODO
wxASSERT_MSG( false, "'description' nodes are not implemented yet" ); //wxASSERT_MSG( false, "'description' nodes are not implemented yet" );
} }
else if( nodeName == "frame" ) else if( nodeName == "frame" )
{ {
} }
else if( nodeName == "circle" ) else if( nodeName == "circle" )
{ {
part->AddDrawItem( loadCircle( part, currentNode ) ); part->AddDrawItem( loadCircle( part.get(), currentNode ) );
} }
else if( nodeName == "pin" ) else if( nodeName == "pin" )
{ {
part->AddDrawItem( loadPin( part, currentNode ) ); // part->AddDrawItem( loadPin( part, currentNode ) );
} }
else if( nodeName == "polygon" ) else if( nodeName == "polygon" )
{ {
part->AddDrawItem( loadPolyline( part, currentNode ) ); //part->AddDrawItem( loadPolygon( part.get(), currentNode ) );
} }
else if( nodeName == "rectangle" ) else if( nodeName == "rectangle" )
{ {
part->AddDrawItem( loadRectangle( part, currentNode ) ); part->AddDrawItem( loadRectangle( part.get(), currentNode ) );
} }
else if( nodeName == "text" ) else if( nodeName == "text" )
{ {
part->AddDrawItem( loadText( part, currentNode ) ); // part->AddDrawItem( loadText( part, currentNode ) );
} }
else if( nodeName == "wire" ) else if( nodeName == "wire" )
{ {
part->AddDrawItem( loadPolyline( part, currentNode ) ); // part->AddDrawItem( loadPolyline( part, currentNode ) );
} }
currentNode = currentNode->GetNext(); currentNode = currentNode->GetNext();
@ -521,28 +543,59 @@ LIB_PART* SCH_EAGLE_PLUGIN::loadSymbol( wxXmlNode* aSymbolNode )
LIB_CIRCLE* SCH_EAGLE_PLUGIN::loadCircle( LIB_PART* aPart, wxXmlNode* aCircleNode ) LIB_CIRCLE* SCH_EAGLE_PLUGIN::loadCircle( LIB_PART* aPart, wxXmlNode* aCircleNode )
{ {
unique_ptr< LIB_CIRCLE > circle( new LIB_CIRCLE( aPart.get() ) ); // Parse the circle properties
ECIRCLE c( aCircleNode );
int layer = wxAtoi( aCircleNode->GetAttribute( "layer" ) ); unique_ptr<LIB_CIRCLE> circle( new LIB_CIRCLE( aPart ) );
int x; circle->SetPosition( wxPoint( c.x, c.y ) );
int y; circle->SetRadius( c.radius );
int radius; circle->SetWidth( c.width );
int width;
aCircleNode->GetAttribute( "x" ).ToDouble( &x );
aCircleNode->GetAttribute( "y" ).ToDouble( &y );
aCircleNode->GetAttribute( "radius" ).ToDouble( &radius );
aCircleNode->GetAttribute( "width" ).ToDouble( &width );
circle->SetPosition( wxPoint( x, y ) );
circle->SetRadius( radius );
circle->SetWidth( width ;
return circle.release(); return circle.release();
} }
LIB_RECTANGLE* SCH_EAGLE_PLUGIN::loadRectangle( LIB_PART* aPart, wxXmlNode* aRectNode )
{
ERECT rect( aRectNode );
unique_ptr<LIB_RECTANGLE> rectangle( new LIB_RECTANGLE( aPart ) );
rectangle->SetPosition( wxPoint( rect.x1, rect.y1 ) );
rectangle->SetEnd( wxPoint( rect.x2, rect.y2 ) );
// TODO: Manage rotation
return rectangle.release();
}
LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadPolyLine( LIB_PART* aPart, wxXmlNode* aRectNode )
{
std::unique_ptr< LIB_POLYLINE > polyLine( new LIB_POLYLINE( aPart ) );
/*int points = parseInt( aReader, line, &line );
polyLine->SetUnit( parseInt( aReader, line, &line ) );
polyLine->SetConvert( parseInt( aReader, line, &line ) );
polyLine->SetWidth( parseInt( aReader, line, &line ) );
wxPoint pt;
for( int i = 0; i < points; i++ )
{
pt.x = parseInt( aReader, line, &line );
pt.y = parseInt( aReader, line, &line );
polyLine->AddPoint( pt );
}
if( *line != 0 )
polyLine->SetFillMode( parseFillMode( aReader, line, &line ) );*/
return polyLine.release();
}
void SCH_EAGLE_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway, void SCH_EAGLE_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {

View File

@ -26,23 +26,26 @@
#include <sch_line.h> #include <sch_line.h>
#include <sch_io_mgr.h> #include <sch_io_mgr.h>
// class KIWAY; class KIWAY;
// class LINE_READER; class LINE_READER;
// class SCH_SCREEN; class SCH_SCREEN;
// class SCH_SHEET; class SCH_SHEET;
// class SCH_BITMAP; class SCH_BITMAP;
// class SCH_JUNCTION; class SCH_JUNCTION;
// class SCH_NO_CONNECT; class SCH_NO_CONNECT;
// class SCH_LINE; class SCH_LINE;
// class SCH_BUS_ENTRY_BASE;s class SCH_BUS_ENTRY_BASE;
// class SCH_TEXT; class SCH_TEXT;
// class SCH_COMPONENT; class SCH_COMPONENT;
// class SCH_FIELD; class SCH_FIELD;
// class PROPERTIES; class PROPERTIES;
// class SCH_EAGLE_PLUGIN_CACHE; class SCH_EAGLE_PLUGIN_CACHE;
// class LIB_PART; class LIB_PART;
// class PART_LIB; class PART_LIB;
// class LIB_ALIAS; class LIB_ALIAS;
class LIB_CIRCLE;
class LIB_RECTANGLE;
class LIB_POLYLINE;
/** /**
@ -114,6 +117,9 @@ private:
void loadLibrary( wxXmlNode* aLibraryNode ); void loadLibrary( wxXmlNode* aLibraryNode );
LIB_PART* loadSymbol( wxXmlNode* aSymbolNode ); LIB_PART* loadSymbol( wxXmlNode* aSymbolNode );
LIB_CIRCLE* loadCircle( LIB_PART* aPart, wxXmlNode* aCircleNode );
LIB_RECTANGLE* loadRectangle( LIB_PART* aPart, wxXmlNode* aRectNode );
LIB_POLYLINE* loadPolyLine( LIB_PART* aPart, wxXmlNode* aRectNode );
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.. SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
wxString m_version; ///< Eagle file version. wxString m_version; ///< Eagle file version.

View File

@ -24,6 +24,7 @@
*/ */
#include <richio.h> #include <richio.h>
#include <import_export.h>
#include <map> #include <map>
@ -73,6 +74,7 @@ public:
* @return the plugin corresponding to aFileType or NULL if not found. * @return the plugin corresponding to aFileType or NULL if not found.
* Caller owns the returned object, and must call PluginRelease when done using it. * Caller owns the returned object, and must call PluginRelease when done using it.
*/ */
APIEXPORT
static SCH_PLUGIN* FindPlugin( SCH_FILE_T aFileType ); static SCH_PLUGIN* FindPlugin( SCH_FILE_T aFileType );
/** /**

View File

@ -48,6 +48,12 @@ class MODULE;
typedef std::unordered_map<string, wxXmlNode*> NODE_MAP; typedef std::unordered_map<string, wxXmlNode*> NODE_MAP;
typedef std::map<string, MODULE*> MODULE_MAP; typedef std::map<string, MODULE*> MODULE_MAP;
static inline wxXmlNode* getChildrenNodes( NODE_MAP& aMap, const string& aName )
{
auto it = aMap.find( aName );
return it == aMap.end() ? nullptr : it->second->GetChildren();
}
/** /**
* Class XML_PARSER_ERROR * Class XML_PARSER_ERROR