Kicad: Add Project import function. -- add menu entry -- add ImportFile kiway function -- expose functions for creating/reading netlist -- add example eagle boad file as well

This commit is contained in:
Russell Oliver 2017-08-25 01:56:15 +10:00 committed by Maciej Suminski
parent d260609e69
commit 433aa653fe
14 changed files with 3238 additions and 19 deletions

View File

@ -72,6 +72,7 @@ const wxString SchematicSymbolFileWildcard( _( "KiCad drawing symbol file (*.sym
const wxString SchematicLibraryFileWildcard( _( "KiCad component library file (*.lib)|*.lib" ) );
const wxString ProjectFileWildcard( _( "KiCad project files (*.pro)|*.pro" ) );
const wxString SchematicFileWildcard( _( "KiCad schematic files (*.sch)|*.sch|Eagle 6.x XML schematic file (*.sch)|*.sch" ) );
const wxString EagleSchematicFileWildcard( _( "Eagle XML schematic file (*.sch)|*.sch" ) );
const wxString NetlistFileWildcard( _( "KiCad netlist files (*.net)|*.net" ) );
const wxString GerberFileWildcard( _( "Gerber files (*.pho)|*.pho" ) );
const wxString LegacyPcbFileWildcard( _( "KiCad printed circuit board files (*.brd)|*.brd" ) );

View File

@ -48,6 +48,8 @@
#include <eeschema_config.h>
#include <sch_legacy_plugin.h>
#include <sch_eagle_plugin.h>
#include <schframe.h>
#include <netlist.h>
//#define USE_SCH_LEGACY_IO_PLUGIN
@ -620,3 +622,60 @@ bool SCH_EDIT_FRAME::doAutoSave()
return autoSaveOk;
}
bool SCH_EDIT_FRAME::ImportFile( const wxString 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;
pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) );
g_RootSheet = pi->Load( fullFileName, &Kiway() );
wxString projectpath = Kiway().Prj().GetProjectPath();
wxFileName newfilename( fullFileName );
newfilename.SetPath(projectpath);
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_SCREENS schematic;
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -13205,9 +13205,9 @@ Based on the following sources:&lt;p&gt;
<parts>
<part name="GND1" library="supply1" library_urn="urn:adsk.eagle:library:371" deviceset="GND" device=""/>
<part name="P+1" library="supply1" library_urn="urn:adsk.eagle:library:371" deviceset="+5V" device=""/>
<part name="R1" library="resistor" library_urn="urn:adsk.eagle:library:348" deviceset="R-US_" device="R0603"/>
<part name="L1" library="rcl" library_urn="urn:adsk.eagle:library:334" deviceset="L-US" device="L2012C"/>
<part name="C1" library="rcl" library_urn="urn:adsk.eagle:library:334" deviceset="CPOL-EU" device="085CS-1AR"/>
<part name="R1" library="resistor" library_urn="urn:adsk.eagle:library:348" deviceset="R-US_" device="R0603" value="10k"/>
<part name="L1" library="rcl" library_urn="urn:adsk.eagle:library:334" deviceset="L-US" device="L2012C" value="10mH"/>
<part name="C1" library="rcl" library_urn="urn:adsk.eagle:library:334" deviceset="CPOL-EU" device="085CS-1AR" value="1uF"/>
<part name="JP1" library="pinhead" library_urn="urn:adsk.eagle:library:325" deviceset="PINHD-1X3" device=""/>
<part name="JP2" library="pinhead" library_urn="urn:adsk.eagle:library:325" deviceset="PINHD-1X3" device=""/>
<part name="JP3" library="pinhead" library_urn="urn:adsk.eagle:library:325" deviceset="PINHD-1X3" device=""/>

View File

