KiCad PCB EDA Suite
SCH_EAGLE_PLUGIN Class Reference

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
 Segments representing wires for intersection checking. More...
 

Public Member Functions

 SCH_EAGLE_PLUGIN ()
 
 ~SCH_EAGLE_PLUGIN ()
 
const wxString GetName () const override
 Return a brief hard coded name for this SCH_PLUGIN. More...
 
void SetReporter (REPORTER *aReporter) override
 Set an optional reporter for warnings/errors. More...
 
void SetProgressReporter (PROGRESS_REPORTER *aReporter) override
 Set an optional progress reporter. More...
 
const wxString GetFileExtension () const override
 Return 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=nullptr, const PROPERTIES *aProperties=nullptr) 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=nullptr)
 
virtual void Save (const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const PROPERTIES *aProperties=nullptr)
 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=nullptr)
 Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath. More...
 
virtual void EnumerateSymbolLib (std::vector< LIB_SYMBOL * > &aSymbolList, const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 Populate a list of LIB_SYMBOL aliases contained within the library aLibraryPath. More...
 
virtual LIB_SYMBOLLoadSymbol (const wxString &aLibraryPath, const wxString &aPartName, const PROPERTIES *aProperties=nullptr)
 Load a LIB_SYMBOL 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_SYMBOL *aSymbol, const PROPERTIES *aProperties=nullptr)
 Write aSymbol to an existing library located at aLibraryPath. More...
 
virtual void DeleteSymbol (const wxString &aLibraryPath, const wxString &aSymbolName, const PROPERTIES *aProperties=nullptr)
 Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath. More...
 
virtual void CreateSymbolLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 Create a new empty symbol library at aLibraryPath. More...
 
virtual bool DeleteSymbolLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=nullptr)
 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 checkpoint ()
 
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_LINE *aWire, const wxPoint &aNewEndPoint)
 Move 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)
 
void loadFrame (wxXmlNode *aFrameNode, std::vector< SCH_LINE * > &aLines)
 
