2017-02-27 10:07:52 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017 CERN
|
|
|
|
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
|
|
|
|
*
|
|
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <properties.h>
|
|
|
|
|
|
|
|
#include <wx/filename.h>
|
2017-03-09 12:49:24 +00:00
|
|
|
#include <memory>
|
2017-05-08 14:10:23 +00:00
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
2017-02-27 10:07:52 +00:00
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
#include <sch_sheet.h>
|
2017-02-27 10:07:52 +00:00
|
|
|
#include <sch_eagle_plugin.h>
|
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
#include <class_sch_screen.h>
|
|
|
|
#include <class_libentry.h>
|
|
|
|
#include <lib_circle.h>
|
|
|
|
#include <lib_rectangle.h>
|
|
|
|
#include <lib_polyline.h>
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
#include <eagle_parser.h>
|
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP mapChildren( wxXmlNode* aCurrentNode )
|
2017-05-08 14:10:23 +00:00
|
|
|
{
|
|
|
|
// Map node_name -> node_pointer
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP nodesMap;
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// Loop through all children mapping them in nodesMap
|
2017-05-08 14:27:11 +00:00
|
|
|
aCurrentNode = aCurrentNode->GetChildren();
|
|
|
|
while( aCurrentNode )
|
2017-05-08 14:10:23 +00:00
|
|
|
{
|
|
|
|
// Create a new pair in the map
|
|
|
|
// key: current node name
|
|
|
|
// value: current node pointer
|
2017-05-08 14:27:11 +00:00
|
|
|
nodesMap[aCurrentNode->GetName().ToStdString()] = aCurrentNode;
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// Get next child
|
2017-05-08 14:27:11 +00:00
|
|
|
aCurrentNode = aCurrentNode->GetNext();
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nodesMap;
|
|
|
|
}
|
|
|
|
|
2017-06-18 11:25:09 +00:00
|
|
|
int countChildren( wxXmlNode* aCurrentNode, std::string name)
|
|
|
|
{
|
|
|
|
// Map node_name -> node_pointer
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
// Loop through all children counting them if they match the given name
|
|
|
|
aCurrentNode = aCurrentNode->GetChildren();
|
|
|
|
while( aCurrentNode )
|
|
|
|
{
|
|
|
|
if(aCurrentNode->GetName().ToStdString() == name) count++;
|
|
|
|
// Get next child
|
|
|
|
aCurrentNode = aCurrentNode->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
void kicadLayer( int aEagleLayer )
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Layers in Kicad schematics are not actually layers, but abstract groups mainly used to
|
|
|
|
* decide item colours.
|
|
|
|
*
|
|
|
|
* <layers>
|
|
|
|
* <layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="91" name="Nets" color="2" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="92" name="Busses" color="1" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="93" name="Pins" color="2" fill="1" visible="no" active="yes"/>
|
|
|
|
* <layer number="94" name="Symbols" color="4" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="95" name="Names" color="7" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="96" name="Values" color="7" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="97" name="Info" color="7" fill="1" visible="yes" active="yes"/>
|
|
|
|
* <layer number="98" name="Guide" color="6" fill="1" visible="yes" active="yes"/>
|
|
|
|
* </layers>
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch( aEagleLayer )
|
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
case 90: break;
|
|
|
|
case 91: break;
|
|
|
|
case 92: break;
|
|
|
|
case 93: break;
|
|
|
|
case 94: break;
|
|
|
|
case 95: break;
|
|
|
|
case 96: break;
|
|
|
|
case 97: break;
|
|
|
|
case 98: break;
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-27 10:07:52 +00:00
|
|
|
|
|
|
|
SCH_EAGLE_PLUGIN::SCH_EAGLE_PLUGIN()
|
|
|
|
{
|
2017-03-09 12:49:24 +00:00
|
|
|
m_rootSheet = nullptr;
|
2017-02-27 10:07:52 +00:00
|
|
|
}
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-02-27 10:07:52 +00:00
|
|
|
SCH_EAGLE_PLUGIN::~SCH_EAGLE_PLUGIN()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-02-27 10:07:52 +00:00
|
|
|
const wxString SCH_EAGLE_PLUGIN::GetName() const
|
|
|
|
{
|
|
|
|
return wxT( "EAGLE" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const wxString SCH_EAGLE_PLUGIN::GetFileExtension() const
|
|
|
|
{
|
|
|
|
return wxT( "sch" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int SCH_EAGLE_PLUGIN::GetModifyHash() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway,
|
|
|
|
SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties )
|
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
// TODO: Handle Kiway and uncomment next line.
|
2017-03-09 12:49:24 +00:00
|
|
|
// wxASSERT( !aFileName || aKiway != NULL );
|
2017-02-27 10:07:52 +00:00
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
// Load the document
|
|
|
|
wxXmlDocument xmlDocument;
|
2017-02-27 10:07:52 +00:00
|
|
|
wxFileName fn = aFileName;
|
2017-06-18 11:25:09 +00:00
|
|
|
m_kiway = aKiway;
|
2017-02-27 10:07:52 +00:00
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
if( !xmlDocument.Load( fn.GetFullPath() ) )
|
2017-03-01 22:57:12 +00:00
|
|
|
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ), fn.GetFullPath() ) );
|
2017-02-27 10:07:52 +00:00
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
// Delete on exception, if I own m_rootSheet, according to aAppendToMe
|
2017-05-08 15:11:14 +00:00
|
|
|
unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
|
|
|
if( aAppendToMe )
|
|
|
|
{
|
|
|
|
m_rootSheet = aAppendToMe->GetRootSheet();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_rootSheet = new SCH_SHEET();
|
|
|
|
m_rootSheet->SetFileName( aFileName );
|
|
|
|
}
|
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
// 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 );
|
|
|
|
}
|
|
|
|
|
2017-03-09 12:49:24 +00:00
|
|
|
// Retrieve the root as current node
|
|
|
|
wxXmlNode* currentNode = xmlDocument.GetRoot();
|
|
|
|
|
|
|
|
// If the attribute is found, store the Eagle version;
|
|
|
|
// otherwise, store the dummy "0.0" version.
|
2017-05-08 14:10:23 +00:00
|
|
|
m_version = currentNode->GetAttribute( "version", "0.0" );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// Map all children into a readable dictionary
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP children = mapChildren( currentNode );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// TODO: handle compatibility nodes
|
|
|
|
// wxXmlNode* compatibility = children["compatibility"];
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// Load drawing
|
|
|
|
loadDrawing( children["drawing"] );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
|
|
|
deleter.release();
|
|
|
|
return m_rootSheet;
|
2017-02-27 10:07:52 +00:00
|
|
|
}
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadDrawing( wxXmlNode* aDrawingNode )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
// Map all children into a readable dictionary
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP drawingChildren = mapChildren( aDrawingNode );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// Board nodes should not appear in .sch files
|
|
|
|
// wxXmlNode* board = drawingChildren["board"]
|
|
|
|
|
|
|
|
// TODO: handle grid nodes
|
|
|
|
// wxXmlNode* grid = drawingChildren["grid"]
|
|
|
|
|
|
|
|
// TODO: handle layers nodes
|
|
|
|
// wxXmlNode* layers = drawingChildren["layers"]
|
|
|
|
|
|
|
|
// TODO: handle library nodes
|
|
|
|
// wxXmlNode* library = drawingChildren["library"]
|
|
|
|
|
|
|
|
// TODO: handle settings nodes
|
|
|
|
// wxXmlNode* settings = drawingChildren["settings"]
|
|
|
|
|
|
|
|
// Load schematic
|
|
|
|
loadSchematic( drawingChildren["schematic"] );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
|
|
|
{
|
|
|
|
// Map all children into a readable dictionary
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP schematicChildren = mapChildren( aSchematicNode );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// TODO : handle classes nodes
|
2017-05-08 14:27:11 +00:00
|
|
|
//wxXmlNode* classes = schematicChildren["classes"];
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// TODO : handle description nodes
|
|
|
|
// wxXmlNode* description = schematicChildren["description"];
|
|
|
|
|
|
|
|
// TODO : handle errors nodes
|
|
|
|
// wxXmlNode* errors = schematicChildren["errors"];
|
|
|
|
|
|
|
|
// TODO : handle modules nodes
|
|
|
|
// wxXmlNode* modules = schematicChildren["modules"];
|
|
|
|
|
|
|
|
// TODO : handle parts nodes
|
|
|
|
// wxXmlNode* parts = schematicChildren["parts"];
|
|
|
|
|
|
|
|
// TODO : handle variantdefs nodes
|
|
|
|
// wxXmlNode* variantdefs = schematicChildren["variantdefs"];
|
|
|
|
|
|
|
|
// TODO: handle attributes node
|
|
|
|
// wxXmlNode* attributes = schematicChildren["attributes"];
|
|
|
|
// Possible children: constant, display, font, layer, name, ratio, rot, size, value, x, y
|
|
|
|
|
|
|
|
// Loop through all the libraries
|
|
|
|
wxXmlNode* libraryNode = schematicChildren["libraries"]->GetChildren();
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( libraryNode )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
loadLibrary( libraryNode );
|
|
|
|
libraryNode = libraryNode->GetNext();
|
|
|
|
}
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// Loop through all the sheets
|
|
|
|
wxXmlNode* sheetNode = schematicChildren["sheets"]->GetChildren();
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-06-18 11:25:09 +00:00
|
|
|
int sheet_count = countChildren(schematicChildren["sheets"], "sheet" );
|
|
|
|
|
|
|
|
// If eagle schematic has multiple sheets.
|
|
|
|
|
|
|
|
if(sheet_count > 1){
|
|
|
|
// TODO: set up a heirachical sheet for each Eagle sheet.
|
|
|
|
int x, y, i;
|
|
|
|
i=1;
|
|
|
|
x = 1;
|
|
|
|
y = 1;
|
|
|
|
|
|
|
|
while( sheetNode ){
|
|
|
|
wxPoint pos = wxPoint(x*1000, y*1000);
|
|
|
|
std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET(pos) );
|
|
|
|
SCH_SCREEN* screen = new SCH_SCREEN(m_kiway) ;
|
|
|
|
|
|
|
|
sheet->SetTimeStamp( GetNewTimeStamp() );
|
|
|
|
sheet->SetParent( m_rootSheet->GetScreen() );
|
|
|
|
sheet->SetScreen( screen );
|
|
|
|
|
|
|
|
m_currentSheet = sheet.get();
|
|
|
|
loadSheet( sheetNode );
|
|
|
|
m_rootSheet->GetScreen()->Append(sheet.release());
|
|
|
|
|
|
|
|
sheetNode = sheetNode->GetNext();
|
|
|
|
x+=2;
|
|
|
|
if(x>10)
|
|
|
|
{
|
|
|
|
x = 1;
|
|
|
|
y+=2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
while( sheetNode )
|
|
|
|
{
|
|
|
|
m_currentSheet = m_rootSheet;
|
|
|
|
loadSheet( sheetNode );
|
|
|
|
sheetNode = sheetNode->GetNext();
|
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
2017-06-18 11:25:09 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-06-18 11:25:09 +00:00
|
|
|
void SCH_EAGLE_PLUGIN::loadSheet( wxXmlNode* aSheetNode )
|
2017-05-08 14:10:23 +00:00
|
|
|
{
|
|
|
|
// Map all children into a readable dictionary
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP sheetChildren = mapChildren( aSheetNode );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-06-18 11:25:09 +00:00
|
|
|
// Get description node
|
|
|
|
|
|
|
|
wxXmlNode* descriptionNode = getChildrenNodes( sheetChildren, "description" );
|
|
|
|
if( descriptionNode )
|
|
|
|
{
|
|
|
|
wxString des = descriptionNode->GetContent();
|
|
|
|
m_currentSheet->SetName(des);
|
|
|
|
|
|
|
|
std::string filename = des.ToStdString();
|
|
|
|
ReplaceIllegalFileNameChars(&filename);
|
|
|
|
replace(filename.begin(),filename.end(), ' ', '_');
|
|
|
|
|
|
|
|
wxString fn = wxString(filename);
|
|
|
|
m_currentSheet->SetFileName(fn);
|
|
|
|
wxFileName fileName = m_currentSheet->GetFileName();
|
|
|
|
m_currentSheet->GetScreen()->SetFileName( fileName.GetFullPath() );
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
// Loop through all busses
|
|
|
|
// 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.
|
|
|
|
// These are always created by means of the nets and their names."
|
2017-05-08 15:11:14 +00:00
|
|
|
wxXmlNode* busNode = getChildrenNodes( sheetChildren, "busses" );
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( busNode )
|
|
|
|
{
|
|
|
|
// Get the bus name
|
|
|
|
wxString busName = busNode->GetAttribute( "name" );
|
|
|
|
|
|
|
|
// Load segments of this bus
|
|
|
|
loadSegments( busNode );
|
|
|
|
|
|
|
|
// Get next bus
|
|
|
|
busNode = busNode->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop through all nets
|
|
|
|
// From the DTD: "Net is an electrical connection in a schematic."
|
2017-05-08 15:11:14 +00:00
|
|
|
wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( netNode )
|
|
|
|
{
|
|
|
|
// Get the net name and class
|
|
|
|
wxString netName = netNode->GetAttribute( "name" );
|
|
|
|
wxString netClass = netNode->GetAttribute( "class" );
|
|
|
|
|
|
|
|
// Load segments of this net
|
|
|
|
loadSegments( netNode );
|
|
|
|
|
|
|
|
// Get next net
|
|
|
|
netNode = netNode->GetNext();
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// Loop through all instances
|
2017-05-08 15:11:14 +00:00
|
|
|
wxXmlNode* instanceNode = getChildrenNodes( sheetChildren, "instances" );
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( instanceNode )
|
|
|
|
{
|
|
|
|
loadInstance( instanceNode );
|
|
|
|
instanceNode = instanceNode->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop through all moduleinsts
|
2017-05-08 15:11:14 +00:00
|
|
|
wxXmlNode* moduleinstNode = getChildrenNodes( sheetChildren, "moduleinsts" );
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( moduleinstNode )
|
|
|
|
{
|
|
|
|
loadModuleinst( moduleinstNode );
|
|
|
|
moduleinstNode = moduleinstNode->GetNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: do something with the description
|
|
|
|
// wxXmlNode* description = sheetChildren["description"];
|
|
|
|
// wxString language = description->GetAttribute( "language", "en" ); // Defaults to "en"
|
|
|
|
// wxString description = description->GetNodeContent();
|
|
|
|
|
|
|
|
// TODO: do something with the plain
|
2017-05-08 15:11:14 +00:00
|
|
|
wxXmlNode* plainNode = sheetChildren["plain"];
|
|
|
|
|
|
|
|
while( plainNode )
|
|
|
|
{
|
|
|
|
loadSegments( plainNode );
|
|
|
|
plainNode = plainNode->GetNext();
|
|
|
|
}
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadSegments( wxXmlNode* aSegmentsNode )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
// Loop through all segments
|
|
|
|
wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
|
2017-05-08 15:11:14 +00:00
|
|
|
SCH_SCREEN* screen = m_rootSheet->GetScreen();
|
|
|
|
//wxCHECK( screen, [>void<] );
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( currentSegment )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
// Loop through all segment children
|
|
|
|
wxXmlNode* segmentAttribute = currentSegment->GetChildren();
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( segmentAttribute )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
wxString nodeName = segmentAttribute->GetName();
|
|
|
|
|
|
|
|
if( nodeName == "junction" )
|
|
|
|
{
|
|
|
|
// TODO: handle junctions attributes
|
|
|
|
segmentAttribute->GetAttribute( "x" );
|
|
|
|
segmentAttribute->GetAttribute( "y" );
|
|
|
|
}
|
|
|
|
else if( nodeName == "label" )
|
|
|
|
{
|
|
|
|
// TODO: handle labels attributes
|
|
|
|
segmentAttribute->GetAttribute( "x" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "y" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "size" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "layer" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "font" ); // Defaults to "proportional"
|
|
|
|
segmentAttribute->GetAttribute( "ratio" ); // Defaults to "8"
|
|
|
|
segmentAttribute->GetAttribute( "rot" ); // Defaults to "R0"
|
|
|
|
segmentAttribute->GetAttribute( "xref" ); // Defaults to "no"
|
|
|
|
}
|
|
|
|
else if( nodeName == "pinref" )
|
|
|
|
{
|
|
|
|
// TODO: handle pinref attributes
|
|
|
|
segmentAttribute->GetAttribute( "gate" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "part" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "pin" ); // REQUIRED
|
|
|
|
}
|
|
|
|
else if( nodeName == "portref" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:10:23 +00:00
|
|
|
// TODO: handle portref attributes
|
|
|
|
segmentAttribute->GetAttribute( "moduleinst" ); // REQUIRED
|
|
|
|
segmentAttribute->GetAttribute( "port" ); // REQUIRED
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "wire" )
|
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
screen->Append( loadWire( segmentAttribute ) );
|
|
|
|
}
|
|
|
|
else if( nodeName == "segment" )
|
|
|
|
{
|
|
|
|
loadSegments( segmentAttribute );
|
|
|
|
}
|
|
|
|
else if( nodeName == "text" )
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
//loadSegments( segmentAttribute );
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
|
|
|
else // DEFAULT
|
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
// TODO uncomment
|
|
|
|
//THROW_IO_ERROR( wxString::Format( _( "XML node '%s' unknown" ), nodeName ) );
|
2017-05-08 14:10:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get next segment attribute
|
|
|
|
segmentAttribute = segmentAttribute->GetNext();
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
currentSegment = currentSegment->GetNext();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCH_LINE* SCH_EAGLE_PLUGIN::loadWire( wxXmlNode* aWireNode )
|
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
std::unique_ptr<SCH_LINE> wire( new SCH_LINE );
|
|
|
|
|
|
|
|
auto ewire = EWIRE( aWireNode );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// TODO: layer map?
|
|
|
|
// wire->SetLayer( layerMap( layer ) );
|
|
|
|
|
|
|
|
// if( strCompare( "Wire", line, &line ) )
|
2017-05-08 15:11:14 +00:00
|
|
|
wire->SetLayer( LAYER_WIRE );
|
2017-05-08 14:10:23 +00:00
|
|
|
// else if( strCompare( "Bus", line, &line ) )
|
|
|
|
// wire->SetLayer( LAYER_BUS );
|
|
|
|
// else if( strCompare( "Notes", line, &line ) )
|
|
|
|
// wire->SetLayer( LAYER_NOTES );
|
|
|
|
// else
|
|
|
|
// SCH_PARSE_ERROR( "invalid line type", aReader, line );
|
|
|
|
|
|
|
|
wxPoint begin, end;
|
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
begin.x = ewire.x1;
|
|
|
|
begin.y = ewire.y1;
|
|
|
|
end.x = ewire.x2;
|
|
|
|
end.y = ewire.y2;
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
wire->SetStartPoint( begin );
|
|
|
|
wire->SetEndPoint( end );
|
|
|
|
|
|
|
|
return wire.release();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadModuleinst( wxXmlNode* aModuleinstNode )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode )
|
|
|
|
{
|
|
|
|
// Read the library name
|
|
|
|
wxString libName = aLibraryNode->GetAttribute( "name" );
|
|
|
|
|
|
|
|
// Query all children and map them into a readable dictionary
|
2017-05-08 14:27:11 +00:00
|
|
|
NODE_MAP libraryChildren = mapChildren( aLibraryNode );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// TODO: Do something with the description
|
|
|
|
// wxXmlNode* libraryChildren["description"];
|
|
|
|
|
|
|
|
// Loop through the devicesets and load each of them
|
2017-05-08 14:27:11 +00:00
|
|
|
// wxXmlNode* devicesetNode = libraryChildren["devicesets"]->GetChildren();
|
2017-05-08 14:10:23 +00:00
|
|
|
// while( devicesetNode )
|
|
|
|
// {
|
|
|
|
// loadDeviceset( devicesetNode );
|
|
|
|
// devicesetNode = devicesetNode->GetNext();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Loop through the packages and load each of them
|
2017-05-08 14:27:11 +00:00
|
|
|
// wxXmlNode* packageNode = libraryChildren["packages"]->GetChildren();
|
2017-05-08 14:10:23 +00:00
|
|
|
// while( packageNode )
|
|
|
|
// {
|
|
|
|
// loadPackage( packageNode );
|
|
|
|
// packageNode = packageNode->GetNext();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Loop through the symbols and load each of them
|
|
|
|
wxXmlNode* symbolNode = libraryChildren["symbols"]->GetChildren();
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
while( symbolNode )
|
|
|
|
{
|
|
|
|
loadSymbol( symbolNode );
|
|
|
|
symbolNode = symbolNode->GetNext();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LIB_PART* SCH_EAGLE_PLUGIN::loadSymbol( wxXmlNode* aSymbolNode )
|
|
|
|
{
|
|
|
|
// Create a new part with the symbol name
|
|
|
|
wxString symbolName = aSymbolNode->GetAttribute( "name" );
|
2017-05-08 14:27:11 +00:00
|
|
|
std::unique_ptr<LIB_PART> part( new LIB_PART( symbolName ) );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
wxXmlNode* currentNode = aSymbolNode->GetChildren();
|
|
|
|
|
|
|
|
while( currentNode )
|
|
|
|
{
|
|
|
|
wxString nodeName = currentNode->GetName();
|
|
|
|
|
|
|
|
if( nodeName == "description" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:27:11 +00:00
|
|
|
// TODO
|
2017-05-08 15:11:14 +00:00
|
|
|
//wxASSERT_MSG( false, "'description' nodes are not implemented yet" );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "dimension" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 14:27:11 +00:00
|
|
|
// TODO
|
2017-05-08 15:11:14 +00:00
|
|
|
//wxASSERT_MSG( false, "'description' nodes are not implemented yet" );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "frame" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "circle" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
part->AddDrawItem( loadCircle( part.get(), currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "pin" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
// part->AddDrawItem( loadPin( part, currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "polygon" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
//part->AddDrawItem( loadPolygon( part.get(), currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "rectangle" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
part->AddDrawItem( loadRectangle( part.get(), currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "text" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
// part->AddDrawItem( loadText( part, currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
else if( nodeName == "wire" )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
// part->AddDrawItem( loadPolyline( part, currentNode ) );
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
currentNode = currentNode->GetNext();
|
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
return part.release();
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
|
|
|
|
2017-05-08 14:27:11 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
LIB_CIRCLE* SCH_EAGLE_PLUGIN::loadCircle( LIB_PART* aPart, wxXmlNode* aCircleNode )
|
2017-03-09 12:49:24 +00:00
|
|
|
{
|
2017-05-08 15:11:14 +00:00
|
|
|
// Parse the circle properties
|
|
|
|
ECIRCLE c( aCircleNode );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
unique_ptr<LIB_CIRCLE> circle( new LIB_CIRCLE( aPart ) );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
circle->SetPosition( wxPoint( c.x, c.y ) );
|
|
|
|
circle->SetRadius( c.radius );
|
|
|
|
circle->SetWidth( c.width );
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
return circle.release();
|
|
|
|
}
|
2017-03-09 12:49:24 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-05-08 15:11:14 +00:00
|
|
|
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();
|
2017-03-09 12:49:24 +00:00
|
|
|
}
|
2017-02-27 10:07:52 +00:00
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-02-27 10:07:52 +00:00
|
|
|
void SCH_EAGLE_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t SCH_EAGLE_PLUGIN::GetSymbolLibCount( const wxString& aLibraryPath,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::EnumerateSymbolLib( wxArrayString& aAliasNameList,
|
|
|
|
const wxString& aLibraryPath,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LIB_ALIAS* SCH_EAGLE_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EAGLE_PLUGIN::CreateSymbolLib( const wxString& aLibraryPath,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EAGLE_PLUGIN::DeleteSymbolLib( const wxString& aLibraryPath,
|
|
|
|
const PROPERTIES* aProperties )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EAGLE_PLUGIN::IsSymbolLibWritable( const wxString& aLibraryPath )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-05-08 14:10:23 +00:00
|
|
|
|
2017-02-27 10:07:52 +00:00
|
|
|
void SCH_EAGLE_PLUGIN::SymbolLibOptions( PROPERTIES* aListToAppendTo ) const
|
|
|
|
{
|
|
|
|
}
|
2017-05-08 14:10:23 +00:00
|
|
|
|
|
|
|
// approved
|
|
|
|
// attribute
|
|
|
|
// circle
|
|
|
|
// clearance
|
|
|
|
// connect
|
|
|
|
// contactref
|
|
|
|
// description
|
|
|
|
// dimension
|
|
|
|
// frame
|
|
|
|
// gate
|
|
|
|
// grid
|
|
|
|
// hole
|
|
|
|
// junction
|
|
|
|
// label
|
|
|
|
// layer
|
|
|
|
// note
|
|
|
|
// pad
|
|
|
|
// param
|
|
|
|
// pin
|
|
|
|
// pinref
|
|
|
|
// port
|
|
|
|
// portref
|
|
|
|
// rectangle
|
|
|
|
// setting
|
|
|
|
// smd
|
|
|
|
// textvariant
|
|
|
|
// variantdef
|
|
|
|
// vertex
|
|
|
|
// via
|
|
|
|
// wire
|