KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema_helpers.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "eeschema_helpers.h"
25
26#include <connection_graph.h>
27#include <locale_io.h>
28#include <schematic.h>
29#include <sch_commit.h>
30#include <sch_edit_frame.h>
31#include <sch_label.h>
32#include <sch_io/sch_io.h>
33#include <sch_io/sch_io_mgr.h>
36#include <tool/tool_manager.h>
37#include <kiface_base.h>
38
39#include <wx/app.h>
40
41
44
45
47{
48 s_SchEditFrame = aSchEditFrame;
49}
50
51
53{
55 {
56 if( s_SchEditFrame )
57 {
58 s_SettingsManager = s_SchEditFrame->GetSettingsManager();
59 }
60 else
61 {
63 }
64 }
65
66 return s_SettingsManager;
67}
68
69
71{
72 // For some reasons, LoadProject() needs a C locale, so ensure we have the right locale
73 // This is mainly when running QA Python tests
75
77
78 if( !project )
79 {
80 GetSettingsManager()->LoadProject( "", aSetActive );
82 }
83
84 return project;
85}
86
87
88SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName, bool aSetActive,
89 bool aForceDefaultProject, PROJECT* aProject, bool aCalculateConnectivity )
90{
91 if( aFileName.EndsWith( FILEEXT::KiCadSchematicFileExtension ) )
92 return LoadSchematic( aFileName, SCH_IO_MGR::SCH_KICAD, aSetActive, aForceDefaultProject,
93 aProject, aCalculateConnectivity );
94 else if( aFileName.EndsWith( FILEEXT::LegacySchematicFileExtension ) )
95 return LoadSchematic( aFileName, SCH_IO_MGR::SCH_LEGACY, aSetActive, aForceDefaultProject,
96 aProject, aCalculateConnectivity );
97
98 // as fall back for any other kind use the legacy format
99 return LoadSchematic( aFileName, SCH_IO_MGR::SCH_LEGACY, aSetActive, aForceDefaultProject, aProject,
100 aCalculateConnectivity );
101}
102
103
104SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName,
105 SCH_IO_MGR::SCH_FILE_T aFormat,
106 bool aSetActive,
107 bool aForceDefaultProject,
108 PROJECT* aProject,
109 bool aCalculateConnectivity )
110{
111 wxFileName pro = aFileName;
112 pro.SetExt( FILEEXT::ProjectFileExtension );
113 pro.MakeAbsolute();
114 wxString projectPath = pro.GetFullPath();
115
116 // Ensure the "C" locale is temporary set, before reading any file
117 // It also avoid wxWidget alerts about locale issues, later, when using Python 3
119
120 PROJECT* project = aProject;
121
122 if( !project )
123 {
124 project = GetSettingsManager()->GetProject( projectPath );
125 }
126
127 if( !aForceDefaultProject )
128 {
129 if( !project )
130 {
131 if( wxFileExists( projectPath ) )
132 {
133 GetSettingsManager()->LoadProject( projectPath, aSetActive );
134 project = GetSettingsManager()->GetProject( projectPath );
135 }
136 }
137 else if( s_SchEditFrame && project == &GetSettingsManager()->Prj() )
138 {
139 // Project is already loaded? Then so is the board
140 return &s_SchEditFrame->Schematic();
141 }
142 }
143
144 // Board cannot be loaded without a project, so create the default project
145 if( !project || aForceDefaultProject )
146 project = GetDefaultProject( aSetActive );
147
148 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( aFormat ) );
149
150 SCHEMATIC* schematic = new SCHEMATIC( project );
151
152 SCH_SHEET* rootSheet = new SCH_SHEET( schematic );
153 schematic->SetRoot( rootSheet );
154
155 SCH_SCREEN* rootScreen = new SCH_SCREEN( schematic );
156 const_cast<KIID&>( rootSheet->m_Uuid ) = rootScreen->GetUuid();
157 rootSheet->SetScreen( rootScreen ); // Set screen on the top-level sheet, not virtual root
158
159 schematic->RootScreen()->SetFileName( wxEmptyString );
160
161 // Don't leave root page number empty
162 schematic->RootScreen()->SetPageNumber( wxT( "1" ) );
163
164 wxFileName schFile = aFileName;
165 schFile.MakeAbsolute();
166
167 try
168 {
169 schematic->SetRoot( pi->LoadSchematicFile( schFile.GetFullPath(), schematic ) );
170 }
171 catch( ... )
172 {
173 return nullptr;
174 }
175
176 SCH_SHEET_LIST sheetList = schematic->BuildSheetListSortedByPageNumbers();
177 SCH_SCREENS screens( schematic->Root() );
178
179 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
180 screen->UpdateLocalLibSymbolLinks();
181
182 if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
183 sheetList.UpdateSymbolInstanceData( schematic->RootScreen()->GetSymbolInstances());
184
185 sheetList.UpdateSheetInstanceData( schematic->RootScreen()->GetSheetInstances());
186
187 if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
189
190 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
191 screen->MigrateSimModels();
192
193 sheetList.AnnotatePowerSymbols();
194
195 schematic->ConnectionGraph()->Reset();
196
197 TOOL_MANAGER* toolManager = new TOOL_MANAGER;
198 toolManager->SetEnvironment( schematic, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
199
200 if( aCalculateConnectivity )
201 {
202 SCH_COMMIT dummyCommit( toolManager );
203 schematic->RecalculateConnections( &dummyCommit, GLOBAL_CLEANUP, toolManager );
204 }
205
207
208 schematic->SetSheetNumberAndCount();
209 schematic->RecomputeIntersheetRefs();
210
211 for( SCH_SHEET_PATH& sheet : sheetList )
212 {
213 sheet.UpdateAllScreenReferences();
214 sheet.LastScreen()->TestDanglingEnds( nullptr, nullptr );
215 }
216
217 if( aCalculateConnectivity )
218 schematic->ConnectionGraph()->Recalculate( sheetList, true );
219
220 return schematic;
221}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
void SetPageNumber(const wxString &aPageNumber)
Definition base_screen.h:79
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
const KIID m_Uuid
Definition eda_item.h:516
static SETTINGS_MANAGER * s_SettingsManager
static void SetSchEditFrame(SCH_EDIT_FRAME *aSchEditFrame)
static SETTINGS_MANAGER * GetSettingsManager()
static SCH_EDIT_FRAME * s_SchEditFrame
static SCHEMATIC * LoadSchematic(const wxString &aFileName, bool aSetActive, bool aForceDefaultProject, PROJECT *aProject=nullptr, bool aCalculateConnectivity=true)
static PROJECT * GetDefaultProject(bool aSetActive)
Definition kiid.h:49
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
Container for project specific data.
Definition project.h:66
Holds all the data relating to one schematic.
Definition schematic.h:88
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
CONNECTION_GRAPH * ConnectionGraph() const
Definition schematic.h:198
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
SCH_SHEET & Root() const
Definition schematic.h:125
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, TOOL_MANAGER *aToolManager, PROGRESS_REPORTER *aProgressReporter=nullptr, KIGFX::SCH_VIEW *aSchView=nullptr, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PICKED_ITEMS_LIST *aLastChangeList=nullptr)
Generate the connection data for the entire schematic hierarchy.
Schematic editor (Eeschema) main window.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition sch_screen.h:728
SCH_SCREEN * GetNext()
void FixLegacyPowerSymbolMismatches()
Fix legacy power symbols that have mismatched value text fields and invisible power pin names.
SCH_SCREEN * GetFirst()
const KIID & GetUuid() const
Definition sch_screen.h:520
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
const std::vector< SCH_SYMBOL_INSTANCE > & GetSymbolInstances() const
Definition sch_screen.h:510
int GetFileFormatVersionAtLoad() const
Definition sch_screen.h:137
const std::vector< SCH_SHEET_INSTANCE > & GetSheetInstances() const
Definition sch_screen.h:515
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void UpdateSheetInstanceData(const std::vector< SCH_SHEET_INSTANCE > &aSheetInstances)
Update all of the sheet instance information using aSheetInstances.
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
void UpdateSymbolInstanceData(const std::vector< SCH_SYMBOL_INSTANCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:47
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT * GetProject(const wxString &aFullPath) const
Retrieve a loaded project by name.
Master controller class:
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
static const std::string LegacySchematicFileExtension
static const std::string ProjectFileExtension
static const std::string KiCadSchematicFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
PROJECT & Prj()
Definition kicad.cpp:623
PROJECT * GetDefaultProject()
@ GLOBAL_CLEANUP
Definition schematic.h:77
std::vector< FAB_LAYER_COLOR > dummy
Definition of file extensions used in Kicad.