bool loadSymbol (wxXmlNode *aSymbolNode, std::unique_ptr< LIB_SYMBOL > &aSymbol, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
 
LIB_SHAPEloadSymbolCircle (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aCircleNode, int aGateNumber)
 
LIB_SHAPEloadSymbolRectangle (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aRectNode, int aGateNumber)
 
LIB_SHAPEloadSymbolPolyLine (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aPolygonNode, int aGateNumber)
 
LIB_ITEMloadSymbolWire (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aWireNode, int aGateNumber)
 
LIB_PINloadPin (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *, EPIN *epin, int aGateNumber)
 
LIB_TEXTloadSymbolText (std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aLibText, int aGateNumber)
 
void loadFrame (wxXmlNode *aFrameNode, std::vector< LIB_ITEM * > &aLines)
 
void loadTextAttributes (EDA_TEXT *aText, const ETEXT &aAttribs) const
 
void loadFieldAttributes (LIB_FIELD *aField, const LIB_TEXT *aText) const
 Move net labels that are detached from any wire to the nearest wire. More...
 
void adjustNetLabels ()
 
wxString translateEagleBusName (const wxString &aEagleName) const
 Translate an Eagle-style bus name into one that is KiCad-compatible. More...
 
wxString getLibName ()
 
wxFileName getLibFileName ()
 Checks if there are other wires or pins at the position of the tested pin. More...
 
bool checkConnections (const SCH_SYMBOL *aSymbol, const LIB_PIN *aPin) const
 
void addImplicitConnections (SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
 Create net labels to emulate implicit connections in Eagle. More...
 
bool netHasPowerDriver (SCH_LINE *aLine, const wxString &aNetName) const
 

Private Attributes

REPORTERm_reporter
 Reporter for warnings/errors. More...
 
std::map< wxString, EAGLE_MISSING_CMPm_missingCmps
 
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
 PI to create KiCad symbol library. More...
 
std::unique_ptr< PROPERTIESm_properties
 Library plugin properties. More...
 
PROGRESS_REPORTERm_progressReporter
 optional; may be nullptr More...
 
unsigned m_doneCount
 
unsigned m_lastProgressCount
 
unsigned m_totalCount
 for progress reporting More...
 
std::map< wxString, int > m_netCounts
 
std::map< int, SCH_LAYER_IDm_layerMap
 
std::map< wxString, wxString > m_powerPorts
 map from symbol reference to global label equivalent More...
 
std::vector< VECTOR2Im_wireIntersections
 Wires and labels of a single connection (segment in Eagle nomenclature) More...
 
std::vector< SEG_DESCm_segments
 Nets as defined in the <nets> sections of an Eagle schematic file. More...
 
std::map< wxString, ENETm_nets
 Positions of pins and wire endings mapped to its parent. More...
 
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
 

Detailed Description

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 353 of file sch_eagle_plugin.cpp.

353  :
354  m_progressReporter( nullptr ),
355  m_doneCount( 0 ),
356  m_lastProgressCount( 0 ),
357  m_totalCount( 0 )
358 {
359  m_rootSheet = nullptr;
360  m_currentSheet = nullptr;
361  m_schematic = nullptr;
362 
364 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
static REPORTER & GetInstance()
Definition: reporter.cpp:175
unsigned m_totalCount
for progress reporting
unsigned m_lastProgressCount
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
REPORTER * m_reporter
Reporter for warnings/errors.
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr

References WXLOG_REPORTER::GetInstance(), m_currentSheet, m_reporter, m_rootSheet, and m_schematic.

◆ ~SCH_EAGLE_PLUGIN()

SCH_EAGLE_PLUGIN::~SCH_EAGLE_PLUGIN ( )

Definition at line 367 of file sch_eagle_plugin.cpp.

368 {
369 }

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 2325 of file sch_eagle_plugin.cpp.

2326 {
2327  // Add bus entry symbols
2328  // TODO: Cleanup this function and break into pieces
2329 
2330  // for each wire segment, compare each end with all busses.
2331  // If the wire end is found to end on a bus segment, place a bus entry symbol.
2332 
2333  std::vector<SCH_LINE*> buses;
2334  std::vector<SCH_LINE*> wires;
2335 
2336  for( SCH_ITEM* ii : m_currentSheet->GetScreen()->Items().OfType( SCH_LINE_T ) )
2337  {
2338  SCH_LINE* line = static_cast<SCH_LINE*>( ii );
2339 
2340  if( line->IsBus() )
2341  buses.push_back( line );
2342  else if( line->IsWire() )
2343  wires.push_back( line );
2344  }
2345 
2346  for( SCH_LINE* wire : wires )
2347  {
2348  wxPoint wireStart = wire->GetStartPoint();
2349  wxPoint wireEnd = wire->GetEndPoint();
2350 
2351  for( SCH_LINE* bus : buses )
2352  {
2353  wxPoint busStart = bus->GetStartPoint();
2354  wxPoint busEnd = bus->GetEndPoint();
2355 
2356  auto entrySize =
2357  []( int signX, int signY ) -> wxPoint
2358  {
2359  return wxPoint( Mils2iu( DEFAULT_SCH_ENTRY_SIZE ) * signX,
2360  Mils2iu( DEFAULT_SCH_ENTRY_SIZE ) * signY );
2361  };
2362 
2363  auto testBusHit =
2364  [&]( const wxPoint& aPt ) -> bool
2365  {
2366  return TestSegmentHit( aPt, busStart, busEnd, 0 );
2367  };
2368 
2369  if( wireStart.y == wireEnd.y && busStart.x == busEnd.x )
2370  {
2371  // Horizontal wire and vertical bus
2372 
2373  if( testBusHit( wireStart ) )
2374  {
2375  // Wire start is on the vertical bus
2376 
2377  if( wireEnd.x < busStart.x )
2378  {
2379  /* the end of the wire is to the left of the bus
2380  * ⎥⎢
2381  * ——————⎥⎢
2382  * ⎥⎢
2383  */
2384  wxPoint p = wireStart + entrySize( -1, 0 );
2385 
2386  if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2387  {
2388  /* there is room above the wire for the bus entry
2389  * ⎥⎢
2390  * _____/⎥⎢
2391  * ⎥⎢
2392  */
2393  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2394  busEntry->SetFlags( IS_NEW );
2395  m_currentSheet->GetScreen()->Append( busEntry );
2396  moveLabels( wire, p );
2397  wire->SetStartPoint( p );
2398  }
2399  else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2400  {
2401  /* there is room below the wire for the bus entry
2402  * _____ ⎥⎢
2403  * \⎥⎢
2404  * ⎥⎢
2405  */
2406  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2407  busEntry->SetFlags( IS_NEW );
2408  m_currentSheet->GetScreen()->Append( busEntry );
2409  moveLabels( wire, p );
2410  wire->SetStartPoint( p );
2411  }
2412  else
2413  {
2414  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2415  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2416  m_currentSheet->GetScreen()->Append( marker );
2417  }
2418  }
2419  else
2420  {
2421  /* the wire end is to the right of the bus
2422  * ⎥⎢
2423  * ⎥⎢——————
2424  * ⎥⎢
2425  */
2426  wxPoint p = wireStart + entrySize( 1, 0 );
2427 
2428  if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2429  {
2430  /* There is room above the wire for the bus entry
2431  * ⎥⎢
2432  * ⎥⎢\_____
2433  * ⎥⎢
2434  */
2435  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p , 4 );
2436  busEntry->SetFlags( IS_NEW );
2437  m_currentSheet->GetScreen()->Append( busEntry );
2438  moveLabels( wire, p );
2439  wire->SetStartPoint( p );
2440  }
2441  else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2442  {
2443  /* There is room below the wire for the bus entry
2444  * ⎥⎢ _____
2445  * ⎥⎢/
2446  * ⎥⎢
2447  */
2448  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2449  busEntry->SetFlags( IS_NEW );
2450  m_currentSheet->GetScreen()->Append( busEntry );
2451  moveLabels( wire, p );
2452  wire->SetStartPoint( p );
2453  }
2454  else
2455  {
2456  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2457  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2458  m_currentSheet->GetScreen()->Append( marker );
2459  }
2460  }
2461 
2462  break;
2463  }
2464  else if( testBusHit( wireEnd ) )
2465  {
2466  // Wire end is on the vertical bus
2467 
2468  if( wireStart.x < busStart.x )
2469  {
2470  /* start of the wire is to the left of the bus
2471  * ⎥⎢
2472  * ——————⎥⎢
2473  * ⎥⎢
2474  */
2475  wxPoint p = wireEnd + entrySize( -1, 0 );
2476 
2477  if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2478  {
2479  /* there is room above the wire for the bus entry
2480  * ⎥⎢
2481  * _____/⎥⎢
2482  * ⎥⎢
2483  */
2484  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2485  busEntry->SetFlags( IS_NEW );
2486  m_currentSheet->GetScreen()->Append( busEntry );
2487  moveLabels( wire, p );
2488  wire->SetEndPoint( p );
2489  }
2490  else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2491  {
2492  /* there is room below the wire for the bus entry
2493  * _____ ⎥⎢
2494  * \⎥⎢
2495  * ⎥⎢
2496  */
2497  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2498  busEntry->SetFlags( IS_NEW );
2499  m_currentSheet->GetScreen()->Append( busEntry );
2500  moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2501  wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2502  }
2503  else
2504  {
2505  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2506  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2507  m_currentSheet->GetScreen()->Append( marker );
2508  }
2509  }
2510  else
2511  {
2512  /* the start of the wire is to the right of the bus
2513  * ⎥⎢
2514  * ⎥⎢——————
2515  * ⎥⎢
2516  */
2517  wxPoint p = wireEnd + entrySize( 1, 0 );
2518 
2519  if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2520  {
2521  /* There is room above the wire for the bus entry
2522  * ⎥⎢
2523  * ⎥⎢\_____
2524  * ⎥⎢
2525  */
2526  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2527  busEntry->SetFlags( IS_NEW );
2528  m_currentSheet->GetScreen()->Append( busEntry );
2529  moveLabels( wire, p );
2530  wire->SetEndPoint( p );
2531  }
2532  else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
2533  {
2534  /* There is room below the wire for the bus entry
2535  * ⎥⎢ _____
2536  * ⎥⎢/
2537  * ⎥⎢
2538  */
2539  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2540  busEntry->SetFlags( IS_NEW );
2541  m_currentSheet->GetScreen()->Append( busEntry );
2542  moveLabels( wire, p );
2543  wire->SetEndPoint( p );
2544  }
2545  else
2546  {
2547  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2548  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2549  m_currentSheet->GetScreen()->Append( marker );
2550  }
2551  }
2552 
2553  break;
2554  }
2555  }
2556  else if( wireStart.x == wireEnd.x && busStart.y == busEnd.y )
2557  {
2558  // Vertical wire and horizontal bus
2559 
2560  if( testBusHit( wireStart ) )
2561  {
2562  // Wire start is on the bus
2563 
2564  if( wireEnd.y < busStart.y )
2565  {
2566  /* the end of the wire is above the bus
2567  * |
2568  * |
2569  * |
2570  * =======
2571  */
2572  wxPoint p = wireStart + entrySize( 0, -1 );
2573 
2574  if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
2575  {
2576  /* there is room to the left of the wire for the bus entry
2577  * |
2578  * |
2579  * /
2580  * =======
2581  */
2582  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2583  busEntry->SetFlags( IS_NEW );
2584  m_currentSheet->GetScreen()->Append( busEntry );
2585  moveLabels( wire, p );
2586  wire->SetStartPoint( p );
2587  }
2588  else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
2589  {
2590  /* there is room to the right of the wire for the bus entry
2591  * |
2592  * |
2593  * \
2594  * =======
2595  */
2596  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2597  busEntry->SetFlags( IS_NEW );
2598  m_currentSheet->GetScreen()->Append( busEntry );
2599  moveLabels( wire, p );
2600  wire->SetStartPoint( p );
2601  }
2602  else
2603  {
2604  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2605  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2606  m_currentSheet->GetScreen()->Append( marker );
2607  }
2608  }
2609  else
2610  {
2611  /* wire end is below the bus
2612  * =======
2613  * |
2614  * |
2615  * |
2616  */
2617  wxPoint p = wireStart + entrySize( 0, 1 );
2618 
2619  if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
2620  {
2621  /* there is room to the left of the wire for the bus entry
2622  * =======
2623  * \
2624  * |
2625  * |
2626  */
2627  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2628  busEntry->SetFlags( IS_NEW );
2629  m_currentSheet->GetScreen()->Append( busEntry );
2630  moveLabels( wire, p );
2631  wire->SetStartPoint( p );
2632  }
2633  else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
2634  {
2635  /* there is room to the right of the wire for the bus entry
2636  * =======
2637  * /
2638  * |
2639  * |
2640  */
2641  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2642  busEntry->SetFlags( IS_NEW );
2643  m_currentSheet->GetScreen()->Append( busEntry );
2644  moveLabels( wire, p );
2645  wire->SetStartPoint( p );
2646  }
2647  else
2648  {
2649  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2650  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2651  m_currentSheet->GetScreen()->Append( marker );
2652  }
2653  }
2654 
2655  break;
2656  }
2657  else if( testBusHit( wireEnd ) )
2658  {
2659  // Wire end is on the bus
2660 
2661  if( wireStart.y < busStart.y )
2662  {
2663  /* the start of the wire is above the bus
2664  * |
2665  * |
2666  * |
2667  * =======
2668  */
2669  wxPoint p = wireEnd + entrySize( 0, -1 );
2670 
2671  if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
2672  {
2673  /* there is room to the left of the wire for the bus entry
2674  * |
2675  * |
2676  * /
2677  * =======
2678  */
2679  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2680  busEntry->SetFlags( IS_NEW );
2681  m_currentSheet->GetScreen()->Append( busEntry );
2682  moveLabels( wire, p );
2683  wire->SetEndPoint( p );
2684  }
2685  else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
2686  {
2687  /* there is room to the right of the wire for the bus entry
2688  * |
2689  * |
2690  * \
2691  * =======
2692  */
2693  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2694  busEntry->SetFlags( IS_NEW );
2695  m_currentSheet->GetScreen()->Append( busEntry );
2696  moveLabels( wire, p );
2697  wire->SetEndPoint( p );
2698  }
2699  else
2700  {
2701  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2702  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2703  m_currentSheet->GetScreen()->Append( marker );
2704  }
2705  }
2706  else
2707  {
2708  /* wire start is below the bus
2709  * =======
2710  * |
2711  * |
2712  * |
2713  */
2714  wxPoint p = wireEnd + entrySize( 0, 1 );
2715 
2716  if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
2717  {
2718  /* there is room to the left of the wire for the bus entry
2719  * =======
2720  * \
2721  * |
2722  * |
2723  */
2724  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2725  busEntry->SetFlags( IS_NEW );
2726  m_currentSheet->GetScreen()->Append( busEntry );
2727  moveLabels( wire, p );
2728  wire->SetEndPoint( p );
2729  }
2730  else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
2731  {
2732  /* there is room to the right of the wire for the bus entry
2733  * =======
2734  * /
2735  * |
2736  * |
2737  */
2738  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2739  busEntry->SetFlags( IS_NEW );
2740  m_currentSheet->GetScreen()->Append( busEntry );
2741  moveLabels( wire, p );
2742  wire->SetEndPoint( p );
2743  }
2744  else
2745  {
2746  auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2747  SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2748  m_currentSheet->GetScreen()->Append( marker );
2749  }
2750  }
2751 
2752  break;
2753  }
2754  }
2755  else
2756  {
2757  // Wire isn't horizontal or vertical
2758 
2759  if( testBusHit( wireStart ) )
2760  {
2761  wxPoint wirevector = wireStart - wireEnd;
2762 
2763  if( wirevector.x > 0 )
2764  {
2765  if( wirevector.y > 0 )
2766  {
2767  wxPoint p = wireStart + entrySize( -1, -1 );
2768  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2769  busEntry->SetFlags( IS_NEW );
2770  m_currentSheet->GetScreen()->Append( busEntry );
2771 
2772  moveLabels( wire, p );
2773  wire->SetStartPoint( p );
2774  }
2775  else
2776  {
2777  wxPoint p = wireStart + entrySize( -1, 1 );
2778  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2779  busEntry->SetFlags( IS_NEW );
2780  m_currentSheet->GetScreen()->Append( busEntry );
2781 
2782  moveLabels( wire, p );
2783  wire->SetStartPoint( p );
2784  }
2785  }
2786  else
2787  {
2788  if( wirevector.y > 0 )
2789  {
2790  wxPoint p = wireStart + entrySize( 1, -1 );
2791  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2792  busEntry->SetFlags( IS_NEW );
2793  m_currentSheet->GetScreen()->Append( busEntry );
2794 
2795  moveLabels( wire, p );
2796  wire->SetStartPoint( p );
2797  }
2798  else
2799  {
2800  wxPoint p = wireStart + entrySize( 1, 1 );
2801  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2802  busEntry->SetFlags( IS_NEW );
2803  m_currentSheet->GetScreen()->Append( busEntry );
2804 
2805  moveLabels( wire, p );
2806  wire->SetStartPoint( p );
2807  }
2808  }
2809 
2810  break;
2811  }
2812  else if( testBusHit( wireEnd ) )
2813  {
2814  wxPoint wirevector = wireStart - wireEnd;
2815 
2816  if( wirevector.x > 0 )
2817  {
2818  if( wirevector.y > 0 )
2819  {
2820  wxPoint p = wireEnd + entrySize( 1, 1 );
2821  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2822  busEntry->SetFlags( IS_NEW );
2823  m_currentSheet->GetScreen()->Append( busEntry );
2824 
2825  moveLabels( wire, p );
2826  wire->SetEndPoint( p );
2827  }
2828  else
2829  {
2830  wxPoint p = wireEnd + entrySize( 1, -1 );
2831  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2832  busEntry->SetFlags( IS_NEW );
2833  m_currentSheet->GetScreen()->Append( busEntry );
2834 
2835  moveLabels( wire, p );
2836  wire->SetEndPoint( p );
2837  }
2838  }
2839  else
2840  {
2841  if( wirevector.y > 0 )
2842  {
2843  wxPoint p = wireEnd + entrySize( -1, 1 );
2844  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2845  busEntry->SetFlags( IS_NEW );
2846  m_currentSheet->GetScreen()->Append( busEntry );
2847 
2848  moveLabels( wire, p );
2849  wire->SetEndPoint( p );
2850  }
2851  else
2852  {
2853  wxPoint p = wireEnd + entrySize( -1, -1 );
2854  SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2855  busEntry->SetFlags( IS_NEW );
2856  m_currentSheet->GetScreen()->Append( busEntry );
2857 
2858  moveLabels( wire, p );
2859  wire->SetEndPoint( p );
2860  }
2861  }
2862 
2863  break;
2864  }
2865  }
2866  }
2867  }
2868 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:230
void moveLabels(SCH_LINE *aWire, const wxPoint &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:970
#define DEFAULT_SCH_ENTRY_SIZE
The default text size in mils. (can be changed in preference menu)
#define IS_NEW
New item, just created.
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:152
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
bool TestSegmentHit(const wxPoint &aRefPoint, const wxPoint &aStart, const wxPoint &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
Importer failed to auto-place a bus entry.
Definition: erc_settings.h:72
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:146
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
Class for a wire to bus entry.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
bool IsBus() const
Return true if the line is a bus.
Definition: sch_line.cpp:975

References SCH_SCREEN::Append(), ERC_ITEM::Create(), DEFAULT_SCH_ENTRY_SIZE, ERCE_BUS_ENTRY_NEEDED, SCH_SHEET::GetScreen(), IS_NEW, SCH_LINE::IsBus(), SCH_LINE::IsWire(), SCH_SCREEN::Items(), m_currentSheet, moveLabels(), EE_RTREE::OfType(), SCH_LINE_T, EDA_ITEM::SetFlags(), and TestSegmentHit().

Referenced by loadSheet().

◆ addImplicitConnections()

void SCH_EAGLE_PLUGIN::addImplicitConnections ( SCH_SYMBOL aSymbol,
SCH_SCREEN aScreen,
bool  aUpdateSet 
)
private

Create 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
aSymbolis the symbol to process.
aScreenis the screen where net labels should be added.
aUpdateSetdecides whether the missing units data should be updated.

Definition at line 2901 of file sch_eagle_plugin.cpp.

2903 {
2904  wxCHECK( aSymbol->GetLibSymbolRef(), /*void*/ );
2905 
2906  // Normally power parts also have power input pins,
2907  // but they already force net names on the attached wires
2908  if( aSymbol->GetLibSymbolRef()->IsPower() )
2909  return;
2910 
2911  int unit = aSymbol->GetUnit();
2912  const wxString reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
2913  std::vector<LIB_PIN*> pins;
2914  aSymbol->GetLibSymbolRef()->GetPins( pins );
2915  std::set<int> missingUnits;
2916 
2917  // Search all units for pins creating implicit connections
2918  for( const LIB_PIN* pin : pins )
2919  {
2920  if( pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
2921  {
2922  bool pinInUnit = !unit || pin->GetUnit() == unit; // pin belongs to the tested unit
2923 
2924  // Create a global net label only if there are no other wires/pins attached
2925  if( pinInUnit )
2926  {
2927  if( !checkConnections( aSymbol, pin ) )
2928  {
2929  // Create a net label to force the net name on the pin
2930  SCH_GLOBALLABEL* netLabel = new SCH_GLOBALLABEL;
2931  netLabel->SetPosition( aSymbol->GetPinPhysicalPosition( pin ) );
2932  netLabel->SetText( extractNetName( pin->GetName() ) );
2933  netLabel->SetTextSize( wxSize( Mils2iu( 40 ), Mils2iu( 40 ) ) );
2934 
2935  switch( pin->GetOrientation() )
2936  {
2937  case PIN_LEFT: netLabel->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT ); break;
2938  case PIN_RIGHT: netLabel->SetLabelSpinStyle( LABEL_SPIN_STYLE::LEFT ); break;
2939  case PIN_UP: netLabel->SetLabelSpinStyle( LABEL_SPIN_STYLE::UP ); break;
2940  case PIN_DOWN: netLabel->SetLabelSpinStyle( LABEL_SPIN_STYLE::BOTTOM ); break;
2941  }
2942 
2943  aScreen->Append( netLabel );
2944  }
2945  }
2946  else if( aUpdateSet )
2947  {
2948  // Found a pin creating implicit connection information in another unit.
2949  // Such units will be instantiated if they do not appear in another sheet and
2950  // processed later.
2951  wxASSERT( pin->GetUnit() );
2952  missingUnits.insert( pin->GetUnit() );
2953  }
2954  }
2955  }
2956 
2957  if( aUpdateSet && aSymbol->GetLibSymbolRef()->GetUnitCount() > 1 )
2958  {
2959  auto cmpIt = m_missingCmps.find( reference );
2960 
2961  // The first unit found has always already been processed.
2962  if( cmpIt == m_missingCmps.end() )
2963  {
2964  EAGLE_MISSING_CMP& entry = m_missingCmps[reference];
2965  entry.cmp = aSymbol;
2966  entry.units.emplace( unit, false );
2967  }
2968  else
2969  {
2970  // Set the flag indicating this unit has been processed.
2971  cmpIt->second.units[unit] = false;
2972  }
2973 
2974  if( !missingUnits.empty() ) // Save the units that need later processing
2975  {
2976  EAGLE_MISSING_CMP& entry = m_missingCmps[reference];
2977  entry.cmp = aSymbol;
2978 
2979  // Add units that haven't already been processed.
2980  for( int i : missingUnits )
2981  {
2982  if( entry.units.find( i ) != entry.units.end() )
2983  entry.units.emplace( i, true );
2984  }
2985  }
2986  }
2987 }
Field Reference of part, i.e. "IC21".
power input (GND, VCC for ICs). Must be connected to a power output.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:675
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
Definition: lib_pin.h:48
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:164
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:146
static wxString extractNetName(const wxString &aPinName)
bool checkConnections(const SCH_SYMBOL *aSymbol, const LIB_PIN *aPin) const
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:1058
int GetUnit() const
Definition: sch_symbol.h:195
void SetPosition(const wxPoint &aPosition) override
Definition: sch_text.h:240
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:154

References SCH_SCREEN::Append(), LABEL_SPIN_STYLE::BOTTOM, checkConnections(), SCH_EAGLE_PLUGIN::EAGLE_MISSING_CMP::cmp, extractNetName(), SCH_SYMBOL::GetField(), SCH_SYMBOL::GetLibSymbolRef(), SCH_SYMBOL::GetPinPhysicalPosition(), EDA_TEXT::GetText(), SCH_SYMBOL::GetUnit(), LABEL_SPIN_STYLE::LEFT, m_missingCmps, pin, PIN_DOWN, PIN_LEFT, PIN_RIGHT, PIN_UP, PT_POWER_IN, REFERENCE_FIELD, LABEL_SPIN_STYLE::RIGHT, SCH_GLOBALLABEL::SetLabelSpinStyle(), SCH_TEXT::SetPosition(), EDA_TEXT::SetText(), EDA_TEXT::SetTextSize(), SCH_EAGLE_PLUGIN::EAGLE_MISSING_CMP::units, and LABEL_SPIN_STYLE::UP.

Referenced by loadSchematic(), and loadSheet().

◆ adjustNetLabels()

void SCH_EAGLE_PLUGIN::adjustNetLabels ( )
private

Definition at line 2215 of file sch_eagle_plugin.cpp.

2216 {
2217  // Eagle supports detached labels, so a label does not need to be placed on a wire
2218  // to be associated with it. KiCad needs to move them, so the labels actually touch the
2219  // corresponding wires.
2220 
2221  // Sort the intersection points to speed up the search process
2222  std::sort( m_wireIntersections.begin(), m_wireIntersections.end() );
2223 
2224  auto onIntersection =
2225  [&]( const VECTOR2I& aPos )
2226  {
2227  return std::binary_search( m_wireIntersections.begin(),
2228  m_wireIntersections.end(), aPos );
2229  };
2230 
2231  for( SEG_DESC& segDesc : m_segments )
2232  {
2233  for( SCH_TEXT* label : segDesc.labels )
2234  {
2235  VECTOR2I labelPos( label->GetPosition() );
2236  const SEG* segAttached = segDesc.LabelAttached( label );
2237 
2238  if( segAttached && !onIntersection( labelPos ) )
2239  continue; // label is placed correctly
2240 
2241  // Move the label to the nearest wire
2242  if( !segAttached )
2243  {
2244  std::tie( labelPos, segAttached ) = findNearestLinePoint( label->GetPosition(),
2245  segDesc.segs );
2246 
2247  if( !segAttached ) // we cannot do anything
2248  continue;
2249  }
2250 
2251  // Create a vector pointing in the direction of the wire, 50 mils long
2252  VECTOR2I wireDirection( segAttached->B - segAttached->A );
2253  wireDirection = wireDirection.Resize( Mils2iu( 50 ) );
2254  const VECTOR2I origPos( labelPos );
2255 
2256  // Flags determining the search direction
2257  bool checkPositive = true, checkNegative = true, move = false;
2258  int trial = 0;
2259 
2260  // Be sure the label is not placed on a wire intersection
2261  while( ( !move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2262  {
2263  move = false;
2264 
2265  // Move along the attached wire to find the new label position
2266  if( trial % 2 == 1 )
2267  {
2268  labelPos = wxPoint( origPos + wireDirection * trial / 2 );
2269  move = checkPositive = segAttached->Contains( labelPos );
2270  }
2271  else
2272  {
2273  labelPos = wxPoint( origPos - wireDirection * trial / 2 );
2274  move = checkNegative = segAttached->Contains( labelPos );
2275  }
2276 
2277  ++trial;
2278  }
2279 
2280  if( move )
2281  label->SetPosition( wxPoint( labelPos ) );
2282  }
2283  }
2284 
2285  m_segments.clear();
2286  m_wireIntersections.clear();
2287 }
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const wxPoint &aPoint, const std::vector< SEG > &aLines) const
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
wxPoint GetPosition() const override
Definition: sch_text.h:239
Definition: seg.h:40
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
void SetPosition(const wxPoint &aPosition) override
Definition: sch_text.h:240

References findNearestLinePoint(), SCH_TEXT::GetPosition(), m_segments, m_wireIntersections, move, VECTOR2< T >::Resize(), and SCH_TEXT::SetPosition().

Referenced by loadSheet().

◆ checkConnections()

bool SCH_EAGLE_PLUGIN::checkConnections ( const SCH_SYMBOL aSymbol,
const LIB_PIN aPin 
) const
private

Definition at line 2887 of file sch_eagle_plugin.cpp.

2888 {
2889  wxPoint pinPosition = aSymbol->GetPinPhysicalPosition( aPin );
2890  auto pointIt = m_connPoints.find( pinPosition );
2891 
2892  if( pointIt == m_connPoints.end() )
2893  return false;
2894 
2895  const auto& items = pointIt->second;
2896  wxASSERT( items.find( aPin ) != items.end() );
2897  return items.size() > 1;
2898 }
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints

References SCH_SYMBOL::GetPinPhysicalPosition(), and m_connPoints.

Referenced by addImplicitConnections().

◆ 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 2290 of file sch_eagle_plugin.cpp.

2291 {
2292  // Open file and check first line
2293  wxTextFile tempFile;
2294 
2295  tempFile.Open( aFileName );
2296  wxString firstline;
2297 
2298  // read the first line
2299  firstline = tempFile.GetFirstLine();
2300  wxString secondline = tempFile.GetNextLine();
2301  wxString thirdline = tempFile.GetNextLine();
2302  tempFile.Close();
2303 
2304  return firstline.StartsWith( "<?xml" ) && secondline.StartsWith( "<!DOCTYPE eagle SYSTEM" )
2305  && thirdline.StartsWith( "<eagle version" );
2306 }

◆ checkpoint()

void SCH_EAGLE_PLUGIN::checkpoint ( )
private

Definition at line 396 of file sch_eagle_plugin.cpp.

397 {
398  const unsigned PROGRESS_DELTA = 5;
399 
400  if( m_progressReporter )
401  {
402  if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
403  {
405  / std::max( 1U, m_totalCount ) );
406 
408  THROW_IO_ERROR( ( "Open canceled by user." ) );
409 
411  }
412  }
413 }
unsigned m_totalCount
for progress reporting
unsigned m_lastProgressCount
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).

References PROGRESS_REPORTER::KeepRefreshing(), m_doneCount, m_lastProgressCount, m_progressReporter, m_totalCount, PROGRESS_REPORTER::SetCurrentProgress(), and THROW_IO_ERROR.

Referenced by loadLibrary(), loadSchematic(), and loadSheet().

◆ countNets()

void SCH_EAGLE_PLUGIN::countNets ( wxXmlNode *  aSchematicNode)
private

Definition at line 551 of file sch_eagle_plugin.cpp.

552 {
553  // Map all children into a readable dictionary
554  NODE_MAP schematicChildren = MapChildren( aSchematicNode );
555 
556  // Loop through all the sheets
557  wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, "sheets" );
558 
559  while( sheetNode )
560  {
561  NODE_MAP sheetChildren = MapChildren( sheetNode );
562 
563  // Loop through all nets
564  // From the DTD: "Net is an electrical connection in a schematic."
565  wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
566 
567  while( netNode )
568  {
569  wxString netName = netNode->GetAttribute( "name" );
570 
571  if( m_netCounts.count( netName ) )
572  m_netCounts[netName] = m_netCounts[netName] + 1;
573  else
574  m_netCounts[netName] = 1;
575 
576  // Get next net
577  netNode = netNode->GetNext();
578  }
579 
580  sheetNode = sheetNode->GetNext();
581  }
582 }
std::map< wxString, int > m_netCounts
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57

References getChildrenNodes(), m_netCounts, and MapChildren().

Referenced by loadSchematic().

◆ CreateSymbolLib()

void SCH_PLUGIN::CreateSymbolLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
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 110 of file sch_plugin.cpp.

111 {
112  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
113  not_implemented( this, __FUNCTION__ );
114 }
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:37

References not_implemented().

◆ DeleteSymbol()

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

Delete the entire LIB_SYMBOL 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_SYMBOL associated with it's root LIB_SYMBOL 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 102 of file sch_plugin.cpp.

104 {
105  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
106  not_implemented( this, __FUNCTION__ );
107 }
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:37

References not_implemented().

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

◆ DeleteSymbolLib()

bool SCH_PLUGIN::DeleteSymbolLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = nullptr 
)
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 117 of file sch_plugin.cpp.

118 {
119  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
120  not_implemented( this, __FUNCTION__ );
121  return false;
122 }
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:37

References not_implemented().

◆ EnumerateSymbolLib() [1/2]

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

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

Parameters
aSymbolNameListis an array to populate with the LIB_SYMBOL names associated with the library.
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing one or more LIB_SYMBOL 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 67 of file sch_plugin.cpp.

70 {
71  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
72  not_implemented( this, __FUNCTION__ );
73 }
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:37

References not_implemented().

◆ EnumerateSymbolLib() [2/2]

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

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

Note
It is the responsibility 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_SYMBOL pointers associated with the library.
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing one or more LIB_SYMBOL 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 76 of file sch_plugin.cpp.

79 {
80  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
81  not_implemented( this, __FUNCTION__ );
82 }
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:37

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 1213 of file sch_eagle_plugin.cpp.

1215 {
1216  VECTOR2I nearestPoint;
1217  const SEG* nearestLine = nullptr;
1218 
1219  float d, mindistance = std::numeric_limits<float>::max();
1220 
1221  // Find the nearest start, middle or end of a line from the list of lines.
1222  for( const SEG& line : aLines )
1223  {
1224  VECTOR2I testpoint = line.A;
1225  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1226 
1227  if( d < mindistance )
1228  {
1229  mindistance = d;
1230  nearestPoint = testpoint;
1231  nearestLine = &line;
1232  }
1233 
1234  testpoint = line.Center();
1235  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1236 
1237  if( d < mindistance )
1238  {
1239  mindistance = d;
1240  nearestPoint = testpoint;
1241  nearestLine = &line;
1242  }
1243 
1244  testpoint = line.B;
1245  d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1246 
1247  if( d < mindistance )
1248  {
1249  mindistance = d;
1250  nearestPoint = testpoint;
1251  nearestLine = &line;
1252  }
1253  }
1254 
1255  return std::make_pair( nearestPoint, nearestLine );
1256 }
Definition: seg.h:40

References VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by adjustNetLabels().

◆ 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 177 of file sch_plugin.cpp.

178 {
179  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
180  not_implemented( this, __FUNCTION__ );
181  static wxString error;
182  return error;
183 }
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:37

References not_implemented().

Referenced by TEST_SCH_SHEET_LIST_FIXTURE::loadSchematic(), and TEST_NETLISTS_FIXTURE::loadSchematic().

◆ GetFileExtension()

const wxString SCH_EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Return the file extension for the SCH_PLUGIN.

Implements SCH_PLUGIN.

Definition at line 378 of file sch_eagle_plugin.cpp.

379 {
380  return "sch";
381 }

◆ getLibFileName()

wxFileName SCH_EAGLE_PLUGIN::getLibFileName ( )
private

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

Definition at line 156 of file sch_eagle_plugin.cpp.

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

References KiCadSymbolLibFileExtension.

Referenced by Load(), loadInstance(), loadLibrary(), and loadSchematic().

◆ getLibName()

wxString SCH_EAGLE_PLUGIN::getLibName ( )
private

Definition at line 132 of file sch_eagle_plugin.cpp.

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

References LIB_ID::FixIllegalChars().

Referenced by Load(), and loadInstance().

◆ 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 384 of file sch_eagle_plugin.cpp.

385 {
386  return "lbr";
387 }

◆ 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 390 of file sch_eagle_plugin.cpp.

391 {
392  return 0;
393 }

◆ GetName()

const wxString SCH_EAGLE_PLUGIN::GetName ( ) const
overridevirtual

Return a brief hard coded name for this SCH_PLUGIN.

Implements SCH_PLUGIN.

Definition at line 372 of file sch_eagle_plugin.cpp.

373 {
374  return "EAGLE";
375 }

◆ 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 125 of file sch_plugin.cpp.

126 {
127  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
128  not_implemented( this, __FUNCTION__ );
129  return false;
130 }
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:37

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 215 of file sch_eagle_plugin.cpp.

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

References LAYER_NOTES.

Referenced by loadWire().

◆ Load()

SCH_SHEET * SCH_EAGLE_PLUGIN::Load ( const wxString &  aFileName,
SCHEMATIC aSchematic,
SCH_SHEET aAppendToMe = nullptr,
const PROPERTIES aProperties = nullptr 
)
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 symbol 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 416 of file sch_eagle_plugin.cpp.

418 {
419  wxASSERT( !aFileName || aSchematic != nullptr );
420  LOCALE_IO toggle; // toggles on, then off, the C locale.
421 
422  m_filename = aFileName;
423  m_schematic = aSchematic;
424 
425  if( m_progressReporter )
426  {
427  m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
428 
430  THROW_IO_ERROR( ( "Open canceled by user." ) );
431  }
432 
433  // Load the document
434  wxXmlDocument xmlDocument;
435  wxFFileInputStream stream( m_filename.GetFullPath() );
436 
437  if( !stream.IsOk() || !xmlDocument.Load( stream ) )
438  {
439  THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ),
440  m_filename.GetFullPath() ) );
441  }
442 
443  // Delete on exception, if I own m_rootSheet, according to aAppendToMe
444  unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
445 
446  wxFileName newFilename( m_filename );
447  newFilename.SetExt( KiCadSchematicFileExtension );
448 
449  if( aAppendToMe )
450  {
451  wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
452  m_rootSheet = &aSchematic->Root();
453  }
454  else
455  {
456  m_rootSheet = new SCH_SHEET( aSchematic );
457  m_rootSheet->SetFileName( newFilename.GetFullPath() );
458  }
459 
460  if( !m_rootSheet->GetScreen() )
461  {
462  SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
463  screen->SetFileName( newFilename.GetFullPath() );
464  m_rootSheet->SetScreen( screen );
465  }
466 
467  SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
468 
469  wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
470 
471  m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
472  m_properties = std::make_unique<PROPERTIES>();
473  ( *m_properties )[SCH_LEGACY_PLUGIN::PropBuffering] = "";
474 
477  if( !libTable->HasLibrary( getLibName() ) )
478  {
479  // Create a new empty symbol library.
480  m_pi->CreateSymbolLib( getLibFileName().GetFullPath() );
481  wxString libTableUri = "${KIPRJMOD}/" + getLibFileName().GetFullName();
482 
483  // Add the new library to the project symbol library table.
484  libTable->InsertRow(
485  new SYMBOL_LIB_TABLE_ROW( getLibName(), libTableUri, wxString( "KiCad" ) ) );
486 
487  // Save project symbol library table.
488  wxFileName fn( m_schematic->Prj().GetProjectPath(),
490 
491  // So output formatter goes out of scope and closes the file before reloading.
492  {
493  FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
494  libTable->Format( &formatter, 0 );
495  }
496 
497  // Reload the symbol library table.
499  m_schematic->Prj().SchSymbolLibTable();
500  }
501 
502  // Retrieve the root as current node
503  wxXmlNode* currentNode = xmlDocument.GetRoot();
504 
505  // If the attribute is found, store the Eagle version;
506  // otherwise, store the dummy "0.0" version.
507  m_version = currentNode->GetAttribute( "version", "0.0" );
508 
509  // Map all children into a readable dictionary
510  NODE_MAP children = MapChildren( currentNode );
511 
512  // Load drawing
513  loadDrawing( children["drawing"] );
514 
515  m_pi->SaveLibrary( getLibFileName().GetFullPath() );
516 
517  SCH_SCREENS allSheets( m_rootSheet );
518  allSheets.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
519 
520  return m_rootSheet;
521 }
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.
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:323
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:172
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:108
void set(SCH_PLUGIN *aPlugin)
Definition: sch_io_mgr.h:507
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:122
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:258
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
#define _(s)
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
wxString m_version
Eagle file version.
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation 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:54
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
SCH_SHEET & Root() const
Definition: schematic.h:92
void loadDrawing(wxXmlNode *aDrawingNode)
const std::string KiCadSchematicFileExtension
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.
Used for text file output.
Definition: richio.h:456
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:110
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:593
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47

