Remove confusing active library interactions with save.

Add a library selector to the save dialog.  Initialize it to the
footprint's library.  This way a straigh-up save will do what's
expected.

However, the user can still select the active library (or any
other library) if they really did want to move the footprint.

Fixes: lp:1750918
* https://bugs.launchpad.net/kicad/+bug/1750918
This commit is contained in:
Jeff Young 2018-02-22 00:17:04 +00:00 committed by Wayne Stambaugh
parent b67b4b9ea9
commit e552c2fbff
9 changed files with 130 additions and 113 deletions

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Nov 22 2017)
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -11,7 +11,7 @@
EDA_LIST_DIALOG_BASE::EDA_LIST_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
@ -25,9 +25,9 @@ EDA_LIST_DIALOG_BASE::EDA_LIST_DIALOG_BASE( wxWindow* parent, wxWindowID id, con
m_filterBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizerMain->Add( m_filterBox, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_staticText2 = new wxStaticText( this, wxID_ANY, _("Items:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText2->Wrap( -1 );
bSizerMain->Add( m_staticText2, 0, wxRIGHT|wxLEFT, 5 );
m_listLabel = new wxStaticText( this, wxID_ANY, _("Items:"), wxDefaultPosition, wxDefaultSize, 0 );
m_listLabel->Wrap( -1 );
bSizerMain->Add( m_listLabel, 0, wxRIGHT|wxLEFT, 5 );
m_listBox = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES|wxALWAYS_SHOW_SB|wxVSCROLL );
m_listBox->SetMinSize( wxSize( -1,200 ) );

View File

@ -41,10 +41,10 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="minimum_size"></property>
<property name="name">EDA_LIST_DIALOG_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="size"></property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title"></property>
@ -307,7 +307,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText2</property>
<property name="name">m_listLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Nov 22 2017)
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -37,7 +37,7 @@ class EDA_LIST_DIALOG_BASE : public DIALOG_SHIM
protected:
wxStaticText* m_filterLabel;
wxTextCtrl* m_filterBox;
wxStaticText* m_staticText2;
wxStaticText* m_listLabel;
wxListCtrl* m_listBox;
wxStaticText* m_staticTextMsg;
wxTextCtrl* m_messages;
@ -56,7 +56,7 @@ class EDA_LIST_DIALOG_BASE : public DIALOG_SHIM
public:
EDA_LIST_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
EDA_LIST_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~EDA_LIST_DIALOG_BASE();
};

View File

@ -87,14 +87,19 @@ void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxStr
m_staticTextMsg->Show( false );
}
if( !!aSelection )
if( !aSelection.IsEmpty() )
{
for( unsigned row = 0; row < m_itemsListCp->size(); ++row )
{
if( (*m_itemsListCp)[row][0] == aSelection )
{
m_listBox->SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
// Set to a small size so EnsureVisible() won't be foiled by later additions.
// ListBox will expand to fit later.
m_listBox->SetSize( m_listBox->GetSize().GetX(), 100 );
m_listBox->EnsureVisible( row );
break;
}
}
@ -102,6 +107,18 @@ void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxStr
}
void EDA_LIST_DIALOG::SetFilterLabel( const wxString& aLabel )
{
m_filterLabel->SetLabel( aLabel );
}
void EDA_LIST_DIALOG::SetListLabel( const wxString& aLabel )
{
m_listLabel->SetLabel( aLabel );
}
void EDA_LIST_DIALOG::textChangeInFilterBox( wxCommandEvent& event )
{
wxString filter;

View File

@ -75,6 +75,9 @@ public:
// ~EDA_LIST_DIALOG() {}
void SetFilterLabel( const wxString& aLabel );
void SetListLabel( const wxString& aLabel );
void Append( const wxArrayString& aItemStr );
void InsertItems( const std::vector<wxArrayString>& aItemList, int aPosition = 0 );

View File

@ -192,7 +192,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
EVT_UPDATE_UI( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected )
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
@ -560,19 +560,15 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
case wxID_YES:
// code from FOOTPRINT_EDIT_FRAME::Process_Special_Functions,
// at case ID_MODEDIT_SAVE_LIBMODULE
if( GetBoard()->m_Modules && GetCurrentLib().size() )
if( GetBoard()->m_Modules )
{
if( SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true ) )
if( SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules ) )
{
// save was correct
GetScreen()->ClrModify();
break;
}
}
else
{
DisplayError( this, _( "Library is not set, the footprint could not be saved." ) );
}
// fall through: cancel the close because of an error
case wxID_CANCEL:
@ -646,12 +642,6 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
}
void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( getLibPath() != wxEmptyString && GetBoard()->m_Modules != NULL );
}
void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent )
{
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );

