mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Store hierarchy expansion/collapse state
Defaults to fully expanded but stores the names for nodes that are collapsed in project local settings. Because project local settings are generally changed by modifying views or selection filters, these should be saved on close rather than only when the project is saved Fixes https://gitlab.com/kicad/code/kicad/-/issues/19276
This commit is contained in:
parent
b67b467483
commit
e379e91081
@ -354,6 +354,9 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
||||
{ "otherItems", true }
|
||||
} ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_LIST<wxString>( "schematic.hierarchy_collapsed",
|
||||
&m_SchHierarchyCollapsed, {} ) );
|
||||
|
||||
registerMigration( 1, 2,
|
||||
[&]()
|
||||
{
|
||||
|
@ -156,9 +156,10 @@ void SETTINGS_MANAGER::Save()
|
||||
if( dynamic_cast<COLOR_SETTINGS*>( settings.get() ) )
|
||||
continue;
|
||||
|
||||
// Never automatically save project settings, caller should use SaveProject or UnloadProject
|
||||
if( dynamic_cast<PROJECT_FILE*>( settings.get() )
|
||||
|| dynamic_cast<PROJECT_LOCAL_SETTINGS*>( settings.get() ) )
|
||||
// Never automatically save project file, caller should use SaveProject or UnloadProject
|
||||
// We do want to save the project local settings, though because they are generally view
|
||||
// settings that should persist even if the project is not saved
|
||||
if( dynamic_cast<PROJECT_FILE*>( settings.get() ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -246,6 +246,7 @@ void SCH_EDIT_FRAME::SaveProjectLocalSettings()
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
|
||||
localSettings.m_SchSelectionFilter = selTool->GetFilter();
|
||||
localSettings.m_SchHierarchyCollapsed = m_hierarchy->GetCollapsedPaths();
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <hierarchy_pane.h>
|
||||
#include <project/project_local_settings.h>
|
||||
#include <kiface_base.h>
|
||||
#include <wx/object.h>
|
||||
#include <wx/generic/textdlgg.h>
|
||||
@ -95,6 +96,11 @@ HIERARCHY_PANE::HIERARCHY_PANE( SCH_EDIT_FRAME* aParent ) :
|
||||
|
||||
m_events_bound = false;
|
||||
|
||||
PROJECT_LOCAL_SETTINGS& localSettings = m_frame->Prj().GetLocalSettings();
|
||||
|
||||
for( const wxString& path : localSettings.m_SchHierarchyCollapsed )
|
||||
m_collapsedPaths.insert( path );
|
||||
|
||||
UpdateHierarchyTree();
|
||||
|
||||
// Enable selection events
|
||||
@ -220,32 +226,39 @@ void HIERARCHY_PANE::UpdateHierarchyTree( bool aClear )
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy();
|
||||
std::set<SCH_SHEET_PATH> expandedNodes;
|
||||
std::set<wxString> collapsedNodes = m_collapsedPaths;
|
||||
|
||||
std::function<void( const wxTreeItemId& )> getExpandedNodes =
|
||||
std::function<void( const wxTreeItemId& )> getCollapsedNodes =
|
||||
[&]( const wxTreeItemId& id )
|
||||
{
|
||||
wxCHECK_RET( id.IsOk(), wxT( "Invalid tree item" ) );
|
||||
|
||||
TREE_ITEM_DATA* itemData = static_cast<TREE_ITEM_DATA*>( m_tree->GetItemData( id ) );
|
||||
|
||||
if( m_tree->IsExpanded( id ) && hierarchy.HasPath( itemData->m_SheetPath.Path() ) )
|
||||
expandedNodes.emplace( itemData->m_SheetPath );
|
||||
if( m_tree->ItemHasChildren( id ) && !m_tree->IsExpanded( id )
|
||||
&& hierarchy.HasPath( itemData->m_SheetPath.Path() ) )
|
||||
{
|
||||
collapsedNodes.emplace( itemData->m_SheetPath.PathAsString() );
|
||||
return;
|
||||
}
|
||||
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_tree->GetFirstChild( id, cookie );
|
||||
|
||||
while( child.IsOk() )
|
||||
{
|
||||
getExpandedNodes( child );
|
||||
getCollapsedNodes( child );
|
||||
child = m_tree->GetNextChild( id, cookie );
|
||||
}
|
||||
};
|
||||
|
||||
// If we are clearing the tree, don't try to get expanded nodes as they
|
||||
// If we are clearing the tree, don't try to get collapsed nodes as they
|
||||
// might be deleted
|
||||
if( !aClear && !m_tree->IsEmpty() )
|
||||
getExpandedNodes( m_tree->GetRootItem() );
|
||||
{
|
||||
collapsedNodes.clear();
|
||||
getCollapsedNodes( m_tree->GetRootItem() );
|
||||
}
|
||||
|
||||
m_list.clear();
|
||||
m_list.push_back( &m_frame->Schematic().Root() );
|
||||
@ -258,35 +271,35 @@ void HIERARCHY_PANE::UpdateHierarchyTree( bool aClear )
|
||||
buildHierarchyTree( &m_list, root );
|
||||
UpdateHierarchySelection();
|
||||
|
||||
if( !expandedNodes.empty() )
|
||||
{
|
||||
std::function<void( const wxTreeItemId& )> expandNodes =
|
||||
[&]( const wxTreeItemId& id )
|
||||
m_tree->ExpandAll();
|
||||
|
||||
std::function<void( const wxTreeItemId& )> collapseNodes =
|
||||
[&]( const wxTreeItemId& id )
|
||||
{
|
||||
wxCHECK_RET( id.IsOk(), wxT( "Invalid tree item" ) );
|
||||
|
||||
TREE_ITEM_DATA* itemData =
|
||||
static_cast<TREE_ITEM_DATA*>( m_tree->GetItemData( id ) );
|
||||
|
||||
if( id != root &&
|
||||
collapsedNodes.find( itemData->m_SheetPath.PathAsString() ) != collapsedNodes.end() )
|
||||
{
|
||||
wxCHECK_RET( id.IsOk(), wxT( "Invalid tree item" ) );
|
||||
m_tree->Collapse( id );
|
||||
return;
|
||||
}
|
||||
|
||||
TREE_ITEM_DATA* itemData =
|
||||
static_cast<TREE_ITEM_DATA*>( m_tree->GetItemData( id ) );
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_tree->GetFirstChild( id, cookie );
|
||||
|
||||
if( expandedNodes.find( itemData->m_SheetPath ) != expandedNodes.end() )
|
||||
m_tree->Expand( id );
|
||||
while( child.IsOk() )
|
||||
{
|
||||
collapseNodes( child );
|
||||
child = m_tree->GetNextChild( id, cookie );
|
||||
}
|
||||
};
|
||||
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_tree->GetFirstChild( id, cookie );
|
||||
|
||||
while( child.IsOk() )
|
||||
{
|
||||
expandNodes( child );
|
||||
child = m_tree->GetNextChild( id, cookie );
|
||||
}
|
||||
};
|
||||
|
||||
expandNodes( m_tree->GetRootItem() );
|
||||
}
|
||||
else if( m_tree->ItemHasChildren( root ) )
|
||||
{
|
||||
m_tree->Expand( root );
|
||||
}
|
||||
collapseNodes( root );
|
||||
m_collapsedPaths = std::move( collapsedNodes );
|
||||
|
||||
if( eventsWereBound )
|
||||
{
|
||||
@ -359,6 +372,42 @@ void HIERARCHY_PANE::UpdateLabelsHierarchyTree()
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> HIERARCHY_PANE::GetCollapsedPaths() const
|
||||
{
|
||||
std::vector<wxString> collapsed;
|
||||
|
||||
if( m_tree->IsEmpty() )
|
||||
return collapsed;
|
||||
|
||||
std::function<void( const wxTreeItemId& )> collect =
|
||||
[&]( const wxTreeItemId& id )
|
||||
{
|
||||
wxCHECK_RET( id.IsOk(), wxT( "Invalid tree item" ) );
|
||||
|
||||
TREE_ITEM_DATA* itemData = static_cast<TREE_ITEM_DATA*>( m_tree->GetItemData( id ) );
|
||||
|
||||
if( id != m_tree->GetRootItem() && m_tree->ItemHasChildren( id )
|
||||
&& !m_tree->IsExpanded( id ) )
|
||||
{
|
||||
collapsed.push_back( itemData->m_SheetPath.PathAsString() );
|
||||
return;
|
||||
}
|
||||
|
||||
wxTreeItemIdValue cookie;
|
||||
wxTreeItemId child = m_tree->GetFirstChild( id, cookie );
|
||||
|
||||
while( child.IsOk() )
|
||||
{
|
||||
collect( child );
|
||||
child = m_tree->GetNextChild( id, cookie );
|
||||
}
|
||||
};
|
||||
|
||||
collect( m_tree->GetRootItem() );
|
||||
return collapsed;
|
||||
}
|
||||
|
||||
|
||||
void HIERARCHY_PANE::onTreeItemRightClick( wxTreeEvent& aEvent )
|
||||
{
|
||||
onRightClick( aEvent.GetItem() );
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <wx/imaglist.h>
|
||||
#include <wx/object.h> // wxRTTI macros
|
||||
#include <wx/treectrl.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "widgets/wx_panel.h"
|
||||
|
||||
|
||||
@ -98,6 +100,11 @@ public:
|
||||
*/
|
||||
void UpdateLabelsHierarchyTree();
|
||||
|
||||
/**
|
||||
* Returns a list of sheet paths for nodes that are currently collapsed.
|
||||
*/
|
||||
std::vector<wxString> GetCollapsedPaths() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create the hierarchical tree of the schematic.
|
||||
@ -149,6 +156,7 @@ private:
|
||||
HIERARCHY_TREE* m_tree;
|
||||
|
||||
bool m_events_bound;
|
||||
std::set<wxString> m_collapsedPaths;
|
||||
};
|
||||
|
||||
#endif // HIERARCHY_PANE_H
|
||||
|
@ -151,6 +151,9 @@ public:
|
||||
PCB_SELECTION_FILTER_OPTIONS m_PcbSelectionFilter;
|
||||
SCH_SELECTION_FILTER_OPTIONS m_SchSelectionFilter;
|
||||
|
||||
/// Collapsed nodes in the schematic hierarchy navigator
|
||||
std::vector<wxString> m_SchHierarchyCollapsed;
|
||||
|
||||
// Upstream git repo info
|
||||
wxString m_GitRepoUsername;
|
||||
wxString m_GitRepoType;
|
||||
|
Loading…
x
Reference in New Issue
Block a user