kicad/eeschema/sch_eagle_plugin.cpp

1402 lines
40 KiB
C++
Raw Normal View History

/*
2017-07-06 12:31:11 +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 <kiway.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>
#include <sch_junction.h>
2017-03-09 12:49:24 +00:00
#include <sch_sheet.h>
#include <schframe.h>
#include <template_fieldnames.h>
#include <wildcards_and_files_ext.h>
#include <class_sch_screen.h>
#include <class_library.h>
#include <class_libentry.h>
#include <lib_draw_item.h>
2017-06-26 07:56:11 +00:00
#include <sch_component.h>
#include <lib_circle.h>
#include <lib_rectangle.h>
#include <lib_polyline.h>
#include <lib_pin.h>
#include <lib_text.h>
#include <sch_text.h>
#include <drawtxt.h>
2017-05-08 14:10:23 +00:00
#include <eagle_parser.h>
#include <sch_eagle_plugin.h>
using std::string;
// Eagle schematic internal units are millimeters
// Kicad schematic units are thousandths of an inch
constexpr double EUNIT_TO_MIL = 1000.0 / 25.4;
// Eagle schematic axes are aligned with x increasing left to right and Y increasing bottom to top
2017-06-19 13:43:55 +00:00
// Kicad schematic axes are aligned with x increasing left to rigth and Y increasing top to bottom.
2017-03-09 12:49:24 +00:00
using namespace std;
static 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();
2017-07-06 12:31:11 +00:00
2017-05-08 14:27:11 +00:00
while( aCurrentNode )
2017-05-08 14:10:23 +00:00
{
// Create a new pair in the map
2017-07-06 12:31:11 +00:00
// 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-19 13:43:55 +00:00
static int countChildren( wxXmlNode* aCurrentNode, const std::string& aName )
{
// Map node_name -> node_pointer
int count = 0;
// Loop through all children counting them if they match the given name
aCurrentNode = aCurrentNode->GetChildren();
2017-06-19 13:43:55 +00:00
while( aCurrentNode )
{
2017-06-19 13:43:55 +00:00
if( aCurrentNode->GetName().ToStdString() == aName )
count++;
// Get next child
aCurrentNode = aCurrentNode->GetNext();
}
return count;
}
2017-05-08 14:10:23 +00:00
2017-07-09 01:46:18 +00:00
static SCH_LAYER_ID kicadLayer( int aEagleLayer )
2017-05-08 14:10:23 +00:00
{
/**
* 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-07-06 12:31:11 +00:00
case 90:
break;
case 91:
2017-07-09 01:46:18 +00:00
return LAYER_WIRE;
2017-07-06 12:31:11 +00:00
case 92:
2017-07-09 01:46:18 +00:00
return LAYER_BUS;
2017-07-06 12:31:11 +00:00
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-07-09 01:46:18 +00:00
return LAYER_NOTES;
2017-05-08 14:10:23 +00:00
}
static COMPONENT_ORIENTATION_T kicadComponentRotation( float eagleDegrees )
{
int roti = int(eagleDegrees);
switch( roti )
{
default:
wxASSERT_MSG( false, wxString::Format( "Unhandled orientation (%d degrees)", roti ) );
// fall through
case 0:
return CMP_ORIENT_0;
case 90:
return CMP_ORIENT_90;
case 180:
return CMP_ORIENT_180;
case 270:
return CMP_ORIENT_270;
}
return CMP_ORIENT_0;
}
SCH_EAGLE_PLUGIN::SCH_EAGLE_PLUGIN()
{
2017-03-09 12:49:24 +00:00
m_rootSheet = nullptr;
}
2017-05-08 14:10:23 +00:00
SCH_EAGLE_PLUGIN::~SCH_EAGLE_PLUGIN()
{
}
2017-03-09 12:49:24 +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,
2017-07-06 12:31:11 +00:00
SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties )
{
2017-05-08 14:10:23 +00:00
// TODO: Handle Kiway and uncomment next line.
2017-06-26 07:56:11 +00:00
// wxASSERT( !aFileName || aKiway != null );
2017-03-09 12:49:24 +00:00
// Load the document
wxXmlDocument xmlDocument;
2017-07-06 12:31:11 +00:00
m_filename = aFileName;
m_kiway = aKiway;
if( !xmlDocument.Load( m_filename.GetFullPath() ) )
2017-07-06 12:31:11 +00:00
THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'" ),
m_filename.GetFullPath() ) );
2017-03-09 12:49:24 +00:00
// Delete on exception, if I own m_rootSheet, according to aAppendToMe
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 );
}
// 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 );
}
// Create a schematic symbol library
wxFileName libfn = aFileName;
libfn.SetName( libfn.GetName() );
libfn.SetExt( SchematicLibraryFileExtension );
std::unique_ptr<PART_LIB> lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, libfn.GetFullPath() ) );
lib->EnableBuffering();
if( !wxFileName::FileExists( lib->GetFullFileName() ) )
{
lib->Create();
}
m_partlib = lib.release();
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
// There are two ways to add a new library, the official one that requires creating a file:
m_partlib->Save( false );
2017-07-06 12:31:11 +00:00
// aKiway->Prj().SchLibs()->AddLibrary( m_partlib->GetFullFileName() );
// or undocumented one:
aKiway->Prj().SchLibs()->push_back( m_partlib );
2017-03-09 12:49:24 +00:00
deleter.release();
return m_rootSheet;
}
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-07-06 12:31: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"];
wxXmlNode* partNode = schematicChildren["parts"]->GetChildren();
2017-07-06 12:31:11 +00:00
while( partNode )
{
std::unique_ptr<EPART> epart( new EPART( partNode ) );
const string& name = epart->name;
m_partlist[name] = epart.release();
partNode = partNode->GetNext();
}
2017-05-08 14:10:23 +00:00
// 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
{
auto elib = loadLibrary( libraryNode );
m_eaglelibraries[elib->name] = elib;
2017-05-08 14:10:23 +00:00
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-07-06 12:31:11 +00:00
int sheet_count = countChildren( schematicChildren["sheets"], "sheet" );
// If eagle schematic has multiple sheets.
2017-06-19 13:43:55 +00:00
if( sheet_count > 1 )
{
// TODO: set up a heirachical sheet for each Eagle sheet.
int x, y;
x = 1;
y = 1;
2017-06-19 13:43:55 +00:00
while( sheetNode )
{
2017-07-06 12:31:11 +00:00
wxPoint pos = wxPoint( x * 1000, y * 1000 );
2017-06-19 13:43:55 +00:00
std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET( pos ) );
SCH_SCREEN* screen = new SCH_SCREEN( m_kiway );
2017-06-19 13:43:55 +00:00
sheet->SetTimeStamp( GetNewTimeStamp() );
sheet->SetParent( m_rootSheet->GetScreen() );
sheet->SetScreen( screen );
m_currentSheet = sheet.get();
loadSheet( sheetNode );
sheet->GetScreen()->SetFileName( sheet->GetFileName() );
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-03-09 12:49:24 +00:00
2017-05-08 14:10:23 +00:00
2017-06-19 13:43:55 +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
// Get description node
wxXmlNode* descriptionNode = getChildrenNodes( sheetChildren, "description" );
2017-06-19 13:43:55 +00:00
if( descriptionNode )
{
2017-06-19 13:43:55 +00:00
wxString des = descriptionNode->GetContent();
m_currentSheet->SetName( des );
2017-06-19 13:43:55 +00:00
std::string filename = des.ToStdString();
ReplaceIllegalFileNameChars( &filename );
replace( filename.begin(), filename.end(), ' ', '_' );
2017-06-19 13:43:55 +00:00
wxString fn = wxString( filename + ".sch" );
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."
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
2017-07-09 01:46:18 +00:00
loadSegments( busNode, busName, wxString() );
2017-05-08 14:10:23 +00:00
// Get next bus
busNode = busNode->GetNext();
}
// Loop through all nets
// From the DTD: "Net is an electrical connection in a schematic."
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
2017-06-19 13:43:55 +00:00
loadSegments( netNode, netName, netClass );
2017-05-08 14:10:23 +00:00
// 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
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
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-07-06 12:31:11 +00:00
wxXmlNode* plainNode = getChildrenNodes( sheetChildren, "plain" );
while( plainNode )
{
wxString nodeName = plainNode->GetName();
2017-07-06 12:31:11 +00:00
if( nodeName =="text" )
{
2017-07-06 12:31:11 +00:00
m_currentSheet->GetScreen()->Append( loadplaintext( plainNode ) );
}
plainNode = plainNode->GetNext();
}
wxSize targetSheetSize( (sheetTopRight.x - sheetBottomLeft.x) * 1.5,
-( sheetTopRight.y - sheetBottomLeft.y) * 1.5 );
wxPoint itemsCentre( (sheetTopRight.x - sheetBottomLeft.x) / 2,
(sheetTopRight.y - sheetBottomLeft.y) / 2 );
SCH_ITEM* item = m_currentSheet->GetScreen()->GetDrawItems();
wxSize pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
PAGE_INFO pageInfo = m_currentSheet->GetScreen()->GetPageSettings();
if( pageSizeIU.x<targetSheetSize.x )
pageInfo.SetWidthMils( targetSheetSize.x );
if( pageSizeIU.y<targetSheetSize.y )
pageInfo.SetHeightMils( targetSheetSize.y );
m_currentSheet->GetScreen()->SetPageSettings( pageInfo );
pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
wxPoint sheetcentre( pageSizeIU.x / 2, pageSizeIU.y / 2 );
// round the translation to nearest 100mil.
wxPoint translation = sheetcentre- itemsCentre;
translation.x = translation.x - translation.x%100;
translation.y = translation.y - translation.y%100;
while( item )
{
item->SetPosition( item->GetPosition() +translation);
item = item->Next();
}
2017-03-09 12:49:24 +00:00
}
2017-05-08 14:10:23 +00:00
2017-06-19 13:43:55 +00:00
void SCH_EAGLE_PLUGIN::loadSegments( wxXmlNode* aSegmentsNode, const wxString& netName,
const wxString& netClass )
2017-03-09 12:49:24 +00:00
{
2017-05-08 14:10:23 +00:00
// Loop through all segments
wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
SCH_SCREEN* screen = m_currentSheet->GetScreen();
2017-07-06 12:31:11 +00:00
// wxCHECK( screen, [>void<] );
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" );
2017-06-19 13:43:55 +00:00
screen->Append( loadJunction( segmentAttribute ) );
2017-05-08 14:10:23 +00:00
}
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"
2017-06-19 13:43:55 +00:00
screen->Append( loadLabel( segmentAttribute, netName ) );
2017-05-08 14:10:23 +00:00
}
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" )
{
screen->Append( loadSignalWire( segmentAttribute ) );
}
else if( nodeName == "segment" )
{
2017-07-06 12:31:11 +00:00
// loadSegments( segmentAttribute );
}
else if( nodeName == "text" )
{
// TODO
2017-07-06 12:31:11 +00:00
// loadSegments( segmentAttribute );
2017-05-08 14:10:23 +00:00
}
2017-07-06 12:31:11 +00:00
else // DEFAULT
2017-05-08 14:10:23 +00:00
{
// TODO uncomment
2017-07-06 12:31:11 +00:00
// 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::loadSignalWire( wxXmlNode* aWireNode )
2017-05-08 14:10:23 +00:00
{
std::unique_ptr<SCH_LINE> wire( new SCH_LINE );
auto ewire = EWIRE( aWireNode );
2017-05-08 14:10:23 +00:00
2017-07-09 01:46:18 +00:00
wire->SetLayer( kicadLayer(ewire.layer) );
2017-05-08 14:10:23 +00:00
wxPoint begin, end;
2017-07-06 12:31:11 +00:00
begin.x = ewire.x1 * EUNIT_TO_MIL;
begin.y = -ewire.y1 * EUNIT_TO_MIL;
end.x = ewire.x2 * EUNIT_TO_MIL;
end.y = -ewire.y2 * EUNIT_TO_MIL;
2017-05-08 14:10:23 +00:00
wire->SetStartPoint( begin );
wire->SetEndPoint( end );
if( begin.x > sheetTopRight.x) sheetTopRight.x = begin.x;
if( begin.y < sheetTopRight.y) sheetTopRight.y = begin.y;
if( end.x > sheetTopRight.x) sheetTopRight.x = end.x;
if( end.y < sheetTopRight.y) sheetTopRight.y = end.y;
if( begin.x < sheetBottomLeft.x) sheetBottomLeft.x = begin.x;
if( begin.y > sheetBottomLeft.y) sheetBottomLeft.y = begin.y;
if( end.x < sheetBottomLeft.x) sheetBottomLeft.x = end.x;
if( end.y > sheetBottomLeft.y) sheetBottomLeft.y = end.y;
2017-05-08 14:10:23 +00:00
return wire.release();
}
2017-06-19 13:43:55 +00:00
SCH_JUNCTION* SCH_EAGLE_PLUGIN::loadJunction( wxXmlNode* aJunction )
{
std::unique_ptr<SCH_JUNCTION> junction( new SCH_JUNCTION );
2017-06-19 13:43:55 +00:00
auto ejunction = EJUNCTION( aJunction );
wxPoint pos( ejunction.x * EUNIT_TO_MIL, -ejunction.y * EUNIT_TO_MIL );
junction->SetPosition( pos );
if( pos.x > sheetTopRight.x) sheetTopRight.x = pos.x;
if( pos.y < sheetTopRight.y) sheetTopRight.y = pos.y;
if( pos.x < sheetBottomLeft.x) sheetBottomLeft.x = pos.x;
if( pos.y > sheetBottomLeft.y) sheetBottomLeft.y = pos.y;
2017-06-19 13:43:55 +00:00
return junction.release();
}
2017-07-06 12:31:11 +00:00
SCH_GLOBALLABEL* SCH_EAGLE_PLUGIN::loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName )
2017-06-19 13:43:55 +00:00
{
std::unique_ptr<SCH_GLOBALLABEL> glabel( new SCH_GLOBALLABEL );
2017-06-19 13:43:55 +00:00
auto elabel = ELABEL( aLabelNode, aNetName );
2017-07-06 12:31:11 +00:00
glabel->SetPosition( wxPoint( elabel.x * EUNIT_TO_MIL, -elabel.y * EUNIT_TO_MIL ) );
glabel->SetText( elabel.netname );
2017-06-19 13:43:55 +00:00
glabel->SetTextSize( wxSize( GetDefaultTextSize(), GetDefaultTextSize() ) );
glabel->SetLabelSpinStyle(0);
2017-06-19 13:43:55 +00:00
if( elabel.rot )
{
glabel->SetLabelSpinStyle( int( 360-elabel.rot->degrees / 90) % 4 );
if(elabel.rot->mirror && ( glabel->GetLabelSpinStyle() == 0 || glabel->GetLabelSpinStyle() == 2 )) glabel->SetLabelSpinStyle((glabel->GetLabelSpinStyle()+2)%4);
}
2017-06-19 13:43:55 +00:00
return glabel.release();
}
2017-05-08 14:10:23 +00:00
void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
{
2017-06-26 07:56:11 +00:00
auto einstance = EINSTANCE( aInstanceNode );
SCH_SCREEN* screen = m_currentSheet->GetScreen();
// Find the part in the list for the sheet.
// Assign the component its value from the part entry
// Calculate the unit number from the gate entry of the instance
2017-07-06 12:31:11 +00:00
// Assign the the LIB_ID from deviceset and device names
2017-06-26 07:56:11 +00:00
EPART* epart = m_partlist[einstance.part];
2017-06-26 07:56:11 +00:00
std::string gatename = epart->deviceset + epart->device + einstance.gate;
std::string symbolname = epart->deviceset + epart->device;
int unit = m_eaglelibraries[epart->library]->gate_unit[gatename];
std::string package = m_eaglelibraries[epart->library]->package[symbolname];
2017-07-06 12:31:11 +00:00
// std::cout << "Instance> part: " << einstance.part << " Gate: " << einstance.gate << " " << symbolname << '\n';
2017-06-26 07:56:11 +00:00
LIB_ID libId( m_partlib->GetLogicalName(), symbolname );
2017-07-06 12:31:11 +00:00
LIB_PART* part = m_partlib->FindPart(symbolname);
std::unique_ptr<SCH_COMPONENT> component( new SCH_COMPONENT() );
component->SetLibId( libId );
component->SetUnit( unit );
component->SetConvert( 0 );
component->SetPosition( wxPoint( einstance.x * EUNIT_TO_MIL, -einstance.y * EUNIT_TO_MIL ) );
2017-07-06 12:31:11 +00:00
component->GetField( FOOTPRINT )->SetText( wxString( package ) );
// component->SetTimeStamp( parseHex( aReader, line, &line ) ); // TODO we need to find a way
// to correlate symbols and footprints
// component->AddHierarchicalReference( path, reference, (int)tmp ); // TODO ??
if( einstance.rot )
{
2017-07-06 12:31:11 +00:00
component->SetOrientation( kicadComponentRotation( einstance.rot->degrees ) );
if( einstance.rot->mirror )
{
component->MirrorY( einstance.x * EUNIT_TO_MIL );
}
}
LIB_FIELDS partFields;
part->GetFields(partFields);
for( auto const& field : partFields )
{
component->GetField(field.GetId())->ImportValues(field);
component->GetField(field.GetId())->SetTextPos( component->GetPosition() + field.GetTextPos() );
}
component->GetField( REFERENCE )->SetText( einstance.part );
if(epart->value)
{
component->GetField( VALUE )->SetText( *epart->value );
} else
{
component->GetField( VALUE )->SetText( *epart->value );
}
component->GetField( VALUE )->SetVisible(true);
component->GetField( REFERENCE )->SetVisible(true);
component->SetModified();
component->ClearFlags();
2017-06-26 07:56:11 +00:00
screen->Append( component.release() );
2017-05-08 14:10:23 +00:00
}
void SCH_EAGLE_PLUGIN::loadModuleinst( wxXmlNode* aModuleinstNode )
{
}
EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode )
2017-05-08 14:10:23 +00:00
{
2017-07-06 12:31:11 +00:00
unique_ptr<EAGLE_LIBRARY> elib( new EAGLE_LIBRARY );
std::map<std::string, wxXmlNode*> gate;
2017-05-08 14:10:23 +00:00
// Read the library name
wxString libName = aLibraryNode->GetAttribute( "name" );
elib.get()->name = libName.ToStdString();
2017-05-08 14:10:23 +00:00
////std::cout << "Importing Eagle Library "<< libName.ToStdString() << std::endl;
2017-06-26 07:56:11 +00:00
2017-05-08 14:10:23 +00:00
// 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 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 )
// {
2017-07-06 12:31:11 +00:00
// loadPackage( packageNode );
// packageNode = packageNode->GetNext();
2017-05-08 14:10:23 +00:00
// }
// 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 )
{
2017-06-26 07:56:11 +00:00
wxString symbolName = symbolNode->GetAttribute( "name" );
elib->symbolnodes[symbolName.ToStdString()] = symbolNode;
2017-05-08 14:10:23 +00:00
symbolNode = symbolNode->GetNext();
}
2017-06-26 07:56:11 +00:00
// Loop through the devicesets and load each of them
wxXmlNode* devicesetNode = libraryChildren["devicesets"]->GetChildren();
2017-07-06 12:31:11 +00:00
while( devicesetNode )
2017-06-26 07:56:11 +00:00
{
// Get Device set information
2017-07-06 12:31:11 +00:00
EDEVICESET edeviceset = EDEVICESET( devicesetNode );
2017-06-26 07:56:11 +00:00
2017-07-06 12:31:11 +00:00
// std::cout << "Importing Eagle device set "<< edeviceset.name << std::endl;
2017-06-26 07:56:11 +00:00
2017-07-06 12:31:11 +00:00
NODE_MAP aDeviceSetChildren = MapChildren( devicesetNode );
wxXmlNode* deviceNode = getChildrenNodes( aDeviceSetChildren, "devices" );
2017-06-26 07:56:11 +00:00
// For each device in the device set:
2017-07-06 12:31:11 +00:00
while( deviceNode )
{
// Get device information
2017-07-06 12:31:11 +00:00
EDEVICE edevice = EDEVICE( deviceNode );
2017-06-26 07:56:11 +00:00
// Create symbol name from deviceset and device names.
2017-07-06 12:31:11 +00:00
wxString symbolName = wxString( edeviceset.name + edevice.name );
// std::cout << "Creating Kicad Symbol: " << symbolName.ToStdString() << '\n';
elib.get()->package[symbolName.ToStdString()] = edevice.package.Get();
2017-06-26 07:56:11 +00:00
// Create kicad symbol.
2017-07-06 12:31:11 +00:00
unique_ptr<LIB_PART> kpart( new LIB_PART( symbolName ) );
2017-06-26 07:56:11 +00:00
// Process each gate in the deviceset for this device.
2017-07-06 12:31:11 +00:00
wxXmlNode* gateNode = getChildrenNodes( aDeviceSetChildren, "gates" );
int gates_count = countChildren( aDeviceSetChildren["gates"], "gate" );
kpart->SetUnitCount( gates_count );
int gateindex;
2017-07-06 12:31:11 +00:00
if( gates_count>1 )
{
gateindex = 1;
}
else
{
2017-07-06 12:31:11 +00:00
gateindex = 0;
}
2017-06-26 07:56:11 +00:00
2017-07-06 12:31:11 +00:00
while( gateNode )
{
EGATE egate = EGATE( gateNode );
elib.get()->gate_unit[edeviceset.name + edevice.name + egate.name] = gateindex;
2017-06-26 07:56:11 +00:00
2017-07-06 12:31:11 +00:00
loadSymbol( elib->symbolnodes[egate.symbol],
(LIB_PART*) kpart.get(), &edevice, gateindex, egate.name );
2017-06-26 07:56:11 +00:00
gateindex++;
gateNode = gateNode->GetNext();
2017-07-06 12:31:11 +00:00
} // gateNode
2017-06-26 07:56:11 +00:00
2017-07-06 12:31:11 +00:00
kpart->SetUnitCount( gates_count );
kpart->GetField( VALUE )->SetVisible(true);
kpart->GetField( REFERENCE )->SetVisible(true);
2017-06-26 07:56:11 +00:00
const string& name = kpart->GetName().ToStdString();
m_partlib->AddPart( kpart.get() );
elib->kicadsymbols[name] = kpart.release();
deviceNode = deviceNode->GetNext();
2017-07-06 12:31:11 +00:00
} // devicenode
2017-06-26 07:56:11 +00:00
devicesetNode = devicesetNode->GetNext();
2017-07-06 12:31:11 +00:00
} // devicesetNode
return elib.release();
2017-05-08 14:10:23 +00:00
}
2017-07-06 12:31:11 +00:00
void SCH_EAGLE_PLUGIN::loadSymbol( wxXmlNode* aSymbolNode,
LIB_PART* aPart,
EDEVICE* aDevice,
int gateNumber,
string gateName )
2017-05-08 14:10:23 +00:00
{
wxString symbolName = aSymbolNode->GetAttribute( "name" );
2017-07-06 12:31:11 +00:00
std::vector<LIB_ITEM*> items;
2017-05-08 14:10:23 +00:00
wxXmlNode* currentNode = aSymbolNode->GetChildren();
while( currentNode )
{
wxString nodeName = currentNode->GetName();
2017-07-06 12:31:11 +00:00
2017-05-08 14:10:23 +00:00
if( nodeName == "description" )
2017-03-09 12:49:24 +00:00
{
2017-05-08 14:27:11 +00:00
// TODO
2017-07-06 12:31:11 +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-07-06 12:31:11 +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
{
LIB_CIRCLE* circle = loadSymbolCircle( aPart, currentNode );
2017-07-06 12:31:11 +00:00
circle->SetUnit( gateNumber );
aPart->AddDrawItem( circle );
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-07-06 12:31:11 +00:00
LIB_PIN* pin = loadPin( aPart, currentNode );
if(aDevice->connects.size() != 0)
2017-07-06 12:31:11 +00:00
{
for( auto connect : aDevice->connects )
2017-07-06 12:31:11 +00:00
{
if( connect.gate == gateName and pin->GetName().ToStdString() == connect.pin )
{
wxString padname( connect.pad );
pin->SetPinNumFromString( padname );
pin->SetPartNumber( gateNumber );
pin->SetUnit( gateNumber );
aPart->AddDrawItem( pin );
break;
}
2017-07-06 12:31:11 +00:00
}
}
else
{
pin->SetPartNumber( gateNumber );
pin->SetUnit( gateNumber );
aPart->AddDrawItem( pin );
break;
}
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-07-06 12:31:11 +00:00
// loadPolygon( aPart, currentNode );
// aPart->AddDrawItem();
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
{
LIB_RECTANGLE* rectangle = loadSymbolRectangle( aPart, currentNode );
2017-07-06 12:31:11 +00:00
rectangle->SetUnit( gateNumber );
aPart->AddDrawItem( rectangle );
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
{
LIB_TEXT* libtext = loadSymboltext( aPart, currentNode );
2017-07-06 12:31:11 +00:00
libtext->SetUnit( gateNumber );
2017-06-26 07:56:11 +00:00
// TODO: Reimplement mandatory field positioning.
std::cout << libtext->GetText() << '\n';
if( libtext->GetText() ==">NAME" )
{
aPart->GetField( REFERENCE )->SetTextPos( libtext->GetPosition() );
aPart->GetField( REFERENCE )->SetTextSize( libtext->GetTextSize() );
aPart->GetField( REFERENCE )->SetTextAngle( libtext->GetTextAngle() );
aPart->GetField( REFERENCE )->SetBold( libtext->IsBold() );
aPart->GetField( REFERENCE )->SetVertJustify(libtext->GetVertJustify());
aPart->GetField( REFERENCE )->SetHorizJustify(libtext->GetHorizJustify());
aPart->GetField( REFERENCE )->SetVisible(true);
}
else if( libtext->GetText() == ">VALUE" )
{
aPart->GetField( VALUE )->SetTextPos( libtext->GetPosition() );
aPart->GetField( VALUE )->SetTextSize( libtext->GetTextSize() );
aPart->GetField( VALUE )->SetTextAngle( libtext->GetTextAngle() );
aPart->GetField( VALUE )->SetBold( libtext->IsBold() );
aPart->GetField( VALUE )->SetVertJustify(libtext->GetVertJustify());
aPart->GetField( VALUE )->SetHorizJustify(libtext->GetHorizJustify());
aPart->GetField( VALUE )->SetVisible(true);
}
else
{
2017-07-06 12:31:11 +00:00
aPart->AddDrawItem( libtext );
}
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-07-06 12:31:11 +00:00
LIB_POLYLINE* pline = loadSymbolWire( aPart, currentNode );
pline->SetUnit( gateNumber );
aPart->AddDrawItem( pline );
2017-03-09 12:49:24 +00:00
}
currentNode = currentNode->GetNext();
}
}
2017-05-08 14:27:11 +00:00
LIB_CIRCLE* SCH_EAGLE_PLUGIN::loadSymbolCircle( LIB_PART* aPart, wxXmlNode* aCircleNode )
2017-03-09 12:49:24 +00:00
{
// Parse the circle properties
ECIRCLE c( aCircleNode );
2017-05-08 14:10:23 +00:00
unique_ptr<LIB_CIRCLE> circle( new LIB_CIRCLE( aPart ) );
2017-05-08 14:10:23 +00:00
2017-07-06 12:31:11 +00:00
circle->SetPosition( wxPoint( c.x * EUNIT_TO_MIL, c.y * EUNIT_TO_MIL ) );
circle->SetRadius( c.radius * EUNIT_TO_MIL );
circle->SetWidth( c.width * EUNIT_TO_MIL );
2017-05-08 14:10:23 +00:00
return circle.release();
}
2017-03-09 12:49:24 +00:00
2017-05-08 14:10:23 +00:00
LIB_RECTANGLE* SCH_EAGLE_PLUGIN::loadSymbolRectangle( LIB_PART* aPart, wxXmlNode* aRectNode )
{
ERECT rect( aRectNode );
unique_ptr<LIB_RECTANGLE> rectangle( new LIB_RECTANGLE( aPart ) );
2017-07-06 12:31:11 +00:00
rectangle->SetPosition( wxPoint( rect.x1 * EUNIT_TO_MIL, rect.y1 * EUNIT_TO_MIL ) );
rectangle->SetEnd( wxPoint( rect.x2 * EUNIT_TO_MIL, rect.y2 * EUNIT_TO_MIL ) );
// TODO: Manage rotation
return rectangle.release();
}
2017-06-19 13:43:55 +00:00
LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolWire( LIB_PART* aPart, wxXmlNode* aWireNode )
{
// TODO: Layer map
2017-07-06 12:31:11 +00:00
std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( aPart ) );
2017-07-06 12:31:11 +00:00
auto ewire = EWIRE( aWireNode );
wxPoint begin, end;
2017-07-06 12:31:11 +00:00
begin.x = ewire.x1 * EUNIT_TO_MIL;
begin.y = ewire.y1 * EUNIT_TO_MIL;
end.x = ewire.x2 * EUNIT_TO_MIL;
end.y = ewire.y2 * EUNIT_TO_MIL;
polyLine->AddPoint( begin );
polyLine->AddPoint( end );
return polyLine.release();
}
2017-06-19 13:43:55 +00:00
LIB_POLYLINE* SCH_EAGLE_PLUGIN::loadSymbolPolyLine( LIB_PART* aPart, wxXmlNode* aPolygonNode )
{
// TODO: Layer map
2017-07-06 12:31:11 +00:00
std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( aPart ) );
NODE_MAP polygonChildren = mapChildren( aPolygonNode );
wxXmlNode* vertex = getChildrenNodes( polygonChildren, "vertex" );
2017-06-19 13:43:55 +00:00
while( vertex )
{
auto evertex = EVERTEX( vertex );
2017-07-06 12:31:11 +00:00
auto v = wxPoint( evertex.x * EUNIT_TO_MIL, evertex.y * EUNIT_TO_MIL );
polyLine->AddPoint( v );
vertex->GetNext();
}
return polyLine.release();
2017-03-09 12:49:24 +00:00
}
2017-06-19 13:43:55 +00:00
LIB_PIN* SCH_EAGLE_PLUGIN::loadPin( LIB_PART* aPart, wxXmlNode* aPin )
{
std::unique_ptr<LIB_PIN> pin( new LIB_PIN( aPart ) );
auto epin = EPIN( aPin );
pin->SetPosition( wxPoint( epin.x * EUNIT_TO_MIL, epin.y * EUNIT_TO_MIL ) );
pin->SetName( epin.name );
int roti = 0;
if( epin.rot )
{
2017-07-06 12:31:11 +00:00
roti = int(epin.rot->degrees);
}
switch( roti )
{
default:
wxASSERT_MSG( false, wxString::Format( "Unhandled orientation (%d degrees)", roti ) );
2017-07-06 12:31:11 +00:00
// fall through
case 0:
pin->SetOrientation( 'R' );
break;
case 90:
pin->SetOrientation( 'U' );
break;
case 180:
pin->SetOrientation( 'L' );
break;
case 270:
pin->SetOrientation( 'D' );
break;
}
if( epin.length )
{
wxString length = epin.length.Get();
if( length =="short" )
{
pin->SetLength( 100 );
}
else if( length =="middle" )
{
pin->SetLength( 200 );
}
else if( length == "long" )
{
pin->SetLength( 300 );
}
else if( length == "point" )
{
pin->SetLength( 0 );
}
}
return pin.release();
}
2017-06-19 13:43:55 +00:00
LIB_TEXT* SCH_EAGLE_PLUGIN::loadSymboltext( LIB_PART* aPart, wxXmlNode* aLibText )
{
std::unique_ptr<LIB_TEXT> libtext( new LIB_TEXT( aPart ) );
auto etext = ETEXT( aLibText );
libtext->SetPosition( wxPoint( etext.x * EUNIT_TO_MIL, etext.y * EUNIT_TO_MIL ) );
libtext->SetText( aLibText->GetNodeContent() );
libtext->SetTextSize( wxSize( int(etext.size * EUNIT_TO_MIL),
int(etext.size * EUNIT_TO_MIL) ) );
if( etext.ratio )
{
if( etext.ratio.Get()>12 )
{
libtext->SetBold( true );
libtext->SetThickness( GetPenSizeForBold( libtext->GetTextWidth() ) );
}
}
int align = etext.align ? *etext.align : ETEXT::BOTTOM_LEFT;
switch( align )
{
case ETEXT::CENTER:
// this was the default in eda_text's constructor
break;
case ETEXT::CENTER_LEFT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
break;
case ETEXT::CENTER_RIGHT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
break;
case ETEXT::TOP_CENTER:
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::TOP_LEFT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::TOP_RIGHT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::BOTTOM_CENTER:
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
case ETEXT::BOTTOM_LEFT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
case ETEXT::BOTTOM_RIGHT:
libtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
libtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
}
libtext->SetItalic( false );
return libtext.release();
}
2017-05-08 14:10:23 +00:00
SCH_TEXT* SCH_EAGLE_PLUGIN::loadplaintext( wxXmlNode* aSchText )
{
std::unique_ptr<SCH_TEXT> schtext( new SCH_TEXT() );
auto etext = ETEXT( aSchText );
schtext->SetItalic( false );
schtext->SetPosition( wxPoint( etext.x * EUNIT_TO_MIL, -etext.y * EUNIT_TO_MIL ) );
schtext->SetText( aSchText->GetNodeContent() );
if( etext.ratio )
{
if( etext.ratio.Get()>12 )
{
schtext->SetBold( true );
schtext->SetThickness( GetPenSizeForBold( schtext->GetTextWidth() ) );
}
}
schtext->SetTextSize( wxSize( int(etext.size * EUNIT_TO_MIL),
int(etext.size * EUNIT_TO_MIL) ) );
int align = etext.align ? *etext.align : ETEXT::BOTTOM_LEFT;
switch( align )
{
case ETEXT::CENTER:
// this was the default in eda_text's constructor
break;
case ETEXT::CENTER_LEFT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
break;
case ETEXT::CENTER_RIGHT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
break;
case ETEXT::TOP_CENTER:
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::TOP_LEFT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::TOP_RIGHT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
break;
case ETEXT::BOTTOM_CENTER:
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
case ETEXT::BOTTOM_LEFT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
case ETEXT::BOTTOM_RIGHT:
schtext->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
schtext->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
break;
}
return schtext.release();
}
bool SCH_EAGLE_PLUGIN::CheckHeader( const wxString& aFileName )
{
// Open file and check first line
wxTextFile tempFile;
tempFile.Open( aFileName );
wxString firstline;
// read the first line
firstline = tempFile.GetFirstLine();
tempFile.Close();
return firstline.StartsWith( "<?xml" );
}
void SCH_EAGLE_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway,
2017-07-06 12:31:11 +00:00
const PROPERTIES* aProperties )
{
2017-07-06 12:31:11 +00:00
// std::cout << "SCH_EAGLE_PLUGIN::Save" << '\n';
}
2017-07-06 12:31:11 +00:00
size_t SCH_EAGLE_PLUGIN::GetSymbolLibCount( const wxString& aLibraryPath,
const PROPERTIES* aProperties )
{
return 0;
}
2017-07-06 12:31:11 +00:00
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,
2017-07-06 12:31:11 +00:00
const PROPERTIES* aProperties )
{
return nullptr;
}
void SCH_EAGLE_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
2017-07-06 12:31:11 +00:00
const PROPERTIES* aProperties )
{
2017-07-06 12:31:11 +00:00
// std::cout << "SCH_EAGLE_PLUGIN::SaveSymbol" << '\n';
}
void SCH_EAGLE_PLUGIN::DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
2017-07-06 12:31:11 +00:00
const PROPERTIES* aProperties )
{
}
void SCH_EAGLE_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
2017-07-06 12:31:11 +00:00
const PROPERTIES* aProperties )
{
}
2017-07-06 12:31:11 +00:00
void SCH_EAGLE_PLUGIN::CreateSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties )
{
}
2017-07-06 12:31:11 +00:00
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
void SCH_EAGLE_PLUGIN::SymbolLibOptions( PROPERTIES* aListToAppendTo ) const
{
}
2017-05-08 14:10:23 +00:00
2017-07-06 12:31:11 +00:00
2017-05-08 14:10:23 +00:00
// approved
// attribute
// circle
// clearance
// connect
// contactref
// description
// dimension
// frame
// gate
// grid
// hole
// layer
// note
// pad
// param
// pin
// pinref
// port
// portref
// rectangle
// setting
// smd
// textvariant
// variantdef
// vertex
// via
// wire