@ -36,6 +36,7 @@
#include <class_libentry.h>
#include <lib_draw_item.h>
#include <sch_component.h>
#include <sch_sheet_path.h>
#include <lib_arc.h>
#include <lib_circle.h>
#include <lib_rectangle.h>
@ -550,9 +551,10 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
sheet->SetScreen( screen );
m_currentSheet = sheet.get();
loadSheet( sheetNode, i);
sheet->GetScreen()->SetFileName( sheet->GetFileName() );
m_rootSheet->GetScreen()->Append( sheet.release() );
loadSheet( sheetNode, i);
sheetNode = sheetNode->GetNext();
x += 2;
@ -1040,7 +1042,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
std::string libraryname = epart->library;
std::string gatename = epart->deviceset + epart->device + einstance.gate;
wxString sntemp( epart->deviceset + epart->device );
wxString sntemp = wxString( epart->deviceset + epart->device );
sntemp.Replace("*", "");
std::string symbolname = sntemp.ToStdString();
@ -1060,6 +1062,8 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
LIB_PART* part = m_partlib->FindPart(symbolname);
if( !part ) return;
std::unique_ptr<SCH_COMPONENT> component( new SCH_COMPONENT() );
component->SetLibId( libId );
component->SetUnit( unit );
@ -1067,7 +1071,6 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
component->SetPosition( wxPoint( einstance.x * EUNIT_TO_MIL, -einstance.y * EUNIT_TO_MIL ) );
component->GetField( FOOTPRINT )->SetText( wxString( package ) );
component->SetTimeStamp( moduleTstamp( einstance.part, epart->value ? *epart->value : "", unit ) );
// component->AddHierarchicalReference( path, reference, (int)tmp ); // TODO ??
if( einstance.rot )
{
@ -1091,7 +1094,15 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
component->GetField( REFERENCE )->SetText( einstance.part );
SCH_SHEET_PATH sheetpath;
m_rootSheet->LocatePathOfScreen(screen, &sheetpath);
wxString current_sheetpath = sheetpath.Path();
wxString tstamp;
tstamp.Printf( "%8.8lX", (unsigned long)component->GetTimeStamp() );
current_sheetpath += tstamp;
component->AddHierarchicalReference( current_sheetpath, wxString(einstance.part), unit );
if( epart->value )
{
@ -1099,7 +1110,6 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
}
else
{
component->GetField( VALUE )->SetText( symbolname );
}
@ -1257,7 +1267,7 @@ EAGLE_LIBRARY* SCH_EAGLE_PLUGIN::loadLibrary( wxXmlNode* aLibraryNode, EAGLE_LIB
// Create symbol name from deviceset and device names.
wxString symbolName = wxString( edeviceset.name + edevice.name );
//std::cout << "edevice.name \""<< edevice.name << "\"\n";
//symbolName.Replace("*", "");
symbolName.Replace("*", "");
std::string symbolname = symbolName.ToStdString();
@ -1758,10 +1768,6 @@ LIB_PIN* SCH_EAGLE_PLUGIN::loadPin( std::unique_ptr< LIB_PART >& aPart, wxXmlNod
{
pin->SetShape(PINSHAPE_INVERTED);
}
else if( function == "dot")
{
pin->SetShape(PINSHAPE_CLOCK);
}
else if( function == "clk")
{
pin->SetShape(PINSHAPE_CLOCK);
@ -1809,6 +1815,8 @@ LIB_TEXT* SCH_EAGLE_PLUGIN::loadSymboltext( std::unique_ptr< LIB_PART >& aPart,
return libtext.release();
}
// convert text method.
wxSize SCH_EAGLE_PLUGIN::convertTextSize(ETEXT& etext ) {
wxSize textsize;

View File

@ -532,7 +532,7 @@ public:
bool CreateNetlist( int aFormat,
const wxString& aFullFileName,
unsigned aNetlistOptions,
REPORTER* aReporter = NULL );
REPORTER* aReporter = NULL ) override;
/**
* Function WriteNetListFile
@ -784,6 +784,7 @@ public:
bool IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria );
bool ImportFile( const wxString aFileName ) override ;
private:

View File

@ -179,6 +179,47 @@ public:
return false;
}
/**
* Function OpenProjectFiles
* load the given filename but sets the path to the current project path.
*/
VTBL_ENTRY bool ImportFile( const wxString aFileName)
{
// overload me for your wxFrame type.
return false;
}
/**
* Function ReadPcbNetlist
* provides access to PcbNew's function.
*/
VTBL_ENTRY void ReadPcbNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName,
REPORTER* aReporter,
bool aChangeFootprint,
bool aDeleteBadTracks,
bool aDeleteExtraFootprints,
bool aSelectByTimestamp,
bool aDeleteSinglePadNets,
bool aIsDryRun )
{
};
/**
* Function ReadPcbNetlist
* provides access to Eeschema's function.
*/
VTBL_ENTRY bool CreateNetlist( int aFormat,
const wxString& aFullFileName,
unsigned aNetlistOptions,
REPORTER* aReporter = NULL )
{
return false;
};
/**
* Function ShowModal
* puts up this wxFrame as if it were a modal dialog, with all other instantiated

View File

@ -88,6 +88,7 @@ extern const wxString CsvFileWildcard;
extern const wxString LegacyPcbFileWildcard;
extern const wxString PcbFileWildcard;
extern const wxString EaglePcbFileWildcard;
extern const wxString EagleSchematicFileWildcard;
extern const wxString PCadPcbFileWildcard;
extern const wxString PdfFileWildcard;
extern const wxString PSFileWildcard;

View File

@ -7,6 +7,8 @@ add_definitions( -DKICAD )
include_directories( BEFORE ${INC_BEFORE} )
include_directories(
../pcbnew
../eeschema
${INC_AFTER}
)
@ -25,6 +27,7 @@ set( KICAD_SRCS
prjconfig.cpp
project_template.cpp
tree_project_frame.cpp
import_project.cpp
)
if( MINGW )

201
kicad/import_project.cpp Normal file
View File

@ -0,0 +1,201 @@
/*
* 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) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file eagle_project.cpp
* @brief routines for importing an eagle project
*/
#include <wx/filename.h>
#include <wx/dir.h>
#include <wx/log.h>
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <common.h>
#include <confirm.h>
#include <hotkeys_basic.h>
#include <kiway.h>
#include <richio.h>
#include <wildcards_and_files_ext.h>
#include <systemdirsappend.h>
#include <kiway_player.h>
#include <stdexcept>
#include "pgm_kicad.h"
#include <wxPcbStruct.h>
#include <schframe.h>
#include <netlist.h>
class PCB_EDIT_FRAME;
#include "kicad.h"
void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
{
// Close other windows.
if( !Kiway.PlayersClose( false ) )
return;
wxString title = _( "Import Eagle Project Files" );
int style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
wxString default_dir = GetMruPath();
ClearMsg();
wxFileDialog schdlg( this, title, default_dir, wxEmptyString,
EagleSchematicFileWildcard, style );
if( schdlg.ShowModal() == wxID_CANCEL )
return;
wxFileName sch( schdlg.GetPath() );
wxString protitle = _( "Kicad Project Destination" );
wxFileDialog prodlg( this, protitle, default_dir, wxEmptyString,
ProjectFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( prodlg.ShowModal() == wxID_CANCEL )
return;
wxFileName pro( prodlg.GetPath() );
// Check if the project directory is empty
wxDir directory( pro.GetPath() );
if( directory.HasFiles() )
{
wxString msg = _( "The selected directory is not empty. We recommend you "
"create projects in their own clean directory.\n\nDo you "
"want to create a new empty directory for the project?" );
if( IsOK( this, msg ) )
{
// Append a new directory with the same name of the project file
// and try to create it
pro.AppendDir( pro.GetName() );
if( !wxMkdir( pro.GetPath() ) )
// There was a problem, undo
pro.RemoveLastDir();
}
}
wxFileName pcb( sch );
wxFileName netlist( pro );
pro.SetExt( ProjectFileExtension ); // enforce extension
pcb.SetExt( LegacyPcbFileExtension ); // enforce extension
netlist.SetExt( NetlistFileExtension );
if( !pro.IsAbsolute() )
pro.MakeAbsolute();
SetProjectFileName( pro.GetFullPath() );
wxString prj_filename = GetProjectFileName();
wxString sch_filename = sch.GetFullPath();
SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) Kiway.Player( FRAME_SCH, false );
if( !schframe )
{
try
{
schframe = (SCH_EDIT_FRAME*) Kiway.Player( FRAME_SCH, true );
}
catch( IO_ERROR err )
{
wxMessageBox( _( "Eeschema failed to load:\n" ) + err.What(),
_( "KiCad Error" ), wxOK | wxICON_ERROR, this );
return;
}
}
schframe->ImportFile( sch_filename );
if( !schframe->IsShown() ) // the frame exists, (created by the dialog field editor)
// but no project loaded.
{
schframe->Show( true );
}
if( schframe->IsIconized() )
schframe->Iconize( false );
schframe->Raise();
// Calculate the netlist filename
wxString nestlistFileFullpath = netlist.GetFullPath();
schframe->CreateNetlist( NET_TYPE_PCBNEW, nestlistFileFullpath, 0 );
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway.Player( FRAME_PCB, false );
if( !pcbframe )
{
try
{
pcbframe = (PCB_EDIT_FRAME*) Kiway.Player( FRAME_PCB, true );
}
catch( IO_ERROR err )
{
wxMessageBox( _( "Pcbnew failed to load:\n" ) + err.What(), _( "KiCad Error" ),
wxOK | wxICON_ERROR, this );
return;
}
}
// a pcb frame can be already existing, but not yet used.
// this is the case when running the footprint editor, or the footprint viewer first
// if the frame is not visible, the board is not yet loaded
if( !pcbframe->IsVisible() )
{
pcbframe->ImportFile( pcb.GetFullPath() );
pcbframe->Show( true );
}
// On Windows, Raise() does not bring the window on screen, when iconized
if( pcbframe->IsIconized() )
pcbframe->Iconize( false );
pcbframe->Raise();
pcbframe->ReadPcbNetlist( nestlistFileFullpath,
wxEmptyString,
NULL,
false,
false,
false,
false,
false,
false );
ReCreateTreePrj();
}

View File

@ -123,6 +123,7 @@ enum id_kicad_frm {
ID_SAVE_AND_ZIP_FILES,
ID_READ_ZIP_ARCHIVE,
ID_INIT_WATCHED_PATHS,
ID_IMPORT_EAGLE_PROJECT,
// Please, verify: the number of items in this list should be
// less than ROOM_FOR_KICADMANAGER (see id.h)
@ -194,6 +195,8 @@ public:
void ReCreateMenuBar() override;
void RecreateBaseHToolbar();
void OnImportEagleFiles( wxCommandEvent& event );
/**
* Displays \a aText in the text panel.
*

View File

@ -66,6 +66,7 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
EVT_MENU( wxID_INDEX, KICAD_MANAGER_FRAME::GetKicadHelp )
EVT_MENU( ID_HELP_GET_INVOLVED, KICAD_MANAGER_FRAME::GetKicadContribute )
EVT_MENU( wxID_ABOUT, KICAD_MANAGER_FRAME::GetKicadAbout )
EVT_MENU( ID_IMPORT_EAGLE_PROJECT, KICAD_MANAGER_FRAME::OnImportEagleFiles )
// Range menu events
EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END,
@ -265,7 +266,21 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
KiBitmap( save_project_xpm ) );
#endif
// Separator
fileMenu->AppendSeparator();
wxMenu* importprjSubMenu = new wxMenu();
AddMenuItem( importprjSubMenu, ID_IMPORT_EAGLE_PROJECT, _( "Eagle CAD" ),
_( "Import Eagle CAD XML schematic and board" ),
KiBitmap( new_project_xpm ) );
AddMenuItem( fileMenu, importprjSubMenu,
wxID_ANY,
_( "Import Project" ),
_( "Import project files from other software" ),
KiBitmap( new_project_xpm ) );
fileMenu->AppendSeparator();
// Archive

View File

@ -42,6 +42,8 @@
#include <msgpanel.h>
#include <fp_lib_table.h>
#include <ratsnest_data.h>
#include <kiway.h>
#include <kiway_player.h>
#include <pcbnew.h>
#include <pcbnew_id.h>
@ -861,3 +863,22 @@ bool PCB_EDIT_FRAME::doAutoSave()
return false;
}
bool PCB_EDIT_FRAME::ImportFile( const wxString aFileName )
{
if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ),
KICTL_EAGLE_BRD ) )
{
wxString projectpath = Kiway().Prj().GetProjectPath();
wxFileName newfilename( aFileName );
newfilename.SetPath( projectpath );
GetBoard()->SetFileName( newfilename.GetFullPath() );
UpdateTitle();
return true;
}
return false;
}

View File

@ -30,10 +30,10 @@
#define WXPCB_STRUCT_H_
#include <pcb_base_edit_frame.h>
#include <config_params.h>
#include <class_undoredo_container.h>
#include <zones.h>
#include "pcb_base_edit_frame.h"
#include "config_params.h"
#include "class_undoredo_container.h"
#include "zones.h"
/* Forward declarations of classes. */
@ -864,6 +864,12 @@ public:
*/
bool AppendBoardFile( const wxString& aFullFileName, int aCtl );
/**
* Function ImportFile
* import a board file and sets file path to current project path.
*/
bool ImportFile( const wxString aFileName) override;
/**
* Function SavePcbFile
* writes the board data structures to \a a aFileName
@ -1546,7 +1552,7 @@ public:
bool aDeleteExtraFootprints,
bool aSelectByTimestamp,
bool aDeleteSinglePadNets,
bool aIsDryRun );
bool aIsDryRun ) override;
/**
* Function RemoveMisConnectedTracks