Symbol editor: fix crash caused by broken root symbol name.
The symbol editor selection criteria did not include LIB_FIELD objects which allowed the root symbol name to be changed causing broken derived symbol links. Disable the symbols fields from being edited when a derived part is shown in the editor to prevent this. Add a missing warning that deleting a root symbol used to derive other symbols would also delete all derived symbols from a library. Give the user a chance to cancel the delete operation in this case. Fixes kicad/code/kicad#3654
This commit is contained in:
parent
eb3d32f967
commit
bec878640c
|
@ -642,6 +642,15 @@ void LIB_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER:: HasDerivedSymbols( const wxString& aSymbolName,
|
||||||
|
const wxString& aLibraryName )
|
||||||
|
{
|
||||||
|
LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
|
||||||
|
|
||||||
|
return libBuf.HasDerivedSymbols( aSymbolName );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString LIB_MANAGER::getLibraryName( const wxString& aFilePath )
|
wxString LIB_MANAGER::getLibraryName( const wxString& aFilePath )
|
||||||
{
|
{
|
||||||
wxFileName fn( aFilePath );
|
wxFileName fn( aFilePath );
|
||||||
|
|
|
@ -290,6 +290,14 @@ public:
|
||||||
|
|
||||||
void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames );
|
void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if symbol \a aSymbolName in library \a aLibraryName is a root symbol that
|
||||||
|
* has derived symbols.
|
||||||
|
*
|
||||||
|
* @return true if \aSymbolName in \a aLibraryName has derived symbols.
|
||||||
|
*/
|
||||||
|
bool HasDerivedSymbols( const wxString& aSymbolName, const wxString& aLibraryName );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///> Extracts library name basing on the file name
|
///> Extracts library name basing on the file name
|
||||||
static wxString getLibraryName( const wxString& aFilePath );
|
static wxString getLibraryName( const wxString& aFilePath );
|
||||||
|
|
|
@ -460,7 +460,7 @@ void LIB_EDIT_FRAME::savePartAs()
|
||||||
|
|
||||||
if( new_lib.IsEmpty() )
|
if( new_lib.IsEmpty() )
|
||||||
{
|
{
|
||||||
DisplayError( NULL, _( "No library specified. Symbol could not be saved." ) );
|
DisplayError( this, _( "No library specified. Symbol could not be saved." ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ void LIB_EDIT_FRAME::savePartAs()
|
||||||
|
|
||||||
if( new_name.IsEmpty() )
|
if( new_name.IsEmpty() )
|
||||||
{
|
{
|
||||||
DisplayError( NULL, _( "No symbol name specified. Symbol could not be saved." ) );
|
DisplayError( this, _( "No symbol name specified. Symbol could not be saved." ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +487,6 @@ void LIB_EDIT_FRAME::savePartAs()
|
||||||
LIB_PART new_part( *part );
|
LIB_PART new_part( *part );
|
||||||
new_part.SetName( new_name );
|
new_part.SetName( new_name );
|
||||||
|
|
||||||
fixDuplicateAliases( &new_part, new_lib );
|
|
||||||
m_libMgr->UpdatePart( &new_part, new_lib );
|
m_libMgr->UpdatePart( &new_part, new_lib );
|
||||||
SyncLibraries( false );
|
SyncLibraries( false );
|
||||||
m_treePane->GetLibTree()->SelectLibId( LIB_ID( new_lib, new_part.GetName() ) );
|
m_treePane->GetLibTree()->SelectLibId( LIB_ID( new_lib, new_part.GetName() ) );
|
||||||
|
@ -539,13 +538,33 @@ void LIB_EDIT_FRAME::DeletePartFromLibrary()
|
||||||
LIB_ID libId = getTargetLibId();
|
LIB_ID libId = getTargetLibId();
|
||||||
|
|
||||||
if( m_libMgr->IsPartModified( libId.GetLibItemName(), libId.GetLibNickname() )
|
if( m_libMgr->IsPartModified( libId.GetLibItemName(), libId.GetLibNickname() )
|
||||||
&& !IsOK( this, _( wxString::Format( "Component %s has been modified\n"
|
&& !IsOK( this, _( wxString::Format( "The symbol \"%s\" has been modified\n"
|
||||||
"Do you want to remove it from the library?",
|
"Do you want to remove it from the library?",
|
||||||
libId.GetUniStringLibItemName() ) ) ) )
|
libId.GetUniStringLibItemName() ) ) ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_libMgr->HasDerivedSymbols( libId.GetLibItemName(), libId.GetLibNickname() ) )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
msg.Printf( _( "The symbol \"%s\" is used to derive other symbols.\n"
|
||||||
|
"Deleting this symbol will delete all of the symbols derived from it.\n\n"
|
||||||
|
"Do you wish to delete this symbol and all of it's derivatives?" ),
|
||||||
|
libId.GetLibItemName().wx_str() );
|
||||||
|
|
||||||
|
wxMessageDialog::ButtonLabel yesButtonLabel( _( "Delete Symbol" ) );
|
||||||
|
wxMessageDialog::ButtonLabel noButtonLabel( _( "Keep Symbol" ) );
|
||||||
|
|
||||||
|
wxMessageDialog dlg( this, msg, _( "Warning" ),
|
||||||
|
wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTER );
|
||||||
|
dlg.SetYesNoLabels( yesButtonLabel, noButtonLabel );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_NO )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( isCurrentPart( libId ) )
|
if( isCurrentPart( libId ) )
|
||||||
emptyScreen();
|
emptyScreen();
|
||||||
|
|
||||||
|
|
|
@ -1083,17 +1083,31 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
|
||||||
bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const
|
bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const
|
||||||
{
|
{
|
||||||
// NOTE: in the future this is where eeschema layer/itemtype visibility will be handled
|
// NOTE: in the future this is where eeschema layer/itemtype visibility will be handled
|
||||||
|
LIB_EDIT_FRAME* editFrame = dynamic_cast< LIB_EDIT_FRAME* >( m_frame );
|
||||||
|
|
||||||
|
wxCHECK( editFrame, false );
|
||||||
|
|
||||||
switch( aItem->Type() )
|
switch( aItem->Type() )
|
||||||
{
|
{
|
||||||
case SCH_PIN_T:
|
case SCH_PIN_T:
|
||||||
if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !m_frame->GetShowAllPins() )
|
if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !editFrame->GetShowAllPins() )
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
|
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case LIB_FIELD_T:
|
||||||
|
{
|
||||||
|
LIB_PART* currentPart = editFrame->GetCurPart();
|
||||||
|
|
||||||
|
// Nothing in derived symbols is editable at the moment.
|
||||||
|
if( currentPart && currentPart->IsAlias() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case LIB_ARC_T:
|
case LIB_ARC_T:
|
||||||
case LIB_CIRCLE_T:
|
case LIB_CIRCLE_T:
|
||||||
case LIB_TEXT_T:
|
case LIB_TEXT_T:
|
||||||
|
@ -1102,7 +1116,6 @@ bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityO
|
||||||
case LIB_BEZIER_T:
|
case LIB_BEZIER_T:
|
||||||
case LIB_PIN_T:
|
case LIB_PIN_T:
|
||||||
{
|
{
|
||||||
LIB_EDIT_FRAME* editFrame = (LIB_EDIT_FRAME*) m_frame;
|
|
||||||
LIB_ITEM* lib_item = (LIB_ITEM*) aItem;
|
LIB_ITEM* lib_item = (LIB_ITEM*) aItem;
|
||||||
|
|
||||||
if( lib_item->GetUnit() && lib_item->GetUnit() != editFrame->GetUnit() )
|
if( lib_item->GetUnit() && lib_item->GetUnit() != editFrame->GetUnit() )
|
||||||
|
@ -1113,6 +1126,7 @@ bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityO
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SCH_MARKER_T: // Always selectable
|
case SCH_MARKER_T: // Always selectable
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue