Eagle Project Import: Code cleanup and documentation.

- Also makes the project and file import functions filetype dependent.
- The change from IO_MGR::KICAD to IO_MGR::KICAD_SEXP removes a conflict from a compile definition for KICAD when compiling kicad/import_project.cpp
This commit is contained in:
Russell Oliver 2017-10-03 21:23:52 +11:00 committed by Maciej Suminski
parent c3b0fca922
commit 3b0855d204
24 changed files with 855 additions and 850 deletions

View File

@ -42,6 +42,7 @@ Cheng Sheng <chengsheng[at]google-dot-com> Google Inc.
Kristoffer Ödmark <kristoffer.odmark90[at]gmail-dot-com> Kristoffer Ödmark <kristoffer.odmark90[at]gmail-dot-com>
Oliver Walters <oliver.henry.walters[at]gmail-dot-com> Oliver Walters <oliver.henry.walters[at]gmail-dot-com>
Jon Evans <jon[at]craftyjon-dot-com> Jon Evans <jon[at]craftyjon-dot-com>
Russell Oliver <roliver8143[at]gmail-dot-com>
See also CHANGELOG.txt for contributors. See also CHANGELOG.txt for contributors.

View File

@ -0,0 +1,39 @@
Eagle Plugin Implementation Notes. 2017 Russell Oliver
Below is some notes on the correspondence between Eagle schematics and symbols libraries and the
KiCad equivalent.
Eagle libraries are a many to many listing of symbols and footprints connected by a device set and
device definitions. They are embedded in the schematic and board files if there are used, and
therefore the schematic symbols and footprints can be recovered from either file.
An Eagle device set definition is the information needed to represent a physical part at the
schematic level including the functional gates of the device. Each gate is lists the symbol to be
displayed for that gate. This is equivalent to a KiCad symbol unit. Since the symbol is defined
outside of the device set, multiple devices sets in the library can use the same symbol for a gate.
Lower to a device set, is the device definition. This establishes the link between the schematic
symbols and a physical part through the 'connect' elements. These map the symbol pins for each gate
to the physical pins provided by the package (footprint) definition. An Eagle Symbol outlines the
layout of graphical of items including pins. Pins for multi gate symbols are generally labelled
per their function, i.e. input / output. An Eagle symbol pin is not numbered but merely labelled. A
connect element gives the pad number for each pin found in that gate. Therefore the equivalent
KiCad pin number is read from the connect element pad number. Since an Eagle gate is equivalent to
a KiCad symbol unit, the graphical items for that unit will be copied from the Eagle symbol for
that gate and will be unique for that unit. This will yield duplication of the graphical elements
if the same symbol is used for multiple gates but the conversion will be complete.
An Eagle sheet contains a list of instances, which are equivalent to KiCad schematic component
entries. An instance describes the part, the gate used and its location on the sheet. This is
translated into the equivalent KiCad symbol with the given unit number.
Eagle 'plain' items describe graphical items with no electrical connection, such as note text,
lines etc. Of importance is the use of wire elements to describe both electrical connections and
graphical items. A wire element will act as an electrical connection when defined within a net and
segment. Anywhere else it is a graphical line. The layer for the wire element will change the
displayed colour for the wire. Connections between regular wires and busses occur when a wire ends
on a bus segment. When translated to KiCad a bus connection symbol is created. Within an Eagle
schematic there can be multiple sheets in a flat hierarchy. For each sheet, there is a list of
electrically connected nets. Each net is broken up into graphically connected segments, defined by
a list of wires and labels. Labels remain associate with wires of that net segment, even if they
are not located on a wire element. This necessitates the movement of such a label to the nearest
wire segment within KiCad.

View File

