KiCad PCB EDA Suite
SCH_EAGLE_PLUGIN Class Reference

SCH_EAGLE_PLUGIN is a SCH_PLUGIN derivation for loading 6.x+ Eagle schematic files. More...

#include <sch_eagle_plugin.h>

Inheritance diagram for SCH_EAGLE_PLUGIN:
SCH_PLUGIN

Classes

struct  EAGLE_MISSING_CMP
 
struct  SEG_DESC
 

Wires and labels of a single connection (segment in Eagle nomenclature)

More...
 

Public Member Functions

 SCH_EAGLE_PLUGIN ()
 
 ~SCH_EAGLE_PLUGIN ()
 
const wxString GetName () const override
 Returns a brief hard coded name for this SCH_PLUGIN. More...
 
const wxString GetFileExtension () const override
 Returns the file extension for the SCH_PLUGIN. More...
 
const wxString GetLibraryFileExtension () const override
 Return the library file extension for the SCH_PLUGIN object. More...
 
int GetModifyHash () const override
 Return the modification hash from the library cache. More...
 
SCH_SHEETLoad (const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=NULL, const PROPERTIES *aProperties=NULL) override
 Load information from some input file format that this SCH_PLUGIN implementation knows about, into either a new SCH_SHEET or an existing one. More...
 
bool CheckHeader (const wxString &aFileName) override
 Return true if the first line in aFileName begins with the expected header. More...
 
virtual void SaveLibrary (const wxString &aFileName, const PROPERTIES *aProperties=NULL)
 
virtual void Save (const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const PROPERTIES *aProperties=NULL)
 Write aSchematic to a storage file in a format that this SCH_PLUGIN implementation knows about, or it can be used to write a portion of aSchematic to a special kind of export file. More...
 
virtual void EnumerateSymbolLib (wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Populate a list of LIB_PART alias names contained within the library aLibraryPath. More...
 
virtual void EnumerateSymbolLib (std::vector< LIB_PART * > &aSymbolList, const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Populate a list of LIB_PART aliases contained within the library aLibraryPath. More...
 
virtual LIB_PARTLoadSymbol (const wxString &aLibraryPath, const wxString &aPartName, const PROPERTIES *aProperties=NULL)
 Load a LIB_PART object having aPartName from the aLibraryPath containing a library format that this SCH_PLUGIN knows about. More...
 
virtual void SaveSymbol (const wxString &aLibraryPath, const LIB_PART *aSymbol, const PROPERTIES *aProperties=NULL)
 Write aSymbol to an existing library located at aLibraryPath. More...
 
virtual void DeleteSymbol (const wxString &aLibraryPath, const wxString &aSymbolName, const PROPERTIES *aProperties=NULL)
 Delete the entire LIB_PART associated with aAliasName from the library aLibraryPath. More...
 
virtual void CreateSymbolLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Create a new empty symbol library at aLibraryPath. More...
 
virtual bool DeleteSymbolLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
 Delete an existing symbol library and returns true if successful, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason. More...
 
virtual bool IsSymbolLibWritable (const wxString &aLibraryPath)
 Return true if the library at aLibraryPath is writable. More...
 
virtual void SymbolLibOptions (PROPERTIES *aListToAppendTo) const
 Append supported SCH_PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 
virtual const wxString & GetError () const
 Return an error string to the caller. More...
 

Private Member Functions

void loadDrawing (wxXmlNode *aDrawingNode)
 
void loadLayerDefs (wxXmlNode *aLayers)
 
void loadSchematic (wxXmlNode *aSchematicNode)
 
void loadSheet (wxXmlNode *aSheetNode, int sheetcount)
 
void loadInstance (wxXmlNode *aInstanceNode)
 
EAGLE_LIBRARYloadLibrary (wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
 
void countNets (wxXmlNode *aSchematicNode)
 
void moveLabels (SCH_ITEM *aWire, const wxPoint &aNewEndPoint)
 Moves any labels on the wire to the new end point of the wire. More...
 
void addBusEntries ()
 This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Eagle bus segment. More...
 
SCH_LAYER_ID kiCadLayer (int aEagleLayer)
 Return the matching layer or return LAYER_NOTES. More...
 
std::pair< VECTOR2I, const SEG * > findNearestLinePoint (const wxPoint &aPoint, const std::vector< SEG > &aLines) const
 
void loadSegments (wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
 
SCH_LINEloadWire (wxXmlNode *aWireNode)
 
SCH_TEXTloadLabel (wxXmlNode *aLabelNode, const wxString &aNetName)
 
SCH_JUNCTIONloadJunction (wxXmlNode *aJunction)
 
SCH_TEXTloadPlainText (wxXmlNode *aSchText)
 
bool loadSymbol (wxXmlNode *aSymbolNode, std::unique_ptr< LIB_PART > &aPart, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
 
LIB_CIRCLEloadSymbolCircle (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aCircleNode, int aGateNumber)
 
LIB_RECTANGLEloadSymbolRectangle (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aRectNode, int aGateNumber)
 
LIB_POLYLINEloadSymbolPolyLine (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aPolygonNode, int aGateNumber)
 
LIB_ITEMloadSymbolWire (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aWireNode, int aGateNumber)
 
LIB_PINloadPin (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *, EPIN *epin, int aGateNumber)
 
LIB_TEXTloadSymbolText (std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aLibText, int aGateNumber)
 
void loadTextAttributes (EDA_TEXT *aText, const ETEXT &aAttribs) const
 
void loadFieldAttributes (LIB_FIELD *aField, const LIB_TEXT *aText) const
 
void adjustNetLabels ()
 

Moves net labels that are detached from any wire to the nearest wire

More...
 
wxString translateEagleBusName (const wxString &aEagleName) const
 Translates an Eagle-style bus name into one that is KiCad-compatible. More...
 
wxString getLibName ()
 
wxFileName getLibFileName ()
 
bool checkConnections (const SCH_COMPONENT *aComponent, const LIB_PIN *aPin) const
 

Checks if there are other wires or pins at the position of the tested pin

More...
 
void addImplicitConnections (SCH_COMPONENT *aComponent, SCH_SCREEN *aScreen, bool aUpdateSet)
 Creates net labels to emulate implicit connections in Eagle. More...
 

Static Private Member Functions

static wxString fixSymbolName (const wxString &aName)
 Fixes invalid characters in Eagle symbol names. More...
 

Private Attributes

KIWAYm_kiway
 For creating sub sheets. More...
 
SCH_SHEETm_rootSheet
 The root sheet of the schematic being loaded.. More...
 
SCH_SHEETm_currentSheet
 The current sheet of the schematic being loaded.. More...
 
wxString m_version
 Eagle file version. More...
 
wxFileName m_filename
 
wxString m_libName
 Library name to save symbols. More...
 
SCHEMATICm_schematic
 Passed to Load(), the schematic object being loaded. More...
 
EPART_MAP m_partlist
 
std::map< wxString, EAGLE_LIBRARYm_eagleLibs
 
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
 Plugin to create the KiCad symbol library. More...
 
std::unique_ptr< PROPERTIESm_properties
 Library plugin properties. More...
 
std::map< wxString, int > m_netCounts
 
std::map< int, SCH_LAYER_IDm_layerMap
 
std::vector< VECTOR2Im_wireIntersections
 

Wire intersection points, used for quick checks whether placing a net label in a particular place would short two nets.

More...
 
std::vector< SEG_DESCm_segments
 

Segments representing wires for intersection checking

More...
 
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
 

Positions of pins and wire endings mapped to its parent

More...
 
std::map< wxString, EAGLE_MISSING_CMPm_missingCmps
 

Map references to missing component units data

More...
 

Detailed Description

SCH_EAGLE_PLUGIN is a SCH_PLUGIN derivation for loading 6.x+ Eagle schematic files.

As with all SCH_PLUGINs there is no UI dependencies i.e. windowing calls allowed.

Definition at line 80 of file sch_eagle_plugin.h.

Constructor & Destructor Documentation

◆ SCH_EAGLE_PLUGIN()

SCH_EAGLE_PLUGIN::SCH_EAGLE_PLUGIN ( )

Definition at line 356 of file sch_eagle_plugin.cpp.

357 {
358  m_kiway = nullptr;
359  m_rootSheet = nullptr;
360  m_currentSheet = nullptr;
361  m_schematic = nullptr;
362 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
KIWAY * m_kiway
For creating sub sheets.
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded..
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.

◆ ~SCH_EAGLE_PLUGIN()

SCH_EAGLE_PLUGIN::~SCH_EAGLE_PLUGIN ( )

Definition at line 365 of file sch_eagle_plugin.cpp.

366 {
367 }

Member Function Documentation

◆ addBusEntries()

void SCH_EAGLE_PLUGIN::addBusEntries ( )
private

This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Eagle bus segment.

Definition at line 1982 of file sch_eagle_plugin.cpp.

1983 {
1984  // Add bus entry symbols
1985  // TODO: Cleanup this function and break into pieces
1986 
1987  // for each wire segment, compare each end with all busess.
1988  // If the wire end is found to end on a bus segment, place a bus entry symbol.
1989 
1990  for( auto it1 = m_currentSheet->GetScreen()->Items().OfType( SCH_LINE_T ).begin();
1991  it1 != m_currentSheet->GetScreen()->Items().end(); ++it1 )
1992  {
1993  SCH_LINE* bus = static_cast<SCH_LINE*>( *it1 );
1994 
1995  // Check line type for wire
1996  if( bus->GetLayer() != LAYER_BUS )
1997  continue;
1998 
1999 
2000  wxPoint busstart = bus->GetStartPoint();
2001  wxPoint busend = bus->GetEndPoint();
2002 
2003  auto it2 = it1;
2004  ++it2;
2005  for( ; it2 != m_currentSheet->GetScreen()->Items().end(); ++it2 )
2006  {
2007  SCH_LINE* line = static_cast<SCH_LINE*>( *it2 );
2008 
2009  // Check line type for bus
2010  if( ( (SCH_LINE*) *it2 )->GetLayer() == LAYER_WIRE )
2011  {
2012  // Get points of both segments.
2013  wxPoint linestart = line->GetStartPoint();
2014  wxPoint lineend = line->GetEndPoint();
2015 
2016  // Test for horizontal wire and vertical bus
2017  if( linestart.y == lineend.y && busstart.x == busend.x )
2018  {
2019  if( TestSegmentHit( linestart, busstart, busend, 0 ) )
2020  {
2021  // Wire start is on a bus.
2022  // Wire start is on the vertical bus
2023 
2024  // if the end of the wire is to the left of the bus
2025  if( lineend.x < busstart.x )
2026  {
2027  // |
2028  // ---|
2029  // |
2030  if( TestSegmentHit(
2031  linestart + wxPoint( 0, -100 ), busstart, busend, 0 ) )
2032  {
2033  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2034  linestart + wxPoint( -100, 0 ), true );
2035  busEntry->SetFlags( IS_NEW );
2036  m_currentSheet->GetScreen()->Append( busEntry );
2037  moveLabels( line, linestart + wxPoint( -100, 0 ) );
2038  line->SetStartPoint( linestart + wxPoint( -100, 0 ) );
2039  }
2040  else if( TestSegmentHit(
2041  linestart + wxPoint( 0, 100 ), busstart, busend, 0 ) )
2042  {
2043  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2044  linestart + wxPoint( -100, 0 ), false );
2045  busEntry->SetFlags( IS_NEW );
2046  m_currentSheet->GetScreen()->Append( busEntry );
2047  moveLabels( line, linestart + wxPoint( -100, 0 ) );
2048  line->SetStartPoint( linestart + wxPoint( -100, 0 ) );
2049  }
2050  else
2051  {
2052  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2053  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2054 
2055  SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart );
2056  m_currentSheet->GetScreen()->Append( marker );
2057  }
2058  }
2059  // else the wire end is to the right of the bus
2060  // Wire is to the right of the bus
2061  // |
2062  // |----
2063  // |
2064  else
2065  {
2066  // test is bus exists above the wire
2067  if( TestSegmentHit(
2068  linestart + wxPoint( 0, -100 ), busstart, busend, 0 ) )
2069  {
2070  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2071  linestart + wxPoint( 0, -100 ), false );
2072  busEntry->SetFlags( IS_NEW );
2073  m_currentSheet->GetScreen()->Append( busEntry );
2074  moveLabels( line, linestart + wxPoint( 100, 0 ) );
2075  line->SetStartPoint( linestart + wxPoint( 100, 0 ) );
2076  }
2077  // test is bus exists below the wire
2078  else if( TestSegmentHit(
2079  linestart + wxPoint( 0, 100 ), busstart, busend, 0 ) )
2080  {
2081  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2082  linestart + wxPoint( 0, 100 ), true );
2083  busEntry->SetFlags( IS_NEW );
2084  m_currentSheet->GetScreen()->Append( busEntry );
2085  moveLabels( line, linestart + wxPoint( 100, 0 ) );
2086  line->SetStartPoint( linestart + wxPoint( 100, 0 ) );
2087  }
2088  else
2089  {
2090  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2091  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2092 
2093  SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart );
2094  m_currentSheet->GetScreen()->Append( marker );
2095  }
2096  }
2097  }
2098 
2099  // Same thing but test end of the wire instead.
2100  if( TestSegmentHit( lineend, busstart, busend, 0 ) )
2101  {
2102  // Wire end is on the vertical bus
2103 
2104  // if the start of the wire is to the left of the bus
2105  if( linestart.x < busstart.x )
2106  {
2107  // Test if bus exists above the wire
2108  if( TestSegmentHit( lineend + wxPoint( 0, 100 ), busstart, busend, 0 ) )
2109  {
2110  // |
2111  // ___/|
2112  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2113  lineend + wxPoint( -100, 0 ), false );
2114  busEntry->SetFlags( IS_NEW );
2115  m_currentSheet->GetScreen()->Append( busEntry );
2116  moveLabels( line, lineend + wxPoint( -100, 0 ) );
2117  line->SetEndPoint( lineend + wxPoint( -100, 0 ) );
2118  }
2119  // Test if bus exists below the wire
2120  else if( TestSegmentHit(
2121  lineend + wxPoint( 0, -100 ), busstart, busend, 0 ) )
2122  {
2123  SCH_BUS_WIRE_ENTRY* busEntry =
2124  new SCH_BUS_WIRE_ENTRY( lineend + wxPoint( -100, 0 ), true );
2125  busEntry->SetFlags( IS_NEW );
2126  m_currentSheet->GetScreen()->Append( busEntry );
2127  moveLabels( line, lineend + wxPoint( -100, 0 ) );
2128  line->SetEndPoint( lineend + wxPoint( -100, 0 ) );
2129  }
2130  else
2131  {
2132  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2133  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2134 
2135  SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend );
2136  m_currentSheet->GetScreen()->Append( marker );
2137  }
2138  }
2139  // else the start of the wire is to the right of the bus
2140  // |
2141  // |----
2142  // |
2143  else
2144  {
2145  // test if bus existed above the wire
2146  if( TestSegmentHit(
2147  lineend + wxPoint( 0, -100 ), busstart, busend, 0 ) )
2148  {
2149  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2150  lineend + wxPoint( 0, -100 ), false );
2151  busEntry->SetFlags( IS_NEW );
2152  m_currentSheet->GetScreen()->Append( busEntry );
2153  moveLabels( line, lineend + wxPoint( 100, 0 ) );
2154  line->SetEndPoint( lineend + wxPoint( 100, 0 ) );
2155  }
2156  // test if bus existed below the wire
2157  else if( TestSegmentHit(
2158  lineend + wxPoint( 0, 100 ), busstart, busend, 0 ) )
2159  {
2160  SCH_BUS_WIRE_ENTRY* busEntry =
2161  new SCH_BUS_WIRE_ENTRY( lineend + wxPoint( 0, 100 ), true );
2162  busEntry->SetFlags( IS_NEW );
2163  m_currentSheet->GetScreen()->Append( busEntry );
2164  moveLabels( line, lineend + wxPoint( 100, 0 ) );
2165  line->SetEndPoint( lineend + wxPoint( 100, 0 ) );
2166  }
2167  else
2168  {
2169  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2170  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2171 
2172  SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend );
2173  m_currentSheet->GetScreen()->Append( marker );
2174  }
2175  }
2176  }
2177  } // if( linestart.y == lineend.y && busstart.x == busend.x)
2178 
2179  // Test for horizontal wire and vertical bus
2180  if( linestart.x == lineend.x && busstart.y == busend.y )
2181  {
2182  if( TestSegmentHit( linestart, busstart, busend, 0 ) )
2183  {
2184  // Wire start is on the bus
2185  // If wire end is above the bus,
2186  if( lineend.y < busstart.y )
2187  {
2188  // Test for bus existance to the left of the wire
2189  if( TestSegmentHit(
2190  linestart + wxPoint( -100, 0 ), busstart, busend, 0 ) )
2191  {
2192  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2193  linestart + wxPoint( -100, 0 ), true );
2194  busEntry->SetFlags( IS_NEW );
2195  m_currentSheet->GetScreen()->Append( busEntry );
2196  moveLabels( line, linestart + wxPoint( 0, -100 ) );
2197  line->SetStartPoint( linestart + wxPoint( 0, -100 ) );
2198  }
2199  else if( TestSegmentHit(
2200  linestart + wxPoint( 100, 0 ), busstart, busend, 0 ) )
2201  {
2202  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2203  linestart + wxPoint( 0, 100 ), false );
2204  busEntry->SetFlags( IS_NEW );
2205  m_currentSheet->GetScreen()->Append( busEntry );
2206  moveLabels( line, linestart + wxPoint( 0, -100 ) );
2207  line->SetStartPoint( linestart + wxPoint( 0, -100 ) );
2208  }
2209  else
2210  {
2211  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2212  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2213 
2214  SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart );
2215  m_currentSheet->GetScreen()->Append( marker );
2216  }
2217  }
2218  else // wire end is below the bus.
2219  {
2220  // Test for bus existance to the left of the wire
2221  if( TestSegmentHit(
2222  linestart + wxPoint( -100, 0 ), busstart, busend, 0 ) )
2223  {
2224  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2225  linestart + wxPoint( -100, 0 ), false );
2226  busEntry->SetFlags( IS_NEW );
2227  m_currentSheet->GetScreen()->Append( busEntry );
2228  moveLabels( line, linestart + wxPoint( 0, 100 ) );
2229  line->SetStartPoint( linestart + wxPoint( 0, 100 ) );
2230  }
2231  else if( TestSegmentHit(
2232  linestart + wxPoint( 100, 0 ), busstart, busend, 0 ) )
2233  {
2234  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2235  linestart + wxPoint( 100, 0 ), true );
2236  busEntry->SetFlags( IS_NEW );
2237  m_currentSheet->GetScreen()->Append( busEntry );
2238  moveLabels( line, linestart + wxPoint( 0, 100 ) );
2239  line->SetStartPoint( linestart + wxPoint( 0, 100 ) );
2240  }
2241  else
2242  {
2243  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2244  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2245 
2246  SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart );
2247  m_currentSheet->GetScreen()->Append( marker );
2248  }
2249  }
2250  }
2251 
2252  if( TestSegmentHit( lineend, busstart, busend, 0 ) )
2253  {
2254  // Wire end is on the bus
2255  // If wire start is above the bus,
2256 
2257  if( linestart.y < busstart.y )
2258  {
2259  // Test for bus existance to the left of the wire
2260  if( TestSegmentHit(
2261  lineend + wxPoint( -100, 0 ), busstart, busend, 0 ) )
2262  {
2263  SCH_BUS_WIRE_ENTRY* busEntry =
2264  new SCH_BUS_WIRE_ENTRY( lineend + wxPoint( -100, 0 ), true );
2265  busEntry->SetFlags( IS_NEW );
2266  m_currentSheet->GetScreen()->Append( busEntry );
2267  moveLabels( line, lineend + wxPoint( 0, -100 ) );
2268  line->SetEndPoint( lineend + wxPoint( 0, -100 ) );
2269  }
2270  else if( TestSegmentHit(
2271  lineend + wxPoint( 100, 0 ), busstart, busend, 0 ) )
2272  {
2273  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2274  lineend + wxPoint( 0, -100 ), false );
2275  busEntry->SetFlags( IS_NEW );
2276  m_currentSheet->GetScreen()->Append( busEntry );
2277  moveLabels( line, lineend + wxPoint( 0, -100 ) );
2278  line->SetEndPoint( lineend + wxPoint( 0, -100 ) );
2279  }
2280  else
2281  {
2282  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2283  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2284 
2285  SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend );
2286  m_currentSheet->GetScreen()->Append( marker );
2287  }
2288  }
2289  else // wire end is below the bus.
2290  {
2291  // Test for bus existance to the left of the wire
2292  if( TestSegmentHit(
2293  lineend + wxPoint( -100, 0 ), busstart, busend, 0 ) )
2294  {
2295  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY(
2296  lineend + wxPoint( -100, 0 ), false );
2297  busEntry->SetFlags( IS_NEW );
2298  m_currentSheet->GetScreen()->Append( busEntry );
2299  moveLabels( line, lineend + wxPoint( 0, 100 ) );
2300  line->SetEndPoint( lineend + wxPoint( 0, 100 ) );
2301  }
2302  else if( TestSegmentHit(
2303  lineend + wxPoint( 100, 0 ), busstart, busend, 0 ) )
2304  {
2305  SCH_BUS_WIRE_ENTRY* busEntry =
2306  new SCH_BUS_WIRE_ENTRY( lineend + wxPoint( 0, 100 ), true );
2307  busEntry->SetFlags( IS_NEW );
2308  m_currentSheet->GetScreen()->Append( busEntry );
2309  moveLabels( line, lineend + wxPoint( 0, 100 ) );
2310  line->SetEndPoint( lineend + wxPoint( 0, 100 ) );
2311  }
2312  else
2313  {
2314  ERC_ITEM* ercItem = ERC_ITEM::Create( 0 );
2315  ercItem->SetErrorMessage( _( "Bus Entry needed" ) );
2316 
2317  SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend );
2318  m_currentSheet->GetScreen()->Append( marker );
2319  }
2320  }
2321  }
2322  }
2323 
2324  linestart = line->GetStartPoint();
2325  lineend = line->GetEndPoint();
2326  busstart = bus->GetStartPoint();
2327  busend = bus->GetEndPoint();
2328 
2329  // bus entry wire isn't horizontal or vertical
2330  if( TestSegmentHit( linestart, busstart, busend, 0 ) )
2331  {
2332  wxPoint wirevector = linestart - lineend;
2333 
2334  if( wirevector.x > 0 )
2335  {
2336  if( wirevector.y > 0 )
2337  {
2338  wxPoint p = linestart + wxPoint( -100, -100 );
2339  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, false );
2340  busEntry->SetFlags( IS_NEW );
2341  m_currentSheet->GetScreen()->Append( busEntry );
2342  moveLabels( line, p );
2343 
2344  if( p == lineend ) // wire is overlapped by bus entry symbol
2345  {
2346  m_currentSheet->GetScreen()->DeleteItem( line );
2347  line = nullptr;
2348  }
2349  else
2350  {
2351  line->SetStartPoint( p );
2352  }
2353  }
2354  else
2355  {
2356  wxPoint p = linestart + wxPoint( -100, 100 );
2357  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, true );
2358  busEntry->SetFlags( IS_NEW );
2359  m_currentSheet->GetScreen()->Append( busEntry );
2360 
2361  moveLabels( line, p );
2362 
2363  if( p == lineend ) // wire is overlapped by bus entry symbol
2364  {
2365  m_currentSheet->GetScreen()->DeleteItem( line );
2366  line = nullptr;
2367  }
2368  else
2369  {
2370  line->SetStartPoint( p );
2371  }
2372  }
2373  }
2374  else
2375  {
2376  if( wirevector.y > 0 )
2377  {
2378  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( linestart, true );
2379  busEntry->SetFlags( IS_NEW );
2380  m_currentSheet->GetScreen()->Append( busEntry );
2381 
2382  moveLabels( line, linestart + wxPoint( 100, -100 ) );
2383 
2384  if( linestart + wxPoint( 100, -100 )
2385  == lineend ) // wire is overlapped by bus entry symbol
2386  {
2387  m_currentSheet->GetScreen()->DeleteItem( line );
2388  line = nullptr;
2389  }
2390  else
2391  {
2392  line->SetStartPoint( linestart + wxPoint( 100, -100 ) );
2393  }
2394  }
2395  else
2396  {
2397  SCH_BUS_WIRE_ENTRY* busEntry =
2398  new SCH_BUS_WIRE_ENTRY( linestart, false );
2399  busEntry->SetFlags( IS_NEW );
2400  m_currentSheet->GetScreen()->Append( busEntry );
2401  moveLabels( line, linestart + wxPoint( 100, 100 ) );
2402 
2403  if( linestart + wxPoint( 100, 100 )
2404  == lineend ) // wire is overlapped by bus entry symbol
2405  {
2406  m_currentSheet->GetScreen()->DeleteItem( line );
2407  line = nullptr;
2408  }
2409  else
2410  {
2411  line->SetStartPoint( linestart + wxPoint( 100, 100 ) );
2412  }
2413  }
2414  }
2415  }
2416 
2417  if( line && TestSegmentHit( lineend, busstart, busend, 0 ) )
2418  {
2419  wxPoint wirevector = linestart - lineend;
2420 
2421  if( wirevector.x > 0 )
2422  {
2423  if( wirevector.y > 0 )
2424  {
2425  wxPoint p = lineend + wxPoint( 100, 100 );
2426  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( lineend, false );
2427  busEntry->SetFlags( IS_NEW );
2428  m_currentSheet->GetScreen()->Append( busEntry );
2429 
2430  moveLabels( line, p );
2431 
2432  if( p == linestart ) // wire is overlapped by bus entry symbol
2433  {
2434  m_currentSheet->GetScreen()->DeleteItem( line );
2435  }
2436  else
2437  {
2438  line->SetEndPoint( p );
2439  }
2440  }
2441  else
2442  {
2443  wxPoint p = lineend + wxPoint( 100, -100 );
2444  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( lineend, true );
2445  busEntry->SetFlags( IS_NEW );
2446  m_currentSheet->GetScreen()->Append( busEntry );
2447 
2448  moveLabels( line, p );
2449 
2450  if( p == linestart ) // wire is overlapped by bus entry symbol
2451  {
2452  m_currentSheet->GetScreen()->DeleteItem( line );
2453  }
2454  else
2455  {
2456  line->SetEndPoint( p );
2457  }
2458  }
2459  }
2460  else
2461  {
2462  if( wirevector.y > 0 )
2463  {
2464  wxPoint p = lineend + wxPoint( -100, 100 );
2465  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, true );
2466  busEntry->SetFlags( IS_NEW );
2467  m_currentSheet->GetScreen()->Append( busEntry );
2468  moveLabels( line, p );
2469 
2470  if( p == linestart ) // wire is overlapped by bus entry symbol
2471  {
2472  m_currentSheet->GetScreen()->DeleteItem( line );
2473  }
2474  else
2475  {
2476  line->SetEndPoint( p );
2477  }
2478  }
2479  else
2480  {
2481  wxPoint p = lineend + wxPoint( -100, -100 );
2482  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, false );
2483  busEntry->SetFlags( IS_NEW );
2484  m_currentSheet->GetScreen()->Append( busEntry );
2485  moveLabels( line, p );
2486 
2487  if( p == linestart ) // wire is overlapped by bus entry symbol
2488  {
2489  m_currentSheet->GetScreen()->DeleteItem( line );
2490  }
2491  else
2492  {
2493  line->SetEndPoint( p );
2494  }
2495  }
2496  }
2497  }
2498  }
2499  }
2500  } // for ( bus ..
2501 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
wxPoint GetStartPoint() const
Definition: sch_line.h:94
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
void SetEndPoint(const wxPoint &aPosition)
Definition: sch_line.h:98
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
#define IS_NEW
New item, just created.
Definition: base_struct.h:117
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:232
void DeleteItem(SCH_ITEM *aItem)
Removes aItem from the linked list and deletes the object.
Definition: sch_screen.cpp:283
iterator end()
Definition: sch_rtree.h:253
void SetStartPoint(const wxPoint &aPosition)
Definition: sch_line.h:95
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:272
static ERC_ITEM * Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:144
iterator begin()
Definition: sch_rtree.h:208
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
#define _(s)
Definition: 3d_actions.cpp:33
EE_RTREE & Items()
Definition: sch_screen.h:158
void moveLabels(SCH_ITEM *aWire, const wxPoint &aNewEndPoint)
Moves any labels on the wire to the new end point of the wire.
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
Class for a wire to bus entry.
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
wxPoint GetEndPoint() const
Definition: sch_line.h:97

