From d7bd4c9b047c2e151b6acf7ff29129af2418d27c Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Tue, 12 May 2020 22:00:37 -0400 Subject: [PATCH] Move Eeschema globals to new SCHEMATIC object Set up a new lineage for SCH_ITEMS to get back to the SCHEMATIC they live on: Items will all be parented to the SCH_SCREEN that they are added to, and each SCH_SCREEN will point back to the SCHEMATIC that it is part of. Note that this hierarchy is not the same as the actual schematic hierarchy, which continues to be managed through SCH_SHEETs and SCH_SHEET_PATHS. --- common/dialogs/dialog_page_settings.cpp | 7 +- eeschema/CMakeLists.txt | 1 + eeschema/annotate.cpp | 28 ++- eeschema/connection_graph.cpp | 57 +++-- eeschema/connection_graph.h | 42 ++-- eeschema/cross-probing.cpp | 39 ++-- eeschema/dialogs/dialog_bom.cpp | 3 +- eeschema/dialogs/dialog_bus_manager.cpp | 8 +- .../dialogs/dialog_edit_components_libid.cpp | 3 +- eeschema/dialogs/dialog_edit_label.cpp | 15 +- eeschema/dialogs/dialog_erc.cpp | 55 ++--- .../dialogs/dialog_fields_editor_global.cpp | 4 +- .../dialog_global_edit_text_and_graphics.cpp | 7 +- eeschema/dialogs/dialog_migrate_buses.cpp | 11 +- eeschema/dialogs/dialog_netlist.cpp | 3 +- eeschema/dialogs/dialog_plot_schematic.cpp | 4 +- .../dialogs/dialog_print_using_printer.cpp | 15 +- .../dialogs/dialog_sch_import_settings.cpp | 3 +- eeschema/dialogs/dialog_sch_sheet_props.cpp | 22 +- eeschema/dialogs/dialog_schematic_setup.cpp | 6 +- eeschema/dialogs/dialog_symbol_remap.cpp | 12 +- eeschema/dialogs/dialog_symbol_remap.h | 2 + eeschema/dialogs/dialog_update_from_pcb.cpp | 2 +- eeschema/eeschema_config.cpp | 34 +-- eeschema/erc.cpp | 17 +- eeschema/erc.h | 9 +- eeschema/files-io.cpp | 67 +++--- eeschema/general.h | 28 --- eeschema/getpart.cpp | 2 +- eeschema/hierarch.cpp | 11 +- eeschema/lib_pin.cpp | 8 +- eeschema/libarch.cpp | 7 +- eeschema/menubar.cpp | 73 ++++--- .../netlist_exporters/netlist_exporter.cpp | 2 +- eeschema/netlist_exporters/netlist_exporter.h | 9 +- .../netlist_exporter_cadstar.cpp | 2 +- .../netlist_exporter_cadstar.h | 4 +- .../netlist_exporter_generic.cpp | 9 +- .../netlist_exporter_generic.h | 3 +- .../netlist_exporter_kicad.h | 3 +- .../netlist_exporter_orcadpcb2.cpp | 2 +- .../netlist_exporter_orcadpcb2.h | 4 +- .../netlist_exporter_pspice.cpp | 5 +- .../netlist_exporter_pspice.h | 7 +- eeschema/netlist_generator.cpp | 30 +-- eeschema/netlist_object.cpp | 6 +- eeschema/plot_schematic_DXF.cpp | 3 +- eeschema/plot_schematic_HPGL.cpp | 3 +- eeschema/plot_schematic_PDF.cpp | 3 +- eeschema/plot_schematic_PS.cpp | 3 +- eeschema/plot_schematic_SVG.cpp | 3 +- eeschema/project_rescue.cpp | 36 ++-- eeschema/project_rescue.h | 13 +- eeschema/sch_base_frame.cpp | 29 --- eeschema/sch_bus_entry.cpp | 9 +- eeschema/sch_component.cpp | 33 ++- eeschema/sch_connection.cpp | 6 +- eeschema/sch_connection.h | 12 ++ eeschema/sch_eagle_plugin.cpp | 19 +- eeschema/sch_eagle_plugin.h | 5 +- eeschema/sch_edit_frame.cpp | 196 ++++++++--------- eeschema/sch_edit_frame.h | 17 +- eeschema/sch_field.cpp | 5 +- eeschema/sch_io_mgr.h | 3 +- eeschema/sch_item.cpp | 27 ++- eeschema/sch_item.h | 14 ++ eeschema/sch_legacy_plugin.cpp | 21 +- eeschema/sch_legacy_plugin.h | 3 +- eeschema/sch_line.cpp | 7 +- eeschema/sch_marker.cpp | 11 +- eeschema/sch_painter.cpp | 25 ++- eeschema/sch_painter.h | 8 + eeschema/sch_plugin.cpp | 4 +- eeschema/sch_screen.cpp | 77 +++---- eeschema/sch_screen.h | 20 +- eeschema/sch_sexpr_plugin.cpp | 14 +- eeschema/sch_sexpr_plugin.h | 3 +- eeschema/sch_sheet.cpp | 53 ++--- eeschema/sch_sheet.h | 21 +- eeschema/sch_sheet_path.cpp | 145 +++---------- eeschema/sch_sheet_path.h | 40 +--- eeschema/sch_text.cpp | 40 +++- eeschema/schematic.cpp | 203 ++++++++++++++++++ eeschema/schematic.h | 179 +++++++++++++++ eeschema/sheet.cpp | 19 +- eeschema/sim/netlist_exporter_pspice_sim.h | 5 +- eeschema/sim/sim_plot_frame.cpp | 3 +- eeschema/tools/backanno.cpp | 5 +- eeschema/tools/backannotate.cpp | 3 +- eeschema/tools/ee_selection_tool.cpp | 73 ++++--- eeschema/tools/lib_control.cpp | 3 +- eeschema/tools/sch_drawing_tools.cpp | 21 +- eeschema/tools/sch_edit_tool.cpp | 26 +-- eeschema/tools/sch_editor_control.cpp | 90 ++++---- eeschema/tools/sch_line_wire_bus_tool.cpp | 11 +- include/core/typeinfo.h | 2 + .../sim/test_netlist_exporter_pspice_sim.cpp | 3 +- qa/eeschema/test_sch_sheet.cpp | 21 +- qa/eeschema/test_sch_sheet_path.cpp | 2 +- 99 files changed, 1361 insertions(+), 930 deletions(-) create mode 100644 eeschema/schematic.cpp create mode 100644 eeschema/schematic.h diff --git a/common/dialogs/dialog_page_settings.cpp b/common/dialogs/dialog_page_settings.cpp index b9c02b651e..611f27d65f 100644 --- a/common/dialogs/dialog_page_settings.cpp +++ b/common/dialogs/dialog_page_settings.cpp @@ -43,7 +43,9 @@ #ifdef EESCHEMA #include +#include #include +#include #include #endif @@ -611,8 +613,11 @@ bool DIALOG_PAGES_SETTINGS::SavePageSettings() #ifdef EESCHEMA + wxCHECK_MSG( dynamic_cast( m_parent ), true, + "DIALOG_PAGES_SETTINGS::OnDateApplyClick frame is not a schematic frame!" ); + // Exports settings to other sheets if requested: - SCH_SCREENS ScreenList; + SCH_SCREENS ScreenList( dynamic_cast( m_parent )->Schematic().Root() ); // Update page info and/or title blocks for all screens for( SCH_SCREEN* screen = ScreenList.GetFirst(); screen; screen = ScreenList.GetNext() ) diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 1d3c7e2150..effce305a0 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -216,6 +216,7 @@ set( EESCHEMA_SRCS sch_sheet_pin.cpp sch_text.cpp sch_validators.cpp + schematic.cpp schematic_undo_redo.cpp sch_edit_frame.cpp sheet.cpp diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index ba4e3e0d6f..13e032146a 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -28,17 +28,17 @@ #include #include #include +#include #include #include -void mapExistingAnnotation( std::map& aMap ) +void SCH_EDIT_FRAME::mapExistingAnnotation( std::map& aMap ) { - SCH_SHEET_LIST sheets( g_RootSheet ); SCH_REFERENCE_LIST references; - sheets.GetComponents( references ); + Schematic().GetSheets().GetComponents( references ); for( size_t i = 0; i < references.GetCount(); i++ ) { @@ -64,16 +64,16 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly ) { SCH_SCREEN* screen = GetScreen(); wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) ); - screen->ClearAnnotation( g_CurrentSheet ); + screen->ClearAnnotation( &GetCurrentSheet() ); } else { - SCH_SCREENS ScreenList; + SCH_SCREENS ScreenList( Schematic().Root() ); ScreenList.ClearAnnotation(); } // Update the references for the sheet that is currently being displayed. - g_CurrentSheet->UpdateAllScreenReferences(); + GetCurrentSheet().UpdateAllScreenReferences(); SyncView(); GetCanvas()->Refresh(); @@ -92,10 +92,10 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, { SCH_REFERENCE_LIST references; - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); // Build the sheet list. - SCH_SHEET_LIST sheets( g_RootSheet ); + SCH_SHEET_LIST sheets = Schematic().GetSheets(); // Map of locked components SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents; @@ -124,7 +124,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, if( aAnnotateSchematic ) sheets.GetMultiUnitComponents( lockedComponents ); else - g_CurrentSheet->GetMultiUnitComponents( lockedComponents ); + GetCurrentSheet().GetMultiUnitComponents( lockedComponents ); } // Store previous annotations for building info messages @@ -141,7 +141,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, if( aAnnotateSchematic ) sheets.GetComponents( references ); else - g_CurrentSheet->GetComponents( references ); + GetCurrentSheet().GetComponents( references ); // Break full components reference in name (prefix) and number: // example: IC1 become IC, and 1 @@ -229,7 +229,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, aReporter.ReportTail( _( "Annotation complete." ), RPT_SEVERITY_ACTION ); // Update on screen references, that can be modified by previous calculations: - g_CurrentSheet->UpdateAllScreenReferences(); + GetCurrentSheet().UpdateAllScreenReferences(); SetSheetNumberAndCount(); SyncView(); @@ -240,15 +240,13 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly ) { - // build the screen list - SCH_SHEET_LIST sheetList( g_RootSheet ); SCH_REFERENCE_LIST componentsList; // Build the list of components if( !aOneSheetOnly ) - sheetList.GetComponents( componentsList ); + Schematic().GetSheets().GetComponents( componentsList ); else - g_CurrentSheet->GetComponents( componentsList ); + GetCurrentSheet().GetComponents( componentsList ); // Empty schematic does not need annotation if( componentsList.GetCount() == 0 ) diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 96d170a3ce..d5d9db25ad 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -297,7 +298,10 @@ void CONNECTION_SUBGRAPH::UpdateItemConnections() SCH_CONNECTION* item_conn = item->Connection( m_sheet ); if( !item_conn ) + { item_conn = item->InitializeConnection( m_sheet ); + item_conn->SetGraph( m_graph ); + } if( ( m_driver_connection->IsBus() && item_conn->IsNet() ) || ( m_driver_connection->IsNet() && item_conn->IsBus() ) ) @@ -432,7 +436,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, for( SCH_SHEET_PIN* pin : static_cast( item )->GetPins() ) { if( !pin->Connection( aSheet ) ) - pin->InitializeConnection( aSheet ); + pin->InitializeConnection( aSheet )->SetGraph( this ); pin->ConnectedItems( aSheet ).clear(); pin->Connection( aSheet )->Reset(); @@ -454,7 +458,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, for( SCH_PIN* pin : component->GetSchPins( &aSheet ) ) { - pin->InitializeConnection( aSheet ); + pin->InitializeConnection( aSheet )->SetGraph( this ); wxPoint pos = pin->GetPosition(); @@ -475,6 +479,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, { m_items.insert( item ); auto conn = item->InitializeConnection( aSheet ); + conn->SetGraph( this ); // Set bus/net property here so that the propagation code uses it switch( item->Type() ) @@ -636,8 +641,9 @@ void CONNECTION_GRAPH::updateItemConnectivity( SCH_SHEET_PATH aSheet, void CONNECTION_GRAPH::buildConnectionGraph() { // Recache all bus aliases for later use + wxCHECK_RET( m_schematic, "Connection graph cannot be built without schematic pointer" ); - SCH_SHEET_LIST all_sheets( g_RootSheet ); + SCH_SHEET_LIST all_sheets = m_schematic->GetSheets(); for( unsigned i = 0; i < all_sheets.size(); i++ ) { @@ -656,7 +662,7 @@ void CONNECTION_GRAPH::buildConnectionGraph() if( connection->SubgraphCode() == 0 ) { - auto subgraph = new CONNECTION_SUBGRAPH( m_frame ); + auto subgraph = new CONNECTION_SUBGRAPH( this ); subgraph->m_code = m_last_subgraph_code++; subgraph->m_sheet = sheet; @@ -667,15 +673,19 @@ void CONNECTION_GRAPH::buildConnectionGraph() std::list members; - auto get_items = [ &sheet ] ( SCH_ITEM* aItem ) -> bool - { - auto* conn = aItem->Connection( sheet ); + auto get_items = + [&]( SCH_ITEM* aItem ) -> bool + { + auto* conn = aItem->Connection( sheet ); - if( !conn ) - conn = aItem->InitializeConnection( sheet ); + if( !conn ) + { + conn = aItem->InitializeConnection( sheet ); + conn->SetGraph( this ); + } - return ( conn->SubgraphCode() == 0 ); - }; + return ( conn->SubgraphCode() == 0 ); + }; std::copy_if( item->ConnectedItems( sheet ).begin(), item->ConnectedItems( sheet ).end(), @@ -916,7 +926,10 @@ void CONNECTION_GRAPH::buildConnectionGraph() SCH_CONNECTION* connection = pin->Connection( sheet ); if( !connection ) + { connection = pin->InitializeConnection( sheet ); + connection->SetGraph( this ); + } // If this pin already has a subgraph, don't need to process if( connection->SubgraphCode() > 0 ) @@ -937,7 +950,7 @@ void CONNECTION_GRAPH::buildConnectionGraph() } else { - subgraph = new CONNECTION_SUBGRAPH( m_frame ); + subgraph = new CONNECTION_SUBGRAPH( this ); subgraph->m_code = m_last_subgraph_code++; subgraph->m_sheet = sheet; @@ -1920,6 +1933,10 @@ int CONNECTION_GRAPH::RunERC() { int error_count = 0; + wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ); + + ERC_SETTINGS* settings = m_schematic->ErcSettings(); + for( auto&& subgraph : m_subgraphs ) { // Graph is supposed to be up-to-date before calling RunERC() @@ -1936,18 +1953,18 @@ int CONNECTION_GRAPH::RunERC() * format due to their TestDanglingEnds() implementation. */ - if( g_ErcSettings->IsTestEnabled( ERCE_DRIVER_CONFLICT ) && !subgraph->ResolveDrivers() ) + if( settings->IsTestEnabled( ERCE_DRIVER_CONFLICT ) && !subgraph->ResolveDrivers() ) error_count++; - if( g_ErcSettings->IsTestEnabled( ERCE_BUS_TO_NET_CONFLICT ) + if( settings->IsTestEnabled( ERCE_BUS_TO_NET_CONFLICT ) && !ercCheckBusToNetConflicts( subgraph ) ) error_count++; - if( g_ErcSettings->IsTestEnabled( ERCE_BUS_ENTRY_CONFLICT ) + if( settings->IsTestEnabled( ERCE_BUS_ENTRY_CONFLICT ) && !ercCheckBusToBusEntryConflicts( subgraph ) ) error_count++; - if( g_ErcSettings->IsTestEnabled( ERCE_BUS_TO_BUS_CONFLICT ) + if( settings->IsTestEnabled( ERCE_BUS_TO_BUS_CONFLICT ) && !ercCheckBusToBusConflicts( subgraph ) ) error_count++; @@ -1957,8 +1974,8 @@ int CONNECTION_GRAPH::RunERC() if( !ercCheckNoConnects( subgraph ) ) error_count++; - if( ( g_ErcSettings->IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) - || g_ErcSettings->IsTestEnabled( ERCE_GLOBLABEL ) ) && !ercCheckLabels( subgraph ) ) + if( ( settings->IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) + || settings->IsTestEnabled( ERCE_GLOBLABEL ) ) && !ercCheckLabels( subgraph ) ) error_count++; } @@ -2329,8 +2346,10 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph ) bool is_global = text->Type() == SCH_GLOBAL_LABEL_T; + wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ); + // Global label check can be disabled independently - if( !g_ErcSettings->IsTestEnabled( ERCE_GLOBLABEL ) && is_global ) + if( !m_schematic->ErcSettings()->IsTestEnabled( ERCE_GLOBLABEL ) && is_global ) return true; wxString name = text->GetShownText(); diff --git a/eeschema/connection_graph.h b/eeschema/connection_graph.h index 4b6caca657..744fbdd970 100644 --- a/eeschema/connection_graph.h +++ b/eeschema/connection_graph.h @@ -36,6 +36,8 @@ #endif +class CONNECTION_GRAPH; +class SCHEMATIC; class SCH_EDIT_FRAME; class SCH_HIERLABEL; class SCH_PIN; @@ -70,11 +72,20 @@ public: GLOBAL }; - explicit CONNECTION_SUBGRAPH( SCH_EDIT_FRAME* aFrame ) : - m_dirty( false ), m_absorbed( false ), m_absorbed_by( nullptr ), m_code( -1 ), - m_multiple_drivers( false ), m_strong_driver( false ), m_local_driver( false ), - m_no_connect( nullptr ), m_bus_entry( nullptr ), m_driver( nullptr ), m_frame( aFrame ), - m_driver_connection( nullptr ), m_hier_parent( nullptr ) + explicit CONNECTION_SUBGRAPH( CONNECTION_GRAPH* aGraph ) : + m_graph( aGraph ), + m_dirty( false ), + m_absorbed( false ), + m_absorbed_by( nullptr ), + m_code( -1 ), + m_multiple_drivers( false ), + m_strong_driver( false ), + m_local_driver( false ), + m_no_connect( nullptr ), + m_bus_entry( nullptr ), + m_driver( nullptr ), + m_driver_connection( nullptr ), + m_hier_parent( nullptr ) {} ~CONNECTION_SUBGRAPH() = default; @@ -126,6 +137,8 @@ public: */ static PRIORITY GetDriverPriority( SCH_ITEM* aDriver ); + CONNECTION_GRAPH* m_graph; + bool m_dirty; /// True if this subgraph has been absorbed into another. No pointers here are safe if so! @@ -163,9 +176,6 @@ public: SCH_SHEET_PATH m_sheet; - // Needed for m_userUnits for now; maybe refactor later - SCH_EDIT_FRAME* m_frame; - /// Cache for driver connection SCH_CONNECTION* m_driver_connection; @@ -210,11 +220,11 @@ typedef std::map> NET_MAP; class CONNECTION_GRAPH { public: - CONNECTION_GRAPH( SCH_EDIT_FRAME* aFrame ) - : m_last_net_code( 1 ), + CONNECTION_GRAPH( SCHEMATIC* aSchematic = nullptr ) : + m_last_net_code( 1 ), m_last_bus_code( 1 ), m_last_subgraph_code( 1 ), - m_frame( aFrame ) + m_schematic( aSchematic ) {} ~CONNECTION_GRAPH() @@ -224,6 +234,11 @@ public: void Reset(); + void SetSchematic( SCHEMATIC* aSchematic ) + { + m_schematic = aSchematic; + } + /** * Updates the connection graph for the given list of sheets. * @@ -301,10 +316,7 @@ private: int m_last_subgraph_code; - std::mutex m_item_mutex; - - // Needed for m_userUnits for now; maybe refactor later - SCH_EDIT_FRAME* m_frame; + SCHEMATIC* m_schematic; ///< The schematic this graph represents /** * Updates the graphical connectivity between items (i.e. where they touch) diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index b11be51d97..0850af4876 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -48,18 +49,18 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference, const wxString& aSearchText ) { SCH_SHEET_PATH* sheetWithComponentFound = NULL; - SCH_COMPONENT* Component = NULL; + SCH_COMPONENT* component = NULL; wxPoint pos; LIB_PIN* pin = nullptr; - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList; SCH_ITEM* foundItem = nullptr; if( !aSearchHierarchy ) - sheetList.push_back( *g_CurrentSheet ); + sheetList.push_back( m_frame->GetCurrentSheet() ); else - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &m_frame->Schematic().Root() ); - for( SCH_SHEET_PATH& sheet : sheetList) + for( SCH_SHEET_PATH& sheet : sheetList ) { SCH_SCREEN* screen = sheet.LastScreen(); @@ -69,7 +70,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference, if( aReference.CmpNoCase( pSch->GetRef( &sheet ) ) == 0 ) { - Component = pSch; + component = pSch; sheetWithComponentFound = &sheet; if( aSearchType == HIGHLIGHT_PIN ) @@ -80,14 +81,14 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference, if( pin ) { pos += pin->GetPosition(); - foundItem = Component; + foundItem = component; break; } } else { pos = pSch->GetPosition(); - foundItem = Component; + foundItem = component; break; } } @@ -97,19 +98,19 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference, break; } - if( Component ) + if( component ) { - if( *sheetWithComponentFound != *g_CurrentSheet ) + if( *sheetWithComponentFound != m_frame->GetCurrentSheet() ) { sheetWithComponentFound->LastScreen()->SetZoom( m_frame->GetScreen()->GetZoom() ); - *g_CurrentSheet = *sheetWithComponentFound; + m_frame->Schematic().SetCurrentSheet( *sheetWithComponentFound ); m_frame->DisplayCurrentSheet(); } wxPoint delta; - pos -= Component->GetPosition(); - delta = Component->GetTransform().TransformCoordinate( pos ); - pos = delta + Component->GetPosition(); + pos -= component->GetPosition(); + delta = component->GetTransform().TransformCoordinate( pos ); + pos = delta + component->GetPosition(); m_frame->GetCanvas()->GetViewControls()->SetCrossHairCursorPosition( pos, false ); m_frame->CenterScreen( pos, false ); @@ -124,7 +125,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference, else msg_item = _( "component" ); - if( Component ) + if( component ) { if( foundItem ) msg.Printf( _( "%s %s found" ), aReference, msg_item ); @@ -390,8 +391,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) case MAIL_SCH_GET_NETLIST: if( payload.find( "quiet-annotate" ) != std::string::npos ) { - SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols(); + Schematic().GetSheets().AnnotatePowerSymbols(); AnnotateComponents( true, UNSORTED, INCREMENTAL_BY_REF, 0, false, false, true, NULL_REPORTER::GetInstance() ); } @@ -405,7 +405,8 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) { NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase(); - NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph ); + NETLIST_EXPORTER_KICAD exporter( + this, net_atoms, &Schematic(), Schematic().ConnectionGraph() ); STRING_FORMATTER formatter; exporter.Format( &formatter, GNL_ALL ); @@ -428,7 +429,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) case MAIL_SCH_REFRESH: { - SCH_SCREENS schematic; + SCH_SCREENS schematic( Schematic().Root() ); schematic.TestDanglingEnds(); GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL ); diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp index 0db2aeac65..f4228c7702 100644 --- a/eeschema/dialogs/dialog_bom.cpp +++ b/eeschema/dialogs/dialog_bom.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -456,7 +457,7 @@ void DIALOG_BOM::pluginInit() void DIALOG_BOM::OnRunGenerator( wxCommandEvent& event ) { // Calculate the xml netlist filename - wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fn = m_parent->Schematic().GetFileName(); fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) ); fn.ClearExt(); diff --git a/eeschema/dialogs/dialog_bus_manager.cpp b/eeschema/dialogs/dialog_bus_manager.cpp index c02faf28c5..bc43639e22 100644 --- a/eeschema/dialogs/dialog_bus_manager.cpp +++ b/eeschema/dialogs/dialog_bus_manager.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "dialog_bus_manager.h" @@ -192,13 +193,14 @@ bool DIALOG_BUS_MANAGER::TransferDataToWindow() { m_aliases.clear(); - SCH_SHEET_LIST aSheets( g_RootSheet ); + const SCH_SHEET_LIST& sheets = m_parent->Schematic().GetSheets(); + std::vector< std::shared_ptr< BUS_ALIAS > > original_aliases; // collect aliases from each open sheet - for( unsigned i = 0; i < aSheets.size(); i++ ) + for( unsigned i = 0; i < sheets.size(); i++ ) { - auto sheet_aliases = aSheets[i].LastScreen()->GetBusAliases(); + auto sheet_aliases = sheets[i].LastScreen()->GetBusAliases(); original_aliases.insert( original_aliases.end(), sheet_aliases.begin(), sheet_aliases.end() ); } diff --git a/eeschema/dialogs/dialog_edit_components_libid.cpp b/eeschema/dialogs/dialog_edit_components_libid.cpp index 6f567aac68..1aa4cafa40 100644 --- a/eeschema/dialogs/dialog_edit_components_libid.cpp +++ b/eeschema/dialogs/dialog_edit_components_libid.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -423,7 +424,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::initDlg() // In complex hierarchies, the same component is in fact duplicated, but // it is listed with different references (one by sheet instance) // the list is larger and looks like it contains all components - SCH_SHEET_LIST sheets( g_RootSheet ); + const SCH_SHEET_LIST& sheets = GetParent()->Schematic().GetSheets(); SCH_REFERENCE_LIST references; // build the full list of components including component having no symbol in loaded libs // (orphan components) diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp index 7938a8e96b..29ad36367d 100644 --- a/eeschema/dialogs/dialog_edit_label.cpp +++ b/eeschema/dialogs/dialog_edit_label.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,10 @@ private: bool TransferDataToWindow() override; bool TransferDataFromWindow() override; + wxString convertKIIDsToReferences( const wxString& aSource ) const; + + wxString convertReferencesToKIIDs( const wxString& aSource ) const; + SCH_EDIT_FRAME* m_Parent; SCH_TEXT* m_CurrentText; wxWindow* m_activeTextCtrl; @@ -204,7 +209,7 @@ DIALOG_LABEL_EDITOR::~DIALOG_LABEL_EDITOR() } -wxString convertKIIDsToReferences( const wxString& aSource ) +wxString DIALOG_LABEL_EDITOR::convertKIIDsToReferences( const wxString& aSource ) const { wxString newbuf; size_t sourceLen = aSource.length(); @@ -229,7 +234,7 @@ wxString convertKIIDsToReferences( const wxString& aSource ) if( isCrossRef ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_Parent->Schematic().GetSheets(); wxString remainder; wxString ref = token.BeforeFirst( ':', &remainder ); @@ -255,7 +260,7 @@ wxString convertKIIDsToReferences( const wxString& aSource ) } -wxString convertReferencesToKIIDs( const wxString& aSource ) +wxString DIALOG_LABEL_EDITOR::convertReferencesToKIIDs( const wxString& aSource ) const { wxString newbuf; size_t sourceLen = aSource.length(); @@ -280,7 +285,7 @@ wxString convertReferencesToKIIDs( const wxString& aSource ) if( isCrossRef ) { - SCH_SHEET_LIST sheets( g_RootSheet ); + SCH_SHEET_LIST sheets = m_Parent->Schematic().GetSheets(); wxString remainder; wxString ref = token.BeforeFirst( ':', &remainder ); SCH_REFERENCE_LIST references; @@ -335,7 +340,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataToWindow() { // Load the combobox with the existing labels of the same type std::set existingLabels; - SCH_SCREENS allScreens; + SCH_SCREENS allScreens( m_Parent->Schematic().Root() ); for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() ) { diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 821e4e844a..5dda2ef909 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) : EESCHEMA_SETTINGS* settings = dynamic_cast( Kiface().KifaceSettings() ); m_severities = settings->m_Appearance.erc_severities; - m_markerProvider = new SHEETLIST_ERC_ITEMS_PROVIDER(); + m_markerProvider = new SHEETLIST_ERC_ITEMS_PROVIDER( &m_parent->Schematic() ); m_markerTreeModel = new RC_TREE_MODEL( parent, m_markerDataView ); m_markerDataView->AssociateModel( m_markerTreeModel ); @@ -180,9 +181,10 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) { wxFileName fn; + SCHEMATIC* sch = &m_parent->Schematic(); + // Build the whole sheet list in hierarchy (sheet, not screen) - SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols(); + sch->GetSheets().AnnotatePowerSymbols(); if( m_parent->CheckAnnotate( aReporter, false ) ) { @@ -192,31 +194,33 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) return; } - SCH_SCREENS screens; + SCH_SCREENS screens( sch->Root() ); + ERC_SETTINGS* settings = sch->ErcSettings(); // Test duplicate sheet names inside a given sheet. While one can have multiple references // to the same file, each must have a unique name. - if( g_ErcSettings->IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) ) + if( settings->IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) ) { aReporter.ReportTail( _( "Checking sheet names...\n" ), RPT_SEVERITY_INFO ); - TestDuplicateSheetNames( true ); + TestDuplicateSheetNames( sch, true ); } - if( g_ErcSettings->IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) ) + if( settings->IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) ) { aReporter.ReportTail( _( "Checking bus conflicts...\n" ), RPT_SEVERITY_INFO ); - TestConflictingBusAliases(); + TestConflictingBusAliases( sch ); } // The connection graph has a whole set of ERC checks it can run aReporter.ReportTail( _( "Checking conflicts...\n" ) ); m_parent->RecalculateConnections( NO_CLEANUP ); - g_ConnectionGraph->RunERC(); + sch->ConnectionGraph()->RunERC(); // Test is all units of each multiunit component have the same footprint assigned. - if( g_ErcSettings->IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) ) + if( settings->IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) ) { aReporter.ReportTail( _( "Checking footprints...\n" ), RPT_SEVERITY_INFO ); + SCH_SHEET_LIST sheets = sch->GetSheets(); TestMultiunitFootprints( sheets ); } @@ -273,7 +277,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) case NETLIST_ITEM::PIN: { // Check if this pin has appeared before on a different net - if( item->m_Link && g_ErcSettings->IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) ) + if( item->m_Link && settings->IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) ) { wxString ref = item->GetComponentParent()->GetRef( &item->m_SheetPath ); wxString pin_name = ref + "_" + item->m_PinNum; @@ -312,14 +316,14 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) // Test similar labels (i;e. labels which are identical when // using case insensitive comparisons) - if( g_ErcSettings->IsTestEnabled( ERCE_SIMILAR_LABELS ) ) + if( settings->IsTestEnabled( ERCE_SIMILAR_LABELS ) ) { aReporter.ReportTail( _( "Checking labels...\n" ), RPT_SEVERITY_INFO ); objectsConnectedList->TestforSimilarLabels(); } - if( g_ErcSettings->IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) - TestTextVars(); + if( settings->IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) + TestTextVars( sch ); // Display diags: m_markerTreeModel->SetProvider( m_markerProvider ); @@ -343,9 +347,8 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent ) { const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() ); - SCH_SHEET_LIST sheetList( g_RootSheet ); SCH_SHEET_PATH sheet; - SCH_ITEM* item = sheetList.GetItem( itemID, &sheet ); + SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet ); if( item ) { @@ -391,12 +394,14 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) if( !node ) return; + SCHEMATIC& sch = m_parent->Schematic(); + RC_ITEM* rcItem = node->m_RcItem; wxString listName; wxMenu menu; wxString msg; - switch( GetSeverity( rcItem->GetErrorCode() ) ) + switch( sch.GetErcSeverity( rcItem->GetErrorCode() ) ) { case RPT_SEVERITY_ERROR: listName = _( "errors" ); break; case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break; @@ -421,7 +426,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) { // Pin to pin severities edited through pin conflict map } - else if( GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING ) + else if( sch.GetErcSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING ) { menu.Append( 4, wxString::Format( _( "Change severity to Error for all '%s' violations" ), rcItem->GetErrorText( rcItem->GetErrorCode() ) ), @@ -474,7 +479,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) break; case 4: - SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR ); + sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR ); // Rebuild model and view static_cast( aEvent.GetModel() )->SetProvider( m_markerProvider ); @@ -482,7 +487,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) break; case 5: - SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING ); + sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING ); // Rebuild model and view static_cast( aEvent.GetModel() )->SetProvider( m_markerProvider ); @@ -491,12 +496,12 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) case 6: { - SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE ); + sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE ); if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR ) - SetSeverity( ERCE_PIN_TO_PIN_WARNING, RPT_SEVERITY_IGNORE ); + sch.SetErcSeverity( ERCE_PIN_TO_PIN_WARNING, RPT_SEVERITY_IGNORE ); - SCH_SCREENS ScreenList; + SCH_SCREENS ScreenList( sch.Root() ); ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() ); // Rebuild model and view @@ -607,7 +612,7 @@ bool DIALOG_ERC::writeReport( const wxString& aFullFileName ) int err_count = 0; int warn_count = 0; int total_count = 0; - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets(); sheetList.FillItemMap( itemMap ); @@ -624,7 +629,7 @@ bool DIALOG_ERC::writeReport( const wxString& aFullFileName ) total_count++; - switch( GetSeverity( marker->GetRCItem()->GetErrorCode() ) ) + switch( m_parent->Schematic().GetErcSeverity( marker->GetRCItem()->GetErrorCode() ) ) { case RPT_SEVERITY_ERROR: err_count++; break; case RPT_SEVERITY_WARNING: warn_count++; break; diff --git a/eeschema/dialogs/dialog_fields_editor_global.cpp b/eeschema/dialogs/dialog_fields_editor_global.cpp index 7f934f56d3..7dff64a1bf 100644 --- a/eeschema/dialogs/dialog_fields_editor_global.cpp +++ b/eeschema/dialogs/dialog_fields_editor_global.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -678,8 +679,7 @@ DIALOG_FIELDS_EDITOR_GLOBAL::DIALOG_FIELDS_EDITOR_GLOBAL( SCH_EDIT_FRAME* parent wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) ); // Get all components from the list of schematic sheets - SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.GetComponents( m_componentRefs, false ); + m_parent->Schematic().GetSheets().GetComponents( m_componentRefs, false ); m_bRefresh->SetBitmap( KiBitmap( refresh_xpm ) ); diff --git a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp index 1ef1b45a23..1ca90ac4fc 100644 --- a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp +++ b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -179,7 +180,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow() else if( selection.GetSize() ) { SCH_ITEM* sch_item = (SCH_ITEM*) selection.Front(); - SCH_CONNECTION* connection = sch_item->Connection( *g_CurrentSheet ); + SCH_CONNECTION* connection = sch_item->Connection( m_parent->GetCurrentSheet() ); if( connection ) m_netFilter->SetValue( connection->Name() ); @@ -430,10 +431,8 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow() if( !m_textSize.Validate( Mils2iu( 1 ), Mils2iu( 10000 ) ) ) // 1 mil .. 10 inches return false; - SCH_SHEET_LIST aSheets( g_RootSheet ); - // Go through sheets - for( const SCH_SHEET_PATH& sheetPath : aSheets ) + for( const SCH_SHEET_PATH& sheetPath : m_parent->Schematic().GetSheets() ) { SCH_SCREEN* screen = sheetPath.LastScreen(); diff --git a/eeschema/dialogs/dialog_migrate_buses.cpp b/eeschema/dialogs/dialog_migrate_buses.cpp index 7df2c0bf96..a8974fbbbd 100644 --- a/eeschema/dialogs/dialog_migrate_buses.cpp +++ b/eeschema/dialogs/dialog_migrate_buses.cpp @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -72,7 +73,7 @@ DIALOG_MIGRATE_BUSES::DIALOG_MIGRATE_BUSES( SCH_EDIT_FRAME* aParent ) void DIALOG_MIGRATE_BUSES::loadGraphData() { m_items.clear(); - auto subgraphs = g_ConnectionGraph->GetBusesNeedingMigration(); + auto subgraphs = m_frame->Schematic().ConnectionGraph()->GetBusesNeedingMigration(); for( auto subgraph : subgraphs ) { @@ -172,11 +173,13 @@ void DIALOG_MIGRATE_BUSES::onItemSelected( wxListEvent& aEvent ) auto sheet = subgraph->m_sheet; auto driver = subgraph->m_driver; - if( sheet != *g_CurrentSheet ) + const SCH_SHEET_PATH& current = m_frame->GetCurrentSheet(); + + if( sheet != current ) { sheet.LastScreen()->SetZoom( m_frame->GetScreen()->GetZoom() ); - *g_CurrentSheet = sheet; - g_CurrentSheet->UpdateAllScreenReferences(); + sheet.UpdateAllScreenReferences(); + m_frame->Schematic().SetCurrentSheet( sheet ); sheet.LastScreen()->TestDanglingEnds(); } diff --git a/eeschema/dialogs/dialog_netlist.cpp b/eeschema/dialogs/dialog_netlist.cpp index 3a45c01ff4..2f87e41b2c 100644 --- a/eeschema/dialogs/dialog_netlist.cpp +++ b/eeschema/dialogs/dialog_netlist.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -439,7 +440,7 @@ bool NETLIST_DIALOG::TransferDataFromWindow() unsigned netlist_opt = 0; // Calculate the netlist filename - fn = g_RootSheet->GetScreen()->GetFileName(); + fn = m_Parent->Schematic().GetFileName(); FilenamePrms( currPage->m_IdNetType, &fileExt, &fileWildcard ); // Set some parameters diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp index 55229c26d1..f98bde6d91 100644 --- a/eeschema/dialogs/dialog_plot_schematic.cpp +++ b/eeschema/dialogs/dialog_plot_schematic.cpp @@ -29,10 +29,10 @@ #include #include #include -#include #include #include #include +#include // static members (static to remember last state): int DIALOG_PLOT_SCHEMATIC::m_pageSizeSelect = PAGE_SIZE_AUTO; @@ -151,7 +151,7 @@ void DIALOG_PLOT_SCHEMATIC::OnOutputDirectoryBrowseClicked( wxCommandEvent& even wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() ); - wxFileName fn( Prj().AbsolutePath( g_RootSheet->GetFileName() ) ); + wxFileName fn( Prj().AbsolutePath( m_parent->Schematic().Root().GetFileName() ) ); wxString defaultPath = fn.GetPathWithSep(); wxString msg; msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ), GetChars( defaultPath ) ); diff --git a/eeschema/dialogs/dialog_print_using_printer.cpp b/eeschema/dialogs/dialog_print_using_printer.cpp index de5389c72b..23c2f6d92e 100644 --- a/eeschema/dialogs/dialog_print_using_printer.cpp +++ b/eeschema/dialogs/dialog_print_using_printer.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -319,10 +320,12 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataFromWindow() SavePrintOptions(); - wxPrintDialogData printDialogData( m_parent->GetPageSetupData().GetPrintData() ); - printDialogData.SetMaxPage( g_RootSheet->CountSheets() ); + int sheet_count = m_parent->Schematic().Root().CountSheets(); - if( g_RootSheet->CountSheets() > 1 ) + wxPrintDialogData printDialogData( m_parent->GetPageSetupData().GetPrintData() ); + printDialogData.SetMaxPage( sheet_count ); + + if( sheet_count > 1 ) printDialogData.EnablePageNumbers( true ); wxPrinter printer( &printDialogData ); @@ -348,7 +351,7 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataFromWindow() bool SCH_PRINTOUT::OnPrintPage( int page ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets(); wxCHECK_MSG( page >= 1 && page <= (int)sheetList.size(), false, wxT( "Cannot print invalid page number." ) ); @@ -379,13 +382,13 @@ bool SCH_PRINTOUT::OnPrintPage( int page ) void SCH_PRINTOUT::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo ) { *minPage = *selPageFrom = 1; - *maxPage = *selPageTo = g_RootSheet->CountSheets(); + *maxPage = *selPageTo = m_parent->Schematic().Root().CountSheets(); } bool SCH_PRINTOUT::HasPage( int pageNum ) { - return g_RootSheet->CountSheets() >= pageNum; + return m_parent->Schematic().Root().CountSheets() >= pageNum; } diff --git a/eeschema/dialogs/dialog_sch_import_settings.cpp b/eeschema/dialogs/dialog_sch_import_settings.cpp index 88a56f672d..0cf5b11129 100644 --- a/eeschema/dialogs/dialog_sch_import_settings.cpp +++ b/eeschema/dialogs/dialog_sch_import_settings.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -54,7 +55,7 @@ bool DIALOG_SCH_IMPORT_SETTINGS::TransferDataToWindow() void DIALOG_SCH_IMPORT_SETTINGS::OnBrowseClicked( wxCommandEvent& event ) { - wxFileName fn = g_RootSheet->GetFileName(); + wxFileName fn = m_frame->Schematic().Root().GetFileName(); fn.SetExt( ProjectFileExtension ); wxFileDialog dlg( this, _( "Import Settings From" ), fn.GetPath(), fn.GetFullName(), diff --git a/eeschema/dialogs/dialog_sch_sheet_props.cpp b/eeschema/dialogs/dialog_sch_sheet_props.cpp index fefcb30df2..6310677236 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props.cpp +++ b/eeschema/dialogs/dialog_sch_sheet_props.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -168,7 +169,7 @@ bool DIALOG_SCH_SHEET_PROPS::TransferDataToWindow() m_backgroundSwatch->SetSwatchBackground( canvas ); // set up the read-only fields - m_heirarchyPath->SetValue( g_CurrentSheet->PathHumanReadable() ); + m_heirarchyPath->SetValue( m_frame->GetCurrentSheet().PathHumanReadable() ); m_textCtrlTimeStamp->SetValue( m_sheet->m_Uuid.AsString() ); Layout(); @@ -356,7 +357,7 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam if( !fileName.IsAbsolute() ) { - const SCH_SCREEN* currentScreen = g_CurrentSheet->LastScreen(); + const SCH_SCREEN* currentScreen = m_frame->GetCurrentSheet().LastScreen(); wxCHECK_MSG( currentScreen, false, "Invalid sheet path object." ); wxFileName currentSheetFileName = currentScreen->GetFileName(); @@ -382,7 +383,7 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam // Search for a schematic file having the same filename already in use in the hierarchy // or on disk, in order to reuse it. - if( !g_RootSheet->SearchHierarchy( newAbsoluteFilename, &useScreen ) ) + if( !m_frame->Schematic().Root().SearchHierarchy( newAbsoluteFilename, &useScreen ) ) { loadFromFile = wxFileExists( newAbsoluteFilename ); @@ -521,6 +522,7 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam } wxFileName nativeFileName( aNewFilename ); + SCH_SHEET_PATH& currentSheet = m_frame->GetCurrentSheet(); if( useScreen ) { @@ -531,10 +533,10 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam tmpSheet->SetScreen( useScreen ); // No need to check for valid library IDs if we are using an existing screen. - if( m_frame->CheckSheetForRecursion( tmpSheet.get(), g_CurrentSheet ) ) + if( m_frame->CheckSheetForRecursion( tmpSheet.get(), ¤tSheet ) ) { if( restoreSheet ) - g_CurrentSheet->LastScreen()->Append( m_sheet ); + currentSheet.LastScreen()->Append( m_sheet ); return false; } @@ -549,20 +551,20 @@ bool DIALOG_SCH_SHEET_PROPS::onSheetFilenameChanged( const wxString& aNewFilenam // Temporarily remove the sheet from the current schematic page so that recursion // and symbol library link tests can be performed with the modified sheet settings. restoreSheet = true; - g_CurrentSheet->LastScreen()->Remove( m_sheet ); + currentSheet.LastScreen()->Remove( m_sheet ); } - if( !m_frame->LoadSheetFromFile( m_sheet, g_CurrentSheet, newAbsoluteFilename ) - || m_frame->CheckSheetForRecursion( m_sheet, g_CurrentSheet ) ) + if( !m_frame->LoadSheetFromFile( m_sheet, ¤tSheet, newAbsoluteFilename ) + || m_frame->CheckSheetForRecursion( m_sheet, ¤tSheet ) ) { if( restoreSheet ) - g_CurrentSheet->LastScreen()->Append( m_sheet ); + currentSheet.LastScreen()->Append( m_sheet ); return false; } if( restoreSheet ) - g_CurrentSheet->LastScreen()->Append( m_sheet ); + currentSheet.LastScreen()->Append( m_sheet ); } if( m_clearAnnotationNewItems ) diff --git a/eeschema/dialogs/dialog_schematic_setup.cpp b/eeschema/dialogs/dialog_schematic_setup.cpp index f8e877a6dc..94ba937956 100644 --- a/eeschema/dialogs/dialog_schematic_setup.cpp +++ b/eeschema/dialogs/dialog_schematic_setup.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -41,8 +42,9 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) : m_pinMap = new PANEL_SETUP_PINMAP( m_treebook, aFrame ); ERC_ITEM dummyItem( 0 ); - m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, g_ErcSettings->m_Severities, - ERCE_FIRST, ERCE_LAST, ERCE_PIN_TO_PIN_WARNING ); + m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, + m_frame->Schematic().ErcSettings()->m_Severities, ERCE_FIRST, ERCE_LAST, + ERCE_PIN_TO_PIN_WARNING ); m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() ); diff --git a/eeschema/dialogs/dialog_symbol_remap.cpp b/eeschema/dialogs/dialog_symbol_remap.cpp index f078d25179..1172249773 100644 --- a/eeschema/dialogs/dialog_symbol_remap.cpp +++ b/eeschema/dialogs/dialog_symbol_remap.cpp @@ -35,10 +35,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -46,7 +46,8 @@ DIALOG_SYMBOL_REMAP::DIALOG_SYMBOL_REMAP( SCH_EDIT_FRAME* aParent ) : - DIALOG_SYMBOL_REMAP_BASE( aParent ) + DIALOG_SYMBOL_REMAP_BASE( aParent ), + m_frame( aParent ) { m_remapped = false; @@ -87,7 +88,8 @@ void DIALOG_SYMBOL_REMAP::OnRemapSymbols( wxCommandEvent& aEvent ) // Ignore the never show rescue setting for one last rescue of legacy symbol // libraries before remapping to the symbol library table. This ensures the // best remapping results. - LEGACY_RESCUER rescuer( Prj(), &parent->GetCurrentSheet(), parent->GetCanvas()->GetBackend() ); + LEGACY_RESCUER rescuer( Prj(), &parent->Schematic(), &parent->GetCurrentSheet(), + parent->GetCanvas()->GetBackend() ); if( RESCUER::RescueProject( this, rescuer, false ) ) { @@ -241,7 +243,7 @@ void DIALOG_SYMBOL_REMAP::createProjectSymbolLibTable( REPORTER& aReporter ) void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter ) { wxString msg; - SCH_SCREENS schematic; + SCH_SCREENS schematic( m_frame->Schematic().Root() ); SCH_COMPONENT* symbol; SCH_SCREEN* screen; @@ -327,7 +329,7 @@ bool DIALOG_SYMBOL_REMAP::backupProject( REPORTER& aReporter ) wxFileName srcFileName; wxFileName destFileName; wxFileName backupPath; - SCH_SCREENS schematic; + SCH_SCREENS schematic( m_frame->Schematic().Root() ); // Copy backup files to different folder so as not to pollute the project folder. destFileName.SetPath( Prj().GetProjectPath() ); diff --git a/eeschema/dialogs/dialog_symbol_remap.h b/eeschema/dialogs/dialog_symbol_remap.h index c21bce6e55..6f33345b41 100644 --- a/eeschema/dialogs/dialog_symbol_remap.h +++ b/eeschema/dialogs/dialog_symbol_remap.h @@ -87,6 +87,8 @@ private: bool backupProject( REPORTER& aReporter ); bool m_remapped; + + SCH_EDIT_FRAME* m_frame; }; #endif // _DIALOG_SYMBOL_REMAP_H_ diff --git a/eeschema/dialogs/dialog_update_from_pcb.cpp b/eeschema/dialogs/dialog_update_from_pcb.cpp index 55008b5fd2..054794b3c3 100644 --- a/eeschema/dialogs/dialog_update_from_pcb.cpp +++ b/eeschema/dialogs/dialog_update_from_pcb.cpp @@ -123,7 +123,7 @@ void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event ) if( backAnno.FetchNetlistFromPCB( netlist ) && backAnno.BackAnnotateSymbols( netlist ) ) { - g_CurrentSheet->UpdateAllScreenReferences(); + m_frame->GetCurrentSheet().UpdateAllScreenReferences(); m_frame->SetSheetNumberAndCount(); m_frame->SyncView(); m_frame->OnModify(); diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index cf6acd53e0..3ab75d98b6 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -207,35 +208,6 @@ public: }; -int GetSeverity( int aErrorCode ) -{ - // Special-case pin-to-pin errors: - // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both) - // Warning-or-error is controlled by which errorCode it is - if( aErrorCode == ERCE_PIN_TO_PIN_ERROR ) - { - if( g_ErcSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) - return RPT_SEVERITY_IGNORE; - else - return RPT_SEVERITY_ERROR; - } - else if( aErrorCode == ERCE_PIN_TO_PIN_WARNING ) - { - if( g_ErcSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) - return RPT_SEVERITY_IGNORE; - else - return RPT_SEVERITY_WARNING; - } - - return g_ErcSettings->m_Severities[ aErrorCode ]; -} - -void SetSeverity( int aErrorCode, int aSeverity ) -{ - g_ErcSettings->m_Severities[ aErrorCode ] = aSeverity; -} - - /// Helper for all the old plotting/printing code while it still exists COLOR4D GetLayerColor( SCH_LAYER_ID aLayer ) { @@ -327,7 +299,7 @@ std::vector& SCH_EDIT_FRAME::GetProjectFileParameters() params.push_back( new PARAM_CFG_FIELDNAMES( &m_templateFieldNames ) ); - params.push_back( new PARAM_CFG_SEVERITIES( g_ErcSettings ) ); + params.push_back( new PARAM_CFG_SEVERITIES( Schematic().ErcSettings() ) ); return params; } @@ -393,7 +365,7 @@ void SCH_EDIT_FRAME::DoShowSchematicSetupDialog( const wxString& aInitialPage, void SCH_EDIT_FRAME::SaveProjectSettings() { PROJECT& prj = Prj(); - wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); //ConfigFileName + wxFileName fn = Schematic().RootScreen()->GetFileName(); //ConfigFileName fn.SetExt( ProjectFileExtension ); diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index de6fa77eaf..ac23cbb6cb 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -154,11 +155,12 @@ static int MinimalReq[ELECTRICAL_PINTYPES_TOTAL][ELECTRICAL_PINTYPES_TOTAL] = }; -int TestDuplicateSheetNames( bool aCreateMarker ) +int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker ) { SCH_SCREEN* screen; int err_count = 0; - SCH_SCREENS screenList; // Created the list of screen + + SCH_SCREENS screenList( aSchematic->Root() ); for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() ) { @@ -199,9 +201,9 @@ int TestDuplicateSheetNames( bool aCreateMarker ) } -void TestTextVars() +void TestTextVars( SCHEMATIC* aSchematic ) { - SCH_SCREENS screens; + SCH_SCREENS screens( aSchematic->Root() ); for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { @@ -271,11 +273,12 @@ void TestTextVars() } -int TestConflictingBusAliases() +int TestConflictingBusAliases( SCHEMATIC* aSchematic ) { wxString msg; int err_count = 0; - SCH_SCREENS screens; + + SCH_SCREENS screens( aSchematic->Root() ); std::vector< std::shared_ptr > aliases; for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) @@ -311,7 +314,7 @@ int TestConflictingBusAliases() } -int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ) +int TestMultiunitFootprints( const SCH_SHEET_LIST& aSheetList ) { int errors = 0; std::map footprints; diff --git a/eeschema/erc.h b/eeschema/erc.h index 517143f593..951d8c1f02 100644 --- a/eeschema/erc.h +++ b/eeschema/erc.h @@ -34,6 +34,7 @@ class NETLIST_OBJECT; class NETLIST_OBJECT_LIST; class SCH_SHEET_LIST; +class SCHEMATIC; /* For ERC markers: error types (used in diags, and to set the color): */ @@ -115,13 +116,13 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned * @param aCreateMarker: true = create error markers in schematic, * false = calculate error count only */ -int TestDuplicateSheetNames( bool aCreateMarker ); +int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker ); /** * Function TestTextVars() * Checks for any unresolved text variable references. */ -void TestTextVars(); +void TestTextVars( SCHEMATIC* aSchematic ); /** * Checks that there are not conflicting bus alias definitions in the schematic @@ -131,14 +132,14 @@ void TestTextVars(); * * @return the error count */ -int TestConflictingBusAliases(); +int TestConflictingBusAliases( SCHEMATIC* aSchematic ); /** * Test if all units of each multiunit component have the same footprint assigned. * @param aSheetList contains components to be validated. * @return The error count. */ -int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList ); +int TestMultiunitFootprints( const SCH_SHEET_LIST& aSheetList ); #endif // _ERC_H diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index a8ac2a23a8..f1b82451db 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -258,18 +259,11 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // unload current project file before loading new { SetScreen( nullptr ); - delete g_RootSheet; - - if( g_CurrentSheet ) - g_CurrentSheet->clear(); - - g_RootSheet = nullptr; - CreateScreens(); } GetScreen()->SetFileName( fullFileName ); - g_RootSheet->SetFileName( fullFileName ); + Schematic().Root().SetFileName( fullFileName ); SetStatusText( wxEmptyString ); ClearMsgPanel(); @@ -323,8 +317,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in else { SetScreen( nullptr ); - delete g_RootSheet; // Delete the current project. - g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure. + Schematic().Reset(); SCH_PLUGIN* plugin = SCH_IO_MGR::FindPlugin( schFileType ); SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin ); @@ -334,11 +327,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in try { - g_RootSheet = pi->Load( fullFileName, &Kiway() ); + Schematic().SetRoot( pi->Load( fullFileName, &Kiway(), &Schematic() ) ); - g_CurrentSheet = new SCH_SHEET_PATH(); - g_CurrentSheet->clear(); - g_CurrentSheet->push_back( g_RootSheet ); + GetCurrentSheet().push_back( &Schematic().Root() ); if( !pi->GetError().IsEmpty() ) { @@ -368,7 +359,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( g_RootSheet ); + SCH_SHEET_LIST sheetList = Schematic().GetSheets(); if( sheetList.IsModified() ) { @@ -381,7 +372,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in UpdateFileHistory( fullFileName ); - SCH_SCREENS schematic; + SCH_SCREENS schematic( Schematic().Root() ); // LIB_ID checks and symbol rescue only apply to the legacy file formats. if( schFileType == SCH_IO_MGR::SCH_LEGACY ) @@ -464,16 +455,16 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in screen->UpdateLocalLibSymbolLinks(); // Restore all of the loaded symbol instances from the root sheet screen. - sheetList.UpdateSymbolInstances( g_RootSheet->GetScreen()->m_symbolInstances ); + sheetList.UpdateSymbolInstances( Schematic().RootScreen()->m_symbolInstances ); } - g_ConnectionGraph->Reset(); + Schematic().ConnectionGraph()->Reset(); - SetScreen( g_CurrentSheet->LastScreen() ); + SetScreen( GetCurrentSheet().LastScreen() ); // Migrate conflicting bus definitions // TODO(JE) This should only run once based on schematic file version - if( g_ConnectionGraph->GetBusesNeedingMigration().size() > 0 ) + if( Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() > 0 ) { DIALOG_MIGRATE_BUSES dlg( this ); dlg.ShowQuasiModal(); @@ -603,12 +594,12 @@ bool SCH_EDIT_FRAME::SaveProject() { wxString msg; SCH_SCREEN* screen; - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); bool success = true; bool updateFileType = false; // I want to see it in the debugger, show me the string! Can't do that with wxFileName. - wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() ); + wxString fileName = Prj().AbsolutePath( Schematic().Root().GetFileName() ); wxFileName fn = fileName; if( !fn.IsDirWritable() ) @@ -697,7 +688,7 @@ bool SCH_EDIT_FRAME::SaveProject() } if( updateFileType ) - UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); + UpdateFileHistory( Schematic().RootScreen()->GetFileName() ); // Save the sheet name map to the project file wxString configFile = Prj().GetProjectFullName(); @@ -707,9 +698,7 @@ bool SCH_EDIT_FRAME::SaveProject() config->DeleteGroup( GROUP_SHEET_NAMES ); config->SetPath( GROUP_SHEET_NAMES ); - SCH_SHEET_LIST sheetList( g_RootSheet ); - - for( SCH_SHEET_PATH& sheetPath : sheetList ) + for( SCH_SHEET_PATH& sheetPath : Schematic().GetSheets() ) { SCH_SHEET* sheet = sheetPath.Last(); config->Write( wxString::Format( "%d", index++ ), @@ -727,10 +716,10 @@ bool SCH_EDIT_FRAME::SaveProject() bool SCH_EDIT_FRAME::doAutoSave() { - wxFileName tmpFileName = g_RootSheet->GetFileName(); + wxFileName tmpFileName = Schematic().Root().GetFileName(); wxFileName fn = tmpFileName; wxFileName tmp; - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); bool autoSaveOk = true; @@ -773,7 +762,7 @@ bool SCH_EDIT_FRAME::doAutoSave() bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) { wxFileName newfilename; - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = Schematic().GetSheets(); switch( (SCH_IO_MGR::SCH_FILE_T) aFileType ) { @@ -792,10 +781,10 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) try { - delete g_RootSheet; - g_RootSheet = nullptr; + Schematic().Reset(); + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_EAGLE ) ); - g_RootSheet = pi->Load( aFileName, &Kiway() ); + Schematic().SetRoot( pi->Load( aFileName, &Kiway(), &Schematic() ) ); // Eagle sheets do not use a worksheet frame by default, so set it to an empty one WS_DATA_MODEL& pglayout = WS_DATA_MODEL::GetTheInstance(); @@ -815,23 +804,21 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) newfilename.SetName( Prj().GetProjectName() ); newfilename.SetExt( LegacySchematicFileExtension ); - g_CurrentSheet->clear(); - g_CurrentSheet->push_back( g_RootSheet ); - SetScreen( g_CurrentSheet->LastScreen() ); + GetCurrentSheet().push_back( &Schematic().Root() ); + SetScreen( GetCurrentSheet().LastScreen() ); - g_RootSheet->SetFileName( newfilename.GetFullPath() ); + Schematic().Root().SetFileName( newfilename.GetFullPath() ); GetScreen()->SetFileName( newfilename.GetFullPath() ); GetScreen()->SetModify(); SaveProjectSettings(); UpdateFileHistory( aFileName ); - SCH_SCREENS schematic; + SCH_SCREENS schematic( Schematic().Root() ); schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets. GetScreen()->m_Initialized = true; - SCH_SCREENS allScreens; - for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() ) + for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) { for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) ) { @@ -888,7 +875,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) bool SCH_EDIT_FRAME::AskToSaveChanges() { - SCH_SCREENS screenList; + SCH_SCREENS screenList( Schematic().Root() ); // Save any currently open and modified project files. for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() ) diff --git a/eeschema/general.h b/eeschema/general.h index fc247552ab..77afc598af 100644 --- a/eeschema/general.h +++ b/eeschema/general.h @@ -27,15 +27,10 @@ #include #include -#include using KIGFX::COLOR4D; -class CONNECTION_GRAPH; class TRANSFORM; -class SCH_SHEET; -class SCH_SHEET_PATH; -class ERC_SETTINGS; #define EESCHEMA_VERSION 5 #define SCHEMATIC_HEAD_STRING "Schematic File Version" @@ -48,27 +43,4 @@ class ERC_SETTINGS; */ extern TRANSFORM DefaultTransform; -/* First and main (root) screen */ -extern SCH_SHEET* g_RootSheet; - -/** - * With the new connectivity algorithm, many more places than before want to - * know what the current sheet is. This was moved here from SCH_EDIT_FRAME - * but we could refactor things to get rid of this global. - */ -extern SCH_SHEET_PATH* g_CurrentSheet; ///< which sheet we are presently working on. - -/** - * This also wants to live in the eventual SCHEMATIC object - */ -extern CONNECTION_GRAPH* g_ConnectionGraph; - -/** - * This also wants to live in the eventual SCHEMATIC object - */ -extern ERC_SETTINGS* g_ErcSettings; - -int GetSeverity( int aErrorCode ); -void SetSeverity( int aErrorCode, int aSeverity ); - #endif // _GENERAL_H_ diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 07f8677990..92127b3693 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -214,7 +214,7 @@ void SCH_EDIT_FRAME::SelectUnit( SCH_COMPONENT* aComponent, int aUnit ) SaveCopyInUndoList( aComponent, UR_CHANGED ); /* Update the unit number. */ - aComponent->SetUnitSelection( g_CurrentSheet, aUnit ); + aComponent->SetUnitSelection( &GetCurrentSheet(), aUnit ); aComponent->SetUnit( aUnit ); aComponent->ClearFlags(); aComponent->SetFlags( savedFlags ); // Restore m_Flag modified by SetUnit() diff --git a/eeschema/hierarch.cpp b/eeschema/hierarch.cpp index 5527a625fa..39004578ff 100644 --- a/eeschema/hierarch.cpp +++ b/eeschema/hierarch.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -95,10 +96,10 @@ HIERARCHY_NAVIG_DLG::HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* aParent ) : wxTreeItemId root = m_Tree->AddRoot( _( "Root" ), 0, 1 ); m_Tree->SetItemBold( root, true ); - m_list.push_back( g_RootSheet ); + m_list.push_back( &m_SchFrameEditor->Schematic().Root() ); m_Tree->SetItemData( root, new TreeItemData( m_list ) ); - if( m_SchFrameEditor->GetCurrentSheet().Last() == g_RootSheet ) + if( m_SchFrameEditor->GetCurrentSheet().Last() == &m_SchFrameEditor->Schematic().Root() ) m_Tree->SelectItem( root ); buildHierarchyTree( &m_list, &root ); @@ -195,7 +196,7 @@ void HIERARCHY_NAVIG_DLG::UpdateHierarchyTree() wxTreeItemId root = m_Tree->GetRootItem(); m_Tree->DeleteChildren( root ); m_list.clear(); - m_list.push_back( g_RootSheet ); + m_list.push_back( &m_SchFrameEditor->Schematic().Root() ); buildHierarchyTree( &m_list, &root ); Thaw(); @@ -230,7 +231,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet() m_toolManager->RunAction( ACTIONS::cancelInteractive, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); - SCH_SCREEN* screen = g_CurrentSheet->LastScreen(); + SCH_SCREEN* screen = GetCurrentSheet().LastScreen(); wxASSERT( screen ); @@ -240,7 +241,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet() GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 ); // update the References - g_CurrentSheet->UpdateAllScreenReferences(); + GetCurrentSheet().UpdateAllScreenReferences(); SetSheetNumberAndCount(); if( !screen->m_Initialized ) diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index 4413f105b2..dac616eb3a 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -48,6 +48,7 @@ #include #include #include +#include // For message panel debug info #include #include #include @@ -1482,7 +1483,12 @@ void LIB_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorGetConnectionForPin( this, *g_CurrentSheet ); + SCH_EDIT_FRAME* frame = dynamic_cast( aFrame ); + + if( !frame ) + return; + + auto conn = aComponent->GetConnectionForPin( this, frame->GetCurrentSheet() ); if( conn ) conn->AppendDebugInfoToMsgPanel( aList ); diff --git a/eeschema/libarch.cpp b/eeschema/libarch.cpp index fc35077f9b..edd3d15d95 100644 --- a/eeschema/libarch.cpp +++ b/eeschema/libarch.cpp @@ -37,6 +37,7 @@ #include #include #include +#include bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename ) @@ -46,7 +47,7 @@ bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilenam if( aUseCurrentSheetFilename ) fn = GetScreen()->GetFileName(); else - fn = g_RootSheet->GetScreen()->GetFileName(); + fn = Schematic().RootScreen()->GetFileName(); fn.SetName( fn.GetName() + "-cache" ); fn.SetExt( SchematicLibraryFileExtension ); @@ -55,7 +56,7 @@ bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilenam // Update the schematic symbol library links. // because the lib cache has changed - SCH_SCREENS schematic; + SCH_SCREENS schematic( Schematic().Root() ); schematic.UpdateSymbolLinks(); return success; @@ -66,7 +67,7 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) { wxString tmp; wxString errorMsg; - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); // Create a new empty library to archive components: std::unique_ptr archLib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) ); diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 971730aa42..7cb4d3320a 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,10 +47,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() wxMenuBar* oldMenuBar = GetMenuBar(); wxMenuBar* menuBar = new wxMenuBar(); - auto modifiedDocumentCondition = [] ( const SELECTION& sel ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); - return sheetList.IsModified(); - }; + auto modifiedDocumentCondition = [&]( const SELECTION& sel ) + { + return Schematic().GetSheets().IsModified(); + }; //-- File menu ----------------------------------------------------------- // @@ -162,24 +163,40 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // CONDITIONAL_MENU* viewMenu = new CONDITIONAL_MENU( false, selTool ); - auto belowRootSheetCondition = [] ( const SELECTION& aSel ) { - return g_CurrentSheet->Last() != g_RootSheet; - }; - auto gridShownCondition = [ this ] ( const SELECTION& aSel ) { - return IsGridVisible(); - }; - auto imperialUnitsCondition = [this]( const SELECTION& aSel ) { - return GetUserUnits() == EDA_UNITS::INCHES; - }; - auto metricUnitsCondition = [this]( const SELECTION& aSel ) { - return GetUserUnits() == EDA_UNITS::MILLIMETRES; - }; - auto fullCrosshairCondition = [ this ] ( const SELECTION& aSel ) { - return GetGalDisplayOptions().m_fullscreenCursor; - }; - auto hiddenPinsCondition = [ this ] ( const SELECTION& aSel ) { - return GetShowAllPins(); - }; + auto belowRootSheetCondition = + [this]( const SELECTION& aSel ) + { + return GetCurrentSheet().Last() != &Schematic().Root(); + }; + + auto gridShownCondition = + [this]( const SELECTION& aSel ) + { + return IsGridVisible(); + }; + + auto imperialUnitsCondition = + [this]( const SELECTION& aSel ) + { + return GetUserUnits() == EDA_UNITS::INCHES; + }; + + auto metricUnitsCondition = + [this]( const SELECTION& aSel ) + { + return GetUserUnits() == EDA_UNITS::MILLIMETRES; + }; + + auto fullCrosshairCondition = + [this]( const SELECTION& aSel ) + { + return GetGalDisplayOptions().m_fullscreenCursor; + }; + auto hiddenPinsCondition = + [this]( const SELECTION& aSel ) + { + return GetShowAllPins(); + }; viewMenu->AddItem( ACTIONS::showSymbolBrowser, EE_CONDITIONS::ShowAlways ); viewMenu->AddItem( EE_ACTIONS::navigateHierarchy, EE_CONDITIONS::ShowAlways ); @@ -256,12 +273,14 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // CONDITIONAL_MENU* toolsMenu = new CONDITIONAL_MENU( false, selTool ); - auto remapSymbolsCondition = [] ( const SELECTION& aSel ) { - SCH_SCREENS schematic; + auto remapSymbolsCondition = + [&]( const SELECTION& aSel ) + { + SCH_SCREENS schematic( Schematic().Root() ); - // The remapping can only be performed on legacy projects. - return schematic.HasNoFullyDefinedLibIds(); - }; + // The remapping can only be performed on legacy projects. + return schematic.HasNoFullyDefinedLibIds(); + }; toolsMenu->AddItem( ACTIONS::updatePcbFromSchematic, EE_CONDITIONS::ShowAlways ); toolsMenu->AddItem( ACTIONS::updateSchematicFromPcb, EE_CONDITIONS::ShowAlways ); diff --git a/eeschema/netlist_exporters/netlist_exporter.cpp b/eeschema/netlist_exporters/netlist_exporter.cpp index 50cfdfb06c..1695900e1e 100644 --- a/eeschema/netlist_exporters/netlist_exporter.cpp +++ b/eeschema/netlist_exporters/netlist_exporter.cpp @@ -305,7 +305,7 @@ void NETLIST_EXPORTER::findAllUnitsOfComponent( SCH_COMPONENT* aComponent, wxString ref = aComponent->GetRef( aSheetPath ); wxString ref2; - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); for( unsigned i = 0; i < sheetList.size(); i++ ) { diff --git a/eeschema/netlist_exporters/netlist_exporter.h b/eeschema/netlist_exporters/netlist_exporter.h index 37674af89c..95e0711ae7 100644 --- a/eeschema/netlist_exporters/netlist_exporter.h +++ b/eeschema/netlist_exporters/netlist_exporter.h @@ -34,6 +34,7 @@ #include #include #include +#include /** * UNIQUE_STRINGS @@ -102,6 +103,9 @@ protected: /// unique library parts used. LIB_PART items are sorted by names std::set m_LibParts; + /// The schematic we're generating a netlist for + SCHEMATIC* m_schematic; + /** * Function sprintPinNetName * formats the net name for \a aPin using \a aNetNameFormat into \a aResult. @@ -171,8 +175,9 @@ public: * @param aMasterList we take ownership of this here. * @param aLibTable is the symbol library table of the project. */ - NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList ) : - m_masterList( aMasterList ) + NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) : + m_masterList( aMasterList ), + m_schematic( aSchematic ) { wxASSERT( aMasterList ); } diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp index 7bc649ea1c..fec5f2c186 100644 --- a/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.cpp @@ -69,7 +69,7 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig // Create netlist module section m_ReferencesAlreadyFound.Clear(); - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); for( unsigned i = 0; i < sheetList.size(); i++ ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.h b/eeschema/netlist_exporters/netlist_exporter_cadstar.h index ca67fb9792..620925c7ce 100644 --- a/eeschema/netlist_exporters/netlist_exporter_cadstar.h +++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.h @@ -48,8 +48,8 @@ class NETLIST_EXPORTER_CADSTAR : public NETLIST_EXPORTER bool writeListOfNets( FILE* f ); public: - NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList ) : - NETLIST_EXPORTER( aMasterList ) + NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) : + NETLIST_EXPORTER( aMasterList, aSchematic ) { } diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.cpp b/eeschema/netlist_exporters/netlist_exporter_generic.cpp index d9d523edde..4627121e43 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_generic.cpp @@ -106,7 +106,7 @@ void NETLIST_EXPORTER_GENERIC::addComponentFields( XNODE* xcomp, SCH_COMPONENT* wxString ref = comp->GetRef( aSheet ); - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); int minUnit = comp->GetUnit(); for( unsigned i = 0; i < sheetList.size(); i++ ) @@ -193,7 +193,6 @@ void NETLIST_EXPORTER_GENERIC::addComponentFields( XNODE* xcomp, SCH_COMPONENT* xfield->AddAttribute( "name", it->first ); } } - } @@ -203,7 +202,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents() m_ReferencesAlreadyFound.Clear(); - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); // 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. @@ -290,7 +289,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader() wxFileName sourceFileName; // the root sheet is a special sheet, call it source - xdesign->AddChild( node( "source", g_RootSheet->GetScreen()->GetFileName() ) ); + xdesign->AddChild( node( "source", m_schematic->GetFileName() ) ); xdesign->AddChild( node( "date", DateAndTime() ) ); @@ -300,7 +299,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader() /* Export the sheets information */ - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); for( unsigned i = 0; i < sheetList.size(); i++ ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.h b/eeschema/netlist_exporters/netlist_exporter_generic.h index 7ec1d01c72..5aebeadef3 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.h +++ b/eeschema/netlist_exporters/netlist_exporter_generic.h @@ -70,8 +70,9 @@ protected: public: NETLIST_EXPORTER_GENERIC( SCH_EDIT_FRAME* aFrame, NETLIST_OBJECT_LIST* aMasterList, + SCHEMATIC* aSchematic, CONNECTION_GRAPH* aGraph = nullptr ) : - NETLIST_EXPORTER( aMasterList ), + NETLIST_EXPORTER( aMasterList, aSchematic ), m_libTable( aFrame->Prj().SchSymbolLibTable() ), m_graph( aGraph ) {} diff --git a/eeschema/netlist_exporters/netlist_exporter_kicad.h b/eeschema/netlist_exporters/netlist_exporter_kicad.h index 27813d64e9..7ecdfe9ef8 100644 --- a/eeschema/netlist_exporters/netlist_exporter_kicad.h +++ b/eeschema/netlist_exporters/netlist_exporter_kicad.h @@ -40,8 +40,9 @@ class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC public: NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame, NETLIST_OBJECT_LIST* aMasterList, + SCHEMATIC* aSchematic, CONNECTION_GRAPH* aGraph = nullptr ) : - NETLIST_EXPORTER_GENERIC( aFrame, aMasterList, aGraph ) + NETLIST_EXPORTER_GENERIC( aFrame, aMasterList, aSchematic, aGraph ) {} /** diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp index 04f5f77241..7e9ce0936a 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp @@ -68,7 +68,7 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, // Create netlist module section m_ReferencesAlreadyFound.Clear(); - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); for( unsigned i = 0; i < sheetList.size(); i++ ) { diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h index 8b53b7d75c..c93849ec6d 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h @@ -35,8 +35,8 @@ class NETLIST_EXPORTER_ORCADPCB2 : public NETLIST_EXPORTER { public: - NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList ) : - NETLIST_EXPORTER( aMasterList ) + NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) : + NETLIST_EXPORTER( aMasterList, aSchematic ) { } diff --git a/eeschema/netlist_exporters/netlist_exporter_pspice.cpp b/eeschema/netlist_exporters/netlist_exporter_pspice.cpp index 6735afeef9..917a38de05 100644 --- a/eeschema/netlist_exporters/netlist_exporter_pspice.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_pspice.cpp @@ -267,7 +267,8 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceFieldDefVal( SPICE_FIELD aField, bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl ) { const wxString delimiters( "{:,; }" ); - SCH_SHEET_LIST sheetList( g_RootSheet ); + + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); // Set of reference names, to check for duplications std::set refNames; @@ -378,7 +379,7 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl ) void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl ) { - const SCH_SHEET_LIST& sheetList = g_RootSheet; + const SCH_SHEET_LIST& sheetList = m_schematic->GetSheets(); wxRegEx couplingK( "^[kK][[:digit:]]*[[:space:]]+[[:alnum:]]+[[:space:]]+[[:alnum:]]+", wxRE_ADVANCED ); diff --git a/eeschema/netlist_exporters/netlist_exporter_pspice.h b/eeschema/netlist_exporters/netlist_exporter_pspice.h index d651311fe4..0c163c1ac8 100644 --- a/eeschema/netlist_exporters/netlist_exporter_pspice.h +++ b/eeschema/netlist_exporters/netlist_exporter_pspice.h @@ -101,9 +101,10 @@ struct SPICE_ITEM class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER { public: - NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, PROJECT* aProject = NULL ) : - NETLIST_EXPORTER( aMasterList ), - m_project( aProject ) + NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic, + PROJECT* aProject = nullptr ) : + NETLIST_EXPORTER( aMasterList, aSchematic ), + m_project( aProject ) { } diff --git a/eeschema/netlist_generator.cpp b/eeschema/netlist_generator.cpp index fa55c60754..f0acd29570 100644 --- a/eeschema/netlist_generator.cpp +++ b/eeschema/netlist_generator.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -61,22 +62,25 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList, NETLIST_EXPORTER *helper; + SCHEMATIC* sch = &Schematic(); + switch( aFormat ) { case NET_TYPE_PCBNEW: - helper = new NETLIST_EXPORTER_KICAD( this, aConnectedItemsList, g_ConnectionGraph ); + helper = new NETLIST_EXPORTER_KICAD( + this, aConnectedItemsList, sch, sch->ConnectionGraph() ); break; case NET_TYPE_ORCADPCB2: - helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList ); + helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList, sch ); break; case NET_TYPE_CADSTAR: - helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList ); + helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList, sch ); break; case NET_TYPE_SPICE: - helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList ); + helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList, sch ); break; default: @@ -85,8 +89,8 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList, tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT ); fileName = tmpFile.GetFullPath(); - helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList, - g_ConnectionGraph ); + helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList, sch, + sch->ConnectionGraph() ); executeCommandLine = true; } break; @@ -158,14 +162,13 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList, //Imported function: -int TestDuplicateSheetNames( bool aCreateMarker ); +int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker ); bool SCH_EDIT_FRAME::prepareForNetlist() { // Ensure all power symbols have a valid reference - SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols(); + Schematic().GetSheets().AnnotatePowerSymbols(); // Performs some controls: if( CheckAnnotate( NULL_REPORTER::GetInstance(), 0 ) ) @@ -178,7 +181,7 @@ bool SCH_EDIT_FRAME::prepareForNetlist() } // Test duplicate sheet names: - if( TestDuplicateSheetNames( false ) > 0 ) + if( TestDuplicateSheetNames( &Schematic(), false ) > 0 ) { if( !IsOK( this, _( "Error: duplicate sheet names. Continue?" ) ) ) return false; @@ -191,7 +194,7 @@ bool SCH_EDIT_FRAME::prepareForNetlist() void SCH_EDIT_FRAME::sendNetlistToCvpcb() { NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase(); - NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph ); + NETLIST_EXPORTER_KICAD exporter( this, net_atoms, &Schematic(), Schematic().ConnectionGraph() ); STRING_FORMATTER formatter; // @todo : trim GNL_ALL down to minimum for CVPCB @@ -212,8 +215,7 @@ NETLIST_OBJECT_LIST* SCH_EDIT_FRAME::CreateNetlist( bool aSilent, } else // performs similar function as prepareForNetlist but without a dialog. { - SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols(); + Schematic().GetSheets().AnnotatePowerSymbols(); if( aSilentAnnotate ) AnnotateComponents( true, UNSORTED, INCREMENTAL_BY_REF, 0, false, false, true, @@ -236,7 +238,7 @@ NETLIST_OBJECT_LIST* SCH_EDIT_FRAME::BuildNetListBase( bool updateStatusText ) std::unique_ptr ret( new NETLIST_OBJECT_LIST() ); // Creates the flattened sheet list: - SCH_SHEET_LIST aSheets( g_RootSheet ); + SCH_SHEET_LIST aSheets = Schematic().GetSheets(); // Build netlist info bool success = ret->BuildNetListInfo( aSheets ); diff --git a/eeschema/netlist_object.cpp b/eeschema/netlist_object.cpp index 6cf9406336..17df2fdfb3 100644 --- a/eeschema/netlist_object.cpp +++ b/eeschema/netlist_object.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #if defined(DEBUG) @@ -242,7 +243,7 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem // bus groups (including with nested vectors) the code is something arbitrary. long member_offset = 0; - auto alias = SCH_SCREEN::GetBusAlias( m_Label ); + auto alias = static_cast( m_Comp )->Schematic()->GetBusAlias( m_Label ); wxString group_name; bool self_set = false; std::vector bus_contents_vec; @@ -286,7 +287,8 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem fillBusVector( aNetListItems, prefix, begin, end, member_offset ); member_offset += std::abs( end - begin ); } - else if( auto nested_alias = SCH_SCREEN::GetBusAlias( bus_member ) ) + else if( auto nested_alias = static_cast( m_Comp )->Schematic()->GetBusAlias( + bus_member ) ) { // Nested alias inside a group for( const auto& alias_member : nested_alias->Members() ) diff --git a/eeschema/plot_schematic_DXF.cpp b/eeschema/plot_schematic_DXF.cpp index 211989e397..a78d52c651 100644 --- a/eeschema/plot_schematic_DXF.cpp +++ b/eeschema/plot_schematic_DXF.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,7 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) SCH_SHEET_LIST sheetList; if( aPlotAll ) - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &schframe->Schematic().Root() ); else sheetList.push_back( schframe->GetCurrentSheet() ); diff --git a/eeschema/plot_schematic_HPGL.cpp b/eeschema/plot_schematic_HPGL.cpp index 054f179aef..326e995e9c 100644 --- a/eeschema/plot_schematic_HPGL.cpp +++ b/eeschema/plot_schematic_HPGL.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) SCH_SHEET_LIST sheetList; if( aPlotAll ) - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &m_parent->Schematic().Root() ); else sheetList.push_back( m_parent->GetCurrentSheet() ); diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp index fbbc6813ee..b66ec5637a 100644 --- a/eeschema/plot_schematic_PDF.cpp +++ b/eeschema/plot_schematic_PDF.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,7 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef, SCH_SHEET_LIST sheetList; if( aPlotAll ) - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &m_parent->Schematic().Root() ); else sheetList.push_back( m_parent->GetCurrentSheet() ); diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp index 84b7101999..3c0bc4b536 100644 --- a/eeschema/plot_schematic_PS.cpp +++ b/eeschema/plot_schematic_PS.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef, SCH_SHEET_LIST sheetList; if( aPlotAll ) - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &m_parent->Schematic().Root() ); else sheetList.push_back( m_parent->GetCurrentSheet() ); diff --git a/eeschema/plot_schematic_SVG.cpp b/eeschema/plot_schematic_SVG.cpp index e6c10cda4a..89a5a3772f 100644 --- a/eeschema/plot_schematic_SVG.cpp +++ b/eeschema/plot_schematic_SVG.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +52,7 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef, SCH_SHEET_LIST sheetList; if( aPrintAll ) - sheetList.BuildSheetList( g_RootSheet ); + sheetList.BuildSheetList( &m_parent->Schematic().Root() ); else sheetList.push_back( m_parent->GetCurrentSheet() ); diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp index 2c701e83f0..69820e9919 100644 --- a/eeschema/project_rescue.cpp +++ b/eeschema/project_rescue.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -59,9 +60,9 @@ static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp ) * * @param aComponents - a vector that will take the symbols */ -static void get_components( std::vector& aComponents ) +static void get_components( SCHEMATIC* aSchematic, std::vector& aComponents ) { - SCH_SCREENS screens; + SCH_SCREENS screens( aSchematic->Root() ); // Get the full list for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) @@ -108,9 +109,9 @@ static LIB_PART* find_component( const wxString& aName, PART_LIBS* aLibs, bool a } -static wxFileName GetRescueLibraryFileName() +static wxFileName GetRescueLibraryFileName( SCHEMATIC* aSchematic ) { - wxFileName fn( g_RootSheet->GetScreen()->GetFileName() ); + wxFileName fn = aSchematic->GetFileName(); fn.SetName( fn.GetName() + wxT( "-rescue" ) ); fn.SetExt( SchematicLibraryFileExtension ); return fn; @@ -429,7 +430,7 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues( // Differentiate symbol name in the rescue library by appending the symbol library // table nickname to the symbol name to prevent name clashes in the rescue library. - wxString libNickname = GetRescueLibraryFileName().GetName(); + wxString libNickname = GetRescueLibraryFileName( aRescuer.Schematic() ).GetName(); // Spaces in the file name will break the symbol name because they are not // quoted in the symbol library file format. @@ -495,10 +496,14 @@ bool RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::PerformAction( RESCUER* aRescuer ) } -RESCUER::RESCUER( PROJECT& aProject, SCH_SHEET_PATH* aCurrentSheet, +RESCUER::RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType ) { - get_components( m_components ); + m_schematic = aSchematic ? aSchematic : aCurrentSheet->LastScreen()->Schematic(); + + wxASSERT( m_schematic ); + + get_components( m_schematic, m_components ); m_prj = &aProject; m_currentSheet = aCurrentSheet; m_galBackEndType = aGalBackEndType; @@ -634,7 +639,7 @@ void LEGACY_RESCUER::InvokeDialog( wxWindow* aParent, bool aAskShowAgain ) void LEGACY_RESCUER::OpenRescueLibrary() { - wxFileName fn = GetRescueLibraryFileName(); + wxFileName fn = GetRescueLibraryFileName( m_schematic ); std::unique_ptr rescue_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, fn.GetFullPath() ) ); @@ -736,10 +741,8 @@ bool LEGACY_RESCUER::WriteRescueLibrary( wxWindow *aParent ) m_prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs ); // Update the schematic symbol library links since the library list has changed. - SCH_SCREENS schematic; - + SCH_SCREENS schematic( m_schematic->Root() ); schematic.UpdateSymbolLinks(); - return true; } @@ -753,10 +756,10 @@ void LEGACY_RESCUER::AddPart( LIB_PART* aNewPart ) } -SYMBOL_LIB_TABLE_RESCUER::SYMBOL_LIB_TABLE_RESCUER( PROJECT& aProject, +SYMBOL_LIB_TABLE_RESCUER::SYMBOL_LIB_TABLE_RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType ) : - RESCUER( aProject, aCurrentSheet, aGalBackEndType ) + RESCUER( aProject, aSchematic, aCurrentSheet, aGalBackEndType ) { m_properties = std::make_unique(); } @@ -785,7 +788,7 @@ void SYMBOL_LIB_TABLE_RESCUER::OpenRescueLibrary() bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( wxWindow *aParent ) { wxString msg; - wxFileName fn = GetRescueLibraryFileName(); + wxFileName fn = GetRescueLibraryFileName( m_schematic ); // If the rescue library already exists in the symbol library table no need save it to add // it to the table. @@ -835,8 +838,7 @@ bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( wxWindow *aParent ) return false; // Update the schematic symbol library links since the library list has changed. - SCH_SCREENS schematic; - + SCH_SCREENS schematic( m_schematic->Root() ); schematic.UpdateSymbolLinks(); return true; } @@ -846,7 +848,7 @@ void SYMBOL_LIB_TABLE_RESCUER::AddPart( LIB_PART* aNewPart ) { wxCHECK_RET( aNewPart, "Invalid LIB_PART pointer." ); - wxFileName fn = GetRescueLibraryFileName(); + wxFileName fn = GetRescueLibraryFileName( m_schematic ); try { diff --git a/eeschema/project_rescue.h b/eeschema/project_rescue.h index 250cda2bc4..1fa3d6a20b 100644 --- a/eeschema/project_rescue.h +++ b/eeschema/project_rescue.h @@ -53,6 +53,7 @@ class RESCUER; class SCH_EDIT_FRAME; class SCH_LEGACY_PLUGIN; class SCH_SHEET_PATH; +class SCHEMATIC; enum RESCUE_TYPE @@ -234,6 +235,7 @@ protected: std::vector m_components; PROJECT* m_prj; + SCHEMATIC* m_schematic; EDA_DRAW_PANEL_GAL::GAL_TYPE m_galBackEndType; SCH_SHEET_PATH* m_currentSheet; @@ -243,7 +245,7 @@ protected: std::vector m_rescue_log; public: - RESCUER( PROJECT& aProject, SCH_SHEET_PATH* aCurrentSheet, + RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackeEndType ); virtual ~RESCUER() @@ -299,6 +301,8 @@ public: */ PROJECT* GetPrj() { return m_prj; } + SCHEMATIC* Schematic() { return m_schematic; } + /** * Used by individual #RESCUE_CANDIDATE objects to log a rescue for undoing. */ @@ -327,9 +331,9 @@ private: std::unique_ptr m_rescue_lib; public: - LEGACY_RESCUER( PROJECT& aProject, SCH_SHEET_PATH* aCurrentSheet, + LEGACY_RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, SCH_SHEET_PATH* aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackEndType ) : - RESCUER( aProject, aCurrentSheet, aGalBackEndType ) + RESCUER( aProject, aSchematic, aCurrentSheet, aGalBackEndType ) { } @@ -357,7 +361,8 @@ private: std::unique_ptr< PROPERTIES > m_properties; ///< Library plugin properties public: - SYMBOL_LIB_TABLE_RESCUER( PROJECT& aProject, SCH_SHEET_PATH* aCurrentSheet, + SYMBOL_LIB_TABLE_RESCUER( PROJECT& aProject, SCHEMATIC* aSchematic, + SCH_SHEET_PATH* aCurrentSheet, EDA_DRAW_PANEL_GAL::GAL_TYPE aGalBackeEndType ); virtual ~SYMBOL_LIB_TABLE_RESCUER() diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 751941973e..f334322050 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -345,35 +345,6 @@ void SCH_BASE_FRAME::CenterScreen( const wxPoint& aCenterPoint, bool aWarpPointe } -void SCH_BASE_FRAME::FocusOnItem( SCH_ITEM* aItem ) -{ - static KIID lastBrightenedItemID( niluuid ); - - SCH_SHEET_LIST sheetList( g_RootSheet ); - SCH_SHEET_PATH dummy; - SCH_ITEM* lastItem = sheetList.GetItem( lastBrightenedItemID, &dummy ); - - if( lastItem && lastItem != aItem ) - { - lastItem->ClearBrightened(); - - RefreshItem( lastItem ); - lastBrightenedItemID = niluuid; - } - - if( aItem ) - { - aItem->SetBrightened(); - - RefreshItem( aItem ); - lastBrightenedItemID = aItem->m_Uuid; - - // JEY TODO: test this with pins and fields (and with rotated symbols) .... - FocusOnLocation( aItem->GetFocusPosition() ); - } -} - - void SCH_BASE_FRAME::HardRedraw() { GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL ); diff --git a/eeschema/sch_bus_entry.cpp b/eeschema/sch_bus_entry.cpp index 96f42f660c..4d6731734d 100644 --- a/eeschema/sch_bus_entry.cpp +++ b/eeschema/sch_bus_entry.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -402,7 +403,13 @@ void SCH_BUS_ENTRY_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEM } aList.push_back( MSG_PANEL_ITEM( _( "Bus Entry Type" ), msg, DARKCYAN ) ); - if( auto conn = Connection( *g_CurrentSheet ) ) + + SCH_EDIT_FRAME* frame = dynamic_cast( aFrame ); + + if( !frame ) + return; + + if( auto conn = Connection( frame->GetCurrentSheet() ) ) { #if defined(DEBUG) conn->AppendDebugInfoToMsgPanel( aList ); diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 61ff7de27b..aae2bb8ed3 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -722,13 +723,17 @@ void SCH_COMPONENT::GetPins( std::vector& aPinsList ) SCH_PIN_PTRS SCH_COMPONENT::GetSchPins( const SCH_SHEET_PATH* aSheet ) const { - if( aSheet == nullptr ) - aSheet = g_CurrentSheet; - - // TODO(JE) if this works, consider caching in m_sheet_pins - int unit = GetUnitSelection( aSheet ); SCH_PIN_PTRS ptrs; + if( aSheet == nullptr ) + { + wxCHECK_MSG( Schematic(), ptrs, "Can't call GetSchPins on a component with no schematic" ); + + aSheet = &Schematic()->CurrentSheet(); + } + + int unit = GetUnitSelection( aSheet ); + for( const auto& p : m_pins ) { if( unit && p->GetLibPin()->GetUnit() && ( p->GetLibPin()->GetUnit() != unit ) ) @@ -1160,14 +1165,18 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aL { wxString msg; + SCH_EDIT_FRAME* schframe = dynamic_cast( aFrame ); + // part and alias can differ if alias is not the root if( m_part ) { if( m_part.get() != dummy() ) { - if( g_CurrentSheet ) - aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ), - DARKCYAN ) ); + if( schframe ) + { + aList.push_back( MSG_PANEL_ITEM( + _( "Reference" ), GetRef( &schframe->GetCurrentSheet() ), DARKCYAN ) ); + } msg = m_part->IsPower() ? _( "Power symbol" ) : _( "Value" ); @@ -1213,9 +1222,11 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aL } else { - if( g_CurrentSheet ) - aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ), - DARKCYAN ) ); + if( schframe ) + { + aList.push_back( MSG_PANEL_ITEM( + _( "Reference" ), GetRef( &schframe->GetCurrentSheet() ), DARKCYAN ) ); + } aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(), DARKCYAN ) ); diff --git a/eeschema/sch_connection.cpp b/eeschema/sch_connection.cpp index d98e824b37..d6a8c1d765 100644 --- a/eeschema/sch_connection.cpp +++ b/eeschema/sch_connection.cpp @@ -150,7 +150,7 @@ void SCH_CONNECTION::ConfigureFromLabel( const wxString& aLabel ) for( const wxString& group_member : members ) { // Handle alias inside bus group member list - if( auto alias = g_ConnectionGraph->GetBusAlias( group_member ) ) + if( auto alias = m_graph->GetBusAlias( group_member ) ) { for( const wxString& alias_member : alias->Members() ) { @@ -332,7 +332,7 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const } #endif - if( auto alias = g_ConnectionGraph->GetBusAlias( m_name ) ) + if( auto alias = m_graph->GetBusAlias( m_name ) ) { msg.Printf( _( "Bus Alias %s Members" ), m_name ); @@ -347,7 +347,7 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const { for( const auto& group_member : group_members ) { - if( auto group_alias = g_ConnectionGraph->GetBusAlias( group_member ) ) + if( auto group_alias = m_graph->GetBusAlias( group_member ) ) { msg.Printf( _( "Bus Alias %s Members" ), group_alias->GetName() ); diff --git a/eeschema/sch_connection.h b/eeschema/sch_connection.h index c929eb8b13..c9ed9a2993 100644 --- a/eeschema/sch_connection.h +++ b/eeschema/sch_connection.h @@ -32,6 +32,7 @@ #include +class CONNECTION_GRAPH; class SCH_ITEM; class SCH_SHEET_PATH; @@ -73,6 +74,11 @@ public: bool operator!=( const SCH_CONNECTION& aOther ) const; + void SetGraph( CONNECTION_GRAPH* aGraph ) + { + m_graph = aGraph; + } + /** * Configures the connection given a label. * For CONNECTION_NET, this just sets the name. @@ -370,6 +376,12 @@ private: */ std::vector< std::shared_ptr< SCH_CONNECTION > > m_members; + /** + * Pointer to the connection graph for the schematic this connection exists on. + * Needed for bus alias lookups. + */ + CONNECTION_GRAPH* m_graph; + }; #endif diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index 2c55255177..43e8abb5dd 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -389,7 +390,8 @@ int SCH_EAGLE_PLUGIN::GetModifyHash() const } -SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCH_SHEET* aAppendToMe, +SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, + SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties ) { wxASSERT( !aFileName || aKiway != NULL ); @@ -398,8 +400,9 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCH // Load the document wxXmlDocument xmlDocument; - m_filename = aFileName; - m_kiway = aKiway; + m_filename = aFileName; + m_kiway = aKiway; + m_schematic = aSchematic; if( !xmlDocument.Load( m_filename.GetFullPath() ) ) THROW_IO_ERROR( @@ -410,11 +413,12 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCH if( aAppendToMe ) { - m_rootSheet = aAppendToMe->GetRootSheet(); + wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" ); + m_rootSheet = &aSchematic->Root(); } else { - m_rootSheet = new SCH_SHEET(); + m_rootSheet = new SCH_SHEET( aSchematic ); m_rootSheet->SetFileName( aFileName ); } @@ -422,6 +426,7 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCH { SCH_SCREEN* screen = new SCH_SCREEN( aKiway ); screen->SetFileName( aFileName ); + screen->SetParent( m_schematic ); m_rootSheet->SetScreen( screen ); } @@ -593,12 +598,12 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode ) while( sheetNode ) { wxPoint pos = wxPoint( x * Mils2iu( 1000 ), y * Mils2iu( 1000 ) ); - std::unique_ptr sheet( new SCH_SHEET( pos ) ); + std::unique_ptr sheet( new SCH_SHEET( m_rootSheet, pos ) ); SCH_SCREEN* screen = new SCH_SCREEN( m_kiway ); - sheet->SetParent( m_rootSheet ); sheet->SetScreen( screen ); sheet->GetScreen()->SetFileName( sheet->GetFileName() ); + sheet->GetScreen()->SetParent( m_schematic ); m_currentSheet = sheet.get(); loadSheet( sheetNode, i ); diff --git a/eeschema/sch_eagle_plugin.h b/eeschema/sch_eagle_plugin.h index caa5547601..9e02351596 100644 --- a/eeschema/sch_eagle_plugin.h +++ b/eeschema/sch_eagle_plugin.h @@ -91,8 +91,8 @@ public: int GetModifyHash() const override; - SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCH_SHEET* aAppendToMe = NULL, - const PROPERTIES* aProperties = NULL ) override; + SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, + SCH_SHEET* aAppendToMe = NULL, const PROPERTIES* aProperties = NULL ) override; bool CheckHeader( const wxString& aFileName ) override; @@ -188,6 +188,7 @@ private: wxString m_version; ///< Eagle file version. wxFileName m_filename; wxString m_libName; ///< Library name to save symbols + SCHEMATIC* m_schematic; ///< Passed to Load(), the schematic object being loaded EPART_MAP m_partlist; std::map m_eagleLibs; diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 65959dc868..0effab9165 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -73,10 +74,6 @@ #include -SCH_SHEET_PATH* g_CurrentSheet = nullptr; // declared in general.h -CONNECTION_GRAPH* g_ConnectionGraph = nullptr; -ERC_SETTINGS* g_ErcSettings = nullptr; - // non-member so it can be moved easily, and kept REALLY private. // Do NOT Clear() in here. static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex ) @@ -210,9 +207,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ), m_item_to_repeat( nullptr ) { - g_CurrentSheet = new SCH_SHEET_PATH(); - g_ConnectionGraph = new CONNECTION_GRAPH( this ); - g_ErcSettings = new ERC_SETTINGS(); + m_schematic = new SCHEMATIC(); m_showBorderAndTitleBlock = true; // true to show sheet references m_hasAutoSave = true; @@ -269,6 +264,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): { GetCanvas()->GetGAL()->SetGridVisibility( IsGridVisible() ); GetCanvas()->GetGAL()->SetAxesEnabled( false ); + + if( auto p = dynamic_cast( GetCanvas()->GetView()->GetPainter() ) ) + p->SetSchematic( m_schematic ); } InitExitKey(); @@ -296,15 +294,7 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME() SetScreen( NULL ); - delete g_CurrentSheet; // a SCH_SHEET_PATH, on the heap. - delete g_ConnectionGraph; - delete g_RootSheet; - delete g_ErcSettings; - - g_CurrentSheet = nullptr; - g_ConnectionGraph = nullptr; - g_RootSheet = nullptr; - g_ErcSettings = nullptr; + delete m_schematic; } @@ -358,58 +348,54 @@ void SCH_EDIT_FRAME::SaveCopyForRepeatItem( SCH_ITEM* aItem ) EDA_ITEM* SCH_EDIT_FRAME::GetItem( const KIID& aId ) { - SCH_SHEET_LIST schematic( g_RootSheet ); - SCH_SHEET_PATH dummy; - - return schematic.GetItem( aId, &dummy ); + return Schematic().GetSheets().GetItem( aId ); } void SCH_EDIT_FRAME::SetSheetNumberAndCount() { SCH_SCREEN* screen; - SCH_SCREENS s_list; + SCH_SCREENS s_list( Schematic().Root() ); // Set the sheet count, and the sheet number (1 for root sheet) - int sheet_count = g_RootSheet->CountSheets(); - int SheetNumber = 1; - const KIID_PATH& current_sheetpath = g_CurrentSheet->Path(); - SCH_SHEET_LIST sheetList( g_RootSheet ); + int sheet_count = Schematic().Root().CountSheets(); + int sheet_number = 1; + const KIID_PATH& current_sheetpath = GetCurrentSheet().Path(); // Examine all sheets path to find the current sheets path, // and count them from root to the current sheet path: - for( const SCH_SHEET_PATH& sheet : sheetList ) + for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() ) { if( sheet.Path() == current_sheetpath ) // Current sheet path found break; - SheetNumber++; // Not found, increment before this current path + sheet_number++; // Not found, increment before this current path } - g_CurrentSheet->SetPageNumber( SheetNumber ); + GetCurrentSheet().SetPageNumber( sheet_number ); for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() ) screen->m_NumberOfScreens = sheet_count; - GetScreen()->m_ScreenNumber = SheetNumber; + GetScreen()->m_ScreenNumber = sheet_number; } SCH_SCREEN* SCH_EDIT_FRAME::GetScreen() const { - if( !g_CurrentSheet ) - return nullptr; + return GetCurrentSheet().LastScreen(); +} - return g_CurrentSheet->LastScreen(); + +SCHEMATIC& SCH_EDIT_FRAME::Schematic() const +{ + return *m_schematic; } wxString SCH_EDIT_FRAME::GetScreenDesc() const { - if(! g_CurrentSheet ) - return wxT(""); - - wxString s = g_CurrentSheet->PathHumanReadable(); + wxString s = GetCurrentSheet().PathHumanReadable(); return s; } @@ -417,22 +403,17 @@ wxString SCH_EDIT_FRAME::GetScreenDesc() const void SCH_EDIT_FRAME::CreateScreens() { - if( g_RootSheet == NULL ) - g_RootSheet = new SCH_SHEET(); + m_schematic->Reset(); + m_schematic->SetRoot( new SCH_SHEET( m_schematic ) ); - if( g_RootSheet->GetScreen() == NULL ) - { - SCH_SCREEN* screen = new SCH_SCREEN( &Kiway() ); - screen->SetMaxUndoItems( m_UndoRedoCountMax ); - g_RootSheet->SetScreen( screen ); - SetScreen( g_RootSheet->GetScreen() ); - } + SCH_SCREEN* rootScreen = new SCH_SCREEN( &Kiway() ); + rootScreen->SetMaxUndoItems( m_UndoRedoCountMax ); + m_schematic->Root().SetScreen( rootScreen ); + SetScreen( Schematic().RootScreen() ); - g_RootSheet->GetScreen()->SetFileName( wxEmptyString ); + m_schematic->RootScreen()->SetFileName( wxEmptyString ); - g_CurrentSheet->clear(); - g_CurrentSheet->push_back( g_RootSheet ); - g_ConnectionGraph->Reset(); + GetCurrentSheet().push_back( &m_schematic->Root() ); if( GetScreen() == NULL ) { @@ -445,22 +426,20 @@ void SCH_EDIT_FRAME::CreateScreens() } -SCH_SHEET_PATH& SCH_EDIT_FRAME::GetCurrentSheet() +SCH_SHEET_PATH& SCH_EDIT_FRAME::GetCurrentSheet() const { - wxASSERT_MSG( g_CurrentSheet != NULL, wxT( "SCH_EDIT_FRAME g_CurrentSheet member is NULL." ) ); - - return *g_CurrentSheet; + return m_schematic->CurrentSheet(); } void SCH_EDIT_FRAME::SetCurrentSheet( const SCH_SHEET_PATH& aSheet ) { - if( aSheet != *g_CurrentSheet ) + if( aSheet != GetCurrentSheet() ) { FocusOnItem( nullptr ); - *g_CurrentSheet = aSheet; - GetCanvas()->DisplaySheet( g_CurrentSheet->LastScreen() ); + Schematic().SetCurrentSheet( aSheet ); + GetCanvas()->DisplaySheet( aSheet.LastScreen() ); } } @@ -469,18 +448,16 @@ void SCH_EDIT_FRAME::HardRedraw() { FocusOnItem( nullptr ); - GetCanvas()->DisplaySheet( g_CurrentSheet->LastScreen() ); + GetCanvas()->DisplaySheet( GetCurrentSheet().LastScreen() ); GetCanvas()->ForceRefresh(); } void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); - // Shutdown blocks must be determined and vetoed as early as possible if( SupportsShutdownBlockReason() && aEvent.GetId() == wxEVT_QUERY_END_SESSION - && sheetList.IsModified() ) + && Schematic().GetSheets().IsModified() ) { aEvent.Veto(); return; @@ -507,9 +484,11 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) if( simFrame && !simFrame->Close() ) // Can close the simulator? return; - if( sheetList.IsModified() ) + SCH_SHEET_LIST sheetlist = Schematic().GetSheets(); + + if( sheetlist.IsModified() ) { - wxFileName fileName = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fileName = Schematic().RootScreen()->GetFileName(); wxString msg = _( "Save changes to \"%s\" before closing?" ); if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ), @@ -546,7 +525,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) if( FindHierarchyNavigator() ) FindHierarchyNavigator()->Close( true ); - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); wxFileName fn; for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) @@ -560,17 +539,17 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) wxRemoveFile( fn.GetFullPath() ); } - sheetList.ClearModifyStatus(); + sheetlist.ClearModifyStatus(); - wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxString fileName = Prj().AbsolutePath( Schematic().RootScreen()->GetFileName() ); - if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() && !g_RootSheet->GetScreen()->IsEmpty() ) + if( !Schematic().GetFileName().IsEmpty() && !Schematic().RootScreen()->IsEmpty() ) UpdateFileHistory( fileName ); - g_RootSheet->GetScreen()->Clear(); + Schematic().RootScreen()->Clear(); // all sub sheets are deleted, only the main sheet is usable - g_CurrentSheet->clear(); + GetCurrentSheet().clear(); Destroy(); } @@ -582,11 +561,11 @@ wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet() // Note that we need to fetch the rootSheetName out of its filename, as the root SCH_SHEET's // name is just a timestamp. - wxFileName rootFn( g_CurrentSheet->at( 0 )->GetFileName() ); + wxFileName rootFn( GetCurrentSheet().at( 0 )->GetFileName() ); wxString filename = rootFn.GetName(); - for( unsigned i = 1; i < g_CurrentSheet->size(); i++ ) - filename += wxT( "-" ) + g_CurrentSheet->at( i )->GetName(); + for( unsigned i = 1; i < GetCurrentSheet().size(); i++ ) + filename += wxT( "-" ) + GetCurrentSheet().at( i )->GetName(); return filename; } @@ -611,7 +590,7 @@ void SCH_EDIT_FRAME::OnModify() void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event ) { - wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxFileName fn = Prj().AbsolutePath( Schematic().GetFileName() ); fn.SetExt( PcbFileExtension ); @@ -811,7 +790,7 @@ void SCH_EDIT_FRAME::ParseArgs( wxCmdLineParser& aParser ) void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) { - wxFileName kicad_board = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxFileName kicad_board = Prj().AbsolutePath( Schematic().GetFileName() ); if( kicad_board.IsOk() ) { @@ -857,7 +836,7 @@ void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) { - wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxFileName fn = Prj().AbsolutePath( Schematic().GetFileName() ); fn.SetExt( NetlistFileExtension ); if( !prepareForNetlist() ) @@ -909,9 +888,9 @@ bool SCH_EDIT_FRAME::isAutoSaveRequired() const // In case this event happens before g_RootSheet is initialized which does happen // on mingw64 builds. - if( g_RootSheet != NULL ) + if( Schematic().IsValid() ) { - SCH_SCREENS screenList; + SCH_SCREENS screenList( Schematic().Root() ); for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() ) { @@ -1004,7 +983,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe TestDanglingEnds(); - for( SCH_ITEM* item : aItem->ConnectedItems( *g_CurrentSheet ) ) + for( SCH_ITEM* item : aItem->ConnectedItems( GetCurrentSheet() ) ) RefreshItem( item ); } @@ -1028,7 +1007,7 @@ void SCH_EDIT_FRAME::UpdateTitle() title.Printf( _( "Eeschema" ) + wxT( " \u2014 %s [%s] \u2014 %s" ), fn.GetFullName(), - g_CurrentSheet->PathHumanReadable(), + GetCurrentSheet().PathHumanReadable(), fn.GetPath() ); if( fn.FileExists() ) @@ -1044,15 +1023,9 @@ void SCH_EDIT_FRAME::UpdateTitle() } -int SCH_EDIT_FRAME::GetSeverity( int aErrorCode ) const -{ - return ::GetSeverity( aErrorCode ); -} - - void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags ) { - SCH_SHEET_LIST list( g_RootSheet ); + SCH_SHEET_LIST list = Schematic().GetSheets(); PROF_COUNTER timer; // Ensure schematic graph is accurate @@ -1069,7 +1042,7 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags ) timer.Stop(); wxLogTrace( "CONN_PROFILE", "SchematicCleanUp() %0.4f ms", timer.msecs() ); - g_ConnectionGraph->Recalculate( list, true ); + Schematic().ConnectionGraph()->Recalculate( list, true ); } @@ -1133,8 +1106,7 @@ void SCH_EDIT_FRAME::FixupJunctions() bool modified = false; - SCH_SHEET_LIST sheetList; - sheetList.BuildSheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = Schematic().GetSheets(); for( const SCH_SHEET_PATH& sheet : sheetList ) { @@ -1179,9 +1151,7 @@ void SCH_EDIT_FRAME::FixupJunctions() bool SCH_EDIT_FRAME::IsContentModified() { - SCH_SHEET_LIST sheetList( g_RootSheet ); - - return sheetList.IsModified(); + return Schematic().GetSheets().IsModified(); } @@ -1192,6 +1162,35 @@ bool SCH_EDIT_FRAME::GetShowAllPins() const } +void SCH_EDIT_FRAME::FocusOnItem( SCH_ITEM* aItem ) +{ + static KIID lastBrightenedItemID( niluuid ); + + SCH_SHEET_LIST sheetList = Schematic().GetSheets(); + SCH_SHEET_PATH dummy; + SCH_ITEM* lastItem = sheetList.GetItem( lastBrightenedItemID, &dummy ); + + if( lastItem && lastItem != aItem ) + { + lastItem->ClearBrightened(); + + RefreshItem( lastItem ); + lastBrightenedItemID = niluuid; + } + + if( aItem ) + { + aItem->SetBrightened(); + + RefreshItem( aItem ); + lastBrightenedItemID = aItem->m_Uuid; + + // JEY TODO: test this with pins and fields (and with rotated symbols) .... + FocusOnLocation( aItem->GetFocusPosition() ); + } +} + + void SCH_EDIT_FRAME::ConvertTimeStampUuids() { // Remove this once this method is fully implemented. Otherwise, don't use it. @@ -1201,14 +1200,14 @@ void SCH_EDIT_FRAME::ConvertTimeStampUuids() // sheet paths using the new UUID based sheet paths. // Save the time stamp sheet paths. - SCH_SHEET_LIST timeStampSheetPaths( g_RootSheet ); + SCH_SHEET_LIST timeStampSheetPaths = Schematic().GetSheets(); std::vector oldSheetPaths = timeStampSheetPaths.GetPaths(); // The root sheet now gets a permanent UUID. - const_cast( g_RootSheet->m_Uuid ).ConvertTimestampToUuid(); + const_cast( Schematic().Root().m_Uuid ).ConvertTimestampToUuid(); - SCH_SCREENS schematic; + SCH_SCREENS schematic( Schematic().Root() ); // Change the sheet and symbol time stamps to UUIDs. for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) @@ -1220,18 +1219,11 @@ void SCH_EDIT_FRAME::ConvertTimeStampUuids() const_cast( symbol->m_Uuid ).ConvertTimestampToUuid(); } - SCH_SHEET_LIST uuidSheetPaths( g_RootSheet ); - timeStampSheetPaths.ReplaceLegacySheetPaths( oldSheetPaths ); } wxString SCH_EDIT_FRAME::GetCurrentFileName() const { - SCH_SCREEN* screen = g_RootSheet->GetScreen(); - - if( screen ) - return screen->GetFileName(); - - return wxEmptyString; + return Schematic().GetFileName(); } diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 441943d8ac..87d37a576c 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -58,6 +58,7 @@ class SCH_SHEET_PIN; class SCH_COMPONENT; class SCH_FIELD; class SCH_JUNCTION; +class SCHEMATIC; class DIALOG_SCH_FIND; class wxFindReplaceData; class RESCUER; @@ -121,6 +122,7 @@ class SCH_EDIT_FRAME : public SCH_BASE_FRAME friend class SCH_EDITOR_CONTROL; private: + SCHEMATIC* m_schematic; ///< The currently loaded schematic wxString m_SelectedNetName; std::vector m_projectFileParams; @@ -185,6 +187,8 @@ public: SCH_SCREEN* GetScreen() const override; + SCHEMATIC& Schematic() const; + void OnCloseWindow( wxCloseEvent& Event ); /** @@ -506,11 +510,8 @@ public: */ int ModalAnnotate( const wxString& aMessage ); - ///> @copydoc EDA_BASE_FRAME::GetSeverity() - int GetSeverity( int aErrorCode ) const override; - // Functions used for hierarchy handling - SCH_SHEET_PATH& GetCurrentSheet(); + SCH_SHEET_PATH& GetCurrentSheet() const; void SetCurrentSheet( const SCH_SHEET_PATH& aSheet ); @@ -691,6 +692,12 @@ private: */ bool importFile( const wxString& aFileName, int aFileType ); + /** + * Fills a map of uuid -> reference from the currently loaded schematic + * @param aMap is a map to fill + */ + void mapExistingAnnotation( std::map& aMap ); + public: /** * Verify that \a aSheet will not cause a recursion error in \a aHierarchy. @@ -984,6 +991,8 @@ public: void FixupJunctions(); + void FocusOnItem( SCH_ITEM* aItem ); + /** * Convert sheet and symbol legacy time stamp UUIDs to full UUIDs. * diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 96d9c3c8cc..c8c04ab832 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -120,8 +121,8 @@ wxString SCH_FIELD::GetShownText( int aDepth ) const if( processTextVars ) { - if( g_RootSheet && g_RootSheet->GetScreen() ) - project = &g_RootSheet->GetScreen()->Kiway().Prj(); + if( Schematic() ) + project = &Schematic()->RootScreen()->Kiway().Prj(); if( aDepth < 10 ) { diff --git a/eeschema/sch_io_mgr.h b/eeschema/sch_io_mgr.h index fe2edd9ff4..94c121e133 100644 --- a/eeschema/sch_io_mgr.h +++ b/eeschema/sch_io_mgr.h @@ -32,6 +32,7 @@ class SCH_SHEET; class SCH_SCREEN; class SCH_PLUGIN; +class SCHEMATIC; class KIWAY; class LIB_PART; class PART_LIB; @@ -208,7 +209,7 @@ public: * wrong, using line number and character offsets of the input file if * possible. */ - virtual SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, + virtual SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe = NULL, const PROPERTIES* aProperties = NULL ); /** diff --git a/eeschema/sch_item.cpp b/eeschema/sch_item.cpp index 090275007c..7cc8347df0 100644 --- a/eeschema/sch_item.cpp +++ b/eeschema/sch_item.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -46,9 +47,8 @@ SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ) : EDA_ITEM( aParent, aType ) { - m_Layer = LAYER_WIRE; // It's only a default, in fact - m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; - + m_Layer = LAYER_WIRE; // It's only a default, in fact + m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; m_connectivity_dirty = true; } @@ -56,9 +56,8 @@ SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ) : SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) : EDA_ITEM( aItem ) { - m_Layer = aItem.m_Layer; - m_fieldsAutoplaced = aItem.m_fieldsAutoplaced; - + m_Layer = aItem.m_Layer; + m_fieldsAutoplaced = aItem.m_fieldsAutoplaced; m_connectivity_dirty = true; } @@ -111,6 +110,22 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const } +SCHEMATIC* SCH_ITEM::Schematic() const +{ + EDA_ITEM* parent = GetParent(); + + while( parent ) + { + if( parent->Type() == SCHEMATIC_T ) + return static_cast( parent ); + else + parent = parent->GetParent(); + } + + return nullptr; +} + + void SCH_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const { // Basic fallback diff --git a/eeschema/sch_item.h b/eeschema/sch_item.h index 6d516dfafb..02aad8d75f 100644 --- a/eeschema/sch_item.h +++ b/eeschema/sch_item.h @@ -36,6 +36,7 @@ class SCH_CONNECTION; class SCH_SHEET_PATH; +class SCHEMATIC; class LINE_READER; class SCH_EDIT_FRAME; class wxFindReplaceData; @@ -208,6 +209,19 @@ public: wxPoint& GetStoredPos() { return m_storedPos; } void SetStoredPos( wxPoint aPos ) { m_storedPos = aPos; } + /** + * Searches the item hierarchy to find a SCHEMATIC + * + * Every SCH_ITEM that lives on a SCH_SCREEN should be parented to either that screen + * or another SCH_ITEM on the same screen (for example, pins to their components). + * + * Every SCH_SCREEN should be parented to the SCHEMATIC. + * Note that this hierarchy is not the same as the sheet hierarchy! + * + * @return the parent schematic this item lives on, or nullptr + */ + SCHEMATIC* Schematic() const; + /** * Function IsLocked * @return bool - true if the object is locked, else false diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index d9d1a1e989..73aa54b3ed 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -586,7 +587,7 @@ void SCH_LEGACY_PLUGIN::init( KIWAY* aKiway, const PROPERTIES* aProperties ) } -SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, +SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties ) { wxASSERT( !aFileName || aKiway != NULL ); @@ -594,6 +595,8 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, LOCALE_IO toggle; // toggles on, then off, the C locale. SCH_SHEET* sheet; + m_schematic = aSchematic; + wxFileName fn = aFileName; // Unfortunately child sheet file names the legacy schematic file format are not fully @@ -630,7 +633,7 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, if( aAppendToMe == NULL ) { // Clean up any allocated memory if an exception occurs loading the schematic. - std::unique_ptr< SCH_SHEET > newSheet( new SCH_SHEET ); + std::unique_ptr< SCH_SHEET > newSheet( new SCH_SHEET( aSchematic ) ); newSheet->SetFileName( aFileName ); m_rootSheet = newSheet.get(); loadHierarchy( newSheet.get() ); @@ -640,8 +643,8 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, } else { - m_rootSheet = aAppendToMe->GetRootSheet(); - wxASSERT( m_rootSheet ); + wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" ); + m_rootSheet = &aSchematic->Root(); sheet = aAppendToMe; loadHierarchy( sheet ); } @@ -682,13 +685,14 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet ) if( screen ) { aSheet->SetScreen( screen ); - + screen->SetParent( m_schematic ); // Do not need to load the sub-sheets - this has already been done. } else { aSheet->SetScreen( new SCH_SCREEN( m_kiway ) ); aSheet->GetScreen()->SetFileName( fileName.GetFullPath() ); + aSheet->GetScreen()->SetParent( m_schematic ); try { @@ -757,10 +761,9 @@ void SCH_LEGACY_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen, { m_version = version; - // We cannot safely load content without a set root level. If we haven't been given one, - // pick the default - if( m_rootSheet == nullptr ) - m_rootSheet = g_RootSheet; + // We cannot safely load content without a set root level. + wxCHECK_RET( m_rootSheet, + "Cannot call SCH_LEGACY_PLUGIN::LoadContent() without setting root sheet." ); while( aReader.ReadLine() ) { diff --git a/eeschema/sch_legacy_plugin.h b/eeschema/sch_legacy_plugin.h index ded4bf81a5..7ca7e7fbf4 100644 --- a/eeschema/sch_legacy_plugin.h +++ b/eeschema/sch_legacy_plugin.h @@ -97,7 +97,7 @@ public: int GetModifyHash() const override; - SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, + SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway , SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe = nullptr, const PROPERTIES* aProperties = nullptr ) override; @@ -181,6 +181,7 @@ protected: SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.. OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects. SCH_LEGACY_PLUGIN_CACHE* m_cache; + SCHEMATIC* m_schematic; ///< Passed to Load(), the schematic object being loaded /// initialize PLUGIN like a constructor would. void init( KIWAY* aKiway, const PROPERTIES* aProperties = nullptr ); diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp index ed6e71498e..9b63a9fcf6 100644 --- a/eeschema/sch_line.cpp +++ b/eeschema/sch_line.cpp @@ -791,7 +791,12 @@ void SCH_LINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Line Type" ), msg, DARKCYAN ) ); - if( auto conn = Connection( *g_CurrentSheet ) ) + SCH_EDIT_FRAME* frame = dynamic_cast( aFrame ); + + if( !frame ) + return; + + if( auto conn = Connection( frame->GetCurrentSheet() ) ) { #if defined(DEBUG) conn->AppendDebugInfoToMsgPanel( aList ); diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp index f91b8f8b9e..642ee4f362 100644 --- a/eeschema/sch_marker.cpp +++ b/eeschema/sch_marker.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -75,9 +76,11 @@ void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const void SCH_MARKER::ViewGetLayers( int aLayers[], int& aCount ) const { - aCount = 2; + aCount = 2; - switch( GetSeverity( m_rcItem->GetErrorCode() ) ) + wxCHECK_RET( Schematic(), "No SCHEMATIC set for SCH_MARKER!" ); + + switch( Schematic()->GetErcSeverity( m_rcItem->GetErrorCode() ) ) { default: case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_ERC_ERR; break; @@ -93,7 +96,9 @@ SCH_LAYER_ID SCH_MARKER::GetColorLayer() const if( IsExcluded() ) return LAYER_HIDDEN; - switch( GetSeverity( m_rcItem->GetErrorCode() ) ) + wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" ); + + switch( Schematic()->GetErcSeverity( m_rcItem->GetErrorCode() ) ) { default: case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR; diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index 964c2d8c10..5d7591ca12 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -150,7 +151,8 @@ static LIB_PART* dummy() SCH_PAINTER::SCH_PAINTER( GAL* aGal ) : - KIGFX::PAINTER( aGal ) + KIGFX::PAINTER( aGal ), + m_schematic( nullptr ) { } @@ -1267,11 +1269,15 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer ) default: aLayer = LAYER_NOTES; break; } - COLOR4D color = getRenderColor( aText, aLayer, drawingShadows ); - SCH_CONNECTION* conn = aText->Connection( *g_CurrentSheet ); + COLOR4D color = getRenderColor( aText, aLayer, drawingShadows ); - if( conn && conn->IsBus() ) - color = getRenderColor( aText, LAYER_BUS, drawingShadows ); + if( m_schematic ) + { + SCH_CONNECTION* conn = aText->Connection( m_schematic->CurrentSheet() ); + + if( conn && conn->IsBus() ) + color = getRenderColor( aText, LAYER_BUS, drawingShadows ); + } if( !( aText->IsVisible() || aText->IsForceVisible() ) ) { @@ -1565,10 +1571,13 @@ void SCH_PAINTER::draw( SCH_HIERLABEL *aLabel, int aLayer ) COLOR4D color = getRenderColor( aLabel, LAYER_SHEETLABEL, drawingShadows ); - SCH_CONNECTION* conn = aLabel->Connection( *g_CurrentSheet ); + if( m_schematic ) + { + SCH_CONNECTION* conn = aLabel->Connection( m_schematic->CurrentSheet() ); - if( conn && conn->IsBus() ) - color = getRenderColor( aLabel, LAYER_BUS, drawingShadows ); + if( conn && conn->IsBus() ) + color = getRenderColor( aLabel, LAYER_BUS, drawingShadows ); + } std::vector pts; std::deque pts2; diff --git a/eeschema/sch_painter.h b/eeschema/sch_painter.h index 9a422ee867..ee84eb7c4a 100644 --- a/eeschema/sch_painter.h +++ b/eeschema/sch_painter.h @@ -54,6 +54,7 @@ class SCH_NO_CONNECT; class SCH_LINE; class SCH_BUS_ENTRY_BASE; class SCH_BITMAP; +class SCHEMATIC; namespace KIGFX { @@ -143,6 +144,11 @@ public: return &m_schSettings; } + void SetSchematic( SCHEMATIC* aSchematic ) + { + m_schematic = aSchematic; + } + private: void draw( LIB_RECTANGLE* aRect, int aLayer ); void draw( LIB_PIN* aPin, int aLayer ); @@ -190,6 +196,8 @@ private: void strokeText( const wxString& aText, const VECTOR2D& aPosition, double aRotationAngle ); SCH_RENDER_SETTINGS m_schSettings; + + SCHEMATIC* m_schematic; }; }; // namespace KIGFX diff --git a/eeschema/sch_plugin.cpp b/eeschema/sch_plugin.cpp index 8b9f96039c..5ae9e351fa 100644 --- a/eeschema/sch_plugin.cpp +++ b/eeschema/sch_plugin.cpp @@ -47,8 +47,8 @@ void SCH_PLUGIN::SaveLibrary( const wxString& aFileName, const PROPERTIES* aProp } -SCH_SHEET* SCH_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCH_SHEET* aAppendToMe, - const PROPERTIES* aProperties ) +SCH_SHEET* SCH_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, + SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties ) { not_implemented( this, __FUNCTION__ ); return NULL; diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 74c716dba8..9e85d63658 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -154,6 +155,15 @@ SCH_SCREEN::~SCH_SCREEN() } +SCHEMATIC* SCH_SCREEN::Schematic() const +{ + wxCHECK_MSG( GetParent() && GetParent()->Type() == SCHEMATIC_T, nullptr, + "SCH_SCREEN must have a SCHEMATIC parent!" ); + + return static_cast( GetParent() ); +} + + void SCH_SCREEN::clearLibSymbols() { for( auto libSymbol : m_libSymbols ) @@ -187,6 +197,9 @@ bool SCH_SCREEN::HasItems( KICAD_T aItemType ) const void SCH_SCREEN::Append( SCH_ITEM* aItem ) { + // Ensure the item can reach the SCHEMATIC through this screen + aItem->SetParent( this ); + if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T ) { if( aItem->Type() == SCH_COMPONENT_T ) @@ -1178,42 +1191,6 @@ void SCH_SCREEN::AddBusAlias( std::shared_ptr aAlias ) } -bool SCH_SCREEN::IsBusAlias( const wxString& aLabel ) -{ - SCH_SHEET_LIST aSheets( g_RootSheet ); - for( unsigned i = 0; i < aSheets.size(); i++ ) - { - for( const auto& alias : aSheets[i].LastScreen()->GetBusAliases() ) - { - if( alias->GetName() == aLabel ) - { - return true; - } - } - } - - return false; -} - - -std::shared_ptr SCH_SCREEN::GetBusAlias( const wxString& aLabel ) -{ - SCH_SHEET_LIST aSheets( g_RootSheet ); - for( unsigned i = 0; i < aSheets.size(); i++ ) - { - for( auto alias : aSheets[i].LastScreen()->GetBusAliases() ) - { - if( alias->GetName() == aLabel ) - { - return alias; - } - } - } - - return NULL; -} - - #if defined(DEBUG) void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const { @@ -1231,7 +1208,7 @@ void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const SCH_SCREENS::SCH_SCREENS( SCH_SHEET* aSheet ) { m_index = 0; - buildScreenList( ( !aSheet ) ? g_RootSheet : aSheet ); + buildScreenList( aSheet ); } @@ -1317,16 +1294,18 @@ void SCH_SCREENS::ClearAnnotation() void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList ) { + SCHEMATIC* sch = GetFirst()->Schematic(); + + wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::ClearAnnotationOfNewSheetPaths" ); + // Clear the annotation for the components inside new sheetpaths // not already in aInitialSheetList - SCH_SCREENS screensList( g_RootSheet ); // The list of screens, shared by sheet paths + SCH_SCREENS screensList( sch->Root() ); // The list of screens, shared by sheet paths screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen // Search for new sheet paths, not existing in aInitialSheetPathList // and existing in sheetpathList - SCH_SHEET_LIST sheetpathList( g_RootSheet ); - - for( SCH_SHEET_PATH& sheetpath: sheetpathList ) + for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() ) { bool path_exists = false; @@ -1440,12 +1419,16 @@ void SCH_SCREENS::UpdateSymbolLinks( REPORTER* aReporter ) for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() ) screen->UpdateSymbolLinks( aReporter ); - SCH_SHEET_LIST sheets( g_RootSheet ); + SCHEMATIC* sch = GetFirst()->Schematic(); + + wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::UpdateSymbolLinks" ); + + SCH_SHEET_LIST sheets = sch->GetSheets(); // All of the library symbols have been replaced with copies so the connection graph // pointer are stale. - if( g_ConnectionGraph ) - g_ConnectionGraph->Recalculate( sheets, true ); + if( sch->ConnectionGraph() ) + sch->ConnectionGraph()->Recalculate( sheets, true ); } @@ -1588,12 +1571,14 @@ bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileNa void SCH_SCREENS::BuildClientSheetPathList() { - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCHEMATIC* sch = GetFirst()->Schematic(); + + wxCHECK_RET( sch, "Null schematic in SCH_SCREENS::BuildClientSheetPathList" ); for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() ) curr_screen->GetClientSheetPaths().clear(); - for( SCH_SHEET_PATH& sheetpath: sheetList ) + for( SCH_SHEET_PATH& sheetpath : sch->GetSheets() ) { SCH_SCREEN* used_screen = sheetpath.LastScreen(); diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index b58f38344f..3883da9ede 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -157,6 +157,8 @@ public: ~SCH_SCREEN(); + SCHEMATIC* Schematic() const; + EE_RTREE& Items() { return m_rtree; @@ -534,17 +536,6 @@ public: return m_aliases; } - /** - * Returns true if the given string is a valid bus alias in a loaded screen - */ - static bool IsBusAlias( const wxString& aLabel ); - - /** - * Returns a pointer to a bus alias object for the given label, - * or null if one doesn't exist - */ - static std::shared_ptr GetBusAlias( const wxString& aLabel ); - #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override; #endif @@ -555,6 +546,10 @@ public: * Container class that holds multiple #SCH_SCREEN objects in a hierarchy. * * Individual #SCH_SCREEN objects are unique and correspond to .sch files. + * + * NOTE: It may be desirable to fold the functionality of SCH_SCREENS into + * the new SCHEMATIC class at some point, since SCHEMATIC can also be thought + * of as owning the collection of all the SCH_SCREEN objects. */ class SCH_SCREENS { @@ -564,7 +559,8 @@ private: unsigned int m_index; public: - SCH_SCREENS( SCH_SHEET* aSheet = NULL ); + SCH_SCREENS( SCH_SHEET* aSheet ); + SCH_SCREENS( SCH_SHEET& aSheet ) : SCH_SCREENS( &aSheet ) {} ~SCH_SCREENS(); size_t GetCount() const { return m_screens.size(); } SCH_SCREEN* GetFirst(); diff --git a/eeschema/sch_sexpr_plugin.cpp b/eeschema/sch_sexpr_plugin.cpp index a6b807903c..9bb336791a 100644 --- a/eeschema/sch_sexpr_plugin.cpp +++ b/eeschema/sch_sexpr_plugin.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -418,7 +419,7 @@ void SCH_SEXPR_PLUGIN::init( KIWAY* aKiway, const PROPERTIES* aProperties ) } -SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, +SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe, const PROPERTIES* aProperties ) { wxASSERT( !aFileName || aKiway != NULL ); @@ -459,10 +460,12 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, m_currentPath.push( m_path ); init( aKiway, aProperties ); + m_schematic = aSchematic; + if( aAppendToMe == NULL ) { // Clean up any allocated memory if an exception occurs loading the schematic. - std::unique_ptr< SCH_SHEET > newSheet( new SCH_SHEET ); + std::unique_ptr< SCH_SHEET > newSheet( new SCH_SHEET( aSchematic ) ); newSheet->SetFileName( aFileName ); m_rootSheet = newSheet.get(); loadHierarchy( newSheet.get() ); @@ -473,8 +476,8 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, } else { - m_rootSheet = aAppendToMe->GetRootSheet(); - wxASSERT( m_rootSheet != NULL ); + wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" ); + m_rootSheet = &aSchematic->Root(); sheet = aAppendToMe; loadHierarchy( sheet ); } @@ -514,13 +517,14 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( SCH_SHEET* aSheet ) if( screen ) { aSheet->SetScreen( screen ); - + aSheet->GetScreen()->SetParent( m_schematic ); // Do not need to load the sub-sheets - this has already been done. } else { aSheet->SetScreen( new SCH_SCREEN( m_kiway ) ); aSheet->GetScreen()->SetFileName( fileName.GetFullPath() ); + aSheet->GetScreen()->SetParent( m_schematic ); try { diff --git a/eeschema/sch_sexpr_plugin.h b/eeschema/sch_sexpr_plugin.h index 2384a6add5..0d1877eb9e 100644 --- a/eeschema/sch_sexpr_plugin.h +++ b/eeschema/sch_sexpr_plugin.h @@ -84,7 +84,7 @@ public: int GetModifyHash() const override; - SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, + SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway, SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe = nullptr, const PROPERTIES* aProperties = nullptr ) override; @@ -156,6 +156,7 @@ protected: const PROPERTIES* m_props; ///< Passed via Save() or Load(), no ownership, may be nullptr. KIWAY* m_kiway; ///< Required for path to legacy component libraries. SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.. + SCHEMATIC* m_schematic; ///< Passed to Load(), the schematic object being loaded OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects. SCH_SEXPR_PLUGIN_CACHE* m_cache; diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 0949b009d5..9823de4f53 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -67,8 +68,8 @@ const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx ) } -SCH_SHEET::SCH_SHEET( const wxPoint& pos ) : - SCH_ITEM( NULL, SCH_SHEET_T ) +SCH_SHEET::SCH_SHEET( EDA_ITEM* aParent, const wxPoint& pos ) : + SCH_ITEM( aParent, SCH_SHEET_T ) { m_Layer = LAYER_SHEET; m_pos = pos; @@ -146,19 +147,6 @@ EDA_ITEM* SCH_SHEET::Clone() const } -void SCH_SHEET::SetParent( EDA_ITEM* aSheet ) -{ - m_Parent = nullptr; - - if( aSheet ) - { - // Parent must be another SCH_SHEET object or nullptr - wxCHECK( aSheet->Type() == SCH_SHEET_T, /* void */ ); - m_Parent = aSheet; - } -} - - void SCH_SHEET::SetScreen( SCH_SCREEN* aScreen ) { if( aScreen == m_screen ) @@ -191,20 +179,11 @@ int SCH_SHEET::GetScreenCount() const } -SCH_SHEET* SCH_SHEET::GetRootSheet() +bool SCH_SHEET::IsRootSheet() const { - EDA_ITEM* item = GetParent(); + wxCHECK_MSG( Schematic(), false, "Can't call IsRootSheet without setting a schematic" ); - if( item == nullptr ) - return this; - - SCH_SHEET* sheet = dynamic_cast< SCH_SHEET* >( item ); - - // The parent must be a SCH_SHEET object. - wxCHECK( sheet, nullptr ); - - // Recurse until a sheet is found with no parent which is the root sheet. - return sheet->GetRootSheet(); + return &Schematic()->Root() == this; } @@ -230,9 +209,7 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const if( token->IsSameAs( wxT( "#" ) ) ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); - - for( const SCH_SHEET_PATH& sheet : sheetList ) + for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() ) { if( sheet.Last() == this ) // Current sheet path found { @@ -243,7 +220,7 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const } else if( token->IsSameAs( wxT( "##" ) ) ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = Schematic()->GetSheets(); *token = wxString::Format( wxT( "%d" ), (int) sheetList.size() ); return true; } @@ -703,7 +680,7 @@ bool SCH_SHEET::LocatePathOfScreen( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aList ) } -int SCH_SHEET::CountSheets() +int SCH_SHEET::CountSheets() const { int count = 1; //1 = this!! @@ -723,11 +700,15 @@ void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList aList.emplace_back( _( "File Name" ), m_fields[ SHEETFILENAME ].GetText(), BROWN ); #if 1 // Set to 1 to display the sheet UUID and hierarchical path - wxString msgU, msgL; - msgU << _( "UUID" ) << ": " << m_Uuid.AsString(); - msgL << _( "Path" ) << ": " << g_CurrentSheet->PathHumanReadable(); - aList.push_back( MSG_PANEL_ITEM( msgU, msgL, BLUE ) ); + if( auto schframe = dynamic_cast( aFrame ) ) + { + wxString msgU, msgL; + msgU << _( "UUID" ) << ": " << m_Uuid.AsString(); + msgL << _( "Path" ) << ": " << schframe->GetCurrentSheet().PathHumanReadable(); + + aList.push_back( MSG_PANEL_ITEM( msgU, msgL, BLUE ) ); + } #endif } diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index de92753dc4..9c77c172d9 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -234,7 +234,7 @@ class SCH_SHEET : public SCH_ITEM KIGFX::COLOR4D m_backgroundColor; public: - SCH_SHEET( const wxPoint& pos = wxPoint( 0, 0 ) ); + SCH_SHEET( EDA_ITEM* aParent = nullptr, const wxPoint& pos = wxPoint( 0, 0 ) ); /** * Copy \a aSheet into a new object. All sheet pins are copied as is except and @@ -254,8 +254,6 @@ public: return wxT( "SCH_SHEET" ); } - virtual void SetParent( EDA_ITEM* aSheet ) override; - /** * Return true for items which are moved with the anchor point at mouse cursor * and false for items moved with no reference to anchor. @@ -281,7 +279,7 @@ public: wxString GetName() const { return m_fields[ SHEETNAME ].GetText(); } - SCH_SCREEN* GetScreen() { return m_screen; } + SCH_SCREEN* GetScreen() const { return m_screen; } wxSize GetSize() { return m_size; } void SetSize( const wxSize& aSize ) { m_size = aSize; } @@ -307,21 +305,10 @@ public: */ bool UsesDefaultStroke() const; - /** - * Return the root sheet of this SCH_SHEET object. - * - * The root (top level) sheet can be found by walking up the parent links until the only - * sheet that has no parent is found. The root sheet can be found from any sheet without - * having to maintain a global root sheet pointer. - * - * @return a SCH_SHEET pointer to the root sheet. - */ - SCH_SHEET* GetRootSheet(); - /** * @return true if this sheet is the root sheet. */ - bool IsRootSheet() { return GetRootSheet() == this; } + bool IsRootSheet() const; /** * Set the #SCH_SCREEN associated with this sheet to \a aScreen. @@ -494,7 +481,7 @@ public: * * @return the full count of sheets+subsheets contained by "this" */ - int CountSheets(); + int CountSheets() const; /** * Return the filename corresponding to this sheet. diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index ee0b56e414..fe0c7732b0 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu void SCH_SHEET_PATH::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP& aRefList, - bool aIncludePowerSymbols ) + bool aIncludePowerSymbols ) const { for( auto item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) ) { @@ -263,7 +264,11 @@ bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxStr if( m_recursion_test_cache.count( pair ) ) return m_recursion_test_cache.at( pair ); - wxFileName rootFn = g_RootSheet->GetFileName(); + SCHEMATIC* sch = LastScreen()->Schematic(); + + wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_PATH::TestForRecursion!" ); + + wxFileName rootFn = sch->GetFileName(); wxFileName srcFn = aSrcFileName; wxFileName destFn = aDestFileName; @@ -335,8 +340,6 @@ bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxStr SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) { - m_isRootSheet = false; - if( aSheet != NULL ) BuildSheetList( aSheet ); } @@ -348,9 +351,6 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) std::vector badSheets; - if( aSheet == g_RootSheet ) - m_isRootSheet = true; - m_currentSheetPath.push_back( aSheet ); /** @@ -432,7 +432,9 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { if( aItem->m_Uuid == aID ) { - *aPathOut = sheet; + if( aPathOut ) + *aPathOut = sheet; + return aItem; } else if( aItem->Type() == SCH_COMPONENT_T ) @@ -443,7 +445,9 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { if( field.m_Uuid == aID ) { - *aPathOut = sheet; + if( aPathOut ) + *aPathOut = sheet; + return &field; } } @@ -452,7 +456,9 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { if( pin->m_Uuid == aID ) { - *aPathOut = sheet; + if( aPathOut ) + *aPathOut = sheet; + return pin; } } @@ -465,7 +471,8 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { if( field.m_Uuid == aID ) { - *aPathOut = sheet; + if( aPathOut ) + *aPathOut = sheet; return &field; } } @@ -474,7 +481,9 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { if( pin->m_Uuid == aID ) { - *aPathOut = sheet; + if( aPathOut ) + *aPathOut = sheet; + return pin; } } @@ -595,16 +604,17 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols() void SCH_SHEET_LIST::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols, - bool aForceIncludeOrphanComponents ) + bool aForceIncludeOrphanComponents ) const { - for( SCH_SHEET_PATH& sheet : *this ) + for( const SCH_SHEET_PATH& sheet : *this ) sheet.GetComponents( aReferences, aIncludePowerSymbols, aForceIncludeOrphanComponents ); } + void SCH_SHEET_LIST::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, - bool aIncludePowerSymbols ) + bool aIncludePowerSymbols ) const { - for( SCH_SHEET_PATHS_ITER it = begin(); it != end(); ++it ) + for( SCH_SHEET_PATHS::const_iterator it = begin(); it != end(); ++it ) { SCH_MULTI_UNIT_REFERENCE_MAP tempMap; (*it).GetMultiUnitComponents( tempMap ); @@ -638,7 +648,14 @@ bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference, bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy, const wxString& aDestFileName ) { - wxFileName rootFn = g_RootSheet->GetFileName(); + if( empty() ) + return false; + + SCHEMATIC* sch = at( 0 ).LastScreen()->Schematic(); + + wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_LIST::TestForRecursion!" ); + + wxFileName rootFn = sch->GetFileName(); wxFileName destFn = aDestFileName; if( destFn.IsRelative() ) @@ -681,8 +698,6 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForScreen( SCH_SCREEN* aScreen ) void SCH_SHEET_LIST::UpdateSymbolInstances( std::vector& aSymbolInstances ) { - wxCHECK( m_isRootSheet, /* void */ ); // Only performed for the entire schematic. - SCH_REFERENCE_LIST symbolInstances; GetComponents( symbolInstances, true, true ); @@ -749,95 +764,3 @@ void SCH_SHEET_LIST::ReplaceLegacySheetPaths( const std::vector& aOld } } } - - -void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) -{ - m_severities = aSeverities; - - m_filteredMarkers.clear(); - - SCH_SHEET_LIST sheetList( g_RootSheet); - - for( unsigned i = 0; i < sheetList.size(); i++ ) - { - for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) - { - SCH_MARKER* marker = static_cast( aItem ); - int markerSeverity; - - if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) - continue; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = GetSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity & m_severities ) - m_filteredMarkers.push_back( marker ); - } - } -} - - -int SHEETLIST_ERC_ITEMS_PROVIDER::GetCount( int aSeverity ) -{ - if( aSeverity < 0 ) - return m_filteredMarkers.size(); - - int count = 0; - - SCH_SHEET_LIST sheetList( g_RootSheet); - - for( unsigned i = 0; i < sheetList.size(); i++ ) - { - for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) - { - SCH_MARKER* marker = static_cast( aItem ); - int markerSeverity; - - if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) - continue; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = GetSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity == aSeverity ) - count++; - } - } - - return count; -} - - -ERC_ITEM* SHEETLIST_ERC_ITEMS_PROVIDER::GetItem( int aIndex ) -{ - SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; - - return marker ? static_cast( marker->GetRCItem() ) : nullptr; -} - - -void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteItem( int aIndex, bool aDeep ) -{ - SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; - m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex ); - - if( aDeep ) - { - SCH_SCREENS ScreenList; - ScreenList.DeleteMarker( marker ); - } -} - - -void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteAllItems() -{ - SCH_SCREENS ScreenList; - ScreenList.DeleteAllMarkers( MARKER_BASE::MARKER_ERC ); - m_filteredMarkers.clear(); -} diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index d3df3bbe4a..3cce4ba6e5 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -270,7 +270,7 @@ public: * @param aIncludePowerSymbols : false to only get normal components. */ void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, - bool aIncludePowerSymbols = true ); + bool aIncludePowerSymbols = true ) const; /** * Function SetFootprintField @@ -333,7 +333,6 @@ typedef SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER; class SCH_SHEET_LIST : public SCH_SHEET_PATHS { private: - bool m_isRootSheet; SCH_SHEET_PATH m_currentSheetPath; public: @@ -360,7 +359,7 @@ public: /** * Fetch a SCH_ITEM by ID. Also returns the sheet the item was found on in \a aPathOut. */ - SCH_ITEM* GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ); + SCH_ITEM* GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut = nullptr ); /** * Fill an item cache for temporary use when many items need to be fetched. @@ -389,7 +388,7 @@ public: * The normal option is false, and set to true only to build the full list of components. */ void GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true, - bool aForceIncludeOrphanComponents = false ); + bool aForceIncludeOrphanComponents = false ) const; /** * Function GetMultiUnitComponents @@ -401,7 +400,7 @@ public: * @param aIncludePowerSymbols Set to false to only get normal components. */ void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, - bool aIncludePowerSymbols = true ); + bool aIncludePowerSymbols = true ) const; /** * Function SetFootprintField @@ -451,7 +450,7 @@ public: /** * Update all of the symbol instance information using \a aSymbolInstances. - * + * WARNING: Do not call this on anything other than the full hierarchy. * @param aSymbolInstances is the symbol path information loaded from the root schematic. */ void UpdateSymbolInstances( std::vector& aSymbolInstances ); @@ -473,33 +472,4 @@ public: void ReplaceLegacySheetPaths( const std::vector& aOldSheetPaths ); }; - -/** - * SHEETLIST_ERC_ITEMS_PROVIDER - * is an implementation of the RC_ITEM_LISTinterface which uses the global SHEETLIST - * to fulfill the contract. - */ -class SHEETLIST_ERC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER -{ -private: - int m_severities; - std::vector m_filteredMarkers; - -public: - SHEETLIST_ERC_ITEMS_PROVIDER() : - m_severities( 0 ) - { } - - void SetSeverities( int aSeverities ) override; - - int GetCount( int aSeverity = -1 ) override; - - ERC_ITEM* GetItem( int aIndex ) override; - - void DeleteItem( int aIndex, bool aDeep ) override; - - void DeleteAllItems() override; -}; - - #endif // CLASS_DRAWSHEET_PATH_H diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 550a40db20..c2145174f0 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -41,6 +41,7 @@ #include // for KiROUND #include #include +#include #include #include #include @@ -474,7 +475,10 @@ wxString SCH_TEXT::GetShownText( int aDepth ) const { if( token->Contains( ':' ) ) { - SCH_SHEET_LIST sheetList( g_RootSheet ); + wxCHECK_MSG( Schematic(), wxEmptyString, + "No parent SCHEMATIC set for SCH_TEXT!" ); + + SCH_SHEET_LIST sheetList = Schematic()->GetSheets(); wxString remainder; wxString ref = token->BeforeFirst( ':', &remainder ); SCH_SHEET_PATH dummy; @@ -511,10 +515,13 @@ wxString SCH_TEXT::GetShownText( int aDepth ) const if( processTextVars ) { - PROJECT* project = nullptr; + wxCHECK_MSG( Schematic(), wxEmptyString, + "No parent SCHEMATIC set for SCH_TEXT!" ); - if( g_RootSheet && g_RootSheet->GetScreen() ) - project = &g_RootSheet->GetScreen()->Kiway().Prj(); + PROJECT* project = nullptr; + + if( Schematic()->RootScreen() ) + project = &Schematic()->RootScreen()->Kiway().Prj(); if( aDepth < 10 ) text = ExpandTextVars( text, &textResolver, project ); @@ -675,8 +682,13 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Size" ), msg, RED ) ); #if defined(DEBUG) - if( auto conn = Connection( *g_CurrentSheet ) ) - conn->AppendDebugInfoToMsgPanel( aList ); + SCH_EDIT_FRAME* schframe = dynamic_cast( aFrame ); + + if( schframe ) + { + if( auto conn = Connection( schframe->GetCurrentSheet() ) ) + conn->AppendDebugInfoToMsgPanel( aList ); + } msg.Printf( "%p", this ); aList.push_back( MSG_PANEL_ITEM( "Object Address", msg, RED ) ); @@ -727,13 +739,17 @@ bool SCH_LABEL::IsType( const KICAD_T aScanTypes[] ) const if( SCH_ITEM::IsType( aScanTypes ) ) return true; + wxCHECK_MSG( Schematic(), false, "No parent SCHEMATIC set for SCH_LABEL!" ); + + SCH_SHEET_PATH current = Schematic()->CurrentSheet(); + for( const KICAD_T* p = aScanTypes; *p != EOT; ++p ) { if( *p == SCH_LABEL_LOCATE_WIRE_T ) { - wxASSERT( m_connected_items.count( *g_CurrentSheet ) ); + wxASSERT( m_connected_items.count( current ) ); - for( SCH_ITEM* connection : m_connected_items.at( *g_CurrentSheet ) ) + for( SCH_ITEM* connection : m_connected_items.at( current ) ) { if( connection->IsType( wireTypes ) ) return true; @@ -741,9 +757,9 @@ bool SCH_LABEL::IsType( const KICAD_T aScanTypes[] ) const } else if ( *p == SCH_LABEL_LOCATE_BUS_T ) { - wxASSERT( m_connected_items.count( *g_CurrentSheet ) ); + wxASSERT( m_connected_items.count( current ) ); - for( SCH_ITEM* connection : m_connected_items.at( *g_CurrentSheet ) ) + for( SCH_ITEM* connection : m_connected_items.at( current ) ) { if( connection->IsType( busTypes ) ) return true; @@ -1097,10 +1113,12 @@ void SCH_HIERLABEL::SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) void SCH_HIERLABEL::Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) { + wxCHECK_RET( Schematic(), "No parent SCHEMATIC set for SCH_LABEL!" ); + static std::vector Poly; wxDC* DC = aSettings->GetPrintDC(); - SCH_CONNECTION* conn = Connection( *g_CurrentSheet ); + SCH_CONNECTION* conn = Connection( Schematic()->CurrentSheet() ); bool isBus = conn && conn->IsBus(); COLOR4D color = aSettings->GetLayerColor( isBus ? LAYER_BUS : m_Layer ); int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() ); diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp new file mode 100644 index 0000000000..c53cdde068 --- /dev/null +++ b/eeschema/schematic.cpp @@ -0,0 +1,203 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 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 + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + + +SCHEMATIC::SCHEMATIC() : + EDA_ITEM( nullptr, SCHEMATIC_T ), + m_rootSheet( nullptr ) +{ + m_currentSheet = new SCH_SHEET_PATH(); + m_connectionGraph = new CONNECTION_GRAPH( this ); + m_ercSettings = new ERC_SETTINGS(); +} + + +SCHEMATIC::~SCHEMATIC() +{ + delete m_currentSheet; + delete m_connectionGraph; + delete m_ercSettings; +} + + +void SCHEMATIC::Reset() +{ + delete m_rootSheet; + + m_rootSheet = nullptr; + + m_connectionGraph->Reset(); + m_currentSheet->clear(); +} + + +SCH_SCREEN* SCHEMATIC::RootScreen() const +{ + return IsValid() ? m_rootSheet->GetScreen() : nullptr; +} + + +wxString SCHEMATIC::GetFileName() const +{ + return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString ); +} + + +std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) const +{ + for( const auto& sheet : GetSheets() ) + { + for( const auto& alias : sheet.LastScreen()->GetBusAliases() ) + { + if( alias->GetName() == aLabel ) + return alias; + } + } + + return nullptr; +} + + +int SCHEMATIC::GetErcSeverity( int aErrorCode ) const +{ + // Special-case pin-to-pin errors: + // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both) + // Warning-or-error is controlled by which errorCode it is + if( aErrorCode == ERCE_PIN_TO_PIN_ERROR ) + { + if( m_ercSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) + return RPT_SEVERITY_IGNORE; + else + return RPT_SEVERITY_ERROR; + } + else if( aErrorCode == ERCE_PIN_TO_PIN_WARNING ) + { + if( m_ercSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) + return RPT_SEVERITY_IGNORE; + else + return RPT_SEVERITY_WARNING; + } + + return m_ercSettings->m_Severities[ aErrorCode ]; +} + + +void SCHEMATIC::SetErcSeverity( int aErrorCode, int aSeverity ) +{ + m_ercSettings->m_Severities[ aErrorCode ] = aSeverity; +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) +{ + m_severities = aSeverities; + + m_filteredMarkers.clear(); + + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); + + for( unsigned i = 0; i < sheetList.size(); i++ ) + { + for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( aItem ); + int markerSeverity; + + if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) + continue; + + if( marker->IsExcluded() ) + markerSeverity = RPT_SEVERITY_EXCLUSION; + else + markerSeverity = m_schematic->GetErcSeverity( marker->GetRCItem()->GetErrorCode() ); + + if( markerSeverity & m_severities ) + m_filteredMarkers.push_back( marker ); + } + } +} + + +int SHEETLIST_ERC_ITEMS_PROVIDER::GetCount( int aSeverity ) +{ + if( aSeverity < 0 ) + return m_filteredMarkers.size(); + + int count = 0; + + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); + + for( unsigned i = 0; i < sheetList.size(); i++ ) + { + for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( aItem ); + int markerSeverity; + + if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) + continue; + + if( marker->IsExcluded() ) + markerSeverity = RPT_SEVERITY_EXCLUSION; + else + markerSeverity = m_schematic->GetErcSeverity( marker->GetRCItem()->GetErrorCode() ); + + if( markerSeverity == aSeverity ) + count++; + } + } + + return count; +} + + +ERC_ITEM* SHEETLIST_ERC_ITEMS_PROVIDER::GetItem( int aIndex ) +{ + SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; + + return marker ? static_cast( marker->GetRCItem() ) : nullptr; +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteItem( int aIndex, bool aDeep ) +{ + SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; + m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex ); + + if( aDeep ) + { + SCH_SCREENS screens( m_schematic->Root() ); + screens.DeleteMarker( marker ); + } +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteAllItems() +{ + SCH_SCREENS screens( m_schematic->Root() ); + screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC ); + m_filteredMarkers.clear(); +} diff --git a/eeschema/schematic.h b/eeschema/schematic.h new file mode 100644 index 0000000000..25d24c7036 --- /dev/null +++ b/eeschema/schematic.h @@ -0,0 +1,179 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 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 + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef KICAD_SCHEMATIC_H +#define KICAD_SCHEMATIC_H + +#include +#include + + +class BUS_ALIAS; +class CONNECTION_GRAPH; +class EDA_BASE_FRAME; +class ERC_SETTINGS; +class SCH_SCREEN; +class SCH_SHEET; + +/** + * Holds all the data relating to one schematic + * A schematic may consist of one or more sheets (and one root sheet) + * Right now, eeschema can have only one schematic open at a time, but this could change. + * Please keep this possibility in mind when adding to this object. + */ +class SCHEMATIC : public EDA_ITEM +{ + friend class SCH_EDIT_FRAME; + +private: + + /// The top-level sheet in this schematic hierarchy (or potentially the only one) + SCH_SHEET* m_rootSheet; + + /** + * The sheet path of the sheet currently being edited or displayed. + * Note that this was moved here from SCH_EDIT_FRAME because currently many places in the code + * want to know the current sheet. Potentially this can be moved back to the UI code once + * the only places that want to know it are UI-related + */ + SCH_SHEET_PATH* m_currentSheet; + + /// Holds and calculates connectivity information of this schematic + CONNECTION_GRAPH* m_connectionGraph; + + /// Holds this schematic's ERC settings + // TODO: This should be moved to project settings, not schematic + ERC_SETTINGS* m_ercSettings; + +public: + SCHEMATIC(); + + ~SCHEMATIC(); + + virtual wxString GetClass() const override + { + return wxT( "SCHEMATIC" ); + } + + /// Initializes this schematic to a blank one, unloading anything existing + void Reset(); + + /** + * Builds and returns an updated schematic hierarchy + * TODO: can this be cached? + * @return a SCH_SHEET_LIST containing the schematic hierarchy + */ + SCH_SHEET_LIST GetSheets() const + { + return SCH_SHEET_LIST( m_rootSheet ); + } + + SCH_SHEET& Root() const + { + return *m_rootSheet; + } + + void SetRoot( SCH_SHEET* aRootSheet ) + { + m_rootSheet = aRootSheet; + } + + /// A simple test if the schematic is loaded, not a complete one + bool IsValid() const + { + return m_rootSheet != nullptr; + } + + /// Helper to retreive the screen of the root sheet + SCH_SCREEN* RootScreen() const; + + /// Helper to retrieve the filename from the root sheet screen + wxString GetFileName() const; + + SCH_SHEET_PATH& CurrentSheet() const + { + return *m_currentSheet; + } + + void SetCurrentSheet( const SCH_SHEET_PATH& aPath ) + { + *m_currentSheet = aPath; + } + + CONNECTION_GRAPH* ConnectionGraph() const + { + return m_connectionGraph; + } + + /** + * Returns a pointer to a bus alias object for the given label, + * or null if one doesn't exist + */ + std::shared_ptr GetBusAlias( const wxString& aLabel ) const; + + ERC_SETTINGS* ErcSettings() const + { + return m_ercSettings; + } + + // TODO(JE) Move out of SCHEMATIC + int GetErcSeverity( int aErrorCode ) const; + + // TODO(JE) Move out of SCHEMATIC + void SetErcSeverity( int aErrorCode, int aSeverity ); + +#if defined(DEBUG) + void Show( int nestLevel, std::ostream& os ) const override {} +#endif + +}; + + +/** + * SHEETLIST_ERC_ITEMS_PROVIDER + * is an implementation of the RC_ITEM_LISTinterface which uses the global SHEETLIST + * to fulfill the contract. + */ +class SHEETLIST_ERC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER +{ +private: + SCHEMATIC* m_schematic; + int m_severities; + std::vector m_filteredMarkers; + +public: + SHEETLIST_ERC_ITEMS_PROVIDER( SCHEMATIC* aSchematic ) : + m_schematic( aSchematic ), + m_severities( 0 ) + { } + + void SetSeverities( int aSeverities ) override; + + int GetCount( int aSeverity = -1 ) override; + + ERC_ITEM* GetItem( int aIndex ) override; + + void DeleteItem( int aIndex, bool aDeep ) override; + + void DeleteAllItems() override; +}; + + + +#endif diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index ce1cfced8e..7aec94736d 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,7 @@ bool SCH_EDIT_FRAME::CheckSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* wxASSERT( aSheet && aHierarchy ); wxString msg; - SCH_SHEET_LIST hierarchy( g_RootSheet ); // This is the full schematic sheet hierarchy. + SCH_SHEET_LIST hierarchy = Schematic().GetSheets(); // The full schematic sheet hierarchy. SCH_SHEET_LIST sheetHierarchy( aSheet ); // This is the hierarchy of the loaded file. wxFileName destFile = aHierarchy->LastScreen()->GetFileName(); @@ -113,7 +114,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier SCH_SCREEN* currentScreen = aHierarchy->LastScreen(); SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( aFileName ); SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( schFileType ) ); - std::unique_ptr< SCH_SHEET> newSheet( new SCH_SHEET ); + std::unique_ptr< SCH_SHEET> newSheet( new SCH_SHEET( &Schematic() ) ); // This will cause the sheet UUID to be set to the loaded schematic UUID. This is required // to ensure all of the sheet paths in any subsheets are correctly generated. @@ -133,12 +134,12 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier { if( aSheet->GetScreen() != nullptr ) { - newSheet.reset( pi->Load( fullFilename, &Kiway() ) ); + newSheet.reset( pi->Load( fullFilename, &Kiway(), &Schematic() ) ); } else { newSheet->SetFileName( fullFilename ); - pi->Load( fullFilename, &Kiway(), newSheet.get() ); + pi->Load( fullFilename, &Kiway(), &Schematic(), newSheet.get() ); } if( !pi->GetError().IsEmpty() ) @@ -209,8 +210,8 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier } // Make sure any new sheet changes do not cause any recursion issues. - SCH_SHEET_LIST hierarchy( g_RootSheet ); // This is the schematic sheet hierarchy. - SCH_SHEET_LIST sheetHierarchy( newSheet.get() ); // This is the hierarchy of the loaded file. + SCH_SHEET_LIST hierarchy = Schematic().GetSheets(); // This is the schematic sheet hierarchy. + SCH_SHEET_LIST sheetHierarchy( newSheet.get() ); // This is the hierarchy of the loaded file. if( CheckSheetForRecursion( newSheet.get(), aHierarchy ) || checkForNoFullyDefinedLibIds( newSheet.get() ) ) @@ -221,7 +222,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier wxArrayString names; wxArrayString newLibNames; SCH_SCREENS newScreens( newSheet.get() ); // All screens associated with the import. - SCH_SCREENS prjScreens( g_RootSheet ); + SCH_SCREENS prjScreens( &Schematic().Root() ); newScreens.GetLibNicknames( names ); @@ -471,7 +472,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier else aSheet->GetScreen()->Append( newScreen ); - SCH_SCREENS allScreens; + SCH_SCREENS allScreens( Schematic().Root() ); allScreens.ReplaceDuplicateTimeStamps(); return true; @@ -628,7 +629,7 @@ void SCH_EDIT_FRAME::DrawCurrentSheetToClipboard() bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ) { wxString msg; - SCH_SCREENS screens; + SCH_SCREENS screens( Schematic().Root() ); wxFileName fn = aSchematicFileName; wxCHECK( fn.IsAbsolute(), false ); diff --git a/eeschema/sim/netlist_exporter_pspice_sim.h b/eeschema/sim/netlist_exporter_pspice_sim.h index 5dc6091de9..e9dd737b5f 100644 --- a/eeschema/sim/netlist_exporter_pspice_sim.h +++ b/eeschema/sim/netlist_exporter_pspice_sim.h @@ -46,8 +46,9 @@ struct SPICE_DC_PARAMS class NETLIST_EXPORTER_PSPICE_SIM : public NETLIST_EXPORTER_PSPICE { public: - NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList, PROJECT* aProject = nullptr ) : - NETLIST_EXPORTER_PSPICE( aMasterList, aProject ) + NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic, + PROJECT* aProject = nullptr ) : + NETLIST_EXPORTER_PSPICE( aMasterList, aSchematic, aProject ) { } diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index 46ef02b5b5..d365844136 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -672,7 +672,8 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName, bool aErase ) void SIM_PLOT_FRAME::updateNetlistExporter() { - m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( m_schematicFrame->BuildNetListBase(), &Prj() ) ); + m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( + m_schematicFrame->BuildNetListBase(), &m_schematicFrame->Schematic(), &Prj() ) ); } diff --git a/eeschema/tools/backanno.cpp b/eeschema/tools/backanno.cpp index 4d80e44f03..c3807a5ab9 100644 --- a/eeschema/tools/backanno.cpp +++ b/eeschema/tools/backanno.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ void SCH_EDITOR_CONTROL::BackAnnotateFootprints( const std::string& aChangedSetO { // Build a flat list of components in schematic: SCH_REFERENCE_LIST refs; - SCH_SHEET_LIST sheets( g_RootSheet ); + SCH_SHEET_LIST sheets = m_frame->Schematic().GetSheets(); bool isChanged = false; sheets.GetComponents( refs, false ); @@ -127,7 +128,7 @@ bool SCH_EDITOR_CONTROL::processCmpToFootprintLinkFile( const wxString& aFullFil { // Build a flat list of components in schematic: SCH_REFERENCE_LIST referencesList; - SCH_SHEET_LIST sheetList( g_RootSheet ); + SCH_SHEET_LIST sheetList = m_frame->Schematic().GetSheets(); sheetList.GetComponents( referencesList, false ); diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index 7a1479db54..78804fbcc9 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -68,7 +69,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist ) int errors = getPcbModulesFromString( aNetlist ); - SCH_SHEET_LIST sheets( g_RootSheet ); + SCH_SHEET_LIST sheets = m_frame->Schematic().GetSheets(); sheets.GetComponents( m_refs, false ); sheets.GetMultiUnitComponents( m_multiUnitsRefs ); diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 9f14bbd7f8..f27d9ce9ec 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -163,12 +164,21 @@ bool EE_SELECTION_TOOL::Init() auto schEditCondition = [this] ( const SELECTION& aSel ) { return !m_isLibEdit && !m_isLibView; }; - auto belowRootSheetCondition = [this] ( const SELECTION& aSel ) { - return !m_isLibEdit && !m_isLibView && g_CurrentSheet->Last() != g_RootSheet; - }; - auto havePartCondition = [ this ] ( const SELECTION& sel ) { - return m_isLibEdit && ( (LIB_EDIT_FRAME*) m_frame )->GetCurPart(); - }; + auto belowRootSheetCondition = + [&]( const SELECTION& aSel ) + { + SCH_EDIT_FRAME* schEditFrame = dynamic_cast( m_frame ); + + return ( schEditFrame&& + schEditFrame->GetCurrentSheet().Last() != + &schEditFrame->Schematic().Root() ); + }; + + auto havePartCondition = + [&]( const SELECTION& sel ) + { + return m_isLibEdit && libEditFrame->GetCurPart(); + }; auto& menu = m_menu.GetMenu(); @@ -315,7 +325,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) // Single click? Select single object if( evt->IsClick( BUT_LEFT ) ) { - m_frame->FocusOnItem( nullptr ); + if( auto schframe = dynamic_cast( m_frame ) ) + schframe->FocusOnItem( nullptr ); SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, false, m_additive, m_subtractive, m_exclusive_or ); @@ -341,7 +352,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) // double click? Display the properties window else if( evt->IsDblClick( BUT_LEFT ) ) { - m_frame->FocusOnItem( nullptr ); + if( auto schframe = dynamic_cast( m_frame ) ) + schframe->FocusOnItem( nullptr ); if( m_selection.Empty() ) SelectPoint( evt->Position()); @@ -357,7 +369,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) // drag with LMB? Select multiple objects (or at least draw a selection box) or drag them else if( evt->IsDrag( BUT_LEFT ) ) { - m_frame->FocusOnItem( nullptr ); + if( auto schframe = dynamic_cast( m_frame ) ) + schframe->FocusOnItem( nullptr ); if( m_additive || m_subtractive || m_exclusive_or || m_frame->GetDragSelects() ) { @@ -412,14 +425,16 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) else if( evt->IsCancelInteractive() ) { - m_frame->FocusOnItem( nullptr ); + if( auto schframe = dynamic_cast( m_frame ) ) + schframe->FocusOnItem( nullptr ); ClearSelection(); } else if( evt->Action() == TA_UNDO_REDO_PRE ) { - m_frame->FocusOnItem( nullptr ); + if( auto schframe = dynamic_cast( m_frame ) ) + schframe->FocusOnItem( nullptr ); ClearSelection(); } @@ -1244,14 +1259,18 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr // represented in the LIB_PART and will inherit the settings of the parent component.) if( itemType == SCH_COMPONENT_T ) { - SCH_PIN_PTRS pins = static_cast( aItem )->GetSchPins( g_CurrentSheet ); - - for( SCH_PIN* pin : pins ) + if( auto schframe = dynamic_cast( m_frame ) ) { - if( aMode == SELECTED ) - pin->SetSelected(); - else if( aMode == BRIGHTENED ) - pin->SetBrightened(); + SCH_PIN_PTRS pins = static_cast( aItem )->GetSchPins( + &schframe->GetCurrentSheet() ); + + for( SCH_PIN* pin : pins ) + { + if( aMode == SELECTED ) + pin->SetSelected(); + else if( aMode == BRIGHTENED ) + pin->SetBrightened(); + } } for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) @@ -1304,14 +1323,18 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a // represented in the LIB_PART.) if( itemType == SCH_COMPONENT_T ) { - SCH_PIN_PTRS pins = static_cast( aItem )->GetSchPins( g_CurrentSheet ); - - for( SCH_PIN* pin : pins ) + if( auto schframe = dynamic_cast( m_frame ) ) { - if( aMode == SELECTED ) - pin->ClearSelected(); - else if( aMode == BRIGHTENED ) - pin->ClearBrightened(); + SCH_PIN_PTRS pins = static_cast( aItem )->GetSchPins( + &schframe->GetCurrentSheet() ); + + for( SCH_PIN* pin : pins ) + { + if( aMode == SELECTED ) + pin->ClearSelected(); + else if( aMode == BRIGHTENED ) + pin->ClearBrightened(); + } } for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) diff --git a/eeschema/tools/lib_control.cpp b/eeschema/tools/lib_control.cpp index 0a0ca19482..69407fd659 100644 --- a/eeschema/tools/lib_control.cpp +++ b/eeschema/tools/lib_control.cpp @@ -442,7 +442,8 @@ int LIB_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent ) wxCHECK( part->GetLibId().IsValid(), 0 ); - SCH_COMPONENT* comp = new SCH_COMPONENT( *part, libId, g_CurrentSheet, unit, convert ); + SCH_COMPONENT* comp = + new SCH_COMPONENT( *part, libId, &schframe->GetCurrentSheet(), unit, convert ); if( schframe->eeconfig()->m_AutoplaceFields.enable ) comp->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index fb03c46a24..54df760162 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -56,9 +57,11 @@ bool SCH_DRAWING_TOOLS::Init() { EE_TOOL_BASE::Init(); - auto belowRootSheetCondition = [] ( const SELECTION& aSel ) { - return g_CurrentSheet->Last() != g_RootSheet; - }; + auto belowRootSheetCondition = + [&]( const SELECTION& aSel ) + { + return m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root(); + }; auto& ctxMenu = m_menu.GetMenu(); ctxMenu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 2 ); @@ -171,7 +174,8 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) if( !part ) continue; - component = new SCH_COMPONENT( *part, g_CurrentSheet, sel, (wxPoint) cursorPos ); + component = new SCH_COMPONENT( + *part, &m_frame->GetCurrentSheet(), sel, (wxPoint) cursorPos ); component->SetFlags( IS_NEW | IS_MOVED ); if( m_frame->eeconfig()->m_AutoplaceFields.enable ) @@ -218,7 +222,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) next_comp = static_cast( component->Duplicate() ); next_comp->SetFlags( IS_NEW | IS_MOVED ); next_comp->SetUnit( new_unit ); - next_comp->SetUnitSelection( g_CurrentSheet, new_unit ); + next_comp->SetUnitSelection( &m_frame->GetCurrentSheet(), new_unit ); if( m_frame->eeconfig()->m_AutoplaceFields.enable ) component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); @@ -838,9 +842,9 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - sheet = new SCH_SHEET( (wxPoint) cursorPos ); + sheet = new SCH_SHEET( + m_frame->GetCurrentSheet().Last(), static_cast( cursorPos ) ); sheet->SetFlags( IS_NEW | IS_RESIZED ); - sheet->SetParent( m_frame->GetCurrentSheet().Last() ); sheet->SetScreen( NULL ); sheet->SetBorderWidth( m_frame->GetDefaultLineWidth() ); sheet->SetBorderColor( cfg->m_Drawing.default_sheet_border_color ); @@ -858,7 +862,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) getViewControls()->SetAutoPan( false ); getViewControls()->CaptureCursor( false ); - if( m_frame->EditSheetProperties((SCH_SHEET*) sheet, g_CurrentSheet, nullptr ) ) + if( m_frame->EditSheetProperties( + static_cast( sheet ), &m_frame->GetCurrentSheet(), nullptr ) ) { sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 661595c559..8e8b57710a 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -770,7 +771,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) // Keep track of existing sheet paths. Duplicating a selection can modify this list bool copiedSheets = false; - SCH_SHEET_LIST initial_sheetpathList( g_RootSheet ); + SCH_SHEET_LIST initial_sheetpathList = m_frame->Schematic().GetSheets(); for( unsigned ii = 0; ii < selection.GetSize(); ++ii ) { @@ -797,12 +798,12 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) case SCH_SHEET_T: { - SCH_SHEET_LIST hierarchy( g_RootSheet ); - SCH_SHEET* sheet = (SCH_SHEET*) newItem; - SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME]; - wxString baseName = nameField.GetText(); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets(); + SCH_SHEET* sheet = (SCH_SHEET*) newItem; + SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME]; + wxString baseName = nameField.GetText(); wxString candidateName = baseName; - int uniquifier = 1; + int uniquifier = 1; while( hierarchy.NameExists( candidateName ) ) candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ ); @@ -834,7 +835,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) { // We clear annotation of new sheet paths. // Annotation of new components added in current sheet is already cleared. - SCH_SCREENS screensList( g_RootSheet ); + SCH_SCREENS screensList( &m_frame->Schematic().Root() ); screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList ); m_frame->SetSheetNumberAndCount(); } @@ -1113,7 +1114,7 @@ void SCH_EDIT_TOOL::editFieldText( SCH_FIELD* aField ) if( dlg.ShowQuasiModal() != wxID_OK ) return; - dlg.UpdateField( aField, g_CurrentSheet ); + dlg.UpdateField( aField, &m_frame->GetCurrentSheet() ); if( m_frame->eeconfig()->m_AutoplaceFields.enable || aField->GetParent()->Type() == SCH_SHEET_T ) static_cast( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() ); @@ -1304,22 +1305,23 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) bool doClearAnnotation; bool doRefresh = false; // Keep track of existing sheet paths. EditSheet() can modify this list - SCH_SHEET_LIST initial_sheetpathList( g_RootSheet ); + SCH_SHEET_LIST initial_sheetpathList = m_frame->Schematic().GetSheets(); - doRefresh = m_frame->EditSheetProperties( sheet, g_CurrentSheet, &doClearAnnotation ); + doRefresh = m_frame->EditSheetProperties( + sheet, &m_frame->GetCurrentSheet(), &doClearAnnotation ); // If the sheet file is changed and new sheet contents are loaded then we have to // clear the annotations on the new content (as it may have been set from some other // sheet path reference) if( doClearAnnotation ) { - SCH_SCREENS screensList( g_RootSheet ); + SCH_SCREENS screensList( &m_frame->Schematic().Root() ); // We clear annotation of new sheet paths here: screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList ); // Clear annotation of g_CurrentSheet itself, because its sheetpath is not a new // path, but components managed by its sheet path must have their annotation // cleared, because they are new: - sheet->GetScreen()->ClearAnnotation( g_CurrentSheet ); + sheet->GetScreen()->ClearAnnotation( &m_frame->GetCurrentSheet() ); } if( doRefresh ) diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 9f1aa667fb..2054e7cc4f 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +116,7 @@ int SCH_EDITOR_CONTROL::PageSetup( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::RescueSymbols( const TOOL_EVENT& aEvent ) { - SCH_SCREENS schematic; + SCH_SCREENS schematic( m_frame->Schematic().Root() ); if( schematic.HasNoFullyDefinedLibIds() ) RescueLegacyProject( true ); @@ -128,7 +129,7 @@ int SCH_EDITOR_CONTROL::RescueSymbols( const TOOL_EVENT& aEvent ) bool SCH_EDITOR_CONTROL::RescueLegacyProject( bool aRunningOnDemand ) { - LEGACY_RESCUER rescuer( m_frame->Prj(), &m_frame->GetCurrentSheet(), + LEGACY_RESCUER rescuer( m_frame->Prj(), &m_frame->Schematic(), &m_frame->GetCurrentSheet(), m_frame->GetCanvas()->GetBackend() ); return rescueProject( rescuer, aRunningOnDemand ); @@ -137,7 +138,8 @@ bool SCH_EDITOR_CONTROL::RescueLegacyProject( bool aRunningOnDemand ) bool SCH_EDITOR_CONTROL::RescueSymbolLibTableProject( bool aRunningOnDemand ) { - SYMBOL_LIB_TABLE_RESCUER rescuer( m_frame->Prj(), &m_frame->GetCurrentSheet(), + SYMBOL_LIB_TABLE_RESCUER rescuer( m_frame->Prj(), &m_frame->Schematic(), + &m_frame->GetCurrentSheet(), m_frame->GetCanvas()->GetBackend() ); return rescueProject( rescuer, aRunningOnDemand ); @@ -158,10 +160,9 @@ bool SCH_EDITOR_CONTROL::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand if( aRunningOnDemand ) { - SCH_SCREENS schematic; + SCH_SCREENS schematic( m_frame->Schematic().Root() ); schematic.UpdateSymbolLinks(); - g_ConnectionGraph->Reset(); m_frame->RecalculateConnections( GLOBAL_CLEANUP ); } @@ -191,7 +192,7 @@ int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent ) { InvokeDialogPrintUsingPrinter( m_frame ); - wxFileName fn = m_frame->Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->Schematic().RootScreen()->GetFileName() ); if( fn.GetName() != NAMELESS_PROJECT ) m_frame->SaveProjectSettings(); @@ -409,8 +410,8 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent ) if( !item && searchAllSheets ) { - SCH_SHEET_LIST schematic( g_RootSheet ); - SCH_SCREENS screens; + SCH_SHEET_LIST schematic = m_frame->Schematic().GetSheets(); + SCH_SCREENS screens( m_frame->Schematic().Root() ); for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { @@ -429,8 +430,8 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent ) SCH_SHEET_PATH* sheet = schematic.FindSheetForScreen( screen ); wxCHECK_MSG( sheet, 0, "Sheet not found for " + screen->GetFileName() ); - *g_CurrentSheet = *sheet; - g_CurrentSheet->UpdateAllScreenReferences(); + m_frame->Schematic().SetCurrentSheet( *sheet ); + m_frame->GetCurrentSheet().UpdateAllScreenReferences(); screen->SetZoom( m_frame->GetScreen()->GetZoom() ); screen->TestDanglingEnds(); @@ -481,7 +482,7 @@ int SCH_EDITOR_CONTROL::ReplaceAndFindNext( const TOOL_EVENT& aEvent ) if( item && item->Matches( *data, nullptr ) ) { - if( item->Replace( *data, g_CurrentSheet ) ) + if( item->Replace( *data, &m_frame->GetCurrentSheet() ) ) { m_frame->RefreshItem( item ); m_frame->OnModify(); @@ -501,8 +502,8 @@ int SCH_EDITOR_CONTROL::ReplaceAll( const TOOL_EVENT& aEvent ) if( !data ) return FindAndReplace( ACTIONS::find.MakeEvent() ); - SCH_SHEET_LIST schematic( g_RootSheet ); - SCH_SCREENS screens; + SCH_SHEET_LIST schematic = m_frame->Schematic().GetSheets(); + SCH_SCREENS screens( m_frame->Schematic().Root() ); for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { @@ -663,7 +664,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent ) else param = wxString::Format( wxT( "I%s" ), pin->GetName().Lower() ); - simFrame->AddCurrentPlot( comp->GetRef( g_CurrentSheet ), param ); + simFrame->AddCurrentPlot( comp->GetRef( &m_frame->GetCurrentSheet() ), param ); } return true; @@ -687,8 +688,8 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent ) { item = nullptr; - if( wire->Connection( *g_CurrentSheet ) ) - netName = wire->Connection( *g_CurrentSheet )->Name(); + if( wire->Connection( m_frame->GetCurrentSheet() ) ) + netName = wire->Connection( m_frame->GetCurrentSheet() )->Name(); } if( item && item->Type() == SCH_PIN_T ) @@ -828,7 +829,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) if( aPosition != CLEAR ) { - if( TestDuplicateSheetNames( false ) > 0 ) + if( TestDuplicateSheetNames( &editFrame->Schematic(), false ) > 0 ) { wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet." ) ); retVal = false; @@ -848,8 +849,8 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() ) netName = comp->GetPartRef()->GetName(); - else if( item && item->Connection( *g_CurrentSheet ) ) - netName = item->Connection( *g_CurrentSheet )->Name(); + else if( item && item->Connection( editFrame->GetCurrentSheet() ) ) + netName = item->Connection( editFrame->GetCurrentSheet() )->Name(); } } @@ -894,7 +895,7 @@ int SCH_EDITOR_CONTROL::ClearHighlight( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent ) { - SCH_SCREEN* screen = g_CurrentSheet->LastScreen(); + SCH_SCREEN* screen = m_frame->GetCurrentSheet().LastScreen(); std::vector itemsToRedraw; wxString selectedNetName = m_frame->GetSelectedNetName(); @@ -916,7 +917,7 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent ) } else { - SCH_CONNECTION* connection = item->Connection( *g_CurrentSheet ); + SCH_CONNECTION* connection = item->Connection( m_frame->GetCurrentSheet() ); if( connection ) itemConnectionName = connection->Name(); @@ -939,7 +940,8 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent ) for( LIB_PIN* pin : pins ) { - SCH_CONNECTION* pin_conn = comp->GetConnectionForPin( pin, *g_CurrentSheet ); + SCH_CONNECTION* pin_conn = + comp->GetConnectionForPin( pin, m_frame->GetCurrentSheet() ); if( comp && pin_conn && pin_conn->Name( false ) == selectedNetName ) { @@ -965,7 +967,7 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent ) { for( SCH_SHEET_PIN* pin : static_cast( item )->GetPins() ) { - SCH_CONNECTION* pin_conn = pin->Connection( *g_CurrentSheet ); + SCH_CONNECTION* pin_conn = pin->Connection( m_frame->GetCurrentSheet() ); bool redrawPin = pin->IsBrightened(); if( pin_conn && pin_conn->Name() == selectedNetName ) @@ -1214,10 +1216,11 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // SCH_SEXP_PLUGIN added the items to the paste screen, but not to the view or anything // else. Pull them back out to start with. // - EDA_ITEMS loadedItems; - bool sheetsPasted = false; - SCH_SHEET_LIST hierarchy( g_RootSheet ); - wxFileName destFn = g_CurrentSheet->Last()->GetFileName(); + EDA_ITEMS loadedItems; + bool sheetsPasted = false; + SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets(); + SCH_SHEET_PATH& currentSheet = m_frame->GetCurrentSheet(); + wxFileName destFn = currentSheet.Last()->GetFileName(); if( destFn.IsRelative() ) destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() ); @@ -1304,31 +1307,32 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) if( item->Type() == SCH_SHEET_T ) { - SCH_SHEET* sheet = (SCH_SHEET*) item; - SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME]; - wxFileName fn = sheet->GetFileName(); - SCH_SCREEN* existingScreen = nullptr; - bool dropSheetAnnotations = false; - wxString baseName = nameField.GetText(); - wxString candidateName = baseName; - int uniquifier = 1; + SCH_SHEET* sheet = (SCH_SHEET*) item; + SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME]; + wxFileName fn = sheet->GetFileName(); + SCH_SCREEN* existingScreen = nullptr; + bool dropSheetAnnotations = false; + wxString baseName = nameField.GetText(); + wxString candidateName = baseName; + int uniquifier = 1; while( hierarchy.NameExists( candidateName ) ) candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ ); nameField.SetText( candidateName ); - sheet->SetParent( g_CurrentSheet->Last() ); + sheet->SetParent( currentSheet.Last() ); sheet->SetScreen( nullptr ); sheetsPasted = true; if( !fn.IsAbsolute() ) { - wxFileName currentSheetFileName = g_CurrentSheet->LastScreen()->GetFileName(); + wxFileName currentSheetFileName = currentSheet.LastScreen()->GetFileName(); fn.Normalize( wxPATH_NORM_ALL, currentSheetFileName.GetPath() ); } - if( g_RootSheet->SearchHierarchy( fn.GetFullPath( wxPATH_UNIX ), &existingScreen ) ) + if( m_frame->Schematic().Root().SearchHierarchy( + fn.GetFullPath( wxPATH_UNIX ), &existingScreen ) ) dropSheetAnnotations = !forceKeepAnnotations; else searchSupplementaryClipboard( sheet->GetFileName(), &existingScreen ); @@ -1337,7 +1341,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) { sheet->SetScreen( existingScreen ); - SCH_SHEET_PATH sheetpath = *g_CurrentSheet; + SCH_SHEET_PATH sheetpath = currentSheet; sheetpath.push_back( sheet ); // Clear annotation and create the AR for this path, if not exists, @@ -1351,7 +1355,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) } else { - if( !m_frame->LoadSheetFromFile( sheet, g_CurrentSheet, fn.GetFullPath() ) ) + if( !m_frame->LoadSheetFromFile( sheet, ¤tSheet, fn.GetFullPath() ) ) m_frame->InitSheet( sheet, sheet->GetFileName() ); } } @@ -1517,7 +1521,7 @@ int SCH_EDITOR_CONTROL::EnterSheet( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( ACTIONS::cancelInteractive, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - g_CurrentSheet->push_back( sheet ); + m_frame->GetCurrentSheet().push_back( sheet ); m_frame->DisplayCurrentSheet(); m_frame->UpdateHierarchyNavigator(); } @@ -1528,12 +1532,12 @@ int SCH_EDITOR_CONTROL::EnterSheet( const TOOL_EVENT& aEvent ) int SCH_EDITOR_CONTROL::LeaveSheet( const TOOL_EVENT& aEvent ) { - if( g_CurrentSheet->Last() != g_RootSheet ) + if( m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root() ) { m_toolMgr->RunAction( ACTIONS::cancelInteractive, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - g_CurrentSheet->pop_back(); + m_frame->GetCurrentSheet().pop_back(); m_frame->DisplayCurrentSheet(); m_frame->UpdateHierarchyNavigator(); } diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index ef0ced3eb1..593876db2d 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #include #include @@ -131,7 +132,7 @@ private: return; } - SCH_CONNECTION* connection = bus->Connection( *g_CurrentSheet ); + SCH_CONNECTION* connection = bus->Connection( frame->GetCurrentSheet() ); if( !connection || !connection->IsBus() || connection->Members().empty() ) { @@ -203,9 +204,11 @@ bool SCH_LINE_WIRE_BUS_TOOL::Init() return ( m_frame->IsCurrentTool( EE_ACTIONS::drawLines ) ); }; - auto belowRootSheetCondition = [] ( const SELECTION& aSel ) { - return g_CurrentSheet->Last() != g_RootSheet; - }; + auto belowRootSheetCondition = + [&]( const SELECTION& aSel ) + { + return m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root(); + }; auto busSelection = EE_CONDITIONS::MoreThan( 0 ) && EE_CONDITIONS::OnlyType( SCH_LINE_LOCATE_BUS_T ); diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index 4d73369814..92136adaba 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -159,6 +159,8 @@ enum KICAD_T // General SCH_SCREEN_T, + SCHEMATIC_T, + /* * Draw items in library component. * diff --git a/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp b/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp index 1b3d46eca4..4473cb0b13 100644 --- a/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp +++ b/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp @@ -39,7 +39,8 @@ class TEST_NETLIST_EXPORTER_PSPICE_SIM { public: TEST_NETLIST_EXPORTER_PSPICE_SIM() - : m_netlist( new NETLIST_OBJECT_LIST ), m_exporter( m_netlist ) + : m_netlist( new NETLIST_OBJECT_LIST ), + m_exporter( m_netlist, nullptr ) { } diff --git a/qa/eeschema/test_sch_sheet.cpp b/qa/eeschema/test_sch_sheet.cpp index b6fadcd497..8c5bd7bde0 100644 --- a/qa/eeschema/test_sch_sheet.cpp +++ b/qa/eeschema/test_sch_sheet.cpp @@ -30,6 +30,7 @@ // Code under test #include +#include #include "uuid_test_utils.h" @@ -42,6 +43,9 @@ public: { } + ///> Dummy schematic to attach the test sheet to + SCHEMATIC m_schematic; + SCH_SHEET m_sheet; ///> Can use when you need a const ref (lots of places need fixing here) @@ -73,8 +77,7 @@ BOOST_AUTO_TEST_CASE( Default ) { BOOST_CHECK_EQUAL( m_csheet.GetPosition(), wxPoint( 0, 0 ) ); - // it is it's own root sheet - BOOST_CHECK_EQUAL( m_sheet.GetRootSheet(), &m_sheet ); + BOOST_CHECK_EQUAL( m_sheet.GetParent(), nullptr ); BOOST_CHECK_EQUAL( m_sheet.CountSheets(), 1 ); BOOST_CHECK_EQUAL( m_csheet.GetScreenCount(), 0 ); @@ -82,6 +85,20 @@ BOOST_AUTO_TEST_CASE( Default ) BOOST_CHECK_EQUAL( m_sheet.ComponentCount(), 0 ); } +/** + * Test setting parent schematic + */ +BOOST_AUTO_TEST_CASE( SchematicParent ) +{ + m_sheet.SetParent( &m_schematic ); + + BOOST_CHECK_EQUAL( m_sheet.IsRootSheet(), false ); + + m_schematic.SetRoot( &m_sheet ); + + BOOST_CHECK_EQUAL( m_sheet.IsRootSheet(), true ); +} + /** * Test adding pins to a sheet */ diff --git a/qa/eeschema/test_sch_sheet_path.cpp b/qa/eeschema/test_sch_sheet_path.cpp index dbfd8ac6b4..006e1ee566 100644 --- a/qa/eeschema/test_sch_sheet_path.cpp +++ b/qa/eeschema/test_sch_sheet_path.cpp @@ -44,7 +44,7 @@ public: { for( unsigned i = 0; i < 4; ++i ) { - m_sheets.emplace_back( wxPoint( i, i ) ); + m_sheets.emplace_back( nullptr, wxPoint( i, i ) ); std::ostringstream ss; ss << "Sheet" << i;