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 STRING_UTF8_MAP *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 STRING_UTF8_MAP *aProperties=nullptr)
 
virtual void Save (const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const STRING_UTF8_MAP *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 STRING_UTF8_MAP *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 STRING_UTF8_MAP *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 STRING_UTF8_MAP *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 STRING_UTF8_MAP *aProperties=nullptr)
 Write aSymbol to an existing library located at aLibraryPath. More...
 
virtual void DeleteSymbol (const wxString &aLibraryPath, const wxString &aSymbolName, const STRING_UTF8_MAP *aProperties=nullptr)
 Delete the entire LIB_SYMBOL associated with aAliasName from the library aLibraryPath. More...
 
virtual void CreateSymbolLib (const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
 Create a new empty symbol library at aLibraryPath. More...
 
virtual bool DeleteSymbolLib (const wxString &aLibraryPath, const STRING_UTF8_MAP *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 (STRING_UTF8_MAP *aListToAppendTo) const
 Append supported SCH_PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 
virtual bool SupportsSubLibraries () const
 
virtual void GetSubLibraryNames (std::vector< wxString > &aNames)
 Retrieves a list of sub-libraries in this library. More...
 
virtual void GetAvailableSymbolFields (std::vector< wxString > &aNames)
 Retrieves a list of (custom) field names that are present on symbols in this library. More...
 
virtual void GetDefaultSymbolFields (std::vector< wxString > &aNames)
 Retrieves a list of (custom) field names that should be shown by default for this library in the symbol chooser. More...
 
virtual const wxString & GetError () const
 Return an error string to the caller. More...
 
virtual void SetLibTable (SYMBOL_LIB_TABLE *aTable)
 Some library plugins need to have access to their parent library table. 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 VECTOR2I &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 VECTOR2I &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
 
SCH_SHEETgetCurrentSheet ()
 
SCH_SCREENgetCurrentScreen ()
 

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_SHEET_PATH m_sheetPath
 The current sheet path 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< STRING_UTF8_MAPm_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< VECTOR2I, 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 367 of file sch_eagle_plugin.cpp.

367 :
368 m_progressReporter( nullptr ),
369 m_doneCount( 0 ),
371 m_totalCount( 0 )
372{
373 m_rootSheet = nullptr;
374 m_schematic = nullptr;
375
377}
SCH_SHEET * m_rootSheet
The root sheet of the schematic being loaded.
unsigned m_totalCount
for progress reporting
REPORTER * m_reporter
Reporter for warnings/errors.
unsigned m_lastProgressCount
SCHEMATIC * m_schematic
Passed to Load(), the schematic object being loaded.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
static REPORTER & GetInstance()
Definition: reporter.cpp:177

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

◆ ~SCH_EAGLE_PLUGIN()

SCH_EAGLE_PLUGIN::~SCH_EAGLE_PLUGIN ( )

Definition at line 380 of file sch_eagle_plugin.cpp.

381{
382}

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

2414{
2415 // Add bus entry symbols
2416 // TODO: Cleanup this function and break into pieces
2417
2418 // for each wire segment, compare each end with all busses.
2419 // If the wire end is found to end on a bus segment, place a bus entry symbol.
2420
2421 std::vector<SCH_LINE*> buses;
2422 std::vector<SCH_LINE*> wires;
2423
2424 SCH_SCREEN* screen = getCurrentScreen();
2425
2426 wxCHECK( screen, /* void */ );
2427
2428 for( SCH_ITEM* ii : screen->Items().OfType( SCH_LINE_T ) )
2429 {
2430 SCH_LINE* line = static_cast<SCH_LINE*>( ii );
2431
2432 if( line->IsBus() )
2433 buses.push_back( line );
2434 else if( line->IsWire() )
2435 wires.push_back( line );
2436 }
2437
2438 for( SCH_LINE* wire : wires )
2439 {
2440 VECTOR2I wireStart = wire->GetStartPoint();
2441 VECTOR2I wireEnd = wire->GetEndPoint();
2442
2443 for( SCH_LINE* bus : buses )
2444 {
2445 VECTOR2I busStart = bus->GetStartPoint();
2446 VECTOR2I busEnd = bus->GetEndPoint();
2447
2448 auto entrySize =
2449 []( int signX, int signY ) -> VECTOR2I
2450 {
2453 };
2454
2455 auto testBusHit =
2456 [&]( const VECTOR2I& aPt ) -> bool
2457 {
2458 return TestSegmentHit( aPt, busStart, busEnd, 0 );
2459 };
2460
2461 if( wireStart.y == wireEnd.y && busStart.x == busEnd.x )
2462 {
2463 // Horizontal wire and vertical bus
2464
2465 if( testBusHit( wireStart ) )
2466 {
2467 // Wire start is on the vertical bus
2468
2469 if( wireEnd.x < busStart.x )
2470 {
2471 /* the end of the wire is to the left of the bus
2472 * ⎥⎢
2473 * ——————⎥⎢
2474 * ⎥⎢
2475 */
2476 VECTOR2I p = wireStart + entrySize( -1, 0 );
2477
2478 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2479 {
2480 /* there is room above the wire for the bus entry
2481 * ⎥⎢
2482 * _____/⎥⎢
2483 * ⎥⎢
2484 */
2485 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2486 busEntry->SetFlags( IS_NEW );
2487 screen->Append( busEntry );
2488 moveLabels( wire, p );
2489 wire->SetStartPoint( p );
2490 }
2491 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2492 {
2493 /* there is room below the wire for the bus entry
2494 * _____ ⎥⎢
2495 * \⎥⎢
2496 * ⎥⎢
2497 */
2498 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2499 busEntry->SetFlags( IS_NEW );
2500 screen->Append( busEntry );
2501 moveLabels( wire, p );
2502 wire->SetStartPoint( p );
2503 }
2504 else
2505 {
2506 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2507 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2508 screen->Append( marker );
2509 }
2510 }
2511 else
2512 {
2513 /* the wire end is to the right of the bus
2514 * ⎥⎢
2515 * ⎥⎢——————
2516 * ⎥⎢
2517 */
2518 VECTOR2I p = wireStart + entrySize( 1, 0 );
2519
2520 if( testBusHit( wireStart + entrySize( 0, -1 ) ) )
2521 {
2522 /* There is room above the wire for the bus entry
2523 * ⎥⎢
2524 * ⎥⎢\_____
2525 * ⎥⎢
2526 */
2527 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p , 4 );
2528 busEntry->SetFlags( IS_NEW );
2529 screen->Append( busEntry );
2530 moveLabels( wire, p );
2531 wire->SetStartPoint( p );
2532 }
2533 else if( testBusHit( wireStart + entrySize( 0, 1 ) ) )
2534 {
2535 /* There is room below the wire for the bus entry
2536 * ⎥⎢ _____
2537 * ⎥⎢/
2538 * ⎥⎢
2539 */
2540 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2541 busEntry->SetFlags( IS_NEW );
2542 screen->Append( busEntry );
2543 moveLabels( wire, p );
2544 wire->SetStartPoint( p );
2545 }
2546 else
2547 {
2548 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2549 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2550 screen->Append( marker );
2551 }
2552 }
2553
2554 break;
2555 }
2556 else if( testBusHit( wireEnd ) )
2557 {
2558 // Wire end is on the vertical bus
2559
2560 if( wireStart.x < busStart.x )
2561 {
2562 /* start of the wire is to the left of the bus
2563 * ⎥⎢
2564 * ——————⎥⎢
2565 * ⎥⎢
2566 */
2567 VECTOR2I p = wireEnd + entrySize( -1, 0 );
2568
2569 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2570 {
2571 /* there is room above the wire for the bus entry
2572 * ⎥⎢
2573 * _____/⎥⎢
2574 * ⎥⎢
2575 */
2576 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2577 busEntry->SetFlags( IS_NEW );
2578 screen->Append( busEntry );
2579 moveLabels( wire, p );
2580 wire->SetEndPoint( p );
2581 }
2582 else if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2583 {
2584 /* there is room below the wire for the bus entry
2585 * _____ ⎥⎢
2586 * \⎥⎢
2587 * ⎥⎢
2588 */
2589 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2590 busEntry->SetFlags( IS_NEW );
2591 screen->Append( busEntry );
2592 moveLabels( wire, wireEnd + entrySize( -1, 0 ) );
2593 wire->SetEndPoint( wireEnd + entrySize( -1, 0 ) );
2594 }
2595 else
2596 {
2597 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2598 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2599 screen->Append( marker );
2600 }
2601 }
2602 else
2603 {
2604 /* the start of the wire is to the right of the bus
2605 * ⎥⎢
2606 * ⎥⎢——————
2607 * ⎥⎢
2608 */
2609 VECTOR2I p = wireEnd + entrySize( 1, 0 );
2610
2611 if( testBusHit( wireEnd + entrySize( 0, -1 ) ) )
2612 {
2613 /* There is room above the wire for the bus entry
2614 * ⎥⎢
2615 * ⎥⎢\_____
2616 * ⎥⎢
2617 */
2618 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2619 busEntry->SetFlags( IS_NEW );
2620 screen->Append( busEntry );
2621 moveLabels( wire, p );
2622 wire->SetEndPoint( p );
2623 }
2624 else if( testBusHit( wireEnd + entrySize( 0, 1 ) ) )
2625 {
2626 /* There is room below the wire for the bus entry
2627 * ⎥⎢ _____
2628 * ⎥⎢/
2629 * ⎥⎢
2630 */
2631 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2632 busEntry->SetFlags( IS_NEW );
2633 screen->Append( busEntry );
2634 moveLabels( wire, p );
2635 wire->SetEndPoint( p );
2636 }
2637 else
2638 {
2639 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2640 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2641 screen->Append( marker );
2642 }
2643 }
2644
2645 break;
2646 }
2647 }
2648 else if( wireStart.x == wireEnd.x && busStart.y == busEnd.y )
2649 {
2650 // Vertical wire and horizontal bus
2651
2652 if( testBusHit( wireStart ) )
2653 {
2654 // Wire start is on the bus
2655
2656 if( wireEnd.y < busStart.y )
2657 {
2658 /* the end of the wire is above the bus
2659 * |
2660 * |
2661 * |
2662 * =======
2663 */
2664 VECTOR2I p = wireStart + entrySize( 0, -1 );
2665
2666 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
2667 {
2668 /* there is room to the left of the wire for the bus entry
2669 * |
2670 * |
2671 * /
2672 * =======
2673 */
2674 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2675 busEntry->SetFlags( IS_NEW );
2676 screen->Append( busEntry );
2677 moveLabels( wire, p );
2678 wire->SetStartPoint( p );
2679 }
2680 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
2681 {
2682 /* there is room to the right of the wire for the bus entry
2683 * |
2684 * |
2685 * \
2686 * =======
2687 */
2688 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2689 busEntry->SetFlags( IS_NEW );
2690 screen->Append( busEntry );
2691 moveLabels( wire, p );
2692 wire->SetStartPoint( p );
2693 }
2694 else
2695 {
2696 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2697 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2698 screen->Append( marker );
2699 }
2700 }
2701 else
2702 {
2703 /* wire end is below the bus
2704 * =======
2705 * |
2706 * |
2707 * |
2708 */
2709 VECTOR2I p = wireStart + entrySize( 0, 1 );
2710
2711 if( testBusHit( wireStart + entrySize( -1, 0 ) ) )
2712 {
2713 /* there is room to the left of the wire for the bus entry
2714 * =======
2715 * \
2716 * |
2717 * |
2718 */
2719 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2720 busEntry->SetFlags( IS_NEW );
2721 screen->Append( busEntry );
2722 moveLabels( wire, p );
2723 wire->SetStartPoint( p );
2724 }
2725 else if( testBusHit( wireStart + entrySize( 1, 0 ) ) )
2726 {
2727 /* there is room to the right of the wire for the bus entry
2728 * =======
2729 * /
2730 * |
2731 * |
2732 */
2733 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2734 busEntry->SetFlags( IS_NEW );
2735 screen->Append( busEntry );
2736 moveLabels( wire, p );
2737 wire->SetStartPoint( p );
2738 }
2739 else
2740 {
2741 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2742 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireStart );
2743 screen->Append( marker );
2744 }
2745 }
2746
2747 break;
2748 }
2749 else if( testBusHit( wireEnd ) )
2750 {
2751 // Wire end is on the bus
2752
2753 if( wireStart.y < busStart.y )
2754 {
2755 /* the start of the wire is above the bus
2756 * |
2757 * |
2758 * |
2759 * =======
2760 */
2761 VECTOR2I p = wireEnd + entrySize( 0, -1 );
2762
2763 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
2764 {
2765 /* there is room to the left of the wire for the bus entry
2766 * |
2767 * |
2768 * /
2769 * =======
2770 */
2771 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2772 busEntry->SetFlags( IS_NEW );
2773 screen->Append( busEntry );
2774 moveLabels( wire, p );
2775 wire->SetEndPoint( p );
2776 }
2777 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
2778 {
2779 /* there is room to the right of the wire for the bus entry
2780 * |
2781 * |
2782 * \
2783 * =======
2784 */
2785 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2786 busEntry->SetFlags( IS_NEW );
2787 screen->Append( busEntry );
2788 moveLabels( wire, p );
2789 wire->SetEndPoint( p );
2790 }
2791 else
2792 {
2793 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2794 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2795 screen->Append( marker );
2796 }
2797 }
2798 else
2799 {
2800 /* wire start is below the bus
2801 * =======
2802 * |
2803 * |
2804 * |
2805 */
2806 VECTOR2I p = wireEnd + entrySize( 0, 1 );
2807
2808 if( testBusHit( wireEnd + entrySize( -1, 0 ) ) )
2809 {
2810 /* there is room to the left of the wire for the bus entry
2811 * =======
2812 * \
2813 * |
2814 * |
2815 */
2816 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2817 busEntry->SetFlags( IS_NEW );
2818 screen->Append( busEntry );
2819 moveLabels( wire, p );
2820 wire->SetEndPoint( p );
2821 }
2822 else if( testBusHit( wireEnd + entrySize( 1, 0 ) ) )
2823 {
2824 /* there is room to the right of the wire for the bus entry
2825 * =======
2826 * /
2827 * |
2828 * |
2829 */
2830 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2831 busEntry->SetFlags( IS_NEW );
2832 screen->Append( busEntry );
2833 moveLabels( wire, p );
2834 wire->SetEndPoint( p );
2835 }
2836 else
2837 {
2838 auto ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_NEEDED );
2839 SCH_MARKER* marker = new SCH_MARKER( ercItem, wireEnd );
2840 screen->Append( marker );
2841 }
2842 }
2843
2844 break;
2845 }
2846 }
2847 else
2848 {
2849 // Wire isn't horizontal or vertical
2850
2851 if( testBusHit( wireStart ) )
2852 {
2853 VECTOR2I wirevector = wireStart - wireEnd;
2854
2855 if( wirevector.x > 0 )
2856 {
2857 if( wirevector.y > 0 )
2858 {
2859 VECTOR2I p = wireStart + entrySize( -1, -1 );
2860 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2861 busEntry->SetFlags( IS_NEW );
2862 screen->Append( busEntry );
2863
2864 moveLabels( wire, p );
2865 wire->SetStartPoint( p );
2866 }
2867 else
2868 {
2869 VECTOR2I p = wireStart + entrySize( -1, 1 );
2870 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2871 busEntry->SetFlags( IS_NEW );
2872 screen->Append( busEntry );
2873
2874 moveLabels( wire, p );
2875 wire->SetStartPoint( p );
2876 }
2877 }
2878 else
2879 {
2880 if( wirevector.y > 0 )
2881 {
2882 VECTOR2I p = wireStart + entrySize( 1, -1 );
2883 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2884 busEntry->SetFlags( IS_NEW );
2885 screen->Append( busEntry );
2886
2887 moveLabels( wire, p );
2888 wire->SetStartPoint( p );
2889 }
2890 else
2891 {
2892 VECTOR2I p = wireStart + entrySize( 1, 1 );
2893 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2894 busEntry->SetFlags( IS_NEW );
2895 screen->Append( busEntry );
2896
2897 moveLabels( wire, p );
2898 wire->SetStartPoint( p );
2899 }
2900 }
2901
2902 break;
2903 }
2904 else if( testBusHit( wireEnd ) )
2905 {
2906 VECTOR2I wirevector = wireStart - wireEnd;
2907
2908 if( wirevector.x > 0 )
2909 {
2910 if( wirevector.y > 0 )
2911 {
2912 VECTOR2I p = wireEnd + entrySize( 1, 1 );
2913 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 4 );
2914 busEntry->SetFlags( IS_NEW );
2915 screen->Append( busEntry );
2916
2917 moveLabels( wire, p );
2918 wire->SetEndPoint( p );
2919 }
2920 else
2921 {
2922 VECTOR2I p = wireEnd + entrySize( 1, -1 );
2923 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 3 );
2924 busEntry->SetFlags( IS_NEW );
2925 screen->Append( busEntry );
2926
2927 moveLabels( wire, p );
2928 wire->SetEndPoint( p );
2929 }
2930 }
2931 else
2932 {
2933 if( wirevector.y > 0 )
2934 {
2935 VECTOR2I p = wireEnd + entrySize( -1, 1 );
2936 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 1 );
2937 busEntry->SetFlags( IS_NEW );
2938 screen->Append( busEntry );
2939
2940 moveLabels( wire, p );
2941 wire->SetEndPoint( p );
2942 }
2943 else
2944 {
2945 VECTOR2I p = wireEnd + entrySize( -1, -1 );
2946 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( p, 2 );
2947 busEntry->SetFlags( IS_NEW );
2948 screen->Append( busEntry );
2949
2950 moveLabels( wire, p );
2951 wire->SetEndPoint( p );
2952 }
2953 }
2954
2955 break;
2956 }
2957 }
2958 }
2959 }
2960}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:227
Class for a wire to bus entry.
SCH_SCREEN * getCurrentScreen()
void moveLabels(SCH_LINE *aWire, const VECTOR2I &aNewEndPoint)
Move any labels on the wire to the new end point of the wire.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:925
bool IsBus() const
Return true if the line is a bus.
Definition: sch_line.cpp:931
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:141
#define DEFAULT_SCH_ENTRY_SIZE
The default text size in mils. (can be changed in preference menu)
#define IS_NEW
New item, just created.
@ ERCE_BUS_ENTRY_NEEDED
Importer failed to auto-place a bus entry.
Definition: erc_settings.h:79
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
@ SCH_LINE_T
Definition: typeinfo.h:146
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References SCH_SCREEN::Append(), ERC_ITEM::Create(), DEFAULT_SCH_ENTRY_SIZE, ERCE_BUS_ENTRY_NEEDED, getCurrentScreen(), IS_NEW, SCH_LINE::IsBus(), SCH_LINE::IsWire(), SCH_SCREEN::Items(), EDA_IU_SCALE::MilsToIU(), moveLabels(), EE_RTREE::OfType(), SCH_LINE_T, schIUScale, EDA_ITEM::SetFlags(), TestSegmentHit(), VECTOR2< T >::x, and VECTOR2< T >::y.

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