References _, ERC_ITEM::Create(), SCH_LINE::GetEndPoint(), SCH_ITEM::GetLayer(), GetLayer(), SCH_LINE::GetStartPoint(), IS_NEW, LAYER_BUS, LAYER_WIRE, SCH_LINE_T, SCH_LINE::SetEndPoint(), RC_ITEM::SetErrorMessage(), EDA_ITEM::SetFlags(), SCH_LINE::SetStartPoint(), TestSegmentHit(), wxPoint::x, and wxPoint::y.

◆ addImplicitConnections()

void SCH_EAGLE_PLUGIN::addImplicitConnections ( SCH_COMPONENT aComponent,
SCH_SCREEN aScreen,
bool  aUpdateSet 
)
private

Creates net labels to emulate implicit connections in Eagle.

Each named power input pin creates an implicit connection in Eagle. To emulate this behavior one needs to attach global net labels to the mentioned pins. This is is also expected for the units that are not instantiated in the schematics, therefore such units need to be stored in order to create them at later stage.

Parameters
aComponentis the component to process.
aScreenis the screen where net labels should be added.
aUpdateSetdecides whether the missing units data should be updated.

Definition at line 2534 of file sch_eagle_plugin.cpp.

2536 {
2537  wxCHECK( aComponent->GetPartRef(), /*void*/ );
2538 
2539  // Normally power parts also have power input pins,
2540  // but they already force net names on the attached wires
2541  if( aComponent->GetPartRef()->IsPower() )
2542  return;
2543 
2544  int unit = aComponent->GetUnit();
2545  const wxString reference = aComponent->GetField( REFERENCE )->GetText();
2546  std::vector<LIB_PIN*> pins;
2547  aComponent->GetPartRef()->GetPins( pins );
2548  std::set<int> missingUnits;
2549 
2550  // Search all units for pins creating implicit connections
2551  for( const auto& pin : pins )
2552  {
2553  if( pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
2554  {
2555  bool pinInUnit = !unit || pin->GetUnit() == unit; // pin belongs to the tested unit
2556 
2557  // Create a global net label only if there are no other wires/pins attached
2558  if( pinInUnit && !checkConnections( aComponent, pin ) )
2559  {
2560  // Create a net label to force the net name on the pin
2561  SCH_GLOBALLABEL* netLabel = new SCH_GLOBALLABEL;
2562  netLabel->SetPosition( aComponent->GetPinPhysicalPosition( pin ) );
2563  netLabel->SetText( extractNetName( pin->GetName() ) );
2564  netLabel->SetTextSize( wxSize( Mils2iu( 10 ), Mils2iu( 10 ) ) );
2566  aScreen->Append( netLabel );
2567  }
2568 
2569  else if( !pinInUnit && aUpdateSet )
2570  {
2571  // Found a pin creating implicit connection information in another unit.
2572  // Such units will be instantiated if they do not appear in another sheet and
2573  // processed later.
2574  wxASSERT( pin->GetUnit() );
2575  missingUnits.insert( pin->GetUnit() );
2576  }
2577  }
2578  }
2579 
2580  if( aUpdateSet )
2581  {
2582  auto cmpIt = m_missingCmps.find( reference );
2583 
2584  // Set the flag indicating this unit has been processed
2585  if( cmpIt != m_missingCmps.end() )
2586  cmpIt->second.units[unit] = false;
2587 
2588  // Save the units that need later processing
2589  else if( !missingUnits.empty() )
2590  {
2591  EAGLE_MISSING_CMP& entry = m_missingCmps[reference];
2592  entry.cmp = aComponent;
2593 
2594  for( int i : missingUnits )
2595  entry.units.emplace( i, true );
2596  }
2597  }
2598 }
power input (GND, VCC for ICs). Must be connected to a power output.
bool checkConnections(const SCH_COMPONENT *aComponent, const LIB_PIN *aPin) const
Checks if there are other wires or pins at the position of the tested pin
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
Map references to missing component units data
Field Reference of part, i.e. "IC21".
int GetUnit() const
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
std::unique_ptr< LIB_PART > & GetPartRef()
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
static wxString extractNetName(const wxString &aPinName)
Extracts the net name part from a pin name (e.g. return 'GND' for pin named 'GND@2')
void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle) override
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:900
void SetPosition(const wxPoint &aPosition) override
Set the schematic item position to aPosition.
Definition: sch_text.h:314
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126

