KiCad PCB EDA Suite
Loading...
Searching...
No Matches
backannotate.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) 2019 Alexander Shuklin <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25
26#include <backannotate.h>
27#include <boost/property_tree/ptree.hpp>
28#include <confirm.h>
29#include <dsnlexer.h>
30#include <ptree.h>
31#include <reporter.h>
32#include <sch_edit_frame.h>
33#include <sch_sheet_path.h>
34#include <sch_label.h>
35#include <schematic.h>
36#include <sch_commit.h>
37#include <string_utils.h>
38#include <kiface_base.h>
40#include <connection_graph.h>
41#include <wx/log.h>
42
43
44BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints,
45 bool aProcessFootprints, bool aProcessValues,
46 bool aProcessReferences, bool aProcessNetNames,
47 bool aProcessAttributes, bool aProcessOtherFields,
48 bool aDryRun ) :
49 m_reporter( aReporter ),
50 m_matchByReference( aRelinkFootprints ),
51 m_processFootprints( aProcessFootprints ),
52 m_processValues( aProcessValues ),
53 m_processReferences( aProcessReferences ),
54 m_processNetNames( aProcessNetNames ),
55 m_processAttributes( aProcessAttributes ),
56 m_processOtherFields( aProcessOtherFields ),
57 m_dryRun( aDryRun ),
58 m_frame( aFrame ),
60{
61}
62
63
67
68
69bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
70{
72
75 {
76 m_reporter.ReportTail( _( "Select at least one property to back annotate." ),
78 return false;
79 }
80
81 getPcbModulesFromString( aNetlist );
82
83 SCH_SHEET_LIST sheets = m_frame->Schematic().Hierarchy();
84 sheets.GetSymbols( m_refs, false );
86
89
91
92 return true;
93}
94
95
96bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
97{
98 if( Kiface().IsSingle() )
99 {
100 DisplayErrorMessage( m_frame, _( "Cannot fetch PCB netlist because Schematic Editor is opened "
101 "in stand-alone mode.\n"
102 "You must launch the KiCad project manager and create "
103 "a project." ) );
104 return false;
105 }
106
107 KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, false );
108
109 if( !frame )
110 {
111 wxFileName fn( m_frame->Prj().GetProjectFullName() );
112 fn.SetExt( FILEEXT::PcbFileExtension );
113
114 frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, true );
115 frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
116 }
117
118 m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist );
119 return true;
120}
121
122
124{
125 std::string nullPayload;
126
127 m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_UPDATE_LINKS, nullPayload );
128}
129
130
131void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
132{
133 auto getStr = []( const PTREE& pt ) -> wxString
134 {
135 return UTF8( pt.front().first );
136 };
137
138 DSNLEXER lexer( aPayload, From_UTF8( __func__ ) );
139 PTREE doc;
140
141 // NOTE: KiCad's PTREE scanner constructs a property *name* tree, not a property tree.
142 // Every token in the s-expr is stored as a property name; the property's value is then
143 // either the nested s-exprs or an empty PTREE; there are *no* literal property values.
144
145 Scan( &doc, &lexer );
146
147 PTREE& tree = doc.get_child( "pcb_netlist" );
148 wxString msg;
149 m_pcbFootprints.clear();
150
151 for( const std::pair<const std::string, PTREE>& item : tree )
152 {
153 wxString path, value, footprint;
154 bool dnp = false, exBOM = false;
155 std::map<wxString, wxString> pinNetMap, fieldsMap;
156 wxASSERT( item.first == "ref" );
157 wxString ref = getStr( item.second );
158
159 try
160 {
162 path = ref;
163 else
164 path = getStr( item.second.get_child( "timestamp" ) );
165
166 if( path == "" )
167 {
168 msg.Printf( _( "Footprint '%s' has no assigned symbol." ), ref );
169 m_reporter.ReportHead( msg, RPT_SEVERITY_WARNING );
170 continue;
171 }
172
173 footprint = getStr( item.second.get_child( "fpid" ) );
174 value = getStr( item.second.get_child( "value" ) );
175
176 // Get child PTREE of fields
177 boost::optional<const PTREE&> fields = item.second.get_child_optional( "fields" );
178
179 // Parse each field out of the fields string
180 if( fields )
181 {
182 for( const std::pair<const std::string, PTREE>& field : fields.get() )
183 {
184 if( field.first != "field" )
185 continue;
186
187 // Fields are of the format "(field (name "name") "12345")
188 const auto& fieldName = field.second.get_child_optional( "name" );
189 const std::string& fieldValue = field.second.back().first;
190
191 if( !fieldName )
192 continue;
193
194 fieldsMap[getStr( fieldName.get() )] = wxString::FromUTF8( fieldValue );
195 }
196 }
197
198
199 // Get DNP and Exclude from BOM out of the properties if they exist
200 for( const auto& child : item.second )
201 {
202 if( child.first != "property" )
203 continue;
204
205 auto property = child.second;
206 auto name = property.get_child_optional( "name" );
207
208 if( !name )
209 continue;
210
211 if( name.get().front().first == "dnp" )
212 {
213 dnp = true;
214 }
215 else if( name.get().front().first == "exclude_from_bom" )
216 {
217 exBOM = true;
218 }
219 }
220
221 boost::optional<const PTREE&> nets = item.second.get_child_optional( "nets" );
222
223 if( nets )
224 {
225 for( const std::pair<const std::string, PTREE>& pin_net : nets.get() )
226 {
227 wxASSERT( pin_net.first == "pin_net" );
228 wxString pinNumber = UTF8( pin_net.second.front().first );
229 wxString netName = UTF8( pin_net.second.back().first );
230 pinNetMap[ pinNumber ] = netName;
231 }
232 }
233 }
234 catch( ... )
235 {
236 wxLogWarning( "Cannot parse PCB netlist for back-annotation." );
237 }
238
239 // Use lower_bound for not to iterate over map twice
240 auto nearestItem = m_pcbFootprints.lower_bound( path );
241
242 if( nearestItem != m_pcbFootprints.end() && nearestItem->first == path )
243 {
244 // Module with this path already exists - generate error
245 msg.Printf( _( "Footprints '%s' and '%s' linked to same symbol." ),
246 nearestItem->second->m_ref,
247 ref );
248 m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
249 }
250 else
251 {
252 // Add footprint to the map
253 auto data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
254 pinNetMap, fieldsMap );
255 m_pcbFootprints.insert( nearestItem, std::make_pair( path, data ) );
256 }
257 }
258}
259
260
262{
263 for( std::pair<const wxString, std::shared_ptr<PCB_FP_DATA>>& fpData : m_pcbFootprints )
264 {
265 const wxString& pcbPath = fpData.first;
266 auto& pcbData = fpData.second;
267 int refIndex;
268 bool foundInMultiunit = false;
269
270 for( std::pair<const wxString, SCH_REFERENCE_LIST>& item : m_multiUnitsRefs )
271 {
272 SCH_REFERENCE_LIST& refList = item.second;
273
275 refIndex = refList.FindRef( pcbPath );
276 else
277 refIndex = refList.FindRefByFullPath( pcbPath );
278
279 if( refIndex >= 0 )
280 {
281 // If footprint linked to multi unit symbol, we add all symbol's units to
282 // the change list
283 foundInMultiunit = true;
284
285 for( size_t i = 0; i < refList.GetCount(); ++i )
286 {
287 refList[ i ].GetSymbol()->ClearFlags(SKIP_STRUCT );
288 m_changelist.emplace_back( CHANGELIST_ITEM( refList[i], pcbData ) );
289 }
290
291 break;
292 }
293 }
294
295 if( foundInMultiunit )
296 continue;
297
299 refIndex = m_refs.FindRef( pcbPath );
300 else
301 refIndex = m_refs.FindRefByFullPath( pcbPath );
302
303 if( refIndex >= 0 )
304 {
305 m_refs[ refIndex ].GetSymbol()->ClearFlags( SKIP_STRUCT );
306 m_changelist.emplace_back( CHANGELIST_ITEM( m_refs[refIndex], pcbData ) );
307 }
308 else
309 {
310 // Haven't found linked symbol in multiunits or common refs. Generate error
311 wxString msg = wxString::Format( _( "Cannot find symbol for footprint '%s'." ),
312 pcbData->m_ref );
313 m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
314 }
315 }
316}
317
319{
320 m_refs.SortByTimeStamp();
321
322 std::sort( m_changelist.begin(), m_changelist.end(),
323 []( const CHANGELIST_ITEM& a, const CHANGELIST_ITEM& b )
324 {
325 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
326 } );
327
328 size_t i = 0;
329
330 for( const std::pair<SCH_REFERENCE, std::shared_ptr<PCB_FP_DATA>>& item : m_changelist )
331 {
332 // Refs and changelist are both sorted by paths, so we just go over m_refs and
333 // generate errors before we will find m_refs member to which item linked
334 while( i < m_refs.GetCount() && m_refs[i].GetPath() != item.first.GetPath() )
335 {
336 const SCH_REFERENCE& ref = m_refs[i];
337
338 if( ref.GetSymbol()->GetExcludedFromBoard() )
339 {
340 wxString msg = wxString::Format( _( "Footprint '%s' is not present on PCB. "
341 "Corresponding symbols in schematic must be "
342 "manually deleted (if desired)." ),
343 m_refs[i].GetRef() );
344 m_reporter.ReportTail( msg, RPT_SEVERITY_WARNING );
345 }
346
347 ++i;
348 }
349
350 ++i;
351 }
352
353 if( m_matchByReference && !m_frame->ReadyToNetlist( _( "Re-linking footprints requires a fully "
354 "annotated schematic." ) ) )
355 {
356 m_reporter.ReportTail( _( "Footprint re-linking canceled by user." ), RPT_SEVERITY_ERROR );
357 }
358}
359
360
362{
363 SCH_COMMIT commit( m_frame );
364 wxString msg;
365
366 // Apply changes from change list
367 for( CHANGELIST_ITEM& item : m_changelist )
368 {
369 SCH_REFERENCE& ref = item.first;
370 PCB_FP_DATA& fpData = *item.second;
371 SCH_SYMBOL* symbol = ref.GetSymbol();
372 SCH_SCREEN* screen = ref.GetSheetPath().LastScreen();
373 wxString oldFootprint = ref.GetFootprint();
374 wxString oldValue = ref.GetValue();
375 bool oldDNP = ref.GetSymbol()->GetDNP();
376 bool oldExBOM = ref.GetSymbol()->GetExcludedFromBOM();
377 bool skip = ( ref.GetSymbol()->GetFlags() & SKIP_STRUCT ) > 0;
378
379 auto boolString =
380 []( bool b ) -> wxString
381 {
382 return b ? _( "true" ) : _( "false" );
383 };
384 if( !m_dryRun )
385 commit.Modify( symbol, screen, RECURSE_MODE::NO_RECURSE );
386
387 if( m_processReferences && ref.GetRef() != fpData.m_ref && !skip
388 && !symbol->GetField( FIELD_T::REFERENCE )->HasTextVars() )
389 {
391 msg.Printf( _( "Change %s reference designator to '%s'." ),
392 ref.GetRef(),
393 fpData.m_ref );
394
395 if( !m_dryRun )
396 symbol->SetRef( &ref.GetSheetPath(), fpData.m_ref );
397
398 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
399 }
400
401 if( m_processFootprints && oldFootprint != fpData.m_footprint && !skip
402 && !symbol->GetField( FIELD_T::FOOTPRINT )->HasTextVars() )
403 {
405 msg.Printf( _( "Change %s footprint assignment from '%s' to '%s'." ),
406 ref.GetRef(),
407 EscapeHTML( oldFootprint ),
408 EscapeHTML( fpData.m_footprint ) );
409
410 if( !m_dryRun )
411 symbol->SetFootprintFieldText( fpData.m_footprint );
412
413 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
414 }
415
416 if( m_processValues && oldValue != fpData.m_value && !skip
417 && !symbol->GetField( FIELD_T::VALUE )->HasTextVars() )
418 {
420 msg.Printf( _( "Change %s value from '%s' to '%s'." ),
421 ref.GetRef(),
422 EscapeHTML( oldValue ),
423 EscapeHTML( fpData.m_value ) );
424
425 if( !m_dryRun )
426 symbol->SetValueFieldText( fpData.m_value );
427
428 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
429 }
430
431 if( m_processAttributes && oldDNP != fpData.m_DNP && !skip )
432 {
434 msg.Printf( _( "Change %s 'Do not populate' from '%s' to '%s'." ),
435 ref.GetRef(),
436 boolString( oldDNP ),
437 boolString( fpData.m_DNP ) );
438
439 if( !m_dryRun )
440 symbol->SetDNP( fpData.m_DNP );
441
442 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
443 }
444
445 if( m_processAttributes && oldExBOM != fpData.m_excludeFromBOM && !skip )
446 {
448 msg.Printf( _( "Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
449 ref.GetRef(),
450 boolString( oldExBOM ),
451 boolString( fpData.m_excludeFromBOM ) );
452
453 if( !m_dryRun )
454 symbol->SetExcludedFromBOM( fpData.m_excludeFromBOM );
455
456 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
457 }
458
460 {
461 for( const std::pair<const wxString, wxString>& entry : fpData.m_pinMap )
462 {
463 const wxString& pinNumber = entry.first;
464 const wxString& shortNetName = entry.second;
465 SCH_PIN* pin = symbol->GetPin( pinNumber );
466
467 if( !pin )
468 {
469 msg.Printf( _( "Cannot find %s pin '%s'." ),
470 ref.GetRef(),
471 EscapeHTML( pinNumber ) );
472 m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
473
474 continue;
475 }
476
477 SCH_CONNECTION* connection = pin->Connection( &ref.GetSheetPath() );
478
479 if( connection && connection->Name( true ) != shortNetName )
480 {
481 processNetNameChange( &commit, ref.GetRef(), pin, connection,
482 connection->Name( true ), shortNetName );
483 }
484 }
485 }
486
488 {
489 // Need to handle three cases: existing field, new field, deleted field
490 for( const std::pair<const wxString, wxString>& field : fpData.m_fieldsMap )
491 {
492 const wxString& fpFieldName = field.first;
493 const wxString& fpFieldValue = field.second;
494 SCH_FIELD* symField = symbol->GetField( fpFieldName );
495
496 // Skip fields that are individually controlled
497 if( fpFieldName == GetCanonicalFieldName( FIELD_T::REFERENCE )
498 || fpFieldName == GetCanonicalFieldName( FIELD_T::VALUE ) )
499 {
500 continue;
501 }
502
503 // 1. Existing fields has changed value
504 // PCB Field value is checked against the shown text because this is the value
505 // with all the variables resolved. The footprints field value gets the symbol's
506 // resolved value when the PCB is updated from the schematic.
507 if( symField
508 && !symField->HasTextVars()
509 && symField->GetShownText( &ref.GetSheetPath(), false ) != fpFieldValue )
510 {
512 msg.Printf( _( "Change %s field '%s' value to '%s'." ),
513 ref.GetRef(),
514 EscapeHTML( symField->GetCanonicalName() ),
515 EscapeHTML( fpFieldValue ) );
516
517 if( !m_dryRun )
518 symField->SetText( fpFieldValue );
519
520 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
521 }
522
523 // 2. New field has been added to footprint and needs to be added to symbol
524 if( symField == nullptr )
525 {
527 msg.Printf( _( "Add %s field '%s' with value '%s'." ),
528 ref.GetRef(),
529 EscapeHTML( fpFieldName ),
530 EscapeHTML( fpFieldValue ) );
531
532 if( !m_dryRun )
533 {
534 SCH_FIELD newField( symbol, FIELD_T::USER, fpFieldName );
535 newField.SetText( fpFieldValue );
536 newField.SetTextPos( symbol->GetPosition() );
537 newField.SetVisible( false ); // Don't clutter up the schematic
538 symbol->AddField( newField );
539 }
540
541 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
542 }
543 }
544
545 // 3. Existing field has been deleted from footprint and needs to be deleted from symbol
546 // Check all symbol fields for existence in the footprint field map
547 for( SCH_FIELD& field : symbol->GetFields() )
548 {
549 // Never delete mandatory fields
550 if( field.IsMandatory() )
551 continue;
552
553 if( fpData.m_fieldsMap.find( field.GetCanonicalName() ) == fpData.m_fieldsMap.end() )
554 {
555 // Field not found in footprint field map, delete it
557 msg.Printf( _( "Delete %s field '%s.'" ),
558 ref.GetRef(),
559 EscapeHTML( field.GetName() ) );
560
561 if( !m_dryRun )
562 symbol->RemoveField( symbol->GetField( field.GetName() ) );
563
564 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
565 }
566 }
567 }
568
569 // TODO: back-annotate netclass changes?
570 }
571
572 if( !m_dryRun )
573 {
574 m_frame->RecalculateConnections( &commit, NO_CLEANUP );
575 m_frame->UpdateNetHighlightStatus();
576
577 commit.Push( _( "Update Schematic from PCB" ) );
578 }
579}
580
581
583{
585
586 // Initial orientation from the pin
587 switch( aPin->GetLibPin()->GetOrientation() )
588 {
589 default:
592 case PIN_ORIENTATION::PIN_DOWN: spin = SPIN_STYLE::UP; break;
594 }
595
596 // Reorient based on the actual symbol orientation now
597 struct ORIENT
598 {
599 int flag;
600 int n_rots;
601 int mirror_x;
602 int mirror_y;
603 }
604 orientations[] =
605 {
606 { SYM_ORIENT_0, 0, 0, 0 },
607 { SYM_ORIENT_90, 1, 0, 0 },
608 { SYM_ORIENT_180, 2, 0, 0 },
609 { SYM_ORIENT_270, 3, 0, 0 },
610 { SYM_MIRROR_X + SYM_ORIENT_0, 0, 1, 0 },
611 { SYM_MIRROR_X + SYM_ORIENT_90, 1, 1, 0 },
612 { SYM_MIRROR_Y, 0, 0, 1 },
613 { SYM_MIRROR_X + SYM_ORIENT_270, 3, 1, 0 },
614 { SYM_MIRROR_Y + SYM_ORIENT_0, 0, 0, 1 },
615 { SYM_MIRROR_Y + SYM_ORIENT_90, 1, 0, 1 },
616 { SYM_MIRROR_Y + SYM_ORIENT_180, 2, 0, 1 },
617 { SYM_MIRROR_Y + SYM_ORIENT_270, 3, 0, 1 }
618 };
619
620 ORIENT o = orientations[ 0 ];
621
622 const SCH_SYMBOL* parentSymbol = static_cast<const SCH_SYMBOL*>( aPin->GetParentSymbol() );
623
624 if( !parentSymbol )
625 return spin;
626
627 int symbolOrientation = parentSymbol->GetOrientation();
628
629 for( const ORIENT& i : orientations )
630 {
631 if( i.flag == symbolOrientation )
632 {
633 o = i;
634 break;
635 }
636 }
637
638 for( int i = 0; i < o.n_rots; i++ )
639 spin = spin.RotateCCW();
640
641 if( o.mirror_x )
642 spin = spin.MirrorX();
643
644 if( o.mirror_y )
645 spin = spin.MirrorY();
646
647 return spin;
648}
649
650
651void addConnections( SCH_ITEM* aItem, const SCH_SHEET_PATH& aSheetPath,
652 std::set<SCH_ITEM*>& connectedItems )
653{
654 if( connectedItems.insert( aItem ).second )
655 {
656 for( SCH_ITEM* connectedItem : aItem->ConnectedItems( aSheetPath ) )
657 addConnections( connectedItem, aSheetPath, connectedItems );
658 }
659}
660
661
662void BACK_ANNOTATE::processNetNameChange( SCH_COMMIT* aCommit, const wxString& aRef, SCH_PIN* aPin,
663 const SCH_CONNECTION* aConnection,
664 const wxString& aOldName, const wxString& aNewName )
665{
666 wxString msg;
667
668 // Find a physically-connected driver. We can't use the SCH_CONNECTION's m_driver because
669 // it has already been resolved by merging subgraphs with the same label, etc., and our
670 // name change may cause that resolution to change.
671
672 std::set<SCH_ITEM*> connectedItems;
673 SCH_ITEM* driver = nullptr;
675
676 addConnections( aPin, aConnection->Sheet(), connectedItems );
677
678 for( SCH_ITEM* item : connectedItems )
679 {
681
682 if( priority > driverPriority )
683 {
684 driver = item;
685 driverPriority = priority;
686 }
687 }
688
689 switch( driver->Type() )
690 {
691 case SCH_LABEL_T:
693 case SCH_HIER_LABEL_T:
694 case SCH_SHEET_PIN_T:
696
697 msg.Printf( _( "Change %s pin %s net label from '%s' to '%s'." ),
698 aRef,
699 EscapeHTML( aPin->GetShownNumber() ),
700 EscapeHTML( aOldName ),
701 EscapeHTML( aNewName ) );
702
703 if( !m_dryRun )
704 {
705 aCommit->Modify( driver, aConnection->Sheet().LastScreen() );
706 static_cast<SCH_LABEL_BASE*>( driver )->SetText( aNewName );
707 }
708
709 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
710 break;
711
712 case SCH_PIN_T:
713 {
714 SCH_PIN* schPin = static_cast<SCH_PIN*>( driver );
715 SPIN_STYLE spin = orientLabel( schPin );
716
717 if( schPin->IsPower() )
718 {
719 msg.Printf( _( "Net %s cannot be changed to %s because it is driven by a power pin." ),
720 EscapeHTML( aOldName ),
721 EscapeHTML( aNewName ) );
722
723 m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
724 break;
725 }
726
728 msg.Printf( _( "Add label '%s' to %s pin %s net." ),
729 EscapeHTML( aNewName ),
730 aRef,
731 EscapeHTML( aPin->GetShownNumber() ) );
732
733 if( !m_dryRun )
734 {
735 SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
736 SCH_LABEL* label = new SCH_LABEL( driver->GetPosition(), aNewName );
737 label->SetParent( &m_frame->Schematic() );
738 label->SetTextSize( VECTOR2I( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
739 label->SetSpinStyle( spin );
740 label->SetFlags( IS_NEW );
741
742 SCH_SCREEN* screen = aConnection->Sheet().LastScreen();
743 aCommit->Add( label, screen );
744 }
745
746 m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
747 }
748 break;
749
750 default:
751 break;
752 }
753}
const char * name
void addConnections(SCH_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath, std::set< SCH_ITEM * > &connectedItems)
static SPIN_STYLE orientLabel(SCH_PIN *aPin)
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
bool BackAnnotateSymbols(const std::string &aNetlist)
Run back annotation algorithm.
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
std::deque< CHANGELIST_ITEM > m_changelist
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_FP_DATA > > CHANGELIST_ITEM
bool m_processReferences
BACK_ANNOTATE(SCH_EDIT_FRAME *aFrame, REPORTER &aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aProcessAttributes, bool aProcessOtherFields, bool aDryRun)
bool m_processFootprints
bool m_processOtherFields
void getPcbModulesFromString(const std::string &aPayload)
Parse netlist sent over KiWay express mail interface and fill m_pcbModules.
SCH_EDIT_FRAME * m_frame
void checkForUnusedSymbols()
Check if some symbols are not represented in PCB footprints and vice versa.
SCH_REFERENCE_LIST m_refs
bool FetchNetlistFromPCB(std::string &aNetlist)
Get netlist from the Pcbnew.
PCB_FOOTPRINTS_MAP m_pcbFootprints
void processNetNameChange(SCH_COMMIT *aCommit, const wxString &aRef, SCH_PIN *aPin, const SCH_CONNECTION *aConnection, const wxString &aOldName, const wxString &aNewName)
REPORTER & m_reporter
bool m_processAttributes
bool m_matchByReference
void PushNewLinksToPCB()
void applyChangelist()
Apply changelist to the schematic.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:106
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Definition commit.h:78
Implement a lexical analyzer for the SPECCTRA DSN file format.
Definition dsnlexer.h:81
virtual VECTOR2I GetPosition() const
Definition eda_item.h:272
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:142
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:534
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:579
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:116
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:387
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
These are loaded from Eeschema settings but then overwritten by the project settings.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
SCH_SHEET_PATH Sheet() const
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
const SCH_ITEM_VEC & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
Definition sch_item.cpp:382
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:223
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
wxString GetShownNumber() const
Definition sch_pin.cpp:587
SCH_PIN * GetLibPin() const
Definition sch_pin.h:89
PIN_ORIENTATION GetOrientation() const
Definition sch_pin.cpp:263
bool IsPower() const
Check if the pin is either a global or local power pin.
Definition sch_pin.cpp:380
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
int FindRef(const wxString &aPath) const
Search the list for a symbol with a given reference.
int FindRefByFullPath(const wxString &aFullPath) const
Search the list for a symbol with the given KIID path (as string).
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
wxString GetRef() const
const wxString GetValue() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
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.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
Schematic symbol object.
Definition sch_symbol.h:75
void SetValueFieldText(const wxString &aValue)
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
Definition sch_symbol.h:760
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
int GetOrientation() const override
Get the display symbol orientation.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
SPIN_STYLE RotateCCW()
void SetDNP(bool aDNP) override
Definition symbol.h:198
bool GetExcludedFromBoard() const override
Definition symbol.h:192
void SetExcludedFromBOM(bool aExcludeFromBOM) override
Set or clear the exclude from schematic bill of materials flag.
Definition symbol.h:185
bool GetDNP() const override
Set or clear the 'Do Not Populate' flag.
Definition symbol.h:197
bool GetExcludedFromBOM() const override
Definition symbol.h:186
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:72
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:194
This file is part of the common library.
#define _(s)
@ NO_RECURSE
Definition eda_item.h:52
#define IS_NEW
New item, just created.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ MAIL_PCB_UPDATE_LINKS
Definition mail_type.h:52
@ MAIL_PCB_GET_NETLIST
Definition mail_type.h:51
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
Definition pin_type.h:127
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:111
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:118
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:135
void Scan(PTREE *aTree, DSNLEXER *aLexer)
Fill an empty PTREE with information from a KiCad s-expression stream.
Definition ptree.cpp:84
boost::property_tree::ptree PTREE
Definition ptree.h:52
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_ACTION
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ NO_CLEANUP
Definition schematic.h:75
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
wxString From_UTF8(const char *cstring)
Container for Pcbnew footprint data.Map to hold NETLIST footprints data.
std::map< wxString, wxString > m_pinMap
std::map< wxString, wxString > m_fieldsMap
@ SYM_ORIENT_270
Definition symbol.h:42
@ SYM_MIRROR_Y
Definition symbol.h:44
@ SYM_ORIENT_180
Definition symbol.h:41
@ SYM_MIRROR_X
Definition symbol.h:43
@ SYM_ORIENT_90
Definition symbol.h:40
@ SYM_ORIENT_0
Definition symbol.h:39
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
@ SCH_LABEL_T
Definition typeinfo.h:169
@ SCH_HIER_LABEL_T
Definition typeinfo.h:171
@ SCH_SHEET_PIN_T
Definition typeinfo.h:176
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:170
@ SCH_PIN_T
Definition typeinfo.h:155
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
Definition of file extensions used in Kicad.