Don't save footprint when it's renamed; wait for the user to save.

Fixes: lp:1792243
* https://bugs.launchpad.net/kicad/+bug/1792243
This commit is contained in:
Jeff Young 2018-09-14 00:39:40 +01:00
parent 0f9ded9563
commit a5e2ddd65a
6 changed files with 77 additions and 49 deletions

View File

@ -345,24 +345,24 @@ BOARD_ITEM_CONTAINER* FOOTPRINT_EDIT_FRAME::GetModel() const
} }
LIB_ID FOOTPRINT_EDIT_FRAME::getTargetFPId() const LIB_ID FOOTPRINT_EDIT_FRAME::getTargetFPID() const
{ {
LIB_ID id = m_treePane->GetLibTree()->GetSelectedLibId(); LIB_ID id = m_treePane->GetLibTree()->GetSelectedLibId();
wxString nickname = id.GetLibNickname(); wxString nickname = id.GetLibNickname();
if( nickname.IsEmpty() ) if( nickname.IsEmpty() )
return GetCurrentFPId(); return GetLoadedFPID();
return id; return id;
} }
LIB_ID FOOTPRINT_EDIT_FRAME::GetCurrentFPId() const LIB_ID FOOTPRINT_EDIT_FRAME::GetLoadedFPID() const
{ {
MODULE* module = GetBoard()->m_Modules; MODULE* module = GetBoard()->m_Modules;
if( module ) if( module )
return module->GetFPID(); return LIB_ID( module->GetFPID().GetLibNickname(), m_footprintNameWhenLoaded );
else else
return LIB_ID(); return LIB_ID();
} }
@ -378,7 +378,7 @@ bool FOOTPRINT_EDIT_FRAME::IsCurrentFPFromBoard() const
void FOOTPRINT_EDIT_FRAME::retainLastFootprint() void FOOTPRINT_EDIT_FRAME::retainLastFootprint()
{ {
LIB_ID id = GetCurrentFPId(); LIB_ID id = GetLoadedFPID();
if( id.IsValid() ) if( id.IsValid() )
{ {
@ -402,7 +402,10 @@ void FOOTPRINT_EDIT_FRAME::restoreLastFootprint()
MODULE* module = loadFootprint( id ); MODULE* module = loadFootprint( id );
if( module ) if( module )
{
m_footprintNameWhenLoaded = curFootprintName;
GetBoard()->Add( module ); GetBoard()->Add( module );
}
} }
} }
@ -570,7 +573,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted( wxUpdateUIEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted( wxUpdateUIEvent& aEvent )
{ {
aEvent.Enable( getTargetFPId().IsValid() ); aEvent.Enable( getTargetFPID().IsValid() );
} }
@ -582,7 +585,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
void FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs( wxUpdateUIEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs( wxUpdateUIEvent& aEvent )
{ {
LIB_ID libId = getTargetFPId(); LIB_ID libId = getTargetFPID();
const wxString& libName = libId.GetLibNickname(); const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName(); const wxString& partName = libId.GetLibItemName();
@ -727,7 +730,7 @@ void FOOTPRINT_EDIT_FRAME::OnModify()
void FOOTPRINT_EDIT_FRAME::updateTitle() void FOOTPRINT_EDIT_FRAME::updateTitle()
{ {
wxString title = _( "Footprint Library Editor" ); wxString title = _( "Footprint Library Editor" );
LIB_ID fpid = GetCurrentFPId(); LIB_ID fpid = GetLoadedFPID();
bool writable = true; bool writable = true;
if( fpid.IsValid() ) if( fpid.IsValid() )
@ -741,14 +744,16 @@ void FOOTPRINT_EDIT_FRAME::updateTitle()
// best efforts... // best efforts...
} }
// Note: don't used GetLoadedFPID(); footprint name may have been edited
title += wxString::Format( wxT( " \u2014 %s %s" ), title += wxString::Format( wxT( " \u2014 %s %s" ),
FROM_UTF8( fpid.Format().c_str() ), FROM_UTF8( GetBoard()->m_Modules->GetFPID().Format().c_str() ),
writable ? wxString( wxEmptyString ) : _( "[Read Only]" ) ); writable ? wxString( wxEmptyString ) : _( "[Read Only]" ) );
} }
else if( !fpid.GetLibItemName().empty() ) else if( !fpid.GetLibItemName().empty() )
{ {
// Note: don't used GetLoadedFPID(); footprint name may have been edited
title += wxString::Format( wxT( " \u2014 %s %s" ), title += wxString::Format( wxT( " \u2014 %s %s" ),
FROM_UTF8( fpid.GetLibItemName().c_str() ), FROM_UTF8( GetBoard()->m_Modules->GetFPID().GetLibItemName().c_str() ),
_( "[Unsaved]" ) ); _( "[Unsaved]" ) );
} }
@ -809,7 +814,7 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
{ {
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs(); FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() ); auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
LIB_ID target = getTargetFPId(); LIB_ID target = getTargetFPID();
bool targetSelected = ( target == m_treePane->GetLibTree()->GetSelectedLibId() ); bool targetSelected = ( target == m_treePane->GetLibTree()->GetSelectedLibId() );
// Sync FOOTPRINT_INFO list to the libraries on disk // Sync FOOTPRINT_INFO list to the libraries on disk

View File

@ -47,6 +47,8 @@ class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
FOOTPRINT_TREE_PANE* m_treePane; FOOTPRINT_TREE_PANE* m_treePane;
LIB_TREE_MODEL_ADAPTER::PTR m_adapter; LIB_TREE_MODEL_ADAPTER::PTR m_adapter;
wxString m_footprintNameWhenLoaded;
public: public:
~FOOTPRINT_EDIT_FRAME(); ~FOOTPRINT_EDIT_FRAME();
@ -295,10 +297,10 @@ public:
BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 ); BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
/// Return the LIB_ID of the part selected in the footprint or the part being edited. /// Return the LIB_ID of the part selected in the footprint or the part being edited.
LIB_ID getTargetFPId() const; LIB_ID getTargetFPID() const;
/// Return the LIB_ID of the part being edited. /// Return the LIB_ID of the part being edited.
LIB_ID GetCurrentFPId() const; LIB_ID GetLoadedFPID() const;
void RemoveStruct( EDA_ITEM* Item ); void RemoveStruct( EDA_ITEM* Item );

View File

@ -276,9 +276,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_DELETE_PART: case ID_MODEDIT_DELETE_PART:
if( DeleteModuleFromLibrary( getTargetFPId(), true ) ) if( DeleteModuleFromLibrary( getTargetFPID(), true ) )
{ {
if( getTargetFPId() == GetCurrentFPId() ) if( getTargetFPID() == GetLoadedFPID() )
Clear_Pcb( false ); Clear_Pcb( false );
SyncLibraryTree( true ); SyncLibraryTree( true );
@ -297,6 +297,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
SetCrossHairPosition( wxPoint( 0, 0 ) ); SetCrossHairPosition( wxPoint( 0, 0 ) );
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
AddModuleToBoard( module ); AddModuleToBoard( module );
// Initialize data relative to nets and netclasses (for a new // Initialize data relative to nets and netclasses (for a new
@ -358,6 +359,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
SetCrossHairPosition( wxPoint( 0, 0 ) ); SetCrossHairPosition( wxPoint( 0, 0 ) );
// Add the new object to board // Add the new object to board
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
GetBoard()->Add( module, ADD_APPEND ); GetBoard()->Add( module, ADD_APPEND );
// Initialize data relative to nets and netclasses (for a new // Initialize data relative to nets and netclasses (for a new
@ -392,7 +394,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_SAVE: case ID_MODEDIT_SAVE:
if( getTargetFPId() == GetCurrentFPId() ) if( getTargetFPID() == GetLoadedFPID() )
{ {
if( SaveFootprint( GetBoard()->m_Modules ) ) if( SaveFootprint( GetBoard()->m_Modules ) )
{ {
@ -411,21 +413,21 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_SAVE_AS: case ID_MODEDIT_SAVE_AS:
if( getTargetFPId().GetLibItemName().empty() ) if( getTargetFPID().GetLibItemName().empty() )
{ {
// Save Library As // Save Library As
const wxString& libName = getTargetFPId().GetLibNickname(); const wxString& libName = getTargetFPID().GetLibNickname();
if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) ) if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) )
SyncLibraryTree( true ); SyncLibraryTree( true );
} }
else if( getTargetFPId() == GetCurrentFPId() ) else if( getTargetFPID() == GetLoadedFPID() )
{ {
// Save Board Footprint As // Save Board Footprint As
MODULE* footprint = GetBoard()->m_Modules; MODULE* footprint = GetBoard()->m_Modules;
if( footprint && SaveFootprintAs( footprint ) ) if( footprint && SaveFootprintAs( footprint ) )
{ {
SyncLibraryTree( false ); SyncLibraryTree( true );
m_toolManager->GetView()->Update( GetBoard()->m_Modules ); m_toolManager->GetView()->Update( GetBoard()->m_Modules );
@ -440,7 +442,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
else else
{ {
// Save Selected Footprint As // Save Selected Footprint As
MODULE* footprint = LoadFootprint( getTargetFPId() ); MODULE* footprint = LoadFootprint( getTargetFPID() );
if( footprint && SaveFootprintAs( footprint ) ) if( footprint && SaveFootprintAs( footprint ) )
SyncLibraryTree( false ); SyncLibraryTree( false );
@ -471,10 +473,10 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_EXPORT_PART: case ID_MODEDIT_EXPORT_PART:
if( getTargetFPId() == GetCurrentFPId() ) if( getTargetFPID() == GetLoadedFPID() )
Export_Module( GetBoard()->m_Modules ); Export_Module( GetBoard()->m_Modules );
else else
Export_Module( LoadFootprint( getTargetFPId() ) ); Export_Module( LoadFootprint( getTargetFPID() ) );
break; break;
case ID_MODEDIT_CREATE_NEW_LIB: case ID_MODEDIT_CREATE_NEW_LIB:
@ -486,7 +488,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{ {
LIB_ID newLib( name, wxEmptyString ); LIB_ID newLib( name, wxEmptyString );
SyncLibraryTree( false ); SyncLibraryTree( true );
m_treePane->GetLibTree()->SelectLibId( newLib ); m_treePane->GetLibTree()->SelectLibId( newLib );
} }
} }
@ -507,6 +509,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
SetCrossHairPosition( wxPoint( 0, 0 ) ); SetCrossHairPosition( wxPoint( 0, 0 ) );
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
AddModuleToBoard( module ); AddModuleToBoard( module );
if( GetBoard()->m_Modules ) if( GetBoard()->m_Modules )
@ -774,22 +777,9 @@ void FOOTPRINT_EDIT_FRAME::editFootprintProperties( MODULE* aModule )
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule ); DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule );
dialog.ShowModal(); dialog.ShowModal();
if( aModule->GetValue() != oldFPID.GetLibItemName() )
{
if( aModule->GetLink() )
{
SaveFootprintToBoard( false );
}
else
{
DeleteModuleFromLibrary( oldFPID, false );
SaveFootprint( aModule );
SyncLibraryTree( true );
}
}
GetScreen()->GetCurItem()->ClearFlags(); GetScreen()->GetCurItem()->ClearFlags();
updateTitle(); // in case of a name change...
} }

View File

@ -317,11 +317,10 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module( const wxString& aName )
return NULL; return NULL;
} }
LIB_ID fpid; module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
fpid.SetLibItemName( module->GetFPID().GetLibItemName() );
module->SetFPID( fpid );
// Insert footprint in list // Insert footprint in list
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
GetBoard()->Add( module ); GetBoard()->Add( module );
// Display info : // Display info :
@ -665,16 +664,24 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
{ {
wxString libraryName = aModule->GetFPID().GetLibNickname(); wxString libraryName = aModule->GetFPID().GetLibNickname();
wxString footprintName = aModule->GetFPID().GetLibItemName(); wxString footprintName = aModule->GetFPID().GetLibItemName();
bool nameChanged = m_footprintNameWhenLoaded != footprintName;
if( aModule->GetLink() ) if( aModule->GetLink() )
{ {
return SaveFootprintToBoard( false ); if( SaveFootprintToBoard( false ) )
{
m_footprintNameWhenLoaded = footprintName;
return true;
}
else
return false;
} }
if( libraryName.IsEmpty() || footprintName.IsEmpty() ) if( libraryName.IsEmpty() || footprintName.IsEmpty() )
return SaveFootprintAs( aModule ); return SaveFootprintAs( aModule );
FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();
bool syncLibraryTree = false;
// Legacy libraries are readable, but modifying legacy format is not allowed // 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 // So prompt the user if he try to add/replace a footprint in a legacy lib
@ -686,6 +693,12 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
return false; return false;
} }
if( nameChanged )
{
LIB_ID oldFPID( libraryName, m_footprintNameWhenLoaded );
DeleteModuleFromLibrary( oldFPID, false );
}
try try
{ {
MODULE* m = tbl->FootprintLoad( libraryName, footprintName ); MODULE* m = tbl->FootprintLoad( libraryName, footprintName );
@ -704,6 +717,12 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
return false; return false;
} }
if( nameChanged )
{
m_footprintNameWhenLoaded = footprintName;
SyncLibraryTree( true );
}
return true; return true;
} }
@ -907,6 +926,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule )
return false; return false;
} }
m_footprintNameWhenLoaded = footprintName;
wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) : wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) :
_( "Component \"%s\" added in \"%s\"" ); _( "Component \"%s\" added in \"%s\"" );

View File

@ -26,6 +26,9 @@
#include <footprint_edit_frame.h> #include <footprint_edit_frame.h>
#include <fp_lib_table.h> #include <fp_lib_table.h>
#include <footprint_info_impl.h> #include <footprint_info_impl.h>
#include <class_board.h>
#include <class_module.h>
LIB_TREE_MODEL_ADAPTER::PTR FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame, LIB_TREE_MODEL_ADAPTER::PTR FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame,
FP_LIB_TABLE* aLibs ) FP_LIB_TABLE* aLibs )
@ -157,10 +160,16 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
switch( aCol ) switch( aCol )
{ {
case 0: case 0:
// mark modified part with an asterix if( node->LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
if( node->LibId == m_frame->GetCurrentFPId() && !m_frame->IsCurrentFPFromBoard() {
&& m_frame->GetScreen()->IsModify() ) wxString currentFPName = m_frame->GetBoard()->m_Modules->GetFPID().GetLibItemName();
aVariant = node->Name + " *";
// mark modified part with an asterix
if( m_frame->GetScreen()->IsModify() )
aVariant = currentFPName + " *";
else
aVariant = currentFPName;
}
else else
aVariant = node->Name; aVariant = node->Name;
break; break;
@ -196,7 +205,7 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
switch( node->Type ) switch( node->Type )
{ {
case LIB_TREE_NODE::LIB: case LIB_TREE_NODE::LIB:
if( node->Name == m_frame->GetCurrentFPId().GetLibNickname() ) if( node->Name == m_frame->GetLoadedFPID().GetLibNickname() )
{ {
#ifdef __WXGTK__ #ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour // The native wxGTK+ impl ignores background colour, so set the text colour
@ -213,7 +222,7 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
break; break;
case LIB_TREE_NODE::LIBID: case LIB_TREE_NODE::LIBID:
if( node->LibId == m_frame->GetCurrentFPId() ) if( node->LibId == m_frame->GetLoadedFPID() )
{ {
#ifdef __WXGTK__ #ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour // The native wxGTK+ impl ignores background colour, so set the text colour

View File

@ -121,6 +121,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
newModule->ClearFlags(); newModule->ClearFlags();
newModule->RunOnChildren( std::bind( &clearModuleItemFlags, _1 ) ); newModule->RunOnChildren( std::bind( &clearModuleItemFlags, _1 ) );
m_footprintNameWhenLoaded = newModule->GetFPID().GetLibItemName();
GetBoard()->Add( newModule ); GetBoard()->Add( newModule );
// Clear references to any net info, because the footprint editor // Clear references to any net info, because the footprint editor