Move library table dialogs from PLAYER to KIFACE interface.

Spooling up a full PLAYER in the background takes too long.

This also fixes bugs around how the tables are saved, although
that was just missing code rather than anything architectural.

Fixes: lp:1785436
* https://bugs.launchpad.net/kicad/+bug/1785436
This commit is contained in:
Jeff Young 2018-08-06 19:33:28 +01:00
parent 9a3cfb8570
commit d788c9d479
20 changed files with 242 additions and 346 deletions

View File

@ -27,8 +27,6 @@ set( CVPCB_DIALOGS
dialogs/dialog_config_equfiles.cpp dialogs/dialog_config_equfiles.cpp
../pcbnew/dialogs/dialog_fp_plugin_options.cpp ../pcbnew/dialogs/dialog_fp_plugin_options.cpp
../pcbnew/dialogs/dialog_fp_plugin_options_base.cpp ../pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
../pcbnew/dialogs/panel_fp_lib_table.cpp
../pcbnew/dialogs/panel_fp_lib_table_base.cpp
) )
set( CVPCB_SRCS set( CVPCB_SRCS

View File

@ -455,63 +455,12 @@ bool CVPCB_MAINFRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, i
void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent ) void CVPCB_MAINFRAME::OnEditFootprintLibraryTable( wxCommandEvent& aEvent )
{ {
FP_LIB_TABLE* globalTable;
bool tableChanged = false;
KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB ); KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB );
kiface->CreateWindow( this, DIALOG_PCB_LIBRARY_TABLE, &Kiway() );
if( kiface )
globalTable = (FP_LIB_TABLE*) kiface->IfaceOrAddress( KIFACE_GLOBAL_FOOTPRINT_TABLE );
else
globalTable = &GFootprintTable; // Shouldn't happen now that Cvpcb is integrated
int r = InvokePcbLibTableEditor( this, globalTable, Prj().PcbFootprintLibs( Kiway() ) );
if( r & 1 )
{
wxString fileName = FP_LIB_TABLE::GetGlobalTableFileName();
try
{
globalTable->Save( fileName );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format(
_( "Error occurred saving the global footprint library table:\n\"%s\"\n%s" ),
GetChars( fileName ),
GetChars( ioe.What() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( r & 2 )
{
wxString fileName = Prj().FootprintLibTblName();
try
{
Prj().PcbFootprintLibs( Kiway() )->Save( fileName );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format(
_( "Error occurred saving the project footprint library table:\n\"%s\"\n%s" ),
GetChars( fileName ),
GetChars( ioe.What() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( tableChanged )
{
wxBusyCursor dummy; wxBusyCursor dummy;
BuildLIBRARY_LISTBOX(); BuildLIBRARY_LISTBOX();
m_FootprintsList->ReadFootprintFiles( Prj().PcbFootprintLibs( Kiway() ) ); m_FootprintsList->ReadFootprintFiles( Prj().PcbFootprintLibs( Kiway() ) );
}
} }

View File

@ -33,7 +33,9 @@
#include <lib_table_grid.h> #include <lib_table_grid.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#include <env_paths.h> #include <env_paths.h>
#include <lib_edit_frame.h>
#include <viewlib_frame.h>
#include <kiway.h>
/** /**
* Build a wxGridTableBase by wrapping an #SYMBOL_LIB_TABLE object. * Build a wxGridTableBase by wrapping an #SYMBOL_LIB_TABLE object.
@ -139,15 +141,19 @@ protected:
PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
SYMBOL_LIB_TABLE* aGlobal, SYMBOL_LIB_TABLE* aGlobal,
SYMBOL_LIB_TABLE* aProject ) : const wxString& aGlobalTablePath,
SYMBOL_LIB_TABLE* aProject,
const wxString& aProjectTablePath,
const wxString& aProjectBasePath ) :
PANEL_SYM_LIB_TABLE_BASE( aParent ), PANEL_SYM_LIB_TABLE_BASE( aParent ),
m_global( aGlobal ), m_globalTable( aGlobal ),
m_project( aProject ), m_projectTable( aProject ),
m_projectBasePath( aProjectBasePath ),
m_parent( aParent ) m_parent( aParent )
{ {
// For user info, shows the table filenames: // For user info, shows the table filenames:
m_PrjTableFilename->SetLabel( m_parent->Prj().SymbolLibTableName() ); m_GblTableFilename->SetLabel( aGlobalTablePath );
m_GblTableFilename->SetLabel( SYMBOL_LIB_TABLE::GetGlobalTableFileName() ); m_PrjTableFilename->SetLabel( aProjectTablePath );
// wxGrid only supports user owned tables if they exist past end of ~wxGrid(), // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
// so make it a grid owned table. // so make it a grid owned table.
@ -222,6 +228,11 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE() PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE()
{ {
// When the dialog is closed it will hide the current notebook page first, which will
// in turn select the other one. We then end up saving its index as the "current page".
// So flip them back again:
m_pageNdx = m_pageNdx == 1 ? 0 : 1;
// Delete the GRID_TRICKS. // Delete the GRID_TRICKS.
// Any additional event handlers should be popped before the window is deleted. // Any additional event handlers should be popped before the window is deleted.
m_global_grid->PopEventHandler( true ); m_global_grid->PopEventHandler( true );
@ -323,12 +334,13 @@ void PANEL_SYM_LIB_TABLE::pageChangedHandler( wxAuiNotebookEvent& event )
void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{ {
wxFileDialog dlg( this, _( "Select Library" ), m_parent->Prj().GetProjectPath(), if( m_lastBrowseDir.IsEmpty() )
m_lastBrowseDir = m_projectBasePath;
wxFileDialog dlg( this, _( "Select Library" ), m_lastBrowseDir,
wxEmptyString, SchematicLibraryFileWildcard(), wxEmptyString, SchematicLibraryFileWildcard(),
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE ); wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
dlg.SetDirectory( m_lastBrowseDir );
auto result = dlg.ShowModal(); auto result = dlg.ShowModal();
if( result == wxID_CANCEL ) if( result == wxID_CANCEL )
@ -386,7 +398,7 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) ); SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
// try to use path normalized to an environmental variable or project path // try to use path normalized to an environmental variable or project path
wxString path = NormalizePath( filePath, &envVars, &m_parent->Prj() ); wxString path = NormalizePath( filePath, &envVars, m_projectBasePath );
if( path.IsEmpty() ) if( path.IsEmpty() )
path = fn.GetFullPath(); path = fn.GetFullPath();
@ -533,20 +545,24 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
if( !verifyTables() ) if( !verifyTables() )
return false; return false;
if( *global_model() != *m_global ) if( *global_model() != *m_globalTable )
{ {
m_global->Clear(); m_parent->m_GlobalTableChanged = true;
m_global->rows.transfer( m_global->rows.end(), global_model()->rows.begin(),
m_globalTable->Clear();
m_globalTable->rows.transfer( m_globalTable->rows.end(), global_model()->rows.begin(),
global_model()->rows.end(), global_model()->rows ); global_model()->rows.end(), global_model()->rows );
m_global->reindex(); m_globalTable->reindex();
} }
if( *project_model() != *m_project ) if( *project_model() != *m_projectTable )
{ {
m_project->Clear(); m_parent->m_ProjectTableChanged = true;
m_project->rows.transfer( m_project->rows.end(), project_model()->rows.begin(),
m_projectTable->Clear();
m_projectTable->rows.transfer( m_projectTable->rows.end(), project_model()->rows.begin(),
project_model()->rows.end(), project_model()->rows ); project_model()->rows.end(), project_model()->rows );
m_project->reindex(); m_projectTable->reindex();
} }
return true; return true;
@ -651,3 +667,62 @@ SYMBOL_LIB_TABLE_GRID* PANEL_SYM_LIB_TABLE::cur_model() const
size_t PANEL_SYM_LIB_TABLE::m_pageNdx = 0; size_t PANEL_SYM_LIB_TABLE::m_pageNdx = 0;
void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
{
SYMBOL_LIB_TABLE* globalTable = &SYMBOL_LIB_TABLE::GetGlobalLibTable();
wxString globalTablePath = SYMBOL_LIB_TABLE::GetGlobalTableFileName();
SYMBOL_LIB_TABLE* projectTable = aKiway->Prj().SchSymbolLibTable();
wxString projectPath = aKiway->Prj().GetProjectPath();
wxFileName projectTableFn( projectPath, SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
wxString msg;
DIALOG_EDIT_LIBRARY_TABLES dlg( aParent, _( "Symbol Libraries" ) );
dlg.InstallPanel( new PANEL_SYM_LIB_TABLE( &dlg, globalTable, globalTablePath,
projectTable, projectTableFn.GetFullPath(),
aKiway->Prj().GetProjectPath() ) );
if( dlg.ShowModal() == wxID_CANCEL )
return;
if( dlg.m_GlobalTableChanged )
{
try
{
globalTable->Save( globalTablePath );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( dlg.m_ProjectTableChanged )
{
try
{
projectTable->Save( projectTableFn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
auto editor = (LIB_EDIT_FRAME*) aKiway->Player( FRAME_SCH_LIB_EDITOR, false );
if( editor )
editor->SyncLibraries( true );
LIB_VIEW_FRAME* viewer = (LIB_VIEW_FRAME*) aKiway->Player( FRAME_SCH_VIEWER, false );
if( viewer )
viewer->ReCreateListLib();
}

View File

@ -35,8 +35,10 @@ class PANEL_SYM_LIB_TABLE : public PANEL_SYM_LIB_TABLE_BASE
{ {
public: public:
PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, SYMBOL_LIB_TABLE* aGlobal, PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
SYMBOL_LIB_TABLE* aProject ); SYMBOL_LIB_TABLE* aGlobal, const wxString& aGlobalTablePath,
SYMBOL_LIB_TABLE* aProject, const wxString& aProjectTablePath,
const wxString& m_projectBasePath );
virtual ~PANEL_SYM_LIB_TABLE(); virtual ~PANEL_SYM_LIB_TABLE();
private: private:
@ -63,8 +65,9 @@ private:
void populateEnvironReadOnlyTable(); void populateEnvironReadOnlyTable();
// Caller's tables are modified only on OK button and successful verification. // Caller's tables are modified only on OK button and successful verification.
SYMBOL_LIB_TABLE* m_global; SYMBOL_LIB_TABLE* m_globalTable;
SYMBOL_LIB_TABLE* m_project; SYMBOL_LIB_TABLE* m_projectTable;
wxString m_projectBasePath;
SYMBOL_LIB_TABLE_GRID* global_model() const; SYMBOL_LIB_TABLE_GRID* global_model() const;
@ -79,4 +82,8 @@ private:
wxString m_lastBrowseDir; ///< last browsed directory wxString m_lastBrowseDir; ///< last browsed directory
}; };
void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent );
#endif // PANEL_SYM_LIB_TABLE_H #endif // PANEL_SYM_LIB_TABLE_H

View File

@ -46,7 +46,8 @@
#include <transform.h> #include <transform.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#include <symbol_lib_table.h> #include <symbol_lib_table.h>
#include "dialogs/dialog_global_sym_lib_table_config.h" #include <dialogs/dialog_global_sym_lib_table_config.h>
#include <dialogs/panel_sym_lib_table.h>
#include <kiway.h> #include <kiway.h>
#include <sim/sim_plot_frame.h> #include <sim/sim_plot_frame.h>
@ -113,6 +114,12 @@ static struct IFACE : public KIFACE_I
} }
break; break;
case DIALOG_SCH_LIBRARY_TABLE:
InvokeSchEditSymbolLibTable( aKiway, aParent );
// Dialog has completed; nothing to return.
return nullptr;
default: default:
return NULL; return NULL;
} }

View File

@ -270,56 +270,20 @@ void SCH_BASE_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent ) void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
{ {
DIALOG_EDIT_LIBRARY_TABLES dlg( this, _( "Footprint Libraries" ) ); InvokeSchEditSymbolLibTable( &Kiway(), this );
dlg.InstallPanel( new PANEL_SYM_LIB_TABLE( &dlg, &SYMBOL_LIB_TABLE::GetGlobalLibTable(),
Prj().SchSymbolLibTable() ) );
if( dlg.ShowModal() == wxID_CANCEL )
return;
saveSymbolLibTables( dlg.m_GlobalTableChanged, dlg.m_ProjectTableChanged );
LIB_EDIT_FRAME* editor = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
if( this == editor )
{
// There may be no parent window so use KIWAY message to refresh the schematic editor
// in case any symbols have changed.
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, std::string( "" ), this );
}
LIB_VIEW_FRAME* viewer = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
if( viewer )
viewer->ReCreateListLib();
} }
void SCH_BASE_FRAME::InstallLibraryTablesPanel( DIALOG_EDIT_LIBRARY_TABLES* aDialog ) LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowError )
{ {
SYMBOL_LIB_TABLE* globalTable = &SYMBOL_LIB_TABLE::GetGlobalLibTable();
SYMBOL_LIB_TABLE* projectTable = Prj().SchSymbolLibTable();
aDialog->InstallPanel( new PANEL_SYM_LIB_TABLE( aDialog, globalTable, projectTable ) );
}
LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib,
bool aShowErrorMsg )
{
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL; PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
return SchGetLibAlias( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg ); return SchGetLibAlias( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowError );
} }
LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowErrorMsg ) LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowErrorMsg )
{ {
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL; PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
return SchGetLibPart( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg ); return SchGetLibPart( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg );
@ -328,22 +292,19 @@ LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, b
bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject ) bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject )
{ {
wxString msg;
bool success = true; bool success = true;
if( aGlobal ) if( aGlobal )
{ {
try try
{ {
FILE_OUTPUTFORMATTER sf( SYMBOL_LIB_TABLE::GetGlobalTableFileName() ); SYMBOL_LIB_TABLE::GetGlobalLibTable().Save( SYMBOL_LIB_TABLE::GetGlobalTableFileName() );
SYMBOL_LIB_TABLE::GetGlobalLibTable().Format( &sf, 0 );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
success = false; success = false;
wxString msg = wxString::Format( _( "Error occurred saving the global symbol library " msg.Printf( _( "Error saving global symbol library table:\n\n%s" ), ioe.What() );
"table:\n\n%s" ),
GetChars( ioe.What().GetData() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
@ -359,9 +320,7 @@ bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject )
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
success = false; success = false;
wxString msg = wxString::Format( _( "Error occurred saving project specific " msg.Printf( _( "Error saving project-specific symbol library table:\n\n%s" ), ioe.What() );
"symbol library table:\n\n%s" ),
GetChars( ioe.What() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }

View File

@ -208,11 +208,6 @@ public:
virtual void OnEditSymbolLibTable( wxCommandEvent& aEvent ); virtual void OnEditSymbolLibTable( wxCommandEvent& aEvent );
/**
* Allows Eeschema to install the symbol library tables into the edit libraries dialog.
*/
void InstallLibraryTablesPanel( DIALOG_EDIT_LIBRARY_TABLES* aDialog ) override;
/** /**
* Load symbol from symbol library table. * Load symbol from symbol library table.
* *
@ -223,7 +218,7 @@ public:
* @return The symbol found in the library or NULL if the symbol was not found. * @return The symbol found in the library or NULL if the symbol was not found.
*/ */
LIB_ALIAS* GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib = false, LIB_ALIAS* GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib = false,
bool aShowErrorMsg = false ); bool aShowError = false );
LIB_PART* GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib = false, LIB_PART* GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib = false,
bool aShowErrorMsg = false ); bool aShowErrorMsg = false );

View File

@ -242,13 +242,6 @@ public:
*/ */
virtual void InstallPreferences( PAGED_DIALOG* aParent ) { } virtual void InstallPreferences( PAGED_DIALOG* aParent ) { }
/**
* Function InstallLibraryTablesPanel
* allows a Frame to load its library tables (if any) into a library tables dialog.
* @param aDialog a library tables dialog
*/
virtual void InstallLibraryTablesPanel( DIALOG_EDIT_LIBRARY_TABLES* aDialog ) { }
/** /**
* Function LoadSettings * Function LoadSettings
* loads common frame parameters from a configuration file. * loads common frame parameters from a configuration file.

View File

@ -63,7 +63,11 @@ enum FRAME_T
// C++ project manager is not a KIWAY_PLAYER // C++ project manager is not a KIWAY_PLAYER
KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT, KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT,
FRAME_T_COUNT FRAME_T_COUNT,
// Library table dialogs are transient and are never returned
DIALOG_SCH_LIBRARY_TABLE = FRAME_T_COUNT,
DIALOG_PCB_LIBRARY_TABLE
}; };
//TEXT_EDITOR_FRAME_T, //TEXT_EDITOR_FRAME_T,

View File

@ -564,43 +564,15 @@ void KICAD_MANAGER_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
void KICAD_MANAGER_FRAME::OnEditSymLibTable( wxCommandEvent& aEvent ) void KICAD_MANAGER_FRAME::OnEditSymLibTable( wxCommandEvent& aEvent )
{ {
auto frame = Kiway().Player( FRAME_SCH, false ); KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_SCH );
bool alreadyRunning = frame != nullptr; kiface->CreateWindow( this, DIALOG_SCH_LIBRARY_TABLE, &Kiway() );
if( !frame )
frame = Kiway().Player( FRAME_SCH, true );
if( frame )
{
DIALOG_EDIT_LIBRARY_TABLES dlg( this, _( "Symbol Libraries" ) );
frame->InstallLibraryTablesPanel( &dlg );
dlg.ShowModal();
if( !alreadyRunning )
frame->Destroy();
}
} }
void KICAD_MANAGER_FRAME::OnEditFpLibTable( wxCommandEvent& aEvent ) void KICAD_MANAGER_FRAME::OnEditFpLibTable( wxCommandEvent& aEvent )
{ {
auto frame = Kiway().Player( FRAME_PCB, false ); KIFACE* kiface = Kiway().KiFACE( KIWAY::FACE_PCB );
bool alreadyRunning = frame != nullptr; kiface->CreateWindow( this, DIALOG_PCB_LIBRARY_TABLE, &Kiway() );
if( !frame )
frame = Kiway().Player( FRAME_PCB, true );
if( frame )
{
DIALOG_EDIT_LIBRARY_TABLES dlg( this, _( "Footprint Libraries" ) );
frame->InstallLibraryTablesPanel( &dlg );
dlg.ShowModal();
if( !alreadyRunning )
frame->Destroy();
}
} }

View File

@ -53,6 +53,9 @@
#include <env_paths.h> #include <env_paths.h>
#include <dialogs/dialog_file_dir_picker.h> #include <dialogs/dialog_file_dir_picker.h>
#include <dialog_edit_library_tables.h> #include <dialog_edit_library_tables.h>
#include <footprint_viewer_frame.h>
#include <footprint_edit_frame.h>
#include <kiway.h>
// Filters for the file picker // Filters for the file picker
static constexpr int FILTER_COUNT = 4; static constexpr int FILTER_COUNT = 4;
@ -260,16 +263,18 @@ protected:
PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aGlobal, const wxString& aGlobalTblPath,
FP_LIB_TABLE* aProject ) : FP_LIB_TABLE* aProject, const wxString& aProjectTblPath,
const wxString& aProjectBasePath ) :
PANEL_FP_LIB_TABLE_BASE( aParent ), PANEL_FP_LIB_TABLE_BASE( aParent ),
m_global( aGlobal ), m_global( aGlobal ),
m_project( aProject ), m_project( aProject ),
m_projectBasePath( aProjectBasePath ),
m_parent( aParent ) m_parent( aParent )
{ {
// For user info, shows the table filenames: // For user info, shows the table filenames:
m_PrjTableFilename->SetLabel( m_parent->Prj().FootprintLibTblName() ); m_GblTableFilename->SetLabel( aGlobalTblPath );
m_GblTableFilename->SetLabel( FP_LIB_TABLE::GetGlobalTableFileName() ); m_PrjTableFilename->SetLabel( aProjectTblPath );
// wxGrid only supports user owned tables if they exist past end of ~wxGrid(), // wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
// so make it a grid owned table. // so make it a grid owned table.
@ -349,6 +354,11 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
PANEL_FP_LIB_TABLE::~PANEL_FP_LIB_TABLE() PANEL_FP_LIB_TABLE::~PANEL_FP_LIB_TABLE()
{ {
// When the dialog is closed it will hide the current notebook page first, which will
// in turn select the other one. We then end up saving its index as the "current page".
// So flip them back again:
m_pageNdx = m_pageNdx == 1 ? 0 : 1;
// Delete the GRID_TRICKS. // Delete the GRID_TRICKS.
// Any additional event handlers should be popped before the window is deleted. // Any additional event handlers should be popped before the window is deleted.
m_global_grid->PopEventHandler( true ); m_global_grid->PopEventHandler( true );
@ -570,7 +580,7 @@ void PANEL_FP_LIB_TABLE::moveDownHandler( wxCommandEvent& event )
void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event ) void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{ {
if( m_lastBrowseDir.IsEmpty() ) if( m_lastBrowseDir.IsEmpty() )
m_lastBrowseDir = m_parent->Prj().GetProjectPath(); m_lastBrowseDir = m_projectBasePath;
DIALOG_FILE_DIR_PICKER dlg( this, _( "Select Library" ), m_lastBrowseDir, DIALOG_FILE_DIR_PICKER dlg( this, _( "Select Library" ), m_lastBrowseDir,
getFilterString(), FD_MULTIPLE ); getFilterString(), FD_MULTIPLE );
@ -622,7 +632,7 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
m_cur_grid->SetCellValue( last_row, COL_TYPE, IO_MGR::ShowType( type ) ); m_cur_grid->SetCellValue( last_row, COL_TYPE, IO_MGR::ShowType( type ) );
// try to use path normalized to an environmental variable or project path // try to use path normalized to an environmental variable or project path
wxString path = NormalizePath( filePath, &envVars, &m_parent->Prj() ); wxString path = NormalizePath( filePath, &envVars, m_projectBasePath );
if( path.IsEmpty() ) if( path.IsEmpty() )
path = fn.GetFullPath(); path = fn.GetFullPath();
@ -683,9 +693,11 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow()
project_model()->rows.end(), project_model()->rows ); project_model()->rows.end(), project_model()->rows );
m_project->reindex(); m_project->reindex();
} }
}
return true; return true;
}
return false;
} }
@ -762,31 +774,57 @@ size_t PANEL_FP_LIB_TABLE::m_pageNdx = 0;
wxString PANEL_FP_LIB_TABLE::m_lastBrowseDir; wxString PANEL_FP_LIB_TABLE::m_lastBrowseDir;
int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobalTable, void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
FP_LIB_TABLE* aProjectTable )
{
DIALOG_EDIT_LIBRARY_TABLES dlg( aCaller, _( "Footprint Libraries" ) );
dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, aGlobalTable, aProjectTable ) );
int ret = 0;
if( dlg.ShowModal() != wxID_CANCEL )
{
if( dlg.m_GlobalTableChanged )
ret += 1;
if( dlg.m_ProjectTableChanged )
ret += 2;
}
return ret;
}
void PCB_EDIT_FRAME::InstallLibraryTablesPanel( DIALOG_EDIT_LIBRARY_TABLES* aDialog )
{ {
FP_LIB_TABLE* globalTable = &GFootprintTable; FP_LIB_TABLE* globalTable = &GFootprintTable;
FP_LIB_TABLE* projectTable = Prj().PcbFootprintLibs(); wxString globalTablePath = FP_LIB_TABLE::GetGlobalTableFileName();
FP_LIB_TABLE* projectTable = aKiway->Prj().PcbFootprintLibs();
wxString projectTablePath = aKiway->Prj().FootprintLibTblName();
wxString msg;
aDialog->InstallPanel( new PANEL_FP_LIB_TABLE( aDialog, globalTable, projectTable ) ); DIALOG_EDIT_LIBRARY_TABLES dlg( aCaller, _( "Footprint Libraries" ) );
dlg.SetKiway( &dlg, aKiway );
dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, globalTable, globalTablePath,
projectTable, projectTablePath,
aKiway->Prj().GetProjectPath() ) );
if( dlg.ShowModal() == wxID_CANCEL )
return;
if( dlg.m_GlobalTableChanged )
{
try
{
globalTable->Save( globalTablePath );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( dlg.m_ProjectTableChanged )
{
try
{
projectTable->Save( projectTablePath );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
auto editor = (FOOTPRINT_EDIT_FRAME*) aKiway->Player( FRAME_SCH_LIB_EDITOR, false );
if( editor )
editor->SyncLibraryTree( true );
auto viewer = (FOOTPRINT_VIEWER_FRAME*) aKiway->Player( FRAME_PCB_MODULE_VIEWER, false );
if( viewer )
viewer->ReCreateLibraryList();
} }

View File

@ -34,8 +34,10 @@ class PANEL_FP_LIB_TABLE : public PANEL_FP_LIB_TABLE_BASE
{ {
public: public:
PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, FP_LIB_TABLE* aGlobal, PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
FP_LIB_TABLE* aProject ); FP_LIB_TABLE* aGlobal, const wxString& aGlobalTblPath,
FP_LIB_TABLE* aProject, const wxString& aProjectTblPath,
const wxString& aProjectBasePath );
~PANEL_FP_LIB_TABLE() override; ~PANEL_FP_LIB_TABLE() override;
private: private:
@ -65,6 +67,7 @@ private:
// caller's tables are modified only on OK button and successful verification. // caller's tables are modified only on OK button and successful verification.
FP_LIB_TABLE* m_global; FP_LIB_TABLE* m_global;
FP_LIB_TABLE* m_project; FP_LIB_TABLE* m_project;
wxString m_projectBasePath;
FP_LIB_TABLE_GRID* global_model() const FP_LIB_TABLE_GRID* global_model() const
{ {

View File

@ -55,7 +55,7 @@
"https://github.com/KiCad/kicad-packages3d" "https://github.com/KiCad/kicad-packages3d"
// wxT( "https://github.com/KiCad/kicad-library/tree/master/modules/packages3d" ) // wxT( "https://github.com/KiCad/kicad-library/tree/master/modules/packages3d" )
void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aCaller ) void Invoke3DShapeLibsDownloaderWizard( wxWindow* aCaller )
{ {
WIZARD_3DSHAPE_LIBS_DOWNLOADER wizard( aCaller ); WIZARD_3DSHAPE_LIBS_DOWNLOADER wizard( aCaller );
wizard.RunWizard( wizard.GetFirstPage() ); wizard.RunWizard( wizard.GetFirstPage() );

View File

@ -829,7 +829,7 @@ void FOOTPRINT_EDIT_FRAME::initLibraryTree()
} }
void FOOTPRINT_EDIT_FRAME::syncLibraryTree( bool aProgress ) void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
{ {
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs(); FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() ); auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
@ -918,57 +918,7 @@ void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event )
break; break;
case ID_PCB_LIB_TABLE_EDIT: case ID_PCB_LIB_TABLE_EDIT:
{ InvokePcbLibTableEditor( &Kiway(), this );
bool tableChanged = false;
int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
if( r & 1 )
{
try
{
FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() );
GFootprintTable.Format( &sf, 0 );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg;
msg.Printf( _( "Error saving the global footprint library table:\n\n%s" ),
ioe.What().GetData() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( r & 2 )
{
wxString tblName = Prj().FootprintLibTblName();
try
{
Prj().PcbFootprintLibs()->Save( tblName );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg;
msg.Printf( _( "Error saving project specific footprint library table:\n\n%s" ),
ioe.What() );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
FOOTPRINT_VIEWER_FRAME* viewer;
viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
if( tableChanged )
{
if( viewer != NULL )
viewer->ReCreateLibraryList();
syncLibraryTree( true );
}
}
break; break;
case wxID_PREFERENCES: case wxID_PREFERENCES:

View File

@ -480,6 +480,13 @@ public:
*/ */
void CommonSettingsChanged() override; void CommonSettingsChanged() override;
/**
* Synchronize the footprint library tree to the current state of the footprint library
* table.
* @param aProgress
*/
void SyncLibraryTree( bool aProgress );
/** /**
* redraws the message panel. * redraws the message panel.
* If a item is currently selected, displays the item info. * If a item is currently selected, displays the item info.
@ -507,13 +514,6 @@ protected:
*/ */
void initLibraryTree(); void initLibraryTree();
/**
* Synchronize the footprint library tree to the current state of the footprint library
* table.
* @param aProgress
*/
void syncLibraryTree( bool aProgress );
/** /**
* Function UpdateTitle * Function UpdateTitle
* updates window title according to getLibNickName(). * updates window title according to getLibNickName().

View File

@ -287,7 +287,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( getTargetLibId() == GetCurrentLibId() ) if( getTargetLibId() == GetCurrentLibId() )
Clear_Pcb( false ); Clear_Pcb( false );
syncLibraryTree( true ); SyncLibraryTree( true );
} }
break; break;
@ -342,7 +342,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->Refresh(); m_canvas->Refresh();
Update3DView(); Update3DView();
syncLibraryTree( false ); SyncLibraryTree( false );
} }
break; break;
@ -403,7 +403,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->Refresh(); m_canvas->Refresh();
Update3DView(); Update3DView();
syncLibraryTree( false ); SyncLibraryTree( false );
} }
wizard->Destroy(); wizard->Destroy();
@ -435,7 +435,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
// Save Library As // Save Library As
const wxString& libName = getTargetLibId().GetLibNickname(); const wxString& libName = getTargetLibId().GetLibNickname();
if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) ) if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) )
syncLibraryTree( true ); SyncLibraryTree( true );
} }
else else
{ {
@ -443,7 +443,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
MODULE* footprint = LoadFootprint( getTargetLibId() ); MODULE* footprint = LoadFootprint( getTargetLibId() );
if( footprint && SaveFootprintAs( footprint ) ) if( footprint && SaveFootprintAs( footprint ) )
{ {
syncLibraryTree( false ); SyncLibraryTree( false );
if( getTargetLibId() == GetCurrentLibId() ) if( getTargetLibId() == GetCurrentLibId() )
{ {
@ -582,7 +582,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{ {
LIB_ID newLib( name, wxEmptyString ); LIB_ID newLib( name, wxEmptyString );
syncLibraryTree( false ); SyncLibraryTree( false );
m_treePane->GetLibTree()->SelectLibId( newLib ); m_treePane->GetLibTree()->SelectLibId( newLib );
} }
} }

View File

@ -43,7 +43,7 @@
#define INVOKE_A_DIALOG_H_ #define INVOKE_A_DIALOG_H_
class wxTopLevelWindow; class wxWindow;
class wxPoint; class wxPoint;
class wxSize; class wxSize;
class wxString; class wxString;
@ -59,30 +59,27 @@ class FOOTPRINT_EDIT_FRAME;
class FP_LIB_TABLE; class FP_LIB_TABLE;
class BOARD; class BOARD;
class PCB_PLOT_PARAMS; class PCB_PLOT_PARAMS;
class KIWAY;
/** /**
* Function InvokePcbLibTableEditor * Function InvokePcbLibTableEditor
* shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables. * shows the modal DIALOG_FP_LIB_TABLE for purposes of editing the global and project
* library tables.
* *
* @param aCaller is the wxTopLevelWindow which is invoking the dialog. * @param aCaller is the wxWindow which is invoking the dialog.
* @param aGlobal is the common footprint library table file being edited. * @return true if either table changed.
* @param aProject is the project specific footprint library table file being edited.
*
* @return int - bits 0 and 1 tell whether a change was made to the @a aGlobal
* and/or the @a aProject table, respectively. If set, table was modified.
*/ */
int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller );
FP_LIB_TABLE* aProject );
/** /**
* Function Invoke3DShapeLibsDownloaderWizard * Function Invoke3DShapeLibsDownloaderWizard
* Runs the downloader wizard for easy 3D shape libraries download from * Runs the downloader wizard for easy 3D shape libraries download from
* the official Kicad Github repository of *.3Dshape libraries. * the official Kicad Github repository of *.3Dshape libraries.
* *
* @param aCaller is the wxTopLevelWindow which is invoking the dialog. * @param aCaller is the wxWindow which is invoking the dialog.
*/ */
void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aCaller ); void Invoke3DShapeLibsDownloaderWizard( wxWindow* aCaller );
/** /**

View File

@ -1663,11 +1663,6 @@ public:
*/ */
void InstallPreferences( PAGED_DIALOG* aParent ) override; void InstallPreferences( PAGED_DIALOG* aParent ) override;
/**
* Allows Pcbnew to install the footprint library tables into the edit libraries dialog.
*/
void InstallLibraryTablesPanel( DIALOG_EDIT_LIBRARY_TABLES* aDialog ) override;
/** /**
* Called after the preferences dialog is run. * Called after the preferences dialog is run.
*/ */

View File

@ -61,6 +61,7 @@
#include <footprint_preview_panel.h> #include <footprint_preview_panel.h>
#include <footprint_info_impl.h> #include <footprint_info_impl.h>
#include <gl_context_mgr.h> #include <gl_context_mgr.h>
#include "invoke_pcb_dialog.h"
extern bool IsWxPythonLoaded(); extern bool IsWxPythonLoaded();
@ -154,6 +155,12 @@ static struct IFACE : public KIFACE_I
case FRAME_PCB_FOOTPRINT_PREVIEW: case FRAME_PCB_FOOTPRINT_PREVIEW:
return dynamic_cast< wxWindow* >( FOOTPRINT_PREVIEW_PANEL::New( aKiway, aParent ) ); return dynamic_cast< wxWindow* >( FOOTPRINT_PREVIEW_PANEL::New( aKiway, aParent ) );
case DIALOG_PCB_LIBRARY_TABLE:
InvokePcbLibTableEditor( aKiway, aParent );
// Dialog has completed; nothing to return.
return nullptr;
default: default:
return nullptr; return nullptr;
} }

View File

@ -62,62 +62,11 @@
void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
{ {
int id = event.GetId(); int id = event.GetId();
wxFileName fn;
switch( id ) switch( id )
{ {
case ID_PCB_LIB_TABLE_EDIT: case ID_PCB_LIB_TABLE_EDIT:
{ InvokePcbLibTableEditor( &Kiway(), this );
bool tableChanged = false;
int r = InvokePcbLibTableEditor( this, &GFootprintTable, Prj().PcbFootprintLibs() );
if( r & 1 )
{
try
{
GFootprintTable.Save( FP_LIB_TABLE::GetGlobalTableFileName() );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format( _(
"Error occurred saving the global footprint library "
"table:\n\n%s" ),
GetChars( ioe.What().GetData() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
// If no board file is defined, do not save the project specific library table. It
// is kept in memory and created in the path when the new board is saved.
if( (r & 2) && !GetBoard()->GetFileName().IsEmpty() )
{
wxString tblName = Prj().FootprintLibTblName();
try
{
Prj().PcbFootprintLibs()->Save( tblName );
tableChanged = true;
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format( _(
"Error occurred saving project specific footprint library "
"table:\n\n%s" ),
GetChars( ioe.What() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
FOOTPRINT_VIEWER_FRAME* viewer;
if( tableChanged && (viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false )) != NULL )
{
viewer->ReCreateLibraryList();
}
}
break; break;
case ID_PCB_3DSHAPELIB_WIZARD: case ID_PCB_3DSHAPELIB_WIZARD:
@ -130,9 +79,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
ShowPreferences( g_Pcbnew_Editor_Hotkeys_Descr, g_Board_Editor_Hotkeys_Descr, wxT( "pcbnew" ) ); ShowPreferences( g_Pcbnew_Editor_Hotkeys_Descr, g_Board_Editor_Hotkeys_Descr, wxT( "pcbnew" ) );
break; break;
// Hotkey IDs
case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST: case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
// Display current hotkey list for Pcbnew.
DisplayHotkeyList( this, g_Board_Editor_Hotkeys_Descr ); DisplayHotkeyList( this, g_Board_Editor_Hotkeys_Descr );
break; break;