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