2999{
3000 wxCHECK( aSymbol->GetLibSymbolRef(), /*void*/ );
3001
3002 // Normally power parts also have power input pins,
3003 // but they already force net names on the attached wires
3004 if( aSymbol->GetLibSymbolRef()->IsPower() )
3005 return;
3006
3007 int unit = aSymbol->GetUnit();
3008 const wxString reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
3009 std::vector<LIB_PIN*> pins;
3010 aSymbol->GetLibSymbolRef()->GetPins( pins );
3011 std::set<int> missingUnits;
3012
3013 // Search all units for pins creating implicit connections
3014 for( const LIB_PIN* pin : pins )
3015 {
3016 if( pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3017 {
3018 bool pinInUnit = !unit || pin->GetUnit() == unit; // pin belongs to the tested unit
3019
3020 // Create a global net label only if there are no other wires/pins attached
3021 if( pinInUnit )
3022 {
3023 if( !checkConnections( aSymbol, pin ) )
3024 {
3025 // Create a net label to force the net name on the pin
3026 SCH_GLOBALLABEL* netLabel = new SCH_GLOBALLABEL;
3027 netLabel->SetPosition( aSymbol->GetPinPhysicalPosition( pin ) );
3028 netLabel->SetText( extractNetName( pin->GetName() ) );
3029 netLabel->SetTextSize( wxSize( schIUScale.MilsToIU( 40 ),
3030 schIUScale.MilsToIU( 40 ) ) );
3031
3032 switch( pin->GetOrientation() )
3033 {
3034 case PIN_LEFT: netLabel->SetTextSpinStyle( TEXT_SPIN_STYLE::RIGHT ); break;
3035 case PIN_RIGHT: netLabel->SetTextSpinStyle( TEXT_SPIN_STYLE::LEFT ); break;
3036 case PIN_UP: netLabel->SetTextSpinStyle( TEXT_SPIN_STYLE::UP ); break;
3037 case PIN_DOWN: netLabel->SetTextSpinStyle( TEXT_SPIN_STYLE::BOTTOM ); break;
3038 }
3039
3040 aScreen->Append( netLabel );
3041 }
3042 }
3043 else if( aUpdateSet )
3044 {
3045 // Found a pin creating implicit connection information in another unit.
3046 // Such units will be instantiated if they do not appear in another sheet and
3047 // processed later.
3048 wxASSERT( pin->GetUnit() );
3049 missingUnits.insert( pin->GetUnit() );
3050 }
3051 }
3052 }
3053
3054 if( aUpdateSet && aSymbol->GetLibSymbolRef()->GetUnitCount() > 1 )
3055 {
3056 auto cmpIt = m_missingCmps.find( reference );
3057
3058 // The first unit found has always already been processed.
3059 if( cmpIt == m_missingCmps.end() )
3060 {
3061 EAGLE_MISSING_CMP& entry = m_missingCmps[reference];
3062 entry.cmp = aSymbol;
3063 entry.units.emplace( unit, false );
3064 }
3065 else
3066 {
3067 // Set the flag indicating this unit has been processed.
3068 cmpIt->second.units[unit] = false;
3069 }
3070
3071 if( !missingUnits.empty() ) // Save the units that need later processing
3072 {
3073 EAGLE_MISSING_CMP& entry = m_missingCmps[reference];
3074 entry.cmp = aSymbol;
3075
3076 // Add units that haven't already been processed.
3077 for( int i : missingUnits )
3078 {
3079 if( entry.units.find( i ) != entry.units.end() )
3080 entry.units.emplace( i, true );
3081 }
3082 }
3083 }
3084}
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
std::map< wxString, EAGLE_MISSING_CMP > m_missingCmps
bool checkConnections(const SCH_SYMBOL *aSymbol, const LIB_PIN *aPin) const
void SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle) override
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_label.cpp:1303
int GetUnit() const
Definition: sch_symbol.h:227
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:788
VECTOR2I GetPinPhysicalPosition(const LIB_PIN *Pin) const
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:191
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_text.h:204
@ PIN_LEFT
Definition: lib_pin.h:46
@ PIN_RIGHT
Definition: lib_pin.h:45
@ PIN_UP
Definition: lib_pin.h:47
@ PIN_DOWN
Definition: lib_pin.h:48
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
static wxString extractNetName(const wxString &aPinName)
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".

References SCH_SCREEN::Append(), TEXT_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(), TEXT_SPIN_STYLE::LEFT, m_missingCmps, EDA_IU_SCALE::MilsToIU(), pin, PIN_DOWN, PIN_LEFT, PIN_RIGHT, PIN_UP, PT_POWER_IN, REFERENCE_FIELD, TEXT_SPIN_STYLE::RIGHT, schIUScale, SCH_TEXT::SetPosition(), EDA_TEXT::SetText(), EDA_TEXT::SetTextSize(), SCH_GLOBALLABEL::SetTextSpinStyle(), SCH_EAGLE_PLUGIN::EAGLE_MISSING_CMP::units, and TEXT_SPIN_STYLE::UP.

Referenced by loadSchematic(), and loadSheet().

◆ adjustNetLabels()

void SCH_EAGLE_PLUGIN::adjustNetLabels ( )
private

Definition at line 2301 of file sch_eagle_plugin.cpp.

2302{
2303 // Eagle supports detached labels, so a label does not need to be placed on a wire
2304 // to be associated with it. KiCad needs to move them, so the labels actually touch the
2305 // corresponding wires.
2306
2307 // Sort the intersection points to speed up the search process
2308 std::sort( m_wireIntersections.begin(), m_wireIntersections.end() );
2309
2310 auto onIntersection =
2311 [&]( const VECTOR2I& aPos )
2312 {
2313 return std::binary_search( m_wireIntersections.begin(),
2314 m_wireIntersections.end(), aPos );
2315 };
2316
2317 for( SEG_DESC& segDesc : m_segments )
2318 {
2319 for( SCH_TEXT* label : segDesc.labels )
2320 {
2321 VECTOR2I labelPos( label->GetPosition() );
2322 const SEG* segAttached = segDesc.LabelAttached( label );
2323
2324 if( segAttached && !onIntersection( labelPos ) )
2325 continue; // label is placed correctly
2326
2327 // Move the label to the nearest wire
2328 if( !segAttached )
2329 {
2330 std::tie( labelPos, segAttached ) = findNearestLinePoint( label->GetPosition(),
2331 segDesc.segs );
2332
2333 if( !segAttached ) // we cannot do anything
2334 continue;
2335 }
2336
2337 // Create a vector pointing in the direction of the wire, 50 mils long
2338 VECTOR2I wireDirection( segAttached->B - segAttached->A );
2339 wireDirection = wireDirection.Resize( schIUScale.MilsToIU( 50 ) );
2340 const VECTOR2I origPos( labelPos );
2341
2342 // Flags determining the search direction
2343 bool checkPositive = true, checkNegative = true, move = false;
2344 int trial = 0;
2345
2346 // Be sure the label is not placed on a wire intersection
2347 while( ( !move || onIntersection( labelPos ) ) && ( checkPositive || checkNegative ) )
2348 {
2349 move = false;
2350
2351 // Move along the attached wire to find the new label position
2352 if( trial % 2 == 1 )
2353 {
2354 labelPos = VECTOR2I( origPos + wireDirection * trial / 2 );
2355 move = checkPositive = segAttached->Contains( labelPos );
2356 }
2357 else
2358 {
2359 labelPos = VECTOR2I( origPos - wireDirection * trial / 2 );
2360 move = checkNegative = segAttached->Contains( labelPos );
2361 }
2362
2363 ++trial;
2364 }
2365
2366 if( move )
2367 label->SetPosition( VECTOR2I( labelPos ) );
2368 }
2369 }
2370
2371 m_segments.clear();
2372 m_wireIntersections.clear();
2373}
std::vector< SEG_DESC > m_segments
Nets as defined in the <nets> sections of an Eagle schematic file.
std::vector< VECTOR2I > m_wireIntersections
Wires and labels of a single connection (segment in Eagle nomenclature)
std::pair< VECTOR2I, const SEG * > findNearestLinePoint(const VECTOR2I &aPoint, const std::vector< SEG > &aLines) const
VECTOR2I GetPosition() const override
Definition: sch_text.h:203
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
bool Contains(const SEG &aSeg) const
Definition: seg.h:307

References SEG::A, SEG::B, SEG::Contains(), findNearestLinePoint(), SCH_TEXT::GetPosition(), m_segments, m_wireIntersections, EDA_IU_SCALE::MilsToIU(), move, VECTOR2< T >::Resize(), schIUScale, 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 2979 of file sch_eagle_plugin.cpp.

2980{
2981 wxCHECK( aSymbol && aPin, false );
2982
2983 VECTOR2I pinPosition = aSymbol->GetPinPhysicalPosition( aPin );
2984 auto pointIt = m_connPoints.find( pinPosition );
2985
2986 if( pointIt == m_connPoints.end() )
2987 return false;
2988
2989 const auto& items = pointIt->second;
2990
2991 wxCHECK( items.find( aPin ) != items.end(), false );
2992
2993 return items.size() > 1;
2994}
std::map< VECTOR2I, 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 2376 of file sch_eagle_plugin.cpp.

2377{
2378 // Open file and check first line
2379 wxTextFile tempFile;
2380
2381 tempFile.Open( aFileName );
2382 wxString firstline;
2383
2384 // read the first line
2385 firstline = tempFile.GetFirstLine();
2386 wxString secondline = tempFile.GetNextLine();
2387 wxString thirdline = tempFile.GetNextLine();
2388 tempFile.Close();
2389
2390 return firstline.StartsWith( wxT( "<?xml" ) )
2391 && secondline.StartsWith( wxT( "<!DOCTYPE eagle SYSTEM" ) )
2392 && thirdline.StartsWith( wxT( "<eagle version" ) );
2393}

◆ checkpoint()

void SCH_EAGLE_PLUGIN::checkpoint ( )
private

Definition at line 409 of file sch_eagle_plugin.cpp.

410{
411 const unsigned PROGRESS_DELTA = 5;
412
414 {
415 if( ++m_doneCount > m_lastProgressCount + PROGRESS_DELTA )
416 {
418 / std::max( 1U, m_totalCount ) );
419
421 THROW_IO_ERROR( ( "Open canceled by user." ) );
422
424 }
425 }
426}
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

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

571{
572 // Map all children into a readable dictionary
573 NODE_MAP schematicChildren = MapChildren( aSchematicNode );
574
575 // Loop through all the sheets
576 wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, wxT( "sheets" ) );
577
578 while( sheetNode )
579 {
580 NODE_MAP sheetChildren = MapChildren( sheetNode );
581
582 // Loop through all nets
583 // From the DTD: "Net is an electrical connection in a schematic."
584 wxXmlNode* netNode = getChildrenNodes( sheetChildren, wxT( "nets" ) );
585
586 while( netNode )
587 {
588 wxString netName = netNode->GetAttribute( wxT( "name" ) );
589
590 if( m_netCounts.count( netName ) )
591 m_netCounts[netName] = m_netCounts[netName] + 1;
592 else
593 m_netCounts[netName] = 1;
594
595 // Get next net
596 netNode = netNode->GetNext();
597 }
598
599 sheetNode = sheetNode->GetNext();
600 }
601}
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.
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:49

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

Referenced by loadSchematic().

◆ CreateSymbolLib()