References _, PROJECT::ELEM_SYMBOL_LIB_TABLE, SYMBOL_LIB_TABLE::Format(), Format(), getLibFileName(), getLibName(), PROJECT::GetProjectPath(), SCH_SHEET::GetScreen(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName(), LIB_TABLE::HasLibrary(), LIB_TABLE::InsertRow(), SCHEMATIC::IsValid(), PROGRESS_REPORTER::KeepRefreshing(), KiCadSchematicFileExtension, loadDrawing(), m_filename, m_pi, m_progressReporter, m_properties, m_rootSheet, m_schematic, m_version, MapChildren(), SCHEMATIC::Prj(), SCH_LEGACY_PLUGIN::PropBuffering, PROGRESS_REPORTER::Report(), SCHEMATIC::Root(), SCH_PLUGIN::SCH_PLUGIN_RELEASER::set(), PROJECT::SetElem(), SCH_SCREEN::SetFileName(), SCH_SHEET::SetFileName(), SCH_SHEET::SetScreen(), THROW_IO_ERROR, and SCH_SCREENS::UpdateSymbolLinks().

◆ loadDrawing()

void SCH_EAGLE_PLUGIN::loadDrawing ( wxXmlNode *  aDrawingNode)
private

Definition at line 524 of file sch_eagle_plugin.cpp.

525 {
526  // Map all children into a readable dictionary
527  NODE_MAP drawingChildren = MapChildren( aDrawingNode );
528 
529  // Board nodes should not appear in .sch files
530  // wxXmlNode* board = drawingChildren["board"]
531 
532  // wxXmlNode* grid = drawingChildren["grid"]
533 
534  auto layers = drawingChildren["layers"];
535 
536  if( layers )
537  loadLayerDefs( layers );
538 
539  // wxXmlNode* library = drawingChildren["library"]
540 
541  // wxXmlNode* settings = drawingChildren["settings"]
542 
543  // Load schematic
544  auto schematic = drawingChildren["schematic"];
545 
546  if( schematic )
547  loadSchematic( schematic );
548 }
void loadSchematic(wxXmlNode *aSchematicNode)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide 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:47

References loadLayerDefs(), loadSchematic(), and MapChildren().

Referenced by Load().

◆ loadFieldAttributes()

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

Move net labels that are detached from any wire to the nearest wire.

Definition at line 2203 of file sch_eagle_plugin.cpp.

2204 {
2205  aField->SetTextPos( aText->GetPosition() );
2206  aField->SetTextSize( aText->GetTextSize() );
2207  aField->SetTextAngle( aText->GetTextAngle() );
2208  aField->SetBold( aText->IsBold() );
2209  aField->SetVertJustify( aText->GetVertJustify() );
2210  aField->SetHorizJustify( aText->GetHorizJustify() );
2211  aField->SetVisible( true );
2212 }
bool IsBold() const
Definition: eda_text.h:204
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:220
wxPoint GetPosition() const override
Definition: lib_text.h:91
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
double GetTextAngle() const
Definition: eda_text.h:195
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:219
const wxSize & GetTextSize() const
Definition: eda_text.h:259
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:223
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:222
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:188
void SetBold(bool aBold)
Definition: eda_text.h:203

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().

Referenced by loadSymbol().

◆ loadFrame() [1/2]

void SCH_EAGLE_PLUGIN::loadFrame ( wxXmlNode *  aFrameNode,
std::vector< SCH_LINE * > &  aLines 
)
private

Definition at line 970 of file sch_eagle_plugin.cpp.

971 {
972  EFRAME eframe( aFrameNode );
973 
974  wxPoint corner1( eframe.x1.ToSchUnits(), -eframe.y1.ToSchUnits() );
975  wxPoint corner3( eframe.x2.ToSchUnits(), -eframe.y2.ToSchUnits() );
976  wxPoint corner2( corner3.x, corner1.y );
977  wxPoint corner4( corner1.x, corner3.y );
978 
979  SCH_LINE* line = new SCH_LINE();
981  line->SetStartPoint( corner1 );
982  line->SetEndPoint( corner2 );
983  aLines.push_back( line );
984 
985  line = new SCH_LINE();
987  line->SetStartPoint( corner2 );
988  line->SetEndPoint( corner3 );
989  aLines.push_back( line );
990 
991  line = new SCH_LINE();
993  line->SetStartPoint( corner3 );
994  line->SetEndPoint( corner4 );
995  aLines.push_back( line );
996 
997  line = new SCH_LINE();
999  line->SetStartPoint( corner4 );
1000  line->SetEndPoint( corner1 );
1001  aLines.push_back( line );
1002 }
Parse an Eagle frame element.
Definition: eagle_parser.h:674
void SetEndPoint(const wxPoint &aPosition)
Definition: sch_line.h:94
void SetLineStyle(const PLOT_DASH_TYPE aStyle)
Definition: sch_line.cpp:269
void SetStartPoint(const wxPoint &aPosition)
Definition: sch_line.h:91
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37

References SCH_LINE::SetEndPoint(), SCH_LINE::SetLineStyle(), SCH_LINE::SetStartPoint(), SOLID, ECOORD::ToSchUnits(), EFRAME::x1, EFRAME::x2, EFRAME::y1, and EFRAME::y2.

Referenced by loadSheet(), and loadSymbol().

◆ loadFrame() [2/2]

void SCH_EAGLE_PLUGIN::loadFrame ( wxXmlNode *  aFrameNode,
std::vector< LIB_ITEM * > &  aLines 
)
private

Definition at line 1972 of file sch_eagle_plugin.cpp.

1973 {
1974  EFRAME eframe( aFrameNode );
1975 
1976  int xMin = eframe.x1.ToSchUnits();
1977  int xMax = eframe.x2.ToSchUnits();
1978  int yMin = eframe.y1.ToSchUnits();
1979  int yMax = eframe.y2.ToSchUnits();
1980 
1981  if( xMin > xMax )
1982  std::swap( xMin, xMax );
1983 
1984  if( yMin > yMax )
1985  std::swap( yMin, yMax );
1986 
1987  LIB_SHAPE* lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
1988  lines->AddPoint( wxPoint( xMin, yMin ) );
1989  lines->AddPoint( wxPoint( xMax, yMin ) );
1990  lines->AddPoint( wxPoint( xMax, yMax ) );
1991  lines->AddPoint( wxPoint( xMin, yMax ) );
1992  lines->AddPoint( wxPoint( xMin, yMin ) );
1993  aItems.push_back( lines );
1994 
1995  if( !eframe.border_left )
1996  {
1997  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
1998  lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) );
1999  lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) );
2000  aItems.push_back( lines );
2001 
2002  int i;
2003  int height = yMax - yMin;
2004  int x1 = xMin;
2005  int x2 = x1 + Mils2iu( 150 );
2006  int legendPosX = xMin + Mils2iu( 75 );
2007  double rowSpacing = height / double( eframe.rows );
2008  double legendPosY = yMax - ( rowSpacing / 2 );
2009 
2010  for( i = 1; i < eframe.rows; i++ )
2011  {
2012  int newY = KiROUND( yMin + ( rowSpacing * (double) i ) );
2013  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2014  lines->AddPoint( wxPoint( x1, newY ) );
2015  lines->AddPoint( wxPoint( x2, newY ) );
2016  aItems.push_back( lines );
2017  }
2018 
2019  char legendChar = 'A';
2020 
2021  for( i = 0; i < eframe.rows; i++ )
2022  {
2023  LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2024  legendText->SetPosition( wxPoint( legendPosX, KiROUND( legendPosY ) ) );
2025  legendText->SetText( wxString( legendChar ) );
2026  legendText->SetTextSize( wxSize( Mils2iu( 90 ), Mils2iu( 100 ) ) );
2027  aItems.push_back( legendText );
2028  legendChar++;
2029  legendPosY -= rowSpacing;
2030  }
2031  }
2032 
2033  if( !eframe.border_right )
2034  {
2035  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2036  lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) );
2037  lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) );
2038  aItems.push_back( lines );
2039 
2040  int i;
2041  int height = yMax - yMin;
2042  int x1 = xMax - Mils2iu( 150 );
2043  int x2 = xMax;
2044  int legendPosX = xMax - Mils2iu( 75 );
2045  double rowSpacing = height / double( eframe.rows );
2046  double legendPosY = yMax - ( rowSpacing / 2 );
2047 
2048  for( i = 1; i < eframe.rows; i++ )
2049  {
2050  int newY = KiROUND( yMin + ( rowSpacing * (double) i ) );
2051  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2052  lines->AddPoint( wxPoint( x1, newY ) );
2053  lines->AddPoint( wxPoint( x2, newY ) );
2054  aItems.push_back( lines );
2055  }
2056 
2057  char legendChar = 'A';
2058 
2059  for( i = 0; i < eframe.rows; i++ )
2060  {
2061  LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2062  legendText->SetPosition( wxPoint( legendPosX, KiROUND( legendPosY ) ) );
2063  legendText->SetText( wxString( legendChar ) );
2064  legendText->SetTextSize( wxSize( Mils2iu( 90 ), Mils2iu( 100 ) ) );
2065  aItems.push_back( legendText );
2066  legendChar++;
2067  legendPosY -= rowSpacing;
2068  }
2069  }
2070 
2071  if( !eframe.border_top )
2072  {
2073  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2074  lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) );
2075  lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMax - Mils2iu( 150 ) ) );
2076  aItems.push_back( lines );
2077 
2078  int i;
2079  int width = xMax - xMin;
2080  int y1 = yMin;
2081  int y2 = yMin + Mils2iu( 150 );
2082  int legendPosY = yMax - Mils2iu( 75 );
2083  double columnSpacing = width / double( eframe.columns );
2084  double legendPosX = xMin + ( columnSpacing / 2 );
2085 
2086  for( i = 1; i < eframe.columns; i++ )
2087  {
2088  int newX = KiROUND( xMin + ( columnSpacing * (double) i ) );
2089  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2090  lines->AddPoint( wxPoint( newX, y1 ) );
2091  lines->AddPoint( wxPoint( newX, y2 ) );
2092  aItems.push_back( lines );
2093  }
2094 
2095  char legendChar = '1';
2096 
2097  for( i = 0; i < eframe.columns; i++ )
2098  {
2099  LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2100  legendText->SetPosition( wxPoint( KiROUND( legendPosX ), legendPosY ) );
2101  legendText->SetText( wxString( legendChar ) );
2102  legendText->SetTextSize( wxSize( Mils2iu( 90 ), Mils2iu( 100 ) ) );
2103  aItems.push_back( legendText );
2104  legendChar++;
2105  legendPosX += columnSpacing;
2106  }
2107  }
2108 
2109  if( !eframe.border_bottom )
2110  {
2111  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2112  lines->AddPoint( wxPoint( xMax - Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) );
2113  lines->AddPoint( wxPoint( xMin + Mils2iu( 150 ), yMin + Mils2iu( 150 ) ) );
2114  aItems.push_back( lines );
2115 
2116  int i;
2117  int width = xMax - xMin;
2118  int y1 = yMax - Mils2iu( 150 );
2119  int y2 = yMax;
2120  int legendPosY = yMin + Mils2iu( 75 );
2121  double columnSpacing = width / double( eframe.columns );
2122  double legendPosX = xMin + ( columnSpacing / 2 );
2123 
2124  for( i = 1; i < eframe.columns; i++ )
2125  {
2126  int newX = KiROUND( xMin + ( columnSpacing * (double) i ) );
2127  lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2128  lines->AddPoint( wxPoint( newX, y1 ) );
2129  lines->AddPoint( wxPoint( newX, y2 ) );
2130  aItems.push_back( lines );
2131  }
2132 
2133  char legendChar = '1';
2134 
2135  for( i = 0; i < eframe.columns; i++ )
2136  {
2137  LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2138  legendText->SetPosition( wxPoint( KiROUND( legendPosX ), legendPosY ) );
2139  legendText->SetText( wxString( legendChar ) );
2140  legendText->SetTextSize( wxSize( Mils2iu( 90 ), Mils2iu( 100 ) ) );
2141  aItems.push_back( legendText );
2142  legendChar++;
2143  legendPosX += columnSpacing;
2144  }
2145  }
2146 }
void AddPoint(const wxPoint &aPosition)
Definition: lib_shape.cpp:407
Define a symbol library graphical text item.
Definition: lib_text.h:39
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
Parse an Eagle frame element.
Definition: eagle_parser.h:674
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
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:73
void SetPosition(const wxPoint &aPosition) override
Definition: lib_item.h:222