View File

@ -186,7 +186,6 @@ public:
void OnUpdateOptionsToolbar( wxUpdateUIEvent& aEvent );
void OnUpdateLibSelected( wxUpdateUIEvent& aEvent );
void OnUpdateModuleSelected( wxUpdateUIEvent& aEvent );
void OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent );
void OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent );
void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent );
void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent );
@ -204,18 +203,11 @@ public:
/**
* Function SaveFootprintInLibrary
* Save in an existing library a given footprint
* @param aLibName = name of the library to use
* @param activeLibrary = default library if the footprint has none
* @param aModule = the given footprint
* @param aOverwrite = true to overwrite an existing footprint, false to
* abort if an existing footprint with same name is found
* @param aDisplayDialog = true to display a dialog to enter or confirm the
* footprint name
* @return : true if OK, false if abort
*/
bool SaveFootprintInLibrary( const wxString& aLibName,
MODULE* aModule,
bool aOverwrite,
bool aDisplayDialog );
bool SaveFootprintInLibrary( wxString activeLibrary, MODULE* aModule );
/**
* Virtual Function OnModify()

View File

@ -379,9 +379,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_SAVE_LIBMODULE:
if( GetBoard()->m_Modules && GetCurrentLib().size() )
if( GetBoard()->m_Modules )
{
SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true );
SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules );
GetScreen()->ClrModify();
}
break;

View File

@ -656,20 +656,98 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib, const wxString&
}
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary,
MODULE* aModule,
bool aOverwrite,
bool aDisplayDialog )
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( wxString activeLibrary, MODULE* aModule )
{
if( aModule == NULL )
return false;
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
SetMsgPanel( aModule );
// For 6.0 Save should silently save the footprint in its own library.
// Save As... should allow a rename and/or reparent to a different library.
//
// However, for 5.0 we need a more limited intervention. We'll always display
// the dialog, but add a Library selection widget that will default to saving
// in the footprint's own library but allow switching to the active library
// (or even some other library).
wxString libraryName = aModule->GetFPID().GetLibNickname();
wxString footprintName = aModule->GetFPID().GetLibItemName();
if( libraryName.IsEmpty() )
libraryName = activeLibrary;
wxArrayString headers;
std::vector<wxArrayString> itemsToDisplay;
std::vector<wxString> nicknames = tbl->GetLogicalLibs();
headers.Add( _( "Nickname" ) );
headers.Add( _( "Description" ) );
for( unsigned i = 0; i < nicknames.size(); i++ )
{
wxArrayString item;
item.Add( nicknames[i] );
item.Add( tbl->GetDescription( nicknames[i] ) );
itemsToDisplay.push_back( item );
}
EDA_LIST_DIALOG dlg( this, FMT_SAVE_MODULE, headers, itemsToDisplay, libraryName );
dlg.SetFilterLabel( _( "Library Filter:" ) );
dlg.SetListLabel( _( "Save in Library:" ) );
wxSizer* mainSizer = dlg.GetSizer();
wxStaticLine* separator = new wxStaticLine( &dlg, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Prepend( separator, 0, wxEXPAND|wxBOTTOM|wxTOP, 10 );
wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, footprintName, wxDefaultPosition, wxDefaultSize, 0 );
mainSizer->Prepend( nameTextCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
nameValidator.SetCharExcludes( MODULE::StringLibNameInvalidChars( true ) );
nameTextCtrl->SetValidator( nameValidator );
wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Footprint Name:" ), wxDefaultPosition, wxDefaultSize, 0 );
mainSizer->Prepend( label, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
// Move nameTextCtrl to the head of the tab-order
if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
dlg.GetChildren().Insert( nameTextCtrl );
dlg.Layout();
mainSizer->Fit( &dlg );
if( dlg.ShowModal() != wxID_OK )
return false; // canceled by user
libraryName = dlg.GetTextSelection();
if( libraryName.IsEmpty() )
{
DisplayError( NULL, _( "No library specified. Footprint could not be saved." ) );
return false;
}
footprintName = nameTextCtrl->GetValue();
footprintName.Trim( true );
footprintName.Trim( false );
if( footprintName.IsEmpty() )
{
DisplayError( NULL, _( "No footprint name specified. Footprint could not be saved." ) );
return false;
}
aModule->SetFPID( LIB_ID( 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( aLibrary )->GetFullURI();
wxString libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );
if( piType == IO_MGR::LEGACY )
@ -678,77 +756,18 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary,
return false;
}
// Ask what to use as the footprint name in the library
wxString footprintName = aModule->GetFPID().GetLibItemName();
if( aDisplayDialog )
{
wxTextEntryDialog dlg( this, _( "Name:" ), FMT_SAVE_MODULE, footprintName );
if( dlg.ShowModal() != wxID_OK )
return false; // canceled by user
footprintName = dlg.GetValue();
footprintName.Trim( true );
footprintName.Trim( false );
if( footprintName.IsEmpty() )
return false;
if( ! MODULE::IsLibNameValid( footprintName ) )
{
wxString msg = wxString::Format(
_( "Error:\none of invalid chars \"%s\" found\nin \"%s\"" ),
MODULE::StringLibNameInvalidChars( true ),
GetChars( footprintName ) );
DisplayError( NULL, msg );
return false;
}
aModule->SetFPID( LIB_ID( footprintName ) );
}
// Ensure this footprint has a libname
if( footprintName.IsEmpty() )
{
footprintName = wxT("noname");
aModule->SetFPID( LIB_ID( footprintName ) );
}
bool module_exists = false;
try
{
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
MODULE* m = tbl->FootprintLoad( libraryName, footprintName );
MODULE* m = tbl->FootprintLoad( aLibrary, footprintName );
if( m )
{
delete m;
module_exists = true;
// an existing footprint is found in current lib
if( aDisplayDialog )
{
wxString msg = wxString::Format( FMT_MOD_EXISTS,
footprintName.GetData(), aLibrary.GetData() );
SetStatusText( msg );
}
if( !aOverwrite )
{
// Do not save the given footprint: an old one exists
return true;
}
}
module_exists = m != nullptr;
delete m;
// this always overwrites any existing footprint, but should yell on its
// own if the library or footprint is not writable.
tbl->FootprintSave( aLibrary, aModule );
tbl->FootprintSave( libraryName, aModule );
}
catch( const IO_ERROR& ioe )
{
@ -756,15 +775,11 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary,
return false;
}
if( aDisplayDialog )
{
wxString fmt = module_exists ?
_( "Component \"%s\" replaced in \"%s\"" ) :
_( "Component \"%s\" added in \"%s\"" );
wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) :
_( "Component \"%s\" added in \"%s\"" );
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibrary.GetData() );
SetStatusText( msg );
}
wxString msg = wxString::Format( fmt, footprintName.GetData(), libraryName.GetData() );
SetStatusText( msg );
return true;
}