Use more finesse in updating status while edit control is open.

Doing an ApplyEdit() keeps the wxEVT_GRID_CELL_CHANGED event
from firing in some cases.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22928
This commit is contained in:
Jeff Young
2026-02-05 14:07:20 +00:00
parent 9c1654c496
commit 631d8d7354
5 changed files with 89 additions and 21 deletions
+36
View File
@@ -23,12 +23,15 @@
#include <confirm.h>
#include <lib_table_grid_data_model.h>
#include <lib_table_notebook_panel.h>
#include <libraries/library_manager.h>
LIB_TABLE_NOTEBOOK_PANEL::~LIB_TABLE_NOTEBOOK_PANEL()
{
// Delete the GRID_TRICKS.
GetGrid()->PopEventHandler( true );
GetGrid()->Unbind( wxEVT_GRID_CELL_CHANGING, &LIB_TABLE_NOTEBOOK_PANEL::onGridCellChanging, this );
}
@@ -77,6 +80,8 @@ void LIB_TABLE_NOTEBOOK_PANEL::AddTable( wxAuiNotebook* aNotebook, const wxStrin
panel->Layout();
sizer->Fit( panel );
grid->Bind( wxEVT_GRID_CELL_CHANGING, &LIB_TABLE_NOTEBOOK_PANEL::onGridCellChanging, panel );
aNotebook->AddPage( panel, aTitle, false );
}
@@ -90,6 +95,37 @@ bool LIB_TABLE_NOTEBOOK_PANEL::TableModified()
}
void LIB_TABLE_NOTEBOOK_PANEL::onGridCellChanging( wxGridEvent& aEvent )
{
int row = aEvent.GetRow();
int col = aEvent.GetCol();
if( col == COL_URI || col == COL_TYPE || col == COL_OPTIONS )
{
WX_GRID* grid = GetGrid();
wxString editValue = grid->GetCellValue( row, col );
if( wxGridCellEditor* cellEditor = grid->GetCellEditor( row, col ) )
{
if( cellEditor->IsCreated() && cellEditor->GetWindow()->IsShown() )
editValue = cellEditor->GetValue();
cellEditor->DecRef();
}
grid->GetTable()->SetValue( row, col, editValue );
if( GetModel()->Adapter() )
{
LIBRARY_TABLE_ROW& tableRow = GetModel()->At( row );
GetModel()->Adapter()->CheckTableRow( tableRow );
}
grid->RefreshBlock( row, COL_STATUS, row, COL_STATUS );
}
}
bool LIB_TABLE_NOTEBOOK_PANEL::SaveTable()
{
bool retVal = true;
+2 -2
View File
@@ -474,8 +474,8 @@ void GRID_CELL_TEXT_BUTTON::OnTextChange( wxCommandEvent& event )
{
if( m_grid && m_row >= 0 && m_row < m_grid->GetNumberRows() && m_col >= 0 && m_col < m_grid->GetNumberCols() )
{
m_value = Combo()->GetValue();
ApplyEdit( m_row, m_col, m_grid );
wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_CHANGING, m_grid, m_row, m_col );
m_grid->GetEventHandler()->ProcessEvent( evt );
}
event.Skip(); // Ensure that other handlers can process this event too
+3
View File
@@ -64,4 +64,7 @@ public:
bool SaveTable();
static void AddTable( wxAuiNotebook* aNotebook, const wxString& aTitle, bool aClosable );
private:
void onGridCellChanging( wxGridEvent& aEvent );
};
+46 -19
View File
@@ -144,6 +144,7 @@ PANEL_FP_PROPERTIES_3D_MODEL::PANEL_FP_PROPERTIES_3D_MODEL( PCB_BASE_EDIT_FRAME*
m_button3DShapeBrowse->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
m_button3DShapeRemove->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
m_modelsGrid->Bind( wxEVT_GRID_CELL_CHANGING, &PANEL_FP_PROPERTIES_3D_MODEL::on3DModelCellChanging, this );
Bind( wxEVT_SHOW, &PANEL_FP_PROPERTIES_3D_MODEL::onShowEvent, this );
m_parentDialog->Bind( wxEVT_ACTIVATE, &PANEL_FP_PROPERTIES_3D_MODEL::onDialogActivateEvent, this );
}
@@ -154,6 +155,7 @@ PANEL_FP_PROPERTIES_3D_MODEL::~PANEL_FP_PROPERTIES_3D_MODEL()
// Delete the GRID_TRICKS.
m_modelsGrid->PopEventHandler( true );
m_modelsGrid->Unbind( wxEVT_GRID_CELL_CHANGING, &PANEL_FP_PROPERTIES_3D_MODEL::on3DModelCellChanging, this );
// Unbind OnShowEvent to prevent unnecessary event handling.
Unbind( wxEVT_SHOW, &PANEL_FP_PROPERTIES_3D_MODEL::onShowEvent, this );
@@ -245,31 +247,47 @@ void PANEL_FP_PROPERTIES_3D_MODEL::On3DModelSelected( wxGridEvent& aEvent )
}
void PANEL_FP_PROPERTIES_3D_MODEL::cleanupFilename( wxString* aFilename )
{
if( !aFilename->empty() )
{
bool hasAlias = false;
FILENAME_RESOLVER* res = PROJECT_PCB::Get3DCacheManager( &m_frame->Prj() )->GetResolver();
aFilename->Replace( wxT( "\n" ), wxT( "" ) );
aFilename->Replace( wxT( "\r" ), wxT( "" ) );
aFilename->Replace( wxT( "\t" ), wxT( "" ) );
res->ValidateFileName( *aFilename, hasAlias );
// If the user has specified an alias in the name then prepend ':'
if( hasAlias )
aFilename->insert( 0, wxT( ":" ) );
#ifdef __WINDOWS__
// In KiCad files, filenames and paths are stored using Unix notation
aFilename->Replace( wxT( "\\" ), wxT( "/" ) );
#endif
}
}
void PANEL_FP_PROPERTIES_3D_MODEL::on3DModelCellChanging( wxGridEvent& aEvent )
{
if( aEvent.GetCol() == COL_FILENAME )
updateValidateStatus( aEvent.GetRow() );
}
void PANEL_FP_PROPERTIES_3D_MODEL::On3DModelCellChanged( wxGridEvent& aEvent )
{
if( aEvent.GetCol() == COL_FILENAME )
{
bool hasAlias = false;
FILENAME_RESOLVER* res = PROJECT_PCB::Get3DCacheManager( &m_frame->Prj() )->GetResolver();
wxString filename = m_modelsGrid->GetCellValue( aEvent.GetRow(), COL_FILENAME );
wxString filename = m_modelsGrid->GetCellValue( aEvent.GetRow(), COL_FILENAME );
// Perform cleanup and validation on the filename if it isn't empty
if( !filename.empty() )
{
filename.Replace( wxT( "\n" ), wxT( "" ) );
filename.Replace( wxT( "\r" ), wxT( "" ) );
filename.Replace( wxT( "\t" ), wxT( "" ) );
res->ValidateFileName( filename, hasAlias );
// If the user has specified an alias in the name then prepend ':'
if( hasAlias )
filename.insert( 0, wxT( ":" ) );
#ifdef __WINDOWS__
// In KiCad files, filenames and paths are stored using Unix notation
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
cleanupFilename( &filename );
// Update the grid with the modified filename
m_modelsGrid->SetCellValue( aEvent.GetRow(), COL_FILENAME, filename );
@@ -508,8 +526,17 @@ void PANEL_FP_PROPERTIES_3D_MODEL::updateValidateStatus( int aRow )
{
int icon = 0;
wxString errStr;
wxString filename = m_modelsGrid->GetCellValue( aRow, COL_FILENAME );
switch( validateModelExists( m_modelsGrid->GetCellValue( aRow, COL_FILENAME) ) )
if( wxGridCellEditor* cellEditor = m_modelsGrid->GetCellEditor( aRow, COL_FILENAME ) )
{
if( cellEditor->IsCreated() && cellEditor->GetWindow()->IsShown() )
filename = cellEditor->GetValue();
cellEditor->DecRef();
}
switch( validateModelExists( filename ) )
{
case MODEL_VALIDATE_ERRORS::MODEL_NO_ERROR:
icon = 0;
@@ -62,6 +62,7 @@ public:
private:
// virtual event functions
void On3DModelSelected( wxGridEvent& ) override;
void on3DModelCellChanging( wxGridEvent& aEvent );
void On3DModelCellChanged( wxGridEvent& aEvent ) override;
void OnRemove3DModel( wxCommandEvent& event ) override;
void OnAdd3DModel( wxCommandEvent& event ) override;
@@ -71,6 +72,7 @@ private:
void OnUpdateUI( wxUpdateUIEvent& event ) override;
void updateValidateStatus( int aRow );
void cleanupFilename( wxString* aFilename );
MODEL_VALIDATE_ERRORS validateModelExists( const wxString& aFilename );