Validate new footprint / save as footprint info before exiting dialog.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13923
This commit is contained in:
parent
7a2a2e2df0
commit
c07e9c834f
|
@ -415,9 +415,6 @@ private:
|
||||||
// Set up the tool framework
|
// Set up the tool framework
|
||||||
void setupTools();
|
void setupTools();
|
||||||
|
|
||||||
EDA_LIST_DIALOG* buildSaveAsDialog( const wxString& aSymbolName,
|
|
||||||
const wxString& aLibraryPreselect );
|
|
||||||
|
|
||||||
void saveSymbolAs();
|
void saveSymbolAs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -270,9 +270,11 @@ public:
|
||||||
* footprint is placed on a board and a netlist is read.
|
* footprint is placed on a board and a netlist is read.
|
||||||
*
|
*
|
||||||
* @param aFootprintName is the name of the new footprint in library.
|
* @param aFootprintName is the name of the new footprint in library.
|
||||||
|
* @param aLibName optional, if specified is the library for the new footprint
|
||||||
* @param aQuiet prevents user dialogs from being shown
|
* @param aQuiet prevents user dialogs from being shown
|
||||||
*/
|
*/
|
||||||
FOOTPRINT* CreateNewFootprint( const wxString& aFootprintName, bool aQuiet = false );
|
FOOTPRINT* CreateNewFootprint( const wxString& aFootprintName, const wxString& aLibName,
|
||||||
|
bool aQuiet );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Places \a aFootprint at the current cursor position and updates footprint coordinates
|
* Places \a aFootprint at the current cursor position and updates footprint coordinates
|
||||||
|
|
|
@ -332,9 +332,6 @@ protected:
|
||||||
/// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory.
|
/// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory.
|
||||||
FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||||
|
|
||||||
EDA_LIST_DIALOG* buildSaveAsDialog( const wxString& aFootprintName,
|
|
||||||
const wxString& aLibraryPreselect );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure the footprint info list is loaded (with a progress dialog) and then initialize
|
* Make sure the footprint info list is loaded (with a progress dialog) and then initialize
|
||||||
* the footprint library tree.
|
* the footprint library tree.
|
||||||
|
|
|
@ -931,90 +931,114 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ID_SAVE_AS_NAME = 4172;
|
|
||||||
static int ID_MAKE_NEW_LIBRARY = 4173;
|
static int ID_MAKE_NEW_LIBRARY = 4173;
|
||||||
|
|
||||||
|
|
||||||
EDA_LIST_DIALOG* FOOTPRINT_EDIT_FRAME::buildSaveAsDialog( const wxString& aFootprintName,
|
class SAVE_AS_DIALOG : public EDA_LIST_DIALOG
|
||||||
const wxString& aLibraryPreselect )
|
|
||||||
{
|
{
|
||||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
public:
|
||||||
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
|
SAVE_AS_DIALOG( FOOTPRINT_EDIT_FRAME* aParent, const wxString& aFootprintName,
|
||||||
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
|
const wxString& aLibraryPreselect,
|
||||||
std::vector<wxString> nicknames = tbl->GetLogicalLibs();
|
std::function<bool( wxString libName, wxString fpName )> aValidator ) :
|
||||||
wxArrayString headers;
|
EDA_LIST_DIALOG( aParent, _( "Save Footprint As" ), false ),
|
||||||
std::vector<wxArrayString> itemsToDisplay;
|
m_validator( std::move( aValidator ) )
|
||||||
|
|
||||||
headers.Add( _( "Nickname" ) );
|
|
||||||
headers.Add( _( "Description" ) );
|
|
||||||
|
|
||||||
for( const wxString& nickname : nicknames )
|
|
||||||
{
|
{
|
||||||
if( alg::contains( project.m_PinnedFootprintLibs, nickname )
|
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||||
|| alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
|
PROJECT_FILE& project = aParent->Prj().GetProjectFile();
|
||||||
|
FP_LIB_TABLE* tbl = aParent->Prj().PcbFootprintLibs();
|
||||||
|
std::vector<wxString> nicknames = tbl->GetLogicalLibs();
|
||||||
|
wxArrayString headers;
|
||||||
|
std::vector<wxArrayString> itemsToDisplay;
|
||||||
|
|
||||||
|
headers.Add( _( "Nickname" ) );
|
||||||
|
headers.Add( _( "Description" ) );
|
||||||
|
|
||||||
|
for( const wxString& nickname : nicknames )
|
||||||
{
|
{
|
||||||
wxArrayString item;
|
if( alg::contains( project.m_PinnedFootprintLibs, nickname )
|
||||||
|
|| alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
|
||||||
item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
|
|
||||||
item.Add( tbl->GetDescription( nickname ) );
|
|
||||||
itemsToDisplay.push_back( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( const wxString& nickname : nicknames )
|
|
||||||
{
|
|
||||||
if( !alg::contains( project.m_PinnedFootprintLibs, nickname )
|
|
||||||
&& !alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
|
|
||||||
{
|
|
||||||
wxArrayString item;
|
|
||||||
|
|
||||||
item.Add( nickname );
|
|
||||||
item.Add( tbl->GetDescription( nickname ) );
|
|
||||||
itemsToDisplay.push_back( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EDA_LIST_DIALOG* dlg = new EDA_LIST_DIALOG( this, _( "Save Footprint As" ), headers,
|
|
||||||
itemsToDisplay, aLibraryPreselect, false );
|
|
||||||
|
|
||||||
dlg->SetListLabel( _( "Save in library:" ) );
|
|
||||||
dlg->SetOKLabel( _( "Save" ) );
|
|
||||||
|
|
||||||
wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
|
|
||||||
|
|
||||||
wxStaticText* label = new wxStaticText( dlg, wxID_ANY, _( "Name:" ) );
|
|
||||||
bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
|
||||||
|
|
||||||
wxTextCtrl* nameTextCtrl = new wxTextCtrl( dlg, ID_SAVE_AS_NAME, aFootprintName );
|
|
||||||
bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
|
||||||
|
|
||||||
wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
|
|
||||||
nameValidator.SetCharExcludes( FOOTPRINT::StringLibNameInvalidChars( false ) );
|
|
||||||
nameTextCtrl->SetValidator( nameValidator );
|
|
||||||
|
|
||||||
wxButton* newLibraryButton = new wxButton( dlg, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
|
|
||||||
dlg->m_ButtonsSizer->Prepend( 80, 20 );
|
|
||||||
dlg->m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
|
|
||||||
|
|
||||||
dlg->GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
|
|
||||||
|
|
||||||
dlg->Bind( wxEVT_BUTTON,
|
|
||||||
[dlg]( wxCommandEvent& )
|
|
||||||
{
|
{
|
||||||
dlg->EndModal( ID_MAKE_NEW_LIBRARY );
|
wxArrayString item;
|
||||||
}, ID_MAKE_NEW_LIBRARY );
|
|
||||||
|
|
||||||
// Move nameTextCtrl to the head of the tab-order
|
item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
|
||||||
if( dlg->GetChildren().DeleteObject( nameTextCtrl ) )
|
item.Add( tbl->GetDescription( nickname ) );
|
||||||
dlg->GetChildren().Insert( nameTextCtrl );
|
itemsToDisplay.push_back( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dlg->SetInitialFocus( nameTextCtrl );
|
for( const wxString& nickname : nicknames )
|
||||||
|
{
|
||||||
|
if( !alg::contains( project.m_PinnedFootprintLibs, nickname )
|
||||||
|
&& !alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
|
||||||
|
{
|
||||||
|
wxArrayString item;
|
||||||
|
|
||||||
dlg->Layout();
|
item.Add( nickname );
|
||||||
dlg->GetSizer()->Fit( dlg );
|
item.Add( tbl->GetDescription( nickname ) );
|
||||||
|
itemsToDisplay.push_back( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initDialog( headers, itemsToDisplay, aLibraryPreselect );
|
||||||
|
|
||||||
return dlg;
|
SetListLabel( _( "Save in library:" ) );
|
||||||
}
|
SetOKLabel( _( "Save" ) );
|
||||||
|
|
||||||
|
wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
|
||||||
|
wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
|
||||||
|
bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
||||||
|
|
||||||
|
m_fpNameCtrl = new wxTextCtrl( this, wxID_ANY, aFootprintName );
|
||||||
|
bNameSizer->Add( m_fpNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
|
||||||
|
nameValidator.SetCharExcludes( FOOTPRINT::StringLibNameInvalidChars( false ) );
|
||||||
|
m_fpNameCtrl->SetValidator( nameValidator );
|
||||||
|
|
||||||
|
wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
|
||||||
|
m_ButtonsSizer->Prepend( 80, 20 );
|
||||||
|
m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
|
||||||
|
|
||||||
|
GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
|
||||||
|
|
||||||
|
Bind( wxEVT_BUTTON,
|
||||||
|
[this]( wxCommandEvent& )
|
||||||
|
{
|
||||||
|
EndModal( ID_MAKE_NEW_LIBRARY );
|
||||||
|
}, ID_MAKE_NEW_LIBRARY );
|
||||||
|
|
||||||
|
// Move nameTextCtrl to the head of the tab-order
|
||||||
|
if( GetChildren().DeleteObject( m_fpNameCtrl ) )
|
||||||
|
GetChildren().Insert( m_fpNameCtrl );
|
||||||
|
|
||||||
|
SetInitialFocus( m_fpNameCtrl );
|
||||||
|
|
||||||
|
SetupStandardButtons();
|
||||||
|
|
||||||
|
Layout();
|
||||||
|
GetSizer()->Fit( this );
|
||||||
|
|
||||||
|
Centre();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GetFPName()
|
||||||
|
{
|
||||||
|
wxString footprintName = m_fpNameCtrl->GetValue();
|
||||||
|
footprintName.Trim( true );
|
||||||
|
footprintName.Trim( false );
|
||||||
|
return footprintName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool TransferDataFromWindow() override
|
||||||
|
{
|
||||||
|
return m_validator( GetTextSelection(), GetFPName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxTextCtrl* m_fpNameCtrl;
|
||||||
|
std::function<bool( wxString libName, wxString fpName )> m_validator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
|
bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
|
||||||
|
@ -1030,14 +1054,56 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
|
||||||
wxString footprintName = aFootprint->GetFPID().GetLibItemName();
|
wxString footprintName = aFootprint->GetFPID().GetLibItemName();
|
||||||
bool updateValue = aFootprint->GetValue() == footprintName;
|
bool updateValue = aFootprint->GetValue() == footprintName;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
bool footprintExists = false;
|
||||||
std::unique_ptr<EDA_LIST_DIALOG> dlg;
|
|
||||||
|
|
||||||
while( !done )
|
while( !done )
|
||||||
{
|
{
|
||||||
dlg.reset( buildSaveAsDialog( footprintName, libraryName ) );
|
SAVE_AS_DIALOG dlg( this, footprintName, libraryName,
|
||||||
|
[&]( const wxString& newLib, const wxString& newName )
|
||||||
|
{
|
||||||
|
if( newLib.IsEmpty() )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "A library must be specified." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int ret = dlg->ShowModal();
|
if( newName.IsEmpty() )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Footprint must have a name." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy libraries are readable, but modifying legacy format is not allowed
|
||||||
|
// So prompt the user if he try to add/replace a footprint in a legacy lib
|
||||||
|
const FP_LIB_TABLE_ROW* row = Prj().PcbFootprintLibs()->FindRow( libraryName );
|
||||||
|
wxString libPath = row->GetFullURI();
|
||||||
|
IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
|
||||||
|
|
||||||
|
if( piType == IO_MGR::LEGACY )
|
||||||
|
{
|
||||||
|
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
footprintExists = tbl->FootprintExists( libraryName, footprintName );
|
||||||
|
|
||||||
|
if( footprintExists )
|
||||||
|
{
|
||||||
|
wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ),
|
||||||
|
footprintName,
|
||||||
|
libraryName );
|
||||||
|
|
||||||
|
KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
|
||||||
|
wxOK | wxCANCEL | wxICON_WARNING );
|
||||||
|
errorDlg.SetOKLabel( _( "Overwrite" ) );
|
||||||
|
|
||||||
|
return errorDlg.ShowModal() == wxID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} );
|
||||||
|
|
||||||
|
int ret = dlg.ShowModal();
|
||||||
|
|
||||||
if( ret == wxID_CANCEL )
|
if( ret == wxID_CANCEL )
|
||||||
{
|
{
|
||||||
|
@ -1045,6 +1111,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
|
||||||
}
|
}
|
||||||
else if( ret == wxID_OK )
|
else if( ret == wxID_OK )
|
||||||
{
|
{
|
||||||
|
footprintName = dlg.GetFPName();
|
||||||
|
libraryName = dlg.GetTextSelection();
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
else if( ret == ID_MAKE_NEW_LIBRARY )
|
else if( ret == ID_MAKE_NEW_LIBRARY )
|
||||||
|
@ -1054,54 +1122,11 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( FOOTPRINT* aFootprint )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libraryName = dlg->GetTextSelection();
|
|
||||||
|
|
||||||
if( libraryName.IsEmpty() )
|
|
||||||
{
|
|
||||||
DisplayError( this, _( "No library specified. Footprint could not be saved." ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
footprintName = static_cast<wxTextCtrl*>( dlg->FindWindow( ID_SAVE_AS_NAME ) )->GetValue();
|
|
||||||
footprintName.Trim( true );
|
|
||||||
footprintName.Trim( false );
|
|
||||||
|
|
||||||
if( footprintName.IsEmpty() )
|
|
||||||
{
|
|
||||||
DisplayError( this, _( "No footprint name specified. Footprint could not be saved." ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFootprint->SetFPID( LIB_ID( libraryName, footprintName ) );
|
aFootprint->SetFPID( LIB_ID( libraryName, footprintName ) );
|
||||||
|
|
||||||
if( updateValue )
|
if( updateValue )
|
||||||
aFootprint->SetValue( footprintName );
|
aFootprint->SetValue( footprintName );
|
||||||
|
|
||||||
// Legacy libraries are readable, but modifying legacy format is not allowed
|
|
||||||
// So prompt the user if he try to add/replace a footprint in a legacy lib
|
|
||||||
wxString libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
|
|
||||||
IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );
|
|
||||||
|
|
||||||
if( piType == IO_MGR::LEGACY )
|
|
||||||
{
|
|
||||||
DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool footprintExists = tbl->FootprintExists( libraryName, footprintName );
|
|
||||||
|
|
||||||
if( footprintExists )
|
|
||||||
{
|
|
||||||
wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ),
|
|
||||||
footprintName,
|
|
||||||
libraryName );
|
|
||||||
KIDIALOG chkdlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
|
|
||||||
chkdlg.SetOKLabel( _( "Overwrite" ) );
|
|
||||||
|
|
||||||
if( chkdlg.ShowModal() == wxID_CANCEL )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !SaveFootprintInLibrary( aFootprint, libraryName ) )
|
if( !SaveFootprintInLibrary( aFootprint, libraryName ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1150,9 +1175,42 @@ bool FOOTPRINT_EDIT_FRAME::RevertFootprint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, bool aQuiet )
|
class NEW_FP_DIALOG : public WX_TEXT_ENTRY_DIALOG
|
||||||
{
|
{
|
||||||
wxString footprintName = aFootprintName;
|
public:
|
||||||
|
NEW_FP_DIALOG( PCB_BASE_FRAME* aParent, const wxString& aName, int aFootprintType,
|
||||||
|
std::function<bool( wxString newName )> aValidator ) :
|
||||||
|
WX_TEXT_ENTRY_DIALOG( aParent, _( "Enter footprint name:" ), _( "New Footprint" ),
|
||||||
|
aName, _( "Footprint type:" ),
|
||||||
|
{ _( "Through hole" ), _( "SMD" ), _( "Other" ) },
|
||||||
|
aFootprintType ),
|
||||||
|
m_validator( std::move( aValidator ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
wxString GetFPName()
|
||||||
|
{
|
||||||
|
wxString name = m_textCtrl->GetValue();
|
||||||
|
name.Trim( true ).Trim( false );
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool TransferDataFromWindow() override
|
||||||
|
{
|
||||||
|
return m_validator( GetFPName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<bool( wxString newName )> m_validator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName,
|
||||||
|
const wxString& aLibName, bool aQuiet )
|
||||||
|
{
|
||||||
|
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
|
||||||
|
wxString footprintName = aFootprintName;
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
// Static to store user preference for a session
|
// Static to store user preference for a session
|
||||||
static int footprintType = 1;
|
static int footprintType = 1;
|
||||||
|
@ -1161,15 +1219,36 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, b
|
||||||
// Ask for the new footprint name
|
// Ask for the new footprint name
|
||||||
if( footprintName.IsEmpty() && !aQuiet )
|
if( footprintName.IsEmpty() && !aQuiet )
|
||||||
{
|
{
|
||||||
WX_TEXT_ENTRY_DIALOG dlg( this, _( "Enter footprint name:" ), _( "New Footprint" ),
|
NEW_FP_DIALOG dlg( this, footprintName, footprintType,
|
||||||
footprintName, _( "Footprint type:" ),
|
[&]( wxString newName )
|
||||||
{ _( "Through hole" ), _( "SMD" ), _( "Other" ) },
|
{
|
||||||
footprintType );
|
if( newName.IsEmpty() )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Footprint must have a name." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !aLibName.IsEmpty() && tbl->FootprintExists( aLibName, newName ) )
|
||||||
|
{
|
||||||
|
msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
|
||||||
|
newName, aLibName );
|
||||||
|
|
||||||
|
KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
|
||||||
|
wxOK | wxCANCEL | wxICON_WARNING );
|
||||||
|
errorDlg.SetOKLabel( _( "Overwrite" ) );
|
||||||
|
|
||||||
|
return errorDlg.ShowModal() == wxID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} );
|
||||||
|
|
||||||
dlg.SetTextValidator( FOOTPRINT_NAME_VALIDATOR( &footprintName ) );
|
dlg.SetTextValidator( FOOTPRINT_NAME_VALIDATOR( &footprintName ) );
|
||||||
|
|
||||||
if( dlg.ShowModal() != wxID_OK )
|
if( dlg.ShowModal() != wxID_OK )
|
||||||
return nullptr; //Aborted by user
|
return nullptr; //Aborted by user
|
||||||
|
|
||||||
|
footprintName = dlg.GetFPName();
|
||||||
footprintType = dlg.GetChoice();
|
footprintType = dlg.GetChoice();
|
||||||
|
|
||||||
switch( footprintType )
|
switch( footprintType )
|
||||||
|
@ -1180,17 +1259,6 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footprintName.Trim( true );
|
|
||||||
footprintName.Trim( false );
|
|
||||||
|
|
||||||
if( footprintName.IsEmpty() )
|
|
||||||
{
|
|
||||||
if( !aQuiet )
|
|
||||||
DisplayInfoMessage( this, _( "No footprint name defined." ) );
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the new footprint and add it to the head of the linked list of footprints
|
// Creates the new footprint and add it to the head of the linked list of footprints
|
||||||
FOOTPRINT* footprint = new FOOTPRINT( GetBoard() );
|
FOOTPRINT* footprint = new FOOTPRINT( GetBoard() );
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ FOOTPRINT* MICROWAVE_TOOL::createBaseFootprint( const wxString& aValue,
|
||||||
{
|
{
|
||||||
PCB_EDIT_FRAME& editFrame = *getEditFrame<PCB_EDIT_FRAME>();
|
PCB_EDIT_FRAME& editFrame = *getEditFrame<PCB_EDIT_FRAME>();
|
||||||
|
|
||||||
FOOTPRINT* footprint = editFrame.CreateNewFootprint( aValue, true );
|
FOOTPRINT* footprint = editFrame.CreateNewFootprint( aValue, wxEmptyString, true );
|
||||||
|
|
||||||
footprint->SetAttributes( FP_EXCLUDE_FROM_POS_FILES | FP_EXCLUDE_FROM_BOM );
|
footprint->SetAttributes( FP_EXCLUDE_FROM_POS_FILES | FP_EXCLUDE_FROM_BOM );
|
||||||
|
|
||||||
|
|
|
@ -407,7 +407,7 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
|
||||||
if( ( cmpdlg.ShowQuasiModal() != wxID_OK ) || msg.IsEmpty() )
|
if( ( cmpdlg.ShowQuasiModal() != wxID_OK ) || msg.IsEmpty() )
|
||||||
return nullptr; // Aborted by user
|
return nullptr; // Aborted by user
|
||||||
|
|
||||||
FOOTPRINT* footprint = editFrame->CreateNewFootprint( msg, true );
|
FOOTPRINT* footprint = editFrame->CreateNewFootprint( msg, wxEmptyString, true );
|
||||||
|
|
||||||
footprint->SetFPID( LIB_ID( wxEmptyString, wxT( "mw_inductor" ) ) );
|
footprint->SetFPID( LIB_ID( wxEmptyString, wxT( "mw_inductor" ) ) );
|
||||||
footprint->SetAttributes( FP_EXCLUDE_FROM_POS_FILES | FP_EXCLUDE_FROM_BOM );
|
footprint->SetAttributes( FP_EXCLUDE_FROM_POS_FILES | FP_EXCLUDE_FROM_BOM );
|
||||||
|
|
|
@ -151,7 +151,8 @@ bool FOOTPRINT_EDITOR_CONTROL::Init()
|
||||||
int FOOTPRINT_EDITOR_CONTROL::NewFootprint( const TOOL_EVENT& aEvent )
|
int FOOTPRINT_EDITOR_CONTROL::NewFootprint( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
LIB_ID selected = m_frame->GetTreeFPID();
|
LIB_ID selected = m_frame->GetTreeFPID();
|
||||||
FOOTPRINT* newFootprint = m_frame->CreateNewFootprint( wxEmptyString );
|
wxString libraryName = selected.GetUniStringLibNickname();
|
||||||
|
FOOTPRINT* newFootprint = m_frame->CreateNewFootprint( wxEmptyString, libraryName, false );
|
||||||
|
|
||||||
if( !newFootprint )
|
if( !newFootprint )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -396,43 +397,69 @@ int FOOTPRINT_EDITOR_CONTROL::DuplicateFootprint( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RENAME_DIALOG : public wxTextEntryDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RENAME_DIALOG( wxWindow* aParent, const wxString& aName,
|
||||||
|
std::function<bool( wxString newName )> aValidator ) :
|
||||||
|
wxTextEntryDialog( aParent, _( "New name:" ), _( "Change Footprint Name" ), aName ),
|
||||||
|
m_validator( std::move( aValidator ) )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
wxString GetFPName()
|
||||||
|
{
|
||||||
|
wxString name = m_textctrl->GetValue();
|
||||||
|
name.Trim( true ).Trim( false );
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool TransferDataFromWindow() override
|
||||||
|
{
|
||||||
|
return m_validator( GetFPName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<bool( wxString newName )> m_validator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
|
int FOOTPRINT_EDITOR_CONTROL::RenameFootprint( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
FP_LIB_TABLE* tbl = m_frame->Prj().PcbFootprintLibs();
|
FP_LIB_TABLE* tbl = m_frame->Prj().PcbFootprintLibs();
|
||||||
LIB_ID fpID = m_frame->GetTreeFPID();
|
LIB_ID fpID = m_frame->GetTreeFPID();
|
||||||
wxString libraryName = fpID.GetLibNickname();
|
wxString libraryName = fpID.GetLibNickname();
|
||||||
wxString oldName = fpID.GetLibItemName();
|
wxString oldName = fpID.GetLibItemName();
|
||||||
wxString newName = oldName;
|
wxString msg;
|
||||||
bool done = false;
|
|
||||||
|
|
||||||
while( !done )
|
RENAME_DIALOG dlg( m_frame, oldName,
|
||||||
{
|
[&]( wxString newName )
|
||||||
wxTextEntryDialog dlg( m_frame, _( "New name:" ), _( "Change Footprint Name" ), newName );
|
{
|
||||||
|
if( newName.IsEmpty() )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Footprint must have a name." ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if( dlg.ShowModal() != wxID_OK )
|
if( tbl->FootprintExists( libraryName, newName ) )
|
||||||
return 0; // canceled by user
|
{
|
||||||
|
msg = wxString::Format( _( "Footprint '%s' already exists in library '%s'." ),
|
||||||
|
newName, libraryName );
|
||||||
|
|
||||||
newName = dlg.GetValue();
|
KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
|
||||||
newName.Trim( true ).Trim( false );
|
wxOK | wxCANCEL | wxICON_WARNING );
|
||||||
|
errorDlg.SetOKLabel( _( "Overwrite" ) );
|
||||||
|
|
||||||
if( newName.IsEmpty() )
|
return errorDlg.ShowModal() == wxID_OK;
|
||||||
{
|
}
|
||||||
DisplayErrorMessage( m_frame, _( "Footprint name cannot be empty." ) );
|
|
||||||
}
|
|
||||||
else if( tbl->FootprintExists( libraryName, newName ) )
|
|
||||||
{
|
|
||||||
DisplayErrorMessage( m_frame, wxString::Format( _( "Footprint name '%s' already "
|
|
||||||
"in use in library '%s'." ),
|
|
||||||
UnescapeString( newName ),
|
|
||||||
libraryName ) );
|
|
||||||
newName = oldName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() != wxID_OK )
|
||||||
|
return 0; // canceled by user
|
||||||
|
|
||||||
|
wxString newName = dlg.GetFPName();
|
||||||
FOOTPRINT* footprint = nullptr;
|
FOOTPRINT* footprint = nullptr;
|
||||||
|
|
||||||
if( fpID == m_frame->GetLoadedFPID() )
|
if( fpID == m_frame->GetLoadedFPID() )
|
||||||
|
|
Loading…
Reference in New Issue