@ -156,6 +156,26 @@ NODE_MAP MapChildren( wxXmlNode* currentNode )
return nodesMap; return nodesMap;
} }
int CountChildren( wxXmlNode* aCurrentNode, const std::string& aName )
{
// Map node_name -> node_pointer
int count = 0;
// Loop through all children counting them if they match the given name
aCurrentNode = aCurrentNode->GetChildren();
while( aCurrentNode )
{
if( aCurrentNode->GetName().ToStdString() == aName )
count++;
// Get next child
aCurrentNode = aCurrentNode->GetNext();
}
return count;
}
string makeKey( const string& aFirst, const string& aSecond ) string makeKey( const string& aFirst, const string& aSecond )
{ {
@ -211,32 +231,33 @@ wxPoint kicad_arc_center( const wxPoint& aStart, const wxPoint& aEnd, double aAn
return center; return center;
} }
int parseAlignment(wxString alignment) int parseAlignment( const wxString& alignment )
{ {
// (bottom-left | bottom-center | bottom-right | center-left | // (bottom-left | bottom-center | bottom-right | center-left |
// center | center-right | top-left | top-center | top-right) // center | center-right | top-left | top-center | top-right)
if( alignment == "center" ) if( alignment == "center" )
return ETEXT::CENTER; return ETEXT::CENTER;
else if( alignment == "center-right" ) else if( alignment == "center-right" )
return ETEXT::CENTER_RIGHT; return ETEXT::CENTER_RIGHT;
else if( alignment == "top-left" ) else if( alignment == "top-left" )
return ETEXT::TOP_LEFT; return ETEXT::TOP_LEFT;
else if( alignment == "top-center" ) else if( alignment == "top-center" )
return ETEXT::TOP_CENTER; return ETEXT::TOP_CENTER;
else if( alignment == "top-right" ) else if( alignment == "top-right" )
return ETEXT::TOP_RIGHT; return ETEXT::TOP_RIGHT;
else if( alignment == "bottom-left" ) else if( alignment == "bottom-left" )
return ETEXT::BOTTOM_LEFT; return ETEXT::BOTTOM_LEFT;
else if( alignment == "bottom-center" ) else if( alignment == "bottom-center" )
return ETEXT::BOTTOM_CENTER; return ETEXT::BOTTOM_CENTER;
else if( alignment == "bottom-right" ) else if( alignment == "bottom-right" )
return ETEXT::BOTTOM_RIGHT; return ETEXT::BOTTOM_RIGHT;
else if( alignment == "center-left" ) else if( alignment == "center-left" )
return ETEXT::CENTER_LEFT; return ETEXT::CENTER_LEFT;
return DEFAULT_ALIGNMENT; return DEFAULT_ALIGNMENT;
} }
// convert textsize method. // convert textsize method.
wxSize convertTextSize(ETEXT& etext ) { wxSize convertTextSize(ETEXT& etext ) {
@ -909,7 +930,7 @@ EDEVICE::EDEVICE( wxXmlNode* aDevice )
}; };
EDEVICESET::EDEVICESET( wxXmlNode* aDeviceSet ) EDEVICE_SET::EDEVICE_SET( wxXmlNode* aDeviceSet )
{ {
/* /*
<!ELEMENT deviceset (description?, gates, devices)> <!ELEMENT deviceset (description?, gates, devices)>

View File

@ -52,7 +52,7 @@ void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
type = IO_MGR::EnumFromStr( aType ); type = IO_MGR::EnumFromStr( aType );
if( IO_MGR::PCB_FILE_T( -1 ) == type ) if( IO_MGR::PCB_FILE_T( -1 ) == type )
type = IO_MGR::KICAD; type = IO_MGR::KICAD_SEXP;
} }

View File

@ -1,40 +0,0 @@
Eagle Plugin Implementation Notes.
2017 Russell Oliver
Kicad Eagle
Footprint Package
Symbol Device
Unit Gate
Pin # Pad # from connect for gate
An Eagle library is made up of a description, package, symbols and devicesets.
Symbols outline the graphical layout of items including pins.
Pins for multi gate symbols are generally labled according to their function, i.e input / output. I/O
In contrast to kicad, different gates can have different symbols.
An Eagle gate is equivelent to a Kicad symbol Unit.
An Eagle symbol pin is not numbered, therefore the relationship is made by the Eagle connect element.
A connect element gives the pad number for each pin found in that gate.
Therefore the equivelent kicad pin number is read from the connect element pad number.
Since an Eagle gate is equivelent to a kicad symbol unit, the graphical items for that unit will be copied from the Eagle symbol and will be unique for that unit.
This will yield duplication of the graphical elements if the same symbol is used for multiple gates but the conversion will be complete.
A second pass may be used to remove duplicate items.
A kicad pin is numbered using the pad number found in the connect element. The pin name will be retained.
An Eagle sheet contains a list of instances, which are equivelent to Kicad schematic component entries.
An instance describes the part, the gate used and its location on the sheet.
<instance part="C1" gate="G$1" x="27.94" y="30.48"/>
A part has a name, the library used, the deviceset, the device, and optionally the device's value.
<part name="C1" library="rcl" deviceset="C-US" device="C0603" value="1u"/>

View File

@ -623,59 +623,66 @@ bool SCH_EDIT_FRAME::doAutoSave()
return autoSaveOk; return autoSaveOk;
} }
bool SCH_EDIT_FRAME::ImportFile( const wxString aFileName)
bool SCH_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
{ {
wxString fullFileName( aFileName ); wxString fullFileName( aFileName );
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
wxT( "Import eagle schematic caller didn't send full filename" ) );
if( !LockFile( fullFileName ) )
{
wxString msg = wxString::Format( _(
"Schematic file '%s' is already open." ),
GetChars( fullFileName )
);
DisplayError( this, msg );
return false;
}
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi; SCH_PLUGIN::SCH_PLUGIN_RELEASER pi;
wxString projectpath;
pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) ); wxFileName newfilename;
g_RootSheet = pi->Load( fullFileName, &Kiway() );
wxString projectpath = Kiway().Prj().GetProjectPath();
wxFileName newfilename = Prj().AbsolutePath( Prj().GetProjectName() );
newfilename.SetExt( SchematicFileExtension );
m_CurrentSheet->clear();
m_CurrentSheet->push_back( g_RootSheet );
SetScreen( m_CurrentSheet->LastScreen() );
g_RootSheet->SetFileName( newfilename.GetFullPath() );
GetScreen()->SetFileName( newfilename.GetFullPath() );
GetScreen()->SetModify();
SCH_SHEET_LIST sheetList( g_RootSheet ); SCH_SHEET_LIST sheetList( g_RootSheet );
SCH_SCREENS schematic; SCH_SCREENS schematic;
UpdateFileHistory( fullFileName ); switch( (SCH_IO_MGR::SCH_FILE_T)aFileType )
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets. {
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet. case SCH_IO_MGR::SCH_EAGLE:
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
wxT( "Import eagle schematic caller didn't send full filename" ) );
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); if( !LockFile( fullFileName ) )
Zoom_Automatique( false ); {
SetSheetNumberAndCount(); wxString msg = wxString::Format( _(
m_canvas->Refresh( true ); "Schematic file '%s' is already open." ),
UpdateTitle(); GetChars( fullFileName )
);
DisplayError( this, msg );
return false;
}
return true; pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) );
g_RootSheet = pi->Load( fullFileName, &Kiway() );
projectpath = Kiway().Prj().GetProjectPath();
newfilename = Prj().AbsolutePath( Prj().GetProjectName() );
newfilename.SetExt( SchematicFileExtension );
m_CurrentSheet->clear();
m_CurrentSheet->push_back( g_RootSheet );
SetScreen( m_CurrentSheet->LastScreen() );
g_RootSheet->SetFileName( newfilename.GetFullPath() );
GetScreen()->SetFileName( newfilename.GetFullPath() );
GetScreen()->SetModify();
UpdateFileHistory( fullFileName );
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
Zoom_Automatique( false );
SetSheetNumberAndCount();
m_canvas->Refresh( true );
UpdateTitle();
return true;
default:
return false;
}
return false;
} }

View File

@ -112,12 +112,12 @@ void SCH_EDIT_FRAME::sendNetlist()
bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
unsigned aNetlistOptions, REPORTER* aReporter, bool silent ) unsigned aNetlistOptions, REPORTER* aReporter, bool silent )
{ {
if( !silent ) if( !silent ) // checks for errors and invokes annotation dialog as neccessary
{ {
if( !prepareForNetlist() ) if( !prepareForNetlist() )
return false; return false;
} }
else else // performs similar function as prepareForNetlist but without a dialog.
{ {
SCH_SCREENS schematic; SCH_SCREENS schematic;
schematic.UpdateSymbolLinks(); schematic.UpdateSymbolLinks();

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
* *
* Copyright (C) 2017 CERN * Copyright (C) 2017 CERN
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com> * @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* @author Maciej Suminski <maciej.suminski@cern.ch>
* @author Russell Oliver <roliver8143@gmail.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -69,9 +71,9 @@ class LIB_TEXT;
typedef struct EAGLE_LIBRARY typedef struct EAGLE_LIBRARY
{ {
std::string name; std::string name;
boost::ptr_map<std::string, LIB_PART> kicadsymbols; boost::ptr_map<std::string, LIB_PART> KiCadSymbols;
std::unordered_map<std::string, wxXmlNode*> symbolnodes; std::unordered_map<std::string, wxXmlNode*> SymbolNodes;
std::unordered_map<std::string, int> gate_unit; std::unordered_map<std::string, int> GateUnit;
std::unordered_map<std::string, std::string> package; std::unordered_map<std::string, std::string> package;
} EAGLE_LIBRARY; } EAGLE_LIBRARY;
@ -92,58 +94,62 @@ public:
int GetModifyHash() const override; int GetModifyHash() const override;
void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;
SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCH_SHEET* aAppendToMe = NULL, SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCH_SHEET* aAppendToMe = NULL,
const PROPERTIES* aProperties = NULL ) override; const PROPERTIES* aProperties = NULL ) override;
void Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway,
const PROPERTIES* aProperties = NULL ) override;
size_t GetSymbolLibCount( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
void EnumerateSymbolLib( wxArrayString& aAliasNameList, const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
const PROPERTIES* aProperties = NULL ) override;
void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
void CreateSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
bool DeleteSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const override;
bool CheckHeader( const wxString& aFileName ) override; bool CheckHeader( const wxString& aFileName ) override;
// unimplemented functions. Will trigger a not_implemented IO error.
//void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override;
//void Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway,
// const PROPERTIES* aProperties = NULL ) override;
//size_t GetSymbolLibCount( const wxString& aLibraryPath,
// const PROPERTIES* aProperties = NULL ) override;
//void EnumerateSymbolLib( wxArrayString& aAliasNameList, const wxString& aLibraryPath,
// const PROPERTIES* aProperties = NULL ) override;
//LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
// const PROPERTIES* aProperties = NULL ) override;
//void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
// const PROPERTIES* aProperties = NULL ) override;
//void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
// const PROPERTIES* aProperties = NULL ) override;
//void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
// const PROPERTIES* aProperties = NULL ) override;
//void CreateSymbolLib( const wxString& aLibraryPath,
// const PROPERTIES* aProperties = NULL ) override;
// bool DeleteSymbolLib( const wxString& aLibraryPath,
// const PROPERTIES* aProperties = NULL ) override;
//bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
//void SymbolLibOptions( PROPERTIES* aListToAppendTo ) const override;
private: private:
void loadDrawing( wxXmlNode* aDrawingNode ); void loadDrawing( wxXmlNode* aDrawingNode );
void loadLayerDefs( wxXmlNode* aLayers ); void loadLayerDefs( wxXmlNode* aLayers );
void loadSchematic( wxXmlNode* aSchematicNode ); void loadSchematic( wxXmlNode* aSchematicNode );
void loadSheet( wxXmlNode* aSheetNode, int sheetcount ); void loadSheet( wxXmlNode* aSheetNode, int sheetcount );
void loadInstance( wxXmlNode* aInstanceNode ); void loadInstance( wxXmlNode* aInstanceNode );
void loadModuleinst( wxXmlNode* aModuleinstNode ); //void loadModuleinst( wxXmlNode* aModuleinstNode ); // Eagle 8 feature that defines a replicatable schematic circuit and pcb layout.
EAGLE_LIBRARY* loadLibrary( wxXmlNode* aLibraryNode, EAGLE_LIBRARY* elib); EAGLE_LIBRARY* loadLibrary( wxXmlNode* aLibraryNode, EAGLE_LIBRARY* elib);
void countNets( wxXmlNode* aSchematicNode ); void countNets( wxXmlNode* aSchematicNode );
void moveLabels( SCH_ITEM* wire, wxPoint newendpoint); void moveLabels( SCH_ITEM* wire, wxPoint newendpoint);
void addBusEntries(); void addBusEntries();
static wxString fixNetName( const wxString& aNetName ); static wxString fixNetName( const wxString& aNetName );
SCH_LAYER_ID kicadLayer( int aEagleLayer ); SCH_LAYER_ID kiCadLayer( int aEagleLayer );
wxPoint findNearestLinePoint(wxPoint aPoint, const DLIST< SCH_LINE >& lines); wxPoint findNearestLinePoint(wxPoint aPoint, const DLIST< SCH_LINE >& lines);
void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName, void loadSegments( wxXmlNode* aSegmentsNode, const wxString& aNetName,
@ -151,15 +157,15 @@ private:
SCH_LINE* loadWire( wxXmlNode* aWireNode ); SCH_LINE* loadWire( wxXmlNode* aWireNode );
SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName, const DLIST< SCH_LINE >& segmentWires); SCH_TEXT* loadLabel( wxXmlNode* aLabelNode, const wxString& aNetName, const DLIST< SCH_LINE >& segmentWires);
SCH_JUNCTION* loadJunction( wxXmlNode* aJunction ); SCH_JUNCTION* loadJunction( wxXmlNode* aJunction );
SCH_TEXT* loadplaintext( wxXmlNode* aSchText ); SCH_TEXT* loadPlainText( wxXmlNode* aSchText );
bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_PART >& aPart, EDEVICE* aDevice, int gateNumber, string gateName); bool loadSymbol(wxXmlNode *aSymbolNode, std::unique_ptr< LIB_PART >& aPart, EDEVICE* aDevice, int aGateNumber, string aGateName);
LIB_CIRCLE* loadSymbolCircle( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aCircleNode, int gateNumber); LIB_CIRCLE* loadSymbolCircle( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aCircleNode, int aGateNumber);
LIB_RECTANGLE* loadSymbolRectangle( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aRectNode, int gateNumber ); LIB_RECTANGLE* loadSymbolRectangle( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aRectNode, int aGateNumber );
LIB_POLYLINE* loadSymbolPolyLine( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aPolygonNode, int gateNumber ); LIB_POLYLINE* loadSymbolPolyLine( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aPolygonNode, int aGateNumber );
LIB_ITEM* loadSymbolWire( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aWireNode, int gateNumber); LIB_ITEM* loadSymbolWire( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aWireNode, int aGateNumber);
LIB_PIN* loadPin( std::unique_ptr< LIB_PART >& aPart, wxXmlNode*, EPIN* epin, int gateNumber); LIB_PIN* loadPin( std::unique_ptr< LIB_PART >& aPart, wxXmlNode*, EPIN* epin, int aGateNumber);
LIB_TEXT* loadSymboltext( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aLibText, int gateNumber); LIB_TEXT* loadSymbolText( std::unique_ptr< LIB_PART >& aPart, wxXmlNode* aLibText, int aGateNumber);
KIWAY* m_kiway; ///< For creating sub sheets. KIWAY* m_kiway; ///< For creating sub sheets.
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.. SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
@ -171,7 +177,6 @@ private:
EPART_MAP m_partlist; EPART_MAP m_partlist;
std::map<std::string, EAGLE_LIBRARY> m_eaglelibraries; std::map<std::string, EAGLE_LIBRARY> m_eaglelibraries;
EDA_RECT sheetBoundingBox;
std::map<std::string, int > m_NetCounts; std::map<std::string, int > m_NetCounts;
std::map<int, SCH_LAYER_ID> m_LayerMap; std::map<int, SCH_LAYER_ID> m_LayerMap;

View File

@ -488,8 +488,6 @@ public:
/** /**
* Function CheckHeader * Function CheckHeader
* returns true if the first line in @a aFileName begins with the expected header * returns true if the first line in @a aFileName begins with the expected header
* system libraries are read only because of where they are installed.)
*
* @param aFileName is the name of the file to use as input * @param aFileName is the name of the file to use as input
* *
*/ */

View File

@ -785,7 +785,13 @@ public:
bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria ); bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria );
bool ImportFile( const wxString aFileName ) override ; /**
* Function ImportFile
* load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType SCH_FILE_T value for filetype
*/
bool ImportFile( const wxString& aFileName, int aFileType ) override ;
private: private:

View File

@ -210,7 +210,7 @@ public:
* aData is empty, the attribute is understood as unavailable; otherwise, the * aData is empty, the attribute is understood as unavailable; otherwise, the
* conversion to T is tried. * conversion to T is tried.
*/ */
OPTIONAL_XML_ATTRIBUTE( wxString aData ) OPTIONAL_XML_ATTRIBUTE( const wxString& aData )
{ {
m_isAvailable = !aData.IsEmpty(); m_isAvailable = !aData.IsEmpty();
@ -243,7 +243,7 @@ public:
* @param aData is a wxString that should be converted to T. If the string is empty, the * @param aData is a wxString that should be converted to T. If the string is empty, the
* attribute is set to unavailable. * attribute is set to unavailable.
*/ */
OPTIONAL_XML_ATTRIBUTE<T>& operator =( wxString aData ) OPTIONAL_XML_ATTRIBUTE<T>& operator =( const wxString& aData )
{ {
m_isAvailable = !aData.IsEmpty(); m_isAvailable = !aData.IsEmpty();
@ -282,7 +282,7 @@ public:
* tries to convert a string to the base type. * tries to convert a string to the base type.
* @param aString is the string that will be converted to the base type. * @param aString is the string that will be converted to the base type.
*/ */
void Set( wxString aString ) void Set( const wxString& aString )
{ {
m_data = Convert<T>( aString ); m_data = Convert<T>( aString );
} }
@ -360,6 +360,16 @@ public:
*/ */
NODE_MAP MapChildren( wxXmlNode* currentNode ); NODE_MAP MapChildren( wxXmlNode* currentNode );
/**
* Function CountChildren
* provides an easy access to the children of an XML node via their names.
* @param aCurrentNode is a pointer to a wxXmlNode, whose children will be mapped.
* @param aName the name of the specific child names to be counted.
* @return number of children with the give node name.
*/
int CountChildren( wxXmlNode* aCurrentNode, const std::string& aName );
/// Assemble a two part key as a simple concatenation of aFirst and aSecond parts, /// Assemble a two part key as a simple concatenation of aFirst and aSecond parts,
/// using a separator. /// using a separator.
string makeKey( const string& aFirst, const string& aSecond ); string makeKey( const string& aFirst, const string& aSecond );
@ -948,7 +958,7 @@ typedef struct EDEVICE
EDEVICE( wxXmlNode* aDevice ); EDEVICE( wxXmlNode* aDevice );
} EDEVICE; } EDEVICE;
struct EDEVICESET struct EDEVICE_SET
{ {
/* /*
<!ELEMENT deviceset (description?, gates, devices)> <!ELEMENT deviceset (description?, gates, devices)>
@ -966,7 +976,7 @@ struct EDEVICESET
//std::vector<EGATE> gates; //std::vector<EGATE> gates;
EDEVICESET( wxXmlNode* aDeviceSet ); EDEVICE_SET( wxXmlNode* aDeviceSet );
}; };

View File

@ -54,7 +54,7 @@ public:
} }
FP_LIB_TABLE_ROW() : FP_LIB_TABLE_ROW() :
type( IO_MGR::KICAD ) type( IO_MGR::KICAD_SEXP )
{ {
} }

View File

@ -180,10 +180,12 @@ public:
} }
/** /**
* Function OpenProjectFiles * Function ImportFile
* load the given filename but sets the path to the current project path. * load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType enum value for filetype
*/ */
VTBL_ENTRY bool ImportFile( const wxString aFileName) VTBL_ENTRY bool ImportFile( const wxString& aFileName, int aFileType )
{ {
// overload me for your wxFrame type. // overload me for your wxFrame type.
@ -192,7 +194,7 @@ public:
/** /**
* Function ReadPcbNetlist * Function ReadPcbNetlist
* provides access to PcbNew's function. * provides access to PcbNew's function ReadPcbNetlist.
*/ */
VTBL_ENTRY void ReadPcbNetlist( const wxString& aNetlistFileName, VTBL_ENTRY void ReadPcbNetlist( const wxString& aNetlistFileName,
@ -209,7 +211,7 @@ public:
/** /**
* Function ReadPcbNetlist * Function ReadPcbNetlist
* provides access to Eeschema's function. * provides access to Eeschema's function CreateNetlist.
*/ */
VTBL_ENTRY bool CreateNetlist( int aFormat, VTBL_ENTRY bool CreateNetlist( int aFormat,
const wxString& aFullFileName, const wxString& aFullFileName,

View File

@ -1,8 +1,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * @author Russell Oliver <roliver8143@gmail.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,7 +23,7 @@
*/ */
/** /**
* @file eagle_project.cpp * @file import_project.cpp
* @brief routines for importing an eagle project * @brief routines for importing an eagle project
*/ */
@ -45,6 +45,8 @@
#include <stdexcept> #include <stdexcept>
#include "pgm_kicad.h" #include "pgm_kicad.h"
#include <io_mgr.h>
#include <sch_io_mgr.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <schframe.h> #include <schframe.h>
#include <netlist.h> #include <netlist.h>
@ -143,7 +145,7 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
} }
} }
schframe->ImportFile( sch_filename ); schframe->ImportFile( sch_filename, SCH_IO_MGR::SCH_EAGLE );
if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor) if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor)
// but no project loaded. // but no project loaded.
@ -182,7 +184,7 @@ void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
// if the frame is not visible, the board is not yet loaded // if the frame is not visible, the board is not yet loaded
if( !pcbframe->IsVisible() ) if( !pcbframe->IsVisible() )
{ {
pcbframe->ImportFile( pcb.GetFullPath() ); pcbframe->ImportFile( pcb.GetFullPath(), IO_MGR::EAGLE );
pcbframe->Show( true ); pcbframe->Show( true );
} }

View File

@ -195,6 +195,9 @@ public:
void ReCreateMenuBar() override; void ReCreateMenuBar() override;
void RecreateBaseHToolbar(); void RecreateBaseHToolbar();
/**
* Open dialog to import Eagle schematic and board files.
*/
void OnImportEagleFiles( wxCommandEvent& event ); void OnImportEagleFiles( wxCommandEvent& event );
/** /**

View File

@ -185,7 +185,7 @@ public:
wxArrayString choices; wxArrayString choices;
choices.Add( IO_MGR::ShowType( IO_MGR::KICAD ) ); choices.Add( IO_MGR::ShowType( IO_MGR::KICAD_SEXP ) );
choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) ); choices.Add( IO_MGR::ShowType( IO_MGR::GITHUB ) );
choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) ); choices.Add( IO_MGR::ShowType( IO_MGR::LEGACY ) );
choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) ); choices.Add( IO_MGR::ShowType( IO_MGR::EAGLE ) );

View File

@ -65,7 +65,7 @@ static const struct
IO_MGR::PCB_FILE_T m_Plugin; IO_MGR::PCB_FILE_T m_Plugin;
} fileFilters[FILTER_COUNT] = } fileFilters[FILTER_COUNT] =
{ {
{ "KiCad (folder with .kicad_mod files)", "kicad_mod", false, IO_MGR::KICAD }, { "KiCad (folder with .kicad_mod files)", "kicad_mod", false, IO_MGR::KICAD_SEXP },
{ "Eagle 6.x (*.lbr)", "lbr", true, IO_MGR::EAGLE }, { "Eagle 6.x (*.lbr)", "lbr", true, IO_MGR::EAGLE },
{ "KiCad legacy (*.mod)", "mod", true, IO_MGR::LEGACY }, { "KiCad legacy (*.mod)", "mod", true, IO_MGR::LEGACY },
{ "Geda (folder with *.fp files)", "fp", false, IO_MGR::GEDA_PCB }, { "Geda (folder with *.fp files)", "fp", false, IO_MGR::GEDA_PCB },
@ -206,7 +206,7 @@ wxString WIZARD_FPLIB_TABLE::LIBRARY::GetPluginName() const
case IO_MGR::LEGACY: case IO_MGR::LEGACY:
return wxT( "Legacy" ); return wxT( "Legacy" );
case IO_MGR::KICAD: case IO_MGR::KICAD_SEXP:
return wxT( "KiCad" ); return wxT( "KiCad" );
case IO_MGR::EAGLE: case IO_MGR::EAGLE:
@ -544,7 +544,7 @@ void WIZARD_FPLIB_TABLE::OnWizardFinished( wxWizardEvent& aEvent )
wxString path = it->GetAbsolutePath(); wxString path = it->GetAbsolutePath();
path.Replace( GetGithubURL(), getDownloadDir() ); path.Replace( GetGithubURL(), getDownloadDir() );
it->setPath( path ); it->setPath( path );
it->setPluginType( IO_MGR::KICAD ); it->setPluginType( IO_MGR::KICAD_SEXP );
} }
} }
} }
@ -654,7 +654,7 @@ bool WIZARD_FPLIB_TABLE::downloadGithubLibsFromList( wxArrayString& aUrlList,
try try
{ {
PLUGIN::RELEASER src( IO_MGR::PluginFind( IO_MGR::GITHUB ) ); PLUGIN::RELEASER src( IO_MGR::PluginFind( IO_MGR::GITHUB ) );
PLUGIN::RELEASER dst( IO_MGR::PluginFind( IO_MGR::KICAD ) ); PLUGIN::RELEASER dst( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
wxArrayString footprints; wxArrayString footprints;

View File

@ -96,7 +96,7 @@ bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName, bo
IO_MGR::PCB_FILE_T pluginType; IO_MGR::PCB_FILE_T pluginType;
} loaders[] = } loaders[] =
{ {
{ PcbFileWildcard, IO_MGR::KICAD }, // Current Kicad board files { PcbFileWildcard, IO_MGR::KICAD_SEXP }, // Current Kicad board files
{ LegacyPcbFileWildcard, IO_MGR::LEGACY }, // Old Kicad board files { LegacyPcbFileWildcard, IO_MGR::LEGACY }, // Old Kicad board files
{ EaglePcbFileWildcard, IO_MGR::EAGLE }, // Import board files { EaglePcbFileWildcard, IO_MGR::EAGLE }, // Import board files
{ PCadPcbFileWildcard, IO_MGR::PCAD }, // Import board files { PCadPcbFileWildcard, IO_MGR::PCAD }, // Import board files
@ -396,7 +396,7 @@ IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl )
} }
else else
{ {
pluginType = IO_MGR::KICAD; pluginType = IO_MGR::KICAD_SEXP;
} }
return pluginType; return pluginType;
@ -469,7 +469,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP;
if( !converted ) if( !converted )
{ {
@ -711,7 +711,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
try try
{ {
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
wxASSERT( pcbFileName.IsAbsolute() ); wxASSERT( pcbFileName.IsAbsolute() );
@ -790,7 +790,7 @@ bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName )
try try
{ {
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
wxASSERT( pcbFileName.IsAbsolute() ); wxASSERT( pcbFileName.IsAbsolute() );
@ -864,23 +864,32 @@ bool PCB_EDIT_FRAME::doAutoSave()
return false; return false;
} }
bool PCB_EDIT_FRAME::ImportFile( const wxString aFileName )
bool PCB_EDIT_FRAME::ImportFile( const wxString& aFileName, int aFileType )
{ {
if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), switch( (IO_MGR::PCB_FILE_T) aFileType )
KICTL_EAGLE_BRD ) )
{ {
wxString projectpath = Kiway().Prj().GetProjectPath(); case IO_MGR::EAGLE:
wxFileName newfilename = Prj().AbsolutePath( Prj().GetProjectName() ); if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
KICTL_EAGLE_BRD ) )
{
wxString projectpath = Kiway().Prj().GetProjectPath();
wxFileName newfilename = Prj().AbsolutePath( Prj().GetProjectName() );
newfilename.SetExt( KiCadPcbFileExtension ); newfilename.SetExt( KiCadPcbFileExtension );
GetBoard()->SetFileName( newfilename.GetFullPath() );
UpdateTitle();
GetBoard()->SetFileName( newfilename.GetFullPath() ); ArchiveModulesOnBoard( true, newfilename.GetName() );
UpdateTitle();
ArchiveModulesOnBoard( true, newfilename.GetName() ); return true;
}
return true; return false;
default:
return false;
} }
return false; return false;

View File

@ -65,7 +65,7 @@ PLUGIN* IO_MGR::PluginFind( PCB_FILE_T aFileType )
case LEGACY: case LEGACY:
return new LEGACY_PLUGIN(); return new LEGACY_PLUGIN();
case KICAD: case KICAD_SEXP:
return new PCB_IO(); return new PCB_IO();
case EAGLE: case EAGLE:
@ -116,7 +116,7 @@ const wxString IO_MGR::ShowType( PCB_FILE_T aType )
case LEGACY: case LEGACY:
return wxString( wxT( "Legacy" ) ); return wxString( wxT( "Legacy" ) );
case KICAD: case KICAD_SEXP:
return wxString( wxT( "KiCad" ) ); return wxString( wxT( "KiCad" ) );
case EAGLE: case EAGLE:
@ -141,7 +141,7 @@ IO_MGR::PCB_FILE_T IO_MGR::EnumFromStr( const wxString& aType )
// library tables, so don't do change, only additions are ok. // library tables, so don't do change, only additions are ok.
if( aType == wxT( "KiCad" ) ) if( aType == wxT( "KiCad" ) )
return KICAD; return KICAD_SEXP;
if( aType == wxT( "Legacy" ) ) if( aType == wxT( "Legacy" ) )
return LEGACY; return LEGACY;
@ -181,7 +181,7 @@ const wxString IO_MGR::GetFileExtension( PCB_FILE_T aFileType )
IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath ) IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath )
{ {
PCB_FILE_T ret = KICAD; // default guess, unless detected otherwise. PCB_FILE_T ret = KICAD_SEXP; // default guess, unless detected otherwise.
wxFileName fn( aLibPath ); wxFileName fn( aLibPath );
if( fn.GetExt() == LegacyFootprintLibPathExtension ) if( fn.GetExt() == LegacyFootprintLibPathExtension )
@ -209,7 +209,7 @@ IO_MGR::PCB_FILE_T IO_MGR::GuessPluginTypeFromLibPath( const wxString& aLibPath
else if( fn.GetExt() == KiCadFootprintLibPathExtension && else if( fn.GetExt() == KiCadFootprintLibPathExtension &&
!aLibPath.StartsWith( wxT( "http" ) ) ) !aLibPath.StartsWith( wxT( "http" ) ) )
{ {
ret = KICAD; ret = KICAD_SEXP;
} }
else else
{ {
@ -254,4 +254,3 @@ void IO_MGR::Save( PCB_FILE_T aFileType, const wxString& aFileName, BOARD* aBoar
THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) ); THROW_IO_ERROR( wxString::Format( FMT_NOTFOUND, ShowType( aFileType ).GetData() ) );
} }

View File

@ -51,7 +51,7 @@ public:
enum PCB_FILE_T enum PCB_FILE_T
{ {
LEGACY, ///< Legacy Pcbnew file formats prior to s-expression. LEGACY, ///< Legacy Pcbnew file formats prior to s-expression.
KICAD, ///< S-expression Pcbnew file format. KICAD_SEXP, ///< S-expression Pcbnew file format.
EAGLE, EAGLE,
PCAD, PCAD,
GEDA_PCB, ///< Geda PCB file formats. GEDA_PCB, ///< Geda PCB file formats.

View File

@ -144,7 +144,7 @@ static IO_MGR::PCB_FILE_T detect_file_type( FILE* aFile, const wxFileName& aFile
if( !strncasecmp( line, "(module", strlen( "(module" ) ) ) if( !strncasecmp( line, "(module", strlen( "(module" ) ) )
{ {
file_type = IO_MGR::KICAD; file_type = IO_MGR::KICAD_SEXP;
*aName = aFileName.GetName(); *aName = aFileName.GetName();
} }
else if( !strncasecmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) ) else if( !strncasecmp( line, FOOTPRINT_LIBRARY_HEADER, FOOTPRINT_LIBRARY_HEADER_CNT ) )
@ -240,7 +240,7 @@ MODULE* try_load_footprint( const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFil
module = parse_module_with_plugin( aFileName, aFileType, aName ); module = parse_module_with_plugin( aFileName, aFileType, aName );
break; break;
case IO_MGR::KICAD: case IO_MGR::KICAD_SEXP:
module = parse_module_kicad( aFileName ); module = parse_module_kicad( aFileName );
break; break;
@ -479,8 +479,8 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
} }
// We can save fp libs only using IO_MGR::KICAD format (.pretty libraries) // We can save fp libs only using IO_MGR::KICAD_SEXP format (.pretty libraries)
IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD; IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD_SEXP;
try try
{ {
@ -635,7 +635,7 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib, const wxString&
if( libPath.IsEmpty() ) // Aborted if( libPath.IsEmpty() ) // Aborted
return; return;
IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD; IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD_SEXP;
PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) );
for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() ) for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() )

View File

@ -60,7 +60,7 @@ void ScriptingSetPcbEditFrame( PCB_EDIT_FRAME* aPcbEditFrame )
BOARD* LoadBoard( wxString& aFileName ) BOARD* LoadBoard( wxString& aFileName )
{ {
if( aFileName.EndsWith( wxT( ".kicad_pcb" ) ) ) if( aFileName.EndsWith( wxT( ".kicad_pcb" ) ) )
return LoadBoard( aFileName, IO_MGR::KICAD ); return LoadBoard( aFileName, IO_MGR::KICAD_SEXP );
else if( aFileName.EndsWith( wxT( ".brd" ) ) ) else if( aFileName.EndsWith( wxT( ".brd" ) ) )
return LoadBoard( aFileName, IO_MGR::LEGACY ); return LoadBoard( aFileName, IO_MGR::LEGACY );
@ -95,7 +95,7 @@ bool SaveBoard( wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat )
bool SaveBoard( wxString& aFileName, BOARD* aBoard ) bool SaveBoard( wxString& aFileName, BOARD* aBoard )
{ {
return SaveBoard( aFileName, aBoard, IO_MGR::KICAD ); return SaveBoard( aFileName, aBoard, IO_MGR::KICAD_SEXP );
} }

View File

@ -866,9 +866,11 @@ public:
/** /**
* Function ImportFile * Function ImportFile
* import a board file and sets file path to current project path. * load the given filename but sets the path to the current project path.
* @param full filepath of file to be imported.
* @param aFileType PCB_FILE_T value for filetype
*/ */
bool ImportFile( const wxString aFileName) override; bool ImportFile( const wxString& aFileName, int aFileType ) override;
/** /**
* Function SavePcbFile * Function SavePcbFile