KiCad PCB EDA Suite
schematic.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 (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <bus_alias.h>
21 #include <connection_graph.h>
22 #include <erc_settings.h>
23 #include <sch_marker.h>
24 #include <project.h>
25 #include <project/project_file.h>
26 #include <project/net_settings.h>
27 #include <schematic.h>
28 #include <sch_screen.h>
29 #include <sim/spice_settings.h>
30 
31 
33  EDA_ITEM( nullptr, SCHEMATIC_T ),
34  m_project( nullptr ),
35  m_rootSheet( nullptr )
36 {
38  m_connectionGraph = new CONNECTION_GRAPH( this );
39 
40  SetProject( aPrj );
41 }
42 
43 
45 {
46  delete m_currentSheet;
47  delete m_connectionGraph;
48 }
49 
50 
52 {
53  // Assume project already saved
54  if( m_project )
55  {
57 
58  delete project.m_ErcSettings;
59  delete project.m_SchematicSettings;
60 
61  project.m_ErcSettings = nullptr;
62  project.m_SchematicSettings = nullptr;
63  }
64 
65  delete m_rootSheet;
66 
67  m_rootSheet = nullptr;
68 
71 }
72 
73 
75 {
76  if( m_project )
77  {
79 
80  delete project.m_ErcSettings;
81  delete project.m_SchematicSettings;
82 
83  project.m_ErcSettings = nullptr;
84  project.m_SchematicSettings = nullptr;
85  }
86 
87  m_project = aPrj;
88 
89  if( m_project )
90  {
92  project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" );
93  project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" );
94 
95  project.m_SchematicSettings->LoadFromFile();
96  project.m_SchematicSettings->m_NgspiceSimulatorSettings->LoadFromFile();
97  project.m_ErcSettings->LoadFromFile();
98  }
99 }
100 
101 
102 void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
103 {
104  wxCHECK_RET( aRootSheet, "Call to SetRoot with null SCH_SHEET!" );
105 
106  m_rootSheet = aRootSheet;
107 
110 
112 }
113 
114 
116 {
117  return IsValid() ? m_rootSheet->GetScreen() : nullptr;
118 }
119 
120 
121 wxString SCHEMATIC::GetFileName() const
122 {
123  return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString );
124 }
125 
126 
128 {
129  wxASSERT( m_project );
131 }
132 
133 
135 {
136  wxASSERT( m_project );
138 }
139 
140 
141 std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
142 {
143  SCH_SHEET_LIST sheetList = GetSheets();
144  ERC_SETTINGS& settings = ErcSettings();
145 
146  for( const SCH_SHEET_PATH& sheet : sheetList )
147  {
148  for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_MARKER_T ) )
149  {
150  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
151  auto it = settings.m_ErcExclusions.find( marker->Serialize() );
152 
153  if( it != settings.m_ErcExclusions.end() )
154  {
155  marker->SetExcluded( true );
156  settings.m_ErcExclusions.erase( it );
157  }
158  }
159  }
160 
161  std::vector<SCH_MARKER*> newMarkers;
162 
163  for( const wxString& exclusionData : settings.m_ErcExclusions )
164  {
165  SCH_MARKER* marker = SCH_MARKER::Deserialize( exclusionData );
166 
167  if( marker )
168  {
169  marker->SetExcluded( true );
170  newMarkers.push_back( marker );
171  }
172  }
173 
174  settings.m_ErcExclusions.clear();
175 
176  return newMarkers;
177 }
178 
179 
180 std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
181 {
182  for( const auto& sheet : GetSheets() )
183  {
184  for( const auto& alias : sheet.LastScreen()->GetBusAliases() )
185  {
186  if( alias->GetName() == aLabel )
187  return alias;
188  }
189  }
190 
191  return nullptr;
192 }
193 
194 
196 {
197  std::vector<wxString> names;
198 
199  // Key is a NET_NAME_CODE aka std::pair<name, code>
200  for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() )
201  {
202  CONNECTION_SUBGRAPH* subgraph = pair.second[0];
203 
205  names.emplace_back( pair.first.first );
206  }
207 
208  return names;
209 }
210 
211 
212 bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
213 {
214  SCH_SHEET_LIST sheetList = GetSheets();
215  wxString remainder;
216  wxString ref = token->BeforeFirst( ':', &remainder );
218  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &dummy );
219 
220  if( refItem && refItem->Type() == SCH_COMPONENT_T )
221  {
222  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
223 
224  if( refComponent->ResolveTextVar( &remainder, aDepth + 1 ) )
225  {
226  *token = remainder;
227  return true;
228  }
229  }
230  else if( refItem && refItem->Type() == SCH_SHEET_T )
231  {
232  SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
233 
234  if( refSheet->ResolveTextVar( &remainder, aDepth + 1 ) )
235  {
236  *token = remainder;
237  return true;
238  }
239  }
240 
241  return false;
242 }
243 
244 
245 wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
246 {
247  wxString newbuf;
248  size_t sourceLen = aSource.length();
249 
250  for( size_t i = 0; i < sourceLen; ++i )
251  {
252  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
253  {
254  wxString token;
255  bool isCrossRef = false;
256 
257  for( i = i + 2; i < sourceLen; ++i )
258  {
259  if( aSource[i] == '}' )
260  break;
261 
262  if( aSource[i] == ':' )
263  isCrossRef = true;
264 
265  token.append( aSource[i] );
266  }
267 
268  if( isCrossRef )
269  {
270  SCH_SHEET_LIST sheetList = GetSheets();
271  wxString remainder;
272  wxString ref = token.BeforeFirst( ':', &remainder );
273  SCH_REFERENCE_LIST references;
274 
275  sheetList.GetSymbols( references );
276 
277  for( size_t jj = 0; jj < references.GetCount(); jj++ )
278  {
279  SCH_COMPONENT* refSymbol = references[ jj ].GetSymbol();
280 
281  if( ref == refSymbol->GetRef( &references[ jj ].GetSheetPath(), true ) )
282  {
283  wxString test( remainder );
284 
285  if( refSymbol->ResolveTextVar( &test ) )
286  token = refSymbol->m_Uuid.AsString() + ":" + remainder;
287 
288  break;
289  }
290  }
291  }
292 
293  newbuf.append( "${" + token + "}" );
294  }
295  else
296  {
297  newbuf.append( aSource[i] );
298  }
299  }
300 
301  return newbuf;
302 }
303 
304 
305 wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
306 {
307  wxString newbuf;
308  size_t sourceLen = aSource.length();
309 
310  for( size_t i = 0; i < sourceLen; ++i )
311  {
312  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
313  {
314  wxString token;
315  bool isCrossRef = false;
316 
317  for( i = i + 2; i < sourceLen; ++i )
318  {
319  if( aSource[i] == '}' )
320  break;
321 
322  if( aSource[i] == ':' )
323  isCrossRef = true;
324 
325  token.append( aSource[i] );
326  }
327 
328  if( isCrossRef )
329  {
330  SCH_SHEET_LIST sheetList = GetSheets();
331  wxString remainder;
332  wxString ref = token.BeforeFirst( ':', &remainder );
333 
334  SCH_SHEET_PATH refSheetPath;
335  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &refSheetPath );
336 
337  if( refItem && refItem->Type() == SCH_COMPONENT_T )
338  {
339  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
340  token = refComponent->GetRef( &refSheetPath, true ) + ":" + remainder;
341  }
342  }
343 
344  newbuf.append( "${" + token + "}" );
345  }
346  else
347  {
348  newbuf.append( aSource[i] );
349  }
350  }
351 
352  return newbuf;
353 }
354 
355 
357 {
358  static SCH_SHEET_LIST hierarchy;
359 
360  hierarchy.clear();
361  hierarchy.BuildSheetList( m_rootSheet, false );
362  hierarchy.SortByPageNumbers();
363 
364  return hierarchy;
365 }
std::vector< SCH_MARKER * > ResolveERCExclusions()
Definition: schematic.cpp:141
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
virtual ~SCHEMATIC()
Definition: schematic.cpp:44
const wxString & GetFileName() const
Definition: sch_screen.h:133
Container for project specific data.
Definition: project.h:62
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
Definition: sch_symbol.cpp:960
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
Definition: schematic.h:189
SCHEMATIC(PROJECT *aPrj)
Definition: schematic.cpp:32
Calculates the connectivity of a schematic and generates netlists.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:145
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:127
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Returns the priority (higher is more important) of a candidate driver.
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:108
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
wxString AsString() const
Definition: kiid.cpp:218
CONNECTION_GRAPH * m_connectionGraph
Holds and calculates connectivity information of this schematic.
Definition: schematic.h:192
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
A subgraph is a set of items that are electrically connected on a single sheet.
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:64
std::set< wxString > m_ErcExclusions
Definition: erc_settings.h:166
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:102
Definition: kiid.h:44
void SetExcluded(bool aExcluded)
Definition: marker_base.h:95
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel) const
Return a pointer to a bus alias object for the given label, or null if one doesn't exist.
Definition: schematic.cpp:180
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:245
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
const NET_MAP & GetNetMap() const
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:212
PROJECT * m_project
Definition: schematic.h:178
ERC_SETTINGS * m_ErcSettings
Eeschema params.
Definition: project_file.h:137
SCHEMATIC_SETTINGS * m_SchematicSettings
Definition: project_file.h:140
wxString GetFileName() const override
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:121
Container for ERC settings.
Definition: erc_settings.h:105
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
wxString Serialize() const
Definition: sch_marker.cpp:66
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:74
void clear()
Forwarded method from std::vector.
SCH_SHEET * m_rootSheet
The top-level sheet in this schematic hierarchy (or potentially the only one)
Definition: schematic.h:181
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
const KIID m_Uuid
Definition: eda_item.h:525
unsigned GetCount() const
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:305
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:51
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
Schematic symbol object.
Definition: sch_symbol.h:78
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
These settings were stored in SCH_BASE_FRAME previously.
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:210
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:134
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:115
std::vector< wxString > GetNetClassAssignmentCandidates()
Return a list of name candidates for netclass assignment.
Definition: schematic.cpp:195
static SCH_MARKER * Deserialize(const wxString &data)
Definition: sch_marker.cpp:77
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
SCH_SHEET_LIST & GetFullHierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:356
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:432