References LIB_SHAPE::AddPoint(), EFRAME::border_bottom, EFRAME::border_left, EFRAME::border_right, EFRAME::border_top, EFRAME::columns, KiROUND(), POLY, EFRAME::rows, LIB_ITEM::SetPosition(), EDA_TEXT::SetText(), EDA_TEXT::SetTextSize(), ECOORD::ToSchUnits(), EFRAME::x1, EFRAME::x2, EFRAME::y1, and EFRAME::y2.

◆ loadInstance()

void SCH_EAGLE_PLUGIN::loadInstance ( wxXmlNode *  aInstanceNode)
private

Definition at line 1259 of file sch_eagle_plugin.cpp.

1260 {
1261  EINSTANCE einstance = EINSTANCE( aInstanceNode );
1262  SCH_SCREEN* screen = m_currentSheet->GetScreen();
1263 
1264  // Find the part in the list for the sheet.
1265  // Assign the symbol its value from the part entry
1266  // Calculate the unit number from the gate entry of the instance
1267  // Assign the LIB_ID from device set and device names
1268 
1269  auto part_it = m_partlist.find( einstance.part.Upper() );
1270 
1271  if( part_it == m_partlist.end() )
1272  {
1273  m_reporter->Report( wxString::Format( _( "Error parsing Eagle file. Could not find '%s' "
1274  "instance but it is referenced in the schematic." ),
1275  einstance.part ),
1277 
1278  return;
1279  }
1280 
1281  EPART* epart = part_it->second.get();
1282 
1283  wxString libraryname = epart->library;
1284  wxString gatename = epart->deviceset + epart->device + einstance.gate;
1285  wxString symbolname = wxString( epart->deviceset + epart->device );
1286  symbolname.Replace( "*", "" );
1287  wxString kisymbolname = EscapeString( symbolname, CTX_LIBID );
1288 
1289  int unit = m_eagleLibs[libraryname].GateUnit[gatename];
1290 
1291  wxString package;
1292  EAGLE_LIBRARY* elib = &m_eagleLibs[libraryname];
1293 
1294  auto p = elib->package.find( kisymbolname );
1295 
1296  if( p != elib->package.end() )
1297  package = p->second;
1298 
1299  LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1300  m_properties.get() );
1301 
1302  if( !part )
1303  {
1304  m_reporter->Report( wxString::Format( _( "Could not find '%s' in the imported library." ),
1305  UnescapeString( kisymbolname ) ),
1307  return;
1308  }
1309 
1310  LIB_ID libId( getLibName(), kisymbolname );
1311  std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1312  symbol->SetLibId( libId );
1313  symbol->SetUnit( unit );
1314  symbol->SetPosition( wxPoint( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) );
1315  symbol->GetField( FOOTPRINT_FIELD )->SetText( package );
1316 
1317  if( einstance.rot )
1318  {
1319  symbol->SetOrientation( kiCadComponentRotation( einstance.rot->degrees ) );
1320 
1321  if( einstance.rot->mirror )
1322  symbol->MirrorHorizontally( einstance.x.ToSchUnits() );
1323  }
1324 
1325  std::vector<LIB_FIELD*> partFields;
1326  part->GetFields( partFields );
1327 
1328  for( const LIB_FIELD* field : partFields )
1329  {
1330  symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1331  symbol->GetFieldById( field->GetId() )->SetTextPos( symbol->GetPosition()
1332  + field->GetTextPos() );
1333  }
1334 
1335  // If there is no footprint assigned, then prepend the reference value
1336  // with a hash character to mute netlist updater complaints
1337  wxString reference = package.IsEmpty() ? '#' + einstance.part : einstance.part;
1338 
1339  // EAGLE allows references to be single digits. This breaks KiCad netlisting, which requires
1340  // parts to have non-digit + digit annotation. If the reference begins with a number,
1341  // we prepend 'UNK' (unknown) for the symbol designator
1342  if( reference.find_first_not_of( "0123456789" ) == wxString::npos )
1343  reference.Prepend( "UNK" );
1344 
1345  SCH_SHEET_PATH sheetpath;
1346  m_rootSheet->LocatePathOfScreen( screen, &sheetpath );
1347  wxString current_sheetpath = sheetpath.PathAsString() + symbol->m_Uuid.AsString();
1348 
1349  symbol->GetField( REFERENCE_FIELD )->SetText( reference );
1350  symbol->AddHierarchicalReference( current_sheetpath, reference, unit );
1351 
1352  if( epart->value )
1353  symbol->GetField( VALUE_FIELD )->SetText( *epart->value );
1354  else
1355  symbol->GetField( VALUE_FIELD )->SetText( kisymbolname );
1356 
1357  // Set the visibility of fields.
1358  symbol->GetField( REFERENCE_FIELD )->SetVisible(
1359  part->GetFieldById( REFERENCE_FIELD )->IsVisible() );
1360  symbol->GetField( VALUE_FIELD )->SetVisible( part->GetFieldById( VALUE_FIELD )->IsVisible() );
1361 
1362  for( const auto& a : epart->attribute )
1363  {
1364  SCH_FIELD* field = symbol->AddField( *symbol->GetField( VALUE_FIELD ) );
1365  field->SetName( a.first );
1366  field->SetText( a.second );
1367  field->SetVisible( false );
1368  }
1369 
1370  for( const auto& a : epart->variant )
1371  {
1372  SCH_FIELD* field = symbol->AddField( *symbol->GetField( VALUE_FIELD ) );
1373  field->SetName( "VARIANT_" + a.first );
1374  field->SetText( a.second );
1375  field->SetVisible( false );
1376  }
1377 
1378  bool valueAttributeFound = false;
1379  bool nameAttributeFound = false;
1380 
1381  wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1382 
1383  // Parse attributes for the instance
1384  while( attributeNode )
1385  {
1386  if( attributeNode->GetName() == "attribute" )
1387  {
1388  EATTR attr = EATTR( attributeNode );
1389  SCH_FIELD* field = nullptr;
1390 
1391  if( attr.name.Lower() == "name" )
1392  {
1393  field = symbol->GetField( REFERENCE_FIELD );
1394  nameAttributeFound = true;
1395  }
1396  else if( attr.name.Lower() == "value" )
1397  {
1398  field = symbol->GetField( VALUE_FIELD );
1399  valueAttributeFound = true;
1400  }
1401  else
1402  {
1403  field = symbol->FindField( attr.name );
1404 
1405  if( field )
1406  field->SetVisible( false );
1407  }
1408 
1409  if( field )
1410  {
1411 
1412  field->SetPosition( wxPoint( attr.x->ToSchUnits(), -attr.y->ToSchUnits() ) );
1413  int align = attr.align ? *attr.align : ETEXT::BOTTOM_LEFT;
1414  int absdegrees = attr.rot ? attr.rot->degrees : 0;
1415  bool mirror = attr.rot ? attr.rot->mirror : false;
1416 
1417  if( einstance.rot && einstance.rot->mirror )
1418  mirror = !mirror;
1419 
1420  bool spin = attr.rot ? attr.rot->spin : false;
1421 
1422  if( attr.display == EATTR::Off || attr.display == EATTR::NAME )
1423  field->SetVisible( false );
1424 
1425  int rotation = einstance.rot ? einstance.rot->degrees : 0;
1426  int reldegrees = ( absdegrees - rotation + 360.0 );
1427  reldegrees %= 360;
1428 
1429  eagleToKicadAlignment( (EDA_TEXT*) field, align, reldegrees, mirror, spin,
1430  absdegrees );
1431  }
1432  }
1433  else if( attributeNode->GetName() == "variant" )
1434  {
1435  wxString variant, value;
1436 
1437  if( attributeNode->GetAttribute( "name", &variant )
1438  && attributeNode->GetAttribute( "value", &value ) )
1439  {
1440  SCH_FIELD* field = symbol->AddField( *symbol->GetField( VALUE_FIELD ) );
1441  field->SetName( "VARIANT_" + variant );
1442  field->SetText( value );
1443  field->SetVisible( false );
1444  }
1445  }
1446 
1447  attributeNode = attributeNode->GetNext();
1448  }
1449 
1450  if( einstance.smashed && einstance.smashed.Get() )
1451  {
1452  if( !valueAttributeFound )
1453  symbol->GetField( VALUE_FIELD )->SetVisible( false );
1454 
1455  if( !nameAttributeFound )
1456  symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
1457  }
1458 
1459  // Save the pin positions
1460  SYMBOL_LIB_TABLE& schLibTable = *m_schematic->Prj().SchSymbolLibTable();
1461  LIB_SYMBOL* libSymbol = schLibTable.LoadSymbol( symbol->GetLibId() );
1462 
1463  wxCHECK( libSymbol, /*void*/ );
1464 
1465  symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
1466 
1467  std::vector<LIB_PIN*> pins;
1468  symbol->GetLibPins( pins );
1469 
1470  for( const LIB_PIN* pin : pins )
1471  m_connPoints[symbol->GetPinPhysicalPosition( pin )].emplace( pin );
1472 
1473  if( part->IsPower() )
1474  m_powerPorts[ reference ] = symbol->GetField( VALUE_FIELD )->GetText();
1475 
1476  symbol->ClearFlags();
1477 
1478  screen->Append( symbol.release() );
1479 }
Field Reference of part, i.e. "IC21".
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
wxString deviceset
Definition: eagle_parser.h:925
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
bool mirror
Definition: eagle_parser.h:472
wxString part
Definition: eagle_parser.h:950
int ToSchUnits() const
Definition: eagle_parser.h:429
wxString library
Definition: eagle_parser.h:924
std::unordered_map< wxString, wxString > package
T & Get()
Return a reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:292
Field object used in symbol libraries.
Definition: lib_field.h:59
std::map< std::string, std::string > variant
Definition: eagle_parser.h:930
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
double degrees
Definition: eagle_parser.h:474
ECOORD x
Definition: eagle_parser.h:952
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:105
Define a library symbol object.
Definition: lib_symbol.h:96
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
opt_erot rot
Definition: eagle_parser.h:603
opt_wxString value
Definition: eagle_parser.h:928
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:140
opt_int align
Definition: eagle_parser.h:612
wxString gate
Definition: eagle_parser.h:951
wxString name
Definition: eagle_parser.h:596
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
opt_ecoord y
Definition: eagle_parser.h:599
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
#define _(s)
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
std::map< std::string, std::string > attribute
Definition: eagle_parser.h:929
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
wxString UnescapeString(const wxString &aSource)
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Parse an Eagle "attribute" XML element.
Definition: eagle_parser.h:594
opt_ecoord x
Definition: eagle_parser.h:598
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:688
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:146
REPORTER * m_reporter
Reporter for warnings/errors.
void SetName(const wxString &aName)
Definition: sch_field.h:111
opt_bool smashed
Definition: eagle_parser.h:954
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
opt_erot rot
Definition: eagle_parser.h:955
bool spin
Definition: eagle_parser.h:473
ECOORD y
Definition: eagle_parser.h:953
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
opt_int display
Definition: eagle_parser.h:611
wxString device
Definition: eagle_parser.h:926
void SetPosition(const wxPoint &aPosition) override
Definition: sch_field.cpp:822
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints
static SYMBOL_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
Field Name Module PCB, i.e. "16DIP300".

References _, EATTR::align, SCH_SCREEN::Append(), EPART::attribute, ETEXT::BOTTOM_LEFT, CTX_LIBID, EROT::degrees, EPART::device, EPART::deviceset, EATTR::display, eagleToKicadAlignment(), EscapeString(), FOOTPRINT_FIELD, Format(), EINSTANCE::gate, OPTIONAL_XML_ATTRIBUTE< T >::Get(), getLibFileName(), getLibName(), SCH_SHEET::GetScreen(), kiCadComponentRotation(), EPART::library, SYMBOL_LIB_TABLE::LoadSymbol(), SCH_SHEET::LocatePathOfScreen(), m_connPoints, m_currentSheet, m_eagleLibs, m_partlist, m_pi, m_powerPorts, m_properties, m_reporter, m_rootSheet, m_schematic, EROT::mirror, EATTR::name, EATTR::NAME, EATTR::Off, EAGLE_LIBRARY::package, EINSTANCE::part, SCH_SHEET_PATH::PathAsString(), pin, SCHEMATIC::Prj(), REFERENCE_FIELD, REPORTER::Report(), EATTR::rot, EINSTANCE::rot, RPT_SEVERITY_ERROR, SCH_FIELD::SetName(), SCH_FIELD::SetPosition(), EDA_TEXT::SetText(), EDA_TEXT::SetVisible(), EINSTANCE::smashed, EROT::spin, ECOORD::ToSchUnits(), UnescapeString(), EPART::value, VALUE_FIELD, EPART::variant, EATTR::x, EINSTANCE::x, EATTR::y, and EINSTANCE::y.

Referenced by loadSheet().

◆ loadJunction()

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

Definition at line 1163 of file sch_eagle_plugin.cpp.

1164 {
1165  std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1166 
1167  EJUNCTION ejunction = EJUNCTION( aJunction );
1168  wxPoint pos( ejunction.x.ToSchUnits(), -ejunction.y.ToSchUnits() );
1169 
1170  junction->SetPosition( pos );
1171 
1172  return junction.release();
1173 }
Eagle Junction.
Definition: eagle_parser.h:522
int ToSchUnits() const
Definition: eagle_parser.h:429
ECOORD y
Definition: eagle_parser.h:525
ECOORD x
Definition: eagle_parser.h:524

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

Referenced by loadSegments().

◆ loadLabel()

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

Definition at line 1176 of file sch_eagle_plugin.cpp.

1177 {
1178  ELABEL elabel = ELABEL( aLabelNode, aNetName );
1179  wxPoint elabelpos( elabel.x.ToSchUnits(), -elabel.y.ToSchUnits() );
1180 
1181  // Determine if the label is local or global depending on
1182  // the number of sheets the net appears in
1183  bool global = m_netCounts[aNetName] > 1;
1184  std::unique_ptr<SCH_TEXT> label;
1185 
1186  wxSize textSize = wxSize( KiROUND( elabel.size.ToSchUnits() * 0.7 ),
1187  KiROUND( elabel.size.ToSchUnits() * 0.7 ) );
1188 
1189  if( global )
1190  label = std::make_unique<SCH_GLOBALLABEL>();
1191  else
1192  label = std::make_unique<SCH_LABEL>();
1193 
1194  label->SetPosition( elabelpos );
1195  label->SetText( escapeName( elabel.netname ) );
1196  label->SetTextSize( textSize );
1197  label->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT );
1198 
1199  if( elabel.rot )
1200  {
1201  for( int i = 0; i < KiROUND( elabel.rot->degrees / 90 ) %4; ++i )
1202  label->Rotate90( false );
1203 
1204  if( elabel.rot->mirror )
1205  label->MirrorSpinStyle( false );
1206  }
1207 
1208  return label.release();
1209 }
bool mirror
Definition: eagle_parser.h:472
int ToSchUnits() const
Definition: eagle_parser.h:429
ECOORD x
Definition: eagle_parser.h:534
opt_erot rot
Definition: eagle_parser.h:538
std::map< wxString, int > m_netCounts
double degrees
Definition: eagle_parser.h:474
wxString netname
Definition: eagle_parser.h:540
Eagle label.
Definition: eagle_parser.h:532
ECOORD y
Definition: eagle_parser.h:535
wxString escapeName(const wxString &aNetName)
ECOORD size
Definition: eagle_parser.h:536
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:73

