KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema/cross-probing.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 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2011 Wayne Stambaugh <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <wx/tokenzr.h>
23#include <fmt.h>
24#include <kiface_base.h>
25#include <kiway.h>
26#include <kiway_mail.h>
27#include <eda_dde.h>
28#include <connection_graph.h>
29#include <sch_netchain.h>
30#include <sch_sheet.h>
31#include <sch_symbol.h>
32#include <sch_reference_list.h>
33#include <string_utils.h>
37#include <project_sch.h>
38#include <richio.h>
39#include <tools/sch_actions.h>
41#include <advanced_config.h>
42
43#include <pgm_base.h>
46#include <widgets/kistatusbar.h>
47#include <wx/filefn.h>
48#include <wx/log.h>
49#include <trace_helpers.h>
50
51SCH_ITEM* SCH_EDITOR_CONTROL::FindSymbolAndItem( const wxString* aPath, const wxString* aReference,
52 bool aSearchHierarchy, SCH_SEARCH_T aSearchType,
53 const wxString& aSearchText )
54{
55 SCH_SHEET_PATH* sheetWithSymbolFound = nullptr;
56 SCH_SYMBOL* symbol = nullptr;
57 SCH_PIN* pin = nullptr;
58 SCH_SHEET_LIST sheetList;
59 SCH_ITEM* foundItem = nullptr;
60
61 if( !aSearchHierarchy )
62 sheetList.push_back( m_frame->GetCurrentSheet() );
63 else
64 sheetList = m_frame->Schematic().Hierarchy();
65
66 for( SCH_SHEET_PATH& sheet : sheetList )
67 {
68 SCH_SCREEN* screen = sheet.LastScreen();
69
70 for( EDA_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
71 {
72 SCH_SYMBOL* candidate = static_cast<SCH_SYMBOL*>( item );
73
74 // Search by path if specified, otherwise search by reference
75 bool found = false;
76
77 if( aPath )
78 {
79 wxString path = sheet.PathAsString() + candidate->m_Uuid.AsString();
80 found = ( *aPath == path );
81 }
82 else
83 {
84 found = ( aReference && aReference->CmpNoCase( candidate->GetRef( &sheet ) ) == 0 );
85 }
86
87 if( found )
88 {
89 symbol = candidate;
90 sheetWithSymbolFound = &sheet;
91
92 if( aSearchType == HIGHLIGHT_PIN )
93 {
94 pin = symbol->GetPin( aSearchText );
95
96 // Fall back to reverse pin-to-pad resolution so a remapped pad highlights its
97 // owning pin (issue #2282); the search text from pcbnew is a pad number.
98 if( !pin )
99 pin = symbol->GetPinByEffectivePadNumber( aSearchText, &sheet,
100 m_frame->Schematic().GetCurrentVariant() );
101
102 // Ensure we have found the right unit in case of multi-units symbol
103 if( pin )
104 {
105 int unit = pin->GetLibPin()->GetUnit();
106
107 if( unit != 0 && unit != symbol->GetUnit() )
108 {
109 pin = nullptr;
110 continue;
111 }
112
113 // Get pin position in true schematic coordinate
114 foundItem = pin;
115 break;
116 }
117 }
118 else
119 {
120 foundItem = symbol;
121 break;
122 }
123 }
124 }
125
126 if( foundItem )
127 break;
128 }
129
130 CROSS_PROBING_SETTINGS& crossProbingSettings = m_frame->eeconfig()->m_CrossProbing;
131
132 if( symbol )
133 {
134 if( *sheetWithSymbolFound != m_frame->GetCurrentSheet() )
135 {
136 m_frame->GetToolManager()->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet,
137 sheetWithSymbolFound );
138 }
139
140 if( crossProbingSettings.center_on_items )
141 {
142 if( crossProbingSettings.zoom_to_fit )
143 {
144 BOX2I bbox = symbol->GetBoundingBox();
145
146 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
147 }
148
149 if( pin )
150 m_frame->FocusOnItem( pin );
151 else
152 m_frame->FocusOnItem( symbol );
153 }
154 }
155
156 /* Print diag */
157 wxString msg;
158 wxString displayRef;
159
160 if( aReference )
161 displayRef = *aReference;
162 else if( aPath )
163 displayRef = *aPath;
164
165 if( symbol )
166 {
167 if( aSearchType == HIGHLIGHT_PIN )
168 {
169 if( foundItem )
170 msg.Printf( _( "%s pin %s found" ), displayRef, aSearchText );
171 else
172 msg.Printf( _( "%s found but pin %s not found" ), displayRef, aSearchText );
173 }
174 else
175 {
176 msg.Printf( _( "%s found" ), displayRef );
177 }
178 }
179 else
180 {
181 msg.Printf( _( "%s not found" ), displayRef );
182 }
183
184 m_frame->SetStatusText( msg );
185 m_frame->GetCanvas()->Refresh();
186
187 return foundItem;
188}
189
190
191/* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER
192 *
193 * Commands are:
194 *
195 * $PART: "reference" Put cursor on symbol.
196 * $PART: "reference" $REF: "ref" Put cursor on symbol reference.
197 * $PART: "reference" $VAL: "value" Put cursor on symbol value.
198 * $PART: "reference" $PAD: "pin name" Put cursor on the symbol pin.
199 * $NET: "netname" Highlight a specified net
200 * $CLEAR: "HIGHLIGHTED" Clear symbols highlight
201 *
202 * $CONFIG Show the Manage Symbol Libraries dialog
203 * $ERC Show the ERC dialog
204 */
205void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
206{
207 // A remote command can arrive over the cross-probe socket before tools are registered
208 // or after the tool manager has been torn down while the frame is closing.
209 if( !m_toolManager )
210 return;
211
213
214 if( !editor )
215 return;
216
217 char line[1024];
218
219 strncpy( line, cmdline, sizeof( line ) - 1 );
220 line[ sizeof( line ) - 1 ] = '\0';
221
222 char* idcmd = strtok( line, " \n\r" );
223 char* text = strtok( nullptr, "\"\n\r" );
224
225 if( idcmd == nullptr )
226 return;
227
228 CROSS_PROBING_SETTINGS& crossProbingSettings = eeconfig()->m_CrossProbing;
229
230 if( strcmp( idcmd, "$CONFIG" ) == 0 )
231 {
233 return;
234 }
235 else if( strcmp( idcmd, "$ERC" ) == 0 )
236 {
238 return;
239 }
240 else if( strcmp( idcmd, "$NET:" ) == 0 )
241 {
242 if( !crossProbingSettings.auto_highlight )
243 return;
244
245 wxString netName = From_UTF8( text );
246
247 if( auto sg = Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
248 m_highlightedConn = sg->GetDriverConnection()->Name();
249 else
250 m_highlightedConn = wxEmptyString;
251
252 // If the incoming net belongs to a net chain, also turn on chain
253 // highlight so the schematic mirrors what the PCB editor is doing.
254 if( CONNECTION_GRAPH* graph = Schematic().ConnectionGraph() )
255 {
256 if( SCH_NETCHAIN* chain = graph->GetNetChainForNet( m_highlightedConn ) )
257 SetHighlightedNetChain( chain->GetName() );
258 else
259 SetHighlightedNetChain( wxEmptyString );
260 }
261
264
265 SetStatusText( _( "Highlighted net:" ) + wxS( " " ) + UnescapeString( netName ) );
266 return;
267 }
268 else if( strcmp( idcmd, "$CLEAR:" ) == 0 )
269 {
270 // Cross-probing is now done through selection so we no longer need a clear command
271 return;
272 }
273
274 if( !crossProbingSettings.on_selection )
275 return;
276
277 if( text == nullptr )
278 return;
279
280 if( strcmp( idcmd, "$PART:" ) != 0 )
281 return;
282
283 wxString part_ref = From_UTF8( text );
284
285 /* look for a complement */
286 idcmd = strtok( nullptr, " \n\r" );
287
288 if( idcmd == nullptr ) // Highlight symbol only (from CvPcb or Pcbnew)
289 {
290 // Highlight symbol part_ref, or clear Highlight, if part_ref is not existing
291 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
292 return;
293 }
294
295 text = strtok( nullptr, "\"\n\r" );
296
297 if( text == nullptr )
298 return;
299
300 wxString msg = From_UTF8( text );
301
302 if( strcmp( idcmd, "$REF:" ) == 0 )
303 {
304 // Highlighting the reference itself isn't actually that useful, and it's harder to
305 // see. Highlight the parent and display the message.
306 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
307 }
308 else if( strcmp( idcmd, "$VAL:" ) == 0 )
309 {
310 // Highlighting the value itself isn't actually that useful, and it's harder to see.
311 // Highlight the parent and display the message.
312 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
313 }
314 else if( strcmp( idcmd, "$PAD:" ) == 0 )
315 {
316 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_PIN, msg );
317 }
318 else
319 {
320 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
321 }
322}
323
324
325void SCH_EDIT_FRAME::SendSelectItemsToPcb( const std::vector<EDA_ITEM*>& aItems, bool aForce )
326{
327 std::vector<wxString> parts;
328
329 for( EDA_ITEM* item : aItems )
330 {
331 switch( item->Type() )
332 {
333 case SCH_SYMBOL_T:
334 {
335 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
336 wxString ref = symbol->GetField( FIELD_T::REFERENCE )->GetText();
337
338 parts.push_back( wxT( "F" ) + EscapeString( ref, CTX_IPC ) );
339 break;
340 }
341
342 case SCH_SHEET_T:
343 {
344 // For cross probing, we need the full path of the sheet, because
345 // we search by the footprint path prefix in the PCB editor
346 wxString full_path = GetCurrentSheet().PathAsString() + item->m_Uuid.AsString();
347
348 parts.push_back( wxT( "S" ) + full_path );
349 break;
350 }
351
352 case SCH_PIN_T:
353 {
354 SCH_PIN* pin = static_cast<SCH_PIN*>( item );
355 SYMBOL* symbol = pin->GetParentSymbol();
356 wxString ref = symbol->GetRef( &GetCurrentSheet(), false );
357
358 // Highlight the resolved pad(s) in pcbnew (issue #2282); a mapped pin may target more
359 // than one pad via stacked notation, so highlight all of them.
360 wxString effective = pin->GetEffectivePadNumber( GetCurrentSheet(), Schematic().GetCurrentVariant() );
361
362 for( const wxString& pad : ExpandStackedPinNotation( effective ) )
363 {
364 parts.push_back( wxT( "P" ) + EscapeString( ref, CTX_IPC ) + wxT( "/" )
365 + EscapeString( pad, CTX_IPC ) );
366 }
367
368 break;
369 }
370
371 default:
372 break;
373 }
374 }
375
376 if( parts.empty() )
377 return;
378
379 std::string command = "$SELECT: 0,";
380
381 for( wxString part : parts )
382 {
383 command += part;
384 command += ",";
385 }
386
387 command.pop_back();
388
389 if( Kiface().IsSingle() )
390 {
391 SendCommand( MSG_TO_PCB, command );
392 }
393 else
394 {
395 // Typically ExpressMail is going to be s-expression packets, but since
396 // we have existing interpreter of the selection packet on the other
397 // side in place, we use that here.
399 command, this );
400 }
401}
402
403
404void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
405{
406 // The command is a keyword followed by a quoted string.
407
408 std::string packet = fmt::format( "$NET: \"{}\"", TO_UTF8( aNetName ) );
409
410 if( !packet.empty() )
411 {
412 if( Kiface().IsSingle() )
413 {
414 SendCommand( MSG_TO_PCB, packet );
415 }
416 else
417 {
418 // Typically ExpressMail is going to be s-expression packets, but since
419 // we have existing interpreter of the cross probe packet on the other
420 // side in place, we use that here.
422 }
423 }
424}
425
426
428{
429 if( !aConnection )
430 {
432 return;
433 }
434
435 if( aConnection->IsNet() )
436 {
437 SendCrossProbeNetName( aConnection->Name() );
438 return;
439 }
440
441 if( aConnection->Members().empty() )
442 return;
443
444 auto all_members = aConnection->AllMembers();
445
446 wxString nets = all_members[0]->Name();
447
448 if( all_members.size() == 1 )
449 {
450 SendCrossProbeNetName( nets );
451 return;
452 }
453
454 // TODO: This could be replaced by just sending the bus name once we have bus contents
455 // included as part of the netlist sent from Eeschema to Pcbnew (and thus Pcbnew can
456 // natively keep track of bus membership)
457
458 for( size_t i = 1; i < all_members.size(); i++ )
459 nets << "," << all_members[i]->Name();
460
461 std::string packet = fmt::format( "$NETS: \"{}\"", TO_UTF8( nets ) );
462
463 if( !packet.empty() )
464 {
465 if( Kiface().IsSingle() )
466 SendCommand( MSG_TO_PCB, packet );
467 else
468 {
469 // Typically ExpressMail is going to be s-expression packets, but since
470 // we have existing interpreter of the cross probe packet on the other
471 // side in place, we use that here.
473 }
474 }
475}
476
477
479{
480 std::string packet = "$CLEAR\n";
481
482 if( Kiface().IsSingle() )
483 {
484 SendCommand( MSG_TO_PCB, packet );
485 }
486 else
487 {
488 // Typically ExpressMail is going to be s-expression packets, but since
489 // we have existing interpreter of the cross probe packet on the other
490 // side in place, we use that here.
492 }
493}
494
495
496bool findSymbolsAndPins( const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
497 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
498 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
499 const wxString& aVariantName = wxEmptyString, bool aRecursive = false )
500{
501 if( aRecursive )
502 {
503 // Iterate over children
504 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
505 {
506 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
507 continue;
508
509 findSymbolsAndPins( aSchematicSheetList, candidate, aSyncSymMap, aSyncPinMap, aVariantName, aRecursive );
510 }
511 }
512
513 SCH_REFERENCE_LIST references;
514
515 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
516
517 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
518 {
519 SCH_REFERENCE& schRef = references[ii];
520
521 if( schRef.IsSplitNeeded() )
522 schRef.Split();
523
524 SCH_SYMBOL* symbol = schRef.GetSymbol();
525 wxString refNum = schRef.GetRefNumber();
526 wxString fullRef = schRef.GetRef() + refNum;
527
528 // Skip power symbols
529 if( fullRef.StartsWith( wxS( "#" ) ) )
530 continue;
531
532 // Unannotated symbols are not supported
533 if( refNum.compare( wxS( "?" ) ) == 0 )
534 continue;
535
536 // Look for whole footprint
537 auto symMatchIt = aSyncSymMap.find( fullRef );
538
539 if( symMatchIt != aSyncSymMap.end() )
540 {
541 symMatchIt->second.emplace_back( schRef );
542
543 // Whole footprint was selected, no need to select pins
544 continue;
545 }
546
547 // Look for pins
548 auto symPinMatchIt = aSyncPinMap.find( fullRef );
549
550 if( symPinMatchIt != aSyncPinMap.end() )
551 {
552 std::unordered_map<wxString, SCH_PIN*>& pinMap = symPinMatchIt->second;
553 std::vector<SCH_PIN*> pinsOnSheet = symbol->GetPins( &aSheetPath );
554
555 for( SCH_PIN* pin : pinsOnSheet )
556 {
557 int pinUnit = pin->GetLibPin()->GetUnit();
558
559 if( pinUnit > 0 && pinUnit != schRef.GetUnit() )
560 continue;
561
562 // Reverse-map the requested pad back to the owning pin (issue #2282). A pin may
563 // resolve to several pads via the map; match the first that pcbnew asked for.
564 for( const wxString& pad :
565 ExpandStackedPinNotation( pin->GetEffectivePadNumber( aSheetPath, aVariantName ) ) )
566 {
567 auto pinIt = pinMap.find( pad );
568
569 if( pinIt != pinMap.end() )
570 {
571 pinIt->second = pin;
572 break;
573 }
574 }
575 }
576 }
577 }
578
579 return false;
580}
581
582
584 const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
585 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
586 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
587 std::unordered_map<SCH_SHEET_PATH, bool>& aCache )
588{
589 auto cacheIt = aCache.find( aSheetPath );
590
591 if( cacheIt != aCache.end() )
592 return cacheIt->second;
593
594 // Iterate over children
595 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
596 {
597 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
598 continue;
599
600 bool childRet = sheetContainsOnlyWantedItems( aSchematicSheetList, candidate, aSyncSymMap,
601 aSyncPinMap, aCache );
602
603 if( !childRet )
604 {
605 aCache.emplace( aSheetPath, false );
606 return false;
607 }
608 }
609
610 SCH_REFERENCE_LIST references;
611 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
612
613 if( references.GetCount() == 0 ) // Empty sheet, obviously do not contain wanted items
614 {
615 aCache.emplace( aSheetPath, false );
616 return false;
617 }
618
619 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
620 {
621 SCH_REFERENCE& schRef = references[ii];
622
623 if( schRef.IsSplitNeeded() )
624 schRef.Split();
625
626 wxString refNum = schRef.GetRefNumber();
627 wxString fullRef = schRef.GetRef() + refNum;
628
629 // Skip power symbols
630 if( fullRef.StartsWith( wxS( "#" ) ) )
631 continue;
632
633 // Unannotated symbols are not supported
634 if( refNum.compare( wxS( "?" ) ) == 0 )
635 continue;
636
637 if( aSyncSymMap.find( fullRef ) == aSyncSymMap.end() )
638 {
639 aCache.emplace( aSheetPath, false );
640 return false; // Some symbol is not wanted.
641 }
642
643 if( aSyncPinMap.find( fullRef ) != aSyncPinMap.end() )
644 {
645 aCache.emplace( aSheetPath, false );
646 return false; // Looking for specific pins, so can't be mapped
647 }
648 }
649
650 aCache.emplace( aSheetPath, true );
651 return true;
652}
653
654
655std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>>
656findItemsFromSyncSelection( const SCHEMATIC& aSchematic, const std::string aSyncStr,
657 bool aFocusOnFirst )
658{
659 wxArrayString syncArray = wxStringTokenize( aSyncStr, wxS( "," ) );
660
661 std::unordered_map<wxString, std::vector<SCH_REFERENCE>> syncSymMap;
662 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>> syncPinMap;
663 std::unordered_map<SCH_SHEET_PATH, double> symScores;
664 std::unordered_map<SCH_SHEET_PATH, bool> fullyWantedCache;
665
666 std::optional<wxString> focusSymbol;
667 std::optional<std::pair<wxString, wxString>> focusPin;
668 std::unordered_map<SCH_SHEET_PATH, std::vector<SCH_ITEM*>> focusItemResults;
669
670 const SCH_SHEET_LIST allSheetsList = aSchematic.Hierarchy();
671
672 // In orderedSheets, the current sheet comes first.
673 std::vector<SCH_SHEET_PATH> orderedSheets;
674 orderedSheets.reserve( allSheetsList.size() );
675 orderedSheets.push_back( aSchematic.CurrentSheet() );
676
677 for( const SCH_SHEET_PATH& sheetPath : allSheetsList )
678 {
679 if( sheetPath != aSchematic.CurrentSheet() )
680 orderedSheets.push_back( sheetPath );
681 }
682
683 // Init sync maps from the sync string
684 for( size_t i = 0; i < syncArray.size(); i++ )
685 {
686 wxString syncEntry = syncArray[i];
687
688 if( syncEntry.empty() )
689 continue;
690
691 wxString syncData = syncEntry.substr( 1 );
692
693 switch( syncEntry.GetChar( 0 ).GetValue() )
694 {
695 case 'F': // Select by footprint: F<Reference>
696 {
697 wxString symRef = UnescapeString( syncData );
698
699 if( aFocusOnFirst && ( i == 0 ) )
700 focusSymbol = symRef;
701
702 syncSymMap[symRef] = std::vector<SCH_REFERENCE>();
703 break;
704 }
705
706 case 'P': // Select by pad: P<Footprint reference>/<Pad number>
707 {
708 wxString symRef = UnescapeString( syncData.BeforeFirst( '/' ) );
709 wxString padNum = UnescapeString( syncData.AfterFirst( '/' ) );
710
711 if( aFocusOnFirst && ( i == 0 ) )
712 focusPin = std::make_pair( symRef, padNum );
713
714 syncPinMap[symRef][padNum] = nullptr;
715 break;
716 }
717
718 default:
719 break;
720 }
721 }
722
723 // Lambda definitions
724 auto flattenSyncMaps =
725 [&syncSymMap, &syncPinMap]() -> std::vector<SCH_ITEM*>
726 {
727 std::vector<SCH_ITEM*> allVec;
728
729 for( const auto& [symRef, symbols] : syncSymMap )
730 {
731 for( const SCH_REFERENCE& ref : symbols )
732 allVec.push_back( ref.GetSymbol() );
733 }
734
735 for( const auto& [symRef, pinMap] : syncPinMap )
736 {
737 for( const auto& [padNum, pin] : pinMap )
738 {
739 if( pin )
740 allVec.push_back( pin );
741 }
742 }
743
744 return allVec;
745 };
746
747 auto clearSyncMaps =
748 [&syncSymMap, &syncPinMap]()
749 {
750 for( auto& [symRef, symbols] : syncSymMap )
751 symbols.clear();
752
753 for( auto& [reference, pins] : syncPinMap )
754 {
755 for( auto& [number, pin] : pins )
756 pin = nullptr;
757 }
758 };
759
760 auto syncMapsValuesEmpty =
761 [&syncSymMap, &syncPinMap]() -> bool
762 {
763 for( const auto& [symRef, symbols] : syncSymMap )
764 {
765 if( symbols.size() > 0 )
766 return false;
767 }
768
769 for( const auto& [symRef, pins] : syncPinMap )
770 {
771 for( const auto& [padNum, pin] : pins )
772 {
773 if( pin )
774 return false;
775 }
776 }
777
778 return true;
779 };
780
781 auto checkFocusItems =
782 [&]( const SCH_SHEET_PATH& aSheet )
783 {
784 if( focusSymbol )
785 {
786 auto findIt = syncSymMap.find( *focusSymbol );
787
788 if( findIt != syncSymMap.end() )
789 {
790 if( findIt->second.size() > 0 )
791 focusItemResults[aSheet].push_back( findIt->second.front().GetSymbol() );
792 }
793 }
794 else if( focusPin )
795 {
796 auto findIt = syncPinMap.find( focusPin->first );
797
798 if( findIt != syncPinMap.end() )
799 {
800 if( findIt->second[focusPin->second] )
801 focusItemResults[aSheet].push_back( findIt->second[focusPin->second] );
802 }
803 }
804 };
805
806 auto makeRetForSheet =
807 [&]( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aFocusItem )
808 {
809 clearSyncMaps();
810
811 // Fill sync maps
812 findSymbolsAndPins( allSheetsList, aSheet, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
813 std::vector<SCH_ITEM*> itemsVector = flattenSyncMaps();
814
815 // Add fully wanted sheets to vector
816 for( SCH_ITEM* item : aSheet.LastScreen()->Items().OfType( SCH_SHEET_T ) )
817 {
818 KIID_PATH kiidPath = aSheet.Path();
819 kiidPath.push_back( item->m_Uuid );
820
821 std::optional<SCH_SHEET_PATH> subsheetPath =
822 allSheetsList.GetSheetPathByKIIDPath( kiidPath );
823
824 if( !subsheetPath )
825 continue;
826
827 if( sheetContainsOnlyWantedItems( allSheetsList, *subsheetPath, syncSymMap,
828 syncPinMap, fullyWantedCache ) )
829 {
830 itemsVector.push_back( item );
831 }
832 }
833
834 return std::make_tuple( aSheet, aFocusItem, itemsVector );
835 };
836
837 if( aFocusOnFirst )
838 {
839 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
840 {
841 clearSyncMaps();
842
843 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
844
845 checkFocusItems( sheetPath );
846 }
847
848 if( focusItemResults.size() > 0 )
849 {
850 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
851 {
852 const std::vector<SCH_ITEM*>& items = focusItemResults[sheetPath];
853
854 if( !items.empty() )
855 return makeRetForSheet( sheetPath, items.front() );
856 }
857 }
858 }
859 else
860 {
861 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
862 {
863 clearSyncMaps();
864
865 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
866
867 if( !syncMapsValuesEmpty() )
868 {
869 // Something found on sheet
870 return makeRetForSheet( sheetPath, nullptr );
871 }
872 }
873 }
874
875 return std::nullopt;
876}
877
878
880{
881 std::string& payload = mail.GetPayload();
882
883 switch( mail.Command() )
884 {
886 {
887 std::stringstream ss( payload );
888 std::string file;
889
892 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL,
894
895 wxCHECK_RET( optTable.has_value(), "Could not load symbol lib table." );
896 LIBRARY_TABLE* table = optTable.value();
897
898 wxString projectPath = Prj().GetProjectPath();
899
900 // First line of payload is the source project directory.
901 std::string srcProjDir;
902 std::getline( ss, srcProjDir, '\n' );
903
904 std::vector<wxString> toLoad;
905
906 while( std::getline( ss, file, '\n' ) )
907 {
908 if( file.empty() )
909 continue;
910
911 wxFileName fn( file );
913 SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
914
915 if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
916 {
917 wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
918 continue;
919 }
920
921 pi.reset( SCH_IO_MGR::FindPlugin( type ) );
922
923 wxString libTableUri;
924 bool isProjectLocal = fn.GetFullPath().StartsWith( wxString( srcProjDir ) );
925
926 if( isProjectLocal )
927 {
928 // Project-local library: copy into the KiCad project directory and use a
929 // project-relative path so the sym-lib-table stays portable.
930 if( !fn.FileExists() )
931 continue;
932
933 wxFileName projectFn( projectPath, fn.GetFullName() );
934
935 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists() )
936 wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath() );
937
938 libTableUri = wxS( "${KIPRJMOD}/" ) + fn.GetFullName();
939 }
940 else
941 {
942 // External library referenced by absolute path. Preserve the original path.
943 libTableUri = fn.GetFullPath();
944 }
945
946 if( !table->HasRow( fn.GetName() ) )
947 {
948 LIBRARY_TABLE_ROW& row = table->InsertRow();
949 row.SetNickname( fn.GetName() );
950 row.SetURI( libTableUri );
951 row.SetType( SCH_IO_MGR::ShowType( type ) );
952 toLoad.emplace_back( fn.GetName() );
953 }
954 }
955
956 if( !toLoad.empty() )
957 {
958 bool success = true;
959
960 table->Save().map_error(
961 [&]( const LIBRARY_ERROR& aError )
962 {
963 wxLogError( wxT( "Error saving project library table:\n\n" ) + aError.message );
964 success = false;
965 } );
966
967 if( success )
968 {
969 manager.AbortAsyncLoads();
971
972 std::ranges::for_each( toLoad,
973 [adapter]( const wxString& aNick )
974 {
975 adapter->LoadOne( aNick );
976 } );
977 }
978 }
979
983
984 break;
985 }
986
987 case MAIL_CROSS_PROBE:
988 ExecuteRemoteCommand( payload.c_str() );
989 break;
990
991 case MAIL_SELECTION:
992 if( !eeconfig()->m_CrossProbing.on_selection )
993 break;
994
996
998 {
999 // $SELECT: 0,<spec1>,<spec2>,<spec3>
1000 // Try to select specified items.
1001
1002 // $SELECT: 1,<spec1>,<spec2>,<spec3>
1003 // Select and focus on <spec1> item, select other specified items that are on the
1004 // same sheet.
1005
1006 std::string prefix = "$SELECT: ";
1007
1008 std::string paramStr = payload.substr( prefix.size() );
1009
1010 // Empty/broken command: we need at least 2 chars for sync string.
1011 if( paramStr.size() < 2 )
1012 break;
1013
1014 std::string syncStr = paramStr.substr( 2 );
1015
1016 bool focusOnFirst = ( paramStr[0] == '1' );
1017
1018 std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>> findRet =
1019 findItemsFromSyncSelection( Schematic(), syncStr, focusOnFirst );
1020
1021 if( findRet )
1022 {
1023 auto& [sheetPath, focusItem, items] = *findRet;
1024
1025 m_syncingPcbToSchSelection = true; // recursion guard
1026
1027 GetToolManager()->GetTool<SCH_SELECTION_TOOL>()->SyncSelection( sheetPath, focusItem,
1028 items );
1029
1031
1032 if( eeconfig()->m_CrossProbing.flash_selection )
1033 {
1034 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash enabled, items=%zu", items.size() );
1035 if( items.empty() )
1036 {
1037 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): nothing to flash" );
1038 }
1039 else
1040 {
1041 std::vector<SCH_ITEM*> itemPtrs;
1042 std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
1043
1044 StartCrossProbeFlash( itemPtrs );
1045 }
1046 }
1047 else
1048 {
1049 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash disabled" );
1050 }
1051 }
1052
1053 break;
1054 }
1055
1057 {
1058 if( !payload.empty() )
1059 {
1060 wxString annotationMessage( payload );
1061
1062 // Ensure schematic is OK for netlist creation (especially that it is fully annotated):
1063 bool userCancelled = false;
1064
1065 if( !ReadyToNetlist( annotationMessage, &userCancelled ) )
1066 {
1067 // Cancel replies with a sentinel so the caller aborts silently; an unannotated
1068 // schematic echoes the annotation message so the caller shows its own error
1069 if( userCancelled )
1071
1072 return;
1073 }
1074 }
1075
1076 if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
1078
1079 NETLIST_EXPORTER_KICAD exporter( &Schematic() );
1080 STRING_FORMATTER formatter;
1081
1082 exporter.SetKiway( &Kiway() );
1083 exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
1084
1085 payload = formatter.GetString();
1086 break;
1087 }
1088
1089 case MAIL_SCH_GET_ITEM:
1090 {
1091 KIID uuid( payload );
1093
1094 if( SCH_ITEM* item = m_schematic->ResolveItem( uuid, &path, true ) )
1095 {
1096 if( item->Type() == SCH_SHEET_T )
1097 payload = static_cast<SCH_SHEET*>( item )->GetShownName( false );
1098 else if( item->Type() == SCH_SYMBOL_T )
1099 payload = static_cast<SCH_SYMBOL*>( item )->GetRef( &path, true );
1100 else
1101 payload = item->GetFriendlyName();
1102 }
1103
1104 break;
1105 }
1106
1108 try
1109 {
1110 SCH_EDITOR_CONTROL* controlTool = m_toolManager->GetTool<SCH_EDITOR_CONTROL>();
1111 controlTool->AssignFootprints( payload );
1112 }
1113 catch( const IO_ERROR& )
1114 {
1115 }
1116 break;
1117
1118 case MAIL_SCH_REFRESH:
1119 {
1121
1123 GetCanvas()->Refresh();
1124 break;
1125 }
1126
1127 case MAIL_IMPORT_FILE:
1128 {
1129 // Extract file format type and path (plugin type, path and properties keys, values
1130 // separated with \n)
1131 std::stringstream ss( payload );
1132 char delim = '\n';
1133
1134 std::string formatStr;
1135 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
1136
1137 std::string fnameStr;
1138 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
1139
1140 int importFormat;
1141
1142 try
1143 {
1144 importFormat = std::stoi( formatStr );
1145 }
1146 catch( std::invalid_argument& )
1147 {
1148 wxFAIL;
1149 importFormat = -1;
1150 }
1151
1152 std::map<std::string, UTF8> props;
1153
1154 do
1155 {
1156 std::string key, value;
1157
1158 if( !std::getline( ss, key, delim ) )
1159 break;
1160
1161 std::getline( ss, value, delim ); // We may want an empty string as value
1162
1163 props.emplace( key, value );
1164
1165 } while( true );
1166
1167 if( importFormat >= 0 )
1168 importFile( fnameStr, importFormat, props.empty() ? nullptr : &props );
1169
1170 break;
1171 }
1172
1173 case MAIL_SCH_SAVE:
1174 if( SaveProject() )
1175 payload = "success";
1176
1177 break;
1178
1179 case MAIL_SCH_UPDATE:
1181 break;
1182
1183 case MAIL_RELOAD_LIB:
1184 {
1185 if( m_designBlocksPane && m_designBlocksPane->IsShown() )
1186 {
1187 m_designBlocksPane->RefreshLibs();
1188 SyncView();
1189 }
1190
1191 // Show any symbol library load errors in the status bar
1192 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1193 {
1195 wxString errors = adapter->GetLibraryLoadErrors();
1196
1197 if( !errors.IsEmpty() )
1198 statusBar->AddWarningMessages( "load", errors );
1199 }
1200
1201 break;
1202 }
1203
1205 {
1206 wxString targetFile( payload );
1207
1208 for( SCH_SHEET_PATH& sheetPath : m_schematic->Hierarchy() )
1209 {
1210 SCH_SCREEN* screen = sheetPath.LastScreen();
1211
1212 if( screen && screen->GetFileName() == targetFile )
1213 {
1214 m_toolManager->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet, &sheetPath );
1215 payload = "success";
1216 Raise();
1217 return;
1218 }
1219 }
1220
1221 payload.clear();
1222 break;
1223 }
1224
1225 default:;
1226
1227 }
1228}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
static TOOL_ACTION showSymbolLibTable
Definition actions.h:280
static TOOL_ACTION updateSchematicFromPcb
Definition actions.h:261
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
CROSS_PROBING_SETTINGS m_CrossProbing
Calculate the connectivity of a schematic and generates netlists.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:96
const KIID m_Uuid
Definition eda_item.h:531
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:221
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:1686
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:34
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:52
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:44
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:486
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void AbortAsyncLoads()
Abort any async library loading operations in progress.
void LoadProjectTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the project library tables in the given list, or all tables if no list is given
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetURI(const wxString &aUri)
void SetKiway(KIWAY *aKiway)
Generate the KiCad netlist format supported by Pcbnew.
void Format(OUTPUTFORMATTER *aOutputFormatter, int aCtl)
Output this s-expression netlist into aOutputFormatter.
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:126
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
Holds all the data relating to one schematic.
Definition schematic.h:90
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
wxString GetCurrentVariant() const
Return the current variant being edited.
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
static TOOL_ACTION runERC
Inspection and Editing.
static TOOL_ACTION changeSheet
static TOOL_ACTION updateNetHighlighting
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void SyncView()
Mark all items for refresh.
EESCHEMA_SETTINGS * eeconfig() const
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool IsNet() const
const std::vector< std::shared_ptr< SCH_CONNECTION > > AllMembers() const
wxString Name(bool aIgnoreSheet=false) const
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void AssignFootprints(const std::string &aChangedSetOfReferences)
SCH_ITEM * FindSymbolAndItem(const wxString *aPath, const wxString *aReference, bool aSearchHierarchy, SCH_SEARCH_T aSearchType, const wxString &aSearchText)
Find a symbol in the schematic and an item in this symbol and select it.
bool m_syncingPcbToSchSelection
friend class SCH_EDITOR_CONTROL
void SendSelectItemsToPcb(const std::vector< EDA_ITEM * > &aItems, bool aForce)
Send items to board editor for selection.
bool ReadyToNetlist(const wxString &aAnnotateMessage, bool *aUserCancelled=nullptr)
Check if we are ready to write a netlist file for the current schematic.
void SendCrossProbeClearHighlight()
Tell Pcbnew to clear the existing highlighted net, if one exists.
SCHEMATIC * m_schematic
The currently loaded schematic.
SCH_SHEET_PATH & GetCurrentSheet() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, PROGRESS_REPORTER *aProgressReporter=nullptr)
Generate the connection data for the entire schematic hierarchy.
SCHEMATIC & Schematic() const
void ExecuteRemoteCommand(const char *cmdline) override
Execute a remote command sent via a socket on port KICAD_SCH_PORT_SERVICE_NUMBER (which defaults to 4...
void RefreshNetNavigator(const NET_NAVIGATOR_ITEM_DATA *aSelection=nullptr)
SCH_DESIGN_BLOCK_PANE * m_designBlocksPane
bool importFile(const wxString &aFileName, int aFileType, const std::map< std::string, UTF8 > *aProperties=nullptr)
Load the given filename but sets the path to the current project path.
void SendCrossProbeNetName(const wxString &aNetName)
Send a net name to Pcbnew for highlighting.
void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent) override
Receive #KIWAY_ROUTED_EVENT messages from other players.
void StartCrossProbeFlash(const std::vector< SCH_ITEM * > &aItems)
void SetHighlightedNetChain(const wxString &aNetChain)
wxString m_highlightedConn
The highlighted net or bus or empty string.
void SetCrossProbeConnection(const SCH_CONNECTION *aConnection)
Send a connection (net or bus) to Pcbnew for highlighting.
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
bool SaveProject(bool aSaveAs=false)
Save the currently-open schematic (including its hierarchy) and associated project.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
static const wxString ShowType(SCH_FILE_T aFileType)
Return a brief name for a plugin, given aFileType enum.
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a symbol library using the file extension of aLibPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
int GetUnit() const
Definition sch_item.h:233
A net chain is a collection of nets that are connected together through passive components.
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
void Split()
Attempt to split the reference designator into a name (U) and number (1).
bool IsSplitNeeded()
Determine if this reference needs to be split or if it likely already has been.
SCH_SYMBOL * GetSymbol() const
wxString GetRef() const
int GetUnit() const
wxString GetRefNumber() const
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:115
const wxString & GetFileName() const
Definition sch_screen.h:150
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Adds SCH_REFERENCE object to aReferences for each symbol in the sheet.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
bool IsContainedWithin(const SCH_SHEET_PATH &aSheetPathToTest) const
Check if this path is contained inside aSheetPathToTest.
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
Schematic symbol object.
Definition sch_symbol.h:69
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
SCH_PIN * GetPinByEffectivePadNumber(const wxString &aPadNumber, const SCH_SHEET_PATH *aSheet, const wxString &aVariantName=wxEmptyString) const
Find the pin whose effective footprint pad number (issue #2282) is aPadNumber on aSheet,...
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:418
const std::string & GetString()
Definition richio.h:441
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::optional< LIB_STATUS > LoadOne(LIB_DATA *aLib) override
Loads or reloads the given library, if it exists.
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition symbol.h:59
virtual const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const =0
TOOL_MANAGER * m_toolManager
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
#define _(s)
bool SendCommand(int aService, const std::string &aMessage)
Used by a client to sent (by a socket connection) a data to a server.
Definition eda_dde.cpp:225
DDE server & client.
#define MSG_TO_PCB
Definition eda_dde.h:45
std::optional< std::tuple< SCH_SHEET_PATH, SCH_ITEM *, std::vector< SCH_ITEM * > > > findItemsFromSyncSelection(const SCHEMATIC &aSchematic, const std::string aSyncStr, bool aFocusOnFirst)
bool findSymbolsAndPins(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, const wxString &aVariantName=wxEmptyString, bool aRecursive=false)
bool sheetContainsOnlyWantedItems(const SCH_SHEET_LIST &aSchematicSheetList, const SCH_SHEET_PATH &aSheetPath, std::unordered_map< wxString, std::vector< SCH_REFERENCE > > &aSyncSymMap, std::unordered_map< wxString, std::unordered_map< wxString, SCH_PIN * > > &aSyncPinMap, std::unordered_map< SCH_SHEET_PATH, bool > &aCache)
@ FRAME_PCB_EDITOR
Definition frame_type.h:38
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ FRAME_SCH_VIEWER
Definition frame_type.h:32
@ FRAME_CVPCB
Definition frame_type.h:48
const wxChar *const traceCrossProbeFlash
Flag to enable debug output for cross-probe flash operations.
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:728
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition macros.h:79
@ MAIL_IMPORT_FILE
Definition mail_type.h:45
@ MAIL_SCH_REFRESH
Definition mail_type.h:50
@ MAIL_CROSS_PROBE
Definition mail_type.h:35
@ MAIL_SELECTION_FORCE
Definition mail_type.h:37
@ MAIL_SCH_SAVE
Definition mail_type.h:39
@ MAIL_ASSIGN_FOOTPRINTS
Definition mail_type.h:38
@ MAIL_SCH_GET_ITEM
Definition mail_type.h:47
@ MAIL_SCH_UPDATE
Definition mail_type.h:44
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:51
@ MAIL_SCH_NAVIGATE_TO_SHEET
Definition mail_type.h:57
@ MAIL_SCH_GET_NETLIST
Definition mail_type.h:46
@ MAIL_SELECTION
Definition mail_type.h:36
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
#define MAIL_SCH_GET_NETLIST_CANCELLED
Reply payload for MAIL_SCH_GET_NETLIST when the user deliberately aborts netlist generation (for exam...
Definition mail_type.h:66
@ ALL
All except INITIAL_ADD.
Definition view_item.h:55
#define GNL_ALL
@ GNL_OPT_KICAD
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
SCH_SEARCH_T
Schematic search type used by the socket link with Pcbnew.
@ HIGHLIGHT_SYMBOL
@ HIGHLIGHT_PIN
@ SYMBOL_FILTER_NON_POWER
@ GLOBAL_CLEANUP
Definition schematic.h:79
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
wxString UnescapeString(const wxString &aSource)
wxString From_UTF8(const char *cstring)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
@ CTX_IPC
Cross-probing behavior.
bool on_selection
Synchronize the selection for multiple items too.
bool zoom_to_fit
Zoom to fit items (ignored if center_on_items is off).
bool center_on_items
Automatically pan to cross-probed items.
bool auto_highlight
Automatically turn on highlight mode in the target frame.
wxString message
@ REFERENCE
Field Reference of part, i.e. "IC21".
std::string path
KIBIS_PIN * pin
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_PIN_T
Definition typeinfo.h:150