void SCH_PLUGIN::CreateSymbolLib ( const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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_SEXPR_PLUGIN, and SCH_LEGACY_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().

Referenced by SYMBOL_LIB_TABLE::CreateSymbolLib(), SYMBOL_EDIT_FRAME::ExportSymbol(), SCH_ALTIUM_PLUGIN::Load(), CADSTAR_SCH_ARCHIVE_PLUGIN::Load(), and Load().

◆ DeleteSymbol()

void SCH_PLUGIN::DeleteSymbol ( const wxString &  aLibraryPath,
const wxString &  aSymbolName,
const STRING_UTF8_MAP 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_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by SYMBOL_LIB_TABLE::DeleteSymbol(), and SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer().

◆ DeleteSymbolLib()

bool SCH_PLUGIN::DeleteSymbolLib ( const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by SYMBOL_LIB_TABLE::DeleteSymbolLib().

◆ EnumerateSymbolLib() [1/2]

void SCH_PLUGIN::EnumerateSymbolLib ( std::vector< LIB_SYMBOL * > &  aSymbolList,
const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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_DATABASE_PLUGIN, SCH_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

◆ EnumerateSymbolLib() [2/2]

void SCH_PLUGIN::EnumerateSymbolLib ( wxArrayString &  aSymbolNameList,
const wxString &  aLibraryPath,
const STRING_UTF8_MAP 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_DATABASE_PLUGIN, SCH_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by PANEL_SYM_LIB_TABLE::convertLibrary(), SYMBOL_LIB_TABLE::EnumerateSymbolLib(), SYMBOL_EDIT_FRAME::ImportSymbol(), SYMBOL_LIB_TABLE::LoadSymbolLib(), and SYMBOL_LIB_TABLE_ROW::Refresh().

◆ findNearestLinePoint()

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

Definition at line 1262 of file sch_eagle_plugin.cpp.

1264{
1265 VECTOR2I nearestPoint;
1266 const SEG* nearestLine = nullptr;
1267
1268 float d, mindistance = std::numeric_limits<float>::max();
1269
1270 // Find the nearest start, middle or end of a line from the list of lines.
1271 for( const SEG& line : aLines )
1272 {
1273 VECTOR2I testpoint = line.A;
1274 d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1275
1276 if( d < mindistance )
1277 {
1278 mindistance = d;
1279 nearestPoint = testpoint;
1280 nearestLine = &line;
1281 }
1282
1283 testpoint = line.Center();
1284 d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1285
1286 if( d < mindistance )
1287 {
1288 mindistance = d;
1289 nearestPoint = testpoint;
1290 nearestLine = &line;
1291 }
1292
1293 testpoint = line.B;
1294 d = sqrt( abs( ( ( aPoint.x - testpoint.x ) ^ 2 ) + ( ( aPoint.y - testpoint.y ) ^ 2 ) ) );
1295
1296 if( d < mindistance )
1297 {
1298 mindistance = d;
1299 nearestPoint = testpoint;
1300 nearestLine = &line;
1301 }
1302 }
1303
1304 return std::make_pair( nearestPoint, nearestLine );
1305}
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401

References std::abs(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by adjustNetLabels().

◆ GetAvailableSymbolFields()

virtual void SCH_PLUGIN::GetAvailableSymbolFields ( std::vector< wxString > &  aNames)
inlinevirtualinherited

Retrieves a list of (custom) field names that are present on symbols in this library.

The plugin is responsible for guaranteeing that this list contains the set of unique custom field names present on any symbols contained in the library.

The required KiCad fields are not included in this list.

Parameters
aNameswill be filled with any custom fields present in this library.

Reimplemented in SCH_DATABASE_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 474 of file sch_io_mgr.h.

474{}

Referenced by SYMBOL_LIB_TABLE_ROW::GetAvailableSymbolFields(), and SCH_PLUGIN::GetDefaultSymbolFields().

◆ getCurrentScreen()

SCH_SCREEN * SCH_EAGLE_PLUGIN::getCurrentScreen ( )
private

Definition at line 138 of file sch_eagle_plugin.cpp.

139{
140 SCH_SHEET* currentSheet = m_sheetPath.Last();
141 wxCHECK( currentSheet, nullptr );
142 return currentSheet->GetScreen();
143}
SCH_SHEET_PATH m_sheetPath
The current sheet path of the schematic being loaded.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:104

References SCH_SHEET::GetScreen(), SCH_SHEET_PATH::Last(), and m_sheetPath.

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

◆ getCurrentSheet()

SCH_SHEET * SCH_EAGLE_PLUGIN::getCurrentSheet ( )
private

Definition at line 132 of file sch_eagle_plugin.cpp.

133{
134 return m_sheetPath.Last();
135}

References SCH_SHEET_PATH::Last(), and m_sheetPath.

Referenced by loadSheet().

◆ GetDefaultSymbolFields()

virtual void SCH_PLUGIN::GetDefaultSymbolFields ( std::vector< wxString > &  aNames)
inlinevirtualinherited

Retrieves a list of (custom) field names that should be shown by default for this library in the symbol chooser.

This list should be a subset of the result returned by GetAvailableSymbolFields().

The preference for which fields to hide and show for a given library is stored on a per-library basis in a user's preferences (or in the project local settings for a project- local library). The set of fields returned by GetDefaultSymbolFields() will be used if this preference is missing.

Parameters
aNameswill be filled with the custom field names that should be shown by default

Reimplemented in SCH_DATABASE_PLUGIN, and SCH_SEXPR_PLUGIN.

Definition at line 488 of file sch_io_mgr.h.

489 {
490 return GetAvailableSymbolFields( aNames );
491 }
virtual void GetAvailableSymbolFields(std::vector< wxString > &aNames)
Retrieves a list of (custom) field names that are present on symbols in this library.
Definition: sch_io_mgr.h:474

References SCH_PLUGIN::GetAvailableSymbolFields().

Referenced by SYMBOL_LIB_TABLE_ROW::GetDefaultSymbolFields().

◆ 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_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by KI_TEST::SCHEMATIC_TEST_FIXTURE::LoadSchematic(), SCH_EDIT_FRAME::LoadSheetFromFile(), and SCH_EDIT_FRAME::OpenProjectFiles().

◆ GetFileExtension()

const wxString SCH_EAGLE_PLUGIN::GetFileExtension ( ) const
overridevirtual

Return the file extension for the SCH_PLUGIN.

Implements SCH_PLUGIN.

Definition at line 391 of file sch_eagle_plugin.cpp.

392{
393 return wxT( "sch" );
394}

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

171{
173
174 return fn;
175}
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:126
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:76
const std::string KiCadSymbolLibFileExtension

References getLibName(), PROJECT::GetProjectPath(), KiCadSymbolLibFileExtension, m_schematic, and SCHEMATIC::Prj().

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

◆ getLibName()

wxString SCH_EAGLE_PLUGIN::getLibName ( )
private

Definition at line 146 of file sch_eagle_plugin.cpp.

147{
148 if( m_libName.IsEmpty() )
149 {
150 // Try to come up with a meaningful name
152
153 if( m_libName.IsEmpty() )
154 {
155 wxFileName fn( m_rootSheet->GetFileName() );
156 m_libName = fn.GetName();
157 }
158
159 if( m_libName.IsEmpty() )
160 m_libName = wxT( "noname" );
161
162 m_libName += wxT( "-eagle-import" );
164 }
165
166 return m_libName;
167}
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:190
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:132
wxString m_libName
Library name to save symbols.
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:300

References LIB_ID::FixIllegalChars(), SCH_SHEET::GetFileName(), PROJECT::GetProjectName(), m_libName, m_rootSheet, m_schematic, and SCHEMATIC::Prj().

Referenced by getLibFileName(), 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 397 of file sch_eagle_plugin.cpp.

398{
399 return wxT( "lbr" );
400}

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

404{
405 return 0;
406}

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

386{
387 return wxT( "EAGLE" );
388}

◆ GetSubLibraryNames()

virtual void SCH_PLUGIN::GetSubLibraryNames ( std::vector< wxString > &  aNames)
inlinevirtualinherited

Retrieves a list of sub-libraries in this library.

Some types of symbol library support sub-libraries, which are a single-level organizational hierarchy that is implementation-defined per plugin. Most of KiCad ignores sub-libraries and treats the hierarchy between library and symbol as flat, but the sub-libraries are used for sorting and grouping symbols in the symbol chooser.

Has no effect if SupportsSubLibraries() returns false.

Parameters
aNameswill be filled with a list of sub-libraries within this symbol library

Reimplemented in SCH_DATABASE_PLUGIN.

Definition at line 463 of file sch_io_mgr.h.

463{}

Referenced by SYMBOL_LIB_TABLE_ROW::GetSubLibraryNames().

◆ 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_DATABASE_PLUGIN, SCH_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by SYMBOL_LIB_TABLE::IsSymbolLibWritable(), and SYMBOL_LIB_TABLE::SaveSymbol().

◆ kiCadLayer()

SCH_LAYER_ID SCH_EAGLE_PLUGIN::kiCadLayer ( int  aEagleLayer)
private

Return the matching layer or return LAYER_NOTES.

Definition at line 229 of file sch_eagle_plugin.cpp.

230{
231 auto it = m_layerMap.find( aEagleLayer );
232 return it == m_layerMap.end() ? LAYER_NOTES : it->second;
233}
std::map< int, SCH_LAYER_ID > m_layerMap
@ LAYER_NOTES
Definition: layer_ids.h:358

References LAYER_NOTES, and m_layerMap.

Referenced by loadWire().

◆ Load()

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

431{
432 wxASSERT( !aFileName || aSchematic != nullptr );
433 LOCALE_IO toggle; // toggles on, then off, the C locale.
434
435 m_filename = aFileName;
436 m_schematic = aSchematic;
437
439 {
440 m_progressReporter->Report( wxString::Format( _( "Loading %s..." ), aFileName ) );
441
443 THROW_IO_ERROR( ( "Open canceled by user." ) );
444 }
445
446 // Load the document
447 wxXmlDocument xmlDocument;
448 wxFFileInputStream stream( m_filename.GetFullPath() );
449
450 if( !stream.IsOk() || !xmlDocument.Load( stream ) )
451 {
452 THROW_IO_ERROR( wxString::Format( _( "Unable to read file '%s'." ),
453 m_filename.GetFullPath() ) );
454 }
455
456 // Delete on exception, if I own m_rootSheet, according to aAppendToMe
457 unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
458
459 wxFileName newFilename( m_filename );
460 newFilename.SetExt( KiCadSchematicFileExtension );
461
462 if( aAppendToMe )
463 {
464 wxCHECK_MSG( aSchematic->IsValid(), nullptr,
465 wxT( "Can't append to a schematic with no root!" ) );
466
467 m_rootSheet = &aSchematic->Root();
468 }
469 else
470 {
471 m_rootSheet = new SCH_SHEET( aSchematic );
472 m_rootSheet->SetFileName( newFilename.GetFullPath() );
473 aSchematic->SetRoot( m_rootSheet );
474 }
475
476 if( !m_rootSheet->GetScreen() )
477 {
478 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
479 screen->SetFileName( newFilename.GetFullPath() );
480 m_rootSheet->SetScreen( screen );
481
482 // Virtual root sheet UUID must be the same as the schematic file UUID.
483 const_cast<KIID&>( m_rootSheet->m_Uuid ) = screen->GetUuid();
484 }
485
486 SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
487
488 wxCHECK_MSG( libTable, nullptr, wxT( "Could not load symbol lib table." ) );
489
490 m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
491 m_properties = std::make_unique<STRING_UTF8_MAP>();
492 ( *m_properties )[SCH_LEGACY_PLUGIN::PropBuffering] = "";
493
496 if( !libTable->HasLibrary( getLibName() ) )
497 {
498 // Create a new empty symbol library.
499 m_pi->CreateSymbolLib( getLibFileName().GetFullPath() );
500 wxString libTableUri = wxT( "${KIPRJMOD}/" ) + getLibFileName().GetFullName();
501
502 // Add the new library to the project symbol library table.
503 libTable->InsertRow( new SYMBOL_LIB_TABLE_ROW( getLibName(), libTableUri,
504 wxT( "KiCad" ) ) );
505
506 // Save project symbol library table.
507 wxFileName fn( m_schematic->Prj().GetProjectPath(),
509
510 // So output formatter goes out of scope and closes the file before reloading.
511 {
512 FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
513 libTable->Format( &formatter, 0 );
514 }
515
516 // Reload the symbol library table.
518 m_schematic->Prj().SchSymbolLibTable();
519 }
520
521 // Retrieve the root as current node
522 wxXmlNode* currentNode = xmlDocument.GetRoot();
523
524 // If the attribute is found, store the Eagle version;
525 // otherwise, store the dummy "0.0" version.
526 m_version = currentNode->GetAttribute( wxT( "version" ), wxT( "0.0" ) );
527
528 // Map all children into a readable dictionary
529 NODE_MAP children = MapChildren( currentNode );
530
531 // Load drawing
532 loadDrawing( children["drawing"] );
533
534 m_pi->SaveLibrary( getLibFileName().GetFullPath() );
535
536 SCH_SCREENS allSheets( m_rootSheet );
537 allSheets.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
538
539 return m_rootSheet;
540}
const KIID m_Uuid
Definition: eda_item.h:494
Used for text file output.
Definition: richio.h:457
Definition: kiid.h:48
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
virtual void Report(const wxString &aMessage)=0
Display aMessage in the progress bar dialog.
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:294
@ ELEM_SYMBOL_LIB_TABLE
Definition: project.h:210
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:104
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:107
SCH_SHEET & Root() const
Definition: schematic.h:91
std::unique_ptr< STRING_UTF8_MAP > m_properties
Library plugin properties.
wxString m_version
Eagle file version.
void loadDrawing(wxXmlNode *aDrawingNode)
wxFileName getLibFileName()
Checks if there are other wires or pins at the position of the tested pin.
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
PI to create KiCad symbol library.
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
void set(SCH_PLUGIN *aPlugin)
Definition: sch_io_mgr.h:562
virtual void SaveLibrary(const wxString &aFileName, const STRING_UTF8_MAP *aProperties=nullptr)
Definition: sch_plugin.cpp:45
virtual void CreateSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Create a new empty symbol library at aLibraryPath.
Definition: sch_plugin.cpp:110
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:608
const KIID & GetUuid() const
Definition: sch_screen.h:499
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:106
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:306
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:162
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
static const wxString & GetSymbolLibTableFileName()
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
#define _(s)
const std::string KiCadSchematicFileExtension
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 _, SCH_PLUGIN::CreateSymbolLib(), PROJECT::ELEM_SYMBOL_LIB_TABLE, SYMBOL_LIB_TABLE::Format(), Format(), getLibFileName(), getLibName(), PROJECT::GetProjectPath(), SCH_SHEET::GetScreen(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName(), SCH_SCREEN::GetUuid(), 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, EDA_ITEM::m_Uuid, m_version, MapChildren(), SCHEMATIC::Prj(), SCH_LEGACY_PLUGIN::PropBuffering, PROGRESS_REPORTER::Report(), SCHEMATIC::Root(), SCH_PLUGIN::SaveLibrary(), SCH_PLUGIN::SCH_PLUGIN_RELEASER::set(), PROJECT::SetElem(), SCH_SCREEN::SetFileName(), SCH_SHEET::SetFileName(), SCHEMATIC::SetRoot(), SCH_SHEET::SetScreen(), THROW_IO_ERROR, and SCH_SCREENS::UpdateSymbolLinks().

◆ loadDrawing()

void SCH_EAGLE_PLUGIN::loadDrawing ( wxXmlNode *  aDrawingNode)
private

Definition at line 543 of file sch_eagle_plugin.cpp.

544{
545 // Map all children into a readable dictionary
546 NODE_MAP drawingChildren = MapChildren( aDrawingNode );
547
548 // Board nodes should not appear in .sch files
549 // wxXmlNode* board = drawingChildren["board"]
550
551 // wxXmlNode* grid = drawingChildren["grid"]
552
553 auto layers = drawingChildren["layers"];
554
555 if( layers )
556 loadLayerDefs( layers );
557
558 // wxXmlNode* library = drawingChildren["library"]
559
560 // wxXmlNode* settings = drawingChildren["settings"]
561
562 // Load schematic
563 auto schematic = drawingChildren["schematic"];
564
565 if( schematic )
566 loadSchematic( schematic );
567}
void loadSchematic(wxXmlNode *aSchematicNode)
void loadLayerDefs(wxXmlNode *aLayers)

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

2290{
2291 aField->SetTextPos( aText->GetPosition() );
2292 aField->SetTextSize( aText->GetTextSize() );
2293 aField->SetTextAngle( aText->GetTextAngle() );
2294 aField->SetBold( aText->IsBold() );
2295 aField->SetVertJustify( aText->GetVertJustify() );
2296 aField->SetHorizJustify( aText->GetHorizJustify() );
2297 aField->SetVisible( true );
2298}
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:120
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:371
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:248
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:142
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetBold(bool aBold)
Definition: eda_text.cpp:209
bool IsBold() const
Definition: eda_text.h:126
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:145
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
VECTOR2I GetTextSize() const
Definition: eda_text.h:189
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
VECTOR2I GetPosition() const override
Definition: lib_text.h:93

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< LIB_ITEM * > &  aLines 
)
private

Definition at line 2046 of file sch_eagle_plugin.cpp.

2047{
2048 EFRAME eframe( aFrameNode );
2049
2050 int xMin = eframe.x1.ToSchUnits();
2051 int xMax = eframe.x2.ToSchUnits();
2052 int yMin = eframe.y1.ToSchUnits();
2053 int yMax = eframe.y2.ToSchUnits();
2054
2055 if( xMin > xMax )
2056 std::swap( xMin, xMax );
2057
2058 if( yMin > yMax )
2059 std::swap( yMin, yMax );
2060
2061 LIB_SHAPE* lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2062 lines->AddPoint( VECTOR2I( xMin, yMin ) );
2063 lines->AddPoint( VECTOR2I( xMax, yMin ) );
2064 lines->AddPoint( VECTOR2I( xMax, yMax ) );
2065 lines->AddPoint( VECTOR2I( xMin, yMax ) );
2066 lines->AddPoint( VECTOR2I( xMin, yMin ) );
2067 aItems.push_back( lines );
2068
2069 if( !eframe.border_left )
2070 {
2071 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2072 lines->AddPoint( VECTOR2I( xMin + schIUScale.MilsToIU( 150 ),
2073 yMin + schIUScale.MilsToIU( 150 ) ) );
2074 lines->AddPoint( VECTOR2I( xMin + schIUScale.MilsToIU( 150 ),
2075 yMax - schIUScale.MilsToIU( 150 ) ) );
2076 aItems.push_back( lines );
2077
2078 int i;
2079 int height = yMax - yMin;
2080 int x1 = xMin;
2081 int x2 = x1 + schIUScale.MilsToIU( 150 );
2082 int legendPosX = xMin + schIUScale.MilsToIU( 75 );
2083 double rowSpacing = height / double( eframe.rows );
2084 double legendPosY = yMax - ( rowSpacing / 2 );
2085
2086 for( i = 1; i < eframe.rows; i++ )
2087 {
2088 int newY = KiROUND( yMin + ( rowSpacing * (double) i ) );
2089 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2090 lines->AddPoint( VECTOR2I( x1, newY ) );
2091 lines->AddPoint( VECTOR2I( x2, newY ) );
2092 aItems.push_back( lines );
2093 }
2094
2095 char legendChar = 'A';
2096
2097 for( i = 0; i < eframe.rows; i++ )
2098 {
2099 LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2100 legendText->SetPosition( VECTOR2I( legendPosX, KiROUND( legendPosY ) ) );
2101 legendText->SetText( wxString( legendChar ) );
2102 legendText->SetTextSize( wxSize( schIUScale.MilsToIU( 90 ),
2103 schIUScale.MilsToIU( 100 ) ) );
2104 aItems.push_back( legendText );
2105 legendChar++;
2106 legendPosY -= rowSpacing;
2107 }
2108 }
2109
2110 if( !eframe.border_right )
2111 {
2112 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2113 lines->AddPoint( VECTOR2I( xMax - schIUScale.MilsToIU( 150 ),
2114 yMin + schIUScale.MilsToIU( 150 ) ) );
2115 lines->AddPoint( VECTOR2I( xMax - schIUScale.MilsToIU( 150 ),
2116 yMax - schIUScale.MilsToIU( 150 ) ) );
2117 aItems.push_back( lines );
2118
2119 int i;
2120 int height = yMax - yMin;
2121 int x1 = xMax - schIUScale.MilsToIU( 150 );
2122 int x2 = xMax;
2123 int legendPosX = xMax - schIUScale.MilsToIU( 75 );
2124 double rowSpacing = height / double( eframe.rows );
2125 double legendPosY = yMax - ( rowSpacing / 2 );
2126
2127 for( i = 1; i < eframe.rows; i++ )
2128 {
2129 int newY = KiROUND( yMin + ( rowSpacing * (double) i ) );
2130 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2131 lines->AddPoint( VECTOR2I( x1, newY ) );
2132 lines->AddPoint( VECTOR2I( x2, newY ) );
2133 aItems.push_back( lines );
2134 }
2135
2136 char legendChar = 'A';
2137
2138 for( i = 0; i < eframe.rows; i++ )
2139 {
2140 LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2141 legendText->SetPosition( VECTOR2I( legendPosX, KiROUND( legendPosY ) ) );
2142 legendText->SetText( wxString( legendChar ) );
2143 legendText->SetTextSize( wxSize( schIUScale.MilsToIU( 90 ),
2144 schIUScale.MilsToIU( 100 ) ) );
2145 aItems.push_back( legendText );
2146 legendChar++;
2147 legendPosY -= rowSpacing;
2148 }
2149 }
2150
2151 if( !eframe.border_top )
2152 {
2153 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2154 lines->AddPoint( VECTOR2I( xMax - schIUScale.MilsToIU( 150 ),
2155 yMax - schIUScale.MilsToIU( 150 ) ) );
2156 lines->AddPoint( VECTOR2I( xMin + schIUScale.MilsToIU( 150 ),
2157 yMax - schIUScale.MilsToIU( 150 ) ) );
2158 aItems.push_back( lines );
2159
2160 int i;
2161 int width = xMax - xMin;
2162 int y1 = yMin;
2163 int y2 = yMin + schIUScale.MilsToIU( 150 );
2164 int legendPosY = yMax - schIUScale.MilsToIU( 75 );
2165 double columnSpacing = width / double( eframe.columns );
2166 double legendPosX = xMin + ( columnSpacing / 2 );
2167
2168 for( i = 1; i < eframe.columns; i++ )
2169 {
2170 int newX = KiROUND( xMin + ( columnSpacing * (double) i ) );
2171 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2172 lines->AddPoint( VECTOR2I( newX, y1 ) );
2173 lines->AddPoint( VECTOR2I( newX, y2 ) );
2174 aItems.push_back( lines );
2175 }
2176
2177 char legendChar = '1';
2178
2179 for( i = 0; i < eframe.columns; i++ )
2180 {
2181 LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2182 legendText->SetPosition( VECTOR2I( KiROUND( legendPosX ), legendPosY ) );
2183 legendText->SetText( wxString( legendChar ) );
2184 legendText->SetTextSize( wxSize( schIUScale.MilsToIU( 90 ),
2185 schIUScale.MilsToIU( 100 ) ) );
2186 aItems.push_back( legendText );
2187 legendChar++;
2188 legendPosX += columnSpacing;
2189 }
2190 }
2191
2192 if( !eframe.border_bottom )
2193 {
2194 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2195 lines->AddPoint( VECTOR2I( xMax - schIUScale.MilsToIU( 150 ),
2196 yMin + schIUScale.MilsToIU( 150 ) ) );
2197 lines->AddPoint( VECTOR2I( xMin + schIUScale.MilsToIU( 150 ),
2198 yMin + schIUScale.MilsToIU( 150 ) ) );
2199 aItems.push_back( lines );
2200
2201 int i;
2202 int width = xMax - xMin;
2203 int y1 = yMax - schIUScale.MilsToIU( 150 );
2204 int y2 = yMax;
2205 int legendPosY = yMin + schIUScale.MilsToIU( 75 );
2206 double columnSpacing = width / double( eframe.columns );
2207 double legendPosX = xMin + ( columnSpacing / 2 );
2208
2209 for( i = 1; i < eframe.columns; i++ )
2210 {
2211 int newX = KiROUND( xMin + ( columnSpacing * (double) i ) );
2212 lines = new LIB_SHAPE( nullptr, SHAPE_T::POLY );
2213 lines->AddPoint( VECTOR2I( newX, y1 ) );
2214 lines->AddPoint( VECTOR2I( newX, y2 ) );
2215 aItems.push_back( lines );
2216 }
2217
2218 char legendChar = '1';
2219
2220 for( i = 0; i < eframe.columns; i++ )
2221 {
2222 LIB_TEXT* legendText = new LIB_TEXT( nullptr );
2223 legendText->SetPosition( VECTOR2I( KiROUND( legendPosX ), legendPosY ) );
2224 legendText->SetText( wxString( legendChar ) );
2225 legendText->SetTextSize( wxSize( schIUScale.MilsToIU( 90 ),
2226 schIUScale.MilsToIU( 100 ) ) );
2227 aItems.push_back( legendText );
2228 legendChar++;
2229 legendPosX += columnSpacing;
2230 }
2231 }
2232}
void SetPosition(const VECTOR2I &aPosition) override
Definition: lib_item.h:234
void AddPoint(const VECTOR2I &aPosition)
Definition: lib_shape.cpp:501
Define a symbol library graphical text item.
Definition: lib_text.h:40
Parse an Eagle frame element.
Definition: eagle_parser.h:673
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:85

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

◆ loadFrame() [2/2]

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

Definition at line 1017 of file sch_eagle_plugin.cpp.

1018{
1019 EFRAME eframe( aFrameNode );
1020
1021 VECTOR2I corner1( eframe.x1.ToSchUnits(), -eframe.y1.ToSchUnits() );
1022 VECTOR2I corner3( eframe.x2.ToSchUnits(), -eframe.y2.ToSchUnits() );
1023 VECTOR2I corner2( corner3.x, corner1.y );
1024 VECTOR2I corner4( corner1.x, corner3.y );
1025
1026 SCH_LINE* line = new SCH_LINE();
1028 line->SetStartPoint( corner1 );
1029 line->SetEndPoint( corner2 );
1030 aLines.push_back( line );
1031
1032 line = new SCH_LINE();
1034 line->SetStartPoint( corner2 );
1035 line->SetEndPoint( corner3 );
1036 aLines.push_back( line );
1037
1038 line = new SCH_LINE();
1040 line->SetStartPoint( corner3 );
1041 line->SetEndPoint( corner4 );
1042 aLines.push_back( line );
1043
1044 line = new SCH_LINE();
1046 line->SetStartPoint( corner4 );
1047 line->SetEndPoint( corner1 );
1048 aLines.push_back( line );
1049}
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:139
void SetLineStyle(const PLOT_DASH_TYPE aStyle)
Definition: sch_line.cpp:256
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:144

References SCH_LINE::SetEndPoint(), SCH_LINE::SetLineStyle(), SCH_LINE::SetStartPoint(), SOLID, ECOORD::ToSchUnits(), VECTOR2< T >::x, EFRAME::x1, EFRAME::x2, VECTOR2< T >::y, EFRAME::y1, and EFRAME::y2.

Referenced by loadSheet(), and loadSymbol().

◆ loadInstance()

void SCH_EAGLE_PLUGIN::loadInstance ( wxXmlNode *  aInstanceNode)
private

Definition at line 1308 of file sch_eagle_plugin.cpp.

1309{
1310 EINSTANCE einstance = EINSTANCE( aInstanceNode );
1311 SCH_SCREEN* screen = getCurrentScreen();
1312
1313 wxCHECK( screen, /* void */ );
1314
1315 // Find the part in the list for the sheet.
1316 // Assign the symbol its value from the part entry
1317 // Calculate the unit number from the gate entry of the instance
1318 // Assign the LIB_ID from device set and device names
1319 auto part_it = m_partlist.find( einstance.part.Upper() );
1320
1321 if( part_it == m_partlist.end() )
1322 {
1323 m_reporter->Report( wxString::Format( _( "Error parsing Eagle file. Could not find '%s' "
1324 "instance but it is referenced in the schematic." ),
1325 einstance.part ),
1327
1328 return;
1329 }
1330
1331 EPART* epart = part_it->second.get();
1332
1333 wxString libraryname = epart->library;
1334 wxString gatename = epart->deviceset + epart->device + einstance.gate;
1335 wxString symbolname = wxString( epart->deviceset + epart->device );
1336 symbolname.Replace( wxT( "*" ), wxEmptyString );
1337 wxString kisymbolname = EscapeString( symbolname, CTX_LIBID );
1338
1339 int unit = m_eagleLibs[libraryname].GateUnit[gatename];
1340
1341 wxString package;
1342 EAGLE_LIBRARY* elib = &m_eagleLibs[libraryname];
1343
1344 auto p = elib->package.find( kisymbolname );
1345
1346 if( p != elib->package.end() )
1347 package = p->second;
1348
1349 LIB_SYMBOL* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
1350 m_properties.get() );
1351
1352 if( !part )
1353 {
1354 m_reporter->Report( wxString::Format( _( "Could not find '%s' in the imported library." ),
1355 UnescapeString( kisymbolname ) ),
1357 return;
1358 }
1359
1360 LIB_ID libId( getLibName(), kisymbolname );
1361 std::unique_ptr<SCH_SYMBOL> symbol = std::make_unique<SCH_SYMBOL>();
1362 symbol->SetLibId( libId );
1363 symbol->SetUnit( unit );
1364 symbol->SetPosition( VECTOR2I( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) );
1365
1366 // assume that footprint library is identical to project name
1367 wxString footprint = m_schematic->Prj().GetProjectName() + wxT( ":" ) + package;
1368 symbol->GetField( FOOTPRINT_FIELD )->SetText( footprint );
1369
1370 if( einstance.rot )
1371 {
1372 symbol->SetOrientation( kiCadComponentRotation( einstance.rot->degrees ) );
1373
1374 if( einstance.rot->mirror )
1375 symbol->MirrorHorizontally( einstance.x.ToSchUnits() );
1376 }
1377
1378 std::vector<LIB_FIELD*> partFields;
1379 part->GetFields( partFields );
1380
1381 for( const LIB_FIELD* field : partFields )
1382 {
1383 symbol->GetFieldById( field->GetId() )->ImportValues( *field );
1384 symbol->GetFieldById( field->GetId() )->SetTextPos( (VECTOR2I)symbol->GetPosition()
1385 + field->GetTextPos() );
1386 }
1387
1388 // If there is no footprint assigned, then prepend the reference value
1389 // with a hash character to mute netlist updater complaints
1390 wxString reference = package.IsEmpty() ? '#' + einstance.part : einstance.part;
1391
1392 // reference must end with a number but EAGLE does not enforce this
1393 if( reference.find_last_not_of( wxT( "0123456789" ) ) == ( reference.Length()-1 ) )
1394 reference.Append( wxT( "0" ) );
1395
1396 // EAGLE allows references to be single digits. This breaks KiCad netlisting, which requires
1397 // parts to have non-digit + digit annotation. If the reference begins with a number,
1398 // we prepend 'UNK' (unknown) for the symbol designator
1399 if( reference.find_first_not_of( wxT( "0123456789" ) ) != 0 )
1400 reference.Prepend( wxT( "UNK" ) );
1401
1402 // EAGLE allows designator to start with # but that is used in KiCad
1403 // for symbols which do not have a footprint
1404 if( einstance.part.find_first_not_of( wxT( "#" ) ) != 0 )
1405 reference.Prepend( wxT( "UNK" ) );
1406
1407 symbol->GetField( REFERENCE_FIELD )->SetText( reference );
1408
1409 wxString value = ( epart->value ) ? *epart->value : kisymbolname;
1410
1411 symbol->GetField( VALUE_FIELD )->SetText( value );
1412
1413 // Set the visibility of fields.
1414 symbol->GetField( REFERENCE_FIELD )->SetVisible(
1416 symbol->GetField( VALUE_FIELD )->SetVisible( part->GetFieldById( VALUE_FIELD )->IsVisible() );
1417
1418 for( const auto& a : epart->attribute )
1419 {
1420 SCH_FIELD* field = symbol->AddField( *symbol->GetField( VALUE_FIELD ) );
1421 field->SetName( a.first );
1422 field->SetText( a.second );
1423 field->SetVisible( false );
1424 }
1425
1426 for( const auto& a : epart->variant )
1427 {
1428 SCH_FIELD* field = symbol->AddField( *symbol->GetField( VALUE_FIELD ) );
1429 field->SetName( wxT( "VARIANT_" ) + a.first );
1430 field->SetText( a.second );
1431 field->SetVisible( false );
1432 }
1433
1434 bool valueAttributeFound = false;
1435 bool nameAttributeFound = false;
1436
1437 wxXmlNode* attributeNode = aInstanceNode->GetChildren();
1438
1439 // Parse attributes for the instance
1440 while( attributeNode )
1441 {
1442 if( attributeNode->GetName() == wxT( "attribute" ) )
1443 {
1444 EATTR attr = EATTR( attributeNode );
1445 SCH_FIELD* field = nullptr;
1446
1447 if( attr.name.Lower() == wxT( "name" ) )
1448 {
1449 field = symbol->GetField( REFERENCE_FIELD );
1450 nameAttributeFound = true;
1451 }
1452 else if( attr.name.Lower() == wxT( "value" ) )
1453 {
1454 field = symbol->GetField( VALUE_FIELD );
1455 valueAttributeFound = true;
1456 }
1457 else
1458 {
1459 field = symbol->FindField( attr.name );
1460
1461 if( field )
1462 field->SetVisible( false );
1463 }
1464
1465 if( field )
1466 {
1467
1468 field->SetPosition( VECTOR2I( attr.x->ToSchUnits(), -attr.y->ToSchUnits() ) );
1469 int align = attr.align ? *attr.align : ETEXT::BOTTOM_LEFT;
1470 int absdegrees = attr.rot ? attr.rot->degrees : 0;
1471 bool mirror = attr.rot ? attr.rot->mirror : false;
1472
1473 if( einstance.rot && einstance.rot->mirror )
1474 mirror = !mirror;
1475
1476 bool spin = attr.rot ? attr.rot->spin : false;
1477
1478 if( attr.display == EATTR::Off || attr.display == EATTR::NAME )
1479 field->SetVisible( false );
1480
1481 int rotation = einstance.rot ? einstance.rot->degrees : 0;
1482 int reldegrees = ( absdegrees - rotation + 360.0 );
1483 reldegrees %= 360;
1484
1485 eagleToKicadAlignment( (EDA_TEXT*) field, align, reldegrees, mirror, spin,
1486 absdegrees );
1487 }
1488 }
1489 else if( attributeNode->GetName() == wxT( "variant" ) )
1490 {
1491 wxString variantName, fieldValue;
1492
1493 if( attributeNode->GetAttribute( wxT( "name" ), &variantName )
1494 && attributeNode->GetAttribute( wxT( "value" ), &fieldValue ) )
1495 {
1496 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, symbol.get() );
1497 field.SetName( wxT( "VARIANT_" ) + variantName );
1498 field.SetText( fieldValue );
1499 field.SetVisible( false );
1500 symbol->AddField( field );
1501 }
1502 }
1503
1504 attributeNode = attributeNode->GetNext();
1505 }
1506
1507 if( einstance.smashed && einstance.smashed.Get() )
1508 {
1509 if( !valueAttributeFound )
1510 symbol->GetField( VALUE_FIELD )->SetVisible( false );
1511
1512 if( !nameAttributeFound )
1513 symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
1514 }
1515
1516 symbol->AddHierarchicalReference( m_sheetPath.Path(), reference, unit );
1517
1518 // Save the pin positions
1519 SYMBOL_LIB_TABLE& schLibTable = *m_schematic->Prj().SchSymbolLibTable();
1520 LIB_SYMBOL* libSymbol = schLibTable.LoadSymbol( symbol->GetLibId() );
1521
1522 wxCHECK( libSymbol, /*void*/ );
1523
1524 symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
1525
1526 std::vector<LIB_PIN*> pins;
1527 symbol->GetLibPins( pins );
1528
1529 for( const LIB_PIN* pin : pins )
1530 m_connPoints[symbol->GetPinPhysicalPosition( pin )].emplace( pin );
1531
1532 if( part->IsPower() )
1533 m_powerPorts[ reference ] = symbol->GetField( VALUE_FIELD )->GetText();
1534
1535 symbol->ClearFlags();
1536
1537 screen->Append( symbol.release() );
1538}
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
virtual bool IsVisible() const
Definition: eda_text.h:129
Field object used in symbol libraries.
Definition: lib_field.h:60
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
Define a library symbol object.
Definition: lib_symbol.h:98
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
bool IsPower() const
Definition: lib_symbol.cpp:552
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
T & Get()
Return a reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:292
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
std::map< wxString, wxString > m_powerPorts
map from symbol reference to global label equivalent
std::map< wxString, EAGLE_LIBRARY > m_eagleLibs
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:50
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1050
void SetName(const wxString &aName)
Definition: sch_field.h:114
virtual LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aPartName, const STRING_UTF8_MAP *aProperties=nullptr)
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
Definition: sch_plugin.cpp:85
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
@ RPT_SEVERITY_ERROR
static SYMBOL_ORIENTATION_T kiCadComponentRotation(float eagleDegrees)
static void eagleToKicadAlignment(EDA_TEXT *aText, int aEagleAlignment, int aRelDegress, bool aMirror, bool aSpin, int aAbsDegress)
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID
Definition: string_utils.h:55
std::unordered_map< wxString, wxString > package
Parse an Eagle "attribute" XML element.
Definition: eagle_parser.h:593
opt_ecoord y
Definition: eagle_parser.h:597
wxString name
Definition: eagle_parser.h:594
opt_erot rot
Definition: eagle_parser.h:601
opt_int align
Definition: eagle_parser.h:610
opt_int display
Definition: eagle_parser.h:609
opt_ecoord x
Definition: eagle_parser.h:596
int ToSchUnits() const
Definition: eagle_parser.h:429
wxString part
Definition: eagle_parser.h:948
ECOORD x
Definition: eagle_parser.h:950
opt_erot rot
Definition: eagle_parser.h:953
wxString gate
Definition: eagle_parser.h:949
ECOORD y
Definition: eagle_parser.h:951
opt_bool smashed
Definition: eagle_parser.h:952
wxString device
Definition: eagle_parser.h:924
std::map< std::string, std::string > variant
Definition: eagle_parser.h:928
wxString library
Definition: eagle_parser.h:922
wxString deviceset
Definition: eagle_parser.h:923
std::map< std::string, std::string > attribute
Definition: eagle_parser.h:927
opt_wxString value
Definition: eagle_parser.h:926
double degrees
Definition: eagle_parser.h:474
bool spin
Definition: eagle_parser.h:473
bool mirror
Definition: eagle_parser.h:472
@ BOTTOM_LEFT
Definition: eagle_parser.h:656
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".

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(), getCurrentScreen(), LIB_SYMBOL::GetFieldById(), LIB_SYMBOL::GetFields(), getLibFileName(), getLibName(), PROJECT::GetProjectName(), LIB_SYMBOL::IsPower(), EDA_TEXT::IsVisible(), kiCadComponentRotation(), EPART::library, SCH_PLUGIN::LoadSymbol(), SYMBOL_LIB_TABLE::LoadSymbol(), m_connPoints, m_eagleLibs, m_partlist, m_pi, m_powerPorts, m_properties, m_reporter, m_schematic, m_sheetPath, EROT::mirror, EATTR::name, EATTR::NAME, EATTR::Off, EAGLE_LIBRARY::package, EINSTANCE::part, SCH_SHEET_PATH::Path(), 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 1212 of file sch_eagle_plugin.cpp.

1213{
1214 std::unique_ptr<SCH_JUNCTION> junction = std::make_unique<SCH_JUNCTION>();
1215
1216 EJUNCTION ejunction = EJUNCTION( aJunction );
1217 VECTOR2I pos( ejunction.x.ToSchUnits(), -ejunction.y.ToSchUnits() );
1218
1219 junction->SetPosition( pos );
1220
1221 return junction.release();
1222}
Eagle Junction.
Definition: eagle_parser.h:521
ECOORD y
Definition: eagle_parser.h:523
ECOORD x
Definition: eagle_parser.h:522

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

1226{
1227 ELABEL elabel = ELABEL( aLabelNode, aNetName );
1228 VECTOR2I elabelpos( elabel.x.ToSchUnits(), -elabel.y.ToSchUnits() );
1229
1230 // Determine if the label is local or global depending on
1231 // the number of sheets the net appears in
1232 bool global = m_netCounts[aNetName] > 1;
1233 std::unique_ptr<SCH_TEXT> label;
1234
1235 wxSize textSize = wxSize( KiROUND( elabel.size.ToSchUnits() * 0.7 ),
1236 KiROUND( elabel.size.ToSchUnits() * 0.7 ) );
1237
1238 if( global )
1239 label = std::make_unique<SCH_GLOBALLABEL>();
1240 else
1241 label = std::make_unique<SCH_LABEL>();
1242
1243 label->SetPosition( elabelpos );
1244 label->SetText( escapeName( elabel.netname ) );
1245 label->SetTextSize( textSize );
1246 label->SetTextSpinStyle( TEXT_SPIN_STYLE::RIGHT );
1247
1248 if( elabel.rot )
1249 {
1250 for( int i = 0; i < KiROUND( elabel.rot->degrees / 90 ) %4; ++i )
1251 label->Rotate90( false );
1252
1253 if( elabel.rot->mirror )
1254 label->MirrorSpinStyle( false );
1255 }
1256
1257 return label.release();
1258}
wxString escapeName(const wxString &aNetName)
Eagle label.
Definition: eagle_parser.h:531
opt_erot rot
Definition: eagle_parser.h:536
ECOORD size
Definition: eagle_parser.h:534
wxString netname
Definition: eagle_parser.h:538
ECOORD y
Definition: eagle_parser.h:533
ECOORD x
Definition: eagle_parser.h:532

References EROT::degrees, escapeName(), KiROUND(), m_netCounts, EROT::mirror, ELABEL::netname, TEXT_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 178 of file sch_eagle_plugin.cpp.

179{
180 std::vector<ELAYER> eagleLayers;
181
182 // Get the first layer and iterate
183 wxXmlNode* layerNode = aLayers->GetChildren();
184
185 while( layerNode )
186 {
187 ELAYER elayer( layerNode );
188 eagleLayers.push_back( elayer );
189
190 layerNode = layerNode->GetNext();
191 }
192
193 // match layers based on their names
194 for( const ELAYER& elayer : eagleLayers )
195 {
213 if( elayer.name == wxT( "Nets" ) )
214 {
215 m_layerMap[elayer.number] = LAYER_WIRE;
216 }
217 else if( elayer.name == wxT( "Info" ) || elayer.name == wxT( "Guide" ) )
218 {
219 m_layerMap[elayer.number] = LAYER_NOTES;
220 }
221 else if( elayer.name == wxT( "Busses" ) )
222 {
223 m_layerMap[elayer.number] = LAYER_BUS;
224 }
225 }
226}
@ LAYER_WIRE
Definition: layer_ids.h:344
@ LAYER_BUS
Definition: layer_ids.h:345

References LAYER_BUS, LAYER_NOTES, LAYER_WIRE, and m_layerMap.

Referenced by loadDrawing().

◆ loadLibrary()

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

Definition at line 1541 of file sch_eagle_plugin.cpp.

1543{
1544 NODE_MAP libraryChildren = MapChildren( aLibraryNode );
1545
1546 // Loop through the symbols and load each of them
1547 wxXmlNode* symbolNode = getChildrenNodes( libraryChildren, wxT( "symbols" ) );
1548
1549 while( symbolNode )
1550 {
1551 wxString symbolName = symbolNode->GetAttribute( wxT( "name" ) );
1552 aEagleLibrary->SymbolNodes[symbolName] = symbolNode;
1553 symbolNode = symbolNode->GetNext();
1554 }
1555
1556 // Loop through the device sets and load each of them
1557 wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, wxT( "devicesets" ) );
1558
1559 while( devicesetNode )
1560 {
1561 // Get Device set information
1562 EDEVICE_SET edeviceset = EDEVICE_SET( devicesetNode );
1563
1564 wxString prefix = edeviceset.prefix ? edeviceset.prefix.Get() : wxT( "" );
1565
1566 NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
1567 wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, wxT( "devices" ) );
1568
1569 // For each device in the device set:
1570 while( deviceNode )
1571 {
1572 // Get device information
1573 EDEVICE edevice = EDEVICE( deviceNode );
1574
1575 // Create symbol name from deviceset and device names.
1576 wxString symbolName = edeviceset.name + edevice.name;
1577 symbolName.Replace( wxT( "*" ), wxEmptyString );
1578 wxASSERT( !symbolName.IsEmpty() );
1579 symbolName = EscapeString( symbolName, CTX_LIBID );
1580
1581 if( edevice.package )
1582 aEagleLibrary->package[symbolName] = edevice.package.Get();
1583
1584 // Create KiCad symbol.
1585 std::unique_ptr<LIB_SYMBOL> libSymbol = std::make_unique<LIB_SYMBOL>( symbolName );
1586
1587 // Process each gate in the deviceset for this device.
1588 wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, wxT( "gates" ) );
1589 int gates_count = countChildren( deviceSetChildren["gates"], wxT( "gate" ) );
1590 libSymbol->SetUnitCount( gates_count );
1591 libSymbol->LockUnits( true );
1592
1593 LIB_FIELD* reference = libSymbol->GetFieldById( REFERENCE_FIELD );
1594
1595 if( prefix.length() == 0 )
1596 {
1597 reference->SetVisible( false );
1598 }
1599 else
1600 {
1601 // If there is no footprint assigned, then prepend the reference value
1602 // with a hash character to mute netlist updater complaints
1603 reference->SetText( edevice.package ? prefix : '#' + prefix );
1604 }
1605
1606 int gateindex = 1;
1607 bool ispower = false;
1608
1609 while( gateNode )
1610 {
1611 checkpoint();
1612
1613 EGATE egate = EGATE( gateNode );
1614
1615 aEagleLibrary->GateUnit[edeviceset.name + edevice.name + egate.name] = gateindex;
1616 ispower = loadSymbol( aEagleLibrary->SymbolNodes[egate.symbol], libSymbol, &edevice,
1617 gateindex, egate.name );
1618
1619 gateindex++;
1620 gateNode = gateNode->GetNext();
1621 } // gateNode
1622
1623 libSymbol->SetUnitCount( gates_count );
1624
1625 if( gates_count == 1 && ispower )
1626 libSymbol->SetPower();
1627
1628 // assume that footprint library is identical to project name
1629 wxString packageString = m_schematic->Prj().GetProjectName() + wxT( ":" ) + aEagleLibrary->package[symbolName];
1630 libSymbol->GetFootprintField().SetText( packageString );
1631
1632 wxString name = libSymbol->GetName();
1633 libSymbol->SetName( name );
1634 m_pi->SaveSymbol( getLibFileName().GetFullPath(), new LIB_SYMBOL( *libSymbol.get() ),
1635 m_properties.get() );
1636 aEagleLibrary->KiCadSymbols.insert( name, libSymbol.release() );
1637
1638 deviceNode = deviceNode->GetNext();
1639 } // devicenode
1640
1641 devicesetNode = devicesetNode->GetNext();
1642 } // devicesetNode
1643
1644 return aEagleLibrary;
1645}
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)
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:94
static int countChildren(wxXmlNode *aCurrentNode, const wxString &aName)
Provide an easy access to the children of an XML node via their names.
opt_wxString prefix
wxString name
wxString name
opt_wxString package
wxString symbol
Definition: eagle_parser.h:974
wxString name
Definition: eagle_parser.h:973

References checkpoint(), countChildren(), CTX_LIBID, EscapeString(), EAGLE_LIBRARY::GateUnit, OPTIONAL_XML_ATTRIBUTE< T >::Get(), getChildrenNodes(), getLibFileName(), PROJECT::GetProjectName(), EAGLE_LIBRARY::KiCadSymbols, loadSymbol(), m_pi, m_properties, m_schematic, MapChildren(), name, EGATE::name, EDEVICE::name, EDEVICE_SET::name, EDEVICE::package, EAGLE_LIBRARY::package, EDEVICE_SET::prefix, SCHEMATIC::Prj(), REFERENCE_FIELD, SCH_PLUGIN::SaveSymbol(), 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 1944 of file sch_eagle_plugin.cpp.

1946{
1947 std::unique_ptr<LIB_PIN> pin = std::make_unique<LIB_PIN>( aSymbol.get() );
1948 pin->SetPosition( VECTOR2I( aEPin->x.ToSchUnits(), aEPin->y.ToSchUnits() ) );
1949 pin->SetName( aEPin->name );
1950 pin->SetUnit( aGateNumber );
1951
1952 int roti = aEPin->rot ? aEPin->rot->degrees : 0;
1953
1954 switch( roti )
1955 {
1956 case 0: pin->SetOrientation( 'R' ); break;
1957 case 90: pin->SetOrientation( 'U' ); break;
1958 case 180: pin->SetOrientation( 'L' ); break;
1959 case 270: pin->SetOrientation( 'D' ); break;
1960 default: wxFAIL_MSG( wxString::Format( wxT( "Unhandled orientation (%d degrees)." ), roti ) );
1961 }
1962
1963 pin->SetLength( schIUScale.MilsToIU( 300 ) ); // Default pin length when not defined.
1964
1965 if( aEPin->length )
1966 {
1967 wxString length = aEPin->length.Get();
1968
1969 if( length == wxT( "short" ) )
1970 pin->SetLength( schIUScale.MilsToIU( 100 ) );
1971 else if( length == wxT( "middle" ) )
1972 pin->SetLength( schIUScale.MilsToIU( 200 ) );
1973 else if( length == wxT( "long" ) )
1974 pin->SetLength( schIUScale.MilsToIU( 300 ) );
1975 else if( length == wxT( "point" ) )
1976 pin->SetLength( schIUScale.MilsToIU( 0 ) );
1977 }
1978
1979 // emulate the visibility of pin elements
1980 if( aEPin->visible )
1981 {
1982 wxString visible = aEPin->visible.Get();
1983
1984 if( visible == wxT( "off" ) )
1985 {
1986 pin->SetNameTextSize( 0 );
1987 pin->SetNumberTextSize( 0 );
1988 }
1989 else if( visible == wxT( "pad" ) )
1990 {
1991 pin->SetNameTextSize( 0 );
1992 }
1993 else if( visible == wxT( "pin" ) )
1994 {
1995 pin->SetNumberTextSize( 0 );
1996 }
1997
1998 /*
1999 * else if( visible == wxT( "both" ) )
2000 * {
2001 * }
2002 */
2003 }
2004
2005 if( aEPin->function )
2006 {
2007 wxString function = aEPin->function.Get();
2008
2009 if( function == wxT( "dot" ) )
2010 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
2011 else if( function == wxT( "clk" ) )
2012 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
2013 else if( function == wxT( "dotclk" ) )
2015 }
2016
2017 return pin.release();
2018}

References CLOCK, EROT::degrees, Format(), EPIN::function, OPTIONAL_XML_ATTRIBUTE< T >::Get(), INVERTED, INVERTED_CLOCK, EPIN::length, EDA_IU_SCALE::MilsToIU(), EPIN::name, pin, EPIN::rot, schIUScale, 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 2235 of file sch_eagle_plugin.cpp.

2236{
2237 std::unique_ptr<SCH_TEXT> schtext = std::make_unique<SCH_TEXT>();
2238 ETEXT etext = ETEXT( aSchText );
2239
2240 const wxString& thetext = aSchText->GetNodeContent();
2241
2242 wxString adjustedText;
2243 wxStringTokenizer tokenizer( thetext, "\r\n" );
2244
2245 // Strip the whitespace from both ends of each line.
2246 while( tokenizer.HasMoreTokens() )
2247 {
2248 wxString tmp = tokenizer.GetNextToken().Trim();
2249
2250 tmp = tmp.Trim( false );
2251
2252 if( tokenizer.HasMoreTokens() )
2253 tmp += wxT( "\n" );
2254
2255 adjustedText += tmp;
2256 }
2257
2258 schtext->SetText( adjustedText.IsEmpty() ? wxT( "\" \"" ) : escapeName( adjustedText ) );
2259 schtext->SetPosition( VECTOR2I( etext.x.ToSchUnits(), -etext.y.ToSchUnits() ) );
2260 loadTextAttributes( schtext.get(), etext );
2261 schtext->SetItalic( false );
2262
2263 return schtext.release();
2264}
void loadTextAttributes(EDA_TEXT *aText, const ETEXT &aAttribs) const
Eagle text element.
Definition: eagle_parser.h:636
ECOORD y
Definition: eagle_parser.h:639
ECOORD x
Definition: eagle_parser.h:638

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

605{
606 // Map all children into a readable dictionary
607 NODE_MAP schematicChildren = MapChildren( aSchematicNode );
608 wxXmlNode* partNode = getChildrenNodes( schematicChildren, wxT( "parts" ) );
609 wxXmlNode* libraryNode = getChildrenNodes( schematicChildren, wxT( "libraries" ) );
610 wxXmlNode* sheetNode = getChildrenNodes( schematicChildren, wxT( "sheets" ) );
611
612 if( !sheetNode )
613 return;
614
615 auto count_nodes =
616 []( wxXmlNode* aNode ) -> unsigned
617 {
618 unsigned count = 0;
619
620 while( aNode )
621 {
622 count++;
623 aNode = aNode->GetNext();
624 }
625
626 return count;
627 };
628
630 {
631 m_totalCount = 0;
632 m_doneCount = 0;
633
634 m_totalCount += count_nodes( partNode );
635
636 while( libraryNode )
637 {
638 NODE_MAP libraryChildren = MapChildren( libraryNode );
639 wxXmlNode* devicesetNode = getChildrenNodes( libraryChildren, wxT( "devicesets" ) );
640
641 while( devicesetNode )
642 {
643 NODE_MAP deviceSetChildren = MapChildren( devicesetNode );
644 wxXmlNode* deviceNode = getChildrenNodes( deviceSetChildren, wxT( "devices" ) );
645 wxXmlNode* gateNode = getChildrenNodes( deviceSetChildren, wxT( "gates" ) );
646
647 m_totalCount += count_nodes( deviceNode ) * count_nodes( gateNode );
648
649 devicesetNode = devicesetNode->GetNext();
650 }
651
652 libraryNode = libraryNode->GetNext();
653 }
654
655 // Rewind
656 libraryNode = getChildrenNodes( schematicChildren, wxT( "libraries" ) );
657
658 while( sheetNode )
659 {
660 NODE_MAP sheetChildren = MapChildren( sheetNode );
661
662 m_totalCount += count_nodes( getChildrenNodes( sheetChildren, wxT( "instances" ) ) );
663 m_totalCount += count_nodes( getChildrenNodes( sheetChildren, wxT( "busses" ) ) );
664 m_totalCount += count_nodes( getChildrenNodes( sheetChildren, wxT( "nets" ) ) );
665 m_totalCount += count_nodes( getChildrenNodes( sheetChildren, wxT( "plain" ) ) );
666
667 sheetNode = sheetNode->GetNext();
668 }
669
670 // Rewind
671 sheetNode = getChildrenNodes( schematicChildren, wxT( "sheets" ) );
672 }
673
674 while( partNode )
675 {
676 checkpoint();
677
678 std::unique_ptr<EPART> epart = std::make_unique<EPART>( partNode );
679
680 // N.B. Eagle parts are case-insensitive in matching but we keep the display case
681 m_partlist[epart->name.Upper()] = std::move( epart );
682 partNode = partNode->GetNext();
683 }
684
685 if( libraryNode )
686 {
687 while( libraryNode )
688 {
689 // Read the library name
690 wxString libName = libraryNode->GetAttribute( wxT( "name" ) );
691
692 EAGLE_LIBRARY* elib = &m_eagleLibs[libName];
693 elib->name = libName;
694
695 loadLibrary( libraryNode, &m_eagleLibs[libName] );
696
697 libraryNode = libraryNode->GetNext();
698 }
699
700 m_pi->SaveLibrary( getLibFileName().GetFullPath() );
701 }
702
703 // find all nets and count how many sheets they appear on.
704 // local labels will be used for nets found only on that sheet.
705 countNets( aSchematicNode );
706
707 // There is always at least a root sheet.
709
710 SCH_SHEET_PATH rootPath;
712 rootPath.SetPageNumber( wxT( "1" ) );
713
714 int sheetCount = countChildren( sheetNode->GetParent(), wxT( "sheet" ) );
715
716 if( sheetCount > 1 )
717 {
718 int x, y, i;
719 i = 1;
720 x = 1;
721 y = 1;
722
723 while( sheetNode )
724 {
725 VECTOR2I pos = VECTOR2I( x * schIUScale.MilsToIU( 1000 ),
726 y * schIUScale.MilsToIU( 1000 ) );
727
728 // Eagle schematics are never more than one sheet deep so the parent sheet is
729 // always the root sheet.
730 std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( m_rootSheet, pos );
731 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
732 sheet->SetScreen( screen );
733 screen->SetFileName( sheet->GetFileName() );
734
735 wxCHECK2( sheet && screen, continue );
736
737 wxString pageNo = wxString::Format( wxT( "%d" ), i );
738
739 m_sheetPath.push_back( sheet.get() );
740 loadSheet( sheetNode, i );
741
742 m_sheetPath.SetPageNumber( pageNo );
744
745 SCH_SCREEN* currentScreen = m_rootSheet->GetScreen();
746
747 wxCHECK2( currentScreen, continue );
748
749 currentScreen->Append( sheet.release() );
750
751 sheetNode = sheetNode->GetNext();
752 x += 2;
753
754 if( x > 10 ) // Start next row of sheets.
755 {
756 x = 1;
757 y += 2;
758 }
759
760 i++;
761 }
762 }
763 else
764 {
765 // There is only one sheet so we make that the root schematic.
766 while( sheetNode )
767 {
768 loadSheet( sheetNode, 0 );
769 sheetNode = sheetNode->GetNext();
770 }
771 }
772
773 // Handle the missing symbol units that need to be instantiated
774 // to create the missing implicit connections
775
776 // Calculate the already placed items bounding box and the page size to determine
777 // placement for the new symbols
779 BOX2I sheetBbox = getSheetBbox( m_rootSheet );
780 VECTOR2I newCmpPosition( sheetBbox.GetLeft(), sheetBbox.GetBottom() );
781 int maxY = sheetBbox.GetY();
782
783 SCH_SHEET_PATH sheetpath;
785
786 for( auto& cmp : m_missingCmps )
787 {
788 const SCH_SYMBOL* origSymbol = cmp.second.cmp;
789
790 for( auto& unitEntry : cmp.second.units )
791 {
792 if( unitEntry.second == false )
793 continue; // unit has been already processed
794
795 // Instantiate the missing symbol unit
796 int unit = unitEntry.first;
797 const wxString reference = origSymbol->GetField( REFERENCE_FIELD )->GetText();
798 std::unique_ptr<SCH_SYMBOL> symbol( (SCH_SYMBOL*) origSymbol->Duplicate() );
799
800 symbol->SetUnitSelection( &sheetpath, unit );
801 symbol->SetUnit( unit );
802 symbol->SetOrientation( 0 );
803 symbol->AddHierarchicalReference( sheetpath.Path(), reference, unit );
804
805 // Calculate the placement position
806 BOX2I cmpBbox = symbol->GetBoundingBox();
807 int posY = newCmpPosition.y + cmpBbox.GetHeight();
808 symbol->SetPosition( VECTOR2I( newCmpPosition.x, posY ) );
809 newCmpPosition.x += cmpBbox.GetWidth();
810 maxY = std::max( maxY, posY );
811
812 if( newCmpPosition.x >= pageSizeIU.GetWidth() ) // reached the page boundary?
813 newCmpPosition = VECTOR2I( sheetBbox.GetLeft(), maxY ); // then start a new row
814
815 // Add the global net labels to recreate the implicit connections
816 addImplicitConnections( symbol.get(), m_rootSheet->GetScreen(), false );
817 m_rootSheet->GetScreen()->Append( symbol.release() );
818 }
819 }
820
821 m_missingCmps.clear();
822}
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetY() const
Definition: box2.h:181
coord_type GetWidth() const
Definition: box2.h:187
coord_type GetLeft() const
Definition: box2.h:193
coord_type GetBottom() const
Definition: box2.h:190
const wxSize GetSizeIU(double aIUScale) const
Gets the page size in internal units.
Definition: page_info.h:162
void countNets(wxXmlNode *aSchematicNode)
EAGLE_LIBRARY * loadLibrary(wxXmlNode *aLibraryNode, EAGLE_LIBRARY *aEagleLib)
void addImplicitConnections(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen, bool aUpdateSet)
Create net labels to emulate implicit connections in Eagle.
void loadSheet(wxXmlNode *aSheetNode, int sheetcount)
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:93
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:131
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
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:743
bool AddInstance(const SCH_SHEET_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1205
Schematic symbol object.
Definition: sch_symbol.h:80
static BOX2I getSheetBbox(SCH_SHEET *aSheet)
Extract the net name part from a pin name (e.g. return 'GND' for pin named '[email protected]')
const double IU_PER_MILS
Definition: base_units.h:78

References addImplicitConnections(), SCH_SHEET::AddInstance(), SCH_SCREEN::Append(), checkpoint(), countChildren(), countNets(), SCH_ITEM::Duplicate(), Format(), BOX2< Vec >::GetBottom(), getChildrenNodes(), SCH_SYMBOL::GetField(), BOX2< Vec >::GetHeight(), BOX2< Vec >::GetLeft(), getLibFileName(), SCH_SCREEN::GetPageSettings(), SCH_SHEET::GetScreen(), getSheetBbox(), PAGE_INFO::GetSizeIU(), EDA_TEXT::GetText(), BOX2< Vec >::GetWidth(), BOX2< Vec >::GetY(), EDA_IU_SCALE::IU_PER_MILS, loadLibrary(), loadSheet(), SCH_SHEET::LocatePathOfScreen(), m_doneCount, m_eagleLibs, m_missingCmps, m_partlist, m_pi, m_progressReporter, m_rootSheet, m_schematic, m_sheetPath, m_totalCount, MapChildren(), EDA_IU_SCALE::MilsToIU(), EAGLE_LIBRARY::name, SCH_SHEET_PATH::Path(), SCH_SHEET_PATH::pop_back(), SCH_SHEET_PATH::push_back(), REFERENCE_FIELD, SCH_PLUGIN::SaveLibrary(), schIUScale, SCH_SCREEN::SetFileName(), SCH_SHEET_PATH::SetPageNumber(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by loadDrawing().

◆ loadSegments()

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

Definition at line 1052 of file sch_eagle_plugin.cpp.

1054{
1055 // Loop through all segments
1056 wxXmlNode* currentSegment = aSegmentsNode->GetChildren();
1057 SCH_SCREEN* screen = getCurrentScreen();
1058
1059 wxCHECK( screen, /* void */ );
1060
1061 int segmentCount = countChildren( aSegmentsNode, wxT( "segment" ) );
1062
1063 while( currentSegment )
1064 {
1065 bool labelled = false; // has a label been added to this continuously connected segment
1066 NODE_MAP segmentChildren = MapChildren( currentSegment );
1067 SCH_LINE* firstWire = nullptr;
1068 m_segments.emplace_back();
1069 SEG_DESC& segDesc = m_segments.back();
1070
1071 // Loop through all segment children
1072 wxXmlNode* segmentAttribute = currentSegment->GetChildren();
1073
1074 while( segmentAttribute )
1075 {
1076 if( segmentAttribute->GetName() == wxT( "wire" ) )
1077 {
1078 SCH_LINE* wire = loadWire( segmentAttribute );
1079
1080 if( !firstWire )
1081 firstWire = wire;
1082
1083 // Test for intersections with other wires
1084 SEG thisWire( wire->GetStartPoint(), wire->GetEndPoint() );
1085
1086 for( SEG_DESC& desc : m_segments )
1087 {
1088 if( !desc.labels.empty() && desc.labels.front()->GetText() == netName )
1089 continue; // no point in saving intersections of the same net
1090
1091 for( const SEG& seg : desc.segs )
1092 {
1093 OPT_VECTOR2I intersection = thisWire.Intersect( seg, true );
1094
1095 if( intersection )
1096 m_wireIntersections.push_back( *intersection );
1097 }
1098 }
1099
1100 segDesc.segs.push_back( thisWire );
1101 screen->Append( wire );
1102 }
1103
1104 segmentAttribute = segmentAttribute->GetNext();
1105 }
1106
1107 segmentAttribute = currentSegment->GetChildren();
1108
1109 while( segmentAttribute )
1110 {
1111 wxString nodeName = segmentAttribute->GetName();
1112
1113 if( nodeName == wxT( "junction" ) )
1114 {
1115 screen->Append( loadJunction( segmentAttribute ) );
1116 }
1117 else if( nodeName == wxT( "label" ) )
1118 {
1119 SCH_TEXT* label = loadLabel( segmentAttribute, netName );
1120 screen->Append( label );
1121 wxASSERT( segDesc.labels.empty()
1122 || segDesc.labels.front()->GetText() == label->GetText() );
1123 segDesc.labels.push_back( label );
1124 labelled = true;
1125 }
1126 else if( nodeName == wxT( "pinref" ) )
1127 {
1128 segmentAttribute->GetAttribute( wxT( "gate" ) ); // REQUIRED
1129 wxString part = segmentAttribute->GetAttribute( wxT( "part" ) ); // REQUIRED
1130 wxString pin = segmentAttribute->GetAttribute( wxT( "pin" ) ); // REQUIRED
1131
1132 auto powerPort = m_powerPorts.find( wxT( "#" ) + part );
1133
1134 if( powerPort != m_powerPorts.end()
1135 && powerPort->second == EscapeString( pin, CTX_NETNAME ) )
1136 {
1137 labelled = true;
1138 }
1139 }
1140 else if( nodeName == wxT( "wire" ) )
1141 {
1142 // already handled;
1143 }
1144 else // DEFAULT
1145 {
1146 // THROW_IO_ERROR( wxString::Format( _( "XML node '%s' unknown" ), nodeName ) );
1147 }
1148
1149 // Get next segment attribute
1150 segmentAttribute = segmentAttribute->GetNext();
1151 }
1152
1153 // Add a small label to the net segment if it hasn't been labeled already or is not
1154 // connect to a power symbol with a pin on the same net. This preserves the named net
1155 // feature of Eagle schematics.
1156 if( !labelled && firstWire )
1157 {
1158 std::unique_ptr<SCH_TEXT> label;
1159
1160 // Add a global label if the net appears on more than one Eagle sheet
1161 if( m_netCounts[netName.ToStdString()] > 1 )
1162 label.reset( new SCH_GLOBALLABEL );
1163 else if( segmentCount > 1 )
1164 label.reset( new SCH_LABEL );
1165
1166 if( label )
1167 {
1168 label->SetPosition( firstWire->GetStartPoint() );
1169 label->SetText( escapeName( netName ) );
1170 label->SetTextSize( wxSize( schIUScale.MilsToIU( 40 ),
1171 schIUScale.MilsToIU( 40 ) ) );
1172
1173 if( firstWire->GetEndPoint().x > firstWire->GetStartPoint().x )
1174 label->SetTextSpinStyle( TEXT_SPIN_STYLE::LEFT );
1175 else
1176 label->SetTextSpinStyle( TEXT_SPIN_STYLE::RIGHT );
1177
1178 screen->Append( label.release() );
1179 }
1180 }
1181
1182 currentSegment = currentSegment->GetNext();
1183 }
1184}
SCH_TEXT * loadLabel(wxXmlNode *aLabelNode, const wxString &aNetName)
SCH_LINE * loadWire(wxXmlNode *aWireNode)
SCH_JUNCTION * loadJunction(wxXmlNode *aJunction)
VECTOR2I GetEndPoint() const
Definition: sch_line.h:143
VECTOR2I GetStartPoint() const
Definition: sch_line.h:138
std::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
@ CTX_NETNAME
Definition: string_utils.h:54

References SCH_SCREEN::Append(), countChildren(), CTX_NETNAME, escapeName(), EscapeString(), getCurrentScreen(), SCH_LINE::GetEndPoint(), SCH_LINE::GetStartPoint(), EDA_TEXT::GetText(), SEG::Intersect(), SCH_EAGLE_PLUGIN::SEG_DESC::labels, TEXT_SPIN_STYLE::LEFT, loadJunction(), loadLabel(), loadWire(), m_netCounts, m_powerPorts, m_segments, m_wireIntersections, MapChildren(), EDA_IU_SCALE::MilsToIU(), pin, TEXT_SPIN_STYLE::RIGHT, schIUScale, SCH_EAGLE_PLUGIN::SEG_DESC::segs, and VECTOR2< T >::x.

Referenced by loadSheet().

◆ loadSheet()

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

Definition at line 825 of file sch_eagle_plugin.cpp.

826{
827 // Map all children into a readable dictionary
828 NODE_MAP sheetChildren = MapChildren( aSheetNode );
829
830 // Get description node
831 wxXmlNode* descriptionNode = getChildrenNodes( sheetChildren, wxT( "description" ) );
832
833 SCH_SHEET* sheet = getCurrentSheet();
834
835 wxCHECK( sheet, /* void */ );
836
837 wxString des;
838 std::string filename;
839 SCH_FIELD& sheetNameField = sheet->GetFields()[SHEETNAME];
840 SCH_FIELD& filenameField = sheet->GetFields()[SHEETFILENAME];
841
842 if( descriptionNode )
843 {
844 des = descriptionNode->GetContent();
845 des.Replace( wxT( "\n" ), wxT( "_" ), true );
846 sheetNameField.SetText( des );
847 filename = des.ToStdString();
848 }
849 else
850 {
851 filename = wxString::Format( wxT( "%s_%d" ), m_filename.GetName(), aSheetIndex );
852 sheetNameField.SetText( filename );
853 }
854
855 ReplaceIllegalFileNameChars( &filename );
856 replace( filename.begin(), filename.end(), ' ', '_' );
857
858 wxFileName fn( m_filename );
859 fn.SetName( filename );
860 fn.SetExt( KiCadSchematicFileExtension );
861
862 filenameField.SetText( fn.GetFullName() );
863
864 SCH_SCREEN* screen = getCurrentScreen();
865
866 wxCHECK( screen, /* void */ );
867
868 screen->SetFileName( fn.GetFullPath() );
869 sheet->AutoplaceFields( screen, true );
870
871 // Loop through all of the symbol instances.
872 wxXmlNode* instanceNode = getChildrenNodes( sheetChildren, wxT( "instances" ) );
873
874 while( instanceNode )
875 {
876 checkpoint();
877
878 loadInstance( instanceNode );
879 instanceNode = instanceNode->GetNext();
880 }
881
882 // Loop through all buses
883 // From the DTD: "Buses receive names which determine which signals they include.
884 // A bus is a drawing object. It does not create any electrical connections.
885 // These are always created by means of the nets and their names."
886 wxXmlNode* busNode = getChildrenNodes( sheetChildren, wxT( "busses" ) );
887
888 while( busNode )
889 {
890 checkpoint();
891
892 // Get the bus name
893 wxString busName = translateEagleBusName( busNode->GetAttribute( wxT( "name" ) ) );
894
895 // Load segments of this bus
896 loadSegments( busNode, busName, wxString() );
897
898 // Get next bus
899 busNode = busNode->GetNext();
900 }
901
902 // Loop through all nets
903 // From the DTD: "Net is an electrical connection in a schematic."
904 wxXmlNode* netNode = getChildrenNodes( sheetChildren, wxT( "nets" ) );
905
906 while( netNode )
907 {
908 checkpoint();
909
910 // Get the net name and class
911 wxString netName = netNode->GetAttribute( wxT( "name" ) );
912 wxString netClass = netNode->GetAttribute( wxT( "class" ) );
913
914 // Load segments of this net
915 loadSegments( netNode, netName, netClass );
916
917 // Get next net
918 netNode = netNode->GetNext();
919 }
920
921 adjustNetLabels(); // needs to be called before addBusEntries()
923
924 /* moduleinst is a design block definition and is an EagleCad 8 feature,
925 *
926 * // Loop through all moduleinsts
927 * wxXmlNode* moduleinstNode = getChildrenNodes( sheetChildren, "moduleinsts" );
928 *
929 * while( moduleinstNode )
930 * {
931 * loadModuleinst( moduleinstNode );
932 * moduleinstNode = moduleinstNode->GetNext();
933 * }
934 */
935
936 wxXmlNode* plainNode = getChildrenNodes( sheetChildren, wxT( "plain" ) );
937
938 while( plainNode )
939 {
940 checkpoint();
941
942 wxString nodeName = plainNode->GetName();
943
944 if( nodeName == wxT( "text" ) )
945 {
946 screen->Append( loadPlainText( plainNode ) );
947 }
948 else if( nodeName == wxT( "wire" ) )
949 {
950 screen->Append( loadWire( plainNode ) );
951 }
952 else if( nodeName == wxT( "frame" ) )
953 {
954 std::vector<SCH_LINE*> lines;
955
956 loadFrame( plainNode, lines );
957
958 for( SCH_LINE* line : lines )
959 screen->Append( line );
960 }
961
962 plainNode = plainNode->GetNext();
963 }
964
965 // Calculate the new sheet size.
966 BOX2I sheetBoundingBox = getSheetBbox( sheet );
967 VECTOR2I targetSheetSize = sheetBoundingBox.GetSize();
968 targetSheetSize += VECTOR2I( schIUScale.MilsToIU( 1500 ), schIUScale.MilsToIU( 1500 ) );
969
970 // Get current Eeschema sheet size.
971 wxSize pageSizeIU = screen->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS );
972 PAGE_INFO pageInfo = screen->GetPageSettings();
973
974 // Increase if necessary
975 if( pageSizeIU.x < targetSheetSize.x )
976 pageInfo.SetWidthMils( schIUScale.IUToMils( targetSheetSize.x ) );
977
978 if( pageSizeIU.y < targetSheetSize.y )
979 pageInfo.SetHeightMils( schIUScale.IUToMils( targetSheetSize.y ) );
980
981 // Set the new sheet size.
982 screen->SetPageSettings( pageInfo );
983
984 pageSizeIU = screen->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS );
985 VECTOR2I sheetcentre( pageSizeIU.x / 2, pageSizeIU.y / 2 );
986 VECTOR2I itemsCentre = sheetBoundingBox.Centre();
987
988 // round the translation to nearest 100mil to place it on the grid.
989 VECTOR2I translation = sheetcentre - itemsCentre;
990 translation.x = translation.x - translation.x % schIUScale.MilsToIU( 100 );
991 translation.y = translation.y - translation.y % schIUScale.MilsToIU( 100 );
992
993 // Add global net labels for the named power input pins in this sheet
994 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
995 {
996 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
997 addImplicitConnections( symbol, screen, true );
998 }
999
1000 m_connPoints.clear();
1001
1002 // Translate the items.
1003 std::vector<SCH_ITEM*> allItems;
1004
1005 std::copy( screen->Items().begin(), screen->Items().end(), std::back_inserter( allItems ) );
1006
1007 for( SCH_ITEM* item : allItems )
1008 {
1009 item->SetPosition( item->GetPosition() + translation );
1010 item->ClearFlags();
1011 screen->Update( item );
1012
1013 }
1014}
Vec Centre() const
Definition: box2.h:70
const Vec & GetSize() const
Definition: box2.h:179
iterator end()
Returns a read/write iterator that points to one past the last element in the EE_RTREE.
Definition: sch_rtree.h:285
iterator begin()
Returns a read/write iterator that points to the first element in the EE_RTREE N.B.
Definition: sch_rtree.h:276
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
void SetWidthMils(int aWidthInMils)
Definition: page_info.cpp:244
void SetHeightMils(int aHeightInMils)
Definition: page_info.cpp:258
void addBusEntries()
This function finds best way to place a bus entry symbol for when an Eagle wire segment ends on an Ea...
SCH_SHEET * getCurrentSheet()
SCH_TEXT * loadPlainText(wxXmlNode *aSchText)
void loadInstance(wxXmlNode *aInstanceNode)
wxString translateEagleBusName(const wxString &aEagleName) const
Translate an Eagle-style bus name into one that is KiCad-compatible.
void loadSegments(wxXmlNode *aSegmentsNode, const wxString &aNetName, const wxString &aNetClass)
void loadFrame(wxXmlNode *aFrameNode, std::vector< SCH_LINE * > &aLines)
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:261
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:132
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:91
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_sheet.cpp:590
@ SHEETNAME
Definition: sch_sheet.h:43
@ SHEETFILENAME
Definition: sch_sheet.h:44
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
constexpr int IUToMils(int iu) const
Definition: base_units.h:100
@ SCH_SYMBOL_T
Definition: typeinfo.h:156

References addBusEntries(), addImplicitConnections(), adjustNetLabels(), SCH_SCREEN::Append(), SCH_SHEET::AutoplaceFields(), EE_RTREE::begin(), BOX2< Vec >::Centre(), checkpoint(), EE_RTREE::end(), Format(), getChildrenNodes(), getCurrentScreen(), getCurrentSheet(), SCH_SHEET::GetFields(), SCH_SCREEN::GetPageSettings(), getSheetBbox(), BOX2< Vec >::GetSize(), PAGE_INFO::GetSizeIU(), SCH_SCREEN::Items(), EDA_IU_SCALE::IU_PER_MILS, EDA_IU_SCALE::IUToMils(), KiCadSchematicFileExtension, loadFrame(), loadInstance(), loadPlainText(), loadSegments(), loadWire(), m_connPoints, m_filename, MapChildren(), EDA_IU_SCALE::MilsToIU(), EE_RTREE::OfType(), ReplaceIllegalFileNameChars(), SCH_SYMBOL_T, schIUScale, SCH_SCREEN::SetFileName(), PAGE_INFO::SetHeightMils(), SCH_SCREEN::SetPageSettings(), EDA_TEXT::SetText(), PAGE_INFO::SetWidthMils(), SHEETFILENAME, SHEETNAME, translateEagleBusName(), SCH_SCREEN::Update(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by loadSchematic().

◆ LoadSymbol()

LIB_SYMBOL * SCH_PLUGIN::LoadSymbol ( const wxString &  aLibraryPath,
const wxString &  aPartName,
const STRING_UTF8_MAP 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_DATABASE_PLUGIN, SCH_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by SYMBOL_EDIT_FRAME::ExportSymbol(), SYMBOL_EDIT_FRAME::ImportSymbol(), loadInstance(), SYMBOL_LIB_TABLE::LoadSymbol(), SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(), SYMBOL_LIBRARY_MANAGER::SaveLibrary(), and SYMBOL_LIB_TABLE::SaveSymbol().

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

1650{
1651 wxString symbolName = aSymbolNode->GetAttribute( wxT( "name" ) );
1652 std::vector<LIB_ITEM*> items;
1653
1654 wxXmlNode* currentNode = aSymbolNode->GetChildren();
1655
1656 bool foundName = false;
1657 bool foundValue = false;
1658 bool ispower = false;
1659 int pincount = 0;
1660
1661 while( currentNode )
1662 {
1663 wxString nodeName = currentNode->GetName();
1664
1665 if( nodeName == wxT( "circle" ) )
1666 {
1667 aSymbol->AddDrawItem( loadSymbolCircle( aSymbol, currentNode, aGateNumber ) );
1668 }
1669 else if( nodeName == wxT( "pin" ) )
1670 {
1671 EPIN ePin = EPIN( currentNode );
1672 std::unique_ptr<LIB_PIN> pin( loadPin( aSymbol, currentNode, &ePin, aGateNumber ) );
1673 pincount++;
1674
1675 pin->SetType( ELECTRICAL_PINTYPE::PT_BIDI );
1676
1677 if( ePin.direction )
1678 {
1679 for( const auto& pinDir : pinDirectionsMap )
1680 {
1681 if( ePin.direction->Lower() == pinDir.first )
1682 {
1683 pin->SetType( pinDir.second );
1684
1685 if( pinDir.first == wxT( "sup" ) ) // power supply symbol
1686 ispower = true;
1687
1688 break;
1689 }
1690 }
1691 }
1692
1693 if( aDevice->connects.size() != 0 )
1694 {
1695 for( const ECONNECT& connect : aDevice->connects )
1696 {
1697 if( connect.gate == aGateName && pin->GetName() == connect.pin )
1698 {
1699 wxArrayString pads = wxSplit( wxString( connect.pad ), ' ' );
1700
1701 pin->SetUnit( aGateNumber );
1702 pin->SetName( escapeName( pin->GetName() ) );
1703
1704 if( pads.GetCount() > 1 )
1705 {
1706 pin->SetNumberTextSize( 0 );
1707 }
1708
1709 for( unsigned i = 0; i < pads.GetCount(); i++ )
1710 {
1711 LIB_PIN* apin = new LIB_PIN( *pin );
1712
1713 wxString padname( pads[i] );
1714 apin->SetNumber( padname );
1715 aSymbol->AddDrawItem( apin );
1716 }
1717
1718 break;
1719 }
1720 }
1721 }
1722 else
1723 {
1724 pin->SetUnit( aGateNumber );
1725 pin->SetNumber( wxString::Format( wxT( "%i" ), pincount ) );
1726 aSymbol->AddDrawItem( pin.release() );
1727 }
1728 }
1729 else if( nodeName == wxT( "polygon" ) )
1730 {
1731 aSymbol->AddDrawItem( loadSymbolPolyLine( aSymbol, currentNode, aGateNumber ) );
1732 }
1733 else if( nodeName == wxT( "rectangle" ) )
1734 {
1735 aSymbol->AddDrawItem( loadSymbolRectangle( aSymbol, currentNode, aGateNumber ) );
1736 }
1737 else if( nodeName == wxT( "text" ) )
1738 {
1739 std::unique_ptr<LIB_TEXT> libtext( loadSymbolText( aSymbol, currentNode,
1740 aGateNumber ) );
1741
1742 if( libtext->GetText().Upper() == wxT( ">NAME" ) )
1743 {
1744 LIB_FIELD* field = aSymbol->GetFieldById( REFERENCE_FIELD );
1745 loadFieldAttributes( field, libtext.get() );
1746 foundName = true;
1747 }
1748 else if( libtext->GetText().Upper() == wxT( ">VALUE" ) )
1749 {
1750 LIB_FIELD* field = aSymbol->GetFieldById( VALUE_FIELD );
1751 loadFieldAttributes( field, libtext.get() );
1752 foundValue = true;
1753 }
1754 else
1755 {
1756 aSymbol->AddDrawItem( libtext.release() );
1757 }
1758 }
1759 else if( nodeName == wxT( "wire" ) )
1760 {
1761 aSymbol->AddDrawItem( loadSymbolWire( aSymbol, currentNode, aGateNumber ) );
1762 }
1763 else if( nodeName == wxT( "frame" ) )
1764 {
1765 std::vector<LIB_ITEM*> frameItems;
1766
1767 loadFrame( currentNode, frameItems );
1768
1769 for( LIB_ITEM* item : frameItems )
1770 {
1771 item->SetParent( aSymbol.get() );
1772 item->SetUnit( aGateNumber );
1773 aSymbol->AddDrawItem( item );
1774 }
1775 }
1776
1777 /*
1778 * else if( nodeName == "description" )
1779 * {
1780 * }
1781 * else if( nodeName == "dimension" )
1782 * {
1783 * }
1784 */
1785
1786 currentNode = currentNode->GetNext();
1787 }
1788
1789 if( foundName == false )
1790 aSymbol->GetFieldById( REFERENCE_FIELD )->SetVisible( false );
1791
1792 if( foundValue == false )
1793 aSymbol->GetFieldById( VALUE_FIELD )->SetVisible( false );
1794
1795 return pincount == 1 ? ispower : false;
1796}
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:124
LIB_SHAPE * loadSymbolPolyLine(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aPolygonNode, int aGateNumber)
LIB_ITEM * loadSymbolWire(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aWireNode, int aGateNumber)
void loadFieldAttributes(LIB_FIELD *aField, const LIB_TEXT *aText) const
Move net labels that are detached from any wire to the nearest wire.
LIB_SHAPE * loadSymbolRectangle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aRectNode, int aGateNumber)
LIB_PIN * loadPin(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *, EPIN *epin, int aGateNumber)
LIB_SHAPE * loadSymbolCircle(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aCircleNode, int aGateNumber)
LIB_TEXT * loadSymbolText(std::unique_ptr< LIB_SYMBOL > &aSymbol, wxXmlNode *aLibText, int aGateNumber)
@ PT_BIDI
input or output (like port for a microprocessor)
static const std::map< wxString, ELECTRICAL_PINTYPE > pinDirectionsMap
Map of EAGLE pin type values to KiCad pin type values.
wxString pad
wxString gate
wxString pin
std::vector< ECONNECT > connects
Eagle pin element.
Definition: eagle_parser.h:740
opt_wxString direction
Definition: eagle_parser.h:747

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

Referenced by loadLibrary().

◆ loadSymbolCircle()

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

Definition at line 1799 of file sch_eagle_plugin.cpp.

1801{
1802 // Parse the circle properties
1803 ECIRCLE c( aCircleNode );
1804 LIB_SHAPE* circle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::CIRCLE );
1805 VECTOR2I center( c.x.ToSchUnits(), c.y.ToSchUnits() );
1806
1807 circle->SetPosition( center );
1808 circle->SetEnd( VECTOR2I( center.x + c.radius.ToSchUnits(), center.y ) );
1809 circle->SetStroke( STROKE_PARAMS( c.width.ToSchUnits(), PLOT_DASH_TYPE::SOLID ) );
1810 circle->SetUnit( aGateNumber );
1811
1812 return circle;
1813}
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:149
void SetUnit(int aUnit)
Definition: lib_item.h:272
void SetStroke(const STROKE_PARAMS &aStroke)
Definition: lib_shape.h:53
void SetPosition(const VECTOR2I &aPosition) override
Definition: lib_shape.h:86
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
Eagle circle.
Definition: eagle_parser.h:561

References CIRCLE, ECIRCLE::radius, EDA_SHAPE::SetEnd(), LIB_SHAPE::SetPosition(), LIB_SHAPE::SetStroke(), LIB_ITEM::SetUnit(), SOLID, ECOORD::ToSchUnits(), ECIRCLE::width, ECIRCLE::x, VECTOR2< T >::x, ECIRCLE::y, and VECTOR2< T >::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 1917 of file sch_eagle_plugin.cpp.

1919{
1920 LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY );
1921 EPOLYGON epoly( aPolygonNode );
1922 wxXmlNode* vertex = aPolygonNode->GetChildren();
1923 VECTOR2I pt;
1924
1925 while( vertex )
1926 {
1927 if( vertex->GetName() == wxT( "vertex" ) ) // skip <xmlattr> node
1928 {
1929 EVERTEX evertex( vertex );
1930 pt = VECTOR2I( evertex.x.ToSchUnits(), evertex.y.ToSchUnits() );
1931 poly->AddPoint( pt );
1932 }
1933
1934 vertex = vertex->GetNext();
1935 }
1936
1938 poly->SetUnit( aGateNumber );
1939
1940 return poly;
1941}
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:100
@ FILLED_SHAPE
Eagle polygon, without vertices which are parsed as needed.
Definition: eagle_parser.h:769
Eagle vertex.
Definition: eagle_parser.h:758

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

1818{
1819 ERECT rect( aRectNode );
1820 LIB_SHAPE* rectangle = new LIB_SHAPE( aSymbol.get(), SHAPE_T::RECT );
1821
1822 rectangle->SetPosition( VECTOR2I( rect.x1.ToSchUnits(), rect.y1.ToSchUnits() ) );
1823 rectangle->SetEnd( VECTOR2I( rect.x2.ToSchUnits(), rect.y2.ToSchUnits() ) );
1824
1825 if( rect.rot )
1826 {
1827 VECTOR2I pos( rectangle->GetPosition() );
1828 VECTOR2I end( rectangle->GetEnd() );
1829 VECTOR2I center( rectangle->GetCenter() );
1830
1831 RotatePoint( pos, center, EDA_ANGLE( rect.rot->degrees, DEGREES_T ) );
1832 RotatePoint( end, center, EDA_ANGLE( rect.rot->degrees, DEGREES_T ) );
1833
1834 rectangle->SetPosition( pos );
1835 rectangle->SetEnd( end );
1836 }
1837
1838 rectangle->SetUnit( aGateNumber );
1839
1840 // Eagle rectangles are filled by definition.
1841 rectangle->SetFillMode( FILL_T::FILLED_SHAPE );
1842
1843 return rectangle;
1844}
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:145
VECTOR2I GetCenter() const
Definition: lib_shape.h:88
VECTOR2I GetPosition() const override
Definition: lib_shape.h:85
@ DEGREES_T
Definition: eda_angle.h:31
Eagle XML rectangle in binary.
Definition: eagle_parser.h:574
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183

References EROT::degrees, DEGREES_T, FILLED_SHAPE, LIB_SHAPE::GetCenter(), EDA_SHAPE::GetEnd(), LIB_SHAPE::GetPosition(), RECT, ERECT::rot, RotatePoint(), 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 2021 of file sch_eagle_plugin.cpp.

2023{
2024 std::unique_ptr<LIB_TEXT> libtext = std::make_unique<LIB_TEXT>( aSymbol.get() );
2025 ETEXT etext( aLibText );
2026
2027 libtext->SetUnit( aGateNumber );
2028 libtext->SetPosition( VECTOR2I( etext.x.ToSchUnits(), etext.y.ToSchUnits() ) );
2029
2030 // Eagle supports multiple line text in library symbols. Legacy library symbol text cannot
2031 // contain CRs or LFs.
2032 //
2033 // @todo Split this into multiple text objects and offset the Y position so that it looks
2034 // more like the original Eagle schematic.
2035 wxString text = aLibText->GetNodeContent();
2036 std::replace( text.begin(), text.end(), '\n', '_' );
2037 std::replace( text.begin(), text.end(), '\r', '_' );
2038
2039 libtext->SetText( text.IsEmpty() ? wxT( "~" ) : text );
2040 loadTextAttributes( libtext.get(), etext );
2041
2042 return libtext.release();
2043}

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

Referenced by loadSymbol().

◆ loadSymbolWire()

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

Definition at line 1847 of file sch_eagle_plugin.cpp.

1849{
1850 EWIRE ewire = EWIRE( aWireNode );
1851
1852 VECTOR2I begin, end;
1853
1854 begin.x = ewire.x1.ToSchUnits();
1855 begin.y = ewire.y1.ToSchUnits();
1856 end.x = ewire.x2.ToSchUnits();
1857 end.y = ewire.y2.ToSchUnits();
1858
1859 if( begin == end )
1860 return nullptr;
1861
1862 // if the wire is an arc
1863 if( ewire.curve )
1864 {
1865 LIB_SHAPE* arc = new LIB_SHAPE( aSymbol.get(), SHAPE_T::ARC );
1866 VECTOR2I center = ConvertArcCenter( begin, end, *ewire.curve * -1 );
1867 double radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1868 + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1869 * 2;
1870
1871 // this emulates the filled semicircles created by a thick arc with flat ends caps.
1872 if( ewire.width.ToSchUnits() * 2 > radius )
1873 {
1874 VECTOR2I centerStartVector = begin - center;
1875 VECTOR2I centerEndVector = end - center;
1876
1877 centerStartVector.x = centerStartVector.x * ewire.width.ToSchUnits() * 2 / radius;
1878 centerStartVector.y = centerStartVector.y * ewire.width.ToSchUnits() * 2 / radius;
1879
1880 centerEndVector.x = centerEndVector.x * ewire.width.ToSchUnits() * 2 / radius;
1881 centerEndVector.y = centerEndVector.y * ewire.width.ToSchUnits() * 2 / radius;
1882
1883 begin = center + centerStartVector;
1884 end = center + centerEndVector;
1885
1886 radius = sqrt( abs( ( ( center.x - begin.x ) * ( center.x - begin.x ) )
1887 + ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
1888 * 2;
1889
1892 }
1893 else
1894 {
1896 }
1897
1898 arc->SetArcGeometry( begin, CalcArcMid( begin, end, center ), end );
1899 arc->SetUnit( aGateNumber );
1900
1901 return arc;
1902 }
1903 else
1904 {
1905 LIB_SHAPE* poly = new LIB_SHAPE( aSymbol.get(), SHAPE_T::POLY );
1906
1907 poly->AddPoint( begin );
1908 poly->AddPoint( end );
1909 poly->SetUnit( aGateNumber );
1911
1912 return poly;
1913 }
1914}
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:543
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
Eagle wire.
Definition: eagle_parser.h:492
ECOORD width
Definition: eagle_parser.h:497
ECOORD x2
Definition: eagle_parser.h:495
ECOORD y2
Definition: eagle_parser.h:496
ECOORD x1
Definition: eagle_parser.h:493
ECOORD y1
Definition: eagle_parser.h:494
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:507
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

References std::abs(), LIB_SHAPE::AddPoint(), ARC, CalcArcMid(), ConvertArcCenter(), EWIRE::curve, FILLED_SHAPE, POLY, EDA_SHAPE::SetArcGeometry(), EDA_SHAPE::SetFillMode(), LIB_SHAPE::SetStroke(), LIB_ITEM::SetUnit(), SOLID, ECOORD::ToSchUnits(), EWIRE::width, VECTOR2< T >::x, EWIRE::x1, EWIRE::x2, VECTOR2< T >::y, 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 2267 of file sch_eagle_plugin.cpp.

2268{
2269 aText->SetTextSize( aAttribs.ConvertSize() );
2270
2271 if( aAttribs.ratio )
2272 {
2273 if( aAttribs.ratio.CGet() > 12 )
2274 {
2275 aText->SetBold( true );
2276 aText->SetTextThickness( GetPenSizeForBold( aText->GetTextWidth() ) );
2277 }
2278 }
2279
2280 int align = aAttribs.align ? *aAttribs.align : ETEXT::BOTTOM_LEFT;
2281 int degrees = aAttribs.rot ? aAttribs.rot->degrees : 0;
2282 bool mirror = aAttribs.rot ? aAttribs.rot->mirror : false;
2283 bool spin = aAttribs.rot ? aAttribs.rot->spin : false;
2284
2285 eagleToKicadAlignment( aText, align, degrees, mirror, spin, 0 );
2286}
int GetTextWidth() const
Definition: eda_text.h:192
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:303
int GetPenSizeForBold(int aTextSize)
Definition: gr_text.cpp:40
opt_double ratio
Definition: eagle_parser.h:643
opt_erot rot
Definition: eagle_parser.h:644
opt_int align
Definition: eagle_parser.h:660
wxSize ConvertSize() const
Calculate text size based on font type and size.

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

1188{
1189 std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
1190
1191 EWIRE ewire = EWIRE( aWireNode );
1192
1193 wire->SetLayer( kiCadLayer( ewire.layer ) );
1194
1195 VECTOR2I begin, end;
1196
1197 begin.x = ewire.x1.ToSchUnits();
1198 begin.y = -ewire.y1.ToSchUnits();
1199 end.x = ewire.x2.ToSchUnits();
1200 end.y = -ewire.y2.ToSchUnits();
1201
1202 wire->SetStartPoint( begin );
1203 wire->SetEndPoint( end );
1204
1205 m_connPoints[begin].emplace( wire.get() );
1206 m_connPoints[end].emplace( wire.get() );
1207
1208 return wire.release();
1209}
SCH_LAYER_ID kiCadLayer(int aEagleLayer)
Return the matching layer or return LAYER_NOTES.
int layer
Definition: eagle_parser.h:498

References kiCadLayer(), EWIRE::layer, m_connPoints, ECOORD::ToSchUnits(), VECTOR2< T >::x, EWIRE::x1, EWIRE::x2, VECTOR2< T >::y, EWIRE::y1, and EWIRE::y2.

Referenced by loadSegments(), and loadSheet().

◆ moveLabels()

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

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

Definition at line 2396 of file sch_eagle_plugin.cpp.

2397{
2398 SCH_SCREEN* screen = getCurrentScreen();
2399
2400 wxCHECK( screen, /* void */ );
2401
2402 for( SCH_ITEM* item : screen->Items().Overlapping( aWire->GetBoundingBox() ) )
2403 {
2404 if( !item->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
2405 continue;
2406
2407 if( TestSegmentHit( item->GetPosition(), aWire->GetStartPoint(), aWire->GetEndPoint(), 0 ) )
2408 item->SetPosition( aNewEndPoint );
2409 }
2410}
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:243
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:191

References SCH_LINE::GetBoundingBox(), getCurrentScreen(), SCH_LINE::GetEndPoint(), SCH_LINE::GetStartPoint(), SCH_SCREEN::Items(), EE_RTREE::Overlapping(), 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 STRING_UTF8_MAP 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}

References not_implemented().

Referenced by DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged(), and SCH_EDIT_FRAME::saveSchematicFile().

◆ SaveLibrary()

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

◆ SaveSymbol()

void SCH_PLUGIN::SaveSymbol ( const wxString &  aLibraryPath,
const LIB_SYMBOL aSymbol,
const STRING_UTF8_MAP 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_SEXPR_PLUGIN, and SCH_LEGACY_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}

References not_implemented().

Referenced by PANEL_SYM_LIB_TABLE::convertLibrary(), SYMBOL_EDIT_FRAME::ExportSymbol(), SCH_EDITOR_CONTROL::ExportSymbolsToLibrary(), loadLibrary(), SCH_ALTIUM_PLUGIN::ParseFileHeader(), SCH_ALTIUM_PLUGIN::ParsePowerPort(), SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(), SYMBOL_LIBRARY_MANAGER::SaveLibrary(), SYMBOL_LIB_TABLE::SaveSymbol(), and SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary().

◆ SetLibTable()

virtual void SCH_PLUGIN::SetLibTable ( SYMBOL_LIB_TABLE aTable)
inlinevirtualinherited

Some library plugins need to have access to their parent library table.

Parameters
aTableis the table this plugin is registered within.

Reimplemented in SCH_DATABASE_PLUGIN.

Definition at line 515 of file sch_io_mgr.h.

515{}

Referenced by SYMBOL_LIB_TABLE::FindRow(), and SYMBOL_LIB_TABLE_ROW::Refresh().

◆ 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 }

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; }

References m_reporter.

◆ SupportsSubLibraries()

virtual bool SCH_PLUGIN::SupportsSubLibraries ( ) const
inlinevirtualinherited
Returns
true if this plugin supports libraries that contain sub-libraries.

Reimplemented in SCH_DATABASE_PLUGIN.

Definition at line 449 of file sch_io_mgr.h.

449{ return false; }

Referenced by SYMBOL_LIB_TABLE_ROW::SupportsSubLibraries().

◆ SymbolLibOptions()

void SCH_PLUGIN::SymbolLibOptions ( STRING_UTF8_MAP 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:71

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

3088{
3089 if( NET_SETTINGS::ParseBusVector( aEagleName, nullptr, nullptr ) )
3090 return aEagleName;
3091
3092 wxString ret = wxT( "{" );
3093
3094 wxStringTokenizer tokenizer( aEagleName, wxT( "," ) );
3095
3096 while( tokenizer.HasMoreTokens() )
3097 {
3098 wxString member = tokenizer.GetNextToken();
3099
3100 // In Eagle, overbar text is automatically stopped at the end of the net name, even when
3101 // that net name is part of a bus definition. In KiCad, we don't (currently) do that, so
3102 // if there is an odd number of overbar markers in this net name, we need to append one
3103 // to close it out before appending the space.
3104
3105 if( member.Freq( '!' ) % 2 > 0 )
3106 member << wxT( "!" );
3107
3108 ret << member << wxS( " " );
3109 }
3110
3111 ret.Trim( true );
3112 ret << wxT( "}" );
3113
3114 return ret;
3115}
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<VECTOR2I, std::set<const EDA_ITEM*> > SCH_EAGLE_PLUGIN::m_connPoints
private

Definition at line 264 of file sch_eagle_plugin.h.

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

◆ m_doneCount

unsigned SCH_EAGLE_PLUGIN::m_doneCount
private

Definition at line 234 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 228 of file sch_eagle_plugin.h.

Referenced by loadInstance(), and loadSchematic().

◆ m_filename

wxFileName SCH_EAGLE_PLUGIN::m_filename
private

Definition at line 223 of file sch_eagle_plugin.h.

Referenced by Load(), and loadSheet().

◆ m_lastProgressCount

unsigned SCH_EAGLE_PLUGIN::m_lastProgressCount
private

Definition at line 235 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 239 of file sch_eagle_plugin.h.

Referenced by kiCadLayer(), and loadLayerDefs().

◆ m_libName

wxString SCH_EAGLE_PLUGIN::m_libName
private

Library name to save symbols.

Definition at line 224 of file sch_eagle_plugin.h.

Referenced by getLibName().

◆ m_missingCmps

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

Definition at line 218 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 238 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 261 of file sch_eagle_plugin.h.

◆ m_partlist

EPART_MAP SCH_EAGLE_PLUGIN::m_partlist
private

Definition at line 227 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 230 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 240 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 233 of file sch_eagle_plugin.h.

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

◆ m_properties

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

Library plugin properties.

Definition at line 231 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 215 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 220 of file sch_eagle_plugin.h.

Referenced by getLibName(), Load(), 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 225 of file sch_eagle_plugin.h.

Referenced by getLibFileName(), getLibName(), Load(), loadInstance(), loadLibrary(), 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 258 of file sch_eagle_plugin.h.

Referenced by adjustNetLabels(), and loadSegments().

◆ m_sheetPath

SCH_SHEET_PATH SCH_EAGLE_PLUGIN::m_sheetPath
private

The current sheet path of the schematic being loaded.

Definition at line 221 of file sch_eagle_plugin.h.

Referenced by getCurrentScreen(), getCurrentSheet(), loadInstance(), and loadSchematic().

◆ m_totalCount

unsigned SCH_EAGLE_PLUGIN::m_totalCount
private

for progress reporting

Definition at line 236 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 222 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 245 of file sch_eagle_plugin.h.

Referenced by adjustNetLabels(), and loadSegments().


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