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 <project.h>
24 #include <project/project_file.h>
25 #include <project/net_settings.h>
26 #include <schematic.h>
27 #include <sch_screen.h>
28 
29 
31  EDA_ITEM( nullptr, SCHEMATIC_T ),
32  m_project( nullptr ),
33  m_rootSheet( nullptr )
34 {
36  m_connectionGraph = new CONNECTION_GRAPH( this );
37 
38  SetProject( aPrj );
39 }
40 
41 
43 {
44  delete m_currentSheet;
45  delete m_connectionGraph;
46 }
47 
48 
50 {
51  // Assume project already saved
52  if( m_project )
53  {
55 
56  delete project.m_ErcSettings;
57  delete project.m_SchematicSettings;
58 
59  project.m_ErcSettings = nullptr;
60  project.m_SchematicSettings = nullptr;
61  }
62 
63  delete m_rootSheet;
64 
65  m_rootSheet = nullptr;
66 
69 }
70 
71 
73 {
74  if( m_project )
75  {
77 
78  delete project.m_ErcSettings;
79  delete project.m_SchematicSettings;
80 
81  project.m_ErcSettings = nullptr;
82  project.m_SchematicSettings = nullptr;
83  }
84 
85  m_project = aPrj;
86 
87  if( m_project )
88  {
90  project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" );
91  project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" );
92 
94  project.m_ErcSettings->LoadFromFile();
95  }
96 }
97 
98 
99 void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
100 {
101  wxCHECK_RET( aRootSheet, "Call to SetRoot with null SCH_SHEET!" );
102 
103  m_rootSheet = aRootSheet;
104 
107 
109 }
110 
111 
113 {
114  return IsValid() ? m_rootSheet->GetScreen() : nullptr;
115 }
116 
117 
118 wxString SCHEMATIC::GetFileName() const
119 {
120  return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString );
121 }
122 
123 
125 {
126  wxASSERT( m_project );
128 }
129 
130 
132 {
133  wxASSERT( m_project );
135 }
136 
137 
138 std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
139 {
140  for( const auto& sheet : GetSheets() )
141  {
142  for( const auto& alias : sheet.LastScreen()->GetBusAliases() )
143  {
144  if( alias->GetName() == aLabel )
145  return alias;
146  }
147  }
148 
149  return nullptr;
150 }
151 
152 
154 {
155  std::vector<wxString> names;
156 
157  // Key is a NET_NAME_CODE aka std::pair<name, code>
158  for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() )
159  names.emplace_back( pair.first.first );
160 
161  return names;
162 }
163 
164 
165 bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
166 {
167  SCH_SHEET_LIST sheetList = GetSheets();
168  wxString remainder;
169  wxString ref = token->BeforeFirst( ':', &remainder );
171  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &dummy );
172 
173  if( refItem && refItem->Type() == SCH_COMPONENT_T )
174  {
175  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
176 
177  if( refComponent->ResolveTextVar( &remainder, aDepth + 1 ) )
178  {
179  *token = remainder;
180  return true;
181  }
182  }
183  else if( refItem && refItem->Type() == SCH_SHEET_T )
184  {
185  SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
186 
187  if( refSheet->ResolveTextVar( &remainder, aDepth + 1 ) )
188  {
189  *token = remainder;
190  return true;
191  }
192  }
193 
194  return false;
195 }
196 
197 
198 wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
199 {
200  wxString newbuf;
201  size_t sourceLen = aSource.length();
202 
203  for( size_t i = 0; i < sourceLen; ++i )
204  {
205  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
206  {
207  wxString token;
208  bool isCrossRef = false;
209 
210  for( i = i + 2; i < sourceLen; ++i )
211  {
212  if( aSource[i] == '}' )
213  break;
214 
215  if( aSource[i] == ':' )
216  isCrossRef = true;
217 
218  token.append( aSource[i] );
219  }
220 
221  if( isCrossRef )
222  {
223  SCH_SHEET_LIST sheetList = GetSheets();
224  wxString remainder;
225  wxString ref = token.BeforeFirst( ':', &remainder );
226  SCH_REFERENCE_LIST references;
227 
228  sheetList.GetComponents( references );
229 
230  for( size_t jj = 0; jj < references.GetCount(); jj++ )
231  {
232  SCH_COMPONENT* refComponent = references[ jj ].GetComp();
233 
234  if( ref == refComponent->GetRef( &references[ jj ].GetSheetPath(), true ) )
235  {
236  wxString test( remainder );
237 
238  if( refComponent->ResolveTextVar( &test ) )
239  token = refComponent->m_Uuid.AsString() + ":" + remainder;
240 
241  break;
242  }
243  }
244  }
245 
246  newbuf.append( "${" + token + "}" );
247  }
248  else
249  {
250  newbuf.append( aSource[i] );
251  }
252  }
253 
254  return newbuf;
255 }
256 
257 
258 wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
259 {
260  wxString newbuf;
261  size_t sourceLen = aSource.length();
262 
263  for( size_t i = 0; i < sourceLen; ++i )
264  {
265  if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
266  {
267  wxString token;
268  bool isCrossRef = false;
269 
270  for( i = i + 2; i < sourceLen; ++i )
271  {
272  if( aSource[i] == '}' )
273  break;
274 
275  if( aSource[i] == ':' )
276  isCrossRef = true;
277 
278  token.append( aSource[i] );
279  }
280 
281  if( isCrossRef )
282  {
283  SCH_SHEET_LIST sheetList = GetSheets();
284  wxString remainder;
285  wxString ref = token.BeforeFirst( ':', &remainder );
286 
287  SCH_SHEET_PATH refSheetPath;
288  SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &refSheetPath );
289 
290  if( refItem && refItem->Type() == SCH_COMPONENT_T )
291  {
292  SCH_COMPONENT* refComponent = static_cast<SCH_COMPONENT*>( refItem );
293  token = refComponent->GetRef( &refSheetPath, true ) + ":" + remainder;
294  }
295  }
296 
297  newbuf.append( "${" + token + "}" );
298  }
299  else
300  {
301  newbuf.append( aSource[i] );
302  }
303  }
304 
305  return newbuf;
306 }
307 
308 
SCH_SHEET_LIST.
const wxString & GetFileName() const
Definition: sch_screen.h:185
PROJECT holds project specific data.
Definition: project.h:61
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:89
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:58
SCHEMATIC(PROJECT *aPrj)
Definition: schematic.cpp:30
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:124
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:108
wxString AsString() const
Definition: common.cpp:165
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:118
CONNECTION_GRAPH * m_connectionGraph
Holds and calculates connectivity information of this schematic.
Definition: schematic.h:61
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
bool LoadFromFile(const wxString &aDirectory="") override
Loads the JSON document from the parent and then calls Load()
PROJECT_FILE is the backing store for a PROJECT, in JSON format.
Definition: project_file.h:62
SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy,...
void SetRoot(SCH_SHEET *aRootSheet)
Initializes the schematic with a new root sheet.
Definition: schematic.cpp:99
Definition: common.h:68
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:138
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:198
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the list of...
VTBL_ENTRY PROJECT_FILE & GetProjectFile() const
Definition: project.h:141
const NET_MAP & GetNetMap() const
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:165
PROJECT * m_project
Definition: schematic.h:47
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:88
SCH_SHEET_PATH.
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:72
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:50
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
const KIID m_Uuid
Definition: base_struct.h:162
unsigned GetCount() const
Function GetCount.
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:258
void Reset()
Initializes this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:49
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:80
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
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:203
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:131
SCH_SCREEN * RootScreen() const
Helper to retreive the screen of the root sheet.
Definition: schematic.cpp:112
std::vector< wxString > GetNetClassAssignmentCandidates()
Returns a list of name candidates for netclass assignment.
Definition: schematic.cpp:153
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.