References EROT::degrees, escapeName(), KiROUND(), m_netCounts, EROT::mirror, ELABEL::netname, LABEL_SPIN_STYLE::RIGHT, ELABEL::rot, ELABEL::size, ECOORD::ToSchUnits(), ELABEL::x, and ELABEL::y.

Referenced by loadSegments().

◆ 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 colors.

<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 164 of file sch_eagle_plugin.cpp.

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

References LAYER_BUS, LAYER_NOTES, and LAYER_WIRE.

Referenced by loadDrawing().

◆ loadLibrary()

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

Definition at line 1482 of file sch_eagle_plugin.cpp.

1484 {
1485  NODE_MAP libraryChildren = MapChildren( aLibraryNode );
1486 
1487  // Loop through the symbols and load each of them
1488  wxXmlNode* symbolNode = getChildrenNodes( libraryChildren, "symbols" );
1489 
1490  while( symbolNode )
1491  {
1492  wxString symbolName = symbolNode->GetAttribute( "name" );
1493  aEagleLibrary->SymbolNodes[symbolName] = symbolNode;
1494  symbolNode = symbolNode->GetNext();
1495  }
1496 
1497  // Loop through the device sets and load each of them
1498  wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, "devicesets" );
1499 
1500  while( devicesetNode )
1501  {
1502  // Get Device set information
1503  EDEVICE_SET edeviceset = EDEVICE_SET( devicesetNode );
1504 
1505  wxString prefix = edeviceset.prefix ? edeviceset.prefix.Get() : "";
1506 
1507  NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
1508  wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, "devices" );
1509 
1510  // For each device in the device set:
1511  while( deviceNode )
1512  {
1513  // Get device information
1514  EDEVICE edevice = EDEVICE( deviceNode );
1515 
1516  // Create symbol name from deviceset and device names.
1517  wxString symbolName = edeviceset.name + edevice.name;
1518  symbolName.Replace( "*", "" );
1519  wxASSERT( !symbolName.IsEmpty() );
1520  symbolName = EscapeString( symbolName, CTX_LIBID );
1521 
1522  if( edevice.package )
1523  aEagleLibrary->package[symbolName] = edevice.package.Get();
1524 
1525  // Create KiCad symbol.
1526  unique_ptr<LIB_SYMBOL> libSymbol( new LIB_SYMBOL( symbolName ) );
1527 
1528  // Process each gate in the deviceset for this device.
1529  wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, "gates" );
1530  int gates_count = countChildren( deviceSetChildren["gates"], "gate" );
1531  libSymbol->SetUnitCount( gates_count );
1532  libSymbol->LockUnits( true );
1533 
1534  LIB_FIELD* reference = libSymbol->GetFieldById( REFERENCE_FIELD );
1535 
1536  if( prefix.length() == 0 )
1537  {
1538  reference->SetVisible( false );
1539  }
1540  else
1541  {
1542  // If there is no footprint assigned, then prepend the reference value
1543  // with a hash character to mute netlist updater complaints
1544  reference->SetText( edevice.package ? prefix : '#' + prefix );
1545  }
1546 
1547  int gateindex = 1;
1548  bool ispower = false;
1549 
1550  while( gateNode )
1551  {
1552  checkpoint();
1553 
1554  EGATE egate = EGATE( gateNode );
1555 
1556  aEagleLibrary->GateUnit[edeviceset.name + edevice.name + egate.name] = gateindex;
1557  ispower = loadSymbol( aEagleLibrary->SymbolNodes[egate.symbol], libSymbol, &edevice,
1558  gateindex, egate.name );
1559 
1560  gateindex++;
1561  gateNode = gateNode->GetNext();
1562  } // gateNode
1563 
1564  libSymbol->SetUnitCount( gates_count );
1565 
1566  if( gates_count == 1 && ispower )
1567  libSymbol->SetPower();
1568 
1569  wxString name = libSymbol->GetName();
1570  libSymbol->SetName( name );
1571  m_pi->SaveSymbol( getLibFileName().GetFullPath(), new LIB_SYMBOL( *libSymbol.get() ),
1572  m_properties.get() );
1573  aEagleLibrary->KiCadSymbols.insert( name, libSymbol.release() );
1574 
1575  deviceNode = deviceNode->GetNext();
1576  } // devicenode
1577 
1578  devicesetNode = devicesetNode->GetNext();
1579  } // devicesetNode
1580 
1581  return aEagleLibrary;
1582 }
Field Reference of part, i.e. "IC21".
wxString name
T & Get()
Return a reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:292
Field object used in symbol libraries.
Definition: lib_field.h:59
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provide an easy access to the children of an XML node via their names.
Define a library symbol object.
Definition: lib_symbol.h:96
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
wxString name
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:206
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
wxString symbol
Definition: eagle_parser.h:976
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
wxString name
Definition: eagle_parser.h:975
opt_wxString prefix
const char * name
Definition: DXF_plotter.cpp:56
bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_SYMBOL > &aSymbol, EDEVICE *aDevice, int aGateNumber, const wxString &aGateName)
opt_wxString package
std::unique_ptr< PROPERTIES > m_properties
Library plugin properties.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57

References checkpoint(), countChildren(), CTX_LIBID, EscapeString(), EAGLE_LIBRARY::GateUnit, OPTIONAL_XML_ATTRIBUTE< T >::Get(), getChildrenNodes(), getLibFileName(), EAGLE_LIBRARY::KiCadSymbols, loadSymbol(), m_pi, m_properties, MapChildren(), name, EGATE::name, EDEVICE::name, EDEVICE_SET::name, EAGLE_LIBRARY::package, EDEVICE::package, EDEVICE_SET::prefix, REFERENCE_FIELD, EDA_TEXT::SetText(), EDA_TEXT::SetVisible(), EGATE::symbol, and EAGLE_LIBRARY::SymbolNodes.

Referenced by loadSchematic().

◆ loadPin()

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

Definition at line 1870 of file sch_eagle_plugin.cpp.

1872 {
1873  std::unique_ptr<LIB_PIN> pin = std::make_unique<LIB_PIN>( aSymbol.get() );
1874  pin->SetPosition( wxPoint( aEPin->x.ToSchUnits(), aEPin->y.ToSchUnits() ) );
1875  pin->SetName( aEPin->name );
1876  pin->SetUnit( aGateNumber );
1877 
1878  int roti = aEPin->rot ? aEPin->rot->degrees : 0;
1879 
1880  switch( roti )
1881  {
1882  case 0: pin->SetOrientation( 'R' ); break;
1883  case 90: pin->SetOrientation( 'U' ); break;
1884  case 180: pin->SetOrientation( 'L' ); break;
1885  case 270: pin->SetOrientation( 'D' ); break;
1886  default: wxFAIL_MSG( wxString::Format( "Unhandled orientation (%d degrees).", roti ) );
1887  }
1888 
1889  pin->SetLength( Mils2iu( 300 ) ); // Default pin length when not defined.
1890 
1891  if( aEPin->length )
1892  {
1893  wxString length = aEPin->length.Get();
1894 
1895  if( length == "short" )
1896  pin->SetLength( Mils2iu( 100 ) );
1897  else if( length == "middle" )
1898  pin->SetLength( Mils2iu( 200 ) );
1899  else if( length == "long" )
1900  pin->SetLength( Mils2iu( 300 ) );
1901  else if( length == "point" )
1902  pin->SetLength( Mils2iu( 0 ) );
1903  }
1904 
1905  // emulate the visibility of pin elements
1906  if( aEPin->visible )
1907  {
1908  wxString visible = aEPin->visible.Get();
1909 
1910  if( visible == "off" )
1911  {
1912  pin->SetNameTextSize( 0 );
1913  pin->SetNumberTextSize( 0 );
1914  }
1915  else if( visible == "pad" )
1916  {
1917  pin->SetNameTextSize( 0 );
1918  }
1919  else if( visible == "pin" )
1920  {
1921  pin->SetNumberTextSize( 0 );
1922  }
1923 
1924  /*
1925  * else if( visible == "both" )
1926  * {
1927  * }
1928  */
1929  }
1930 
1931  if( aEPin->function )
1932  {
1933  wxString function = aEPin->function.Get();
1934 
1935  if( function == "dot" )
1936  pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
1937  else if( function == "clk" )
1938  pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1939  else if( function == "dotclk" )
1941  }
1942 
1943  return pin.release();
1944 }
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

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

Referenced by loadSymbol().

◆ loadPlainText()

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

Definition at line 2149 of file sch_eagle_plugin.cpp.

2150 {
2151  std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2152  ETEXT etext = ETEXT( aSchText );
2153 
2154  const wxString& thetext = aSchText->GetNodeContent();
2155 
2156  wxString adjustedText;
2157  wxStringTokenizer tokenizer( thetext, "\r\n" );
2158 
2159  // Strip the whitespace from both ends of each line.
2160  while( tokenizer.HasMoreTokens() )
2161  {
2162  wxString tmp = tokenizer.GetNextToken().Trim();
2163 
2164  tmp = tmp.Trim( false );
2165 
2166  if( tokenizer.HasMoreTokens() )
2167  tmp += wxT( "\n" );
2168 
2169  adjustedText += tmp;
2170  }
2171 
2172  schtext->SetText( adjustedText.IsEmpty() ? "\" \"" : escapeName( adjustedText ) );
2173  schtext->SetPosition( wxPoint( etext.x.ToSchUnits(), -etext.y.ToSchUnits() ) );
2174  loadTextAttributes( schtext.get(), etext );
2175  schtext->SetItalic( false );
2176 
2177  return schtext.release();
2178 }
int ToSchUnits() const
Definition: eagle_parser.h:429
Eagle text element.
Definition: eagle_parser.h:637
wxString escapeName(const wxString &aNetName)
ECOORD x
Definition: eagle_parser.h:640
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const
ECOORD y
Definition: eagle_parser.h:641

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

Referenced by loadSheet().

◆ loadSchematic()

void SCH_EAGLE_PLUGIN::loadSchematic ( wxXmlNode *  aSchematicNode)
private

Definition at line 585 of file sch_eagle_plugin.cpp.

