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 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 
30 
32  EDA_ITEM( nullptr, SCHEMATIC_T ),
33  m_project( nullptr ),
34  m_rootSheet( nullptr )
35 {
37  m_connectionGraph = new CONNECTION_GRAPH( this );
38 
39  SetProject( aPrj );
40 }
41 
42 
44 {
45  delete m_currentSheet;
46  delete m_connectionGraph;
47 }
48 
49 
51 {
52  // Assume project already saved
53  if( m_project )
54  {
56 
57  delete project.m_ErcSettings;
58  delete project.m_SchematicSettings;
59 
60  project.m_ErcSettings = nullptr;
61  project.m_SchematicSettings = nullptr;
62  }
63 
64  delete m_rootSheet;
65 
66  m_rootSheet = nullptr;
67 
70 }
71 
72 
74 {
75  if( m_project )
76  {
78 
79  delete project.m_ErcSettings;
80  delete project.m_SchematicSettings;
81 
82  project.m_ErcSettings = nullptr;
83  project.m_SchematicSettings = nullptr;
84  }
85 
86  m_project = aPrj;
87 
88  if( m_project )
89  {
91  project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" );
92  project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" );
93 
95  project.m_ErcSettings->LoadFromFile();
96  }
97 }
98 
99 
100 void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
101 {
102  wxCHECK_RET( aRootSheet, "Call to SetRoot with null SCH_SHEET!" );
103 
104  m_rootSheet = aRootSheet;
105 
108 
110 }
111 
112 
114 {
115  return IsValid() ? m_rootSheet->GetScreen() : nullptr;
116 }
117 
118 
119 wxString SCHEMATIC::GetFileName() const
120 {
121  return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString );
122 }
123 
124 
126 {
127  wxASSERT( m_project );
129 }
130 
131 
133 {
134  wxASSERT( m_project );
136 }
137 
138 
139 std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
140 {
141  SCH_SHEET_LIST sheetList = GetSheets();
142  ERC_SETTINGS& settings = ErcSettings();
143 
144  for( const SCH_SHEET_PATH& sheet : sheetList )
145  {
146  for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_MARKER_T ) )
147  {
148  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
149  auto it = ErcSettings().m_ErcExclusions.find( marker->Serialize() );
150 
151  if( it != ErcSettings().m_ErcExclusions.end() )
152  {
153  marker->SetExcluded( true );
154  settings.m_ErcExclusions.erase( it );
155  }
156  }
157  }
158 
159  std::vector<SCH_MARKER*> newMarkers;
160 
161  for( const wxString& exclusionData : settings.m_ErcExclusions )
162  {
163  SCH_MARKER* marker = SCH_MARKER::Deserialize( exclusionData );
164 
165  if( marker )
166  {
167  marker->SetExcluded( true );
168  newMarkers.push_back( marker );
169  }
170  }
171 
172  settings.m_ErcExclusions.clear();
173 
174  return newMarkers;
175 }
176 
177 
178 std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
179 {
180  for( const auto& sheet : GetSheets() )
181  {
182  for( const auto& alias : sheet.LastScreen()->GetBusAliases() )
183  {
184  if( alias->GetName() == aLabel )
185  return alias;
186  }
187  }
188 
189  return nullptr;
190 }
191 
192 
194 {
195  std::vector<wxString> names;
196 
197  // Key is a NET_NAME_CODE aka std::pair<name, code>
198  for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() )
199  {
200  CONNECTION_SUBGRAPH* subgraph = pair.second[0];
201 
203  names.emplace_back( pair.first.first );
204  }
205 
206  return names;
207 }
208 
209 
210 bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
211 {
212  SCH_SHEET_LIST sheetList = GetSheets();
213  wxString remainder;
214  wxString ref = token->BeforeFirst( ':', &remainder );
216  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &dummy );
217 
218  if( refItem && refItem->Type() == SCH_COMPONENT_T )
219  {
220  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
221 
222  if( refComponent->ResolveTextVar( &remainder, aDepth + 1 ) )
223  {
224  *token = remainder;
225  return true;
226  }
227  }
228  else if( refItem && refItem->Type() == SCH_SHEET_T )
229  {
230  SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
231 
232  if( refSheet->ResolveTextVar( &remainder, aDepth + 1 ) )
233  {
234  *token = remainder;
235  return true;
236  }
237  }
238 
239  return false;
240 }
241 
242 
243 wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
244 {
245  wxString newbuf;
246  size_t sourceLen = aSource.length();
247 
248  for( size_t i = 0; i < sourceLen; ++i )
249  {
250  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
251  {
252  wxString token;
253  bool isCrossRef = false;
254 
255  for( i = i + 2; i < sourceLen; ++i )
256  {
257  if( aSource[i] == '}' )
258  break;
259 
260  if( aSource[i] == ':' )
261  isCrossRef = true;
262 
263  token.append( aSource[i] );
264  }
265 
266  if( isCrossRef )
267  {
268  SCH_SHEET_LIST sheetList = GetSheets();
269  wxString remainder;
270  wxString ref = token.BeforeFirst( ':', &remainder );
271  SCH_REFERENCE_LIST references;
272 
273  sheetList.GetSymbols( references );
274 
275  for( size_t jj = 0; jj < references.GetCount(); jj++ )
276  {
277  SCH_COMPONENT* refSymbol = references[ jj ].GetSymbol();
278 
279  if( ref == refSymbol->GetRef( &references[ jj ].GetSheetPath(), true ) )
280  {
281  wxString test( remainder );
282 
283  if( refSymbol->ResolveTextVar( &test ) )
284  token = refSymbol->m_Uuid.AsString() + ":" + remainder;
285 
286  break;
287  }
288  }
289  }
290 
291  newbuf.append( "${" + token + "}" );
292  }
293  else
294  {
295  newbuf.append( aSource[i] );
296  }
297  }
298 
299  return newbuf;
300 }
301 
302 
303 wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
304 {
305  wxString newbuf;
306  size_t sourceLen = aSource.length();
307 
308  for( size_t i = 0; i < sourceLen; ++i )
309  {
310  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
311  {
312  wxString token;
313  bool isCrossRef = false;
314 
315  for( i = i + 2; i < sourceLen; ++i )
316  {
317  if( aSource[i] == '}' )
318  break;
319 
320  if( aSource[i] == ':' )
321  isCrossRef = true;
322 
323  token.append( aSource[i] );
324  }
325 
326  if( isCrossRef )
327  {
328  SCH_SHEET_LIST sheetList = GetSheets();
329  wxString remainder;
330  wxString ref = token.BeforeFirst( ':', &remainder );
331 
332  SCH_SHEET_PATH refSheetPath;
333  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &refSheetPath );
334 
335  if( refItem && refItem->Type() == SCH_COMPONENT_T )
336  {
337  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
338  token = refComponent->GetRef( &refSheetPath, true ) + ":" + remainder;
339  }
340  }
341 
342  newbuf.append( "${" + token + "}" );
343  }
344  else
345  {
346  newbuf.append( aSource[i] );
347  }
348  }
349 
350  return newbuf;
351 }
352 
353 
355 {
356  static SCH_SHEET_LIST hierarchy;
357 
358  hierarchy.clear();
359  hierarchy.BuildSheetList( m_rootSheet, false );
360 
361  return hierarchy;
362 }
std::vector< SCH_MARKER * > ResolveERCExclusions()
Definition: schematic.cpp:139
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
const wxString & GetFileName() const
Definition: sch_screen.h:186
PROJECT holds project specific data.
Definition: project.h:63
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Add a SCH_REFERENCE object to aReferences for each component in the list of sheets.
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr)
Fetch a SCH_ITEM by ID.
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
Definition: schematic.h:60
SCHEMATIC(PROJECT *aPrj)
Definition: schematic.cpp:31
Calculates the connectivity of a schematic and generates netlists.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:125
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:116
wxString AsString() const
Definition: kiid.cpp:174
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:119
CONNECTION_GRAPH * m_connectionGraph
Holds and calculates connectivity information of this schematic.
Definition: schematic.h:63
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:284
bool LoadFromFile(const wxString &aDirectory="") override
Loads the JSON document from the parent and then calls Load()
A subgraph is a set of items that are electrically connected on a single sheet.
PROJECT_FILE is the backing store for a PROJECT, in JSON format.
Definition: project_file.h:62
std::set< wxString > m_ErcExclusions
Definition: erc_settings.h:158
SCH_REFERENCE_LIST is used to create a flattened list of symbols because in a complex hierarchy,...
void SetRoot(SCH_SHEET *aRootSheet)
Initializes the schematic with a new root sheet.
Definition: schematic.cpp:100
Definition: kiid.h:44
void SetExcluded(bool aExcluded)
Definition: marker_base.h:110
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel) const
Returns a pointer to a bus alias object for the given label, or null if one doesn't exist.
Definition: schematic.cpp:178
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:243
VTBL_ENTRY PROJECT_FILE & GetProjectFile() const
Definition: project.h:143
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:210
PROJECT * m_project
Definition: schematic.h:49
ERC_SETTINGS * m_ErcSettings
Eeschema params.
Definition: project_file.h:135
SCHEMATIC_SETTINGS * m_SchematicSettings
Definition: project_file.h:138
Container for ERC settings.
Definition: erc_settings.h:97
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:73
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:52
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:219
const KIID m_Uuid
Definition: eda_item.h:151
unsigned GetCount() const
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:303
void Reset()
Initializes this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:50
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Schematic symbol object.
Definition: sch_component.h:79
EDA_ITEM is a base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:148
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:204
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:132
SCH_SCREEN * RootScreen() const
Helper to retreive the screen of the root sheet.
Definition: schematic.cpp:113
std::vector< wxString > GetNetClassAssignmentCandidates()
Returns a list of name candidates for netclass assignment.
Definition: schematic.cpp:193
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:194
SCH_SHEET_LIST & GetFullHierarchy() const
Return the full schematic flattened hiearchical sheet list.
Definition: schematic.cpp:354
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.