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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <wx/tokenzr.h>
27#include <fmt.h>
28#include <kiface_base.h>
29#include <kiway.h>
30#include <kiway_mail.h>
31#include <eda_dde.h>
32#include <connection_graph.h>
33#include <sch_netchain.h>
34#include <sch_sheet.h>
35#include <sch_symbol.h>
36#include <sch_reference_list.h>
37#include <string_utils.h>
41#include <project_sch.h>
42#include <richio.h>
43#include <tools/sch_actions.h>
45#include <advanced_config.h>
46
47#include <pgm_base.h>
50#include <widgets/kistatusbar.h>
51#include <wx/filefn.h>
52#include <wx/log.h>
53#include <trace_helpers.h>
54
55SCH_ITEM* SCH_EDITOR_CONTROL::FindSymbolAndItem( const wxString* aPath, const wxString* aReference,
56 bool aSearchHierarchy, SCH_SEARCH_T aSearchType,
57 const wxString& aSearchText )
58{
59 SCH_SHEET_PATH* sheetWithSymbolFound = nullptr;
60 SCH_SYMBOL* symbol = nullptr;
61 SCH_PIN* pin = nullptr;
62 SCH_SHEET_LIST sheetList;
63 SCH_ITEM* foundItem = nullptr;
64
65 if( !aSearchHierarchy )
66 sheetList.push_back( m_frame->GetCurrentSheet() );
67 else
68 sheetList = m_frame->Schematic().Hierarchy();
69
70 for( SCH_SHEET_PATH& sheet : sheetList )
71 {
72 SCH_SCREEN* screen = sheet.LastScreen();
73
74 for( EDA_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
75 {
76 SCH_SYMBOL* candidate = static_cast<SCH_SYMBOL*>( item );
77
78 // Search by path if specified, otherwise search by reference
79 bool found = false;
80
81 if( aPath )
82 {
83 wxString path = sheet.PathAsString() + candidate->m_Uuid.AsString();
84 found = ( *aPath == path );
85 }
86 else
87 {
88 found = ( aReference && aReference->CmpNoCase( candidate->GetRef( &sheet ) ) == 0 );
89 }
90
91 if( found )
92 {
93 symbol = candidate;
94 sheetWithSymbolFound = &sheet;
95
96 if( aSearchType == HIGHLIGHT_PIN )
97 {
98 pin = symbol->GetPin( aSearchText );
99
100 // Ensure we have found the right unit in case of multi-units symbol
101 if( pin )
102 {
103 int unit = pin->GetLibPin()->GetUnit();
104
105 if( unit != 0 && unit != symbol->GetUnit() )
106 {
107 pin = nullptr;
108 continue;
109 }
110
111 // Get pin position in true schematic coordinate
112 foundItem = pin;
113 break;
114 }
115 }
116 else
117 {
118 foundItem = symbol;
119 break;
120 }
121 }
122 }
123
124 if( foundItem )
125 break;
126 }
127
128 CROSS_PROBING_SETTINGS& crossProbingSettings = m_frame->eeconfig()->m_CrossProbing;
129
130 if( symbol )
131 {
132 if( *sheetWithSymbolFound != m_frame->GetCurrentSheet() )
133 {
134 m_frame->GetToolManager()->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet,
135 sheetWithSymbolFound );
136 }
137
138 if( crossProbingSettings.center_on_items )
139 {
140 if( crossProbingSettings.zoom_to_fit )
141 {
142 BOX2I bbox = symbol->GetBoundingBox();
143
144 m_toolMgr->GetTool<SCH_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
145 }
146
147 if( pin )
148 m_frame->FocusOnItem( pin );
149 else
150 m_frame->FocusOnItem( symbol );
151 }
152 }
153
154 /* Print diag */
155 wxString msg;
156 wxString displayRef;
157
158 if( aReference )
159 displayRef = *aReference;
160 else if( aPath )
161 displayRef = *aPath;
162
163 if( symbol )
164 {
165 if( aSearchType == HIGHLIGHT_PIN )
166 {
167 if( foundItem )
168 msg.Printf( _( "%s pin %s found" ), displayRef, aSearchText );
169 else
170 msg.Printf( _( "%s found but pin %s not found" ), displayRef, aSearchText );
171 }
172 else
173 {
174 msg.Printf( _( "%s found" ), displayRef );
175 }
176 }
177 else
178 {
179 msg.Printf( _( "%s not found" ), displayRef );
180 }
181
182 m_frame->SetStatusText( msg );
183 m_frame->GetCanvas()->Refresh();
184
185 return foundItem;
186}
187
188
189/* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER
190 *
191 * Commands are:
192 *
193 * $PART: "reference" Put cursor on symbol.
194 * $PART: "reference" $REF: "ref" Put cursor on symbol reference.
195 * $PART: "reference" $VAL: "value" Put cursor on symbol value.
196 * $PART: "reference" $PAD: "pin name" Put cursor on the symbol pin.
197 * $NET: "netname" Highlight a specified net
198 * $CLEAR: "HIGHLIGHTED" Clear symbols highlight
199 *
200 * $CONFIG Show the Manage Symbol Libraries dialog
201 * $ERC Show the ERC dialog
202 */
203void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
204{
206 char line[1024];
207
208 strncpy( line, cmdline, sizeof( line ) - 1 );
209 line[ sizeof( line ) - 1 ] = '\0';
210
211 char* idcmd = strtok( line, " \n\r" );
212 char* text = strtok( nullptr, "\"\n\r" );
213
214 if( idcmd == nullptr )
215 return;
216
217 CROSS_PROBING_SETTINGS& crossProbingSettings = eeconfig()->m_CrossProbing;
218
219 if( strcmp( idcmd, "$CONFIG" ) == 0 )
220 {
222 return;
223 }
224 else if( strcmp( idcmd, "$ERC" ) == 0 )
225 {
227 return;
228 }
229 else if( strcmp( idcmd, "$NET:" ) == 0 )
230 {
231 if( !crossProbingSettings.auto_highlight )
232 return;
233
234 wxString netName = From_UTF8( text );
235
236 if( auto sg = Schematic().ConnectionGraph()->FindFirstSubgraphByName( netName ) )
237 m_highlightedConn = sg->GetDriverConnection()->Name();
238 else
239 m_highlightedConn = wxEmptyString;
240
241 // If the incoming net belongs to a net chain, also turn on chain
242 // highlight so the schematic mirrors what the PCB editor is doing.
243 if( CONNECTION_GRAPH* graph = Schematic().ConnectionGraph() )
244 {
245 if( SCH_NETCHAIN* chain = graph->GetNetChainForNet( m_highlightedConn ) )
246 SetHighlightedNetChain( chain->GetName() );
247 else
248 SetHighlightedNetChain( wxEmptyString );
249 }
250
253
254 SetStatusText( _( "Highlighted net:" ) + wxS( " " ) + UnescapeString( netName ) );
255 return;
256 }
257 else if( strcmp( idcmd, "$CLEAR:" ) == 0 )
258 {
259 // Cross-probing is now done through selection so we no longer need a clear command
260 return;
261 }
262
263 if( !crossProbingSettings.on_selection )
264 return;
265
266 if( text == nullptr )
267 return;
268
269 if( strcmp( idcmd, "$PART:" ) != 0 )
270 return;
271
272 wxString part_ref = From_UTF8( text );
273
274 /* look for a complement */
275 idcmd = strtok( nullptr, " \n\r" );
276
277 if( idcmd == nullptr ) // Highlight symbol only (from CvPcb or Pcbnew)
278 {
279 // Highlight symbol part_ref, or clear Highlight, if part_ref is not existing
280 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
281 return;
282 }
283
284 text = strtok( nullptr, "\"\n\r" );
285
286 if( text == nullptr )
287 return;
288
289 wxString msg = From_UTF8( text );
290
291 if( strcmp( idcmd, "$REF:" ) == 0 )
292 {
293 // Highlighting the reference itself isn't actually that useful, and it's harder to
294 // see. Highlight the parent and display the message.
295 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
296 }
297 else if( strcmp( idcmd, "$VAL:" ) == 0 )
298 {
299 // Highlighting the value itself isn't actually that useful, and it's harder to see.
300 // Highlight the parent and display the message.
301 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, msg );
302 }
303 else if( strcmp( idcmd, "$PAD:" ) == 0 )
304 {
305 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_PIN, msg );
306 }
307 else
308 {
309 editor->FindSymbolAndItem( nullptr, &part_ref, true, HIGHLIGHT_SYMBOL, wxEmptyString );
310 }
311}
312
313
314void SCH_EDIT_FRAME::SendSelectItemsToPcb( const std::vector<EDA_ITEM*>& aItems, bool aForce )
315{
316 std::vector<wxString> parts;
317
318 for( EDA_ITEM* item : aItems )
319 {
320 switch( item->Type() )
321 {
322 case SCH_SYMBOL_T:
323 {
324 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
325 wxString ref = symbol->GetField( FIELD_T::REFERENCE )->GetText();
326
327 parts.push_back( wxT( "F" ) + EscapeString( ref, CTX_IPC ) );
328 break;
329 }
330
331 case SCH_SHEET_T:
332 {
333 // For cross probing, we need the full path of the sheet, because
334 // we search by the footprint path prefix in the PCB editor
335 wxString full_path = GetCurrentSheet().PathAsString() + item->m_Uuid.AsString();
336
337 parts.push_back( wxT( "S" ) + full_path );
338 break;
339 }
340
341 case SCH_PIN_T:
342 {
343 SCH_PIN* pin = static_cast<SCH_PIN*>( item );
344 SYMBOL* symbol = pin->GetParentSymbol();
345 wxString ref = symbol->GetRef( &GetCurrentSheet(), false );
346
347 parts.push_back( wxT( "P" ) + EscapeString( ref, CTX_IPC ) + wxT( "/" )
348 + EscapeString( pin->GetShownNumber(), CTX_IPC ) );
349 break;
350 }
351
352 default:
353 break;
354 }
355 }
356
357 if( parts.empty() )
358 return;
359
360 std::string command = "$SELECT: 0,";
361
362 for( wxString part : parts )
363 {
364 command += part;
365 command += ",";
366 }
367
368 command.pop_back();
369
370 if( Kiface().IsSingle() )
371 {
372 SendCommand( MSG_TO_PCB, command );
373 }
374 else
375 {
376 // Typically ExpressMail is going to be s-expression packets, but since
377 // we have existing interpreter of the selection packet on the other
378 // side in place, we use that here.
380 command, this );
381 }
382}
383
384
385void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
386{
387 // The command is a keyword followed by a quoted string.
388
389 std::string packet = fmt::format( "$NET: \"{}\"", TO_UTF8( aNetName ) );
390
391 if( !packet.empty() )
392 {
393 if( Kiface().IsSingle() )
394 {
395 SendCommand( MSG_TO_PCB, packet );
396 }
397 else
398 {
399 // Typically ExpressMail is going to be s-expression packets, but since
400 // we have existing interpreter of the cross probe packet on the other
401 // side in place, we use that here.
403 }
404 }
405}
406
407
409{
410 if( !aConnection )
411 {
413 return;
414 }
415
416 if( aConnection->IsNet() )
417 {
418 SendCrossProbeNetName( aConnection->Name() );
419 return;
420 }
421
422 if( aConnection->Members().empty() )
423 return;
424
425 auto all_members = aConnection->AllMembers();
426
427 wxString nets = all_members[0]->Name();
428
429 if( all_members.size() == 1 )
430 {
431 SendCrossProbeNetName( nets );
432 return;
433 }
434
435 // TODO: This could be replaced by just sending the bus name once we have bus contents
436 // included as part of the netlist sent from Eeschema to Pcbnew (and thus Pcbnew can
437 // natively keep track of bus membership)
438
439 for( size_t i = 1; i < all_members.size(); i++ )
440 nets << "," << all_members[i]->Name();
441
442 std::string packet = fmt::format( "$NETS: \"{}\"", TO_UTF8( nets ) );
443
444 if( !packet.empty() )
445 {
446 if( Kiface().IsSingle() )
447 SendCommand( MSG_TO_PCB, packet );
448 else
449 {
450 // Typically ExpressMail is going to be s-expression packets, but since
451 // we have existing interpreter of the cross probe packet on the other
452 // side in place, we use that here.
454 }
455 }
456}
457
458
460{
461 std::string packet = "$CLEAR\n";
462
463 if( Kiface().IsSingle() )
464 {
465 SendCommand( MSG_TO_PCB, packet );
466 }
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
478 const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
479 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
480 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
481 bool aRecursive = false )
482{
483 if( aRecursive )
484 {
485 // Iterate over children
486 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
487 {
488 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
489 continue;
490
491 findSymbolsAndPins( aSchematicSheetList, candidate, aSyncSymMap, aSyncPinMap,
492 aRecursive );
493 }
494 }
495
496 SCH_REFERENCE_LIST references;
497
498 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
499
500 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
501 {
502 SCH_REFERENCE& schRef = references[ii];
503
504 if( schRef.IsSplitNeeded() )
505 schRef.Split();
506
507 SCH_SYMBOL* symbol = schRef.GetSymbol();
508 wxString refNum = schRef.GetRefNumber();
509 wxString fullRef = schRef.GetRef() + refNum;
510
511 // Skip power symbols
512 if( fullRef.StartsWith( wxS( "#" ) ) )
513 continue;
514
515 // Unannotated symbols are not supported
516 if( refNum.compare( wxS( "?" ) ) == 0 )
517 continue;
518
519 // Look for whole footprint
520 auto symMatchIt = aSyncSymMap.find( fullRef );
521
522 if( symMatchIt != aSyncSymMap.end() )
523 {
524 symMatchIt->second.emplace_back( schRef );
525
526 // Whole footprint was selected, no need to select pins
527 continue;
528 }
529
530 // Look for pins
531 auto symPinMatchIt = aSyncPinMap.find( fullRef );
532
533 if( symPinMatchIt != aSyncPinMap.end() )
534 {
535 std::unordered_map<wxString, SCH_PIN*>& pinMap = symPinMatchIt->second;
536 std::vector<SCH_PIN*> pinsOnSheet = symbol->GetPins( &aSheetPath );
537
538 for( SCH_PIN* pin : pinsOnSheet )
539 {
540 int pinUnit = pin->GetLibPin()->GetUnit();
541
542 if( pinUnit > 0 && pinUnit != schRef.GetUnit() )
543 continue;
544
545 auto pinIt = pinMap.find( pin->GetNumber() );
546
547 if( pinIt != pinMap.end() )
548 pinIt->second = pin;
549 }
550 }
551 }
552
553 return false;
554}
555
556
558 const SCH_SHEET_LIST& aSchematicSheetList, const SCH_SHEET_PATH& aSheetPath,
559 std::unordered_map<wxString, std::vector<SCH_REFERENCE>>& aSyncSymMap,
560 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>>& aSyncPinMap,
561 std::unordered_map<SCH_SHEET_PATH, bool>& aCache )
562{
563 auto cacheIt = aCache.find( aSheetPath );
564
565 if( cacheIt != aCache.end() )
566 return cacheIt->second;
567
568 // Iterate over children
569 for( const SCH_SHEET_PATH& candidate : aSchematicSheetList )
570 {
571 if( candidate == aSheetPath || !candidate.IsContainedWithin( aSheetPath ) )
572 continue;
573
574 bool childRet = sheetContainsOnlyWantedItems( aSchematicSheetList, candidate, aSyncSymMap,
575 aSyncPinMap, aCache );
576
577 if( !childRet )
578 {
579 aCache.emplace( aSheetPath, false );
580 return false;
581 }
582 }
583
584 SCH_REFERENCE_LIST references;
585 aSheetPath.GetSymbols( references, SYMBOL_FILTER_NON_POWER, true );
586
587 if( references.GetCount() == 0 ) // Empty sheet, obviously do not contain wanted items
588 {
589 aCache.emplace( aSheetPath, false );
590 return false;
591 }
592
593 for( unsigned ii = 0; ii < references.GetCount(); ii++ )
594 {
595 SCH_REFERENCE& schRef = references[ii];
596
597 if( schRef.IsSplitNeeded() )
598 schRef.Split();
599
600 wxString refNum = schRef.GetRefNumber();
601 wxString fullRef = schRef.GetRef() + refNum;
602
603 // Skip power symbols
604 if( fullRef.StartsWith( wxS( "#" ) ) )
605 continue;
606
607 // Unannotated symbols are not supported
608 if( refNum.compare( wxS( "?" ) ) == 0 )
609 continue;
610
611 if( aSyncSymMap.find( fullRef ) == aSyncSymMap.end() )
612 {
613 aCache.emplace( aSheetPath, false );
614 return false; // Some symbol is not wanted.
615 }
616
617 if( aSyncPinMap.find( fullRef ) != aSyncPinMap.end() )
618 {
619 aCache.emplace( aSheetPath, false );
620 return false; // Looking for specific pins, so can't be mapped
621 }
622 }
623
624 aCache.emplace( aSheetPath, true );
625 return true;
626}
627
628
629std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>>
630findItemsFromSyncSelection( const SCHEMATIC& aSchematic, const std::string aSyncStr,
631 bool aFocusOnFirst )
632{
633 wxArrayString syncArray = wxStringTokenize( aSyncStr, wxS( "," ) );
634
635 std::unordered_map<wxString, std::vector<SCH_REFERENCE>> syncSymMap;
636 std::unordered_map<wxString, std::unordered_map<wxString, SCH_PIN*>> syncPinMap;
637 std::unordered_map<SCH_SHEET_PATH, double> symScores;
638 std::unordered_map<SCH_SHEET_PATH, bool> fullyWantedCache;
639
640 std::optional<wxString> focusSymbol;
641 std::optional<std::pair<wxString, wxString>> focusPin;
642 std::unordered_map<SCH_SHEET_PATH, std::vector<SCH_ITEM*>> focusItemResults;
643
644 const SCH_SHEET_LIST allSheetsList = aSchematic.Hierarchy();
645
646 // In orderedSheets, the current sheet comes first.
647 std::vector<SCH_SHEET_PATH> orderedSheets;
648 orderedSheets.reserve( allSheetsList.size() );
649 orderedSheets.push_back( aSchematic.CurrentSheet() );
650
651 for( const SCH_SHEET_PATH& sheetPath : allSheetsList )
652 {
653 if( sheetPath != aSchematic.CurrentSheet() )
654 orderedSheets.push_back( sheetPath );
655 }
656
657 // Init sync maps from the sync string
658 for( size_t i = 0; i < syncArray.size(); i++ )
659 {
660 wxString syncEntry = syncArray[i];
661
662 if( syncEntry.empty() )
663 continue;
664
665 wxString syncData = syncEntry.substr( 1 );
666
667 switch( syncEntry.GetChar( 0 ).GetValue() )
668 {
669 case 'F': // Select by footprint: F<Reference>
670 {
671 wxString symRef = UnescapeString( syncData );
672
673 if( aFocusOnFirst && ( i == 0 ) )
674 focusSymbol = symRef;
675
676 syncSymMap[symRef] = std::vector<SCH_REFERENCE>();
677 break;
678 }
679
680 case 'P': // Select by pad: P<Footprint reference>/<Pad number>
681 {
682 wxString symRef = UnescapeString( syncData.BeforeFirst( '/' ) );
683 wxString padNum = UnescapeString( syncData.AfterFirst( '/' ) );
684
685 if( aFocusOnFirst && ( i == 0 ) )
686 focusPin = std::make_pair( symRef, padNum );
687
688 syncPinMap[symRef][padNum] = nullptr;
689 break;
690 }
691
692 default:
693 break;
694 }
695 }
696
697 // Lambda definitions
698 auto flattenSyncMaps =
699 [&syncSymMap, &syncPinMap]() -> std::vector<SCH_ITEM*>
700 {
701 std::vector<SCH_ITEM*> allVec;
702
703 for( const auto& [symRef, symbols] : syncSymMap )
704 {
705 for( const SCH_REFERENCE& ref : symbols )
706 allVec.push_back( ref.GetSymbol() );
707 }
708
709 for( const auto& [symRef, pinMap] : syncPinMap )
710 {
711 for( const auto& [padNum, pin] : pinMap )
712 {
713 if( pin )
714 allVec.push_back( pin );
715 }
716 }
717
718 return allVec;
719 };
720
721 auto clearSyncMaps =
722 [&syncSymMap, &syncPinMap]()
723 {
724 for( auto& [symRef, symbols] : syncSymMap )
725 symbols.clear();
726
727 for( auto& [reference, pins] : syncPinMap )
728 {
729 for( auto& [number, pin] : pins )
730 pin = nullptr;
731 }
732 };
733
734 auto syncMapsValuesEmpty =
735 [&syncSymMap, &syncPinMap]() -> bool
736 {
737 for( const auto& [symRef, symbols] : syncSymMap )
738 {
739 if( symbols.size() > 0 )
740 return false;
741 }
742
743 for( const auto& [symRef, pins] : syncPinMap )
744 {
745 for( const auto& [padNum, pin] : pins )
746 {
747 if( pin )
748 return false;
749 }
750 }
751
752 return true;
753 };
754
755 auto checkFocusItems =
756 [&]( const SCH_SHEET_PATH& aSheet )
757 {
758 if( focusSymbol )
759 {
760 auto findIt = syncSymMap.find( *focusSymbol );
761
762 if( findIt != syncSymMap.end() )
763 {
764 if( findIt->second.size() > 0 )
765 focusItemResults[aSheet].push_back( findIt->second.front().GetSymbol() );
766 }
767 }
768 else if( focusPin )
769 {
770 auto findIt = syncPinMap.find( focusPin->first );
771
772 if( findIt != syncPinMap.end() )
773 {
774 if( findIt->second[focusPin->second] )
775 focusItemResults[aSheet].push_back( findIt->second[focusPin->second] );
776 }
777 }
778 };
779
780 auto makeRetForSheet =
781 [&]( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aFocusItem )
782 {
783 clearSyncMaps();
784
785 // Fill sync maps
786 findSymbolsAndPins( allSheetsList, aSheet, syncSymMap, syncPinMap );
787 std::vector<SCH_ITEM*> itemsVector = flattenSyncMaps();
788
789 // Add fully wanted sheets to vector
790 for( SCH_ITEM* item : aSheet.LastScreen()->Items().OfType( SCH_SHEET_T ) )
791 {
792 KIID_PATH kiidPath = aSheet.Path();
793 kiidPath.push_back( item->m_Uuid );
794
795 std::optional<SCH_SHEET_PATH> subsheetPath =
796 allSheetsList.GetSheetPathByKIIDPath( kiidPath );
797
798 if( !subsheetPath )
799 continue;
800
801 if( sheetContainsOnlyWantedItems( allSheetsList, *subsheetPath, syncSymMap,
802 syncPinMap, fullyWantedCache ) )
803 {
804 itemsVector.push_back( item );
805 }
806 }
807
808 return std::make_tuple( aSheet, aFocusItem, itemsVector );
809 };
810
811 if( aFocusOnFirst )
812 {
813 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
814 {
815 clearSyncMaps();
816
817 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap );
818
819 checkFocusItems( sheetPath );
820 }
821
822 if( focusItemResults.size() > 0 )
823 {
824 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
825 {
826 const std::vector<SCH_ITEM*>& items = focusItemResults[sheetPath];
827
828 if( !items.empty() )
829 return makeRetForSheet( sheetPath, items.front() );
830 }
831 }
832 }
833 else
834 {
835 for( const SCH_SHEET_PATH& sheetPath : orderedSheets )
836 {
837 clearSyncMaps();
838
839 findSymbolsAndPins( allSheetsList, sheetPath, syncSymMap, syncPinMap );
840
841 if( !syncMapsValuesEmpty() )
842 {
843 // Something found on sheet
844 return makeRetForSheet( sheetPath, nullptr );
845 }
846 }
847 }
848
849 return std::nullopt;
850}
851
852
854{
855 std::string& payload = mail.GetPayload();
856
857 switch( mail.Command() )
858 {
860 {
861 std::stringstream ss( payload );
862 std::string file;
863
866 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::SYMBOL,
868
869 wxCHECK_RET( optTable.has_value(), "Could not load symbol lib table." );
870 LIBRARY_TABLE* table = optTable.value();
871
872 wxString projectPath = Prj().GetProjectPath();
873
874 // First line of payload is the source project directory.
875 std::string srcProjDir;
876 std::getline( ss, srcProjDir, '\n' );
877
878 std::vector<wxString> toLoad;
879
880 while( std::getline( ss, file, '\n' ) )
881 {
882 if( file.empty() )
883 continue;
884
885 wxFileName fn( file );
887 SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
888
889 if( type == SCH_IO_MGR::SCH_FILE_UNKNOWN )
890 {
891 wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
892 continue;
893 }
894
895 pi.reset( SCH_IO_MGR::FindPlugin( type ) );
896
897 wxString libTableUri;
898 bool isProjectLocal = fn.GetFullPath().StartsWith( wxString( srcProjDir ) );
899
900 if( isProjectLocal )
901 {
902 // Project-local library: copy into the KiCad project directory and use a
903 // project-relative path so the sym-lib-table stays portable.
904 if( !fn.FileExists() )
905 continue;
906
907 wxFileName projectFn( projectPath, fn.GetFullName() );
908
909 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists() )
910 wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath() );
911
912 libTableUri = wxS( "${KIPRJMOD}/" ) + fn.GetFullName();
913 }
914 else
915 {
916 // External library referenced by absolute path. Preserve the original path.
917 libTableUri = fn.GetFullPath();
918 }
919
920 if( !table->HasRow( fn.GetName() ) )
921 {
922 LIBRARY_TABLE_ROW& row = table->InsertRow();
923 row.SetNickname( fn.GetName() );
924 row.SetURI( libTableUri );
925 row.SetType( SCH_IO_MGR::ShowType( type ) );
926 toLoad.emplace_back( fn.GetName() );
927 }
928 }
929
930 if( !toLoad.empty() )
931 {
932 bool success = true;
933
934 table->Save().map_error(
935 [&]( const LIBRARY_ERROR& aError )
936 {
937 wxLogError( wxT( "Error saving project library table:\n\n" ) + aError.message );
938 success = false;
939 } );
940
941 if( success )
942 {
943 manager.AbortAsyncLoads();
945
946 std::ranges::for_each( toLoad,
947 [adapter]( const wxString& aNick )
948 {
949 adapter->LoadOne( aNick );
950 } );
951 }
952 }
953
957
958 break;
959 }
960
961 case MAIL_CROSS_PROBE:
962 ExecuteRemoteCommand( payload.c_str() );
963 break;
964
965 case MAIL_SELECTION:
966 if( !eeconfig()->m_CrossProbing.on_selection )
967 break;
968
970
972 {
973 // $SELECT: 0,<spec1>,<spec2>,<spec3>
974 // Try to select specified items.
975
976 // $SELECT: 1,<spec1>,<spec2>,<spec3>
977 // Select and focus on <spec1> item, select other specified items that are on the
978 // same sheet.
979
980 std::string prefix = "$SELECT: ";
981
982 std::string paramStr = payload.substr( prefix.size() );
983
984 // Empty/broken command: we need at least 2 chars for sync string.
985 if( paramStr.size() < 2 )
986 break;
987
988 std::string syncStr = paramStr.substr( 2 );
989
990 bool focusOnFirst = ( paramStr[0] == '1' );
991
992 std::optional<std::tuple<SCH_SHEET_PATH, SCH_ITEM*, std::vector<SCH_ITEM*>>> findRet =
993 findItemsFromSyncSelection( Schematic(), syncStr, focusOnFirst );
994
995 if( findRet )
996 {
997 auto& [sheetPath, focusItem, items] = *findRet;
998
999 m_syncingPcbToSchSelection = true; // recursion guard
1000
1001 GetToolManager()->GetTool<SCH_SELECTION_TOOL>()->SyncSelection( sheetPath, focusItem,
1002 items );
1003
1005
1006 if( eeconfig()->m_CrossProbing.flash_selection )
1007 {
1008 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash enabled, items=%zu", items.size() );
1009 if( items.empty() )
1010 {
1011 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): nothing to flash" );
1012 }
1013 else
1014 {
1015 std::vector<SCH_ITEM*> itemPtrs;
1016 std::copy( items.begin(), items.end(), std::back_inserter( itemPtrs ) );
1017
1018 StartCrossProbeFlash( itemPtrs );
1019 }
1020 }
1021 else
1022 {
1023 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE): flash disabled" );
1024 }
1025 }
1026
1027 break;
1028 }
1029
1031 {
1032 if( !payload.empty() )
1033 {
1034 wxString annotationMessage( payload );
1035
1036 // Ensure schematic is OK for netlist creation (especially that it is fully annotated):
1037 if( !ReadyToNetlist( annotationMessage ) )
1038 return;
1039 }
1040
1041 if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
1043
1044 NETLIST_EXPORTER_KICAD exporter( &Schematic() );
1045 STRING_FORMATTER formatter;
1046
1047 exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
1048
1049 payload = formatter.GetString();
1050 break;
1051 }
1052
1053 case MAIL_SCH_GET_ITEM:
1054 {
1055 KIID uuid( payload );
1057
1058 if( SCH_ITEM* item = m_schematic->ResolveItem( uuid, &path, true ) )
1059 {
1060 if( item->Type() == SCH_SHEET_T )
1061 payload = static_cast<SCH_SHEET*>( item )->GetShownName( false );
1062 else if( item->Type() == SCH_SYMBOL_T )
1063 payload = static_cast<SCH_SYMBOL*>( item )->GetRef( &path, true );
1064 else
1065 payload = item->GetFriendlyName();
1066 }
1067
1068 break;
1069 }
1070
1072 try
1073 {
1074 SCH_EDITOR_CONTROL* controlTool = m_toolManager->GetTool<SCH_EDITOR_CONTROL>();
1075 controlTool->AssignFootprints( payload );
1076 }
1077 catch( const IO_ERROR& )
1078 {
1079 }
1080 break;
1081
1082 case MAIL_SCH_REFRESH:
1083 {
1085
1087 GetCanvas()->Refresh();
1088 break;
1089 }
1090
1091 case MAIL_IMPORT_FILE:
1092 {
1093 // Extract file format type and path (plugin type, path and properties keys, values
1094 // separated with \n)
1095 std::stringstream ss( payload );
1096 char delim = '\n';
1097
1098 std::string formatStr;
1099 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
1100
1101 std::string fnameStr;
1102 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
1103
1104 int importFormat;
1105
1106 try
1107 {
1108 importFormat = std::stoi( formatStr );
1109 }
1110 catch( std::invalid_argument& )
1111 {
1112 wxFAIL;
1113 importFormat = -1;
1114 }
1115
1116 std::map<std::string, UTF8> props;
1117
1118 do
1119 {
1120 std::string key, value;
1121
1122 if( !std::getline( ss, key, delim ) )
1123 break;
1124
1125 std::getline( ss, value, delim ); // We may want an empty string as value
1126
1127 props.emplace( key, value );
1128
1129 } while( true );
1130
1131 if( importFormat >= 0 )
1132 importFile( fnameStr, importFormat, props.empty() ? nullptr : &props );
1133
1134 break;
1135 }
1136
1137 case MAIL_SCH_SAVE:
1138 if( SaveProject() )
1139 payload = "success";
1140
1141 break;
1142
1143 case MAIL_SCH_UPDATE:
1145 break;
1146
1147 case MAIL_RELOAD_LIB:
1148 {
1149 if( m_designBlocksPane && m_designBlocksPane->IsShown() )
1150 {
1151 m_designBlocksPane->RefreshLibs();
1152 SyncView();
1153 }
1154
1155 // Show any symbol library load errors in the status bar
1156 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
1157 {
1159 wxString errors = adapter->GetLibraryLoadErrors();
1160
1161 if( !errors.IsEmpty() )
1162 statusBar->AddWarningMessages( "load", errors );
1163 }
1164
1165 break;
1166 }
1167
1169 {
1170 wxString targetFile( payload );
1171
1172 for( SCH_SHEET_PATH& sheetPath : m_schematic->Hierarchy() )
1173 {
1174 SCH_SCREEN* screen = sheetPath.LastScreen();
1175
1176 if( screen && screen->GetFileName() == targetFile )
1177 {
1178 m_toolManager->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet, &sheetPath );
1179 payload = "success";
1180 Raise();
1181 return;
1182 }
1183 }
1184
1185 payload.clear();
1186 break;
1187 }
1188
1189 default:;
1190
1191 }
1192}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
static TOOL_ACTION showSymbolLibTable
Definition actions.h:282
static TOOL_ACTION updateSchematicFromPcb
Definition actions.h:265
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:100
const KIID m_Uuid
Definition eda_item.h:528
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:225
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:1685
Definition kiid.h:48
wxString AsString() const
Definition kiid.cpp:244
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:38
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:56
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:48
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:500
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)
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:132
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:187
Holds all the data relating to one schematic.
Definition schematic.h:89
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:188
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:126
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:168
int GetUnit() const
Definition sch_item.h:239
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
wxString GetRefNumber() const
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:119
const wxString & GetFileName() const
Definition sch_screen.h:154
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:48
Schematic symbol object.
Definition sch_symbol.h:76
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
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:422
const std::string & GetString()
Definition richio.h:445
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:63
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:230
DDE server & client.
#define MSG_TO_PCB
Definition eda_dde.h:49
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, 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:42
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
@ FRAME_SCH_VIEWER
Definition frame_type.h:36
@ FRAME_CVPCB
Definition frame_type.h:52
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:655
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition macros.h:83
@ MAIL_IMPORT_FILE
Definition mail_type.h:48
@ MAIL_SCH_REFRESH
Definition mail_type.h:53
@ MAIL_CROSS_PROBE
Definition mail_type.h:39
@ MAIL_SELECTION_FORCE
Definition mail_type.h:41
@ MAIL_SCH_SAVE
Definition mail_type.h:43
@ MAIL_ASSIGN_FOOTPRINTS
Definition mail_type.h:42
@ MAIL_SCH_GET_ITEM
Definition mail_type.h:50
@ MAIL_SCH_UPDATE
Definition mail_type.h:47
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:54
@ MAIL_SCH_NAVIGATE_TO_SHEET
Definition mail_type.h:60
@ MAIL_SCH_GET_NETLIST
Definition mail_type.h:49
@ MAIL_SELECTION
Definition mail_type.h:40
@ MAIL_RELOAD_LIB
Definition mail_type.h:57
@ ALL
All except INITIAL_ADD.
Definition view_item.h:59
#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:78
KIWAY Kiway(KFCTL_STANDALONE)
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:173
@ SCH_SHEET_T
Definition typeinfo.h:176
@ SCH_PIN_T
Definition typeinfo.h:154