586 {
587  // Map all children into a readable dictionary
588  NODE_MAP schematicChildren = MapChildren( aSchematicNode );
589  wxXmlNode* partNode = getChildrenNodes( schematicChildren, "parts" );
590  wxXmlNode* libraryNode = getChildrenNodes( schematicChildren, "libraries" );
591  wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, "sheets" );
592 
593  if( !sheetNode )
594  return;
595 
596  auto count_nodes =
597  []( wxXmlNode* aNode ) -> unsigned
598  {
599  unsigned count = 0;
600 
601  while( aNode )
602  {
603  count++;
604  aNode = aNode->GetNext();
605  }
606 
607  return count;
608  };
609 
610  if( m_progressReporter )
611  {
612  m_totalCount = 0;
613  m_doneCount = 0;
614 
615  m_totalCount += count_nodes( partNode );
616 
617  while( libraryNode )
618  {
619  NODE_MAP libraryChildren = MapChildren( libraryNode );
620  wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, "devicesets" );
621 
622  while( devicesetNode )
623  {
624  NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
625  wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, "devices" );
626  wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, "gates" );
627 
628  m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
629 
630  devicesetNode = devicesetNode->GetNext();
631  }
632 
633  libraryNode = libraryNode->GetNext();
634  }
635 
636  // Rewind
637  libraryNode = getChildrenNodes( schematicChildren, "libraries" );
638 
639  while( sheetNode )
640  {
641  NODE_MAP sheetChildren = MapChildren( sheetNode );
642 
643  m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "instances" ) );
644  m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "busses" ) );
645  m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "nets" ) );
646  m_totalCount += count_nodes( getChildrenNodes( sheetChildren, "plain" ) );
647 
648  sheetNode = sheetNode->GetNext();
649  }
650 
651  // Rewind
652  sheetNode = getChildrenNodes( schematicChildren, "sheets" );
653  }
654 
655  while( partNode )
656  {
657  checkpoint();
658 
659  std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
660 
661  // N.B. Eagle parts are case-insensitive in matching but we keep the display case
662  m_partlist[epart->name.Upper()] = std::move( epart );
663  partNode = partNode->GetNext();
664  }
665 
666  if( libraryNode )
667  {
668  while( libraryNode )
669  {
670  // Read the library name
671  wxString libName = libraryNode->GetAttribute( "name" );
672 
673  EAGLE_LIBRARY* elib = &m_eagleLibs[libName];
674  elib->name = libName;
675 
676  loadLibrary( libraryNode, &m_eagleLibs[libName] );
677 
678  libraryNode = libraryNode->GetNext();
679  }
680  m_pi->SaveLibrary( getLibFileName().GetFullPath() );
681  }
682 
683  // find all nets and count how many sheets they appear on.
684  // local labels will be used for nets found only on that sheet.
685  countNets( aSchematicNode );
686 
687  // Loop through all the sheets
688  int sheet_count = countChildren( sheetNode->GetParent(), "sheet" );
689 
690  // If eagle schematic has multiple sheets then create corresponding subsheets on the root sheet
691  if( sheet_count > 1 )
692  {
693  int x, y, i;
694  i = 1;
695  x = 1;
696  y = 1;
697 
698  while( sheetNode )
699  {
700  wxPoint pos = wxPoint( x * Mils2iu( 1000 ), y * Mils2iu( 1000 ) );
701  std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( m_rootSheet, pos );
702  SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
703 
704  sheet->SetScreen( screen );
705  sheet->GetScreen()->SetFileName( sheet->GetFileName() );
706 
707  m_currentSheet = sheet.get();
708  loadSheet( sheetNode, i );
709  m_rootSheet->GetScreen()->Append( sheet.release() );
710 
711  sheetNode = sheetNode->GetNext();
712  x += 2;
713 
714  if( x > 10 ) // start next row
715  {
716  x = 1;
717  y += 2;
718  }
719 
720  i++;
721  }
722  }
723  else
724  {
725  while( sheetNode )
726  {
728  loadSheet( sheetNode, 0 );
729  sheetNode = sheetNode->GetNext();
730  }
731  }
732 
733  // Handle the missing symbol units that need to be instantiated
734  // to create the missing implicit connections
735 
736  // Calculate the already placed items bounding box and the page size to determine
737  // placement for the new symbols
738  wxSize pageSizeIU = m_rootSheet->GetScreen()->GetPageSettings().GetSizeIU();
739  EDA_RECT sheetBbox = getSheetBbox( m_rootSheet );
740  wxPoint newCmpPosition( sheetBbox.GetLeft(), sheetBbox.GetBottom() );
741  int maxY = sheetBbox.GetY();
742 
743  SCH_SHEET_PATH sheetpath;
745 
746  for( auto& cmp : m_missingCmps )
747  {
748  const SCH_SYMBOL* origSymbol = cmp.second.cmp;
749 
750  for( auto unitEntry : cmp.second.units )
751  {
752  if( unitEntry.second == false )
753  continue; // unit has been already processed
754 
755  // Instantiate the missing symbol unit
756  int unit = unitEntry.first;
757  const wxString reference = origSymbol->GetField( REFERENCE_FIELD )->GetText();
758  std::unique_ptr<SCH_SYMBOL> symbol( (SCH_SYMBOL*) origSymbol->Duplicate() );
759 
760  symbol->SetUnitSelection( &sheetpath, unit );
761  symbol->SetUnit( unit );
762  symbol->SetOrientation( 0 );
763  symbol->AddHierarchicalReference( sheetpath.Path(), reference, unit );
764 
765  // Calculate the placement position
766  EDA_RECT cmpBbox = symbol->GetBoundingBox();
767  int posY = newCmpPosition.y + cmpBbox.GetHeight();
768  symbol->SetPosition( wxPoint( newCmpPosition.x, posY ) );
769  newCmpPosition.x += cmpBbox.GetWidth();
770  maxY = std::max( maxY, posY );
771 
772  if( newCmpPosition.x >= pageSizeIU.GetWidth() ) // reached the page boundary?
773  newCmpPosition = wxPoint( sheetBbox.GetLeft(), maxY ); // then start a new row
774 
775  // Add the global net labels to recreate the implicit connections
776  addImplicitConnections( symbol.get(), m_rootSheet->GetScreen(), false );
777  m_rootSheet->GetScreen()->Append( symbol.release() );
778  }
779  }
780 
781  m_missingCmps.clear();
782 }
Field Reference of part, i.e. "IC21".
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:675
EAGLE_LIBRARY * loadLibrary(wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
int GetLeft() const
Definition: eda_rect.h:112
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
int GetWidth() const
Definition: eda_rect.h:109
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provide an easy access to the children of an XML node via their names.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:132
unsigned m_totalCount
for progress reporting
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
int GetBottom() const
Definition: eda_rect.h:114
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
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:85
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
int GetHeight() const
Definition: eda_rect.h:110
static EDA_RECT getSheetBbox(SCH_SHEET *aSheet)
Extract the net name part from a pin name (e.g. return 'GND' for pin named '[email protected]')
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:688
Schematic symbol object.
Definition: sch_symbol.h:78
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:146
Handle the component boundary box.
Definition: eda_rect.h:42
int GetY() const
Definition: eda_rect.h:99
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
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:154
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57

References addImplicitConnections(), SCH_SCREEN::Append(), checkpoint(), countChildren(), countNets(), SCH_ITEM::Duplicate(), EDA_RECT::GetBottom(), getChildrenNodes(), SCH_SYMBOL::GetField(), EDA_RECT::GetHeight(), EDA_RECT::GetLeft(), getLibFileName(), SCH_SCREEN::GetPageSettings(), SCH_SHEET::GetScreen(), getSheetBbox(), EDA_TEXT::GetText(), EDA_RECT::GetWidth(), EDA_RECT::GetY(), loadLibrary(), loadSheet(), SCH_SHEET::LocatePathOfScreen(), m_currentSheet, m_doneCount, m_eagleLibs, m_missingCmps, m_partlist, m_pi, m_progressReporter, m_rootSheet, m_schematic, m_totalCount, MapChildren(), EAGLE_LIBRARY::name, SCH_SHEET_PATH::Path(), and REFERENCE_FIELD.

Referenced by loadDrawing().

◆ loadSegments()

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

Definition at line 1005 of file sch_eagle_plugin.cpp.

1007 {
1008  // Loop through all segments
1009  wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
1010  SCH_SCREEN* screen = m_currentSheet->GetScreen();
1011 
1012  int segmentCount = countChildren( aSegmentsNode, "segment" );
1013 
1014  // wxCHECK( screen, [>void<] );
1015  while( currentSegment )
1016  {
1017  bool labelled = false; // has a label been added to this continuously connected segment
1018  NODE_MAP segmentChildren = MapChildren( currentSegment );
1019  SCH_LINE* firstWire = nullptr;
1020  m_segments.emplace_back();
1021  SEG_DESC& segDesc = m_segments.back();
1022 
1023  // Loop through all segment children
1024  wxXmlNode* segmentAttribute = currentSegment->GetChildren();
1025 
1026  while( segmentAttribute )
1027  {
1028  if( segmentAttribute->GetName() == "wire" )
1029  {
1030  SCH_LINE* wire = loadWire( segmentAttribute );
1031 
1032  if( !firstWire )
1033  firstWire = wire;
1034 
1035  // Test for intersections with other wires
1036  SEG thisWire( wire->GetStartPoint(), wire->GetEndPoint() );
1037 
1038  for( SEG_DESC& desc : m_segments )
1039  {
1040  if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1041  continue; // no point in saving intersections of the same net
1042 
1043  for( const SEG& seg : desc.segs )
1044  {
1045  OPT_VECTOR2I intersection = thisWire.Intersect( seg, true );
1046 
1047  if( intersection )
1048  m_wireIntersections.push_back( *intersection );
1049  }
1050  }
1051 
1052  segDesc.segs.push_back( thisWire );
1053  screen->Append( wire );
1054  }
1055 
1056  segmentAttribute = segmentAttribute->GetNext();
1057  }
1058 
1059  segmentAttribute = currentSegment->GetChildren();
1060 
1061  while( segmentAttribute )
1062  {
1063  wxString nodeName = segmentAttribute->GetName();
1064 
1065  if( nodeName == "junction" )
1066  {
1067  screen->Append( loadJunction( segmentAttribute ) );
1068  }
1069  else if( nodeName == "label" )
1070  {
1071  SCH_TEXT* label = loadLabel( segmentAttribute, netName );
1072  screen->Append( label );
1073  wxASSERT( segDesc.labels.empty()
1074  || segDesc.labels.front()->GetText() == label->GetText() );
1075  segDesc.labels.push_back( label );
1076  labelled = true;
1077  }
1078  else if( nodeName == "pinref" )
1079  {
1080  segmentAttribute->GetAttribute( "gate" ); // REQUIRED
1081  wxString part = segmentAttribute->GetAttribute( "part" ); // REQUIRED
1082  wxString pin = segmentAttribute->GetAttribute( "pin" ); // REQUIRED
1083 
1084  auto powerPort = m_powerPorts.find( "#" + part );
1085 
1086  if( powerPort != m_powerPorts.end()
1087  && powerPort->second == EscapeString( pin, CTX_NETNAME ) )
1088  {
1089  labelled = true;
1090  }
1091  }
1092  else if( nodeName == "wire" )
1093  {
1094  // already handled;
1095  }
1096  else // DEFAULT
1097  {
1098  // THROW_IO_ERROR( wxString::Format( _( "XML node '%s' unknown" ), nodeName ) );
1099  }
1100 
1101  // Get next segment attribute
1102  segmentAttribute = segmentAttribute->GetNext();
1103  }
1104 
1105  // Add a small label to the net segment if it hasn't been labeled already or is not
1106  // connect to a power symbol with a pin on the same net. This preserves the named net
1107  // feature of Eagle schematics.
1108  if( !labelled && firstWire )
1109  {
1110  std::unique_ptr<SCH_TEXT> label;
1111 
1112  // Add a global label if the net appears on more than one Eagle sheet
1113  if( m_netCounts[netName.ToStdString()] > 1 )
1114  label.reset( new SCH_GLOBALLABEL );
1115  else if( segmentCount > 1 )
1116  label.reset( new SCH_LABEL );
1117 
1118  if( label )
1119  {
1120  label->SetPosition( firstWire->GetStartPoint() );
1121  label->SetText( escapeName( netName ) );
1122  label->SetTextSize( wxSize( Mils2iu( 40 ), Mils2iu( 40 ) ) );
1123 
1124  if( firstWire->GetEndPoint().x > firstWire->GetStartPoint().x )
1125  label->SetLabelSpinStyle( LABEL_SPIN_STYLE::LEFT );
1126  else
1127  label->SetLabelSpinStyle( LABEL_SPIN_STYLE::RIGHT );
1128 
1129  screen->Append( label.release() );
1130  }
1131  }
1132 
1133  currentSegment = currentSegment->GetNext();
1134  }
1135 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
wxPoint GetStartPoint() const
Definition: sch_line.h:90
SCH_LINE * loadWire(wxXmlNode *aWireNode)
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:154
std::map< wxString, int > m_netCounts
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provide an easy access to the children of an XML node via their names.
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
SCH_JUNCTION * loadJunction(wxXmlNode *aJunction)
wxString escapeName(const wxString &aNetName)
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
SCH_TEXT * loadLabel(wxXmlNode *aLabelNode, const wxString &aNetName)
Definition: seg.h:40
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
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:146
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
void SetPosition(const wxPoint &aPosition) override
Definition: sch_text.h:240
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:154
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
wxPoint GetEndPoint() const
Definition: sch_line.h:93

References SCH_SCREEN::Append(), countChildren(), CTX_NETNAME, escapeName(), EscapeString(), SCH_LINE::GetEndPoint(), SCH_SHEET::GetScreen(), SCH_LINE::GetStartPoint(), EDA_TEXT::GetText(), SEG::Intersect(), SCH_EAGLE_PLUGIN::SEG_DESC::labels, LABEL_SPIN_STYLE::LEFT, loadJunction(), loadLabel(), loadWire(), m_currentSheet, m_netCounts, m_powerPorts, m_segments, m_wireIntersections, MapChildren(), pin, LABEL_SPIN_STYLE::RIGHT, and SCH_EAGLE_PLUGIN::SEG_DESC::segs.

Referenced by loadSheet().

◆ loadSheet()

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

Definition at line 785 of file sch_eagle_plugin.cpp.

786 {
787  // Map all children into a readable dictionary
788  NODE_MAP sheetChildren = MapChildren( aSheetNode );
789 
790  // Get description node
791  wxXmlNode* descriptionNode = getChildrenNodes( sheetChildren, "description" );
792 
793  wxString des;
794  std::string filename;
795  SCH_FIELD& sheetNameField = m_currentSheet->GetFields()[SHEETNAME];
796  SCH_FIELD& filenameField = m_currentSheet->GetFields()[SHEETFILENAME];
797 
798  if( descriptionNode )
799  {
800  des = descriptionNode->GetContent();
801  des.Replace( "\n", "_", true );
802  sheetNameField.SetText( des );
803  filename = des.ToStdString();
804  }
805  else
806  {
807  filename = wxString::Format( "%s_%d", m_filename.GetName(), aSheetIndex );
808  sheetNameField.SetText( filename );
809  }
810 
811  ReplaceIllegalFileNameChars( &filename );
812  replace( filename.begin(), filename.end(), ' ', '_' );
813 
814  wxFileName fn( m_filename );
815  fn.SetName( filename );
816  fn.SetExt( KiCadSchematicFileExtension );
817 
818  filenameField.SetText( fn.GetFullName() );
819  m_currentSheet->GetScreen()->SetFileName( fn.GetFullPath() );
821 
822 
823  // Loop through all of the symbol instances.
824  wxXmlNode* instanceNode = getChildrenNodes( sheetChildren, "instances" );
825 
826  while( instanceNode )
827  {
828  checkpoint();
829 
830  loadInstance( instanceNode );
831  instanceNode = instanceNode->GetNext();
832  }
833 
834  // Loop through all buses
835  // From the DTD: "Buses receive names which determine which signals they include.
836  // A bus is a drawing object. It does not create any electrical connections.
837  // These are always created by means of the nets and their names."
838  wxXmlNode* busNode = getChildrenNodes( sheetChildren, "busses" );
839 
840  while( busNode )
841  {
842  checkpoint();
843 
844  // Get the bus name
845  wxString busName = translateEagleBusName( busNode->GetAttribute( "name" ) );
846 
847  // Load segments of this bus
848  loadSegments( busNode, busName, wxString() );
849 
850  // Get next bus
851  busNode = busNode->GetNext();
852  }
853 
854  // Loop through all nets
855  // From the DTD: "Net is an electrical connection in a schematic."
856  wxXmlNode* netNode = getChildrenNodes( sheetChildren, "nets" );
857 
858  while( netNode )
859  {
860  checkpoint();
861 
862  // Get the net name and class
863  wxString netName = netNode->GetAttribute( "name" );
864  wxString netClass = netNode->GetAttribute( "class" );
865 
866  // Load segments of this net
867  loadSegments( netNode, netName, netClass );
868 
869  // Get next net
870  netNode = netNode->GetNext();
871  }
872 
873  adjustNetLabels(); // needs to be called before addBusEntries()
874  addBusEntries();
875 
876  /* moduleinst is a design block definition and is an EagleCad 8 feature,
877  *
878  * // Loop through all moduleinsts
879  * wxXmlNode* moduleinstNode = getChildrenNodes( sheetChildren, "moduleinsts" );
880  *
881  * while( moduleinstNode )
882  * {
883  * loadModuleinst( moduleinstNode );
884  * moduleinstNode = moduleinstNode->GetNext();
885  * }
886  */
887 
888  wxXmlNode* plainNode = getChildrenNodes( sheetChildren, "plain" );
889 
890  while( plainNode )
891  {
892  checkpoint();
893 
894  wxString nodeName = plainNode->GetName();
895 
896  if( nodeName == "text" )
897  {
898  m_currentSheet->GetScreen()->Append( loadPlainText( plainNode ) );
899  }
900  else if( nodeName == "wire" )
901  {
902  m_currentSheet->GetScreen()->Append( loadWire( plainNode ) );
903  }
904  else if( nodeName == "frame" )
905  {
906  std::vector<SCH_LINE*> lines;
907 
908  loadFrame( plainNode, lines );
909 
910  for( SCH_LINE* line : lines )
911  m_currentSheet->GetScreen()->Append( line );
912  }
913 
914  plainNode = plainNode->GetNext();
915  }
916 
917  // Calculate the new sheet size.
918  EDA_RECT sheetBoundingBox = getSheetBbox( m_currentSheet );
919  wxSize targetSheetSize = sheetBoundingBox.GetSize();
920  targetSheetSize.IncBy( Mils2iu( 1500 ), Mils2iu( 1500 ) );
921 
922  // Get current Eeschema sheet size.
923  wxSize pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
925 
926  // Increase if necessary
927  if( pageSizeIU.x < targetSheetSize.x )
928  pageInfo.SetWidthMils( Iu2Mils( targetSheetSize.x ) );
929 
930  if( pageSizeIU.y < targetSheetSize.y )
931  pageInfo.SetHeightMils( Iu2Mils( targetSheetSize.y ) );
932 
933  // Set the new sheet size.
934  m_currentSheet->GetScreen()->SetPageSettings( pageInfo );
935 
936  pageSizeIU = m_currentSheet->GetScreen()->GetPageSettings().GetSizeIU();
937  wxPoint sheetcentre( pageSizeIU.x / 2, pageSizeIU.y / 2 );
938  wxPoint itemsCentre = sheetBoundingBox.Centre();
939 
940  // round the translation to nearest 100mil to place it on the grid.
941  wxPoint translation = sheetcentre - itemsCentre;
942  translation.x = translation.x - translation.x % Mils2iu( 100 );
943  translation.y = translation.y - translation.y % Mils2iu( 100 );
944 
945  // Add global net labels for the named power input pins in this sheet
946  for( SCH_ITEM* item : m_currentSheet->GetScreen()->Items().OfType( SCH_SYMBOL_T ) )
947  {
948  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
949  addImplicitConnections( symbol, m_currentSheet->GetScreen(), true );
950  }
951 
952  m_connPoints.clear();
953 
954  // Translate the items.
955  std::vector<SCH_ITEM*> allItems;
956 
957  std::copy( m_currentSheet->GetScreen()->Items().begin(),
958  m_currentSheet->GetScreen()->Items().end(), std::back_inserter( allItems ) );
959 
960  for( SCH_ITEM* item : allItems )
961  {
962  item->SetPosition( item->GetPosition() + translation );
963  item->ClearFlags();
964  m_currentSheet->GetScreen()->Update( item );
965 
966  }
967 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:230
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
SCH_LINE * loadWire(wxXmlNode *aWireNode)
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:133
SCH_TEXT * loadPlainText(wxXmlNode *aSchText)
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:132
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:90
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:124
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:53
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
Definition: sch_rtree.h:277
void loadSegments(wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
void loadFrame(wxXmlNode *aFrameNode, std::vector< SCH_LINE * > &aLines)
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:257
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
static EDA_RECT getSheetBbox(SCH_SHEET *aSheet)
Extract the net name part from a pin name (e.g. return 'GND' for pin named '[email protected]')
void loadInstance(wxXmlNode *aInstanceNode)
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
Schematic symbol object.
Definition: sch_symbol.h:78
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:146
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
Definition: sch_rtree.h:268
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:243
Handle the component boundary box.
Definition: eda_rect.h:42
const std::string KiCadSchematicFileExtension
wxPoint Centre() const
Definition: eda_rect.h:55
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:266
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:110
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:538
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57
const wxSize GetSize() const
Definition: eda_rect.h:91
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints

References addBusEntries(), addImplicitConnections(), adjustNetLabels(), SCH_SCREEN::Append(), SCH_SHEET::AutoplaceFields(), EE_RTREE::begin(), EDA_RECT::Centre(), checkpoint(), EE_RTREE::end(), Format(), getChildrenNodes(), SCH_SHEET::GetFields(), SCH_SCREEN::GetPageSettings(), SCH_SHEET::GetScreen(), getSheetBbox(), EDA_RECT::GetSize(), SCH_SCREEN::Items(), KiCadSchematicFileExtension, loadFrame(), loadInstance(), loadPlainText(), loadSegments(), loadWire(), m_connPoints, m_currentSheet, m_filename, MapChildren(), EE_RTREE::OfType(), ReplaceIllegalFileNameChars(), SCH_SYMBOL_T, SCH_SCREEN::SetFileName(), PAGE_INFO::SetHeightMils(), SCH_SCREEN::SetPageSettings(), EDA_TEXT::SetText(), PAGE_INFO::SetWidthMils(), SHEETFILENAME, SHEETNAME, translateEagleBusName(), and SCH_SCREEN::Update().

Referenced by loadSchematic().

◆ loadSymbol()

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

Definition at line 1585 of file sch_eagle_plugin.cpp.

1587 {
1588  wxString symbolName = aSymbolNode->GetAttribute( "name" );
1589  std::vector<LIB_ITEM*> items;
1590 
1591  wxXmlNode* currentNode = aSymbolNode->GetChildren();
1592 
1593  bool foundName = false;
1594  bool foundValue = false;
1595  bool ispower = false;
1596  int pincount = 0;
1597 
1598  while( currentNode )
1599  {
1600  wxString nodeName = currentNode->GetName();
1601 
1602  if( nodeName == "circle" )
1603  {
1604  aSymbol->AddDrawItem( loadSymbolCircle( aSymbol, currentNode, aGateNumber ) );
1605  }
1606  else if( nodeName == "pin" )
1607  {
1608  EPIN ePin = EPIN( currentNode );
1609  std::unique_ptr<LIB_PIN> pin( loadPin( aSymbol, currentNode, &ePin, aGateNumber ) );
1610  pincount++;
1611 
1612  pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1613 
1614  if( ePin.direction )
1615  {
1616  for( const auto& pinDir : pinDirectionsMap )
1617  {
1618  if( ePin.direction->Lower() == pinDir.first )
1619  {
1620  pin->SetType( pinDir.second );
1621 
1622  if( pinDir.first == "sup" ) // power supply symbol
1623  ispower = true;
1624 
1625  break;
1626  }
1627  }
1628  }
1629 
1630  if( aDevice->connects.size() != 0 )
1631  {
1632  for( const ECONNECT& connect : aDevice->connects )
1633  {
1634  if( connect.gate == aGateName && pin->GetName() == connect.pin )
1635  {
1636  wxArrayString pads = wxSplit( wxString( connect.pad ), ' ' );
1637 
1638  pin->SetUnit( aGateNumber );
1639  pin->SetName( escapeName( pin->GetName() ) );
1640 
1641  if( pads.GetCount() > 1 )
1642  {
1643  pin->SetNumberTextSize( 0 );
1644  }
1645 
1646  for( unsigned i = 0; i < pads.GetCount(); i++ )
1647  {
1648  LIB_PIN* apin = new LIB_PIN( *pin );
1649 
1650  wxString padname( pads[i] );
1651  apin->SetNumber( padname );
1652  aSymbol->AddDrawItem( apin );
1653  }
1654 
1655  break;
1656  }
1657  }
1658  }
1659  else
1660  {
1661  pin->SetUnit( aGateNumber );
1662  pin->SetNumber( wxString::Format( "%i", pincount ) );
1663  aSymbol->AddDrawItem( pin.release() );
1664  }
1665  }
1666  else if( nodeName == "polygon" )
1667  {
1668  aSymbol->AddDrawItem( loadSymbolPolyLine( aSymbol, currentNode, aGateNumber ) );
1669  }
1670  else if( nodeName == "rectangle" )
1671  {
1672  aSymbol->AddDrawItem( loadSymbolRectangle( aSymbol, currentNode, aGateNumber ) );
1673  }
1674  else if( nodeName == "text" )
1675  {
1676  std::unique_ptr<LIB_TEXT> libtext( loadSymbolText( aSymbol, currentNode,
1677  aGateNumber ) );
1678 
1679  if( libtext->GetText().Upper() == ">NAME" )
1680  {
1681  LIB_FIELD* field = aSymbol->GetFieldById( REFERENCE_FIELD );
1682  loadFieldAttributes( field, libtext.get() );
1683  foundName = true;
1684  }
1685  else if( libtext->GetText().Upper() == ">VALUE" )
1686  {
1687  LIB_FIELD* field = aSymbol->GetFieldById( VALUE_FIELD );
1688  loadFieldAttributes( field, libtext.get() );
1689  foundValue = true;
1690  }
1691  else
1692  {
1693  aSymbol->AddDrawItem( libtext.release() );
1694  }
1695  }
1696  else if( nodeName == "wire" )
1697  {
1698  aSymbol->AddDrawItem( loadSymbolWire( aSymbol, currentNode, aGateNumber ) );
1699  }
1700  else if( nodeName == "frame" )
1701  {
1702  std::vector<LIB_ITEM*> frameItems;
1703 
1704  loadFrame( currentNode, frameItems );
1705 
1706  for( LIB_ITEM* item : frameItems )
1707  {
1708  item->SetParent( aSymbol.get() );
1709  aSymbol->AddDrawItem( item );
1710  }
1711  }
1712 
1713  /*
1714  * else if( nodeName == "description" )
1715  * {
1716  * }
1717  * else if( nodeName == "dimension" )
1718  * {
1719  * }
1720  */
1721 
1722  currentNode = currentNode->GetNext();
1723  }
1724 
1725  if( foundName == false )
1726  aSymbol->GetFieldById( REFERENCE_FIELD )->SetVisible( false );
1727 
1728  if( foundValue == false )
1729  aSymbol->GetFieldById( VALUE_FIELD )->SetVisible( false );
1730 
1731  return pincount == 1 ? ispower : false;
1732 }
Field Reference of part, i.e. "IC21".
wxString pad
opt_wxString direction
Definition: eagle_parser.h:749
Field object used in symbol libraries.
Definition: lib_field.h:59
wxString gate
Eagle pin element.
Definition: eagle_parser.h:741
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
LIB_SHAPE * loadSymbolCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aCircleNode, int aGateNumber)
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:118
wxString escapeName(const wxString &aNetName)
Field Value of part, i.e. "3.3K".
LIB_TEXT * loadSymbolText(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aLibText, int aGateNumber)
LIB_SHAPE * loadSymbolPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aPolygonNode, int aGateNumber)
void loadFrame(wxXmlNode *aFrameNode, std::vector< SCH_LINE * > &aLines)
LIB_ITEM * loadSymbolWire(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aWireNode, int aGateNumber)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void loadFieldAttributes(LIB_FIELD *aField, const LIB_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
std::vector< ECONNECT > connects
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
LIB_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *, EPIN *epin, int aGateNumber)
input or output (like port for a microprocessor)
LIB_SHAPE * loadSymbolRectangle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aRectNode, int aGateNumber)
wxString pin

References EDEVICE::connects, EPIN::direction, escapeName(), Format(), ECONNECT::gate, loadFieldAttributes(), loadFrame(), loadPin(), loadSymbolCircle(), loadSymbolPolyLine(), loadSymbolRectangle(), loadSymbolText(), loadSymbolWire(), ECONNECT::pad, pin, ECONNECT::pin, pinDirectionsMap, PT_BIDI, REFERENCE_FIELD, LIB_PIN::SetNumber(), and VALUE_FIELD.

Referenced by loadLibrary().

◆ LoadSymbol()

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

Load a LIB_SYMBOL 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_SYMBOL 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 85 of file sch_plugin.cpp.

87 {
88  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
89  not_implemented( this, __FUNCTION__ );
90  return nullptr;
91 }
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:37

References not_implemented().

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

◆ loadSymbolCircle()

LIB_SHAPE * SCH_EAGLE_PLUGIN::loadSymbolCircle ( std::unique_ptr< LIB_SYMBOL > &  aSymbol,
wxXmlNode *  aCircleNode,
int  aGateNumber 
)
private

Definition at line 1735 of file sch_eagle_plugin.cpp.

1737 {
1738  // Parse the circle properties
1739  ECIRCLE c( aCircleNode );
1740  LIB_SHAPE* circle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::CIRCLE );
1741  wxPoint center( c.x.ToSchUnits(), c.y.ToSchUnits() );
1742 
1743  circle->SetPosition( center );
1744  circle->SetEnd( wxPoint( center.x + c.radius.ToSchUnits(), center.y ) );
1745  circle->SetWidth( c.width.ToSchUnits() );
1746  circle->SetUnit( aGateNumber );
1747 
1748  return circle;
1749 }
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:126
void SetPosition(const wxPoint &aPosition) override
Definition: lib_shape.h:87
Eagle circle.
Definition: eagle_parser.h:562
void SetWidth(int aWidth)
Definition: eda_shape.h:88
void SetUnit(int aUnit)
Definition: lib_item.h:257

