Don't allow wxDataViewCtrl updates during model update.

Also checks to make sure libraries are activated before adding
them to the component tree.

Fixes: lp:1765286
* https://bugs.launchpad.net/kicad/+bug/1765286
This commit is contained in:
Jeff Young 2018-04-28 10:43:41 +01:00
parent 5a051358b7
commit 91cfecaa12
10 changed files with 48 additions and 11 deletions

View File

@ -261,11 +261,17 @@ const wxString LIB_TABLE::GetDescription( const wxString& aNickname )
} }
bool LIB_TABLE::HasLibrary( const wxString& aNickname ) const bool LIB_TABLE::HasLibrary( const wxString& aNickname, bool aCheckEnabled ) const
{ {
const LIB_TABLE_ROW* row = findRow( aNickname ); const LIB_TABLE_ROW* row = findRow( aNickname );
return row != nullptr; if( row == nullptr )
return false;
if( aCheckEnabled && !row->GetIsEnabled() )
return false;
return true;
} }

View File

@ -80,6 +80,7 @@ CMP_TREE_MODEL_ADAPTER_BASE::CMP_TREE_MODEL_ADAPTER_BASE()
:m_filter( CMP_FILTER_NONE ), :m_filter( CMP_FILTER_NONE ),
m_show_units( true ), m_show_units( true ),
m_preselect_unit( 0 ), m_preselect_unit( 0 ),
m_freeze( 0 ),
m_col_part( nullptr ), m_col_part( nullptr ),
m_col_desc( nullptr ), m_col_desc( nullptr ),
m_widget( nullptr ) m_widget( nullptr )
@ -331,6 +332,12 @@ void CMP_TREE_MODEL_ADAPTER_BASE::GetValue(
wxDataViewItem const& aItem, wxDataViewItem const& aItem,
unsigned int aCol ) const unsigned int aCol ) const
{ {
if( IsFrozen() )
{
aVariant = wxEmptyString;
return;
}
auto node = ToNode( aItem ); auto node = ToNode( aItem );
wxASSERT( node ); wxASSERT( node );
@ -352,6 +359,9 @@ bool CMP_TREE_MODEL_ADAPTER_BASE::GetAttr(
unsigned int aCol, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const wxDataViewItemAttr& aAttr ) const
{ {
if( IsFrozen() )
return false;
auto node = ToNode( aItem ); auto node = ToNode( aItem );
wxASSERT( node ); wxASSERT( node );

View File

@ -260,6 +260,13 @@ public:
wxDataViewItem const& aItem, wxDataViewItem const& aItem,
wxDataViewItemArray& aChildren ) const override; wxDataViewItemArray& aChildren ) const override;
// Freezing/Thawing. Used when updating the table model so that we don't try and fetch
// values during updating. Primarily a problem on OSX which doesn't pay attention to the
// wxDataViewCtrl's freeze count when updating the keyWindow.
void Freeze() { m_freeze++; }
void Thaw() { m_freeze--; }
bool IsFrozen() const { return m_freeze; }
protected: protected:
static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode ); static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode );
static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem ); static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem );
@ -341,6 +348,7 @@ private:
bool m_show_units; bool m_show_units;
LIB_ID m_preselect_lib_id; LIB_ID m_preselect_lib_id;
int m_preselect_unit; int m_preselect_unit;
int m_freeze;
wxDataViewColumn* m_col_part; wxDataViewColumn* m_col_part;
wxDataViewColumn* m_col_desc; wxDataViewColumn* m_col_desc;

View File