References SCH_SCREEN::Append(), SCH_EAGLE_PLUGIN::EAGLE_MISSING_CMP::cmp, extractNetName(), SCH_COMPONENT::GetField(), SCH_COMPONENT::GetPartRef(), SCH_COMPONENT::GetPinPhysicalPosition(), EDA_TEXT::GetText(), SCH_COMPONENT::GetUnit(), LABEL_SPIN_STYLE::LEFT, PT_POWER_IN, REFERENCE, SCH_GLOBALLABEL::SetLabelSpinStyle(), SCH_TEXT::SetPosition(), EDA_TEXT::SetText(), EDA_TEXT::SetTextSize(), and SCH_EAGLE_PLUGIN::EAGLE_MISSING_CMP::units.

◆ adjustNetLabels()

void SCH_EAGLE_PLUGIN::adjustNetLabels ( )
private

Moves net labels that are detached from any wire to the nearest wire

Definition at line 1874 of file sch_eagle_plugin.cpp.

1875 {
1876  // Eagle supports detached labels, so a label does not need to be placed on a wire
1877  // to be associated with it. KiCad needs to move them, so the labels actually touch the
1878  // corresponding wires.
1879 
1880  // Sort the intersection points to speed up the search process
1881  std::sort( m_wireIntersections.begin(), m_wireIntersections.end() );
1882 
1883  auto onIntersection = [&]( const VECTOR2I& aPos ) {
1884  return std::binary_search( m_wireIntersections.begin(), m_wireIntersections.end(), aPos );
1885  };
1886 
1887  for( auto& segDesc : m_segments )
1888  {
1889  for( SCH_TEXT* label : segDesc.labels )
1890  {
1891  VECTOR2I labelPos( label->GetPosition() );
1892  const SEG* segAttached = segDesc.LabelAttached( label );
1893 
1894  if( segAttached && !onIntersection( labelPos ) )
1895  continue; // label is placed correctly
1896 
1897 
1898  // Move the label to the nearest wire
1899  if( !segAttached )
1900  {
1901  std::tie( labelPos, segAttached ) =
1902  findNearestLinePoint( label->GetPosition(), segDesc.segs );
1903 
1904  if( !segAttached ) // we cannot do anything
1905  continue;
1906  }
1907 
1908 
1909  // Create a vector pointing in the direction of the wire, 50 mils long
1910  VECTOR2I wireDirection( segAttached->B - segAttached->A );
1911  wireDirection = wireDirection.Resize( Mils2iu( 50 ) );
1912  const VECTOR2I origPos( labelPos );
1913 
1914  // Flags determining the search direction
1915  bool checkPositive = true, checkNegative = true, move = false;
1916  int trial = 0;
1917 
1918  // Be sure the label is not placed on a wire intersection
1919  while( ( !move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
1920  {
1921  move = false;
1922 
1923  // Move along the attached wire to find the new label position
1924  if( trial % 2 == 1 )
1925  {
1926  labelPos = wxPoint( origPos + wireDirection * trial / 2 );
1927  move = checkPositive = segAttached->Contains( labelPos );
1928  }
1929  else
1930  {
1931  labelPos = wxPoint( origPos - wireDirection * trial / 2 );
1932  move = checkNegative = segAttached->Contains( labelPos );
1933  }
1934 
1935  ++trial;
1936  }
1937 
1938  if( move )
1939  label->SetPosition( wxPoint( labelPos ) );
1940  }
1941  }
1942 
1943  m_segments.clear();
1944  m_wireIntersections.clear();
1945 }
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const wxPoint &aPoint, const std::vector< SEG > &aLines) const
std::vector< VECTOR2I > m_wireIntersections
Wire intersection points, used for quick checks whether placing a net label in a particular place wou...
wxPoint GetPosition() const override
Definition: sch_text.h:313
Definition: seg.h:39
std::vector< SEG_DESC > m_segments
Segments representing wires for intersection checking
void SetPosition(const wxPoint &aPosition) override
Set the schematic item position to aPosition.
Definition: sch_text.h:314

References SCH_TEXT::GetPosition(), VECTOR2< T >::Resize(), and SCH_TEXT::SetPosition().

◆ checkConnections()

bool SCH_EAGLE_PLUGIN::checkConnections ( const SCH_COMPONENT aComponent,
const LIB_PIN aPin 
) const
private

Checks if there are other wires or pins at the position of the tested pin

Definition at line 2519 of file sch_eagle_plugin.cpp.

2521 {
2522  wxPoint pinPosition = aComponent->GetPinPhysicalPosition( aPin );
2523  auto pointIt = m_connPoints.find( pinPosition );
2524 
2525  if( pointIt == m_connPoints.end() )
2526  return false;
2527 
2528  const auto& items = pointIt->second;
2529  wxASSERT( items.find( aPin ) != items.end() );
2530  return items.size() > 1;
2531 }
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
Positions of pins and wire endings mapped to its parent

References SCH_COMPONENT::GetPinPhysicalPosition().

◆ CheckHeader()

bool SCH_EAGLE_PLUGIN::CheckHeader ( const wxString &  aFileName)
overridevirtual

Return true if the first line in aFileName begins with the expected header.

Parameters
aFileNameis the name of the file to use as input

Reimplemented from SCH_PLUGIN.

Definition at line 1948 of file sch_eagle_plugin.cpp.

1949 {
1950  // Open file and check first line
1951  wxTextFile tempFile;
1952 
1953  tempFile.Open( aFileName );
1954  wxString firstline;
1955  // read the first line
1956  firstline = tempFile.GetFirstLine();
1957  wxString secondline = tempFile.GetNextLine();
1958  wxString thirdline = tempFile.GetNextLine();
1959  tempFile.Close();
1960 
1961  return firstline.StartsWith( "<?xml" ) && secondline.StartsWith( "<!DOCTYPE eagle SYSTEM" )
1962  && thirdline.StartsWith( "<eagle version" );
1963 }

◆ countNets()

void SCH_EAGLE_PLUGIN::countNets ( wxXmlNode *  aSchematicNode)
private

Definition at line 512 of file sch_eagle_plugin.cpp.

513 {
514  // Map all children into a readable dictionary
515  NODE_MAP schematicChildren = MapChildren( aSchematicNode );
516  // Loop through all the sheets
517 
518  wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, "sheets" );
519 
520  while( sheetNode )
521  {
522  NODE_MAP sheetChildren = MapChildren( sheetNode );
523  // Loop through all nets
524  // From the DTD: "Net is an electrical connection in a schematic."
525  wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
526 
527  while( netNode )
528  {
529  wxString netName = netNode->GetAttribute( "name" );
530 
531  if( m_netCounts.count( netName ) )
532  m_netCounts[netName] = m_netCounts[netName] + 1;
533  else
534  m_netCounts[netName] = 1;
535 
536  // Get next net
537  netNode = netNode->GetNext();
538  }
539 
540  sheetNode = sheetNode->GetNext();
541  }
542 }
std::map< wxString, int > m_netCounts
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:58

References getChildrenNodes(), and MapChildren().

◆ CreateSymbolLib()

void SCH_PLUGIN::CreateSymbolLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Create a new empty symbol library at aLibraryPath.

It is an error to attempt to create an existing library or to attempt to create on a "read only" location.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the library create function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the library, or creating it.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 109 of file sch_plugin.cpp.

110 {
111  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
112  not_implemented( this, __FUNCTION__ );
113 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ DeleteSymbol()

void SCH_PLUGIN::DeleteSymbol ( const wxString &  aLibraryPath,
const wxString &  aSymbolName,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Delete the entire LIB_PART associated with aAliasName from the library aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several symbols.
aSymbolNameis the name of a LIB_PART associated with it's root LIB_PART object to delete from the specified library.
aPropertiesis an associative array that can be used to tell the library delete function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the alias or the library or deleting it.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 101 of file sch_plugin.cpp.

103 {
104  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
105  not_implemented( this, __FUNCTION__ );
106 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ DeleteSymbolLib()

bool SCH_PLUGIN::DeleteSymbolLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Delete an existing symbol library and returns true if successful, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.

Parameters
aLibraryPathis a locator for the "library", usually a directory or file which will contain symbols.
aPropertiesis an associative array that can be used to tell the library delete implementation function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
true if library deleted or false if library did not exist.
Exceptions
IO_ERRORif there is a problem deleting an existing library.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 116 of file sch_plugin.cpp.

117 {
118  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
119  not_implemented( this, __FUNCTION__ );
120  return false;
121 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ EnumerateSymbolLib() [1/2]

void SCH_PLUGIN::EnumerateSymbolLib ( wxArrayString &  aSymbolNameList,
const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Populate a list of LIB_PART alias names contained within the library aLibraryPath.

Parameters
aSymbolNameListis an array to populate with the LIB_PART names associated with the library.
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing one or more LIB_PART objects.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif the library cannot be found, the part library cannot be loaded.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 66 of file sch_plugin.cpp.

69 {
70  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
71  not_implemented( this, __FUNCTION__ );
72 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ EnumerateSymbolLib() [2/2]

void SCH_PLUGIN::EnumerateSymbolLib ( std::vector< LIB_PART * > &  aSymbolList,
const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Populate a list of LIB_PART aliases contained within the library aLibraryPath.

Note
It is the reponsibility of the caller to delete the returned object from the heap. Failure to do this will result in memory leaks.
Parameters
aSymbolListis an array to populate with the LIB_PART pointers associated with the library.
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing one or more LIB_PART objects.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif the library cannot be found, the part library cannot be loaded.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 75 of file sch_plugin.cpp.

78 {
79  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
80  not_implemented( this, __FUNCTION__ );
81 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ findNearestLinePoint()

std::pair< VECTOR2I, const SEG * > SCH_EAGLE_PLUGIN::findNearestLinePoint ( const wxPoint aPoint,
const std::vector< SEG > &  aLines 
) const
private

Definition at line 1036 of file sch_eagle_plugin.cpp.

1038 {
1039  VECTOR2I nearestPoint;
1040  const SEG* nearestLine = nullptr;
1041 
1042  float d, mindistance = std::numeric_limits<float>::max();
1043 
1044  // Find the nearest start, middle or end of a line from the list of lines.
1045  for( const SEG& line : aLines )
1046  {
1047  auto testpoint = line.A;
1048  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1049 
1050  if( d < mindistance )
1051  {
1052  mindistance = d;
1053  nearestPoint = testpoint;
1054  nearestLine = &line;
1055  }
1056 
1057  testpoint = line.Center();
1058  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1059 
1060  if( d < mindistance )
1061  {
1062  mindistance = d;
1063  nearestPoint = testpoint;
1064  nearestLine = &line;
1065  }
1066 
1067  testpoint = line.B;
1068  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1069 
1070  if( d < mindistance )
1071  {
1072  mindistance = d;
1073  nearestPoint = testpoint;
1074  nearestLine = &line;
1075  }
1076  }
1077 
1078  return std::make_pair( nearestPoint, nearestLine );
1079 }
VECTOR2I Center() const
Returns the center point of the line
Definition: seg.h:350
Definition: seg.h:39
VECTOR2I B
Definition: seg.h:48

References SEG::B, SEG::Center(), wxPoint::x, and wxPoint::y.

◆ fixSymbolName()

wxString SCH_EAGLE_PLUGIN::fixSymbolName ( const wxString &  aName)
staticprivate

Fixes invalid characters in Eagle symbol names.

It changes invalid characters to underscores.

Parameters
aNameis the symbol name to be fixed.
Returns
Fixed symbol name.

Definition at line 2601 of file sch_eagle_plugin.cpp.

2602 {
2603  wxString ret = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
2604 
2605  return ret;
2606 }
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, LIB_ID_TYPE aType, bool aLib=false)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:352

References LIB_ID::FixIllegalChars(), and LIB_ID::ID_SCH.

◆ GetError()

const wxString & SCH_PLUGIN::GetError ( ) const
virtualinherited

Return an error string to the caller.

This is useful for schematic loaders that can load partial schematics where throwing an exception would be problematic such as the KiCad legacy plugin.

Returns
an unformatted string containing errors if any.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 176 of file sch_plugin.cpp.

177 {
178  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
179  not_implemented( this, __FUNCTION__ );
180  static wxString error;
181  return error;
182 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

Referenced by TEST_NETLISTS_FIXTURE::loadSchematic().

◆ GetFileExtension()

const wxString SCH_EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Returns the file extension for the SCH_PLUGIN.

Implements SCH_PLUGIN.

Definition at line 376 of file sch_eagle_plugin.cpp.

377 {
378  return "sch";
379 }

◆ getLibFileName()

wxFileName SCH_EAGLE_PLUGIN::getLibFileName ( )
private

Definition at line 158 of file sch_eagle_plugin.cpp.

159 {
161 
162  return fn;
163 }
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:122
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
const std::string KiCadSymbolLibFileExtension

References KiCadSymbolLibFileExtension.

◆ getLibName()

wxString SCH_EAGLE_PLUGIN::getLibName ( )
private

Definition at line 134 of file sch_eagle_plugin.cpp.

135 {
136  if( m_libName.IsEmpty() )
137  {
138  // Try to come up with a meaningful name
140 
141  if( m_libName.IsEmpty() )
142  {
143  wxFileName fn( m_rootSheet->GetFileName() );
144  m_libName = fn.GetName();
145  }
146 
147  if( m_libName.IsEmpty() )
148  m_libName = "noname";
149 
150  m_libName += "-eagle-import";
152  }
153 
154  return m_libName;
155 }
wxString m_libName
Library name to save symbols.
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:496
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded..
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, LIB_ID_TYPE aType, bool aLib=false)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:352
VTBL_ENTRY const wxString GetProjectName() const
Function GetProjectName returns the short name of the project.
Definition: project.cpp:128

References LIB_ID::FixIllegalChars(), and LIB_ID::ID_SCH.

◆ GetLibraryFileExtension()

const wxString SCH_EAGLE_PLUGIN::GetLibraryFileExtension ( ) const
overridevirtual

Return the library file extension for the SCH_PLUGIN object.

Implements SCH_PLUGIN.

Definition at line 382 of file sch_eagle_plugin.cpp.

383 {
384  return "lbr";
385 }

◆ GetModifyHash()

int SCH_EAGLE_PLUGIN::GetModifyHash ( ) const
overridevirtual

Return the modification hash from the library cache.

Note
This is temporary until the new s-expr file format is implement. The new file format will embed symbols instead of referencing them from the library. This function can be removed when the new file format is implemented.
Returns
the modification hash of the library cache.

Implements SCH_PLUGIN.

Definition at line 388 of file sch_eagle_plugin.cpp.

389 {
390  return 0;
391 }

◆ GetName()

const wxString SCH_EAGLE_PLUGIN::GetName ( ) const
overridevirtual

Returns a brief hard coded name for this SCH_PLUGIN.

Implements SCH_PLUGIN.

Definition at line 370 of file sch_eagle_plugin.cpp.

371 {
372  return "EAGLE";
373 }

◆ IsSymbolLibWritable()

bool SCH_PLUGIN::IsSymbolLibWritable ( const wxString &  aLibraryPath)
virtualinherited

Return true if the library at aLibraryPath is writable.

(Often system libraries are read only because of where they are installed.)

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several symbols.
Exceptions
IO_ERRORif no library at aLibraryPath exists.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 124 of file sch_plugin.cpp.

125 {
126  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
127  not_implemented( this, __FUNCTION__ );
128  return false;
129 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ kiCadLayer()

SCH_LAYER_ID SCH_EAGLE_PLUGIN::kiCadLayer ( int  aEagleLayer)
private

Return the matching layer or return LAYER_NOTES.

Definition at line 218 of file sch_eagle_plugin.cpp.

219 {
220  auto it = m_layerMap.find( aEagleLayer );
221  return it == m_layerMap.end() ? LAYER_NOTES : it->second;
222 }
std::map< int, SCH_LAYER_ID > m_layerMap

References LAYER_NOTES.

◆ Load()

SCH_SHEET * SCH_EAGLE_PLUGIN::Load ( const wxString &  aFileName,
SCHEMATIC aSchematic,
SCH_SHEET aAppendToMe = NULL,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Load information from some input file format that this SCH_PLUGIN implementation knows about, into either a new SCH_SHEET or an existing one.

This may be used to load an entire new SCH_SHEET, or to augment an existing one if aAppendToMe is not NULL.

Parameters
aFileNameis the name of the file to use as input and may be foreign in nature or native in nature.
aKiwayis the KIWAY object used to access the component libraries loaded by the project.
aAppendToMeis an existing SCH_SHEET to append to, but if NULL then this means "do not append, rather load anew".
aPropertiesis an associative array that can be used to tell the loader how to load the file, because it can take any number of additional named arguments that the plugin is known to support. These are tuning parameters for the import or load. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
the successfully loaded schematic, or the same one as aAppendToMe if aAppendToMe was not NULL, and the caller owns it.
Exceptions
IO_ERRORif there is a problem loading, and its contents should say what went wrong, using line number and character offsets of the input file if possible.
Note
No check is being done here to see if the existing symbol library exists so this will overwrite the existing one.

Reimplemented from SCH_PLUGIN.

Definition at line 394 of file sch_eagle_plugin.cpp.

396 {
397  wxASSERT( !aFileName || aSchematic != nullptr );
398  LOCALE_IO toggle; // toggles on, then off, the C locale.
399 
400  // Load the document
401  wxXmlDocument xmlDocument;
402 
403  m_filename = aFileName;
404  m_schematic = aSchematic;
405 
406  if( !xmlDocument.Load( m_filename.GetFullPath() ) )
408  wxString::Format( _( "Unable to read file \"%s\"" ), m_filename.GetFullPath() ) );
409 
410  // Delete on exception, if I own m_rootSheet, according to aAppendToMe
411  unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
412 
413  if( aAppendToMe )
414  {
415  wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
416  m_rootSheet = &aSchematic->Root();
417  }
418  else
419  {
420  m_rootSheet = new SCH_SHEET( aSchematic );
421  m_rootSheet->SetFileName( aFileName );
422  }
423 
424  if( !m_rootSheet->GetScreen() )
425  {
426  SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
427  screen->SetFileName( aFileName );
428  m_rootSheet->SetScreen( screen );
429  }
430 
431  SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
432 
433  wxCHECK_MSG( libTable, NULL, "Could not load symbol lib table." );
434 
435  m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
436  m_properties = std::make_unique<PROPERTIES>();
437  ( *m_properties )[SCH_LEGACY_PLUGIN::PropBuffering] = "";
438 
441  if( !libTable->HasLibrary( getLibName() ) )
442  {
443  // Create a new empty symbol library.
444  m_pi->CreateSymbolLib( getLibFileName().GetFullPath() );
445  wxString libTableUri = "${KIPRJMOD}/" + getLibFileName().GetFullName();
446 
447  // Add the new library to the project symbol library table.
448  libTable->InsertRow(
449  new SYMBOL_LIB_TABLE_ROW( getLibName(), libTableUri, wxString( "KiCad" ) ) );
450 
451  // Save project symbol library table.
452  wxFileName fn( m_schematic->Prj().GetProjectPath(),
454 
455  // So output formatter goes out of scope and closes the file before reloading.
456  {
457  FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
458  libTable->Format( &formatter, 0 );
459  }
460 
461  // Relaod the symbol library table.
463  m_schematic->Prj().SchSymbolLibTable();
464  }
465 
466  // Retrieve the root as current node
467  wxXmlNode* currentNode = xmlDocument.GetRoot();
468 
469  // If the attribute is found, store the Eagle version;
470  // otherwise, store the dummy "0.0" version.
471  m_version = currentNode->GetAttribute( "version", "0.0" );
472 
473  // Map all children into a readable dictionary
474  NODE_MAP children = MapChildren( currentNode );
475 
476  // Load drawing
477  loadDrawing( children["drawing"] );
478 
479  m_pi->SaveLibrary( getLibFileName().GetFullPath() );
480 
481  return m_rootSheet;
482 }
static const wxString & GetSymbolLibTableFileName()
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:216
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:151
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:111
void set(SCH_PLUGIN *aPlugin)
Definition: sch_io_mgr.h:496
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
VTBL_ENTRY const wxString GetProjectPath() const
Function GetProjectPath returns the full path of the project.
Definition: project.cpp:122
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
VTBL_ENTRY void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:252
void SetFileName(wxString aFilename)
Definition: sch_sheet.h:502
#define NULL
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
Plugin to create the KiCad symbol library.
wxFileName getLibFileName()
wxString m_version
Eagle file version.
#define THROW_IO_ERROR(msg)
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indention level of aIndentLevel.
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded..
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
SCH_SHEET & Root() const
Definition: schematic.h:97
void loadDrawing(wxXmlNode *aDrawingNode)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
void SetFileName(const wxString &aFileName)
Definition: sch_screen.h:183
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48

References _, PROJECT::ELEM_SYMBOL_LIB_TABLE, SYMBOL_LIB_TABLE::Format(), Format(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName(), LIB_TABLE::HasLibrary(), LIB_TABLE::InsertRow(), SCHEMATIC::IsValid(), MapChildren(), NULL, SCH_LEGACY_PLUGIN::PropBuffering, SCHEMATIC::Root(), SCH_SCREEN::SetFileName(), and THROW_IO_ERROR.

◆ loadDrawing()

void SCH_EAGLE_PLUGIN::loadDrawing ( wxXmlNode *  aDrawingNode)
private

Definition at line 485 of file sch_eagle_plugin.cpp.

486 {
487  // Map all children into a readable dictionary
488  NODE_MAP drawingChildren = MapChildren( aDrawingNode );
489 
490  // Board nodes should not appear in .sch files
491  // wxXmlNode* board = drawingChildren["board"]
492 
493  // wxXmlNode* grid = drawingChildren["grid"]
494 
495  auto layers = drawingChildren["layers"];
496 
497  if( layers )
498  loadLayerDefs( layers );
499 
500  // wxXmlNode* library = drawingChildren["library"]
501 
502  // wxXmlNode* settings = drawingChildren["settings"]
503 
504  // Load schematic
505  auto schematic = drawingChildren["schematic"];
506 
507  if( schematic )
508  loadSchematic( schematic );
509 }
void loadSchematic(wxXmlNode *aSchematicNode)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
void loadLayerDefs(wxXmlNode *aLayers)
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48

References MapChildren().

◆ loadFieldAttributes()

void SCH_EAGLE_PLUGIN::loadFieldAttributes ( LIB_FIELD aField,
const LIB_TEXT aText 
) const
private

Definition at line 1862 of file sch_eagle_plugin.cpp.

1863 {
1864  aField->SetTextPos( aText->GetPosition() );
1865  aField->SetTextSize( aText->GetTextSize() );
1866  aField->SetTextAngle( aText->GetTextAngle() );
1867  aField->SetBold( aText->IsBold() );
1868  aField->SetVertJustify( aText->GetVertJustify() );
1869  aField->SetHorizJustify( aText->GetHorizJustify() );
1870  aField->SetVisible( true );
1871 }
bool IsBold() const
Definition: eda_text.h:182
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:199
wxPoint GetPosition() const override
Definition: lib_text.h:84
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:246
void SetVisible(bool aVisible)
Definition: eda_text.h:184
double GetTextAngle() const
Definition: eda_text.h:173
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:198
const wxSize & GetTextSize() const
Definition: eda_text.h:238
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:202
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:201
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:166
void SetBold(bool aBold)
Definition: eda_text.h:181

References EDA_TEXT::GetHorizJustify(), LIB_TEXT::GetPosition(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextSize(), EDA_TEXT::GetVertJustify(), EDA_TEXT::IsBold(), EDA_TEXT::SetBold(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetTextAngle(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetVertJustify(), and EDA_TEXT::SetVisible().

◆ loadInstance()

void SCH_EAGLE_PLUGIN::loadInstance ( wxXmlNode *  aInstanceNode)
private

Definition at line 1082 of file sch_eagle_plugin.cpp.

1083 {
1084  auto einstance = EINSTANCE( aInstanceNode );
1085 
1086  SCH_SCREEN* screen = m_currentSheet->GetScreen();
1087 
1088  // Find the part in the list for the sheet.
1089  // Assign the component its value from the part entry
1090  // Calculate the unit number from the gate entry of the instance
1091  // Assign the the LIB_ID from deviceset and device names
1092 
1093  auto part_it = m_partlist.find( einstance.part.Upper() );
1094 
1095  if( part_it == m_partlist.end() )
1096  {
1097  wxLogError( _( "Error parsing Eagle file. "
1098  "Could not find \"%s\" instance but it is referenced in the schematic." ),
1099  einstance.part );
1100 
1101  return;
1102  }
1103 
1104  EPART* epart = part_it->second.get();
1105 
1106  wxString libraryname = epart->library;
1107  wxString gatename = epart->deviceset + epart->device + einstance.gate;
1108  wxString symbolname = wxString( epart->deviceset + epart->device );
1109  symbolname.Replace( "*", "" );
1110  wxString kisymbolname = fixSymbolName( symbolname );
1111 
1112  int unit = m_eagleLibs[libraryname].GateUnit[gatename];
1113 
1114  wxString package;
1115  EAGLE_LIBRARY* elib = &m_eagleLibs[libraryname];
1116 
1117  auto p = elib->package.find( kisymbolname );
1118 
1119  if( p != elib->package.end() )
1120  package = p->second;
1121 
1122  LIB_PART* part =
1123  m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname, m_properties.get() );
1124 
1125  if( !part )
1126  {
1127  wxLogMessage( wxString::Format( _( "Could not find %s in the imported library" ),
1128  kisymbolname ) );
1129  return;
1130  }
1131 
1132  LIB_ID libId( getLibName(), kisymbolname );
1133  std::unique_ptr<SCH_COMPONENT> component( new SCH_COMPONENT() );
1134  component->SetLibId( libId );
1135  component->SetUnit( unit );
1136  component->SetPosition( wxPoint( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) );
1137  component->GetField( FOOTPRINT )->SetText( package );
1138 
1139  if( einstance.rot )
1140  {
1141  component->SetOrientation( kiCadComponentRotation( einstance.rot->degrees ) );
1142 
1143  if( einstance.rot->mirror )
1144  component->MirrorY( einstance.x.ToSchUnits() );
1145  }
1146 
1147  LIB_FIELDS partFields;
1148  part->GetFields( partFields );
1149 
1150  for( auto const& field : partFields )
1151  {
1152  component->GetField( field.GetId() )->ImportValues( field );
1153  component->GetField( field.GetId() )
1154  ->SetTextPos( component->GetPosition() + field.GetTextPos() );
1155  }
1156 
1157  // If there is no footprint assigned, then prepend the reference value
1158  // with a hash character to mute netlist updater complaints
1159  wxString reference = package.IsEmpty() ? '#' + einstance.part : einstance.part;
1160 
1161  // EAGLE allows references to be single digits. This breaks KiCad netlisting, which requires
1162  // parts to have non-digit + digit annotation. If the reference begins with a number,
1163  // we prepend 'UNK' (unknown) for the symbol designator
1164  if( reference.find_first_not_of( "0123456789" ) == wxString::npos )
1165  reference.Prepend( "UNK" );
1166 
1167  SCH_SHEET_PATH sheetpath;
1168  m_rootSheet->LocatePathOfScreen( screen, &sheetpath );
1169  wxString current_sheetpath = sheetpath.PathAsString() + component->m_Uuid.AsString();
1170 
1171  component->GetField( REFERENCE )->SetText( reference );
1172  component->AddHierarchicalReference( current_sheetpath, reference, unit );
1173 
1174  if( epart->value )
1175  component->GetField( VALUE )->SetText( *epart->value );
1176  else
1177  component->GetField( VALUE )->SetText( kisymbolname );
1178 
1179  // Set the visibility of fields.
1180  component->GetField( REFERENCE )->SetVisible( part->GetField( REFERENCE )->IsVisible() );
1181  component->GetField( VALUE )->SetVisible( part->GetField( VALUE )->IsVisible() );
1182 
1183  for( const auto& a : epart->attribute )
1184  {
1185  auto field = component->AddField( *component->GetField( VALUE ) );
1186  field->SetName( a.first );
1187  field->SetText( a.second );
1188  field->SetVisible( false );
1189  }
1190 
1191  for( const auto& a : epart->variant )
1192  {
1193  auto field = component->AddField( *component->GetField( VALUE ) );
1194  field->SetName( "VARIANT_" + a.first );
1195  field->SetText( a.second );
1196  field->SetVisible( false );
1197  }
1198 
1199  bool valueAttributeFound = false;
1200  bool nameAttributeFound = false;
1201 
1202  wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1203 
1204  // Parse attributes for the instance
1205  while( attributeNode )
1206  {
1207  if( attributeNode->GetName() == "attribute" )
1208  {
1209  auto attr = EATTR( attributeNode );
1210  SCH_FIELD* field = NULL;
1211 
1212  if( attr.name.Lower() == "name" )
1213  {
1214  field = component->GetField( REFERENCE );
1215  nameAttributeFound = true;
1216  }
1217  else if( attr.name.Lower() == "value" )
1218  {
1219  field = component->GetField( VALUE );
1220  valueAttributeFound = true;
1221  }
1222  else
1223  {
1224  field = component->FindField( attr.name );
1225 
1226  if( field )
1227  field->SetVisible( false );
1228  }
1229 
1230  if( field )
1231  {
1232 
1233  field->SetPosition( wxPoint( attr.x->ToSchUnits(), -attr.y->ToSchUnits() ) );
1234  int align = attr.align ? *attr.align : ETEXT::BOTTOM_LEFT;
1235  int absdegrees = attr.rot ? attr.rot->degrees : 0;
1236  bool mirror = attr.rot ? attr.rot->mirror : false;
1237 
1238  if( einstance.rot && einstance.rot->mirror )
1239  mirror = !mirror;
1240 
1241  bool spin = attr.rot ? attr.rot->spin : false;
1242 
1243  if( attr.display == EATTR::Off || attr.display == EATTR::NAME )
1244  field->SetVisible( false );
1245 
1246  int rotation = einstance.rot ? einstance.rot->degrees : 0;
1247  int reldegrees = ( absdegrees - rotation + 360.0 );
1248  reldegrees %= 360;
1249 
1251  (EDA_TEXT*) field, align, reldegrees, mirror, spin, absdegrees );
1252  }
1253  }
1254  else if( attributeNode->GetName() == "variant" )
1255  {
1256  wxString variant, value;
1257 
1258  if( attributeNode->GetAttribute( "name", &variant )
1259  && attributeNode->GetAttribute( "value", &value ) )
1260  {
1261  auto field = component->AddField( *component->GetField( VALUE ) );
1262  field->SetName( "VARIANT_" + variant );
1263  field->SetText( value );
1264  field->SetVisible( false );
1265  }
1266  }
1267 
1268  attributeNode = attributeNode->GetNext();
1269  }
1270 
1271  if( einstance.smashed && einstance.smashed.Get() )
1272  {
1273  if( !valueAttributeFound )
1274  component->GetField( VALUE )->SetVisible( false );
1275 
1276  if( !nameAttributeFound )
1277  component->GetField( REFERENCE )->SetVisible( false );
1278  }
1279 
1280  // Save the pin positions
1281  SYMBOL_LIB_TABLE& schLibTable = *m_schematic->Prj().SchSymbolLibTable();
1282  LIB_PART* libSymbol = schLibTable.LoadSymbol( component->GetLibId() );
1283 
1284  wxCHECK( libSymbol, /*void*/ );
1285 
1286  component->SetLibSymbol( new LIB_PART( *libSymbol ) );
1287 
1288  std::vector<LIB_PIN*> pins;
1289  component->GetPins( pins );
1290 
1291  for( const auto& pin : pins )
1292  m_connPoints[component->GetPinPhysicalPosition( pin )].emplace( pin );
1293 
1294  component->ClearFlags();
1295 
1296  screen->Append( component.release() );
1297 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
wxString deviceset
Definition: eagle_parser.h:912
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
wxString library
Definition: eagle_parser.h:911
std::unordered_map< wxString, wxString > package
void SetVisible(bool aVisible)
Definition: eda_text.h:184
LIB_PART * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_PART having aName from the library given by aNickname.
std::map< std::string, std::string > variant
Definition: eagle_parser.h:917
wxString PathAsString() const
Function PathAsString the path uses the time stamps which do not changes even when editing sheet para...
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
opt_wxString value
Definition: eagle_parser.h:915
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:112
static wxString fixSymbolName(const wxString &aName)
Fixes invalid characters in Eagle symbol names.
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
#define NULL
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
Plugin to create the KiCad symbol library.
Define a library symbol object.
wxFileName getLibFileName()
std::map< std::string, std::string > attribute
Definition: eagle_parser.h:916
SCH_SHEET_PATH.
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded..
Field Value of part, i.e. "3.3K".
EATTR parses an Eagle "attribute" XML element.
Definition: eagle_parser.h:602
static COMPONENT_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:668
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
#define _(s)
Definition: 3d_actions.cpp:33
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:218
void SetName(const wxString &aName)
Definition: sch_field.h:112
Schematic symbol object.
Definition: sch_component.h:88
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
wxString device
Definition: eagle_parser.h:913
void SetPosition(const wxPoint &aPosition) override
Set the schematic item position to aPosition.
Definition: sch_field.cpp:558
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
Positions of pins and wire endings mapped to its parent

References _, SCH_SCREEN::Append(), EPART::attribute, ETEXT::BOTTOM_LEFT, EPART::device, EPART::deviceset, eagleToKicadAlignment(), FOOTPRINT, Format(), kiCadComponentRotation(), EPART::library, SYMBOL_LIB_TABLE::LoadSymbol(), EATTR::NAME, NULL, EATTR::Off, EAGLE_LIBRARY::package, SCH_SHEET_PATH::PathAsString(), REFERENCE, SCH_FIELD::SetPosition(), EDA_TEXT::SetVisible(), VALUE, EPART::value, and EPART::variant.

◆ loadJunction()

SCH_JUNCTION * SCH_EAGLE_PLUGIN::loadJunction ( wxXmlNode *  aJunction)
private

Definition at line 989 of file sch_eagle_plugin.cpp.

990 {
991  std::unique_ptr<SCH_JUNCTION> junction( new SCH_JUNCTION );
992 
993  auto ejunction = EJUNCTION( aJunction );
994  wxPoint pos( ejunction.x.ToSchUnits(), -ejunction.y.ToSchUnits() );
995 
996  junction->SetPosition( pos );
997 
998  return junction.release();
999 }
Eagle Junction.
Definition: eagle_parser.h:530

◆ loadLabel()

SCH_TEXT * SCH_EAGLE_PLUGIN::loadLabel ( wxXmlNode *  aLabelNode,
const wxString &  aNetName 
)
private

Definition at line 1002 of file sch_eagle_plugin.cpp.

1003 {
1004  auto elabel = ELABEL( aLabelNode, aNetName );
1005  wxPoint elabelpos( elabel.x.ToSchUnits(), -elabel.y.ToSchUnits() );
1006 
1007  // Determine if the label is local or global depending on
1008  // the number of sheets the net appears in
1009  bool global = m_netCounts[aNetName] > 1;
1010  std::unique_ptr<SCH_TEXT> label;
1011 
1012  if( global )
1013  label.reset( new SCH_GLOBALLABEL );
1014  else
1015  label.reset( new SCH_LABEL );
1016 
1017  label->SetPosition( elabelpos );
1018  label->SetText( escapeName( elabel.netname ) );
1019  label->SetTextSize( wxSize( elabel.size.ToSchUnits(), elabel.size.ToSchUnits() ) );
1020  label->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT );
1021 
1022  if( elabel.rot )
1023  {
1024  label->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) ( KiROUND( elabel.rot->degrees / 90 ) % 4 ) );
1025 
1026  if( elabel.rot->mirror )
1027  {
1028  label->SetLabelSpinStyle( label->GetLabelSpinStyle().MirrorY() );
1029  }
1030  }
1031 
1032  return label.release();
1033 }
std::map< wxString, int > m_netCounts
Eagle label.
Definition: eagle_parser.h:540
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68

References escapeName(), KiROUND(), and LABEL_SPIN_STYLE::RIGHT.

◆ loadLayerDefs()

void SCH_EAGLE_PLUGIN::loadLayerDefs ( wxXmlNode *  aLayers)
private

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>

Definition at line 166 of file sch_eagle_plugin.cpp.

167 {
168  std::vector<ELAYER> eagleLayers;
169 
170  // Get the first layer and iterate
171  wxXmlNode* layerNode = aLayers->GetChildren();
172 
173  while( layerNode )
174  {
175  ELAYER elayer( layerNode );
176  eagleLayers.push_back( elayer );
177 
178  layerNode = layerNode->GetNext();
179  }
180 
181  // match layers based on their names
182  for( const auto& elayer : eagleLayers )
183  {
202  if( elayer.name == "Nets" )
203  {
204  m_layerMap[elayer.number] = LAYER_WIRE;
205  }
206  else if( elayer.name == "Info" || elayer.name == "Guide" )
207  {
208  m_layerMap[elayer.number] = LAYER_NOTES;
209  }
210  else if( elayer.name == "Busses" )
211  {
212  m_layerMap[elayer.number] = LAYER_BUS;
213  }
214  }
215 }
std::map< int, SCH_LAYER_ID > m_layerMap

References LAYER_BUS, LAYER_NOTES, and LAYER_WIRE.

◆ loadLibrary()

EAGLE_LIBRARY * SCH_EAGLE_PLUGIN::loadLibrary ( wxXmlNode *  aLibraryNode,
EAGLE_LIBRARY aEagleLib 
)
private

Definition at line 1300 of file sch_eagle_plugin.cpp.

1302 {
1303  NODE_MAP libraryChildren = MapChildren( aLibraryNode );
1304 
1305  // Loop through the symbols and load each of them
1306  wxXmlNode* symbolNode = getChildrenNodes( libraryChildren, "symbols" );
1307 
1308  while( symbolNode )
1309  {
1310  wxString symbolName = symbolNode->GetAttribute( "name" );
1311  aEagleLibrary->SymbolNodes[symbolName] = symbolNode;
1312  symbolNode = symbolNode->GetNext();
1313  }
1314 
1315  // Loop through the devicesets and load each of them
1316  wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, "devicesets" );
1317 
1318  while( devicesetNode )
1319  {
1320  // Get Device set information
1321  EDEVICE_SET edeviceset = EDEVICE_SET( devicesetNode );
1322 
1323  wxString prefix = edeviceset.prefix ? edeviceset.prefix.Get() : "";
1324 
1325  NODE_MAP aDeviceSetChildren = MapChildren( devicesetNode );
1326  wxXmlNode* deviceNode = getChildrenNodes( aDeviceSetChildren, "devices" );
1327 
1328  // For each device in the device set:
1329  while( deviceNode )
1330  {
1331  // Get device information
1332  EDEVICE edevice = EDEVICE( deviceNode );
1333 
1334  // Create symbol name from deviceset and device names.
1335  wxString symbolName = edeviceset.name + edevice.name;
1336  symbolName.Replace( "*", "" );
1337  wxASSERT( !symbolName.IsEmpty() );
1338  symbolName = fixSymbolName( symbolName );
1339 
1340  if( edevice.package )
1341  aEagleLibrary->package[symbolName] = edevice.package.Get();
1342 
1343  // Create KiCad symbol.
1344  unique_ptr<LIB_PART> kpart( new LIB_PART( symbolName ) );
1345 
1346  // Process each gate in the deviceset for this device.
1347  wxXmlNode* gateNode = getChildrenNodes( aDeviceSetChildren, "gates" );
1348  int gates_count = countChildren( aDeviceSetChildren["gates"], "gate" );
1349  kpart->SetUnitCount( gates_count );
1350  kpart->LockUnits( true );
1351 
1352  LIB_FIELD* reference = kpart->GetField( REFERENCE );
1353 
1354  if( prefix.length() == 0 )
1355  reference->SetVisible( false );
1356  else
1357  // If there is no footprint assigned, then prepend the reference value
1358  // with a hash character to mute netlist updater complaints
1359  reference->SetText( edevice.package ? prefix : '#' + prefix );
1360 
1361  int gateindex = 1;
1362  bool ispower = false;
1363 
1364  while( gateNode )
1365  {
1366  EGATE egate = EGATE( gateNode );
1367 
1368  aEagleLibrary->GateUnit[edeviceset.name + edevice.name + egate.name] = gateindex;
1369 
1370  ispower = loadSymbol( aEagleLibrary->SymbolNodes[egate.symbol], kpart, &edevice,
1371  gateindex, egate.name );
1372 
1373  gateindex++;
1374  gateNode = gateNode->GetNext();
1375  } // gateNode
1376 
1377  kpart->SetUnitCount( gates_count );
1378 
1379  if( gates_count == 1 && ispower )
1380  kpart->SetPower();
1381 
1382  wxString name = fixSymbolName( kpart->GetName() );
1383  kpart->SetName( name );
1384  m_pi->SaveSymbol( getLibFileName().GetFullPath(), new LIB_PART( *kpart.get() ),
1385  m_properties.get() );
1386  aEagleLibrary->KiCadSymbols.insert( name, kpart.release() );
1387 
1388  deviceNode = deviceNode->GetNext();
1389  } // devicenode
1390 
1391  devicesetNode = devicesetNode->GetNext();
1392  } // devicesetNode
1393 
1394  return aEagleLibrary;
1395 }
wxString name
T & Get()
Function Get returns a reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:300
Field object used in symbol libraries.
Definition: lib_field.h:59
void SetVisible(bool aVisible)
Definition: eda_text.h:184
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provides an easy access to the children of an XML node via their names.
Field Reference of part, i.e. "IC21".
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
wxString name
static wxString fixSymbolName(const wxString &aName)
Fixes invalid characters in Eagle symbol names.
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
Plugin to create the KiCad symbol library.
wxString symbol
Definition: eagle_parser.h:963
bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_PART > &aPart, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
Define a library symbol object.
wxFileName getLibFileName()
wxString name
Definition: eagle_parser.h:962
opt_wxString prefix
const char * name
Definition: DXF_plotter.cpp:60
opt_wxString package
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:58

References countChildren(), EAGLE_LIBRARY::GateUnit, OPTIONAL_XML_ATTRIBUTE< T >::Get(), getChildrenNodes(), EAGLE_LIBRARY::KiCadSymbols, MapChildren(), name, EGATE::name, EDEVICE::name, EDEVICE_SET::name, EAGLE_LIBRARY::package, EDEVICE::package, EDEVICE_SET::prefix, REFERENCE, EDA_TEXT::SetText(), EDA_TEXT::SetVisible(), EGATE::symbol, and EAGLE_LIBRARY::SymbolNodes.

◆ loadPin()

LIB_PIN * SCH_EAGLE_PLUGIN::loadPin ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aPin,
EPIN epin,
int  aGateNumber 
)
private

Definition at line 1697 of file sch_eagle_plugin.cpp.

1699 {
1700  std::unique_ptr<LIB_PIN> pin( new LIB_PIN( aPart.get() ) );
1701  pin->SetPosition( wxPoint( aEPin->x.ToSchUnits(), aEPin->y.ToSchUnits() ) );
1702  pin->SetName( aEPin->name );
1703  pin->SetUnit( aGateNumber );
1704 
1705  int roti = aEPin->rot ? aEPin->rot->degrees : 0;
1706 
1707  switch( roti )
1708  {
1709  default:
1710  wxASSERT_MSG( false, wxString::Format( "Unhandled orientation (%d degrees)", roti ) );
1712 
1713  case 0:
1714  pin->SetOrientation( 'R' );
1715  break;
1716 
1717  case 90:
1718  pin->SetOrientation( 'U' );
1719  break;
1720 
1721  case 180:
1722  pin->SetOrientation( 'L' );
1723  break;
1724 
1725  case 270:
1726  pin->SetOrientation( 'D' );
1727  break;
1728  }
1729 
1730  if( aEPin->length )
1731  {
1732  wxString length = aEPin->length.Get();
1733 
1734  if( length == "short" )
1735  {
1736  pin->SetLength( Mils2iu( 100 ) );
1737  }
1738  else if( length == "middle" )
1739  {
1740  pin->SetLength( Mils2iu( 200 ) );
1741  }
1742  else if( length == "long" )
1743  {
1744  pin->SetLength( Mils2iu( 300 ) );
1745  }
1746  else if( length == "point" )
1747  {
1748  pin->SetLength( Mils2iu( 0 ) );
1749  }
1750  }
1751 
1752  // emulate the visibility of pin elements
1753  if( aEPin->visible )
1754  {
1755  wxString visible = aEPin->visible.Get();
1756 
1757  if( visible == "off" )
1758  {
1759  pin->SetNameTextSize( 0 );
1760  pin->SetNumberTextSize( 0 );
1761  }
1762  else if( visible == "pad" )
1763  {
1764  pin->SetNameTextSize( 0 );
1765  }
1766  else if( visible == "pin" )
1767  {
1768  pin->SetNumberTextSize( 0 );
1769  }
1770 
1771  /*
1772  * else if( visible == "both" )
1773  * {
1774  * }
1775  */
1776  }
1777 
1778  if( aEPin->function )
1779  {
1780  wxString function = aEPin->function.Get();
1781 
1782  if( function == "dot" )
1783  {
1784  pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
1785  }
1786  else if( function == "clk" )
1787  {
1788  pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1789  }
1790  else if( function == "dotclk" )
1791  {
1792  pin->SetShape( GRAPHIC_PINSHAPE::INVERTED_CLOCK );
1793  }
1794  }
1795 
1796  return pin.release();
1797 }
#define KI_FALLTHROUGH
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205

References CLOCK, EROT::degrees, Format(), EPIN::function, OPTIONAL_XML_ATTRIBUTE< T >::Get(), INVERTED, INVERTED_CLOCK, KI_FALLTHROUGH, EPIN::length, EPIN::name, EPIN::rot, ECOORD::ToSchUnits(), EPIN::visible, EPIN::x, and EPIN::y.

◆ loadPlainText()

SCH_TEXT * SCH_EAGLE_PLUGIN::loadPlainText ( wxXmlNode *  aSchText)
private

Definition at line 1825 of file sch_eagle_plugin.cpp.

1826 {
1827  std::unique_ptr<SCH_TEXT> schtext( new SCH_TEXT() );
1828  ETEXT etext = ETEXT( aSchText );
1829 
1830  const wxString& thetext = aSchText->GetNodeContent();
1831  schtext->SetText( thetext.IsEmpty() ? "\" \"" : escapeName( thetext ) );
1832  schtext->SetPosition( wxPoint( etext.x.ToSchUnits(), -etext.y.ToSchUnits() ) );
1833  loadTextAttributes( schtext.get(), etext );
1834  schtext->SetItalic( false );
1835 
1836  return schtext.release();
1837 }
int ToSchUnits() const
Definition: eagle_parser.h:437
Eagle text element.
Definition: eagle_parser.h:645
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
ECOORD x
Definition: eagle_parser.h:648
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const
ECOORD y
Definition: eagle_parser.h:649

References escapeName(), ECOORD::ToSchUnits(), ETEXT::x, and ETEXT::y.

◆ loadSchematic()

void SCH_EAGLE_PLUGIN::loadSchematic ( wxXmlNode *  aSchematicNode)
private

Definition at line 545 of file sch_eagle_plugin.cpp.

546 {
547  // Map all children into a readable dictionary
548  NODE_MAP schematicChildren = MapChildren( aSchematicNode );
549  auto partNode = getChildrenNodes( schematicChildren, "parts" );
550  auto libraryNode = getChildrenNodes( schematicChildren, "libraries" );
551  auto sheetNode = getChildrenNodes( schematicChildren, "sheets" );
552 
553  if( !partNode || !libraryNode || !sheetNode )
554  return;
555 
556  while( partNode )
557  {
558  std::unique_ptr<EPART> epart( new EPART( partNode ) );
559 
560  // N.B. Eagle parts are case-insensitive in matching but we keep the display case
561  m_partlist[epart->name.Upper()] = std::move( epart );
562  partNode = partNode->GetNext();
563  }
564 
565  // Loop through all the libraries
566  while( libraryNode )
567  {
568  // Read the library name
569  wxString libName = libraryNode->GetAttribute( "name" );
570 
571  EAGLE_LIBRARY* elib = &m_eagleLibs[libName];
572  elib->name = libName;
573 
574  loadLibrary( libraryNode, &m_eagleLibs[libName] );
575 
576  libraryNode = libraryNode->GetNext();
577  }
578 
579  m_pi->SaveLibrary( getLibFileName().GetFullPath() );
580 
581  // find all nets and count how many sheets they appear on.
582  // local labels will be used for nets found only on that sheet.
583  countNets( aSchematicNode );
584 
585  // Loop through all the sheets
586  int sheet_count = countChildren( sheetNode->GetParent(), "sheet" );
587 
588  // If eagle schematic has multiple sheets then create corresponding subsheets on the root sheet
589  if( sheet_count > 1 )
590  {
591  int x, y, i;
592  i = 1;
593  x = 1;
594  y = 1;
595 
596  while( sheetNode )
597  {
598  wxPoint pos = wxPoint( x * Mils2iu( 1000 ), y * Mils2iu( 1000 ) );
599  std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET( m_rootSheet, pos ) );
600  SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
601 
602  sheet->SetScreen( screen );
603  sheet->GetScreen()->SetFileName( sheet->GetFileName() );
604 
605  m_currentSheet = sheet.get();
606  loadSheet( sheetNode, i );
607  m_rootSheet->GetScreen()->Append( sheet.release() );
608 
609  sheetNode = sheetNode->GetNext();
610  x += 2;
611 
612  if( x > 10 ) // start next row
613  {
614  x = 1;
615  y += 2;
616  }
617 
618  i++;
619  }
620  }
621  else
622  {
623  while( sheetNode )
624  {
626  loadSheet( sheetNode, 0 );
627  sheetNode = sheetNode->GetNext();
628  }
629  }
630 
631 
632  // Handle the missing component units that need to be instantiated
633  // to create the missing implicit connections
634 
635  // Calculate the already placed items bounding box and the page size to determine
636  // placement for the new components
637  wxSize pageSizeIU = m_rootSheet->GetScreen()->GetPageSettings().GetSizeIU();
638  EDA_RECT sheetBbox = getSheetBbox( m_rootSheet );
639  wxPoint newCmpPosition( sheetBbox.GetLeft(), sheetBbox.GetBottom() );
640  int maxY = sheetBbox.GetY();
641 
642  SCH_SHEET_PATH sheetpath;
644 
645  for( auto& cmp : m_missingCmps )
646  {
647  const SCH_COMPONENT* origCmp = cmp.second.cmp;
648 
649  for( auto unitEntry : cmp.second.units )
650  {
651  if( unitEntry.second == false )
652  continue; // unit has been already processed
653 
654  // Instantiate the missing component unit
655  int unit = unitEntry.first;
656  const wxString reference = origCmp->GetField( REFERENCE )->GetText();
657  std::unique_ptr<SCH_COMPONENT> component( (SCH_COMPONENT*) origCmp->Duplicate() );
658  component->SetUnitSelection( &sheetpath, unit );
659  component->SetUnit( unit );
660  component->SetOrientation( 0 );
661  component->AddHierarchicalReference( sheetpath.Path(), reference, unit );
662 
663  // Calculate the placement position
664  EDA_RECT cmpBbox = component->GetBoundingBox();
665  int posY = newCmpPosition.y + cmpBbox.GetHeight();
666  component->SetPosition( wxPoint( newCmpPosition.x, posY ) );
667  newCmpPosition.x += cmpBbox.GetWidth();
668  maxY = std::max( maxY, posY );
669 
670  if( newCmpPosition.x >= pageSizeIU.GetWidth() ) // reached the page boundary?
671  newCmpPosition = wxPoint( sheetBbox.GetLeft(), maxY ); // then start a new row
672 
673  // Add the global net labels to recreate the implicit connections
674  addImplicitConnections( component.get(), m_rootSheet->GetScreen(), false );
675  m_rootSheet->GetScreen()->Append( component.release() );
676  }
677  }
678 
679  m_missingCmps.clear();
680 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
EAGLE_LIBRARY * loadLibrary(wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
int GetLeft() const
Definition: eda_rect.h:122
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
int GetWidth() const
Definition: eda_rect.h:119
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provides an easy access to the children of an XML node via their names.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
Map references to missing component units data
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:180
Field Reference of part, i.e. "IC21".
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
int GetBottom() const
Definition: eda_rect.h:124
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:81
void addImplicitConnections(SCH_COMPONENT *aComponent, SCH_SCREEN *aScreen, bool aUpdateSet)
Creates net labels to emulate implicit connections in Eagle.
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
Plugin to create the KiCad symbol library.
wxFileName getLibFileName()
SCH_SHEET_PATH.
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded..
int GetHeight() const
Definition: eda_rect.h:120
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
static EDA_RECT getSheetBbox(SCH_SHEET *aSheet)
Computes a bounding box for all items in a schematic sheet
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
bool LocatePathOfScreen(SCH_SCREEN *aScreen, SCH_SHEET_PATH *aList)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:668
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
Schematic symbol object.
Definition: sch_component.h:88
int GetY() const
Definition: eda_rect.h:112
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
void countNets(wxXmlNode *aSchematicNode)
void loadSheet(wxXmlNode *aSheetNode, int sheetcount)
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:58

References countChildren(), SCH_ITEM::Duplicate(), EDA_RECT::GetBottom(), getChildrenNodes(), SCH_COMPONENT::GetField(), EDA_RECT::GetHeight(), EDA_RECT::GetLeft(), getSheetBbox(), EDA_TEXT::GetText(), EDA_RECT::GetWidth(), EDA_RECT::GetY(), MapChildren(), EAGLE_LIBRARY::name, SCH_SHEET_PATH::Path(), and REFERENCE.

◆ loadSegments()

void SCH_EAGLE_PLUGIN::loadSegments ( wxXmlNode *  aSegmentsNode,
const wxString &  aNetName,
const wxString &  aNetClass 
)
private

Definition at line 845 of file sch_eagle_plugin.cpp.

847 {
848  // Loop through all segments
849  wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
850  SCH_SCREEN* screen = m_currentSheet->GetScreen();
851 
852  int segmentCount = countChildren( aSegmentsNode, "segment" );
853 
854  // wxCHECK( screen, [>void<] );
855  while( currentSegment )
856  {
857  bool labelled = false; // has a label been added to this continously connected segment
858  NODE_MAP segmentChildren = MapChildren( currentSegment );
859  SCH_LINE* firstWire = nullptr;
860  m_segments.emplace_back();
861  SEG_DESC& segDesc = m_segments.back();
862 
863  // Loop through all segment children
864  wxXmlNode* segmentAttribute = currentSegment->GetChildren();
865 
866  while( segmentAttribute )
867  {
868  if( segmentAttribute->GetName() == "wire" )
869  {
870  SCH_LINE* wire = loadWire( segmentAttribute );
871 
872  if( !firstWire )
873  firstWire = wire;
874 
875  // Test for intersections with other wires
876  SEG thisWire( wire->GetStartPoint(), wire->GetEndPoint() );
877 
878  for( auto& desc : m_segments )
879  {
880  if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
881  continue; // no point in saving intersections of the same net
882 
883  for( const auto& seg : desc.segs )
884  {
885  auto intersection = thisWire.Intersect( seg, true );
886 
887  if( intersection )
888  m_wireIntersections.push_back( *intersection );
889  }
890  }
891 
892  segDesc.segs.push_back( thisWire );
893  screen->Append( wire );
894  }
895 
896  segmentAttribute = segmentAttribute->GetNext();
897  }
898 
899  segmentAttribute = currentSegment->GetChildren();
900 
901  while( segmentAttribute )
902  {
903  wxString nodeName = segmentAttribute->GetName();
904 
905  if( nodeName == "junction" )
906  {
907  screen->Append( loadJunction( segmentAttribute ) );
908  }
909  else if( nodeName == "label" )
910  {
911  SCH_TEXT* label = loadLabel( segmentAttribute, netName );
912  screen->Append( label );
913  wxASSERT( segDesc.labels.empty()
914  || segDesc.labels.front()->GetText() == label->GetText() );
915  segDesc.labels.push_back( label );
916  labelled = true;
917  }
918  else if( nodeName == "pinref" )
919  {
920  segmentAttribute->GetAttribute( "gate" ); // REQUIRED
921  segmentAttribute->GetAttribute( "part" ); // REQUIRED
922  segmentAttribute->GetAttribute( "pin" ); // REQUIRED
923  }
924  else if( nodeName == "wire" )
925  {
926  // already handled;
927  }
928  else // DEFAULT
929  {
930  // THROW_IO_ERROR( wxString::Format( _( "XML node \"%s\" unknown" ), nodeName ) );
931  }
932 
933  // Get next segment attribute
934  segmentAttribute = segmentAttribute->GetNext();
935  }
936 
937  // Add a small label to the net segment if it hasn't been labelled already
938  // this preserves the named net feature of Eagle schematics.
939  if( !labelled && firstWire )
940  {
941  std::unique_ptr<SCH_TEXT> label;
942 
943  // Add a global label if the net appears on more than one Eagle sheet
944  if( m_netCounts[netName.ToStdString()] > 1 )
945  label.reset( new SCH_GLOBALLABEL );
946  else if( segmentCount > 1 )
947  label.reset( new SCH_LABEL );
948 
949  if( label )
950  {
951  label->SetPosition( firstWire->GetStartPoint() );
952  label->SetText( escapeName( netName ) );
953  label->SetTextSize( wxSize( Mils2iu( 10 ), Mils2iu( 10 ) ) );
954  label->SetLabelSpinStyle( LABEL_SPIN_STYLE::LEFT );
955  screen->Append( label.release() );
956  }
957  }
958 
959  currentSegment = currentSegment->GetNext();
960  }
961 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
wxPoint GetStartPoint() const
Definition: sch_line.h:94
SCH_LINE * loadWire(wxXmlNode *aWireNode)
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Function Intersect()
Definition: seg.cpp:93
std::map< wxString, int > m_netCounts
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provides an easy access to the children of an XML node via their names.
std::vector< VECTOR2I > m_wireIntersections
Wire intersection points, used for quick checks whether placing a net label in a particular place wou...
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
SCH_JUNCTION * loadJunction(wxXmlNode *aJunction)
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
SCH_TEXT * loadLabel(wxXmlNode *aLabelNode, const wxString &aNetName)
Definition: seg.h:39
std::vector< SEG_DESC > m_segments
Segments representing wires for intersection checking
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
void SetPosition(const wxPoint &aPosition) override
Set the schematic item position to aPosition.
Definition: sch_text.h:314
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48
wxPoint GetEndPoint() const
Definition: sch_line.h:97

References SCH_SCREEN::Append(), countChildren(), escapeName(), SCH_LINE::GetEndPoint(), SCH_LINE::GetStartPoint(), EDA_TEXT::GetText(), SEG::Intersect(), SCH_EAGLE_PLUGIN::SEG_DESC::labels, LABEL_SPIN_STYLE::LEFT, MapChildren(), and SCH_EAGLE_PLUGIN::SEG_DESC::segs.

◆ loadSheet()

void SCH_EAGLE_PLUGIN::loadSheet ( wxXmlNode *  aSheetNode,
int  sheetcount 
)
private

Definition at line 683 of file sch_eagle_plugin.cpp.

684 {
685  // Map all children into a readable dictionary
686  NODE_MAP sheetChildren = MapChildren( aSheetNode );
687 
688  // Get description node
689  wxXmlNode* descriptionNode = getChildrenNodes( sheetChildren, "description" );
690 
691  wxString des;
692  std::string filename;
693  SCH_FIELD& sheetNameField = m_currentSheet->GetFields()[SHEETNAME];
694  SCH_FIELD& filenameField = m_currentSheet->GetFields()[SHEETFILENAME];
695 
696  if( descriptionNode )
697  {
698  des = descriptionNode->GetContent();
699  des.Replace( "\n", "_", true );
700  sheetNameField.SetText( des );
701  filename = des.ToStdString();
702  }
703  else
704  {
705  filename = wxString::Format( "%s_%d", m_filename.GetName(), aSheetIndex );
706  sheetNameField.SetText( filename );
707  }
708 
709  ReplaceIllegalFileNameChars( &filename );
710  replace( filename.begin(), filename.end(), ' ', '_' );
711 
712  wxString fn = wxString( filename + ".sch" );
713  filenameField.SetText( fn );
714  wxFileName fileName( fn );
715  m_currentSheet->GetScreen()->SetFileName( fileName.GetFullPath() );
716 
717  // Loop through all buses
718  // From the DTD: "Buses receive names which determine which signals they include.
719  // A bus is a drawing object. It does not create any electrical connections.
720  // These are always created by means of the nets and their names."
721  wxXmlNode* busNode = getChildrenNodes( sheetChildren, "busses" );
722 
723  while( busNode )
724  {
725  // Get the bus name
726  wxString busName = translateEagleBusName( busNode->GetAttribute( "name" ) );
727 
728  // Load segments of this bus
729  loadSegments( busNode, busName, wxString() );
730 
731  // Get next bus
732  busNode = busNode->GetNext();
733  }
734 
735  // Loop through all nets
736  // From the DTD: "Net is an electrical connection in a schematic."
737  wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
738 
739  while( netNode )
740  {
741  // Get the net name and class
742  wxString netName = netNode->GetAttribute( "name" );
743  wxString netClass = netNode->GetAttribute( "class" );
744 
745  // Load segments of this net
746  loadSegments( netNode, netName, netClass );
747 
748  // Get next net
749  netNode = netNode->GetNext();
750  }
751 
752  adjustNetLabels(); // needs to be called before addBusEntries()
753  addBusEntries();
754 
755  // Loop through all instances
756  wxXmlNode* instanceNode = getChildrenNodes( sheetChildren, "instances" );
757 
758  while( instanceNode )
759  {
760  loadInstance( instanceNode );
761  instanceNode = instanceNode->GetNext();
762  }
763 
764  /* moduleinst is a design block definition and is an EagleCad 8 feature,
765  *
766  * // Loop through all moduleinsts
767  * wxXmlNode* moduleinstNode = getChildrenNodes( sheetChildren, "moduleinsts" );
768  *
769  * while( moduleinstNode )
770  * {
771  * loadModuleinst( moduleinstNode );
772  * moduleinstNode = moduleinstNode->GetNext();
773  * }
774  */
775 
776  wxXmlNode* plainNode = getChildrenNodes( sheetChildren, "plain" );
777 
778  while( plainNode )
779  {
780  wxString nodeName = plainNode->GetName();
781 
782  if( nodeName == "text" )
783  {
784  m_currentSheet->GetScreen()->Append( loadPlainText( plainNode ) );
785  }
786  else if( nodeName == "wire" )
787  {
788  m_currentSheet->GetScreen()->Append( loadWire( plainNode ) );
789  }
790 
791  plainNode = plainNode->GetNext();
792  }
793 
794  // Calculate the new sheet size.
795  EDA_RECT sheetBoundingBox = getSheetBbox( m_currentSheet );
796  wxSize targetSheetSize = sheetBoundingBox.GetSize();
797  targetSheetSize.IncBy( Mils2iu( 1500 ), Mils2iu( 1500 ) );
798 
799  // Get current Eeschema sheet size.
800  wxSize pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
802 
803  // Increase if necessary
804  if( pageSizeIU.x < targetSheetSize.x )
805  pageInfo.SetWidthMils( Iu2Mils( targetSheetSize.x ) );
806 
807  if( pageSizeIU.y < targetSheetSize.y )
808  pageInfo.SetHeightMils( Iu2Mils( targetSheetSize.y ) );
809 
810  // Set the new sheet size.
811  m_currentSheet->GetScreen()->SetPageSettings( pageInfo );
812 
813  pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
814  wxPoint sheetcentre( pageSizeIU.x / 2, pageSizeIU.y / 2 );
815  wxPoint itemsCentre = sheetBoundingBox.Centre();
816 
817  // round the translation to nearest 100mil to place it on the grid.
818  wxPoint translation = sheetcentre - itemsCentre;
819  translation.x = translation.x - translation.x % Mils2iu( 100 );
820  translation.y = translation.y - translation.y % Mils2iu( 100 );
821 
822  // Add global net labels for the named power input pins in this sheet
823  for( auto item : m_currentSheet->GetScreen()->Items().OfType( SCH_COMPONENT_T ) )
825  static_cast<SCH_COMPONENT*>( item ), m_currentSheet->GetScreen(), true );
826 
827  m_connPoints.clear();
828 
829  // Translate the items.
830  std::vector<SCH_ITEM*> allItems;
831 
832  std::copy( m_currentSheet->GetScreen()->Items().begin(),
833  m_currentSheet->GetScreen()->Items().end(), std::back_inserter( allItems ) );
834 
835  for( auto item : allItems )
836  {
837  item->SetPosition( item->GetPosition() + translation );
838  item->ClearFlags();
839  m_currentSheet->GetScreen()->Update( item );
840 
841  }
842 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
SCH_LINE * loadWire(wxXmlNode *aWireNode)
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
Definition: string.cpp:714
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:181
SCH_TEXT * loadPlainText(wxXmlNode *aSchText)
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:180
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Function MapChildren provides an easy access to the children of an XML node via their names.
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:268
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
void adjustNetLabels()
Moves net labels that are detached from any wire to the nearest wire
void addImplicitConnections(SCH_COMPONENT *aComponent, SCH_SCREEN *aScreen, bool aUpdateSet)
Creates net labels to emulate implicit connections in Eagle.
PAGE_INFO describes the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
iterator end()
Definition: sch_rtree.h:253
void loadSegments(wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:253
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
static EDA_RECT getSheetBbox(SCH_SHEET *aSheet)
Computes a bounding box for all items in a schematic sheet
void loadInstance(wxXmlNode *aInstanceNode)
wxString translateEagleBusName(const wxString &aEagleName) const
Translates an Eagle-style bus name into one that is KiCad-compatible.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:133
iterator begin()
Definition: sch_rtree.h:248
EE_RTREE & Items()
Definition: sch_screen.h:158
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:239
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
wxPoint Centre() const
Definition: eda_rect.h:62
void Update(SCH_ITEM *aItem)
Updates aItem's bounding box in the tree.
Definition: sch_screen.cpp:238
void SetFileName(const wxString &aFileName)
Definition: sch_screen.h:183
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:48
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:58
const wxSize GetSize() const
Definition: eda_rect.h:103
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
Positions of pins and wire endings mapped to its parent

References EDA_RECT::Centre(), Format(), getChildrenNodes(), getSheetBbox(), EDA_RECT::GetSize(), MapChildren(), SCH_FIELD::Replace(), ReplaceIllegalFileNameChars(), SCH_COMPONENT_T, PAGE_INFO::SetHeightMils(), EDA_TEXT::SetText(), PAGE_INFO::SetWidthMils(), SHEETFILENAME, SHEETNAME, wxPoint::x, and wxPoint::y.

◆ loadSymbol()

bool SCH_EAGLE_PLUGIN::loadSymbol ( wxXmlNode *  aSymbolNode,
std::unique_ptr< LIB_PART > &  aPart,
EDEVICE aDevice,
int  aGateNumber,
const wxString &  aGateName 
)
private

Definition at line 1398 of file sch_eagle_plugin.cpp.

1400 {
1401  wxString symbolName = aSymbolNode->GetAttribute( "name" );
1402  std::vector<LIB_ITEM*> items;
1403 
1404  wxXmlNode* currentNode = aSymbolNode->GetChildren();
1405 
1406  bool foundName = false;
1407  bool foundValue = false;
1408  bool ispower = false;
1409  int pincount = 0;
1410 
1411  while( currentNode )
1412  {
1413  wxString nodeName = currentNode->GetName();
1414 
1415  if( nodeName == "circle" )
1416  {
1417  aPart->AddDrawItem( loadSymbolCircle( aPart, currentNode, aGateNumber ) );
1418  }
1419  else if( nodeName == "pin" )
1420  {
1421  EPIN ePin = EPIN( currentNode );
1422  std::unique_ptr<LIB_PIN> pin( loadPin( aPart, currentNode, &ePin, aGateNumber ) );
1423  pincount++;
1424 
1425  pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1426 
1427  if( ePin.direction )
1428  {
1429  for( const auto& pinDir : pinDirectionsMap )
1430  {
1431  if( ePin.direction->Lower() == pinDir.first )
1432  {
1433  pin->SetType( pinDir.second );
1434 
1435  if( pinDir.first == "sup" ) // power supply symbol
1436  ispower = true;
1437 
1438  break;
1439  }
1440  }
1441  }
1442 
1443 
1444  if( aDevice->connects.size() != 0 )
1445  {
1446  for( const auto& connect : aDevice->connects )
1447  {
1448  if( connect.gate == aGateName && pin->GetName() == connect.pin )
1449  {
1450  wxArrayString pads = wxSplit( wxString( connect.pad ), ' ' );
1451 
1452  pin->SetPartNumber( aGateNumber );
1453  pin->SetUnit( aGateNumber );
1454  pin->SetName( escapeName( pin->GetName() ) );
1455 
1456  if( pads.GetCount() > 1 )
1457  {
1458  pin->SetNumberTextSize( 0 );
1459  }
1460 
1461  // Eagle does not connect multiple NC pins together when they are stacked.
1462  // KiCad will do this for pins that are coincident. We opt here for correct
1463  // schematic netlist and leave out the multiple NC pins when stacked.
1464  for( unsigned i = 0; i < pads.GetCount(); i++ )
1465  {
1466  if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC && i > 0 )
1467  break;
1468 
1469  LIB_PIN* apin = new LIB_PIN( *pin );
1470 
1471  wxString padname( pads[i] );
1472  apin->SetNumber( padname );
1473  aPart->AddDrawItem( apin );
1474  }
1475 
1476  break;
1477  }
1478  }
1479  }
1480  else
1481  {
1482  pin->SetPartNumber( aGateNumber );
1483  pin->SetUnit( aGateNumber );
1484  pin->SetNumber( wxString::Format( "%i", pincount ) );
1485  aPart->AddDrawItem( pin.release() );
1486  }
1487  }
1488  else if( nodeName == "polygon" )
1489  {
1490  aPart->AddDrawItem( loadSymbolPolyLine( aPart, currentNode, aGateNumber ) );
1491  }
1492  else if( nodeName == "rectangle" )
1493  {
1494  aPart->AddDrawItem( loadSymbolRectangle( aPart, currentNode, aGateNumber ) );
1495  }
1496  else if( nodeName == "text" )
1497  {
1498  std::unique_ptr<LIB_TEXT> libtext( loadSymbolText( aPart, currentNode, aGateNumber ) );
1499 
1500  if( libtext->GetText().Upper() == ">NAME" )
1501  {
1502  LIB_FIELD* field = aPart->GetField( REFERENCE );
1503  loadFieldAttributes( field, libtext.get() );
1504  foundName = true;
1505  }
1506  else if( libtext->GetText().Upper() == ">VALUE" )
1507  {
1508  LIB_FIELD* field = aPart->GetField( VALUE );
1509  loadFieldAttributes( field, libtext.get() );
1510  foundValue = true;
1511  }
1512  else
1513  {
1514  aPart->AddDrawItem( libtext.release() );
1515  }
1516  }
1517  else if( nodeName == "wire" )
1518  {
1519  aPart->AddDrawItem( loadSymbolWire( aPart, currentNode, aGateNumber ) );
1520  }
1521 
1522  /*
1523  * else if( nodeName == "description" )
1524  * {
1525  * }
1526  * else if( nodeName == "dimension" )
1527  * {
1528  * }
1529  * else if( nodeName == "frame" )
1530  * {
1531  * }
1532  */
1533 
1534  currentNode = currentNode->GetNext();
1535  }
1536 
1537  if( foundName == false )
1538  aPart->GetField( REFERENCE )->SetVisible( false );
1539 
1540  if( foundValue == false )
1541  aPart->GetField( VALUE )->SetVisible( false );
1542 
1543  return pincount == 1 ? ispower : false;
1544 }
opt_wxString direction
Definition: eagle_parser.h:736
Field object used in symbol libraries.
Definition: lib_field.h:59
LIB_RECTANGLE * loadSymbolRectangle(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aRectNode, int aGateNumber)
Field Reference of part, i.e. "IC21".
Eagle pin element.
Definition: eagle_parser.h:728
void SetNumber(const wxString &aNumber)
Set the pin number.
Definition: lib_pin.cpp:249
LIB_PIN * loadPin(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *, EPIN *epin, int aGateNumber)
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
LIB_CIRCLE * loadSymbolCircle(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aCircleNode, int aGateNumber)
LIB_ITEM * loadSymbolWire(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aWireNode, int aGateNumber)
Field Value of part, i.e. "3.3K".
void loadFieldAttributes(LIB_FIELD *aField, const LIB_TEXT *aText) const
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
std::vector< ECONNECT > connects
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
LIB_TEXT * loadSymbolText(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aLibText, int aGateNumber)
input or output (like port for a microprocessor)
not connected (must be left open)
LIB_POLYLINE * loadSymbolPolyLine(std::unique_ptr< LIB_PART > &aPart, wxXmlNode *aPolygonNode, int aGateNumber)

References EDEVICE::connects, EPIN::direction, escapeName(), Format(), pinDirectionsMap, PT_BIDI, PT_NC, REFERENCE, LIB_PIN::SetNumber(), EDA_TEXT::SetVisible(), and VALUE.

◆ LoadSymbol()

LIB_PART * SCH_PLUGIN::LoadSymbol ( const wxString &  aLibraryPath,
const wxString &  aPartName,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Load a LIB_PART object having aPartName from the aLibraryPath containing a library format that this SCH_PLUGIN knows about.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several symbols.
aPartNameis the name of the LIB_PART to load.
aPropertiesis an associative array that can be used to tell the loader implementation to do something special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
the part created on the heap if found caller shares it or NULL if not found.
Exceptions
IO_ERRORif the library cannot be found or read. No exception is thrown in the case where aAliasName cannot be found.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 84 of file sch_plugin.cpp.

86 {
87  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
88  not_implemented( this, __FUNCTION__ );
89  return NULL;
90 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36
#define NULL

References not_implemented(), and NULL.

Referenced by LIB_MANAGER::LIB_BUFFER::SaveBuffer().

◆ loadSymbolCircle()

LIB_CIRCLE * SCH_EAGLE_PLUGIN::loadSymbolCircle ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aCircleNode,
int  aGateNumber 
)
private

Definition at line 1547 of file sch_eagle_plugin.cpp.

1549 {
1550  // Parse the circle properties
1551  ECIRCLE c( aCircleNode );
1552 
1553  unique_ptr<LIB_CIRCLE> circle( new LIB_CIRCLE( aPart.get() ) );
1554 
1555  circle->SetPosition( wxPoint( c.x.ToSchUnits(), c.y.ToSchUnits() ) );
1556  circle->SetRadius( c.radius.ToSchUnits() );
1557  circle->SetWidth( c.width.ToSchUnits() );
1558  circle->SetUnit( aGateNumber );
1559 
1560  return circle.release();
1561 }
Eagle circle.
Definition: eagle_parser.h:570

References ECIRCLE::radius, ECOORD::ToSchUnits(), ECIRCLE::width, ECIRCLE::x, and ECIRCLE::y.

◆ loadSymbolPolyLine()

LIB_POLYLINE * SCH_EAGLE_PLUGIN::loadSymbolPolyLine ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aPolygonNode,
int  aGateNumber 
)
private

Definition at line 1667 of file sch_eagle_plugin.cpp.

1669 {
1670  std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( aPart.get() ) );
1671 
1672  EPOLYGON epoly( aPolygonNode );
1673  wxXmlNode* vertex = aPolygonNode->GetChildren();
1674 
1675 
1676  wxPoint pt;
1677 
1678  while( vertex )
1679  {
1680  if( vertex->GetName() == "vertex" ) // skip <xmlattr> node
1681  {
1682  EVERTEX evertex( vertex );
1683  pt = wxPoint( evertex.x.ToSchUnits(), evertex.y.ToSchUnits() );
1684  polyLine->AddPoint( pt );
1685  }
1686 
1687  vertex = vertex->GetNext();
1688  }
1689 
1690  polyLine->SetFillMode( FILLED_SHAPE );
1691  polyLine->SetUnit( aGateNumber );
1692 
1693  return polyLine.release();
1694 }
Eagle vertex.
Definition: eagle_parser.h:746
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:757

References FILLED_SHAPE, ECOORD::ToSchUnits(), EVERTEX::x, and EVERTEX::y.

◆ loadSymbolRectangle()

LIB_RECTANGLE * SCH_EAGLE_PLUGIN::loadSymbolRectangle ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aRectNode,
int  aGateNumber 
)
private

Definition at line 1564 of file sch_eagle_plugin.cpp.

1566 {
1567  ERECT rect( aRectNode );
1568 
1569  unique_ptr<LIB_RECTANGLE> rectangle( new LIB_RECTANGLE( aPart.get() ) );
1570 
1571  rectangle->SetPosition( wxPoint( rect.x1.ToSchUnits(), rect.y1.ToSchUnits() ) );
1572  rectangle->SetEnd( wxPoint( rect.x2.ToSchUnits(), rect.y2.ToSchUnits() ) );
1573 
1574  rectangle->SetUnit( aGateNumber );
1575  // Eagle rectangles are filled by definition.
1576  rectangle->SetFillMode( FILLED_SHAPE );
1577 
1578  return rectangle.release();
1579 }
Eagle XML rectangle in binary.
Definition: eagle_parser.h:583

References FILLED_SHAPE, ECOORD::ToSchUnits(), ERECT::x1, ERECT::x2, ERECT::y1, and ERECT::y2.

◆ loadSymbolText()

LIB_TEXT * SCH_EAGLE_PLUGIN::loadSymbolText ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aLibText,
int  aGateNumber 
)
private

Definition at line 1800 of file sch_eagle_plugin.cpp.

1802 {
1803  std::unique_ptr<LIB_TEXT> libtext( new LIB_TEXT( aPart.get() ) );
1804  ETEXT etext( aLibText );
1805 
1806  libtext->SetUnit( aGateNumber );
1807  libtext->SetPosition( wxPoint( etext.x.ToSchUnits(), etext.y.ToSchUnits() ) );
1808 
1809  // Eagle supports multiple line text in library symbols. Legacy library symbol text cannot
1810  // contain CRs or LFs.
1811  //
1812  // @todo Split this into multiple text objects and offset the Y position so that it looks
1813  // more like the original Eagle schematic.
1814  wxString text = aLibText->GetNodeContent();
1815  std::replace( text.begin(), text.end(), '\n', '_' );
1816  std::replace( text.begin(), text.end(), '\r', '_' );
1817 
1818  libtext->SetText( text.IsEmpty() ? "~~" : text );
1819  loadTextAttributes( libtext.get(), etext );
1820 
1821  return libtext.release();
1822 }
Define a symbol library graphical text item.
Definition: lib_text.h:40
Eagle text element.
Definition: eagle_parser.h:645
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const

References ECOORD::ToSchUnits(), ETEXT::x, and ETEXT::y.

◆ loadSymbolWire()

LIB_ITEM * SCH_EAGLE_PLUGIN::loadSymbolWire ( std::unique_ptr< LIB_PART > &  aPart,
wxXmlNode *  aWireNode,
int  aGateNumber 
)
private

Definition at line 1582 of file sch_eagle_plugin.cpp.

1584 {
1585  auto ewire = EWIRE( aWireNode );
1586 
1587  wxPoint begin, end;
1588 
1589  begin.x = ewire.x1.ToSchUnits();
1590  begin.y = ewire.y1.ToSchUnits();
1591  end.x = ewire.x2.ToSchUnits();
1592  end.y = ewire.y2.ToSchUnits();
1593 
1594  if( begin == end )
1595  return nullptr;
1596 
1597  // if the wire is an arc
1598  if( ewire.curve )
1599  {
1600  std::unique_ptr<LIB_ARC> arc( new LIB_ARC( aPart.get() ) );
1601  wxPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 );
1602 
1603  double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1604  + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1605  * 2;
1606 
1607  // this emulates the filled semicircles created by a thick arc with flat ends caps.
1608  if( ewire.width.ToSchUnits() * 2 > radius )
1609  {
1610  wxPoint centerStartVector = begin - center;
1611  wxPoint centerEndVector = end - center;
1612 
1613  centerStartVector.x = centerStartVector.x * ewire.width.ToSchUnits() * 2 / radius;
1614  centerStartVector.y = centerStartVector.y * ewire.width.ToSchUnits() * 2 / radius;
1615 
1616  centerEndVector.x = centerEndVector.x * ewire.width.ToSchUnits() * 2 / radius;
1617  centerEndVector.y = centerEndVector.y * ewire.width.ToSchUnits() * 2 / radius;
1618 
1619  begin = center + centerStartVector;
1620  end = center + centerEndVector;
1621 
1622  radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1623  + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1624  * 2;
1625 
1626  arc->SetWidth( 1 );
1627  arc->SetFillMode( FILLED_SHAPE );
1628  }
1629  else
1630  {
1631  arc->SetWidth( ewire.width.ToSchUnits() );
1632  }
1633 
1634  arc->SetPosition( center );
1635 
1636  if( *ewire.curve > 0 )
1637  {
1638  arc->SetStart( begin );
1639  arc->SetEnd( end );
1640  }
1641  else
1642  {
1643  arc->SetStart( end );
1644  arc->SetEnd( begin );
1645  }
1646 
1647  arc->SetRadius( radius );
1648  arc->CalcRadiusAngles();
1649  arc->SetUnit( aGateNumber );
1650 
1651  return (LIB_ITEM*) arc.release();
1652  }
1653  else
1654  {
1655  std::unique_ptr<LIB_POLYLINE> polyLine( new LIB_POLYLINE( aPart.get() ) );
1656 
1657  polyLine->AddPoint( begin );
1658  polyLine->AddPoint( end );
1659  polyLine->SetUnit( aGateNumber );
1660  polyLine->SetWidth( ewire.width.ToSchUnits() );
1661 
1662  return (LIB_ITEM*) polyLine.release();
1663  }
1664 }
The base class for drawable items used by schematic library components.
Definition: lib_item.h:61
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC
Eagle wire.
Definition: eagle_parser.h:499

References ConvertArcCenter(), FILLED_SHAPE, wxPoint::x, and wxPoint::y.

◆ loadTextAttributes()

void SCH_EAGLE_PLUGIN::loadTextAttributes ( EDA_TEXT aText,
const ETEXT aAttribs 
) const
private

Definition at line 1840 of file sch_eagle_plugin.cpp.

1841 {
1842  aText->SetTextSize( aAttribs.ConvertSize() );
1843 
1844  if( aAttribs.ratio )
1845  {
1846  if( aAttribs.ratio.CGet() > 12 )
1847  {
1848  aText->SetBold( true );
1849  aText->SetTextThickness( GetPenSizeForBold( aText->GetTextWidth() ) );
1850  }
1851  }
1852 
1853  int align = aAttribs.align ? *aAttribs.align : ETEXT::BOTTOM_LEFT;
1854  int degrees = aAttribs.rot ? aAttribs.rot->degrees : 0;
1855  bool mirror = aAttribs.rot ? aAttribs.rot->mirror : false;
1856  bool spin = aAttribs.rot ? aAttribs.rot->spin : false;
1857 
1858  eagleToKicadAlignment( aText, align, degrees, mirror, spin, 0 );
1859 }
bool mirror
Definition: eagle_parser.h:480
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
Definition: gr_text.cpp:51
const T & CGet() const
Function CGet returns a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:311
opt_double ratio
Definition: eagle_parser.h:653
double degrees
Definition: eagle_parser.h:482
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
wxSize ConvertSize() const
Calculate text size based on font type and size.
opt_int align
Definition: eagle_parser.h:670
opt_erot rot
Definition: eagle_parser.h:654
int GetTextWidth() const
Definition: eda_text.h:241
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:157
bool spin
Definition: eagle_parser.h:481
void SetBold(bool aBold)
Definition: eda_text.h:181

References ETEXT::align, ETEXT::BOTTOM_LEFT, OPTIONAL_XML_ATTRIBUTE< T >::CGet(), ETEXT::ConvertSize(), EROT::degrees, eagleToKicadAlignment(), GetPenSizeForBold(), EDA_TEXT::GetTextWidth(), EROT::mirror, ETEXT::ratio, ETEXT::rot, EDA_TEXT::SetBold(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), and EROT::spin.

◆ loadWire()

SCH_LINE * SCH_EAGLE_PLUGIN::loadWire ( wxXmlNode *  aWireNode)
private

Definition at line 964 of file sch_eagle_plugin.cpp.

965 {
966  std::unique_ptr<SCH_LINE> wire( new SCH_LINE );
967 
968  auto ewire = EWIRE( aWireNode );
969 
970  wire->SetLayer( kiCadLayer( ewire.layer ) );
971 
972  wxPoint begin, end;
973 
974  begin.x = ewire.x1.ToSchUnits();
975  begin.y = -ewire.y1.ToSchUnits();
976  end.x = ewire.x2.ToSchUnits();
977  end.y = -ewire.y2.ToSchUnits();
978 
979  wire->SetStartPoint( begin );
980  wire->SetEndPoint( end );
981 
982  m_connPoints[begin].emplace( wire.get() );
983  m_connPoints[end].emplace( wire.get() );
984 
985  return wire.release();
986 }
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
Eagle wire.
Definition: eagle_parser.h:499
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
Positions of pins and wire endings mapped to its parent

References wxPoint::x, and wxPoint::y.

◆ moveLabels()

void SCH_EAGLE_PLUGIN::moveLabels ( SCH_ITEM aWire,
const wxPoint aNewEndPoint 
)
private

Moves any labels on the wire to the new end point of the wire.

Definition at line 1966 of file sch_eagle_plugin.cpp.

1967 {
1968  for( auto item : m_currentSheet->GetScreen()->Items().Overlapping( aWire->GetBoundingBox() ) )
1969  {
1970  if( item->Type() == SCH_LABEL_T || item->Type() == SCH_GLOBAL_LABEL_T )
1971  {
1972  if( TestSegmentHit( item->GetPosition(), ( (SCH_LINE*) aWire )->GetStartPoint(),
1973  ( (SCH_LINE*) aWire )->GetEndPoint(), 0 ) )
1974  {
1975  item->SetPosition( aNewEndPoint );
1976  }
1977  }
1978  }
1979 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded..
EE_TYPE Overlapping(const EDA_RECT &aRect)
Definition: sch_rtree.h:224
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
EE_RTREE & Items()
Definition: sch_screen.h:158
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: base_struct.cpp:97

References EDA_ITEM::GetBoundingBox(), SCH_GLOBAL_LABEL_T, SCH_LABEL_T, and TestSegmentHit().

◆ Save()

void SCH_PLUGIN::Save ( const wxString &  aFileName,
SCH_SHEET aSheet,
SCHEMATIC aSchematic,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Write aSchematic to a storage file in a format that this SCH_PLUGIN implementation knows about, or it can be used to write a portion of aSchematic to a special kind of export file.

Parameters
aFileNameis the name of a file to save to on disk.
aSheetis the class SCH_SHEET in memory document tree from which to extract information when writing to aFileName. The caller continues to own the SCHEMATIC, and the plugin should refrain from modifying the SCHEMATIC if possible.
aSchematicis the SCHEMATIC object used to access any schematic-wide or project information needed to save the document.
aPropertiesis an associative array that can be used to tell the saver how to save the file, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL. Set the #PropSaveCurrentSheetOnly property to only save the current sheet. Otherwise, all hierarchial sheets are saved.
Exceptions
IO_ERRORif there is a problem saving or exporting.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 58 of file sch_plugin.cpp.

60 {
61  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
62  not_implemented( this, __FUNCTION__ );
63 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ SaveLibrary()

void SCH_PLUGIN::SaveLibrary ( const wxString &  aFileName,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 44 of file sch_plugin.cpp.

45 {
46  not_implemented( this, __FUNCTION__ );
47 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

◆ SaveSymbol()

void SCH_PLUGIN::SaveSymbol ( const wxString &  aLibraryPath,
const LIB_PART aSymbol,
const PROPERTIES aProperties = NULL 
)
virtualinherited

Write aSymbol to an existing library located at aLibraryPath.

If a LIB_PART by the same name already exists or there are any conflicting alias names, the new LIB_PART will silently overwrite any existing aliases and/or part becaue libraries cannot have duplicate alias names. It is the responsibility of the caller to check the library for conflicts before saving.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several symbols.
aSymbolis what to store in the library. The library is refreshed and the caller must update any LIB_PART pointers that may have changed.
aPropertiesis an associative array that can be used to tell the saver how to save the symbol, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving.

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 93 of file sch_plugin.cpp.

95 {
96  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
97  not_implemented( this, __FUNCTION__ );
98 }
static void not_implemented(const SCH_PLUGIN *aPlugin, const char *aCaller)
Function not_implemented throws an IO_ERROR and complains of an API function not being implemented.
Definition: sch_plugin.cpp:36

References not_implemented().

Referenced by LIB_MANAGER::LIB_BUFFER::SaveBuffer().

◆ SymbolLibOptions()

void SCH_PLUGIN::SymbolLibOptions ( PROPERTIES aListToAppendTo) const
virtualinherited

Append supported SCH_PLUGIN options to aListToAppenTo along with internationalized descriptions.

Options are typically appended so that a derived SCH_PLUGIN can call its base class function by the same name first, thus inheriting options declared there. (Some base class options could pertain to all Symbol*() functions in all derived SCH_PLUGINs.) Note that since aListToAppendTo is a PROPERTIES object, all options will be unique and last guy wins.

Parameters
aListToAppendToholds a tuple of
option
This eventually is what shows up into the fp-lib-table "options" field, possibly combined with others.
internationalized description
The internationalized description is displayed in DIALOG_FP_SCH_PLUGIN_OPTIONS. It may be multi-line and be quite explanatory of the option.

In the future perhaps aListToAppendTo evolves to something capable of also holding a wxValidator for the cells in said dialog: http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180. This would require a 3 column list, and introducing wx GUI knowledge to SCH_PLUGIN, which has been avoided to date.

Definition at line 132 of file sch_plugin.cpp.

133 {
134  // disable all these in another couple of months, after everyone has seen them:
135 #if 1
136  (*aListToAppendTo)["debug_level"] = UTF8( _(
137  "Enable <b>debug</b> logging for Symbol*() functions in this SCH_PLUGIN."
138  ) );
139 
140  (*aListToAppendTo)["read_filter_regex"] = UTF8( _(
141  "Regular expression <b>symbol name</b> filter."
142  ) );
143 
144  (*aListToAppendTo)["enable_transaction_logging"] = UTF8( _(
145  "Enable transaction logging. The mere presence of this option turns on the "
146  "logging, no need to set a Value."
147  ) );
148 
149  (*aListToAppendTo)["username"] = UTF8( _(
150  "User name for <b>login</b> to some special library server."
151  ));
152 
153  (*aListToAppendTo)["password"] = UTF8( _(
154  "Password for <b>login</b> to some special library server."
155  ) );
156 #endif
157 
158 #if 1
159  // Suitable for a C++ to python SCH_PLUGIN::Footprint*() adapter, move it to the adapter
160  // if and when implemented.
161  (*aListToAppendTo)["python_symbol_plugin"] = UTF8( _(
162  "Enter the python symbol which implements the SCH_PLUGIN::Symbol*() functions."
163  ) );
164 #endif
165 }
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
#define _(s)
Definition: 3d_actions.cpp:33

References _.

◆ translateEagleBusName()

wxString SCH_EAGLE_PLUGIN::translateEagleBusName ( const wxString &  aEagleName) const
private

Translates an Eagle-style bus name into one that is KiCad-compatible.

For vector buses such as A[7..0] this has no impact. For group buses, we translate from Eagle-style to KiCad-style.

Parameters
aEagleNameis the name of the bus from the Eagle schematic

Definition at line 2609 of file sch_eagle_plugin.cpp.

2610 {
2611  if( NET_SETTINGS::ParseBusVector( aEagleName, nullptr, nullptr ) )
2612  return aEagleName;
2613 
2614  wxString ret = "{";
2615 
2616  wxStringTokenizer tokenizer( aEagleName, "," );
2617 
2618  while( tokenizer.HasMoreTokens() )
2619  {
2620  wxString member = tokenizer.GetNextToken();
2621 
2622  // In Eagle, overbar text is automatically stopped at the end of the net name, even when
2623  // that net name is part of a bus definition. In KiCad, we don't (currently) do that, so
2624  // if there is an odd number of overbar markers in this net name, we need to append one
2625  // to close it out before appending the space.
2626 
2627  if( member.Freq( '!' ) % 2 > 0 )
2628  member << "!";
2629 
2630  ret << member << " ";
2631  }
2632 
2633  ret.Trim( true );
2634  ret << "}";
2635 
2636  return ret;
2637 }
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parses a bus vector (e.g.

References NET_SETTINGS::ParseBusVector().

Member Data Documentation

◆ m_connPoints

std::map<wxPoint, std::set<const EDA_ITEM*> > SCH_EAGLE_PLUGIN::m_connPoints
private

Positions of pins and wire endings mapped to its parent

Definition at line 219 of file sch_eagle_plugin.h.

◆ m_currentSheet

SCH_SHEET* SCH_EAGLE_PLUGIN::m_currentSheet
private

The current sheet of the schematic being loaded..

Definition at line 187 of file sch_eagle_plugin.h.

◆ m_eagleLibs

std::map<wxString, EAGLE_LIBRARY> SCH_EAGLE_PLUGIN::m_eagleLibs
private

Definition at line 194 of file sch_eagle_plugin.h.

◆ m_filename

wxFileName SCH_EAGLE_PLUGIN::m_filename
private

Definition at line 189 of file sch_eagle_plugin.h.

◆ m_kiway

KIWAY* SCH_EAGLE_PLUGIN::m_kiway
private

For creating sub sheets.

Definition at line 185 of file sch_eagle_plugin.h.

◆ m_layerMap

std::map<int, SCH_LAYER_ID> SCH_EAGLE_PLUGIN::m_layerMap
private

Definition at line 200 of file sch_eagle_plugin.h.

◆ m_libName

wxString SCH_EAGLE_PLUGIN::m_libName
private

Library name to save symbols.

Definition at line 190 of file sch_eagle_plugin.h.

◆ m_missingCmps

std::map<wxString, EAGLE_MISSING_CMP> SCH_EAGLE_PLUGIN::m_missingCmps
private

Map references to missing component units data

Definition at line 244 of file sch_eagle_plugin.h.

◆ m_netCounts

std::map<wxString, int> SCH_EAGLE_PLUGIN::m_netCounts
private

Definition at line 199 of file sch_eagle_plugin.h.

◆ m_partlist

EPART_MAP SCH_EAGLE_PLUGIN::m_partlist
private

Definition at line 193 of file sch_eagle_plugin.h.

◆ m_pi

SCH_PLUGIN::SCH_PLUGIN_RELEASER SCH_EAGLE_PLUGIN::m_pi
private

Plugin to create the KiCad symbol library.

Definition at line 196 of file sch_eagle_plugin.h.

◆ m_properties

std::unique_ptr< PROPERTIES > SCH_EAGLE_PLUGIN::m_properties
private

Library plugin properties.

Definition at line 197 of file sch_eagle_plugin.h.

◆ m_rootSheet

SCH_SHEET* SCH_EAGLE_PLUGIN::m_rootSheet
private

The root sheet of the schematic being loaded..

Definition at line 186 of file sch_eagle_plugin.h.

◆ m_schematic

SCHEMATIC* SCH_EAGLE_PLUGIN::m_schematic
private

Passed to Load(), the schematic object being loaded.

Definition at line 191 of file sch_eagle_plugin.h.

◆ m_segments

std::vector<SEG_DESC> SCH_EAGLE_PLUGIN::m_segments
private

Segments representing wires for intersection checking

Definition at line 216 of file sch_eagle_plugin.h.

◆ m_version

wxString SCH_EAGLE_PLUGIN::m_version
private

Eagle file version.

Definition at line 188 of file sch_eagle_plugin.h.

◆ m_wireIntersections

std::vector<VECTOR2I> SCH_EAGLE_PLUGIN::m_wireIntersections
private

Wire intersection points, used for quick checks whether placing a net label in a particular place would short two nets.

Definition at line 204 of file sch_eagle_plugin.h.


The documentation for this class was generated from the following files: