Add embed option to standard file dialog for 3dmodels

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20025
This commit is contained in:
Seth Hillbrand 2025-08-20 08:27:38 -07:00
parent 8b06071aad
commit 09cdca876c
3 changed files with 55 additions and 14 deletions

View File

@ -443,7 +443,8 @@ public:
TEXT_BUTTON_FILE_BROWSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg, WX_GRID* aGrid,
wxString* aCurrentDir, const wxString& aFileFilter = wxEmptyString,
bool aNormalize = false,
const wxString& aNormalizeBasePath = wxEmptyString ) :
const wxString& aNormalizeBasePath = wxEmptyString,
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
m_dlg( aParentDlg ),
@ -451,7 +452,8 @@ public:
m_currentDir( aCurrentDir ),
m_normalize( aNormalize ),
m_normalizeBasePath( aNormalizeBasePath ),
m_fileFilter( aFileFilter )
m_fileFilter( aFileFilter ),
m_embedCallback( std::move( aEmbedCallback ) )
{
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
@ -463,7 +465,8 @@ public:
wxString* aCurrentDir,
std::function<wxString( WX_GRID* grid, int row )> aFileFilterFn,
bool aNormalize = false,
const wxString& aNormalizeBasePath = wxEmptyString ) :
const wxString& aNormalizeBasePath = wxEmptyString,
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
m_dlg( aParentDlg ),
@ -471,7 +474,8 @@ public:
m_currentDir( aCurrentDir ),
m_normalize( aNormalize ),
m_normalizeBasePath( aNormalizeBasePath ),
m_fileFilterFn( std::move( aFileFilterFn ) )
m_fileFilterFn( std::move( aFileFilterFn ) ),
m_embedCallback( std::move( aEmbedCallback ) )
{
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
@ -502,16 +506,30 @@ protected:
if( !m_fileFilter.IsEmpty() )
{
FILEDLG_HOOK_EMBED_FILE customize( false );
wxFileDialog dlg( m_dlg, _( "Select a File" ), fn.GetPath(), fn.GetFullName(),
m_fileFilter, wxFD_FILE_MUST_EXIST | wxFD_OPEN );
if( m_embedCallback )
dlg.SetCustomizeHook( customize );
if( dlg.ShowModal() == wxID_OK )
{
wxString filePath = dlg.GetPath();
wxString lastPath = dlg.GetDirectory();
wxString relPath = wxEmptyString;
if( m_normalize )
if( m_embedCallback && customize.GetEmbed() )
{
relPath = m_embedCallback( filePath );
if( relPath.IsEmpty() )
{
m_dlg->CleanupAfterModalSubDialog();
return;
}
}
else if( m_normalize )
{
relPath = NormalizePath( filePath, &Pgm().GetLocalEnvVariables(),
m_normalizeBasePath );
@ -573,6 +591,7 @@ protected:
wxString m_fileFilter;
std::function<wxString( WX_GRID* aGrid, int aRow )> m_fileFilterFn;
std::function<wxString( const wxString& )> m_embedCallback;
};
@ -583,12 +602,13 @@ void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
{
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
m_fileFilterFn, m_normalize,
m_normalizeBasePath );
m_normalizeBasePath, m_embedCallback );
}
else
{
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
m_fileFilter, m_normalize, m_normalizeBasePath );
m_fileFilter, m_normalize, m_normalizeBasePath,
m_embedCallback );
}
WX_GRID::CellEditorSetMargins( Combo() );

View File

@ -158,13 +158,15 @@ public:
*/
GRID_CELL_PATH_EDITOR( DIALOG_SHIM* aParentDialog, WX_GRID* aGrid, wxString* aCurrentDir,
bool aNormalize, const wxString& aNormalizeBasePath,
std::function<wxString( WX_GRID* grid, int row )> aFileFilterFn ) :
std::function<wxString( WX_GRID* grid, int row )> aFileFilterFn,
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
m_dlg( aParentDialog ),
m_grid( aGrid ),
m_currentDir( aCurrentDir ),
m_normalize( aNormalize ),
m_normalizeBasePath( aNormalizeBasePath ),
m_fileFilterFn( std::move( aFileFilterFn ) )
m_fileFilterFn( std::move( aFileFilterFn ) ),
m_embedCallback( std::move( aEmbedCallback ) )
{ }
/**
@ -180,13 +182,15 @@ public:
*/
GRID_CELL_PATH_EDITOR( DIALOG_SHIM* aParentDialog, WX_GRID* aGrid, wxString* aCurrentDir,
const wxString& aFileFilter, bool aNormalize = false,
const wxString& aNormalizeBasePath = wxEmptyString ) :
const wxString& aNormalizeBasePath = wxEmptyString,
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
m_dlg( aParentDialog ),
m_grid( aGrid ),
m_currentDir( aCurrentDir ),
m_normalize( aNormalize ),
m_normalizeBasePath( aNormalizeBasePath ),
m_fileFilter( aFileFilter )
m_fileFilter( aFileFilter ),
m_embedCallback( std::move( aEmbedCallback ) )
{ }
wxGridCellEditor* Clone() const override
@ -194,12 +198,12 @@ public:
if( m_fileFilterFn )
{
return new GRID_CELL_PATH_EDITOR( m_dlg, m_grid, m_currentDir, m_normalize,
m_normalizeBasePath, m_fileFilterFn );
m_normalizeBasePath, m_fileFilterFn, m_embedCallback );
}
else
{
return new GRID_CELL_PATH_EDITOR( m_dlg, m_grid, m_currentDir, m_fileFilter,
m_normalize, m_normalizeBasePath );
m_normalize, m_normalizeBasePath, m_embedCallback );
}
}
@ -214,6 +218,7 @@ protected:
wxString m_fileFilter;
std::function<wxString( WX_GRID* aGrid, int aRow )> m_fileFilterFn;
std::function<wxString( const wxString& )> m_embedCallback;
};

View File

@ -108,7 +108,23 @@ PANEL_FP_PROPERTIES_3D_MODEL::PANEL_FP_PROPERTIES_3D_MODEL( PCB_BASE_EDIT_FRAME*
{
attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parentDialog, m_modelsGrid,
&cfg->m_LastFootprint3dDir, wxT( "*.*" ), true,
m_frame->Prj().GetProjectPath() ) );
m_frame->Prj().GetProjectPath(),
[this]( const wxString& aFile ) -> wxString
{
EMBEDDED_FILES::EMBEDDED_FILE* result =
m_filesPanel->AddEmbeddedFile( aFile );
if( !result )
{
wxString msg = wxString::Format(
_( "Error adding 3D model" ) );
wxMessageBox( msg, _( "Error" ),
wxICON_ERROR | wxOK, this );
return wxString();
}
return result->GetLink();
} ) );
}
m_modelsGrid->SetColAttr( COL_FILENAME, attr );