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{
208 char line[1024];
209
210 strncpy( line, cmdline, sizeof( line ) - 1 );
211 line[ sizeof( line ) - 1 ] = '\0';
212
213 char* idcmd = strtok( line, " \n\r" );
214 char* text = strtok( nullptr, "\"\n\r" );
215
216 if( idcmd == nullptr )
217 return;
218
219 CROSS_PROBING_SETTINGS& crossProbingSettings = eeconfig()->m_CrossProbing;
220
221 if( strcmp( idcmd, "$CONFIG" ) == 0 )
222 {
224 return;
225 }
226 else if( strcmp( idcmd, "$ERC" ) == 0 )
227 {
229 return;
230 }
231 else if( strcmp( idcmd, "$NET:" ) == 0 )
232 {
233 if( !crossProbingSettings.auto_highlight )
234 return;
235
236 wxString netName = From_UTF8( text );
237
238 if( auto sg = Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
239 m_highlightedConn = sg->GetDriverConnection()->Name();
240 else
241 m_highlightedConn = wxEmptyString;
242
243 // If the incoming net belongs to a net chain, also turn on chain
244 // highlight so the schematic mirrors what the PCB editor is doing.
245 if( CONNECTION_GRAPH* graph = Schematic().ConnectionGraph() )
246 {
247 if( SCH_NETCHAIN* chain = graph->GetNetChainForNet( m_highlightedConn ) )
248 SetHighlightedNetChain( chain->GetName() );
249 else
250 SetHighlightedNetChain( wxEmptyString );
251 }
252
255
256 SetStatusText( _( "Highlighted net:" ) + wxS( " " ) + UnescapeString( netName ) );
257 return;
258 }
259 else if( strcmp( idcmd, "$CLEAR:" ) == 0 )
260 {
261 // Cross-probing is now done through selection so we no longer need a clear command
262 return;
263 }
264
265 if( !crossProbingSettings.on_selection )
266 return;
267
268 if( text == nullptr )
269 return;
270
271 if( strcmp( idcmd, "$PART:" ) != 0 )
272 return;
273
274 wxString part_ref = From_UTF8( text );
275
276 /* look for a complement */
277 idcmd = strtok( nullptr, " \n\r" );
278
279 if( idcmd == nullptr ) // Highlight symbol only (from CvPcb or Pcbnew)
280 {
281 // Highlight symbol part_ref, or clear Highlight, if part_ref is not existing
282 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
283 return;
284 }
285
286 text = strtok( nullptr, "\"\n\r" );
287
288 if( text == nullptr )
289 return;
290
291 wxString msg = From_UTF8( text );
292
293 if( strcmp( idcmd, "$REF:" ) == 0 )
294 {
295 // Highlighting the reference itself isn't actually that useful, and it's harder to
296 // see. Highlight the parent and display the message.
297 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
298 }
299 else if( strcmp( idcmd, "$VAL:" ) == 0 )
300 {
301 // Highlighting the value itself isn't actually that useful, and it's harder to see.
302 // Highlight the parent and display the message.
303 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
304 }
305 else if( strcmp( idcmd, "$PAD:" ) == 0 )
306 {
307 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_PIN, msg );
308 }
309 else
310 {
311 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
312 }
313}
314
315
316void SCH_EDIT_FRAME::SendSelectItemsToPcb( const std::vector<EDA_ITEM*>& aItems, bool aForce )
317{
318 std::vector<wxString> parts;
319
320 for( EDA_ITEM* item : aItems )
321 {
322 switch( item->Type() )
323 {
324 case SCH_SYMBOL_T:
325 {
326 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
327 wxString ref = symbol->GetField( FIELD_T::REFERENCE )->GetText();
328
329 parts.push_back( wxT( "F" ) + EscapeString( ref, CTX_IPC ) );
330 break;
331 }
332
333 case SCH_SHEET_T:
334 {
335 // For cross probing, we need the full path of the sheet, because
336 // we search by the footprint path prefix in the PCB editor
337 wxString full_path = GetCurrentSheet().PathAsString() + item->m_Uuid.AsString();
338
339 parts.push_back( wxT( "S" ) + full_path );
340 break;
341 }
342
343 case SCH_PIN_T:
344 {
345 SCH_PIN* pin = static_cast<SCH_PIN*>( item );
346 SYMBOL* symbol = pin->GetParentSymbol();
347 wxString ref = symbol->GetRef( &GetCurrentSheet(), false );
348
349 // Highlight the resolved pad(s) in pcbnew (issue #2282); a mapped pin may target more
350 // than one pad via stacked notation, so highlight all of them.
351 wxString effective = pin->GetEffectivePadNumber( GetCurrentSheet(), Schematic().GetCurrentVariant() );
352
353 for( const wxString& pad : ExpandStackedPinNotation( effective ) )
354 {
355 parts.push_back( wxT( "P" ) + EscapeString( ref, CTX_IPC ) + wxT( "/" )
356 + EscapeString( pad, CTX_IPC ) );
357 }
358
359 break;
360 }
361
362 default:
363 break;
364 }
365 }
366
367 if( parts.empty() )
368 return;
369
370 std::string command = "$SELECT: 0,";
371
372 for( wxString part : parts )
373 {
374 command += part;
375 command += ",";
376 }
377
378 command.pop_back();
379
380 if( Kiface().IsSingle() )
381 {
382 SendCommand( MSG_TO_PCB, command );
383 }
384 else
385 {
386 // Typically ExpressMail is going to be s-expression packets, but since
387 // we have existing interpreter of the selection packet on the other
388 // side in place, we use that here.
390 command, this );
391 }
392}
393
394
395void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
396{
397 // The command is a keyword followed by a quoted string.
398
399 std::string packet = fmt::format( "$NET: \"{}\"", TO_UTF8( aNetName ) );
400
401 if( !packet.empty() )
402 {
403 if( Kiface().IsSingle() )
404 {
405 SendCommand( MSG_TO_PCB, packet );
406 }
407 else
408 {
409 // Typically ExpressMail is going to be s-expression packets, but since
410 // we have existing interpreter of the cross probe packet on the other
411 // side in place, we use that here.
413 }
414 }
415}
416
417
419{
420 if( !aConnection )
421 {
423 return;
424 }
425
426 if( aConnection->IsNet() )
427 {
428 SendCrossProbeNetName( aConnection->Name() );
429 return;
430 }
431
432 if( aConnection->Members().empty() )
433 return;
434
435 auto all_members = aConnection->AllMembers();
436
437 wxString nets = all_members[0]->Name();
438
439 if( all_members.size() == 1 )
440 {
441 SendCrossProbeNetName( nets );
442 return;
443 }
444
445 // TODO: This could be replaced by just sending the bus name once we have bus contents
446 // included as part of the netlist sent from Eeschema to Pcbnew (and thus Pcbnew can
447 // natively keep track of bus membership)
448
449 for( size_t i = 1; i < all_members.size(); i++ )
450 nets << "," << all_members[i]->Name();
451
452 std::string packet = fmt::format( "$NETS: \"{}\"", TO_UTF8( nets ) );
453
454 if( !packet.empty() )
455 {
456 if( Kiface().IsSingle() )
457 SendCommand( MSG_TO_PCB, packet );
458 else
459 {
460 // Typically ExpressMail is going to be s-expression packets, but since
461 // we have existing interpreter of the cross probe packet on the other
462 // side in place, we use that here.
464 }
465 }
466}
467
468
470{
471 std::string packet = "$CLEAR\n";
472
473 if( Kiface().IsSingle() )
474 {
475 SendCommand( MSG_TO_PCB, packet );
476 }
477 else
478 {
479 // Typically ExpressMail is going to be s-expression packets, but since
480 // we have existing interpreter of the cross probe packet on the other
481 // side in place, we use that here.
483 }
484}
485
486
487bool findSymbolsAndPins( const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
488 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
489 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
490 const wxString& aVariantName = wxEmptyString, bool aRecursive = false )
491{
492 if( aRecursive )
493 {
494 // Iterate over children
495 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
496 {
497 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
498 continue;
499
500 findSymbolsAndPins( aSchematicSheetList, candidate, aSyncSymMap, aSyncPinMap, aVariantName, aRecursive );
501 }
502 }
503
504 SCH_REFERENCE_LIST references;
505
506 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
507
508 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
509 {
510 SCH_REFERENCE& schRef = references[ii];
511
512 if( schRef.IsSplitNeeded() )
513 schRef.Split();
514
515 SCH_SYMBOL* symbol = schRef.GetSymbol();
516 wxString refNum = schRef.GetRefNumber();
517 wxString fullRef = schRef.GetRef() + refNum;
518
519 // Skip power symbols
520 if( fullRef.StartsWith( wxS( "#" ) ) )
521 continue;
522
523 // Unannotated symbols are not supported
524 if( refNum.compare( wxS( "?" ) ) == 0 )
525 continue;
526
527 // Look for whole footprint
528 auto symMatchIt = aSyncSymMap.find( fullRef );
529
530 if( symMatchIt != aSyncSymMap.end() )
531 {
532 symMatchIt->second.emplace_back( schRef );
533
534 // Whole footprint was selected, no need to select pins
535 continue;
536 }
537
538 // Look for pins
539 auto symPinMatchIt = aSyncPinMap.find( fullRef );
540
541 if( symPinMatchIt != aSyncPinMap.end() )
542 {
543 std::unordered_map<wxString, SCH_PIN*>& pinMap = symPinMatchIt->second;
544 std::vector<SCH_PIN*> pinsOnSheet = symbol->GetPins( &aSheetPath );
545
546 for( SCH_PIN* pin : pinsOnSheet )
547 {
548 int pinUnit = pin->GetLibPin()->GetUnit();
549
550 if( pinUnit > 0 && pinUnit != schRef.GetUnit() )
551 continue;
552
553 // Reverse-map the requested pad back to the owning pin (issue #2282). A pin may
554 // resolve to several pads via the map; match the first that pcbnew asked for.
555 for( const wxString& pad :
556 ExpandStackedPinNotation( pin->GetEffectivePadNumber( aSheetPath, aVariantName ) ) )
557 {
558 auto pinIt = pinMap.find( pad );
559
560 if( pinIt != pinMap.end() )
561 {
562 pinIt->second = pin;
563 break;
564 }
565 }
566 }
567 }
568 }
569
570 return false;
571}
572
573
575 const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
576 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
577 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
578 std::unordered_map<SCH_SHEET_PATH, bool>& aCache )
579{
580 auto cacheIt = aCache.find( aSheetPath );
581
582 if( cacheIt != aCache.end() )
583 return cacheIt->second;
584
585 // Iterate over children
586 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
587 {
588 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
589 continue;
590
591 bool childRet = sheetContainsOnlyWantedItems( aSchematicSheetList, candidate, aSyncSymMap,
592 aSyncPinMap, aCache );
593
594 if( !childRet )
595 {
596 aCache.emplace( aSheetPath, false );
597 return false;
598 }
599 }
600
601 SCH_REFERENCE_LIST references;
602 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
603
604 if( references.GetCount() == 0 ) // Empty sheet, obviously do not contain wanted items
605 {
606 aCache.emplace( aSheetPath, false );
607 return false;
608 }
609
610 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
611 {
612 SCH_REFERENCE& schRef = references[ii];
613
614 if( schRef.IsSplitNeeded() )
615 schRef.Split();
616
617 wxString refNum = schRef.GetRefNumber();
618 wxString fullRef = schRef.GetRef() + refNum;
619
620 // Skip power symbols
621 if( fullRef.StartsWith( wxS( "#" ) ) )
622 continue;
623
624 // Unannotated symbols are not supported
625 if( refNum.compare( wxS( "?" ) ) == 0 )
626 continue;
627
628 if( aSyncSymMap.find( fullRef ) == aSyncSymMap.end() )
629 {
630 aCache.emplace( aSheetPath, false );
631 return false; // Some symbol is not wanted.
632 }
633
634 if( aSyncPinMap.find( fullRef ) != aSyncPinMap.end() )
635 {
636 aCache.emplace( aSheetPath, false );
637 return false; // Looking for specific pins, so can't be mapped
638 }
639 }
640
641 aCache.emplace( aSheetPath, true );
642 return true;
643}
644
645
646std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>>
647findItemsFromSyncSelection( const SCHEMATIC& aSchematic, const std::string aSyncStr,
648 bool aFocusOnFirst )
649{
650 wxArrayString syncArray = wxStringTokenize( aSyncStr, wxS( "," ) );
651
652 std::unordered_map<wxString, std::vector<SCH_REFERENCE>> syncSymMap;
653 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>> syncPinMap;
654 std::unordered_map<SCH_SHEET_PATH, double> symScores;
655 std::unordered_map<SCH_SHEET_PATH, bool> fullyWantedCache;
656
657 std::optional<wxString> focusSymbol;
658 std::optional<std::pair<wxString, wxString>> focusPin;
659 std::unordered_map<SCH_SHEET_PATH, std::vector<SCH_ITEM*>> focusItemResults;
660
661 const SCH_SHEET_LIST allSheetsList = aSchematic.Hierarchy();
662
663 // In orderedSheets, the current sheet comes first.
664 std::vector<SCH_SHEET_PATH> orderedSheets;
665 orderedSheets.reserve( allSheetsList.size() );
666 orderedSheets.push_back( aSchematic.CurrentSheet() );
667
668 for( const SCH_SHEET_PATH& sheetPath : allSheetsList )
669 {
670 if( sheetPath != aSchematic.CurrentSheet() )
671 orderedSheets.push_back( sheetPath );
672 }
673
674 // Init sync maps from the sync string
675 for( size_t i = 0; i < syncArray.size(); i++ )
676 {
677 wxString syncEntry = syncArray[i];
678
679 if( syncEntry.empty() )
680 continue;
681
682 wxString syncData = syncEntry.substr( 1 );
683
684 switch( syncEntry.GetChar( 0 ).GetValue() )
685 {
686 case 'F': // Select by footprint: F<Reference>
687 {
688 wxString symRef = UnescapeString( syncData );
689
690 if( aFocusOnFirst && ( i == 0 ) )
691 focusSymbol = symRef;
692
693 syncSymMap[symRef] = std::vector<SCH_REFERENCE>();
694 break;
695 }
696
697 case 'P': // Select by pad: P<Footprint reference>/<Pad number>
698 {
699 wxString symRef = UnescapeString( syncData.BeforeFirst( '/' ) );
700 wxString padNum = UnescapeString( syncData.AfterFirst( '/' ) );
701
702 if( aFocusOnFirst && ( i == 0 ) )
703 focusPin = std::make_pair( symRef, padNum );
704
705 syncPinMap[symRef][padNum] = nullptr;
706 break;
707 }
708
709 default:
710 break;
711 }
712 }
713
714 // Lambda definitions
715 auto flattenSyncMaps =
716 [&syncSymMap, &syncPinMap]() -> std::vector<SCH_ITEM*>
717 {
718 std::vector<SCH_ITEM*> allVec;
719
720 for( const auto& [symRef, symbols] : syncSymMap )
721 {
722 for( const SCH_REFERENCE& ref : symbols )
723 allVec.push_back( ref.GetSymbol() );
724 }
725
726 for( const auto& [symRef, pinMap] : syncPinMap )
727 {
728 for( const auto& [padNum, pin] : pinMap )
729 {
730 if( pin )
731 allVec.push_back( pin );
732 }
733 }
734
735 return allVec;
736 };
737
738 auto clearSyncMaps =
739 [&syncSymMap, &syncPinMap]()
740 {
741 for( auto& [symRef, symbols] : syncSymMap )
742 symbols.clear();
743
744 for( auto& [reference, pins] : syncPinMap )
745 {
746 for( auto& [number, pin] : pins )
747 pin = nullptr;
748 }
749 };
750
751 auto syncMapsValuesEmpty =
752 [&syncSymMap, &syncPinMap]() -> bool
753 {
754 for( const auto& [symRef, symbols] : syncSymMap )
755 {
756 if( symbols.size() > 0 )
757 return false;
758 }
759
760 for( const auto& [symRef, pins] : syncPinMap )
761 {
762 for( const auto& [padNum, pin] : pins )
763 {
764 if( pin )
765 return false;
766 }
767 }
768
769 return true;
770 };
771
772 auto checkFocusItems =
773 [&]( const SCH_SHEET_PATH& aSheet )
774 {
775 if( focusSymbol )
776 {
777 auto findIt = syncSymMap.find( *focusSymbol );
778
779 if( findIt != syncSymMap.end() )
780 {
781 if( findIt->second.size() > 0 )
782 focusItemResults[aSheet].push_back( findIt->second.front().GetSymbol() );
783 }
784 }
785 else if( focusPin )
786 {
787 auto findIt = syncPinMap.find( focusPin->first );
788
789 if( findIt != syncPinMap.end() )
790 {
791 if( findIt->second[focusPin->second] )
792 focusItemResults[aSheet].push_back( findIt->second[focusPin->second] );
793 }
794 }
795 };
796
797 auto makeRetForSheet =
798 [&]( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aFocusItem )
799 {
800 clearSyncMaps();
801
802 // Fill sync maps
803 findSymbolsAndPins( allSheetsList, aSheet, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
804 std::vector<SCH_ITEM*> itemsVector = flattenSyncMaps();
805
806 // Add fully wanted sheets to vector
807 for( SCH_ITEM* item : aSheet.LastScreen()->Items().OfType( SCH_SHEET_T ) )
808 {
809 KIID_PATH kiidPath = aSheet.Path();
810 kiidPath.push_back( item->m_Uuid );
811
812 std::optional<SCH_SHEET_PATH> subsheetPath =
813 allSheetsList.GetSheetPathByKIIDPath( kiidPath );
814
815 if( !subsheetPath )
816 continue;
817
818 if( sheetContainsOnlyWantedItems( allSheetsList, *subsheetPath, syncSymMap,
819 syncPinMap, fullyWantedCache ) )
820 {
821 itemsVector.push_back( item );
822 }
823 }
824
825 return std::make_tuple( aSheet, aFocusItem, itemsVector );
826 };
827
828 if( aFocusOnFirst )
829 {
830 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
831 {
832 clearSyncMaps();
833
834 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
835
836 checkFocusItems( sheetPath );
837 }
838
839 if( focusItemResults.size() > 0 )
840 {
841 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
842 {
843 const std::vector<SCH_ITEM*>& items = focusItemResults[sheetPath];
844
845 if( !items.empty() )
846 return makeRetForSheet( sheetPath, items.front() );
847 }
848 }
849 }
850 else
851 {
852 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
853 {
854 clearSyncMaps();
855
856 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap, aSchematic.GetCurrentVariant() );
857
858 if( !syncMapsValuesEmpty() )
859 {
860 // Something found on sheet
861 return makeRetForSheet( sheetPath, nullptr );
862 }
863 }
864 }
865
866 return std::nullopt;
867}
868
869
871{
872 std::string& payload = mail.GetPayload();
873
874 switch( mail.Command() )
875 {
877 {
878 std::stringstream ss( payload );
879 std::string file;
880
883 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL,
885
886 wxCHECK_RET( optTable.has_value(), "Could not load symbol lib table." );
887 LIBRARY_TABLE* table = optTable.value();
888
889 wxString projectPath = Prj().GetProjectPath();
890
891 // First line of payload is the source project directory.
892 std::string srcProjDir;
893 std::getline( ss, srcProjDir, '\n' );
894
895 std::vector<wxString> toLoad;
896
897 while( std::getline( ss, file, '\n' ) )
898 {
899 if( file.empty() )
900 continue;
901
902 wxFileName fn( file );
904 SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
905
906 if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
907 {
908 wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
909 continue;
910 }
911
912 pi.reset( SCH_IO_MGR::FindPlugin( type ) );
913
914 wxString libTableUri;
915 bool isProjectLocal = fn.GetFullPath().StartsWith( wxString( srcProjDir ) );
916
917 if( isProjectLocal )
918 {
919 // Project-local library: copy into the KiCad project directory and use a
920 // project-relative path so the sym-lib-table stays portable.
921 if( !fn.FileExists() )
922 continue;
923
924 wxFileName projectFn( projectPath, fn.GetFullName() );
925
926 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists() )
927 wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath() );
928
929 libTableUri = wxS( "${KIPRJMOD}/" ) + fn.GetFullName();
930 }
931 else
932 {
933 // External library referenced by absolute path. Preserve the original path.
934 libTableUri = fn.GetFullPath();
935 }
936
937 if( !table->HasRow( fn.GetName() ) )
938 {
939 LIBRARY_TABLE_ROW& row = table->InsertRow();
940 row.SetNickname( fn.GetName() );
941 row.SetURI( libTableUri );
942 row.SetType( SCH_IO_MGR::ShowType( type ) );
943 toLoad.emplace_back( fn.GetName() );
944 }
945 }
946
947 if( !toLoad.empty() )
948 {
949 bool success = true;
950
951 table->Save().map_error(
952 [&]( const LIBRARY_ERROR& aError )
953 {
954 wxLogError( wxT( "Error saving project library table:\n\n" ) + aError.message );
955 success = false;
956 } );
957
958 if( success )
959 {
960 manager.AbortAsyncLoads();
962
963 std::ranges::for_each( toLoad,
964 [adapter]( const wxString& aNick )
965 {
966 adapter->LoadOne( aNick );
967 } );
968 }
969 }
970
974
975 break;
976 }
977
978 case MAIL_CROSS_PROBE:
979 ExecuteRemoteCommand( payload.c_str() );
980 break;
981
982 case MAIL_SELECTION:
983 if( !eeconfig()->m_CrossProbing.on_selection )
984 break;
985
987
989 {
990 // $SELECT: 0,<spec1>,<spec2>,<spec3>
991 // Try to select specified items.
992
993 // $SELECT: 1,<spec1>,<spec2>,<spec3>
994 // Select and focus on <spec1> item, select other specified items that are on the
995 // same sheet.
996
997 std::string prefix = "$SELECT: ";
998
999 std::string paramStr = payload.substr( prefix.size() );
1000
1001 // Empty/broken command: we need at least 2 chars for sync string.
1002 if( paramStr.size() < 2 )
1003 break;
1004
1005 std::string syncStr = paramStr.substr( 2 );
1006
1007 bool focusOnFirst = ( paramStr[0] == '1' );
1008
1009 std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>> findRet =
1010 findItemsFromSyncSelection( Schematic(), syncStr, focusOnFirst );
1011
1012 if( findRet )
1013 {
1014 auto& [sheetPath, focusItem, items] = *findRet;
1015
1016 m_syncingPcbToSchSelection = true; // recursion guard
1017
1018 GetToolManager()->GetTool<SCH_SELECTION_TOOL>()->SyncSelection( sheetPath, focusItem,
1019 items );
1020
1022
1023 if( eeconfig()->m_CrossProbing.flash_selection )
1024 {
1025 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash enabled, items=%zu", items.size() );
1026 if( items.empty() )
1027 {
1028 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): nothing to flash" );
1029 }
1030 else
1031 {
1032 std::vector<SCH_ITEM*> itemPtrs;
1033 std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
1034
1035 StartCrossProbeFlash( itemPtrs );
1036 }
1037 }
1038 else
1039 {
1040 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash disabled" );
1041 }
1042 }
1043
1044 break;
1045 }
1046
1048 {
1049 if( !payload.empty() )
1050 {
1051 wxString annotationMessage( payload );
1052
1053 // Ensure schematic is OK for netlist creation (especially that it is fully annotated):
1054 if( !ReadyToNetlist( annotationMessage ) )
1055 return;
1056 }
1057
1058 if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
1060
1061 NETLIST_EXPORTER_KICAD exporter( &Schematic() );
1062 STRING_FORMATTER formatter;
1063
1064 exporter.SetKiway( &Kiway() );
1065 exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
1066
1067 payload = formatter.GetString();
1068 break;
1069 }
1070
1071 case MAIL_SCH_GET_ITEM:
1072 {
1073 KIID uuid( payload );
1075
1076 if( SCH_ITEM* item = m_schematic->ResolveItem( uuid, &path, true ) )
1077 {
1078 if( item->Type() == SCH_SHEET_T )
1079 payload = static_cast<SCH_SHEET*>( item )->GetShownName( false );
1080 else if( item->Type() == SCH_SYMBOL_T )
1081 payload = static_cast<SCH_SYMBOL*>( item )->GetRef( &path, true );
1082 else
1083 payload = item->GetFriendlyName();
1084 }
1085
1086 break;
1087 }
1088
1090 try
1091 {
1092 SCH_EDITOR_CONTROL* controlTool = m_toolManager->GetTool<SCH_EDITOR_CONTROL>();
1093 controlTool->AssignFootprints( payload );
1094 }
1095 catch( const IO_ERROR& )
1096 {
1097 }
1098 break;
1099
1100 case MAIL_SCH_REFRESH:
1101 {
1103
1105 GetCanvas()->Refresh();
1106 break;
1107 }
1108
1109 case MAIL_IMPORT_FILE:
1110 {
1111 // Extract file format type and path (plugin type, path and properties keys, values
1112 // separated with \n)
1113 std::stringstream ss( payload );
1114 char delim = '\n';
1115
1116 std::string formatStr;
1117 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
1118
1119 std::string fnameStr;
1120 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
1121
1122 int importFormat;
1123
1124 try
1125 {
1126 importFormat = std::stoi( formatStr );
1127 }
1128 catch( std::invalid_argument& )
1129 {
1130 wxFAIL;
1131 importFormat = -1;
1132 }
1133
1134 std::map<std::string, UTF8> props;
1135
1136 do
1137 {
1138 std::string key, value;
1139
1140 if( !std::getline( ss, key, delim ) )
1141 break;
1142
1143 std::getline( ss, value, delim ); // We may want an empty string as value
1144
1145 props.emplace( key, value );
1146
1147 } while( true );
1148
1149 if( importFormat >= 0 )
1150 importFile( fnameStr, importFormat, props.empty() ? nullptr : &props );
1151
1152 break;
1153 }
1154
1155 case MAIL_SCH_SAVE:
1156 if( SaveProject() )
1157 payload = "success";
1158
1159 break;
1160
1161 case MAIL_SCH_UPDATE:
1163 break;
1164
1165 case MAIL_RELOAD_LIB:
1166 {
1167 if( m_designBlocksPane && m_designBlocksPane->IsShown() )
1168 {
1169 m_designBlocksPane->RefreshLibs();
1170 SyncView();
1171 }
1172
1173 // Show any symbol library load errors in the status bar
1174 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1175 {
1177 wxString errors = adapter->GetLibraryLoadErrors();
1178
1179 if( !errors.IsEmpty() )
1180 statusBar->AddWarningMessages( "load", errors );
1181 }
1182
1183 break;
1184 }
1185
1187 {
1188 wxString targetFile( payload );
1189
1190 for( SCH_SHEET_PATH& sheetPath : m_schematic->Hierarchy() )
1191 {
1192 SCH_SCREEN* screen = sheetPath.LastScreen();
1193
1194 if( screen && screen->GetFileName() == targetFile )
1195 {
1196 m_toolManager->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet, &sheetPath );
1197 payload = "success";
1198 Raise();
1199 return;
1200 }
1201 }
1202
1203 payload.clear();
1204 break;
1205 }
1206
1207 default:;
1208
1209 }
1210}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
static TOOL_ACTION showSymbolLibTable
Definition actions.h:278
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:44
wxString AsString() const
Definition kiid.cpp:242
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:496
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 ReadyToNetlist(const wxString &aAnnotateMessage)
Check if we are ready to write a netlist file for the current schematic.
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.
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:226
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
@ 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
std::vector< std::vector< std::string > > table
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