From a6923b3de360ca54d46d6fd8d53bc0da0edeccbf Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Tue, 8 Oct 2024 13:51:09 -0400 Subject: [PATCH] Cache full schematic sheet list sorted by sheet page number. The sheet list is returned as a copy of the cached list rather than a reference to prevent external code from changing the list. While not as performant, it eliminates the risk of the sheet list being altered in ways that could break the schematic. The sheet list should only be updated by calling SCHEMATIC::RefreshHierarchy() when any appropriate sheet changes are made. Note to developers: there is something inherently different about how the QA tests are loading and handling schematics versus the schematic editor. Using the cached sheet list for the SCHEMATIC object will cause some QA test to fail. This is why SCHEMATIC::Hierarchy() has not replaced SCHEMATIC::BuildSheetListSortedByPageNumbers() everywhere. --- eeschema/annotate.cpp | 10 ++-- eeschema/cross-probing.cpp | 6 +-- eeschema/dialogs/dialog_change_symbols.cpp | 8 +-- .../dialogs/dialog_edit_symbols_libid.cpp | 8 +-- eeschema/dialogs/dialog_field_properties.cpp | 2 +- .../dialog_global_edit_text_and_graphics.cpp | 2 +- eeschema/dialogs/dialog_sheet_properties.cpp | 2 +- .../dialogs/dialog_symbol_fields_table.cpp | 10 ++-- eeschema/dialogs/dialog_table_properties.cpp | 2 +- eeschema/dialogs/dialog_text_properties.cpp | 4 +- eeschema/eeschema.cpp | 4 +- eeschema/eeschema_helpers.cpp | 2 +- eeschema/eeschema_jobs_handler.cpp | 8 +-- eeschema/erc/erc_report.cpp | 6 +-- eeschema/files-io.cpp | 6 +-- eeschema/net_navigator.cpp | 2 +- .../netlist_exporter_allegro.cpp | 4 +- .../netlist_exporter_base.cpp | 4 +- .../netlist_exporter_cadstar.cpp | 4 +- .../netlist_exporter_orcadpcb2.cpp | 4 +- .../netlist_exporter_pads.cpp | 2 +- .../netlist_exporter_spice.cpp | 2 +- .../netlist_exporter_xml.cpp | 6 +-- .../netlist_exporters/netlist_generator.cpp | 6 +-- eeschema/printing/sch_printout.cpp | 4 +- eeschema/sch_commit.cpp | 11 ++-- eeschema/sch_edit_frame.cpp | 8 +-- eeschema/sch_field.cpp | 4 +- .../sch_io/cadstar/sch_io_cadstar_archive.cpp | 2 +- .../sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp | 4 +- eeschema/sch_screen.cpp | 6 +-- eeschema/sch_sheet.cpp | 2 +- eeschema/sch_symbol.cpp | 2 +- eeschema/schematic.cpp | 50 +++++++++++-------- eeschema/schematic.h | 18 +++++-- eeschema/schematic_undo_redo.cpp | 22 +++++++- eeschema/sheet.cpp | 6 +-- eeschema/tools/assign_footprints.cpp | 6 +-- eeschema/tools/backannotate.cpp | 4 +- eeschema/tools/sch_drawing_tools.cpp | 4 +- eeschema/tools/sch_edit_tool.cpp | 5 ++ eeschema/tools/sch_editor_control.cpp | 12 ++--- eeschema/tools/sch_find_replace_tool.cpp | 4 +- eeschema/tools/sch_navigate_tool.cpp | 12 ++--- 44 files changed, 171 insertions(+), 129 deletions(-) diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 1481b9bd32..8907567b4c 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,7 +39,7 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map& aMap ) { SCH_REFERENCE_LIST references; - Schematic().BuildUnorderedSheetList().GetSymbols( references ); + Schematic().Hierarchy().GetSymbols( references ); for( size_t i = 0; i < references.GetCount(); i++ ) { @@ -61,7 +61,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( ANNOTATE_SCOPE_T aAnnotateScope, bool aRe REPORTER& aReporter ) { - SCH_SHEET_LIST sheets = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = Schematic().Hierarchy(); SCH_SCREEN* screen = GetScreen(); SCH_SHEET_PATH currentSheet = GetCurrentSheet(); SCH_COMMIT commit( this ); @@ -219,7 +219,7 @@ void SCH_EDIT_FRAME::AnnotateSymbols( SCH_COMMIT* aCommit, ANNOTATE_SCOPE_T aAn SCH_REFERENCE_LIST references; SCH_SCREENS screens( Schematic().Root() ); - SCH_SHEET_LIST sheets = Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = Schematic().Hierarchy(); SCH_SHEET_PATH currentSheet = GetCurrentSheet(); @@ -463,7 +463,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( ANNOTATION_ERROR_HANDLER aErrorHandler, { SCH_REFERENCE_LIST referenceList; constexpr bool includePowerSymbols = false; - SCH_SHEET_LIST sheets = Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = Schematic().Hierarchy(); SCH_SHEET_PATH currentSheet = GetCurrentSheet(); // Build the list of symbols diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index c68d28c588..ea6b0abafb 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -54,7 +54,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindSymbolAndItem( const wxString* aPath, const wx if( !aSearchHierarchy ) sheetList.push_back( m_frame->GetCurrentSheet() ); else - sheetList = m_frame->Schematic().BuildSheetListSortedByPageNumbers(); + sheetList = m_frame->Schematic().Hierarchy(); for( SCH_SHEET_PATH& sheet : sheetList ) { @@ -620,7 +620,7 @@ findItemsFromSyncSelection( const SCHEMATIC& aSchematic, const std::string aSync std::optional> focusPin; std::unordered_map> focusItemResults; - const SCH_SHEET_LIST allSheetsList = aSchematic.BuildUnorderedSheetList(); + const SCH_SHEET_LIST allSheetsList = aSchematic.Hierarchy(); // In orderedSheets, the current sheet comes first. std::vector orderedSheets; diff --git a/eeschema/dialogs/dialog_change_symbols.cpp b/eeschema/dialogs/dialog_change_symbols.cpp index 97d790f0b9..b8c4e7a7ea 100644 --- a/eeschema/dialogs/dialog_change_symbols.cpp +++ b/eeschema/dialogs/dialog_change_symbols.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020-2021 CERN - * Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * @author Wayne Stambaugh * @@ -289,7 +289,7 @@ void DIALOG_CHANGE_SYMBOLS::updateFieldsList() std::vector libFields; std::set fieldNames; - for( SCH_SHEET_PATH& instance : frame->Schematic().BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& instance : frame->Schematic().Hierarchy() ) { SCH_SCREEN* screen = instance.LastScreen(); @@ -495,7 +495,7 @@ int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols( SCH_COMMIT* aCommit ) std::map symbols; - for( SCH_SHEET_PATH& instance : frame->Schematic().BuildSheetListSortedByPageNumbers() ) + for( SCH_SHEET_PATH& instance : frame->Schematic().Hierarchy() ) { SCH_SCREEN* screen = instance.LastScreen(); @@ -796,7 +796,7 @@ wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, wxCHECK( parent, msg ); - SCH_SHEET_LIST sheets = parent->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = parent->Schematic().Hierarchy(); for( const SCH_SYMBOL_INSTANCE& instance : aSymbol.GetInstances() ) { diff --git a/eeschema/dialogs/dialog_edit_symbols_libid.cpp b/eeschema/dialogs/dialog_edit_symbols_libid.cpp index 4265c95384..a2aa3b1f46 100644 --- a/eeschema/dialogs/dialog_edit_symbols_libid.cpp +++ b/eeschema/dialogs/dialog_edit_symbols_libid.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright 2017 Jean-Pierre Charras, jp.charras@wanadoo.fr - * Copyright 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright 1992-2022, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -395,9 +395,9 @@ void DIALOG_EDIT_SYMBOLS_LIBID::initDlg() // build the full list of symbols including symbol having no symbol in loaded libs // (orphan symbols) - GetParent()->Schematic().BuildUnorderedSheetList().GetSymbols( references, - true /* include power symbols */, - true /* include orphan symbols */ ); + GetParent()->Schematic().Hierarchy().GetSymbols( references, + true /* include power symbols */, + true /* include orphan symbols */ ); for( unsigned ii = 0; ii < references.GetCount(); ii++ ) { diff --git a/eeschema/dialogs/dialog_field_properties.cpp b/eeschema/dialogs/dialog_field_properties.cpp index 390181f508..9c77ed783d 100644 --- a/eeschema/dialogs/dialog_field_properties.cpp +++ b/eeschema/dialogs/dialog_field_properties.cpp @@ -680,7 +680,7 @@ void DIALOG_FIELD_PROPERTIES::UpdateField( SCH_COMMIT* aCommit, SCH_FIELD* aFiel int unit = symbol->GetUnit(); LIB_ID libId = symbol->GetLibId(); - for( SCH_SHEET_PATH& sheet : editFrame->Schematic().BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheet : editFrame->Schematic().Hierarchy() ) { SCH_SCREEN* screen = sheet.LastScreen(); std::vector otherUnits; diff --git a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp index 1e956b1be9..95f0af5e15 100644 --- a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp +++ b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp @@ -583,7 +583,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow() SCH_COMMIT commit( m_parent ); // Go through sheets - for( const SCH_SHEET_PATH& sheetPath : m_parent->Schematic().BuildUnorderedSheetList() ) + for( const SCH_SHEET_PATH& sheetPath : m_parent->Schematic().Hierarchy() ) { SCH_SCREEN* screen = sheetPath.LastScreen(); diff --git a/eeschema/dialogs/dialog_sheet_properties.cpp b/eeschema/dialogs/dialog_sheet_properties.cpp index d1950fdb17..f3d9ed08ab 100644 --- a/eeschema/dialogs/dialog_sheet_properties.cpp +++ b/eeschema/dialogs/dialog_sheet_properties.cpp @@ -437,7 +437,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena // Sheet file names are relative to the path of the current sheet. This allows for // nesting of schematic files in subfolders. Screen file names are always absolute. SCHEMATIC& schematic = m_frame->Schematic(); - SCH_SHEET_LIST fullHierarchy = schematic.GetFullHierarchy(); + SCH_SHEET_LIST fullHierarchy = schematic.Hierarchy(); wxFileName screenFileName( sheetFileName ); wxFileName tmp( sheetFileName ); SCH_SCREEN* currentScreen = m_frame->GetCurrentSheet().LastScreen(); diff --git a/eeschema/dialogs/dialog_symbol_fields_table.cpp b/eeschema/dialogs/dialog_symbol_fields_table.cpp index 52373958ab..7cd3fe6824 100644 --- a/eeschema/dialogs/dialog_symbol_fields_table.cpp +++ b/eeschema/dialogs/dialog_symbol_fields_table.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 Oliver Walters - * Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -176,7 +176,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent ) m_schSettings( parent->Schematic().Settings() ) { // Get all symbols from the list of schematic sheets - m_parent->Schematic().BuildUnorderedSheetList().GetSymbols( m_symbolsList, false ); + m_parent->Schematic().Hierarchy().GetSymbols( m_symbolsList, false ); m_bRefresh->SetBitmap( KiBitmapBundle( BITMAPS::small_refresh ) ); m_bRefreshPreview->SetBitmap( KiBitmapBundle( BITMAPS::small_refresh ) ); @@ -2217,7 +2217,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsAdded( SCHEMATIC& aSch, std::vector& aSchItem ) { SCH_REFERENCE_LIST allRefs; - m_parent->Schematic().BuildUnorderedSheetList().GetSymbols( allRefs ); + m_parent->Schematic().Hierarchy().GetSymbols( allRefs ); for( SCH_ITEM* item : aSchItem ) { @@ -2286,7 +2286,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnSchItemsChanged( SCHEMATIC& aSch std::vector& aSchItem ) { SCH_REFERENCE_LIST allRefs; - m_parent->Schematic().BuildUnorderedSheetList().GetSymbols( allRefs ); + m_parent->Schematic().Hierarchy().GetSymbols( allRefs ); for( SCH_ITEM* item : aSchItem ) { @@ -2383,7 +2383,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::getSymbolReferences( SCH_SYMBOL* aSymbol, SCH_REFERENCE_LIST DIALOG_SYMBOL_FIELDS_TABLE::getSheetSymbolReferences( SCH_SHEET& aSheet ) { - SCH_SHEET_LIST allSheets = m_parent->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST allSheets = m_parent->Schematic().Hierarchy(); SCH_REFERENCE_LIST sheetRefs; // We need to operate on all instances of the sheet diff --git a/eeschema/dialogs/dialog_table_properties.cpp b/eeschema/dialogs/dialog_table_properties.cpp index eee168fafd..ec441bdf2c 100644 --- a/eeschema/dialogs/dialog_table_properties.cpp +++ b/eeschema/dialogs/dialog_table_properties.cpp @@ -242,7 +242,7 @@ void DIALOG_TABLE_PROPERTIES::getContextualTextVars( const wxString& aCrossRef, SCH_REFERENCE_LIST refs; SCH_SYMBOL* refSymbol = nullptr; - m_frame->Schematic().BuildUnorderedSheetList().GetSymbols( refs ); + m_frame->Schematic().Hierarchy().GetSymbols( refs ); for( int jj = 0; jj < (int) refs.GetCount(); jj++ ) { diff --git a/eeschema/dialogs/dialog_text_properties.cpp b/eeschema/dialogs/dialog_text_properties.cpp index bb59903b8e..39afd6b3bd 100644 --- a/eeschema/dialogs/dialog_text_properties.cpp +++ b/eeschema/dialogs/dialog_text_properties.cpp @@ -166,7 +166,7 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_BASE_FRAME* aParent, SCH_ITE { const SCHEMATIC& schematic = schematicEditor->Schematic(); - for( const SCH_SHEET_PATH& sheet : schematic.BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : schematic.Hierarchy() ) { wxString sheetPageNum = sheet.GetPageNumber(); wxString sheetName = sheet.size() == 1 ? _( "" ) @@ -230,7 +230,7 @@ void DIALOG_TEXT_PROPERTIES::getContextualTextVars( const wxString& aCrossRef, if( schematic ) { SCH_REFERENCE_LIST refs; - schematic->BuildUnorderedSheetList().GetSymbols( refs ); + schematic->Hierarchy().GetSymbols( refs ); for( int jj = 0; jj < (int) refs.GetCount(); jj++ ) { diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index 600cad28ec..dfb5103be6 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -94,7 +94,7 @@ static std::unique_ptr readSchematicFromFile( const std::string& aFil for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) screen->UpdateLocalLibSymbolLinks(); - SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = schematic->Hierarchy(); // Restore all of the loaded symbol instances from the root sheet screen. sheets.UpdateSymbolInstanceData( schematic->RootScreen()->GetSymbolInstances() ); @@ -704,4 +704,4 @@ int IFACE::HandleJob( JOB* aJob ) bool IFACE::HandleJobConfig( JOB* aJob, wxWindow* aParent ) { return m_jobHandler->HandleJobConfig( aJob, aParent ); -} \ No newline at end of file +} diff --git a/eeschema/eeschema_helpers.cpp b/eeschema/eeschema_helpers.cpp index 887b3111ab..ebe2b5d560 100644 --- a/eeschema/eeschema_helpers.cpp +++ b/eeschema/eeschema_helpers.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2022 KiCad Developers, see AUTHORS.TXT for contributors. + * Copyright (C) 2022, 2024 KiCad Developers, see AUTHORS.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index b2364ae172..fdef58e01e 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2022 Mark Roszko - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -348,7 +348,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob ) // Annotation warning check SCH_REFERENCE_LIST referenceList; - sch->BuildUnorderedSheetList().GetSymbols( referenceList ); + sch->Hierarchy().GetSymbols( referenceList ); if( referenceList.GetCount() > 0 ) { @@ -458,7 +458,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob ) // Annotation warning check SCH_REFERENCE_LIST referenceList; - sch->BuildUnorderedSheetList().GetSymbols( referenceList, false, false ); + sch->Hierarchy().GetSymbols( referenceList, false, false ); if( referenceList.GetCount() > 0 ) { @@ -711,7 +711,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob ) // Annotation warning check SCH_REFERENCE_LIST referenceList; - sch->BuildUnorderedSheetList().GetSymbols( referenceList ); + sch->Hierarchy().GetSymbols( referenceList ); if( referenceList.GetCount() > 0 ) { diff --git a/eeschema/erc/erc_report.cpp b/eeschema/erc/erc_report.cpp index ab7a36ea61..61427feeb4 100644 --- a/eeschema/erc/erc_report.cpp +++ b/eeschema/erc/erc_report.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -121,7 +121,7 @@ bool ERC_REPORT::WriteJsonReport( const wxString& aFullFileName ) reportHead.kicad_version = GetMajorMinorPatchVersion(); reportHead.coordinate_units = EDA_UNIT_UTILS::GetLabel( m_reportUnits ); - SCH_SHEET_LIST sheetList = m_sch->BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheetList = m_sch->Hierarchy(); sheetList.FillItemMap( itemMap ); ERC_SETTINGS& settings = m_sch->ErcSettings(); @@ -156,4 +156,4 @@ bool ERC_REPORT::WriteJsonReport( const wxString& aFullFileName ) jsonFileStream.close(); return true; -} \ No newline at end of file +} diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index a7102888ae..bd1466c662 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -334,7 +334,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // It's possible the schematic parser fixed errors due to bugs so warn the user // that the schematic has been fixed (modified). - SCH_SHEET_LIST sheetList = Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheetList = Schematic().Hierarchy(); if( sheetList.IsModified() ) { @@ -1022,7 +1022,7 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs ) } // Attempt to make sheet file name paths relative to the new root schematic path. - for( SCH_SHEET_PATH& sheet : Schematic().BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheet : Schematic().Hierarchy() ) { if( !sheet.Last()->IsRootSheet() ) sheet.MakeFilePathRelativeToParentSheet(); @@ -1185,7 +1185,7 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs ) std::vector& sheets = Prj().GetProjectFile().GetSheets(); sheets.clear(); - for( SCH_SHEET_PATH& sheetPath : Schematic().BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheetPath : Schematic().Hierarchy() ) { SCH_SHEET* sheet = sheetPath.Last(); diff --git a/eeschema/net_navigator.cpp b/eeschema/net_navigator.cpp index 0453629781..f5205436c2 100644 --- a/eeschema/net_navigator.cpp +++ b/eeschema/net_navigator.cpp @@ -260,7 +260,7 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect if( !m_netNavigator->IsShown() ) return; - bool singleSheetSchematic = m_schematic->BuildUnorderedSheetList().size() == 1; + bool singleSheetSchematic = m_schematic->Hierarchy().size() == 1; size_t nodeCnt = 0; m_netNavigator->Freeze(); diff --git a/eeschema/netlist_exporters/netlist_exporter_allegro.cpp b/eeschema/netlist_exporters/netlist_exporter_allegro.cpp index 7d827cee28..0f4d89fec1 100644 --- a/eeschema/netlist_exporters/netlist_exporter_allegro.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_allegro.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -136,7 +136,7 @@ void NETLIST_EXPORTER_ALLEGRO::extractComponentsInfo() m_referencesAlreadyFound.Clear(); m_libParts.clear(); - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { m_schematic->SetCurrentSheet( sheet ); diff --git a/eeschema/netlist_exporters/netlist_exporter_base.cpp b/eeschema/netlist_exporters/netlist_exporter_base.cpp index d9b069547d..ade6c1e85f 100644 --- a/eeschema/netlist_exporters/netlist_exporter_base.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_base.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2017 jp.charras at wanadoo.fr * Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -241,7 +241,7 @@ void NETLIST_EXPORTER_BASE::findAllUnitsOfSymbol( SCH_SYMBOL* aSchSymbol, CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph(); - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp index 1e207bda38..12520e98a1 100644 --- a/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2018 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -65,7 +65,7 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, // Create netlist footprints section m_referencesAlreadyFound.Clear(); - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp index 8a3fc9e3ee..44daad4481 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2018 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,7 +62,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, // Create netlist footprints section m_referencesAlreadyFound.Clear(); - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { // Process symbol attributes for( EDA_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) diff --git a/eeschema/netlist_exporters/netlist_exporter_pads.cpp b/eeschema/netlist_exporters/netlist_exporter_pads.cpp index 98d4653de7..ed9d5e81c1 100644 --- a/eeschema/netlist_exporters/netlist_exporter_pads.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_pads.cpp @@ -55,7 +55,7 @@ bool NETLIST_EXPORTER_PADS::WriteNetlist( const wxString& aOutFileName, // Create netlist footprints section m_referencesAlreadyFound.Clear(); - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.cpp b/eeschema/netlist_exporters/netlist_exporter_spice.cpp index b6dd752abc..34c98c8172 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_spice.cpp @@ -706,7 +706,7 @@ SCH_SHEET_LIST NETLIST_EXPORTER_SPICE::BuildSheetList( unsigned aNetlistOptions if( aNetlistOptions & OPTION_CUR_SHEET_AS_ROOT ) sheets = SCH_SHEET_LIST( m_schematic->CurrentSheet().Last() ); else - sheets = m_schematic->BuildSheetListSortedByPageNumbers(); + sheets = m_schematic->Hierarchy(); alg::delete_if( sheets, [&]( const SCH_SHEET_PATH& sheet ) diff --git a/eeschema/netlist_exporters/netlist_exporter_xml.cpp b/eeschema/netlist_exporters/netlist_exporter_xml.cpp index 123fff4af4..4e780b3ea1 100644 --- a/eeschema/netlist_exporters/netlist_exporter_xml.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_xml.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -247,7 +247,7 @@ XNODE* NETLIST_EXPORTER_XML::makeSymbols( unsigned aCtl ) m_libParts.clear(); SCH_SHEET_PATH currentSheet = m_schematic->CurrentSheet(); - SCH_SHEET_LIST sheetList = m_schematic->BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheetList = m_schematic->Hierarchy(); // Output is xml, so there is no reason to remove spaces from the field values. // And XML element names need not be translated to various languages. @@ -535,7 +535,7 @@ XNODE* NETLIST_EXPORTER_XML::makeDesignHeader() */ unsigned sheetIndex = 1; // Human readable index - for( const SCH_SHEET_PATH& sheet : m_schematic->BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_schematic->Hierarchy() ) { screen = sheet.LastScreen(); diff --git a/eeschema/netlist_exporters/netlist_generator.cpp b/eeschema/netlist_exporters/netlist_generator.cpp index 3595ba7525..a339cc6e28 100644 --- a/eeschema/netlist_exporters/netlist_generator.cpp +++ b/eeschema/netlist_exporters/netlist_generator.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2018 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2021 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 1992-2021, 2024 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -51,7 +51,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam unsigned aNetlistOptions, REPORTER* aReporter ) { // Ensure all power symbols have a valid reference - Schematic().BuildSheetListSortedByPageNumbers().AnnotatePowerSymbols(); + Schematic().Hierarchy().AnnotatePowerSymbols(); if( !ReadyToNetlist( _( "Exporting netlist requires a fully annotated schematic." ) ) ) return false; @@ -193,7 +193,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam bool SCH_EDIT_FRAME::ReadyToNetlist( const wxString& aAnnotateMessage ) { // Ensure all power symbols have a valid reference - Schematic().BuildSheetListSortedByPageNumbers().AnnotatePowerSymbols(); + Schematic().Hierarchy().AnnotatePowerSymbols(); // Symbols must be annotated if( CheckAnnotate( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* ) {} ) ) diff --git a/eeschema/printing/sch_printout.cpp b/eeschema/printing/sch_printout.cpp index 8df1eb2be1..20cff5d39b 100644 --- a/eeschema/printing/sch_printout.cpp +++ b/eeschema/printing/sch_printout.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2023 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -71,7 +71,7 @@ bool SCH_PRINTOUT::OnBeginDocument( int startPage, int endPage ) bool SCH_PRINTOUT::OnPrintPage( int page ) { - SCH_SHEET_LIST sheetList = m_parent->Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheetList = m_parent->Schematic().Hierarchy(); sheetList.SortByPageNumbers( false ); wxCHECK_MSG( page >= 1 && page <= (int)sheetList.size(), false, diff --git a/eeschema/sch_commit.cpp b/eeschema/sch_commit.cpp index 2b1ed2e7c3..24ce13c8bd 100644 --- a/eeschema/sch_commit.cpp +++ b/eeschema/sch_commit.cpp @@ -383,8 +383,13 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) if( itemsChanged.size() > 0 ) schematic->OnItemsChanged( itemsChanged ); - if( frame && refreshHierarchy ) - frame->UpdateHierarchyNavigator(); + if( refreshHierarchy ) + { + schematic->RefreshHierarchy(); + + if( frame ) + frame->UpdateHierarchyNavigator(); + } } if( !( aCommitFlags & SKIP_UNDO ) ) @@ -588,7 +593,7 @@ void SCH_COMMIT::Revert() { // Lazy eval of sheet list; this is expensive even when unsorted if( sheets.empty() ) - sheets = schematic->BuildUnorderedSheetList(); + sheets = schematic->Hierarchy(); SCH_SHEET_PATH sheet = sheets.FindSheetForScreen( screen ); symbol->SetRef( &sheet, field->GetText() ); diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index d4b87c90b8..80d8475ce6 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -1050,7 +1050,7 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) void SCH_EDIT_FRAME::doCloseWindow() { - SCH_SHEET_LIST sheetlist = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheetlist = Schematic().Hierarchy(); // Shutdown all running tools if( m_toolManager ) @@ -1763,7 +1763,7 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL wxString highlightedConn = GetHighlightedConnection(); bool hasHighlightedConn = !highlightedConn.IsEmpty(); SCHEMATIC_SETTINGS& settings = Schematic().Settings(); - SCH_SHEET_LIST list = Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST list = Schematic().Hierarchy(); SCH_COMMIT localCommit( m_toolManager ); if( !aCommit ) @@ -2275,7 +2275,7 @@ const BOX2I SCH_EDIT_FRAME::GetDocumentExtents( bool aIncludeAllVisible ) const bool SCH_EDIT_FRAME::IsContentModified() const { - return Schematic().BuildUnorderedSheetList().IsModified(); + return Schematic().Hierarchy().IsModified(); } @@ -2347,7 +2347,7 @@ void SCH_EDIT_FRAME::SaveSymbolToSchematic( const LIB_SYMBOL& aSymbol, const KIID& aSchematicSymbolUUID ) { SCH_SHEET_PATH principalPath; - SCH_SHEET_LIST sheets = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = Schematic().Hierarchy(); SCH_ITEM* item = sheets.GetItem( aSchematicSymbolUUID, &principalPath ); SCH_SYMBOL* principalSymbol = dynamic_cast( item ); SCH_COMMIT commit( m_toolManager ); diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 2e70954937..6746488d20 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -875,7 +875,7 @@ void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, SCH_REFERENCE_LIST refs; SCH_SYMBOL* refSymbol = nullptr; - schematic->BuildUnorderedSheetList().GetSymbols( refs ); + schematic->Hierarchy().GetSymbols( refs ); for( size_t jj = 0; jj < refs.GetCount(); jj++ ) { @@ -1776,4 +1776,4 @@ static struct SCH_FIELD_DESC DECLARE_ENUM_TO_WXANY( GR_TEXT_H_ALIGN_T ) -DECLARE_ENUM_TO_WXANY( GR_TEXT_V_ALIGN_T ) \ No newline at end of file +DECLARE_ENUM_TO_WXANY( GR_TEXT_V_ALIGN_T ) diff --git a/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp b/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp index a7c8c469ef..17b2e59c55 100644 --- a/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp +++ b/eeschema/sch_io/cadstar/sch_io_cadstar_archive.cpp @@ -145,7 +145,7 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi sch_plugin->SaveLibrary( libFileName.GetFullPath() ); // Link up all symbols in the design to the newly created library - for( SCH_SHEET_PATH& sheet : aSchematic->BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheet : aSchematic->Hierarchy() ) { for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) ) { diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp index b40756ff63..7a1cea44ec 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp @@ -368,7 +368,7 @@ void SCH_IO_KICAD_SEXPR::Format( SCH_SHEET* aSheet ) wxCHECK_RET( aSheet != nullptr, "NULL SCH_SHEET* object." ); wxCHECK_RET( m_schematic != nullptr, "NULL SCHEMATIC* object." ); - SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = m_schematic->Hierarchy(); SCH_SCREEN* screen = aSheet->GetScreen(); wxCHECK( screen, /* void */ ); @@ -538,7 +538,7 @@ void SCH_IO_KICAD_SEXPR::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSele wxCHECK( aSelection && aSelectionPath && aFormatter, /* void */ ); LOCALE_IO toggle; - SCH_SHEET_LIST sheets = aSchematic.BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = aSchematic.Hierarchy(); m_schematic = &aSchematic; m_out = aFormatter; diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 96d388b8d2..afb6e4001f 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1696,7 +1696,7 @@ void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetP // Search for new sheet paths, not existing in aInitialSheetPathList // and existing in sheetpathList - for( SCH_SHEET_PATH& sheetpath : sch->BuildSheetListSortedByPageNumbers() ) + for( SCH_SHEET_PATH& sheetpath : sch->Hierarchy() ) { bool path_exists = false; @@ -1836,7 +1836,7 @@ void SCH_SCREENS::UpdateSymbolLinks( REPORTER* aReporter ) wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" ); - SCH_SHEET_LIST sheets = sch->BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheets = sch->Hierarchy(); // All of the library symbols have been replaced with copies so the connection graph // pointers are stale. @@ -1935,7 +1935,7 @@ void SCH_SCREENS::BuildClientSheetPathList() for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() ) curr_screen->GetClientSheetPaths().clear(); - for( SCH_SHEET_PATH& sheetpath : sch->BuildSheetListSortedByPageNumbers() ) + for( SCH_SHEET_PATH& sheetpath : sch->Hierarchy() ) { SCH_SCREEN* used_screen = sheetpath.LastScreen(); diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index af1865cdc2..904f068b91 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -297,7 +297,7 @@ bool SCH_SHEET::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, in } else if( token->IsSameAs( wxT( "##" ) ) ) { - *token = wxString::Format( wxT( "%d" ), (int) schematic->BuildUnorderedSheetList().size() ); + *token = wxString::Format( wxT( "%d" ), (int) schematic->Hierarchy().size() ); return true; } else if( token->IsSameAs( wxT( "SHEETPATH" ) ) ) diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index 88268f0be2..1c2ef40eb5 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -1142,7 +1142,7 @@ void SCH_SYMBOL::SyncOtherUnits( const SCH_SHEET_PATH& aSourceSheet, SCH_COMMIT& { wxString ref = GetRef( &aSourceSheet ); - for( SCH_SHEET_PATH& sheet : Schematic()->BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheet : Schematic()->Hierarchy() ) { SCH_SCREEN* screen = sheet.LastScreen(); std::vector otherUnits; diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index a29cd1b1cb..be84355169 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -78,7 +78,7 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) : int unit = symbol->GetUnit(); LIB_ID libId = symbol->GetLibId(); - for( SCH_SHEET_PATH& sheet : BuildUnorderedSheetList() ) + for( SCH_SHEET_PATH& sheet : Hierarchy() ) { std::vector otherUnits; @@ -200,6 +200,7 @@ void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet ) m_currentSheet->clear(); m_currentSheet->push_back( m_rootSheet ); + m_hierarchy = BuildSheetListSortedByPageNumbers(); m_connectionGraph->Reset(); } @@ -210,6 +211,22 @@ SCH_SCREEN* SCHEMATIC::RootScreen() const } +SCH_SHEET_LIST SCHEMATIC::Hierarchy() const +{ + wxCHECK( !m_hierarchy.empty(), m_hierarchy ); + + return m_hierarchy; +} + + +void SCHEMATIC::RefreshHierarchy() +{ + wxLogDebug( wxS( "Refreshing schematic heirarchy." ) ); + + m_hierarchy = SCH_SHEET_LIST( m_rootSheet ); +} + + void SCHEMATIC::GetContextualTextVars( wxArrayString* aVars ) const { auto add = @@ -310,7 +327,7 @@ ERC_SETTINGS& SCHEMATIC::ErcSettings() const std::vector SCHEMATIC::ResolveERCExclusions() { - SCH_SHEET_LIST sheetList = BuildUnorderedSheetList(); + SCH_SHEET_LIST sheetList = Hierarchy(); ERC_SETTINGS& settings = ErcSettings(); // Migrate legacy marker exclusions to new format to ensure exclusion matching functions across @@ -392,7 +409,7 @@ std::vector SCHEMATIC::ResolveERCExclusions() std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) const { - for( const SCH_SHEET_PATH& sheet : BuildUnorderedSheetList() ) + for( const SCH_SHEET_PATH& sheet : Hierarchy() ) { for( const std::shared_ptr& alias : sheet.LastScreen()->GetBusAliases() ) { @@ -462,7 +479,7 @@ std::map SCHEMATIC::GetVirtualPageToSheetNamesMap() const { std::map namesMap; - for( const SCH_SHEET_PATH& sheet : BuildUnorderedSheetList() ) + for( const SCH_SHEET_PATH& sheet : Hierarchy() ) { if( sheet.size() == 1 ) namesMap[sheet.GetVirtualPageNumber()] = _( "" ); @@ -478,7 +495,7 @@ std::map SCHEMATIC::GetVirtualPageToSheetPagesMap() const { std::map pagesMap; - for( const SCH_SHEET_PATH& sheet : BuildUnorderedSheetList() ) + for( const SCH_SHEET_PATH& sheet : Hierarchy() ) pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber(); return pagesMap; @@ -526,7 +543,7 @@ wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const wxString ref = token.BeforeFirst( ':', &remainder ); SCH_REFERENCE_LIST references; - BuildUnorderedSheetList().GetSymbols( references ); + Hierarchy().GetSymbols( references ); for( size_t jj = 0; jj < references.GetCount(); jj++ ) { @@ -602,17 +619,6 @@ wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const } -SCH_SHEET_LIST& SCHEMATIC::GetFullHierarchy() const -{ - static SCH_SHEET_LIST hierarchy; - - hierarchy.clear(); - hierarchy.BuildSheetList( m_rootSheet, false ); - - return hierarchy; -} - - void SCHEMATIC::SetLegacySymbolInstanceData() { SCH_SCREENS screens( m_rootSheet ); @@ -649,7 +655,7 @@ void SCHEMATIC::SetSheetNumberAndCount() // @todo Remove all pseudo page number system is left over from prior to real page number // implementation. - for( const SCH_SHEET_PATH& sheet : BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : Hierarchy() ) { if( sheet.Path() == current_sheetpath ) // Current sheet path found break; @@ -672,7 +678,7 @@ void SCHEMATIC::RecomputeIntersheetRefs( const std::functionItems().OfType( SCH_GLOBAL_LABEL_T ) ) { @@ -811,7 +817,7 @@ void SCHEMATIC::RemoveAllListeners() void SCHEMATIC::RecordERCExclusions() { // Use a sorted sheetList to reduce file churn - SCH_SHEET_LIST sheetList = BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST sheetList = Hierarchy(); ERC_SETTINGS& ercSettings = ErcSettings(); ercSettings.m_ErcExclusions.clear(); @@ -836,7 +842,7 @@ void SCHEMATIC::RecordERCExclusions() void SCHEMATIC::ResolveERCExclusionsPostUpdate() { - SCH_SHEET_LIST sheetList = BuildUnorderedSheetList(); + SCH_SHEET_LIST sheetList = Hierarchy(); for( SCH_MARKER* marker : ResolveERCExclusions() ) { @@ -867,7 +873,7 @@ void SCHEMATIC::EmbedFonts() { std::set fonts; - SCH_SHEET_LIST sheetList = BuildUnorderedSheetList(); + SCH_SHEET_LIST sheetList = Hierarchy(); for( const SCH_SHEET_PATH& sheet : sheetList ) { diff --git a/eeschema/schematic.h b/eeschema/schematic.h index 529799e9c7..31a7b7bf96 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -49,6 +49,7 @@ public: virtual SCH_SHEET_PATH& CurrentSheet() const = 0; virtual wxString GetFileName() const = 0; virtual PROJECT& Prj() const = 0; + virtual SCH_SHEET_LIST Hierarchy() const = 0; }; class SCHEMATIC; @@ -105,6 +106,13 @@ public: return sheets; } + /** + * Return the full schematic flattened hierarchical sheet list. + */ + SCH_SHEET_LIST Hierarchy() const override; + + void RefreshHierarchy(); + SCH_ITEM* GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut = nullptr ) const { return BuildUnorderedSheetList().GetItem( aID, aPathOut ); @@ -193,11 +201,6 @@ public: wxString ConvertRefsToKIIDs( const wxString& aSource ) const; wxString ConvertKIIDsToRefs( const wxString& aSource ) const; - /** - * Return the full schematic flattened hierarchical sheet list. - */ - SCH_SHEET_LIST& GetFullHierarchy() const; - /** * Update the symbol value and footprint instance data for legacy designs. * @@ -380,6 +383,11 @@ private: */ std::map m_operatingPoints; + /** + * Cache of the entire schematic hierarchy sorted by sheet page number. + */ + SCH_SHEET_LIST m_hierarchy; + /** * Currently installed listeners */ diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 400a0cd305..4cbce3b1ac 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -285,6 +285,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) std::set changedTables; bool dirtyConnectivity = false; bool rebuildHierarchyNavigator = false; + bool refreshHierarchy = false; SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP; SCH_SHEET_LIST sheets; bool clearedRepeatItems = false; @@ -357,6 +358,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) if( eda_item->Type() == SCH_SHEET_T ) { rebuildHierarchyNavigator = true; + refreshHierarchy = true; if( static_cast( eda_item )->GetScreen() == GetScreen() ) GetToolManager()->PostAction( EE_ACTIONS::leaveSheet ); @@ -370,7 +372,10 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) else if( status == UNDO_REDO::DELETED ) { if( eda_item->Type() == SCH_SHEET_T ) + { rebuildHierarchyNavigator = true; + refreshHierarchy = true; + } if( schItem ) updateConnectivityFlag(); @@ -385,7 +390,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) { // Lazy eval of sheet list; this is expensive even when unsorted if( sheets.empty() ) - sheets = m_schematic->BuildUnorderedSheetList(); + sheets = m_schematic->Hierarchy(); SCH_SHEET_PATH undoSheet = sheets.FindSheetForScreen( screen ); @@ -415,7 +420,10 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) AddCopyForRepeatItem( schItem ); if( schItem->Type() == SCH_SHEET_T ) + { rebuildHierarchyNavigator = true; + refreshHierarchy = true; + } } } else if( schItem ) @@ -448,6 +456,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) { rebuildHierarchyNavigator = true; } + + // Sheet name changes do not require rebuilding the hiearchy. + if( ( origSheet->GetFileName() != copySheet->GetFileName() ) + || origSheet->HasPageNumberChanges( *copySheet ) ) + { + refreshHierarchy = true; + } } schItem->SwapData( itemCopy ); @@ -464,7 +479,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) { // Lazy eval of sheet list; this is expensive even when unsorted if( sheets.empty() ) - sheets = m_schematic->BuildUnorderedSheetList(); + sheets = m_schematic->Hierarchy(); SCH_SHEET_PATH sheet = sheets.FindSheetForScreen( screen ); symbol->SetRef( &sheet, field->GetText() ); @@ -504,6 +519,9 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) if( bulkChangedItems.size() > 0 ) Schematic().OnItemsChanged( bulkChangedItems ); + if( refreshHierarchy ) + Schematic().RefreshHierarchy(); + if( dirtyConnectivity ) { wxLogTrace( wxS( "CONN_PROFILE" ), diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 3caf1a9a90..01256f004f 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -53,7 +53,7 @@ bool SCH_EDIT_FRAME::CheckSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* wxASSERT( aSheet && aCurrentSheet ); wxString msg; - SCH_SHEET_LIST schematicSheets = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST schematicSheets = Schematic().Hierarchy(); SCH_SHEET_LIST loadedSheets( aSheet ); // This is the schematicSheets of the loaded file. wxString destFilePath = aCurrentSheet->LastScreen()->GetFileName(); @@ -282,7 +282,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aCurr } SCH_SHEET_LIST loadedSheets( tmpSheet.get() ); - SCH_SHEET_LIST schematicSheets = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST schematicSheets = Schematic().Hierarchy(); // Make sure any new sheet changes do not cause any recursion issues. if( !aSkipRecursionCheck && CheckSheetForRecursion( tmpSheet.get(), aCurrentSheet ) ) @@ -699,7 +699,7 @@ void SCH_EDIT_FRAME::DrawCurrentSheetToClipboard() bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName ) { wxString msg; - SCH_SHEET_LIST sheets = Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = Schematic().Hierarchy(); wxFileName fn = aSchematicFileName; wxCHECK( fn.IsAbsolute(), false ); diff --git a/eeschema/tools/assign_footprints.cpp b/eeschema/tools/assign_footprints.cpp index b5669b4ae8..e8e43fd2d3 100644 --- a/eeschema/tools/assign_footprints.cpp +++ b/eeschema/tools/assign_footprints.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2008 Wayne Stambaugh - * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2022, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -48,7 +48,7 @@ void SCH_EDITOR_CONTROL::AssignFootprints( const std::string& aChangedSetOfRefer bool isChanged = false; bool appendToUndoList = false; - m_frame->Schematic().BuildUnorderedSheetList().GetSymbols( refs, false ); + m_frame->Schematic().Hierarchy().GetSymbols( refs, false ); DSNLEXER lexer( aChangedSetOfReferences, From_UTF8( __func__ ) ); PTREE doc; @@ -128,7 +128,7 @@ bool SCH_EDITOR_CONTROL::processCmpToFootprintLinkFile( const wxString& aFullFil { // Build a flat list of symbols in schematic: SCH_REFERENCE_LIST referencesList; - m_frame->Schematic().BuildUnorderedSheetList().GetSymbols( referencesList, false ); + m_frame->Schematic().Hierarchy().GetSymbols( referencesList, false ); FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) ); diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index 5f587d3de3..83945e0411 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 Alexander Shuklin - * Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -80,7 +80,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist ) getPcbModulesFromString( aNetlist ); - SCH_SHEET_LIST sheets = m_frame->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = m_frame->Schematic().Hierarchy(); sheets.GetSymbols( m_refs, false ); sheets.GetMultiUnitSymbols( m_multiUnitsRefs ); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index f93088041d..827bd9d0b3 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -148,7 +148,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) // First we need to get all instances of this sheet so we can annotate // whatever symbols we place on all copies - SCH_SHEET_LIST hierarchy = m_frame->Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy(); SCH_SHEET_LIST newInstances = hierarchy.FindAllSheetsForScreen( m_frame->GetCurrentSheet().LastScreen() ); newInstances.SortByPageNumbers(); @@ -2929,7 +2929,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) sheet->SetBackgroundColor( cfg->m_Drawing.default_sheet_background_color ); sizeSheet( sheet, cursorPos ); - SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetFullHierarchy(); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy(); SCH_SHEET_PATH instance = m_frame->GetCurrentSheet(); instance.push_back( sheet ); wxString pageNumber; diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 8f188e333c..c848fca56f 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -2086,9 +2086,14 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) if( okPressed ) { if( isUndoable ) + { commit.Push( _( "Edit Sheet Properties" ) ); + } else + { + m_frame->Schematic().RefreshHierarchy(); m_frame->UpdateHierarchyNavigator(); + } } else { diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index a3199c282e..c317996f36 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -1656,7 +1656,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) EDA_ITEMS loadedItems; std::vector sortedLoadedItems; bool sheetsPasted = false; - SCH_SHEET_LIST hierarchy = m_frame->Schematic().BuildSheetListSortedByPageNumbers(); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().Hierarchy(); SCH_SHEET_PATH& pasteRoot = m_frame->GetCurrentSheet(); wxFileName destFn = pasteRoot.Last()->GetFileName(); @@ -1818,7 +1818,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // Update hierarchy to include any other sheets we already added, avoiding // duplicate sheet names - hierarchy = m_frame->Schematic().BuildSheetListSortedByPageNumbers(); + hierarchy = m_frame->Schematic().Hierarchy(); //@todo: it might be better to just iterate through the sheet names // in this screen instead of the whole hierarchy. @@ -1968,7 +1968,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // Get a version with correct sheet numbers since we've pasted sheets, // we'll need this when annotating next - hierarchy = m_frame->Schematic().BuildSheetListSortedByPageNumbers(); + hierarchy = m_frame->Schematic().Hierarchy(); } std::map annotatedSymbols; @@ -2057,7 +2057,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // schematic file. prunePastedSymbolInstances(); - SCH_SHEET_LIST sheets = m_frame->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = m_frame->Schematic().Hierarchy(); SCH_SCREENS allScreens( m_frame->Schematic().Root() ); allScreens.PruneOrphanedSymbolInstances( m_frame->Prj().GetProjectName(), sheets ); @@ -2278,7 +2278,7 @@ int SCH_EDITOR_CONTROL::IncrementAnnotations( const TOOL_EVENT& aEvent ) SCH_REFERENCE_LIST references; if( dlg.m_AllSheets->GetValue() ) - schematic->BuildSheetListSortedByPageNumbers().GetSymbols( references ); + schematic->Hierarchy().GetSymbols( references ); else schematic->CurrentSheet().GetSymbols( references ); @@ -2665,7 +2665,7 @@ int SCH_EDITOR_CONTROL::RepairSchematic( const TOOL_EVENT& aEvent ) std::map ids; int duplicates = 0; - SCH_SHEET_LIST sheets = m_frame->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = m_frame->Schematic().Hierarchy(); auto processItem = [&]( EDA_ITEM* aItem ) diff --git a/eeschema/tools/sch_find_replace_tool.cpp b/eeschema/tools/sch_find_replace_tool.cpp index 08ca0528ae..680f9a24ab 100644 --- a/eeschema/tools/sch_find_replace_tool.cpp +++ b/eeschema/tools/sch_find_replace_tool.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 CERN - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -434,7 +434,7 @@ int SCH_FIND_REPLACE_TOOL::ReplaceAll( const TOOL_EVENT& aEvent ) } else { - SCH_SHEET_LIST allSheets = m_frame->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST allSheets = m_frame->Schematic().Hierarchy(); SCH_SCREENS screens( m_frame->Schematic().Root() ); for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) diff --git a/eeschema/tools/sch_navigate_tool.cpp b/eeschema/tools/sch_navigate_tool.cpp index 9c792c8c0d..cc8585827f 100644 --- a/eeschema/tools/sch_navigate_tool.cpp +++ b/eeschema/tools/sch_navigate_tool.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 CERN - * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -42,7 +42,7 @@ void SCH_NAVIGATE_TOOL::ResetHistory() void SCH_NAVIGATE_TOOL::CleanHistory() { - SCH_SHEET_LIST sheets = m_frame->Schematic().BuildUnorderedSheetList(); + SCH_SHEET_LIST sheets = m_frame->Schematic().Hierarchy(); // Search through our history, and removing any entries // that the no longer point to a sheet on the schematic @@ -69,7 +69,7 @@ void SCH_NAVIGATE_TOOL::HypertextCommand( const wxString& href ) } else if( EDA_TEXT::IsGotoPageHref( href, &destPage ) && !destPage.IsEmpty() ) { - for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().BuildSheetListSortedByPageNumbers() ) + for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().Hierarchy() ) { if( sheet.GetPageNumber() == destPage ) { @@ -147,7 +147,7 @@ int SCH_NAVIGATE_TOOL::Previous( const TOOL_EVENT& aEvent ) if( CanGoPrevious() ) { int targetSheet = m_frame->GetCurrentSheet().GetVirtualPageNumber() - 1; - changeSheet( m_frame->Schematic().BuildSheetListSortedByPageNumbers().at( targetSheet - 1 ) ); + changeSheet( m_frame->Schematic().Hierarchy().at( targetSheet - 1 ) ); } else { @@ -163,7 +163,7 @@ int SCH_NAVIGATE_TOOL::Next( const TOOL_EVENT& aEvent ) if( CanGoNext() ) { int targetSheet = m_frame->GetCurrentSheet().GetVirtualPageNumber() + 1; - changeSheet( m_frame->Schematic().BuildSheetListSortedByPageNumbers().at( targetSheet - 1 ) ); + changeSheet( m_frame->Schematic().Hierarchy().at( targetSheet - 1 ) ); } else { @@ -201,7 +201,7 @@ bool SCH_NAVIGATE_TOOL::CanGoPrevious() bool SCH_NAVIGATE_TOOL::CanGoNext() { return m_frame->GetCurrentSheet().GetVirtualPageNumber() - < (int) m_frame->Schematic().BuildUnorderedSheetList().size(); + < (int) m_frame->Schematic().Hierarchy().size(); }