CHANGED: Library editors are now usable with no project loaded
Fixes https://gitlab.com/kicad/code/kicad/-/issues/3688
This commit is contained in:
parent
db501c2002
commit
dcc484e114
|
@ -886,7 +886,9 @@ bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename,
|
|||
}
|
||||
else
|
||||
{
|
||||
wxFileDialog dlg( this, prompt, Prj().GetProjectPath(), aFilename.GetFullName() ,
|
||||
wxString dir = Prj().IsNullProject() ? aFilename.GetFullPath() : Prj().GetProjectPath();
|
||||
|
||||
wxFileDialog dlg( this, prompt, dir, aFilename.GetFullName(),
|
||||
wildcard, doOpen ? wxFD_OPEN | wxFD_FILE_MUST_EXIST
|
||||
: wxFD_SAVE | wxFD_CHANGE_DIR | wxFD_OVERWRITE_PROMPT );
|
||||
|
||||
|
|
|
@ -132,6 +132,12 @@ const wxString PROJECT::GetProjectName() const
|
|||
}
|
||||
|
||||
|
||||
bool PROJECT::IsNullProject() const
|
||||
{
|
||||
return m_project_name.GetName().IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
const wxString PROJECT::SymbolLibTableName() const
|
||||
{
|
||||
return libTableName( "sym-lib-table" );
|
||||
|
|
|
@ -217,66 +217,82 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
|
|||
m_parent( aParent ),
|
||||
m_lastBrowseDir( aProjectBasePath )
|
||||
{
|
||||
// For user info, shows the table filenames:
|
||||
m_GblTableFilename->SetLabel( aGlobalTablePath );
|
||||
m_PrjTableFilename->SetLabel( aProjectTablePath );
|
||||
|
||||
// wxGrid only supports user owned tables if they exist past end of ~wxGrid(),
|
||||
// so make it a grid owned table.
|
||||
m_global_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aGlobal ), true );
|
||||
m_project_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aProject ), true );
|
||||
m_global_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aGlobal ), true );
|
||||
|
||||
// Give a bit more room for combobox editors
|
||||
m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 4 );
|
||||
m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 4 );
|
||||
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
m_global_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, m_global_grid ) );
|
||||
m_project_grid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, m_project_grid ) );
|
||||
m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
|
||||
|
||||
m_global_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
m_project_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
|
||||
m_global_grid->AutoSizeColumns( false );
|
||||
m_project_grid->AutoSizeColumns( false );
|
||||
// For user info, shows the table filenames:
|
||||
m_GblTableFilename->SetLabel( aGlobalTablePath );
|
||||
|
||||
wxArrayString pluginChoices;
|
||||
|
||||
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_KICAD ) );
|
||||
pluginChoices.Add( SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
|
||||
|
||||
populateEnvironReadOnlyTable();
|
||||
auto setupGrid =
|
||||
[&]( WX_GRID* aGrid )
|
||||
{
|
||||
// Give a bit more room for combobox editors
|
||||
aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
|
||||
|
||||
for( wxGrid* g : { m_global_grid, m_project_grid } )
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
aGrid->PushEventHandler( new SYMBOL_GRID_TRICKS( m_parent, aGrid ) );
|
||||
|
||||
aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
aGrid->AutoSizeColumns( false );
|
||||
|
||||
// Set special attributes
|
||||
wxGridCellAttr* attr;
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_SYMLIB_EDITOR( m_parent, &m_lastBrowseDir,
|
||||
KiCadSymbolLibFileWildcard() ) );
|
||||
aGrid->SetColAttr( COL_URI, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) );
|
||||
aGrid->SetColAttr( COL_TYPE, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetRenderer( new wxGridCellBoolRenderer() );
|
||||
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
|
||||
aGrid->SetColAttr( COL_ENABLED, attr );
|
||||
|
||||
// all but COL_OPTIONS, which is edited with Option Editor anyways.
|
||||
aGrid->AutoSizeColumn( COL_NICKNAME, false );
|
||||
aGrid->AutoSizeColumn( COL_TYPE, false );
|
||||
aGrid->AutoSizeColumn( COL_URI, false );
|
||||
aGrid->AutoSizeColumn( COL_DESCR, false );
|
||||
aGrid->AutoSizeColumn( COL_ENABLED, false );
|
||||
|
||||
// would set this to width of title, if it was easily known.
|
||||
aGrid->SetColSize( COL_OPTIONS, 80 );
|
||||
|
||||
// Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
|
||||
// a currentCell which is sometimes not highlighted.
|
||||
if( aGrid->GetNumberRows() > 0 )
|
||||
aGrid->SelectRow( 0 );
|
||||
};
|
||||
|
||||
setupGrid( m_global_grid );
|
||||
|
||||
if( aProject )
|
||||
{
|
||||
// Set special attributes
|
||||
wxGridCellAttr* attr;
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_SYMLIB_EDITOR( m_parent, &m_lastBrowseDir,
|
||||
KiCadSymbolLibFileWildcard() ) );
|
||||
g->SetColAttr( COL_URI, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new wxGridCellChoiceEditor( pluginChoices ) );
|
||||
g->SetColAttr( COL_TYPE, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetRenderer( new wxGridCellBoolRenderer() );
|
||||
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
|
||||
g->SetColAttr( COL_ENABLED, attr );
|
||||
|
||||
// all but COL_OPTIONS, which is edited with Option Editor anyways.
|
||||
g->AutoSizeColumn( COL_NICKNAME, false );
|
||||
g->AutoSizeColumn( COL_TYPE, false );
|
||||
g->AutoSizeColumn( COL_URI, false );
|
||||
g->AutoSizeColumn( COL_DESCR, false );
|
||||
g->AutoSizeColumn( COL_ENABLED, false );
|
||||
|
||||
// would set this to width of title, if it was easily known.
|
||||
g->SetColSize( COL_OPTIONS, 80 );
|
||||
m_PrjTableFilename->SetLabel( aProjectTablePath );
|
||||
m_project_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *aProject ), true );
|
||||
setupGrid( m_project_grid );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageNdx = 0;
|
||||
m_auinotebook->DeletePage( 1 );
|
||||
m_project_grid = nullptr;
|
||||
}
|
||||
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
|
||||
|
||||
populateEnvironReadOnlyTable();
|
||||
|
||||
// select the last selected page
|
||||
m_auinotebook->SetSelection( m_pageNdx );
|
||||
|
@ -294,14 +310,6 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
|
|||
m_move_up_button->SetBitmap( KiBitmap( small_up_xpm ) );
|
||||
m_move_down_button->SetBitmap( KiBitmap( small_down_xpm ) );
|
||||
m_browse_button->SetBitmap( KiBitmap( folder_xpm ) );
|
||||
|
||||
// Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
|
||||
// a currentCell which is sometimes not highlighted.
|
||||
if( m_global_grid->GetNumberRows() > 0 )
|
||||
m_global_grid->SelectRow( 0 );
|
||||
|
||||
if( m_project_grid->GetNumberRows() > 0 )
|
||||
m_project_grid->SelectRow( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -315,7 +323,10 @@ PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE()
|
|||
// Delete the GRID_TRICKS.
|
||||
// Any additional event handlers should be popped before the window is deleted.
|
||||
m_global_grid->PopEventHandler( true );
|
||||
m_project_grid->PopEventHandler( true );
|
||||
|
||||
if( m_project_grid )
|
||||
m_project_grid->PopEventHandler( true );
|
||||
|
||||
m_path_subs_grid->PopEventHandler( true );
|
||||
}
|
||||
|
||||
|
@ -324,6 +335,9 @@ bool PANEL_SYM_LIB_TABLE::verifyTables()
|
|||
{
|
||||
for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
|
||||
{
|
||||
if( !model )
|
||||
continue;
|
||||
|
||||
for( int r = 0; r < model->GetNumberRows(); )
|
||||
{
|
||||
wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
|
||||
|
@ -368,6 +382,9 @@ bool PANEL_SYM_LIB_TABLE::verifyTables()
|
|||
// check for duplicate nickNames, separately in each table.
|
||||
for( SYMBOL_LIB_TABLE_GRID* model : { global_model(), project_model() } )
|
||||
{
|
||||
if( !model )
|
||||
continue;
|
||||
|
||||
for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
|
||||
{
|
||||
wxString nick1 = model->GetValue( r1, COL_NICKNAME );
|
||||
|
@ -399,6 +416,9 @@ bool PANEL_SYM_LIB_TABLE::verifyTables()
|
|||
|
||||
for( SYMBOL_LIB_TABLE* table : { global_model(), project_model() } )
|
||||
{
|
||||
if( !table )
|
||||
continue;
|
||||
|
||||
for( unsigned int r = 0; r < table->GetCount(); ++r )
|
||||
{
|
||||
SYMBOL_LIB_TABLE_ROW& row = dynamic_cast<SYMBOL_LIB_TABLE_ROW&>( table->At( r ) );
|
||||
|
@ -682,7 +702,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
|||
m_globalTable->reindex();
|
||||
}
|
||||
|
||||
if( *project_model() != *m_projectTable )
|
||||
if( project_model() && *project_model() != *m_projectTable )
|
||||
{
|
||||
m_parent->m_ProjectTableChanged = true;
|
||||
|
||||
|
@ -708,6 +728,9 @@ void PANEL_SYM_LIB_TABLE::populateEnvironReadOnlyTable()
|
|||
|
||||
for( SYMBOL_LIB_TABLE_GRID* tbl : { global_model(), project_model() } )
|
||||
{
|
||||
if( !tbl )
|
||||
continue;
|
||||
|
||||
for( int row = 0; row < tbl->GetNumberRows(); ++row )
|
||||
{
|
||||
wxString uri = tbl->GetValue( row, COL_URI );
|
||||
|
@ -783,7 +806,7 @@ SYMBOL_LIB_TABLE_GRID* PANEL_SYM_LIB_TABLE::global_model() const
|
|||
|
||||
SYMBOL_LIB_TABLE_GRID* PANEL_SYM_LIB_TABLE::project_model() const
|
||||
{
|
||||
return (SYMBOL_LIB_TABLE_GRID*) m_project_grid->GetTable();
|
||||
return m_project_grid ? (SYMBOL_LIB_TABLE_GRID*) m_project_grid->GetTable() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -804,12 +827,16 @@ 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();
|
||||
SYMBOL_LIB_TABLE* projectTable = nullptr;
|
||||
wxString projectPath = aKiway->Prj().GetProjectPath();
|
||||
wxFileName projectTableFn( projectPath, SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
|
||||
wxString msg;
|
||||
wxString currentLib;
|
||||
|
||||
// Don't allow editing project tables if no project is open
|
||||
if( !aKiway->Prj().IsNullProject() )
|
||||
projectTable = aKiway->Prj().SchSymbolLibTable();
|
||||
|
||||
if( libEditor )
|
||||
{
|
||||
currentLib = libEditor->GetCurLib();
|
||||
|
@ -860,7 +887,7 @@ void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
|
|||
}
|
||||
}
|
||||
|
||||
if( dlg.m_ProjectTableChanged )
|
||||
if( projectTable && dlg.m_ProjectTableChanged )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -879,7 +906,7 @@ void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
|
|||
if( libEditor )
|
||||
{
|
||||
// Check if the currently selected symbol library been removed or disabled.
|
||||
if( !currentLib.empty() && !projectTable->HasLibrary( currentLib, true ) )
|
||||
if( !currentLib.empty() && projectTable && !projectTable->HasLibrary( currentLib, true ) )
|
||||
{
|
||||
libEditor->SetCurLib( wxEmptyString );
|
||||
libEditor->emptyScreen();
|
||||
|
|
|
@ -656,6 +656,23 @@ void LIB_EDIT_FRAME::RegenerateLibraryTree()
|
|||
|
||||
SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::selectSymLibTable( bool aOptional )
|
||||
{
|
||||
// If no project is loaded, always work with the global table
|
||||
if( Prj().IsNullProject() )
|
||||
{
|
||||
SYMBOL_LIB_TABLE* ret = &SYMBOL_LIB_TABLE::GetGlobalLibTable();
|
||||
|
||||
if( aOptional )
|
||||
{
|
||||
wxMessageDialog dlg( this, _( "Add the library to the global library table?" ),
|
||||
_( "Add To Global Library Table" ), wxYES_NO );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
ret = nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
wxArrayString libTableNames;
|
||||
libTableNames.Add( _( "Global" ) );
|
||||
libTableNames.Add( _( "Project" ) );
|
||||
|
|
|
@ -109,6 +109,14 @@ public:
|
|||
*/
|
||||
VTBL_ENTRY const wxString GetProjectName() const;
|
||||
|
||||
/**
|
||||
* Checks if this project is a null project (i.e. the default project object created when
|
||||
* no real project is open). The null project still presents all the same project interface,
|
||||
* but is not backed by any files, so saving it makes no sense.
|
||||
* @return true if this is a bull project
|
||||
*/
|
||||
VTBL_ENTRY bool IsNullProject() const;
|
||||
|
||||
/**
|
||||
* Return the name of the sheet identified by the given UUID.
|
||||
*/
|
||||
|
|
|
@ -262,9 +262,7 @@ void KICAD_MANAGER_FRAME::RecreateLauncher()
|
|||
void KICAD_MANAGER_FRAME::SyncToolbars()
|
||||
{
|
||||
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editSchematic, m_active_project );
|
||||
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editSymbols, m_active_project );
|
||||
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editPCB, m_active_project );
|
||||
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editFootprints, m_active_project );
|
||||
m_launcher->Refresh();
|
||||
}
|
||||
|
||||
|
|
|
@ -368,26 +368,12 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
|
|||
{
|
||||
// For user info, shows the table filenames:
|
||||
m_GblTableFilename->SetLabel( aGlobalTblPath );
|
||||
m_PrjTableFilename->SetLabel( aProjectTblPath );
|
||||
|
||||
m_global_grid->SetTable( new FP_LIB_TABLE_GRID( *aGlobal ), true );
|
||||
m_project_grid->SetTable( new FP_LIB_TABLE_GRID( *aProject ), true );
|
||||
|
||||
// Give a bit more room for wxChoice editors
|
||||
m_global_grid->SetDefaultRowSize( m_global_grid->GetDefaultRowSize() + 4 );
|
||||
m_project_grid->SetDefaultRowSize( m_project_grid->GetDefaultRowSize() + 4 );
|
||||
m_global_grid->SetTable( new FP_LIB_TABLE_GRID( *aGlobal ), true );
|
||||
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
m_global_grid->PushEventHandler( new FP_GRID_TRICKS( m_parent, m_global_grid ) );
|
||||
m_project_grid->PushEventHandler( new FP_GRID_TRICKS( m_parent, m_project_grid ) );
|
||||
m_path_subs_grid->PushEventHandler( new GRID_TRICKS( m_path_subs_grid ) );
|
||||
|
||||
m_global_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
m_project_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
|
||||
m_global_grid->AutoSizeColumns( false );
|
||||
m_project_grid->AutoSizeColumns( false );
|
||||
|
||||
wxArrayString choices;
|
||||
|
||||
choices.Add( IO_MGR::ShowType( IO_MGR::KICAD_SEXP ) );
|
||||
|
@ -402,33 +388,64 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
|
|||
choices.Add( IO_MGR::ShowType( IO_MGR::PCAD ) );
|
||||
*/
|
||||
|
||||
auto setupGrid =
|
||||
[&]( WX_GRID* aGrid )
|
||||
{
|
||||
// Give a bit more room for wxChoice editors
|
||||
aGrid->SetDefaultRowSize( aGrid->GetDefaultRowSize() + 4 );
|
||||
|
||||
// add Cut, Copy, and Paste to wxGrids
|
||||
aGrid->PushEventHandler( new FP_GRID_TRICKS( m_parent, aGrid ) );
|
||||
|
||||
aGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
aGrid->AutoSizeColumns( false );
|
||||
|
||||
wxGridCellAttr* attr;
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, &m_lastBrowseDir,
|
||||
wxEmptyString ) );
|
||||
aGrid->SetColAttr( COL_URI, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
|
||||
aGrid->SetColAttr( COL_TYPE, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetRenderer( new wxGridCellBoolRenderer() );
|
||||
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
|
||||
aGrid->SetColAttr( COL_ENABLED, attr );
|
||||
|
||||
// all but COL_OPTIONS, which is edited with Option Editor anyways.
|
||||
aGrid->AutoSizeColumn( COL_NICKNAME, false );
|
||||
aGrid->AutoSizeColumn( COL_TYPE, false );
|
||||
aGrid->AutoSizeColumn( COL_URI, false );
|
||||
aGrid->AutoSizeColumn( COL_DESCR, false );
|
||||
|
||||
// would set this to width of title, if it was easily known.
|
||||
aGrid->SetColSize( COL_OPTIONS, 80 );
|
||||
|
||||
// Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
|
||||
// a currentCell which is sometimes not highlighted.
|
||||
if( aGrid->GetNumberRows() > 0 )
|
||||
aGrid->SelectRow( 0 );
|
||||
};
|
||||
|
||||
setupGrid( m_global_grid );
|
||||
|
||||
populateEnvironReadOnlyTable();
|
||||
|
||||
for( wxGrid* g : { m_global_grid, m_project_grid } )
|
||||
if( aProject )
|
||||
{
|
||||
wxGridCellAttr* attr;
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, &m_lastBrowseDir, wxEmptyString ) );
|
||||
g->SetColAttr( COL_URI, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetEditor( new wxGridCellChoiceEditor( choices ) );
|
||||
g->SetColAttr( COL_TYPE, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
attr->SetRenderer( new wxGridCellBoolRenderer() );
|
||||
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
|
||||
g->SetColAttr( COL_ENABLED, attr );
|
||||
|
||||
// all but COL_OPTIONS, which is edited with Option Editor anyways.
|
||||
g->AutoSizeColumn( COL_NICKNAME, false );
|
||||
g->AutoSizeColumn( COL_TYPE, false );
|
||||
g->AutoSizeColumn( COL_URI, false );
|
||||
g->AutoSizeColumn( COL_DESCR, false );
|
||||
|
||||
// would set this to width of title, if it was easily known.
|
||||
g->SetColSize( COL_OPTIONS, 80 );
|
||||
m_PrjTableFilename->SetLabel( aProjectTblPath );
|
||||
m_project_grid->SetTable( new FP_LIB_TABLE_GRID( *aProject ), true );
|
||||
setupGrid( m_project_grid );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageNdx = 0;
|
||||
m_auinotebook->DeletePage( 1 );
|
||||
m_project_grid = nullptr;
|
||||
}
|
||||
|
||||
m_path_subs_grid->SetColLabelValue( 0, _( "Name" ) );
|
||||
|
@ -457,14 +474,6 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
|
|||
m_browseButton->SetWidthPadding( 4 );
|
||||
m_browseButton->SetMinSize( buttonSize );
|
||||
|
||||
// Gives a selection to each grid, mainly for delete button. wxGrid's wake up with
|
||||
// a currentCell which is sometimes not highlighted.
|
||||
if( m_global_grid->GetNumberRows() > 0 )
|
||||
m_global_grid->SelectRow( 0 );
|
||||
|
||||
if( m_project_grid->GetNumberRows() > 0 )
|
||||
m_project_grid->SelectRow( 0 );
|
||||
|
||||
// Populate the browse library options
|
||||
wxMenu* browseMenu = m_browseButton->GetSplitButtonMenu();
|
||||
|
||||
|
@ -493,7 +502,10 @@ PANEL_FP_LIB_TABLE::~PANEL_FP_LIB_TABLE()
|
|||
// Delete the GRID_TRICKS.
|
||||
// Any additional event handlers should be popped before the window is deleted.
|
||||
m_global_grid->PopEventHandler( true );
|
||||
m_project_grid->PopEventHandler( true );
|
||||
|
||||
if( m_project_grid )
|
||||
m_project_grid->PopEventHandler( true );
|
||||
|
||||
m_path_subs_grid->PopEventHandler( true );
|
||||
}
|
||||
|
||||
|
@ -502,6 +514,9 @@ bool PANEL_FP_LIB_TABLE::verifyTables()
|
|||
{
|
||||
for( FP_LIB_TABLE_GRID* model : { global_model(), project_model() } )
|
||||
{
|
||||
if( !model )
|
||||
continue;
|
||||
|
||||
for( int r = 0; r < model->GetNumberRows(); )
|
||||
{
|
||||
wxString nick = model->GetValue( r, COL_NICKNAME ).Trim( false ).Trim();
|
||||
|
@ -546,6 +561,9 @@ bool PANEL_FP_LIB_TABLE::verifyTables()
|
|||
// check for duplicate nickNames, separately in each table.
|
||||
for( FP_LIB_TABLE_GRID* model : { global_model(), project_model() } )
|
||||
{
|
||||
if( !model )
|
||||
continue;
|
||||
|
||||
for( int r1 = 0; r1 < model->GetNumberRows() - 1; ++r1 )
|
||||
{
|
||||
wxString nick1 = model->GetValue( r1, COL_NICKNAME );
|
||||
|
@ -909,7 +927,7 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow()
|
|||
m_global->reindex();
|
||||
}
|
||||
|
||||
if( *project_model() != *m_project )
|
||||
if( project_model() && *project_model() != *m_project )
|
||||
{
|
||||
m_parent->m_ProjectTableChanged = true;
|
||||
|
||||
|
@ -940,6 +958,9 @@ void PANEL_FP_LIB_TABLE::populateEnvironReadOnlyTable()
|
|||
|
||||
for( FP_LIB_TABLE_GRID* tbl : { global_model(), project_model() } )
|
||||
{
|
||||
if( !tbl )
|
||||
continue;
|
||||
|
||||
for( int row = 0; row < tbl->GetNumberRows(); ++row )
|
||||
{
|
||||
wxString uri = tbl->GetValue( row, COL_URI );
|
||||
|
@ -1010,6 +1031,9 @@ void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
|
|||
DIALOG_EDIT_LIBRARY_TABLES dlg( aCaller, _( "Footprint Libraries" ) );
|
||||
dlg.SetKiway( &dlg, aKiway );
|
||||
|
||||
if( aKiway->Prj().IsNullProject() )
|
||||
projectTable = nullptr;
|
||||
|
||||
dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, globalTable, globalTablePath,
|
||||
projectTable, projectTablePath,
|
||||
aKiway->Prj().GetProjectPath() ) );
|
||||
|
@ -1030,7 +1054,7 @@ void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
|
|||
}
|
||||
}
|
||||
|
||||
if( dlg.m_ProjectTableChanged )
|
||||
if( projectTable && dlg.m_ProjectTableChanged )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -77,7 +77,7 @@ private:
|
|||
|
||||
FP_LIB_TABLE_GRID* project_model() const
|
||||
{
|
||||
return (FP_LIB_TABLE_GRID*) m_project_grid->GetTable();
|
||||
return m_project_grid ? (FP_LIB_TABLE_GRID*) m_project_grid->GetTable() : nullptr;
|
||||
}
|
||||
|
||||
FP_LIB_TABLE_GRID* cur_model() const
|
||||
|
|
|
@ -375,13 +375,14 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule )
|
|||
}
|
||||
|
||||
|
||||
wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
|
||||
wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary( const wxString& aLibName,
|
||||
const wxString& aProposedName )
|
||||
{
|
||||
// Kicad cannot write legacy format libraries, only .pretty new format
|
||||
// because the legacy format cannot handle current features.
|
||||
// The footprint library is actually a directory
|
||||
|
||||
wxString initialPath = wxPathOnly( Prj().GetProjectFullName() );
|
||||
wxString initialPath = aProposedName.IsEmpty() ? Prj().GetProjectPath() : aProposedName;
|
||||
wxFileName fn;
|
||||
bool doAdd = false;
|
||||
|
||||
|
@ -490,18 +491,32 @@ bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aFilename )
|
|||
|
||||
bool saveInGlobalTable = false;
|
||||
bool saveInProjectTable = false;
|
||||
wxArrayString libTableNames;
|
||||
|
||||
libTableNames.Add( _( "Global" ) );
|
||||
libTableNames.Add( _( "Project" ) );
|
||||
|
||||
switch( SelectSingleOption( this, _( "Select Library Table" ),
|
||||
_( "Choose the Library Table to add the library to:" ),
|
||||
libTableNames ) )
|
||||
if( Prj().IsNullProject() )
|
||||
{
|
||||
case 0: saveInGlobalTable = true; break;
|
||||
case 1: saveInProjectTable = true; break;
|
||||
default: return false;
|
||||
saveInGlobalTable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxArrayString libTableNames;
|
||||
|
||||
libTableNames.Add( _( "Global" ) );
|
||||
libTableNames.Add( _( "Project" ) );
|
||||
|
||||
switch( SelectSingleOption( this, _( "Select Library Table" ),
|
||||
_( "Choose the Library Table to add the library to:" ), libTableNames ) )
|
||||
{
|
||||
case 0:
|
||||
saveInGlobalTable = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
saveInProjectTable = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
wxString type = IO_MGR::ShowType( IO_MGR::GuessPluginTypeFromLibPath( libPath ) );
|
||||
|
|
|
@ -384,7 +384,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprintFromBoard( BOARD* aPcb )
|
|||
bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
|
||||
{
|
||||
const wxString& curLibPath = aLibraryPath;
|
||||
wxString dstLibPath = CreateNewLibrary();
|
||||
wxString dstLibPath = CreateNewLibrary( wxEmptyString, aLibraryPath );
|
||||
|
||||
if( !dstLibPath )
|
||||
return false; // user aborted in CreateNewLibrary()
|
||||
|
|
|
@ -44,17 +44,18 @@ public:
|
|||
virtual ~PCB_BASE_EDIT_FRAME();
|
||||
|
||||
/**
|
||||
* Function CreateNewLibrary
|
||||
* If a library name is given, creates a new footprint library in the project folder
|
||||
* with the given name. If no library name is given it prompts user for a library path,
|
||||
* then creates a new footprint library at that location.
|
||||
* If library exists, user is warned about that, and is given a chance
|
||||
* to abort the new creation, and in that case existing library is first deleted.
|
||||
* @param aProposedName is the inital path and filename shown in the file chooser dialog
|
||||
*
|
||||
* @return wxString - the newly created library path if library was successfully
|
||||
* created, else wxEmptyString because user aborted or error.
|
||||
*/
|
||||
wxString CreateNewLibrary(const wxString& aLibName = wxEmptyString);
|
||||
wxString CreateNewLibrary( const wxString& aLibName = wxEmptyString,
|
||||
const wxString& aProposedName = wxEmptyString );
|
||||
|
||||
/**
|
||||
* Function AddLibrary
|
||||
|
|
Loading…
Reference in New Issue