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;