@ -125,7 +125,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibrary(
for( unsigned ii = 0; ii < liblist.GetCount(); ii++ ) for( unsigned ii = 0; ii < liblist.GetCount(); ii++ )
{ {
if( libs->HasLibrary( liblist[ii] ) ) if( libs->HasLibrary( liblist[ii], true ) )
{ {
loaded = true; loaded = true;
adapter->AddLibrary( liblist[ii] ); adapter->AddLibrary( liblist[ii] );

View File

@ -453,8 +453,12 @@ void LIB_EDIT_FRAME::OnToggleSearchTree( wxCommandEvent& event )
void LIB_EDIT_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent ) void LIB_EDIT_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
{ {
m_libMgr->GetAdapter()->Freeze();
SCH_BASE_FRAME::OnEditSymbolLibTable( aEvent ); SCH_BASE_FRAME::OnEditSymbolLibTable( aEvent );
SyncLibraries( true ); SyncLibraries( true );
m_libMgr->GetAdapter()->Thaw();
} }

View File

@ -560,7 +560,7 @@ bool LIB_MANAGER::PartExists( const wxString& aAlias, const wxString& aLibrary )
} }
bool LIB_MANAGER::LibraryExists( const wxString& aLibrary ) const bool LIB_MANAGER::LibraryExists( const wxString& aLibrary, bool aCheckEnabled ) const
{ {
if( aLibrary.IsEmpty() ) if( aLibrary.IsEmpty() )
return false; return false;
@ -568,7 +568,7 @@ bool LIB_MANAGER::LibraryExists( const wxString& aLibrary ) const
if( m_libs.count( aLibrary ) > 0 ) if( m_libs.count( aLibrary ) > 0 )
return true; return true;
return symTable()->HasLibrary( aLibrary ); return symTable()->HasLibrary( aLibrary, aCheckEnabled );
} }

View File

@ -144,9 +144,10 @@ public:
bool PartExists( const wxString& aAlias, const wxString& aLibrary ) const; bool PartExists( const wxString& aAlias, const wxString& aLibrary ) const;
/** /**
* Returns true if library exists. * Returns true if library exists. If \a aCheckEnabled is set, then the library must
* also be enabled in the library table.
*/ */
bool LibraryExists( const wxString& aLibrary ) const; bool LibraryExists( const wxString& aLibrary, bool aCheckEnabled = false ) const;
/** /**
* Returns true if library has unsaved modifications. * Returns true if library has unsaved modifications.

View File

@ -80,7 +80,7 @@ void LIB_MANAGER_ADAPTER::Sync( bool aForce, std::function<void(int, int, const
nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS; nextUpdate = wxGetUTCTimeMillis() + PROGRESS_INTERVAL_MILLIS;
} }
if( !m_libMgr->LibraryExists( name ) ) if( !m_libMgr->LibraryExists( name, true ) )
{ {
it = deleteLibrary( it ); it = deleteLibrary( it );
continue; continue;
@ -202,6 +202,12 @@ CMP_TREE_NODE* LIB_MANAGER_ADAPTER::findLibrary( const wxString& aLibNickName )
void LIB_MANAGER_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem, void LIB_MANAGER_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
unsigned int aCol ) const unsigned int aCol ) const
{ {
if( IsFrozen() )
{
aVariant = wxEmptyString;
return;
}
auto node = ToNode( aItem ); auto node = ToNode( aItem );
wxASSERT( node ); wxASSERT( node );
@ -235,6 +241,9 @@ void LIB_MANAGER_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& a
bool LIB_MANAGER_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol, bool LIB_MANAGER_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const wxDataViewItemAttr& aAttr ) const
{ {
if( IsFrozen() )
return false;
// change attributes only for the name field // change attributes only for the name field
if( aCol != 0 ) if( aCol != 0 )
return false; return false;

View File

@ -356,9 +356,10 @@ public:
/** /**
* Test for the existence of \a aNickname in the library table. * Test for the existence of \a aNickname in the library table.
* *
* @param aCheckEnabled if true will only return true for enabled libraries
* @return true if a library \a aNickname exists in the table. * @return true if a library \a aNickname exists in the table.
*/ */
bool HasLibrary( const wxString& aNickname ) const; bool HasLibrary( const wxString& aNickname, bool aCheckEnabled = false ) const;
/** /**
* Return the logical library names, all of them that are pertinent to * Return the logical library names, all of them that are pertinent to

View File

@ -168,7 +168,6 @@ public:
{ {
LIB_TABLE_ROWS_ITER start = begin() + aPos; LIB_TABLE_ROWS_ITER start = begin() + aPos;
erase( start, start + aNumRows ); erase( start, start + aNumRows );
if( GetView() ) if( GetView() )
{ {
wxGridTableMessage msg( this, wxGridTableMessage msg( this,
@ -178,7 +177,6 @@ public:
GetView()->ProcessTableMessage( msg ); GetView()->ProcessTableMessage( msg );
} }
return true; return true;
} }