Eeschema: Fix a subtle bug in SYMBOL_PREVIEW_WIDGET.

The dialog was using a LIB_ALIAS from library cache to show the symbol to the canvas without making a local copy.
Unfortunately, the library viewer is doing the same thing.

Now the GAL is used in Eeschema, a link to the VIEW used by the GAL canvas is stored in this class.
When The selector symbol dialog is used to choose a symbol to display in the Library viewer,
a race condition between the Library viewer GAL canvas and the dtor dialog that destroyed this link in the same instancied class.

Now, the SYMBOL_PREVIEW_WIDGET used in the dialog works on a local copy of the symbol to display.
This commit is contained in:
jean-pierre charras 2018-10-31 15:52:10 +01:00
parent c4cd81a906
commit 7985234556
4 changed files with 23 additions and 17 deletions

View File

@ -603,8 +603,7 @@ void LIB_VIEW_FRAME::ClickOnCmpList( wxCommandEvent& event )
void LIB_VIEW_FRAME::SetSelectedComponent( const wxString& aComponentName )
{
// Aren't component names case sensitive now?
if( m_entryName.CmpNoCase( aComponentName ) != 0 )
if( m_entryName != aComponentName )
{
m_entryName = aComponentName;
@ -621,8 +620,8 @@ void LIB_VIEW_FRAME::SetSelectedComponent( const wxString& aComponentName )
m_selection_changed = false;
}
Zoom_Automatique( false );
updatePreviewSymbol();
Zoom_Automatique( false );
}
}

View File

@ -45,29 +45,31 @@
void LIB_VIEW_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
{
std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_COMPONENT::g_Mutex, std::defer_lock );
wxString dialogTitle;
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
// One CHOOSE_COMPONENT dialog at a time. User probaby can't handle more anyway.
if( !dialogLock.try_lock() )
return;
// Container doing search-as-you-type.
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
auto adapterPtr( SYMBOL_TREE_MODEL_ADAPTER::Create( libs ) );
auto adapter = static_cast<SYMBOL_TREE_MODEL_ADAPTER*>( adapterPtr.get() );
const auto libNicknames = libs->GetLogicalLibs();
adapter->AddLibraries( libNicknames, this );
LIB_ID id;
int unit;
wxString dialogTitle;
dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), adapter->GetItemCount() );
DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapterPtr, m_convert, false, false, false );
if( dlg.ShowQuasiModal() == wxID_CANCEL )
return;
int unit;
LIB_ID id = dlg.GetSelectedLibId( &unit );
id = dlg.GetSelectedLibId( &unit );
if( !id.IsValid() )
return;
@ -75,8 +77,6 @@ void LIB_VIEW_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
SetSelectedLibrary( id.GetLibNickname() );
SetSelectedComponent( id.GetLibItemName() );
SetUnitAndConvert( unit, 1 );
Zoom_Automatique( false );
}

View File

@ -80,6 +80,8 @@ SYMBOL_PREVIEW_WIDGET::~SYMBOL_PREVIEW_WIDGET()
{
if( m_previewItem )
m_preview->GetView()->Remove( m_previewItem );
delete m_previewItem;
}
@ -149,6 +151,7 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
if( m_previewItem )
{
view->Remove( m_previewItem );
delete m_previewItem;
m_previewItem = nullptr;
}
@ -166,11 +169,11 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
// For symbols having a De Morgan body style, use the first style
settings->m_ShowConvert = part->HasConversion() ? 1 : 0;
view->Add( alias );
m_previewItem = alias;
m_previewItem = new LIB_ALIAS( *alias, part );
view->Add( m_previewItem );
// Get the symbole size, in internal units
m_itemBBox = alias->GetPart()->GetUnitBoundingBox( aUnit, 0 );
m_itemBBox = part->GetUnitBoundingBox( aUnit, 0 );
// Calculate the draw scale to fit the drawing area
fitOnDrawArea();
@ -190,6 +193,7 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
if( m_previewItem )
{
view->Remove( m_previewItem );
delete m_previewItem;
m_previewItem = nullptr;
}
@ -203,9 +207,8 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
// For symbols having a De Morgan body style, use the first style
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
settings->m_ShowConvert = aPart->HasConversion() ? 1 : 0;
view->Add( aPart );
m_previewItem = aPart;
m_previewItem = new LIB_PART( *aPart );
view->Add( m_previewItem );
// Get the symbole size, in internal units
m_itemBBox = aPart->GetUnitBoundingBox( aUnit, 0 );

View File

@ -75,8 +75,12 @@ private:
wxStaticText* m_status;
wxSizer* m_statusSizer;
/** a local copy of the LIB_ALIAS or the LIB_PART to display on the canvas
*/
EDA_ITEM* m_previewItem;
BOX2I m_itemBBox; // The size of the current item
/// The bounding box of the current item
BOX2I m_itemBBox;
};