References CIRCLE, ECIRCLE::radius, EDA_SHAPE::SetEnd(), LIB_SHAPE::SetPosition(), LIB_ITEM::SetUnit(), EDA_SHAPE::SetWidth(), ECOORD::ToSchUnits(), ECIRCLE::width, ECIRCLE::x, and ECIRCLE::y.

Referenced by loadSymbol().

◆ loadSymbolPolyLine()

LIB_SHAPE * SCH_EAGLE_PLUGIN::loadSymbolPolyLine ( std::unique_ptr< LIB_SYMBOL > &  aSymbol,
wxXmlNode *  aPolygonNode,
int  aGateNumber 
)
private

Definition at line 1843 of file sch_eagle_plugin.cpp.

1845 {
1846  LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY );
1847  EPOLYGON epoly( aPolygonNode );
1848  wxXmlNode* vertex = aPolygonNode->GetChildren();
1849  wxPoint pt;
1850 
1851  while( vertex )
1852  {
1853  if( vertex->GetName() == "vertex" ) // skip <xmlattr> node
1854  {
1855  EVERTEX evertex( vertex );
1856  pt = wxPoint( evertex.x.ToSchUnits(), evertex.y.ToSchUnits() );
1857  poly->AddPoint( pt );
1858  }
1859 
1860  vertex = vertex->GetNext();
1861  }
1862 
1864  poly->SetUnit( aGateNumber );
1865 
1866  return poly;
1867 }
Eagle vertex.
Definition: eagle_parser.h:759
void AddPoint(const wxPoint &aPosition)
Definition: lib_shape.cpp:407
void SetUnit(int aUnit)
Definition: lib_item.h:257
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:78
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:770

References LIB_SHAPE::AddPoint(), FILLED_SHAPE, POLY, EDA_SHAPE::SetFillMode(), LIB_ITEM::SetUnit(), ECOORD::ToSchUnits(), EVERTEX::x, and EVERTEX::y.

Referenced by loadSymbol().

◆ loadSymbolRectangle()

LIB_SHAPE * SCH_EAGLE_PLUGIN::loadSymbolRectangle ( std::unique_ptr< LIB_SYMBOL > &  aSymbol,
wxXmlNode *  aRectNode,
int  aGateNumber 
)
private

Definition at line 1752 of file sch_eagle_plugin.cpp.

1754 {
1755  ERECT rect( aRectNode );
1756  LIB_SHAPE* rectangle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::RECT );
1757 
1758  rectangle->SetPosition( wxPoint( rect.x1.ToSchUnits(), rect.y1.ToSchUnits() ) );
1759  rectangle->SetEnd( wxPoint( rect.x2.ToSchUnits(), rect.y2.ToSchUnits() ) );
1760 
1761  rectangle->SetUnit( aGateNumber );
1762 
1763  // Eagle rectangles are filled by definition.
1764  rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1765 
1766  return rectangle;
1767 }
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:126
void SetPosition(const wxPoint &aPosition) override
Definition: lib_shape.h:87
Eagle XML rectangle in binary.
Definition: eagle_parser.h:575
void SetUnit(int aUnit)
Definition: lib_item.h:257
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:78

References FILLED_SHAPE, RECT, EDA_SHAPE::SetEnd(), EDA_SHAPE::SetFillMode(), LIB_SHAPE::SetPosition(), LIB_ITEM::SetUnit(), ECOORD::ToSchUnits(), ERECT::x1, ERECT::x2, ERECT::y1, and ERECT::y2.

Referenced by loadSymbol().

◆ loadSymbolText()

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

Definition at line 1947 of file sch_eagle_plugin.cpp.

1949 {
1950  std::unique_ptr<LIB_TEXT> libtext = std::make_unique<LIB_TEXT>( aSymbol.get() );
1951  ETEXT etext( aLibText );
1952 
1953  libtext->SetUnit( aGateNumber );
1954  libtext->SetPosition( wxPoint( etext.x.ToSchUnits(), etext.y.ToSchUnits() ) );
1955 
1956  // Eagle supports multiple line text in library symbols. Legacy library symbol text cannot
1957  // contain CRs or LFs.
1958  //
1959  // @todo Split this into multiple text objects and offset the Y position so that it looks
1960  // more like the original Eagle schematic.
1961  wxString text = aLibText->GetNodeContent();
1962  std::replace( text.begin(), text.end(), '\n', '_' );
1963  std::replace( text.begin(), text.end(), '\r', '_' );
1964 
1965  libtext->SetText( text.IsEmpty() ? "~" : text );
1966  loadTextAttributes( libtext.get(), etext );
1967 
1968  return libtext.release();
1969 }
Eagle text element.
Definition: eagle_parser.h:637
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const

References loadTextAttributes(), and text.

Referenced by loadSymbol().

◆ loadSymbolWire()

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

Definition at line 1770 of file sch_eagle_plugin.cpp.

1772 {
1773  EWIRE ewire = EWIRE( aWireNode );
1774 
1775  wxPoint begin, end;
1776 
1777  begin.x = ewire.x1.ToSchUnits();
1778  begin.y = ewire.y1.ToSchUnits();
1779  end.x = ewire.x2.ToSchUnits();
1780  end.y = ewire.y2.ToSchUnits();
1781 
1782  if( begin == end )
1783  return nullptr;
1784 
1785  // if the wire is an arc
1786  if( ewire.curve )
1787  {
1788  LIB_SHAPE* arc = new LIB_SHAPE( aSymbol.get(), SHAPE_T::ARC );
1789  wxPoint center = ConvertArcCenter( begin, end, *ewire.curve * -1 );
1790  double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1791  + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1792  * 2;
1793 
1794  // this emulates the filled semicircles created by a thick arc with flat ends caps.
1795  if( ewire.width.ToSchUnits() * 2 > radius )
1796  {
1797  wxPoint centerStartVector = begin - center;
1798  wxPoint centerEndVector = end - center;
1799 
1800  centerStartVector.x = centerStartVector.x * ewire.width.ToSchUnits() * 2 / radius;
1801  centerStartVector.y = centerStartVector.y * ewire.width.ToSchUnits() * 2 / radius;
1802 
1803  centerEndVector.x = centerEndVector.x * ewire.width.ToSchUnits() * 2 / radius;
1804  centerEndVector.y = centerEndVector.y * ewire.width.ToSchUnits() * 2 / radius;
1805 
1806  begin = center + centerStartVector;
1807  end = center + centerEndVector;
1808 
1809  radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1810  + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1811  * 2;
1812 
1813  arc->SetWidth( 1 );
1815  }
1816  else
1817  {
1818  arc->SetWidth( ewire.width.ToSchUnits() );
1819  }
1820 
1821  if( *ewire.curve <= 0 )
1822  std::swap( begin, end );
1823 
1824  arc->SetArcGeometry( begin, (wxPoint) CalcArcMid( begin, end, center ), end );
1825  arc->SetUnit( aGateNumber );
1826 
1827  return arc;
1828  }
1829  else
1830  {
1831  LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY );
1832 
1833  poly->AddPoint( begin );
1834  poly->AddPoint( end );
1835  poly->SetUnit( aGateNumber );
1836  poly->SetWidth( ewire.width.ToSchUnits() );
1837 
1838  return poly;
1839  }
1840 }
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:508
void AddPoint(const wxPoint &aPosition)
Definition: lib_shape.cpp:407
int ToSchUnits() const
Definition: eagle_parser.h:429
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
Definition: trigo.cpp:163
void SetArcGeometry(const wxPoint &aStart, const wxPoint &aMid, const wxPoint &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:489
ECOORD width
Definition: eagle_parser.h:497
ECOORD y1
Definition: eagle_parser.h:494
void SetWidth(int aWidth)
Definition: eda_shape.h:88
ECOORD y2
Definition: eagle_parser.h:496
void SetUnit(int aUnit)
Definition: lib_item.h:257
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
Eagle wire.
Definition: eagle_parser.h:491
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:78
ECOORD x1
Definition: eagle_parser.h:493
ECOORD x2
Definition: eagle_parser.h:495

References LIB_SHAPE::AddPoint(), ARC, CalcArcMid(), ConvertArcCenter(), EWIRE::curve, FILLED_SHAPE, POLY, EDA_SHAPE::SetArcGeometry(), EDA_SHAPE::SetFillMode(), LIB_ITEM::SetUnit(), EDA_SHAPE::SetWidth(), ECOORD::ToSchUnits(), EWIRE::width, EWIRE::x1, EWIRE::x2, EWIRE::y1, and EWIRE::y2.

Referenced by loadSymbol().

◆ loadTextAttributes()

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

Definition at line 2181 of file sch_eagle_plugin.cpp.

2182 {
2183  aText->SetTextSize( aAttribs.ConvertSize() );
2184 
2185  if( aAttribs.ratio )
2186  {
2187  if( aAttribs.ratio.CGet() > 12 )
2188  {
2189  aText->SetBold( true );
2190  aText->SetTextThickness( GetPenSizeForBold( aText->GetTextWidth() ) );
2191  }
2192  }
2193 
2194  int align = aAttribs.align ? *aAttribs.align : ETEXT::BOTTOM_LEFT;
2195  int degrees = aAttribs.rot ? aAttribs.rot->degrees : 0;
2196  bool mirror = aAttribs.rot ? aAttribs.rot->mirror : false;
2197  bool spin = aAttribs.rot ? aAttribs.rot->spin : false;
2198 
2199  eagleToKicadAlignment( aText, align, degrees, mirror, spin, 0 );
2200 }
bool mirror
Definition: eagle_parser.h:472
int GetPenSizeForBold(int aTextSize)
Definition: gr_text.cpp:46
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:303
opt_double ratio
Definition: eagle_parser.h:645
double degrees
Definition: eagle_parser.h:474
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:258
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:662
opt_erot rot
Definition: eagle_parser.h:646
int GetTextWidth() const
Definition: eda_text.h:262
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:180
bool spin
Definition: eagle_parser.h:473
void SetBold(bool aBold)
Definition: eda_text.h:203

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.

Referenced by loadPlainText(), and loadSymbolText().

◆ loadWire()

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

Definition at line 1138 of file sch_eagle_plugin.cpp.

1139 {
1140  std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
1141 
1142  EWIRE ewire = EWIRE( aWireNode );
1143 
1144  wire->SetLayer( kiCadLayer( ewire.layer ) );
1145 
1146  wxPoint begin, end;
1147 
1148  begin.x = ewire.x1.ToSchUnits();
1149  begin.y = -ewire.y1.ToSchUnits();
1150  end.x = ewire.x2.ToSchUnits();
1151  end.y = -ewire.y2.ToSchUnits();
1152 
1153  wire->SetStartPoint( begin );
1154  wire->SetEndPoint( end );
1155 
1156  m_connPoints[begin].emplace( wire.get() );
1157  m_connPoints[end].emplace( wire.get() );
1158 
1159  return wire.release();
1160 }
int ToSchUnits() const
Definition: eagle_parser.h:429
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
ECOORD y1
Definition: eagle_parser.h:494
LAYER_NUM layer
Definition: eagle_parser.h:498
ECOORD y2
Definition: eagle_parser.h:496
Eagle wire.
Definition: eagle_parser.h:491
ECOORD x1
Definition: eagle_parser.h:493
ECOORD x2
Definition: eagle_parser.h:495
std::map< wxPoint, std::set< const EDA_ITEM * > > m_connPoints

References kiCadLayer(), EWIRE::layer, m_connPoints, ECOORD::ToSchUnits(), EWIRE::x1, EWIRE::x2, EWIRE::y1, and EWIRE::y2.

Referenced by loadSegments(), and loadSheet().

◆ moveLabels()

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

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

Definition at line 2309 of file sch_eagle_plugin.cpp.

2310 {
2311  for( SCH_ITEM* item : m_currentSheet->GetScreen()->Items().Overlapping( aWire->GetBoundingBox() ) )
2312  {
2313  if( item->Type() == SCH_LABEL_T || item->Type() == SCH_GLOBAL_LABEL_T )
2314  {
2315  if( TestSegmentHit( item->GetPosition(), aWire->GetStartPoint(), aWire->GetEndPoint(),
2316  0 ) )
2317  {
2318  item->SetPosition( aNewEndPoint );
2319  }
2320  }
2321  }
2322 }
SCH_SHEET * m_currentSheet
The current sheet of the schematic being loaded.
wxPoint GetStartPoint() const
Definition: sch_line.h:90
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:105
bool TestSegmentHit(const wxPoint &aRefPoint, const wxPoint &aStart, const wxPoint &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
EE_TYPE Overlapping(const EDA_RECT &aRect) const
Definition: sch_rtree.h:235
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:190
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
wxPoint GetEndPoint() const
Definition: sch_line.h:93

References SCH_LINE::GetBoundingBox(), SCH_LINE::GetEndPoint(), SCH_SHEET::GetScreen(), SCH_LINE::GetStartPoint(), SCH_SCREEN::Items(), m_currentSheet, EE_RTREE::Overlapping(), SCH_GLOBAL_LABEL_T, SCH_LABEL_T, and TestSegmentHit().

Referenced by addBusEntries().

◆ netHasPowerDriver()

bool SCH_EAGLE_PLUGIN::netHasPowerDriver ( SCH_LINE aLine,
const wxString &  aNetName 
) const
private

◆ Save()

void SCH_PLUGIN::Save ( const wxString &  aFileName,
SCH_SHEET aSheet,
SCHEMATIC aSchematic,
const PROPERTIES aProperties = nullptr 
)
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 hierarchical 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 59 of file sch_plugin.cpp.

61 {
62  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
63  not_implemented( this, __FUNCTION__ );
64 }
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:37

References not_implemented().

◆ SaveLibrary()

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

Reimplemented in SCH_LEGACY_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 45 of file sch_plugin.cpp.

46 {
47  not_implemented( this, __FUNCTION__ );
48 }
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:37

References not_implemented().

◆ SaveSymbol()

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

Write aSymbol to an existing library located at aLibraryPath.

If a LIB_SYMBOL by the same name already exists or there are any conflicting alias names, the new LIB_SYMBOL will silently overwrite any existing aliases and/or part because 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_SYMBOL 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 94 of file sch_plugin.cpp.

96 {
97  // not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
98  not_implemented( this, __FUNCTION__ );
99 }
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:37

References not_implemented().

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

◆ SetProgressReporter()

void SCH_EAGLE_PLUGIN::SetProgressReporter ( PROGRESS_REPORTER aReporter)
inlineoverridevirtual

Set an optional progress reporter.

Reimplemented from SCH_PLUGIN.

Definition at line 90 of file sch_eagle_plugin.h.

91  {
92  m_progressReporter = aReporter;
93  }
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr

References m_progressReporter.

◆ SetReporter()

void SCH_EAGLE_PLUGIN::SetReporter ( REPORTER aReporter)
inlineoverridevirtual

Set an optional reporter for warnings/errors.

Reimplemented from SCH_PLUGIN.

Definition at line 88 of file sch_eagle_plugin.h.

88 { m_reporter = aReporter; }
REPORTER * m_reporter
Reporter for warnings/errors.

References m_reporter.

◆ 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 133 of file sch_plugin.cpp.

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

References _.

◆ translateEagleBusName()

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

Translate 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 2990 of file sch_eagle_plugin.cpp.

2991 {
2992  if( NET_SETTINGS::ParseBusVector( aEagleName, nullptr, nullptr ) )
2993  return aEagleName;
2994 
2995  wxString ret = "{";
2996 
2997  wxStringTokenizer tokenizer( aEagleName, "," );
2998 
2999  while( tokenizer.HasMoreTokens() )
3000  {
3001  wxString member = tokenizer.GetNextToken();
3002 
3003  // In Eagle, overbar text is automatically stopped at the end of the net name, even when
3004  // that net name is part of a bus definition. In KiCad, we don't (currently) do that, so
3005  // if there is an odd number of overbar markers in this net name, we need to append one
3006  // to close it out before appending the space.
3007 
3008  if( member.Freq( '!' ) % 2 > 0 )
3009  member << "!";
3010 
3011  ret << member << " ";
3012  }
3013 
3014  ret.Trim( true );
3015  ret << "}";
3016 
3017  return ret;
3018 }
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.

References NET_SETTINGS::ParseBusVector().

Referenced by loadSheet().

Member Data Documentation

◆ m_connPoints

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

Definition at line 261 of file sch_eagle_plugin.h.

Referenced by checkConnections(), loadInstance(), loadSheet(), and loadWire().

◆ m_currentSheet

SCH_SHEET* SCH_EAGLE_PLUGIN::m_currentSheet
private

The current sheet of the schematic being loaded.

Definition at line 218 of file sch_eagle_plugin.h.

Referenced by addBusEntries(), loadInstance(), loadSchematic(), loadSegments(), loadSheet(), moveLabels(), and SCH_EAGLE_PLUGIN().

◆ m_doneCount

unsigned SCH_EAGLE_PLUGIN::m_doneCount
private

Definition at line 231 of file sch_eagle_plugin.h.

Referenced by checkpoint(), and loadSchematic().

◆ m_eagleLibs

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

Definition at line 225 of file sch_eagle_plugin.h.

Referenced by loadInstance(), and loadSchematic().

◆ m_filename

wxFileName SCH_EAGLE_PLUGIN::m_filename
private

Definition at line 220 of file sch_eagle_plugin.h.

Referenced by Load(), and loadSheet().

◆ m_lastProgressCount

unsigned SCH_EAGLE_PLUGIN::m_lastProgressCount
private

Definition at line 232 of file sch_eagle_plugin.h.

Referenced by checkpoint().

◆ m_layerMap

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

Definition at line 236 of file sch_eagle_plugin.h.

◆ m_libName

wxString SCH_EAGLE_PLUGIN::m_libName
private

Library name to save symbols.

Definition at line 221 of file sch_eagle_plugin.h.

◆ m_missingCmps

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

Definition at line 215 of file sch_eagle_plugin.h.

Referenced by addImplicitConnections(), and loadSchematic().

◆ m_netCounts

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

Definition at line 235 of file sch_eagle_plugin.h.

Referenced by countNets(), loadLabel(), and loadSegments().

◆ m_nets

std::map<wxString, ENET> SCH_EAGLE_PLUGIN::m_nets
private

Positions of pins and wire endings mapped to its parent.

Definition at line 258 of file sch_eagle_plugin.h.

◆ m_partlist

EPART_MAP SCH_EAGLE_PLUGIN::m_partlist
private

Definition at line 224 of file sch_eagle_plugin.h.

Referenced by loadInstance(), and loadSchematic().

◆ m_pi

SCH_PLUGIN::SCH_PLUGIN_RELEASER SCH_EAGLE_PLUGIN::m_pi
private

PI to create KiCad symbol library.

Definition at line 227 of file sch_eagle_plugin.h.

Referenced by Load(), loadInstance(), loadLibrary(), and loadSchematic().

◆ m_powerPorts

std::map<wxString, wxString> SCH_EAGLE_PLUGIN::m_powerPorts
private

map from symbol reference to global label equivalent

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

Definition at line 237 of file sch_eagle_plugin.h.

Referenced by loadInstance(), and loadSegments().

◆ m_progressReporter

PROGRESS_REPORTER* SCH_EAGLE_PLUGIN::m_progressReporter
private

optional; may be nullptr

Definition at line 230 of file sch_eagle_plugin.h.

Referenced by checkpoint(), Load(), loadSchematic(), and SetProgressReporter().

◆ m_properties

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

Library plugin properties.

Definition at line 228 of file sch_eagle_plugin.h.

Referenced by Load(), loadInstance(), and loadLibrary().

◆ m_reporter

REPORTER* SCH_EAGLE_PLUGIN::m_reporter
private

Reporter for warnings/errors.

Map references to missing symbol units data

Definition at line 212 of file sch_eagle_plugin.h.

Referenced by loadInstance(), SCH_EAGLE_PLUGIN(), and SetReporter().

◆ m_rootSheet

SCH_SHEET* SCH_EAGLE_PLUGIN::m_rootSheet
private

The root sheet of the schematic being loaded.

Definition at line 217 of file sch_eagle_plugin.h.

Referenced by Load(), loadInstance(), loadSchematic(), and SCH_EAGLE_PLUGIN().

◆ m_schematic

SCHEMATIC* SCH_EAGLE_PLUGIN::m_schematic
private

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

Definition at line 222 of file sch_eagle_plugin.h.

Referenced by Load(), loadInstance(), loadSchematic(), and SCH_EAGLE_PLUGIN().

◆ m_segments

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

Nets as defined in the <nets> sections of an Eagle schematic file.

Definition at line 255 of file sch_eagle_plugin.h.

Referenced by adjustNetLabels(), and loadSegments().

◆ m_totalCount

unsigned SCH_EAGLE_PLUGIN::m_totalCount
private

for progress reporting

Definition at line 233 of file sch_eagle_plugin.h.

Referenced by checkpoint(), and loadSchematic().

◆ m_version

wxString SCH_EAGLE_PLUGIN::m_version
private

Eagle file version.

Definition at line 219 of file sch_eagle_plugin.h.

Referenced by Load().

◆ m_wireIntersections

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

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

Definition at line 242 of file sch_eagle_plugin.h.

Referenced by adjustNetLabels(), and loadSegments().


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