Implement a different solution to refreshing lib trees.

Fixes https://gitlab.com/kicad/code/kicad/issues/4110
This commit is contained in:
Jeff Young 2020-03-31 02:09:01 +01:00
parent 3047cf5419
commit 13d3f57fce
4 changed files with 40 additions and 35 deletions

View File

@ -386,19 +386,16 @@ unsigned int LIB_TREE_MODEL_ADAPTER::GetChildren( wxDataViewItem const& aItem,
}
void LIB_TREE_MODEL_ADAPTER::RefreshTree( LIB_TREE_NODE* aNode )
void LIB_TREE_MODEL_ADAPTER::RefreshTree()
{
if( !aNode )
aNode = &m_tree;
// Yes, this is an enormous hack. But it works on all platforms, it doesn't suffer
// the On^2 sorting issues that ItemChanged() does on OSX, and it doesn't lose the
// user's scroll position (which re-attaching or deleting/re-inserting columns does).
static int walk = 1;
for( auto const& child: aNode->m_Children )
{
if( child->m_Score > 0 )
{
RefreshTree( child.get() );
ItemChanged( ToItem( aNode ) );
}
}
m_col_part->SetWidth( m_col_part->GetWidth() + walk );
m_col_desc->SetWidth( m_col_desc->GetWidth() - walk );
walk = -walk;
}

View File

@ -270,7 +270,7 @@ public:
void Thaw() { m_freeze--; }
bool IsFrozen() const { return m_freeze; }
void RefreshTree( LIB_TREE_NODE* aNode = nullptr );
void RefreshTree();
// Allows subclasses to nominate a context menu handler.
virtual TOOL_INTERACTIVE* GetContextMenuTool() { return nullptr; }

View File

@ -105,7 +105,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Sync( bool aForce,
}
// Look for new libraries
for( const auto& libName : m_libMgr->GetLibraryNames() )
for( const wxString& libName : m_libMgr->GetLibraryNames() )
{
if( m_libHashes.count( libName ) == 0 )
{
@ -116,8 +116,8 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Sync( bool aForce,
}
SYMBOL_LIB_TABLE_ROW* library = m_libMgr->GetLibrary( libName );
LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( libName, library->GetDescr() );
auto& lib_node = DoAddLibraryNode( libName, library->GetDescr() );
updateLibrary( lib_node );
}
}
@ -130,7 +130,7 @@ int SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetLibrariesCount() const
{
int count = LIB_TREE_MODEL_ADAPTER::GetLibrariesCount();
for( const auto& libName : m_libMgr->GetLibraryNames() )
for( const wxString& libName : m_libMgr->GetLibraryNames() )
{
if( m_libHashes.count( libName ) == 0 )
++count;
@ -147,7 +147,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
if( hashIt == m_libHashes.end() )
{
// add a new library
for( auto alias : m_libMgr->GetAliases( aLibNode.m_Name ) )
for( LIB_PART* alias : m_libMgr->GetAliases( aLibNode.m_Name ) )
aLibNode.AddItem( alias );
}
else if( hashIt->second != m_libMgr->GetLibraryHash( aLibNode.m_Name ) )
@ -179,7 +179,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
}
// now the aliases list contains only new aliases that need to be added to the tree
for( auto alias : aliases )
for( LIB_PART* alias : aliases )
aLibNode.AddItem( alias );
}
@ -207,29 +207,38 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataVie
return;
}
auto node = ToNode( aItem );
LIB_TREE_NODE* node = ToNode( aItem );
wxASSERT( node );
switch( aCol )
{
case 0:
aVariant = node->m_Name;
if( m_frame->GetCurPart() && m_frame->GetCurPart()->GetLibId() == node->m_LibId )
node->m_Name = m_frame->GetCurPart()->GetLibId().GetLibItemName();
if( node->m_Pinned )
aVariant = GetPinningSymbol() + node->m_Name;
else
aVariant = node->m_Name;
// mark modified libs with an asterisk
if( node->m_Type == LIB_TREE_NODE::LIB && m_libMgr->IsLibraryModified( node->m_Name ) )
aVariant = aVariant.GetString() + " *";
// mark modified parts with an aster-ix
if( node->m_Type == LIB_TREE_NODE::LIBID
&& m_libMgr->IsPartModified( node->m_Name, node->m_Parent->m_Name ) )
aVariant = aVariant.GetString() + " *";
// mark modified items with an asterisk
if( node->m_Type == LIB_TREE_NODE::LIB )
{
if( m_libMgr->IsLibraryModified( node->m_Name ) )
aVariant = aVariant.GetString() + " *";
}
else if( node->m_Type == LIB_TREE_NODE::LIBID )
{
if( m_libMgr->IsPartModified( node->m_Name, node->m_Parent->m_Name ) )
aVariant = aVariant.GetString() + " *";
}
break;
case 1:
if( m_frame->GetCurPart() && m_frame->GetCurPart()->GetLibId() == node->m_LibId )
node->m_Desc = m_frame->GetCurPart()->GetDescription();
aVariant = node->m_Desc;
break;
@ -250,7 +259,7 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
if( aCol != 0 )
return false;
auto node = ToNode( aItem );
LIB_TREE_NODE* node = ToNode( aItem );
wxCHECK( node, false );
switch( node->m_Type )

View File

@ -171,17 +171,13 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
case 0:
if( node->m_LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
{
auto mod = m_frame->GetBoard()->GetFirstModule();
wxASSERT( mod );
wxString currentFPName = mod->GetFPID().GetLibItemName();
node->m_Name = m_frame->GetLoadedFPID().GetLibItemName();
// mark modified part with an asterisk
if( m_frame->GetScreen()->IsModify() )
aVariant = currentFPName + " *";
aVariant = node->m_Name + " *";
else
aVariant = currentFPName;
aVariant = node->m_Name;
}
else if( node->m_Pinned )
aVariant = GetPinningSymbol() + node->m_Name;
@ -190,6 +186,9 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
break;
case 1:
if( node->m_LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
node->m_Desc = m_frame->GetBoard()->GetFirstModule()->GetDescription();
aVariant = node->m_Desc;
break;