Commit c9be8bfd authored by Wayne Stambaugh's avatar Wayne Stambaugh

Pcbnew footprint library table work in progress.

* Add code for loading, modifying, and saving the global and project
  footprint library tables.
* Add code to load MODULE objects using the footprint library table to
  the footprint viewer.
* Add static methods to FP_LIB_TABLE to support loading footprint library
  tables.
parent 6b0980d9
......@@ -25,11 +25,11 @@
#include <wx/config.h> // wxExpandEnvVars()
#include <wx/filename.h>
#include <wx/stdpaths.h>
#include <set>
#include <io_mgr.h>
#include <fp_lib_table_lexer.h>
#include <fp_lib_table.h>
......@@ -302,7 +302,7 @@ PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
}
const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString )
const wxString FP_LIB_TABLE::ExpandSubstitutions( const wxString aString )
{
// We reserve the right to do this another way, by providing our own member
// function.
......@@ -310,6 +310,48 @@ const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString )
}
void FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR )
{
wxFileName fn = GetGlobalTableFileName();
wxLogDebug( wxT( "Loading global footprint table file: %s" ), GetChars( fn.GetFullPath() ) );
if( !fn.FileExists() )
{
/// @todo call some script to create initial global footprint table.
}
else
{
FILE_LINE_READER reader( fn.GetFullPath() );
FP_LIB_TABLE_LEXER lexer( &reader );
aTable.Parse( &lexer );
}
}
wxString FP_LIB_TABLE::GetGlobalTableFileName()
{
wxFileName fn;
fn.SetPath( wxStandardPaths::Get().GetUserConfigDir() );
#if defined( __WINDOWS__ )
fn.AppendDir( wxT( "kicad" ) );
#endif
fn.SetName( GetFileName() );
return fn.GetFullPath();
}
wxString FP_LIB_TABLE::GetFileName()
{
return wxString( wxT( ".fp-lib-table" ) );
}
#if 0 // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
throw( IO_ERROR )
......
......@@ -59,7 +59,6 @@ class wxHtmlHelpController;
*/
class EDA_APP : public wxApp
{
protected:
/// Used mainly to handle default paths libs m_Id = APP_EESCHEMA_T, APP_PCBNEW_T ...
EDA_APP_T m_Id;
......@@ -416,6 +415,7 @@ public:
bool LockFile( const wxString& fileName );
};
/*
* Use wxGetApp() to access EDA_APP. It is not necessary to keep copies
* of the application pointer all over the place or worse yet in a global
......
......@@ -105,7 +105,7 @@ public:
}
ROW( const wxString& aNick, const wxString& aURI, const wxString& aType,
const wxString& aOptions, const wxString& aDescr = wxEmptyString ) :
const wxString& aOptions, const wxString& aDescr = wxEmptyString ) :
nickName( aNick ),
uri( aURI ),
options( aOptions ),
......@@ -355,6 +355,11 @@ public:
*/
const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
/**
* Function IsEmpty
* @return true if the footprint library table is empty.
*/
bool IsEmpty() const { return rows.empty(); }
/**
* Function ExpandEnvSubsitutions
......@@ -363,13 +368,31 @@ public:
* This enables (fp_lib_table)s to have platform dependent environment
* variables in them, allowing for a uniform table across platforms.
*/
static const wxString ExpandSubtitutions( const wxString aString );
static const wxString ExpandSubstitutions( const wxString aString );
/**
* Function IsEmpty
* @return true if the footprint library table is empty.
* Function LoadGlobalTable
* loads the global footprint library table into \a aTable.
*
* This probably should be move into the application object when KiCad is changed
* to a single process application. This is the least painful solution for the
* time being.
*
* @param aTable the #FP_LIB_TABLE object to load.
*/
bool IsEmpty() const { return rows.empty(); }
static void LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR );
/**
* Function GetGlobalTableFileName
* @return the platform specific global footprint library path and file name.
*/
static wxString GetGlobalTableFileName();
/**
* Function GetFootprintTableFileName
* @return the footprint library file name.
*/
static wxString GetFileName();
protected:
......
......@@ -102,7 +102,7 @@ public:
* Function GetFootprintName
* returns the footprint name, i.e. footprintName.
*/
const std::string& GetFootprintName() const;
const std::string& GetFootprintName() const { return footprint; }
/**
* Function SetFootprintName
......
......@@ -54,6 +54,8 @@ class GENERAL_COLLECTORS_GUIDE;
class BOARD_DESIGN_SETTINGS;
class ZONE_SETTINGS;
class PCB_PLOT_PARAMS;
class FP_LIB_TABLE;
class FPID;
/**
......@@ -83,9 +85,14 @@ protected:
BOARD* m_Pcb;
GENERAL_COLLECTOR* m_Collector;
/// The project footprint library table. This is a combination of the project
/// footprint library table and the global footprint table. This is the one to
/// use when finding a #MODULE.
FP_LIB_TABLE* m_footprintLibTable;
/// Auxiliary tool bar typically shown below the main tool bar at the top of the
/// main window.
wxAuiToolBar* m_auxiliaryToolBar;
wxAuiToolBar* m_auxiliaryToolBar;
void updateGridSelectBox();
void updateZoomSelectBox();
......@@ -93,15 +100,15 @@ protected:
/**
* Function loadFootprint
* attempts to load \a aFootprintName from the list of libraries.
* attempts to load \a aFootprintId from the footprint library table.
*
* @param aFootprintName is the name of component footprint to load.
* @return the #MODULE if found or NULL if \a aFootprintName not found in any of the
* libraries.
* @param aFootprintId is the #FPID of component footprint to load.
* @return the #MODULE if found or NULL if \a aFootprintId not found in any of the
* libraries in #m_footprintLibTable.
* @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
* occurs while reading footprint library files.
*/
MODULE* loadFootprint( const wxString& aFootprintName )
MODULE* loadFootprint( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR );
public:
......@@ -442,27 +449,31 @@ public:
* @param aKeyWord = keyword list, to display a filtered list of module
* having one (or more) of these keywords in their
* keyword list ( aKeyWord = wxEmptyString if not used )
* @param aTable is the #FP_LIB_TABLE to search.
*
* @return wxEmptyString if abort or fails, or the selected module name if Ok
*/
wxString SelectFootprint( EDA_DRAW_FRAME* aWindow,
const wxString& aLibraryFullFilename,
const wxString& aMask,
const wxString& aKeyWord );
const wxString& aKeyWord,
FP_LIB_TABLE* aTable );
/**
* Function Load_Module_From_Library
* Function LoadModuleFromLibrary
* opens a dialog to select a footprint, and loads it into current board.
*
* @param aLibrary = the library name to use, or empty string to search
* in all loaded libraries
* @param aTable is the #FP_LIB_TABLE containing the avaiable footprint libraries.
* @param aUseFootprintViewer = true to show the option
* allowing the footprint selection by the footprint viewer
* @param aDC (can be NULL ) = the current Device Context, to draw the new footprint
*/
MODULE* Load_Module_From_Library( const wxString& aLibrary,
bool aUseFootprintViewer = true,
wxDC* aDC = NULL );
MODULE* LoadModuleFromLibrary( const wxString& aLibrary,
FP_LIB_TABLE* aTable,
bool aUseFootprintViewer = true,
wxDC* aDC = NULL );
/**
* SelectFootprintFromLibBrowser
......@@ -471,6 +482,14 @@ public:
*/
wxString SelectFootprintFromLibBrowser( void );
/**
* Function GetFootprintLibraryTable
* @return the project #FP_LIB_TABLE so programs can find footprints.
*/
FP_LIB_TABLE* GetFootprintLibraryTable() { return m_footprintLibTable; }
void SetFootprintLibraryTable( FP_LIB_TABLE* aTable ) { m_footprintLibTable = aTable; }
// ratsnest functions
/**
* Function Compile_Ratsnest
......
......@@ -63,6 +63,7 @@ class NETLIST;
class REPORTER;
class PARSE_ERROR;
class IO_ERROR;
class FP_LIB_TABLE;
/**
......@@ -84,6 +85,9 @@ class PCB_EDIT_FRAME : public PCB_BASE_FRAME
/// The auxiliary right vertical tool bar used to access the microwave tools.
wxAuiToolBar* m_microWaveToolBar;
/// The global footprint library table.
FP_LIB_TABLE* m_globalFootprintTable;
/**
* Function loadFootprints
* loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
......@@ -198,6 +202,12 @@ protected:
*/
void duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone );
/**
* Function loadFootprintLibTable
* deletes the existing #FP_LIB_TABLE and creates a new one when a new project is loaded.
*/
void loadFootprintLibTable();
public:
PCB_LAYER_BOX_SELECTOR* m_SelLayerBox; // a combo box to display and select active layer
wxComboBox* m_SelTrackWidthBox; // a combo box to display and select current track width
......@@ -1659,12 +1669,11 @@ public:
*/
void UpdateTitle();
DECLARE_EVENT_TABLE()
};
class FP_LIB_TABLE;
/**
* Function InvokePcbLibTableEditor
* shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables.
......
......@@ -218,7 +218,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer();
if( viewer == NULL )
{
viewer = new FOOTPRINT_VIEWER_FRAME( this, NULL );
viewer = new FOOTPRINT_VIEWER_FRAME( this, m_footprintLibTable, NULL );
viewer->Show( true );
viewer->Zoom_Automatique( false );
}
......
......@@ -463,9 +463,11 @@ wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary()
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
{
wxString libPath = getLibPath();
wxString footprintName = PCB_BASE_FRAME::SelectFootprint( this, libPath,
wxEmptyString, wxEmptyString );
PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) GetParent();
wxString libPath = getLibPath();
wxString footprintName = PCB_BASE_FRAME::SelectFootprint( this, libPath,
wxEmptyString, wxEmptyString,
parent->GetFootprintLibraryTable() );
if( !footprintName )
return false;
......
......@@ -40,6 +40,8 @@
#include <gr_basic.h>
#include <macros.h>
#include <pcbcommon.h>
#include <fp_lib_table.h>
#include <fpid.h>
#include <class_board.h>
#include <class_module.h>
......@@ -123,8 +125,8 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser( void )
if( viewer )
viewer->Destroy();
viewer = new FOOTPRINT_VIEWER_FRAME( this, &semaphore,
KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT );
viewer = new FOOTPRINT_VIEWER_FRAME( this, m_footprintLibTable, &semaphore,
KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT );
// Show the library viewer frame until it is closed
while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event
......@@ -147,9 +149,10 @@ wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser( void )
}
MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
bool aUseFootprintViewer,
wxDC* aDC )
MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
FP_LIB_TABLE* aTable,
bool aUseFootprintViewer,
wxDC* aDC )
{
MODULE* module;
wxPoint curspos = GetScreen()->GetCrossHairPosition();
......@@ -195,7 +198,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
{
allowWildSeach = false;
keys = moduleName;
moduleName = SelectFootprint( this, libName, wxEmptyString, keys );
moduleName = SelectFootprint( this, libName, wxEmptyString, keys, aTable );
if( moduleName.IsEmpty() ) // Cancel command
{
......@@ -207,7 +210,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
|| moduleName.Contains( wxT( "*" ) ) ) // Selection wild card
{
allowWildSeach = false;
moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString );
moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );
if( moduleName.IsEmpty() )
{
......@@ -225,7 +228,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& aLibrary,
wxString wildname = wxChar( '*' ) + moduleName + wxChar( '*' );
moduleName = wildname;
moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString );
moduleName = SelectFootprint( this, libName, moduleName, wxEmptyString, aTable );
if( moduleName.IsEmpty() )
{
......@@ -390,38 +393,40 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
}
MODULE* PCB_BASE_FRAME::loadFootprint( const wxString& aFootprintName )
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
throw( IO_ERROR, PARSE_ERROR )
{
wxString libPath;
wxFileName fn;
MODULE* footprint;
wxCHECK_MSG( m_footprintLibTable != NULL, NULL,
wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) );
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
wxString libName = FROM_UTF8( aFootprintId.GetLibNickname().c_str() );
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
{
fn = wxFileName( wxEmptyString, g_LibraryNames[ii], LegacyFootprintLibPathExtension );
const FP_LIB_TABLE::ROW* row = m_footprintLibTable->FindRow( libName );
libPath = wxGetApp().FindLibraryPath( fn );
if( row == NULL )
{
wxString msg;
msg.Printf( _( "No library named <%s> was found in the footprint library table." ),
aFootprintId.GetLibNickname().c_str() );
THROW_IO_ERROR( msg );
}
if( !libPath )
continue;
wxString footprintName = FROM_UTF8( aFootprintId.GetFootprintName().c_str() );
wxString libPath = row->GetFullURI();
footprint = pi->FootprintLoad( libPath, aFootprintName );
libPath = FP_LIB_TABLE::ExpandSubstitutions( libPath );
if( footprint )
return footprint;
}
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::EnumFromStr( row->GetType() ) ) );
return NULL;
return pi->FootprintLoad( libPath, footprintName );
}
wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
const wxString& aLibraryFullFilename,
const wxString& aMask,
const wxString& aKeyWord )
const wxString& aKeyWord,
FP_LIB_TABLE* aTable )
{
static wxString OldName; // Save the name of the last module loaded.
wxString CmpName;
......@@ -431,9 +436,26 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
if( aLibraryFullFilename.IsEmpty() )
{
#if !defined( USE_FP_LIB_TABLE )
libraries = g_LibraryNames;
#else
wxASSERT( aTable != NULL );
std::vector< wxString > libNames = aTable->GetLogicalLibs();
for( unsigned i = 0; i < libNames.size(); i++ )
{
wxString uri = aTable->FindRow( libNames[i] )->GetFullURI();
uri = FP_LIB_TABLE::ExpandSubstitutions( uri );
libraries.Add( uri );
}
#endif
}
else
{
libraries.Add( aLibraryFullFilename );
}
if( libraries.IsEmpty() )
{
......
......@@ -234,9 +234,10 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_OPEN_MODULE_VIEWER:
{
FOOTPRINT_VIEWER_FRAME * viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer();
if( viewer == NULL )
{
viewer = new FOOTPRINT_VIEWER_FRAME( this, NULL );
viewer = new FOOTPRINT_VIEWER_FRAME( this, m_footprintLibTable, NULL );
viewer->Show( true );
viewer->Zoom_Automatique( false );
}
......@@ -459,6 +460,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_LOAD_MODULE:
{
PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) GetParent();
wxString libPath = getLibPath(); // might be empty
wxLogDebug( wxT( "Loading module from library " ) + libPath );
......@@ -467,7 +469,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
SetCurItem( NULL );
Clear_Pcb( true );
GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
Load_Module_From_Library( libPath, true );
LoadModuleFromLibrary( libPath, parent->GetFootprintLibraryTable(), true );
redraw = true;
}
......
......@@ -143,9 +143,11 @@ void FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary( wxCommandEvent& event )
void FOOTPRINT_VIEWER_FRAME::SelectCurrentFootprint( wxCommandEvent& event )
{
wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension;
MODULE* oldmodule = GetBoard()->m_Modules;
MODULE * module = Load_Module_From_Library( libname, false );
PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) GetParent();
wxString libname = m_libraryName + wxT( "." ) + LegacyFootprintLibPathExtension;
MODULE* oldmodule = GetBoard()->m_Modules;
MODULE* module = LoadModuleFromLibrary( libname, parent->GetFootprintLibraryTable(),
false );
if( module )
{
......
......@@ -35,6 +35,9 @@
#include <pcbcommon.h>
#include <msgpanel.h>
#include <macros.h>
#include <fp_lib_table.h>
#include <fpid.h>
#include <confirm.h>
#include <class_board.h>
#include <class_module.h>
......@@ -113,13 +116,18 @@ static wxAcceleratorEntry accels[] =
#define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" )
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
wxSemaphore* semaphore, long style ) :
PCB_BASE_FRAME( parent, MODULE_VIEWER_FRAME_TYPE, _( "Footprint Library Browser" ),
wxDefaultPosition, wxDefaultSize, style, GetFootprintViewerFrameName() )
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* aParent,
FP_LIB_TABLE* aTable,
wxSemaphore* aSemaphore,
long aStyle ) :
PCB_BASE_FRAME( aParent, MODULE_VIEWER_FRAME_TYPE, _( "Footprint Library Browser" ),
wxDefaultPosition, wxDefaultSize, aStyle, GetFootprintViewerFrameName() )
{
wxASSERT( aTable != NULL );
wxAcceleratorTable table( ACCEL_TABLE_CNT, accels );
m_footprintLibTable = aTable;
m_FrameName = GetFootprintViewerFrameName();
m_configPath = wxT( "FootprintViewer" );
m_showAxis = true; // true to draw axis.
......@@ -134,11 +142,11 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
m_LibList = NULL;
m_LibListWindow = NULL;
m_FootprintListWindow = NULL;
m_Semaphore = semaphore;
m_Semaphore = aSemaphore;
m_selectedFootprintName.Empty();
if( m_Semaphore )
SetModalMode(true);
SetModalMode( true );
SetBoard( new BOARD() );
// Ensure all layers and items are visible:
......@@ -177,16 +185,16 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
m_FootprintListSize.y = size.y;
win_pos.x = m_LibListSize.x;
m_FootprintListWindow = new wxSashLayoutWindow( this, ID_MODVIEW_FOOTPRINT_WINDOW,
win_pos, wxDefaultSize,
wxCLIP_CHILDREN | wxSW_3D,
wxT( "CmpWindow" ) );
win_pos, wxDefaultSize,
wxCLIP_CHILDREN | wxSW_3D,
wxT( "CmpWindow" ) );
m_FootprintListWindow->SetOrientation( wxLAYOUT_VERTICAL );
m_FootprintListWindow->SetSashVisible( wxSASH_RIGHT, true );
m_FootprintListWindow->SetExtraBorderSize( EXTRA_BORDER_SIZE );
m_FootprintList = new wxListBox( m_FootprintListWindow, ID_MODVIEW_FOOTPRINT_LIST,
wxPoint( 0, 0 ), wxDefaultSize,
0, NULL, wxLB_HSCROLL );
wxPoint( 0, 0 ), wxDefaultSize,
0, NULL, wxLB_HSCROLL );
ReCreateLibraryList();
......@@ -194,8 +202,17 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
// If a footprint was previsiously loaded, reload it
if( !m_libraryName.IsEmpty() && !m_footprintName.IsEmpty() )
{
#if !defined( USE_FP_LIB_TABLE )
GetModuleLibrary( m_libraryName + wxT(".") + LegacyFootprintLibPathExtension,
m_footprintName, false );
m_footprintName, false );
#else
FPID id;
id.SetLibNickname( TO_UTF8( m_libraryName ) );
id.SetFootprintName( TO_UTF8( m_footprintName ) );
GetBoard()->Add( loadFootprint( id ) );
#endif
}
if( m_canvas )
......@@ -239,18 +256,19 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent,
// Manage the message panel
m_auimgr.AddPane( m_messagePanel,
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer( 10 ) );
/* Now the minimum windows are fixed, set library list
* and component list of the previous values from last viewlib use
*/
if( m_LibListWindow )
{
wxAuiPaneInfo& pane = m_auimgr.GetPane(m_LibListWindow);
pane.MinSize( wxSize(m_LibListSize.x, -1));
wxAuiPaneInfo& pane = m_auimgr.GetPane( m_LibListWindow );
pane.MinSize( wxSize( m_LibListSize.x, -1 ) );
}
wxAuiPaneInfo& pane = m_auimgr.GetPane(m_FootprintListWindow);
pane.MinSize(wxSize(m_FootprintListSize.x, -1));
wxAuiPaneInfo& pane = m_auimgr.GetPane( m_FootprintListWindow );
pane.MinSize( wxSize( m_FootprintListSize.x, -1 ) );
m_auimgr.Update();
......@@ -296,7 +314,7 @@ void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event )
if( m_Semaphore )
{
m_Semaphore->Post();
SetModalMode(false);
SetModalMode( false );
// This window will be destroyed by the calling function,
// to avoid side effects
}
......@@ -359,10 +377,18 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
return;
m_LibList->Clear();
#if !defined( USE_FP_LIB_TABLE )
for( unsigned ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
{
m_LibList->Append( g_LibraryNames[ii] );
}
#else
std::vector< wxString > libName = m_footprintLibTable->GetLogicalLibs();
for( unsigned ii = 0; ii < libName.size(); ii++ )
m_LibList->Append( libName[ii] );
#endif
// Search for a previous selection:
int index = m_LibList->FindString( m_libraryName );
......@@ -400,7 +426,21 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
}
wxArrayString libsList;
#if !defined( USE_FP_LIB_TABLE )
libsList.Add( m_libraryName );
#else
wxString uri = m_footprintLibTable->FindRow( m_libraryName )->GetFullURI();
if( uri.IsEmpty() )
return;
uri = FP_LIB_TABLE::ExpandSubstitutions( uri );
wxLogDebug( wxT( "Footprint library <%s> selected." ), GetChars( uri ) );
libsList.Add( uri );
#endif
FOOTPRINT_LIST fp_info_list;
fp_info_list.ReadFootprintFiles( libsList );
......@@ -455,8 +495,28 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
SetCurItem( NULL );
// Delete the current footprint
GetBoard()->m_Modules.DeleteAll();
#if !defined( USE_FP_LIB_TABLE )
GetModuleLibrary( m_libraryName + wxT(".") + LegacyFootprintLibPathExtension,
m_footprintName, true );
#else
FPID id;
id.SetLibNickname( TO_UTF8( m_libraryName ) );
id.SetFootprintName( TO_UTF8( m_footprintName ) );
try
{
GetBoard()->Add( loadFootprint( id ) );
}
catch( IO_ERROR ioe )
{
wxString msg;
msg.Printf( _( "Could not load footprint \"%s\" from library \"%s\".\n\n"
"Error %s." ), GetChars( m_footprintName ), GetChars( m_libraryName ),
GetChars( ioe.errorText ) );
DisplayError( this, msg );
}
#endif
DisplayLibInfos();
Zoom_Automatique( false );
m_canvas->Refresh();
......@@ -464,6 +524,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
}
}
void FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList( wxCommandEvent& event )
{
if( m_Semaphore )
......@@ -478,6 +539,7 @@ void FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList( wxCommandEvent& event )
}
}
void FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint( wxCommandEvent& event )
{
int ii = m_FootprintList->GetSelection();
......@@ -549,11 +611,13 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
if( g_LibraryNames.GetCount() == m_LibList->GetCount() )
{
unsigned ii;
for( ii = 0; ii < g_LibraryNames.GetCount(); ii++ )
{
if( m_LibList->GetString(ii) != g_LibraryNames[ii] )
break;
}
if( ii == g_LibraryNames.GetCount() )
return;
}
......@@ -677,11 +741,7 @@ void FOOTPRINT_VIEWER_FRAME::Show3D_Frame( wxCommandEvent& event )
m_Draw3DFrame->Show( true );
}
/**
* Function Update3D_Frame
* must be called after a footprint selection
* Updates the 3D view and 3D frame title.
*/
void FOOTPRINT_VIEWER_FRAME::Update3D_Frame( bool aForceReloadFootprint )
{
if( m_Draw3DFrame == NULL )
......@@ -694,14 +754,15 @@ void FOOTPRINT_VIEWER_FRAME::Update3D_Frame( bool aForceReloadFootprint )
if( aForceReloadFootprint )
{
m_Draw3DFrame->ReloadRequest();
// Force 3D screen refresh immediately
if( GetBoard()->m_Modules )
m_Draw3DFrame->NewDisplay();
}
}
EDA_COLOR_T FOOTPRINT_VIEWER_FRAME::GetGridColor() const
{
return g_ColorsSettings.GetItemColor( GRID_VISIBLE );
}
......@@ -35,6 +35,7 @@
class wxSashLayoutWindow;
class wxListBox;
class wxSemaphore;
class FP_LIB_TABLE;
/**
......@@ -64,8 +65,9 @@ protected:
// the selected footprint is here
public:
FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* parent, wxSemaphore* semaphore = NULL,
long style = KICAD_DEFAULT_DRAWFRAME_STYLE );
FOOTPRINT_VIEWER_FRAME( PCB_BASE_FRAME* aParent, FP_LIB_TABLE* aTable,
wxSemaphore* aSemaphore = NULL,
long aStyle = KICAD_DEFAULT_DRAWFRAME_STYLE );
~FOOTPRINT_VIEWER_FRAME();
......
......@@ -347,7 +347,8 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) )
{
m_canvas->MoveCursorToCrossHair();
DrawStruct = (BOARD_ITEM*) Load_Module_From_Library( wxEmptyString, true, aDC );
DrawStruct = (BOARD_ITEM*) LoadModuleFromLibrary( wxEmptyString, m_footprintLibTable,
true, aDC );
SetCurItem( DrawStruct );
if( DrawStruct )
......
......@@ -40,6 +40,7 @@
#include <macros.h>
#include <3d_viewer.h>
#include <msgpanel.h>
#include <fp_lib_table.h>
#include <pcbnew.h>
#include <protos.h>
......@@ -56,6 +57,7 @@
#include <dialog_plot.h>
#include <convert_from_iu.h>
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
#include <python_scripting.h>
#endif
......@@ -291,9 +293,13 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
m_RecordingMacros = -1;
m_microWaveToolBar = NULL;
m_useCmpFileForFpNames = true;
m_footprintLibTable = NULL;
m_globalFootprintTable = NULL;
#ifdef KICAD_SCRIPTING_WXPYTHON
m_pythonPanel = NULL;
#endif
for ( int i = 0; i < 10; i++ )
m_Macros[i].m_Record.clear();
......@@ -424,7 +430,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( wxWindow* parent, const wxString& title,
m_pythonPanel = CreatePythonShellWindow( this );
m_auimgr.AddPane( m_pythonPanel,
pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) );
pythonAuiInfo.Name( wxT( "PythonPanel" ) ).Bottom().Layer(9) );
m_pythonPanelHidden = true;
#endif
......@@ -447,6 +453,7 @@ PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
m_Macros[i].m_Record.clear();
delete m_drc;
delete m_globalFootprintTable;
}
......
......@@ -45,6 +45,7 @@
#include <wx/file.h>
#include <wx/snglinst.h>
#include <wx/dir.h>
#include <pcbnew.h>
#include <protos.h>
......@@ -188,9 +189,28 @@ bool EDA_APP::OnInit()
frame->LoadProjectSettings( fn.GetFullPath() );
// Set the KISYSMOD environment variable for the current process if it is not already
// defined. This is required to expand the global footprint library table paths.
// defined in the user's environment. This is required to expand the global footprint
// library table paths.
if( !wxGetEnv( wxT( "KISYSMOD" ), &msg ) && !GetLibraryPathList().IsEmpty() )
wxSetEnv( wxT( "KISYSMOD" ), GetLibraryPathList()[0] );
{
unsigned modFileCount = 0;
wxString bestPath;
wxArrayString tmp;
for( unsigned i = 0; i < GetLibraryPathList().GetCount(); i++ )
{
unsigned cnt = wxDir::GetAllFiles( GetLibraryPathList()[i], &tmp, wxT( "*.mod" ) );
if( cnt > modFileCount )
{
modFileCount = cnt;
bestPath = GetLibraryPathList()[i];
}
}
wxLogDebug( wxT( "Setting $KISYSMOD=\"%s\"." ), GetChars( bestPath ) );
wxSetEnv( wxT( "KISYSMOD" ), bestPath );
}
/* Load file specified in the command line. */
if( fn.IsOk() )
......
......@@ -41,12 +41,10 @@
#include <plot_common.h>
#include <worksheet.h>
#include <dialog_hotkeys_editor.h>
#include <class_board.h>
#include <fp_lib_table.h>
#include <fp_lib_table_lexer.h>
#include <class_board.h>
#include <pcbplot.h>
#include <pcbnew.h>
#include <pcbnew_id.h>
......@@ -84,73 +82,28 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
break;
case ID_PCB_LIB_TABLE_EDIT:
{
// scaffolding: dummy up some data into tables, until actual load/save are in place.
FP_LIB_TABLE gbl;
FP_LIB_TABLE prj;
FP_LIB_TABLE_LEXER glex(
"(fp_lib_table\n"
" (lib (name passives)(descr \"R/C Lib\")(type KiCad)(uri ${KISYSMODS}/passives.pretty))\n"
" (lib (name micros)(descr \"Small stuff\")(type Legacy)(uri ${KISYSMODS}/passives.mod)(options \"op1=2\"))\n"
" (lib (name chips)(descr \"Potatoe chips\")(type Eagle)(uri /opt/eagle-6.2.0/lbr/con-amp-micromatch.lbr))\n"
")", wxT( "gbl" ) );
FP_LIB_TABLE_LEXER plex(
"(fp_lib_table\n"
" (lib (name passives)(descr \"Demo Lib\")(type KiCad)(uri ${KIUSRMODS}/passives.pretty))\n"
" (lib (name micros)(descr \"Small stuff\")(type Legacy)(uri ${KIUSRMODS}/micros.mod)(options \"op1=2\"))\n"
" (lib (name chips)(descr \"Potatoe chips\")(type Eagle)(uri /opt/eagle-6.2.0/lbr/con-amp-micromatch.lbr))\n"
")", wxT( "prj" ) );
try
{
gbl.Parse( &glex );
prj.Parse( &plex );
}
/* PARSE_ERROR is an IO_ERROR, handle them the same for now.
catch( PARSE_ERROR pe )
{
DisplayError( this, pe.errorText );
break;
}
*/
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
break;
}
int r = InvokePcbLibTableEditor( this, &gbl, &prj );
if( r & 1 )
{
#if defined(DEBUG)
printf( "changed global:\n" );
STRING_FORMATTER sf;
gbl.Format( &sf, 0 );
{
int r = InvokePcbLibTableEditor( this, m_globalFootprintTable, m_footprintLibTable );
printf( "%s\n", sf.GetString().c_str() );
#endif
// save global table to disk and apply it
}
if( r & 1 )
{
FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );
m_globalFootprintTable->Format( &sf, 0 );
if( r & 2 )
{
#if defined(DEBUG)
printf( "changed project:\n" );
}
STRING_FORMATTER sf;
if( r & 2 )
{
wxFileName fn = GetBoard()->GetFileName();
fn.SetName( FP_LIB_TABLE::GetFileName() );
fn.SetExt( wxEmptyString );
prj.Format( &sf, 0 );
FILE_OUTPUTFORMATTER sf( fn.GetFullPath() );
m_footprintLibTable->Format( &sf, 0 );
printf( "%s\n", sf.GetString().c_str() );
#endif
// save project table to disk and apply it
}
}
}
break;
case ID_PCB_MASK_CLEARANCE:
......@@ -268,6 +221,8 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName )
SetElementVisibility( RATSNEST_VISIBLE, showRats );
#endif
loadFootprintLibTable();
return true;
}
......@@ -579,3 +534,48 @@ void PCB_EDIT_FRAME::ReadMacros()
macrosNode = (XNODE*) macrosNode->GetNext();
}
}
void PCB_EDIT_FRAME::loadFootprintLibTable()
{
if( m_globalFootprintTable == NULL )
{
try
{
m_globalFootprintTable = new FP_LIB_TABLE();
FP_LIB_TABLE::LoadGlobalTable( *m_globalFootprintTable );
}
catch( IO_ERROR ioe )
{
wxString msg;
msg.Printf( _( "An error occurred attempting to load the global footprint library "
"table:\n\n%s" ), GetChars( ioe.errorText ) );
DisplayError( this, msg );
}
}
delete m_footprintLibTable;
wxFileName fn = GetBoard()->GetFileName();
fn.SetName( FP_LIB_TABLE::GetFileName() );
fn.SetExt( wxEmptyString );
// Check if a project footprint table is defined and load it. If no project footprint
// table is defined, then the global library table is the footprint library table.
m_footprintLibTable = new FP_LIB_TABLE( m_globalFootprintTable );
if( fn.FileExists() )
{
try
{
FILE_LINE_READER reader( fn.GetFullPath() );
FP_LIB_TABLE_LEXER lexer( &reader );
m_footprintLibTable->Parse( &lexer );
}
catch( IO_ERROR ioe )
{
DisplayError( this, ioe.errorText );
}
}
}
......@@ -589,7 +589,8 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event )
{
wxString newname;
newname = m_Parent->SelectFootprint( m_Parent, wxEmptyString, wxEmptyString, wxEmptyString );
newname = m_Parent->SelectFootprint( m_Parent, wxEmptyString, wxEmptyString, wxEmptyString,
m_Parent->GetFootprintLibraryTable() );
if( newname != wxEmptyString )
m_NewModule->SetValue( newname );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment