KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20
29
30#include <wx/tokenzr.h>
31#include <board.h>
33#include <fmt.h>
34#include <footprint.h>
35#include <pad.h>
36#include <pcb_track.h>
37#include <pcb_group.h>
38#include <zone.h>
39#include <collectors.h>
40#include <eda_dde.h>
41#include <kiface_base.h>
42#include <kiway_mail.h>
43#include <string_utils.h>
46#include <gal/painter.h>
47#include <pcb_painter.h>
48#include <pcb_edit_frame.h>
49#include <pcbnew_settings.h>
50#include <render_settings.h>
51#include <richio.h>
52#include <tool/tool_manager.h>
53#include <tools/pcb_actions.h>
55#include <trace_helpers.h>
58#include <widgets/kistatusbar.h>
59#include <project_pcb.h>
61#include <pcb_io/pcb_io_mgr.h>
62#include <pgm_base.h>
65#include <wx/filename.h>
66#include <wx/log.h>
67
68/* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER
69 *
70 * Commands are:
71 *
72 * $NET: "net name" Highlight the given net
73 * $NETS: "net name 1,net name 2" Highlight all given nets
74 * $CLEAR Clear existing highlight
75 *
76 * $CONFIG Show the Manage Footprint Libraries dialog
77 * $CUSTOM_RULES Show the "Custom Rules" page of the Board Setup dialog
78 * $DRC Show the DRC dialog
79 */
80void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
81{
82 char line[1024];
83 char* idcmd;
84 char* text;
85 int netcode = -1;
86 bool multiHighlight = false;
87 BOARD* pcb = GetBoard();
88
90
91 KIGFX::VIEW* view = m_toolManager->GetView();
92 KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
93
94 strncpy( line, cmdline, sizeof(line) - 1 );
95 line[sizeof(line) - 1] = 0;
96
97 idcmd = strtok( line, " \n\r" );
98 text = strtok( nullptr, "\"\n\r" );
99
100 if( idcmd == nullptr )
101 return;
102
103 if( strcmp( idcmd, "$CONFIG" ) == 0 )
104 {
106 return;
107 }
108 else if( strcmp( idcmd, "$CUSTOM_RULES" ) == 0 )
109 {
110 ShowBoardSetupDialog( _( "Custom Rules" ) );
111 return;
112 }
113 else if( strcmp( idcmd, "$DRC" ) == 0 )
114 {
116 return;
117 }
118 else if( strcmp( idcmd, "$CLEAR" ) == 0 )
119 {
120 auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
121
122 bool hadHighlight = renderSettings->IsHighlightEnabled();
123 bool hadChain = pcbRender && !pcbRender->GetHighlightedNetChain().IsEmpty();
124
125 if( hadHighlight )
126 renderSettings->SetHighlight( false );
127
128 if( hadChain )
129 pcbRender->SetHighlightedNetChain( wxString() );
130
131 if( hadHighlight || hadChain )
132 view->UpdateAllLayersColor();
133
134 if( pcb->IsHighLightNetON() )
135 {
136 pcb->ResetNetHighLight();
137 SetMsgPanel( pcb );
138 }
139
140 GetCanvas()->Refresh();
141 return;
142 }
143 else if( strcmp( idcmd, "$NET:" ) == 0 )
144 {
145 if( !crossProbingSettings.auto_highlight )
146 return;
147
148 wxString net_name = From_UTF8( text );
149
150 NETINFO_ITEM* netinfo = pcb->FindNet( net_name );
151
152 if( netinfo )
153 {
154 netcode = netinfo->GetNetCode();
155
156 std::vector<MSG_PANEL_ITEM> items;
157 netinfo->GetMsgPanelInfo( this, items );
158 SetMsgPanel( items );
159
160 // If the incoming net belongs to a net chain, promote the single-net
161 // highlight into a multi-net highlight covering every chain member so
162 // the PCB mirrors the chain highlight happening on the schematic side.
163 const wxString& chainName = netinfo->GetNetChain();
164
165 if( !chainName.IsEmpty() )
166 {
167 pcb->SetHighLightNet( netcode );
168 renderSettings->SetHighlight( true, netcode );
169 multiHighlight = true;
170
171 for( NETINFO_ITEM* candidate : pcb->GetNetInfo() )
172 {
173 if( !candidate || candidate == netinfo )
174 continue;
175
176 if( candidate->GetNetChain() == chainName )
177 {
178 pcb->SetHighLightNet( candidate->GetNetCode(), true );
179 renderSettings->SetHighlight( true, candidate->GetNetCode(), true );
180 }
181 }
182
183 if( auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings ) )
184 pcbRender->SetHighlightedNetChain( chainName );
185
186 netcode = -1;
187 }
188 }
189
190 // fall through to highlighting section
191 }
192 else if( strcmp( idcmd, "$NETS:" ) == 0 )
193 {
194 if( !crossProbingSettings.auto_highlight )
195 return;
196
197 wxStringTokenizer netsTok = wxStringTokenizer( From_UTF8( text ), ",", wxTOKEN_STRTOK );
198 bool first = true;
199
200 while( netsTok.HasMoreTokens() )
201 {
202 NETINFO_ITEM* netinfo = pcb->FindNet( netsTok.GetNextToken().Trim( true ).Trim( false ) );
203
204 if( netinfo )
205 {
206 if( first )
207 {
208 // TODO: Once buses are included in netlist, show bus name
209 std::vector<MSG_PANEL_ITEM> items;
210 netinfo->GetMsgPanelInfo( this, items );
211 SetMsgPanel( items );
212 first = false;
213
214 pcb->SetHighLightNet( netinfo->GetNetCode() );
215 renderSettings->SetHighlight( true, netinfo->GetNetCode() );
216 multiHighlight = true;
217 }
218 else
219 {
220 pcb->SetHighLightNet( netinfo->GetNetCode(), true );
221 renderSettings->SetHighlight( true, netinfo->GetNetCode(), true );
222 }
223 }
224 }
225
226 netcode = -1;
227
228 // fall through to highlighting section
229 }
230
231 BOX2I bbox;
232
233 if( netcode > 0 || multiHighlight )
234 {
235 if( !multiHighlight )
236 {
237 renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
238 pcb->SetHighLightNet( netcode );
239 }
240 else
241 {
242 // Just pick the first one for area calculation
243 netcode = *pcb->GetHighLightNetCodes().begin();
244 }
245
246 pcb->HighLightON();
247
248 auto merge_area =
249 [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
250 {
251 if( aItem->GetNetCode() == netcode )
252 bbox.Merge( aItem->GetBoundingBox() );
253 };
254
255 if( crossProbingSettings.center_on_items )
256 {
257 for( ZONE* zone : pcb->Zones() )
258 merge_area( zone );
259
260 for( PCB_TRACK* track : pcb->Tracks() )
261 merge_area( track );
262
263 for( FOOTPRINT* fp : pcb->Footprints() )
264 {
265 for( PAD* p : fp->Pads() )
266 merge_area( p );
267 }
268 }
269 }
270 else
271 {
272 renderSettings->SetHighlight( false );
273 }
274
275 if( crossProbingSettings.center_on_items && bbox.GetWidth() != 0 && bbox.GetHeight() != 0 )
276 {
277 if( crossProbingSettings.zoom_to_fit )
278 GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
279
280 FocusOnLocation( bbox.Centre() );
281 }
282
283 view->UpdateAllLayersColor();
284
285 // Ensure the display is refreshed, because in some installs the refresh is done only
286 // when the gal canvas has the focus, and that is not the case when crossprobing from
287 // Eeschema:
288 GetCanvas()->Refresh();
289}
290
291
292std::string FormatProbeItem( BOARD_ITEM* aItem )
293{
294 if( !aItem )
295 return "$CLEAR: \"HIGHLIGHTED\""; // message to clear highlight state
296
297 switch( aItem->Type() )
298 {
299 case PCB_FOOTPRINT_T:
300 {
301 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem );
302 return fmt::format( "$PART: \"{}\"", TO_UTF8( footprint->GetReference() ) );
303 }
304
305 case PCB_PAD_T:
306 {
307 PAD* pad = static_cast<PAD*>( aItem );
308 FOOTPRINT* footprint = pad->GetParentFootprint();
309
310 return fmt::format( "$PART: \"{}\" $PAD: \"{}\"",
311 TO_UTF8( footprint->GetReference() ),
312 TO_UTF8( pad->GetNumber() ) );
313 }
314
315 case PCB_FIELD_T:
316 {
317 PCB_FIELD* field = static_cast<PCB_FIELD*>( aItem );
318 FOOTPRINT* footprint = field->GetParentFootprint();
319 const char* text_key;
320
321 /* This can't be a switch since the break need to pull out
322 * from the outer switch! */
323 if( field->IsReference() )
324 text_key = "$REF:";
325 else if( field->IsValue() )
326 text_key = "$VAL:";
327 else
328 break;
329
330 return fmt::format( "$PART: \"{}\" {} \"{}\"",
331 TO_UTF8( footprint->GetReference() ),
332 text_key,
333 TO_UTF8( field->GetText() ) );
334 }
335
336 default:
337 break;
338 }
339
340 return "";
341}
342
343
344template <typename ItemContainer>
345void collectItemsForSyncParts( ItemContainer& aItems, std::set<wxString>& parts )
346{
347 for( EDA_ITEM* item : aItems )
348 {
349 switch( item->Type() )
350 {
351 case PCB_GROUP_T:
352 {
353 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
354
355 collectItemsForSyncParts( group->GetItems(), parts );
356 break;
357 }
358 case PCB_FOOTPRINT_T:
359 {
360 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
361 wxString ref = footprint->GetReference();
362
363 parts.emplace( wxT( "F" ) + EscapeString( ref, CTX_IPC ) );
364 break;
365 }
366
367 case PCB_PAD_T:
368 {
369 PAD* pad = static_cast<PAD*>( item );
370 wxString ref = pad->GetParentFootprint()->GetReference();
371
372 parts.emplace( wxT( "P" ) + EscapeString( ref, CTX_IPC ) + wxT( "/" )
373 + EscapeString( pad->GetNumber(), CTX_IPC ) );
374 break;
375 }
376
377 default: break;
378 }
379 }
380}
381
382
383void PCB_EDIT_FRAME::SendSelectItemsToSch( const std::deque<EDA_ITEM*>& aItems,
384 EDA_ITEM* aFocusItem, bool aForce )
385{
386 std::string command = "$SELECT: ";
387
388 if( aFocusItem )
389 {
390 std::deque<EDA_ITEM*> focusItems = { aFocusItem };
391 std::set<wxString> focusParts;
392 collectItemsForSyncParts( focusItems, focusParts );
393
394 if( focusParts.size() > 0 )
395 {
396 command += "1,";
397 command += *focusParts.begin();
398 command += ",";
399 }
400 else
401 {
402 command += "0,";
403 }
404 }
405 else
406 {
407 command += "0,";
408 }
409
410 std::set<wxString> parts;
411 collectItemsForSyncParts( aItems, parts );
412
413 if( parts.empty() )
414 return;
415
416 for( wxString part : parts )
417 {
418 command += part;
419 command += ",";
420 }
421
422 command.pop_back();
423
424 if( Kiface().IsSingle() )
425 {
426 SendCommand( MSG_TO_SCH, command );
427 }
428 else
429 {
430 // Typically ExpressMail is going to be s-expression packets, but since
431 // we have existing interpreter of the selection packet on the other
432 // side in place, we use that here.
434 this );
435 }
436}
437
438
439void PCB_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
440{
441 std::string packet = fmt::format( "$NET: \"{}\"", TO_UTF8( aNetName ) );
442
443 if( !packet.empty() )
444 {
445 if( Kiface().IsSingle() )
446 {
447 SendCommand( MSG_TO_SCH, packet );
448 }
449 else
450 {
451 // Typically ExpressMail is going to be s-expression packets, but since
452 // we have existing interpreter of the cross probe packet on the other
453 // side in place, we use that here.
454 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this );
455 }
456 }
457}
458
459
461{
462 std::string packet = FormatProbeItem( aSyncItem );
463
464 if( !packet.empty() )
465 {
466 if( Kiface().IsSingle() )
467 {
468 SendCommand( MSG_TO_SCH, packet );
469 }
470 else
471 {
472 // Typically ExpressMail is going to be s-expression packets, but since
473 // we have existing interpreter of the cross probe packet on the other
474 // side in place, we use that here.
475 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this );
476 }
477 }
478}
479
480
481std::vector<BOARD_ITEM*> PCB_EDIT_FRAME::FindItemsFromSyncSelection( std::string syncStr )
482{
483 wxArrayString syncArray = wxStringTokenize( syncStr, "," );
484
485 std::vector<std::pair<int, BOARD_ITEM*>> orderPairs;
486
487 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
488 {
489 if( footprint == nullptr )
490 continue;
491
492 wxString fpSheetPath = footprint->GetPath().AsString().BeforeLast( '/' );
493 wxString fpUUID = footprint->m_Uuid.AsString();
494
495 if( fpSheetPath.IsEmpty() )
496 fpSheetPath += '/';
497
498 if( fpUUID.empty() )
499 continue;
500
501 wxString fpRefEscaped = EscapeString( footprint->GetReference(), CTX_IPC );
502
503 for( unsigned index = 0; index < syncArray.size(); ++index )
504 {
505 wxString syncEntry = syncArray[index];
506
507 if( syncEntry.empty() )
508 continue;
509
510 wxString syncData = syncEntry.substr( 1 );
511
512 switch( syncEntry.GetChar( 0 ).GetValue() )
513 {
514 case 'S': // Select sheet with subsheets: S<Sheet path>
515 if( fpSheetPath.StartsWith( syncData ) )
516 {
517 orderPairs.emplace_back( index, footprint );
518 }
519 break;
520 case 'F': // Select footprint: F<Reference>
521 if( syncData == fpRefEscaped )
522 {
523 orderPairs.emplace_back( index, footprint );
524 }
525 break;
526 case 'P': // Select pad: P<Footprint reference>/<Pad number>
527 {
528 if( syncData.StartsWith( fpRefEscaped ) )
529 {
530 wxString selectPadNumberEscaped =
531 syncData.substr( fpRefEscaped.size() + 1 ); // Skips the slash
532
533 wxString selectPadNumber = UnescapeString( selectPadNumberEscaped );
534
535 for( PAD* pad : footprint->Pads() )
536 {
537 if( selectPadNumber == pad->GetNumber() )
538 {
539 orderPairs.emplace_back( index, pad );
540 }
541 }
542 }
543 break;
544 }
545 default: break;
546 }
547 }
548 }
549
550 std::sort(
551 orderPairs.begin(), orderPairs.end(),
552 []( const std::pair<int, BOARD_ITEM*>& a, const std::pair<int, BOARD_ITEM*>& b ) -> bool
553 {
554 return a.first < b.first;
555 } );
556
557 std::vector<BOARD_ITEM*> items;
558 items.reserve( orderPairs.size() );
559
560 for( const std::pair<int, BOARD_ITEM*>& pair : orderPairs )
561 items.push_back( pair.second );
562
563 return items;
564}
565
566
568{
569 std::string& payload = mail.GetPayload();
570
571 switch( mail.Command() )
572 {
574 {
577
578 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
579 {
580 if( footprint->GetAttributes() & FP_BOARD_ONLY )
581 continue; // Don't add board-only footprints to the netlist
582
583 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
584 footprint->GetValue(), footprint->GetPath(), {} );
585
586 for( PAD* pad : footprint->Pads() )
587 {
588 const wxString& netname = pad->GetShortNetname();
589
590 if( !netname.IsEmpty() )
591 {
592 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(),
593 pad->GetPinType() );
594 }
595 }
596
597 nlohmann::ordered_map<wxString, wxString> fields;
598
599 for( PCB_FIELD* field : footprint->GetFields() )
600 {
601 wxCHECK2( field, continue );
602
603 fields[field->GetCanonicalName()] = field->GetText();
604 }
605
606 component->SetFields( fields );
607
608 // Add DNP, Exclude from BOM, and Exclude from Position Files properties
609 std::map<wxString, wxString> properties;
610
611 if( footprint->GetAttributes() & FP_DNP )
612 properties.emplace( "dnp", "" );
613
614 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_BOM )
615 properties.emplace( "exclude_from_bom", "" );
616
617 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES )
618 properties.emplace( "exclude_from_pos_files", "" );
619
620 component->SetProperties( properties );
621
622 netlist.AddComponent( component );
623 }
624
625 netlist.Format( "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS );
626 payload = sf.GetString();
627 break;
628 }
629
631 try
632 {
634 FetchNetlistFromSchematic( netlist, wxEmptyString );
635
636 BOARD_NETLIST_UPDATER updater( this, GetBoard() );
637 updater.SetLookupByTimestamp( false );
638 updater.SetDeleteUnusedFootprints( false );
639 updater.SetReplaceFootprints( false );
640 updater.SetTransferGroups( false );
641 updater.UpdateNetlist( netlist );
642
643 bool dummy;
644 OnNetlistChanged( updater, &dummy );
645 }
646 catch( const IO_ERROR& )
647 {
648 assert( false ); // should never happen
649 return;
650 }
651
652 break;
653
655 {
656 std::stringstream ss( payload );
657 std::string file;
658
661 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::FOOTPRINT,
663
664 wxCHECK_RET( optTable.has_value(), "Could not load footprint lib table." );
665 LIBRARY_TABLE* table = optTable.value();
666
667 wxString projectPath = Prj().GetProjectPath();
668
669 // First line of payload is the source project directory.
670 std::string srcProjDir;
671 std::getline( ss, srcProjDir, '\n' );
672
673 wxString srcProjectPath = wxString::FromUTF8( srcProjDir );
674 std::vector<wxString> toLoad;
675
676 while( std::getline( ss, file, '\n' ) )
677 {
678 if( file.empty() )
679 continue;
680
681 wxFileName fn( wxString::FromUTF8( file ) );
683
684 if( type == PCB_IO_MGR::FILE_TYPE_NONE )
685 {
686 wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
687 continue;
688 }
689
690 // Only libraries that live under the source project are relocated; a plain path
691 // prefix would also match a sibling directory sharing the project name's stem.
692 wxFileName relFn( fn );
693 bool isProjectLocal =
694 !srcProjectPath.IsEmpty() && relFn.MakeRelativeTo( srcProjectPath )
695 && !relFn.IsAbsolute()
696 && !relFn.GetFullPath().StartsWith( wxS( ".." ) );
697
698 wxString libTableUri;
699
700 if( isProjectLocal )
701 {
702 // Copy a project-local library into the KiCad project directory and reference it
703 // with a project-relative path so the fp-lib-table stays portable.
704 if( !fn.FileExists() )
705 continue;
706
707 wxFileName projectFn( projectPath, fn.GetFullName() );
708
709 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists()
710 && !wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath(), false ) )
711 {
712 wxLogError( _( "Error copying footprint library '%s'." ), fn.GetFullPath() );
713 continue;
714 }
715
716 libTableUri = wxS( "${KIPRJMOD}/" ) + fn.GetFullName();
717 }
718 else
719 {
720 // External library referenced by absolute path. Preserve the original path.
721 libTableUri = fn.GetFullPath();
722 }
723
724 if( !table->HasRow( fn.GetName() ) )
725 {
726 LIBRARY_TABLE_ROW& row = table->InsertRow();
727 row.SetNickname( fn.GetName() );
728 row.SetURI( libTableUri );
729 row.SetType( PCB_IO_MGR::ShowType( type ) );
730 toLoad.emplace_back( fn.GetName() );
731 }
732 }
733
734 if( !toLoad.empty() )
735 {
736 bool success = true;
737
738 table->Save().map_error(
739 [&]( const LIBRARY_ERROR& aError )
740 {
741 wxLogError( wxT( "Error saving project library table:\n\n" ) + aError.message );
742 success = false;
743 } );
744
745 if( success )
746 {
747 manager.AbortAsyncLoads();
749
750 for( const wxString& nick : toLoad )
751 adapter->LoadOne( nick );
752 }
753 }
754
758
759 break;
760 }
761
762 case MAIL_CROSS_PROBE:
763 ExecuteRemoteCommand( payload.c_str() );
764 break;
765
766
767 case MAIL_SELECTION:
768 if( !GetPcbNewSettings()->m_CrossProbing.on_selection )
769 break;
770
772
774 {
775 // $SELECT: <mode 0 - only footprints, 1 - with connections>,<spec1>,<spec2>,<spec3>
776 std::string prefix = "$SELECT: ";
777
778 if( !payload.compare( 0, prefix.size(), prefix ) )
779 {
780 std::string del = ",";
781 std::string paramStr = payload.substr( prefix.size() );
782 size_t modeEnd = paramStr.find( del );
783 bool selectConnections = false;
784
785 try
786 {
787 if( std::stoi( paramStr.substr( 0, modeEnd ) ) == 1 )
788 selectConnections = true;
789 }
790 catch( std::invalid_argument& )
791 {
792 wxFAIL;
793 }
794
795 std::vector<BOARD_ITEM*> items =
796 FindItemsFromSyncSelection( paramStr.substr( modeEnd + 1 ) );
797
798 m_ProbingSchToPcb = true; // recursion guard
799
800 if( selectConnections )
802 else
804
805 // Update 3D viewer highlighting
806 Update3DView( false, GetPcbNewSettings()->m_Display.m_Live3DRefresh );
807
808 m_ProbingSchToPcb = false;
809
810 if( GetPcbNewSettings()->m_CrossProbing.flash_selection )
811 {
812 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE) PCB: flash enabled, items=%zu", items.size() );
813 if( items.empty() )
814 {
815 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE) PCB: nothing to flash" );
816 }
817 else
818 {
819 std::vector<BOARD_ITEM*> boardItems;
820 std::copy( items.begin(), items.end(), std::back_inserter( boardItems ) );
821 StartCrossProbeFlash( boardItems );
822 }
823 }
824 else
825 {
826 wxLogTrace( traceCrossProbeFlash, "MAIL_SELECTION(_FORCE) PCB: flash disabled" );
827 }
828 }
829
830 break;
831 }
832
833 case MAIL_PCB_UPDATE:
835 break;
836
837 case MAIL_IMPORT_FILE:
838 {
839 // Extract file format type and path (plugin type, path and properties keys, values separated with \n)
840 std::stringstream ss( payload );
841 char delim = '\n';
842
843 std::string formatStr;
844 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
845
846 std::string fnameStr;
847 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
848 wxASSERT( !fnameStr.empty() );
849
850 int importFormat;
851
852 try
853 {
854 importFormat = std::stoi( formatStr );
855 }
856 catch( std::invalid_argument& )
857 {
858 wxFAIL;
859 importFormat = -1;
860 }
861
862 std::map<std::string, UTF8> props;
863
864 std::string key, value;
865 do
866 {
867 if( !std::getline( ss, key, delim ) )
868 break;
869
870 if( !std::getline( ss, value, delim ) )
871 break;
872
873 props.emplace( key, value );
874
875 } while( true );
876
877 if( importFormat >= 0 )
878 importFile( fnameStr, importFormat, props.empty() ? nullptr : &props );
879
880 break;
881 }
882
885 break;
886
887 case MAIL_PCB_SAVE:
888 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
889 payload = "success";
890
891 break;
892
893 case MAIL_RELOAD_LIB:
894 {
895 m_designBlocksPane->RefreshLibs();
896
897 // Show any footprint library load errors in the status bar
898 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
899 {
901 wxString errors = adapter->GetLibraryLoadErrors();
902
903 if( !errors.IsEmpty() )
904 statusBar->AddWarningMessages( "load", errors );
905 }
906
907 break;
908 }
909
910 // many many others.
911 default:
912 ;
913 }
914}
915
int index
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
static TOOL_ACTION updatePcbFromSchematic
Definition actions.h:260
static TOOL_ACTION pluginsReload
Definition actions.h:290
static TOOL_ACTION showFootprintLibTable
Definition actions.h:279
CROSS_PROBING_SETTINGS m_CrossProbing
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:81
FOOTPRINT * GetParentFootprint() const
Update the BOARD with a new netlist.
bool UpdateNetlist(NETLIST &aNetlist)
Update the board's components according to the new netlist.
void SetDeleteUnusedFootprints(bool aEnabled)
void SetReplaceFootprints(bool aEnabled)
void SetLookupByTimestamp(bool aEnabled)
void SetTransferGroups(bool aEnabled)
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
const NETINFO_LIST & GetNetInfo() const
Definition board.h:1094
const std::set< int > & GetHighLightNetCodes() const
Definition board.h:718
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition board.cpp:3663
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:2708
const ZONES & Zones() const
Definition board.h:425
void ResetNetHighLight()
Reset all high light data to the init state.
Definition board.cpp:3654
const FOOTPRINTS & Footprints() const
Definition board.h:421
const TRACKS & Tracks() const
Definition board.h:419
bool IsHighLightNetON() const
Definition board.h:734
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition board.cpp:3678
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr Vec Centre() const
Definition box2.h:93
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:654
constexpr size_type GetHeight() const
Definition box2.h:211
Store all of the related component information found in a netlist.
void SetProperties(std::map< wxString, wxString > aProps)
void AddNet(const wxString &aPinName, const wxString &aNetName, const wxString &aPinFunction, const wxString &aPinType)
void SetFields(nlohmann::ordered_map< wxString, wxString > aFields)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void FocusOnLocation(const VECTOR2I &aPos, bool aAllowScroll=true)
Useful to focus on a particular location, in find functions.
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
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:110
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.
const wxString & GetReference() const
Definition footprint.h:841
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition pcb_painter.h:78
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
bool IsHighlightEnabled() const
Return current highlight setting.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition view.cpp:844
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:225
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)
Handle the data for a net.
Definition netinfo.h:46
const wxString & GetNetChain() const
Definition netinfo.h:112
int GetNetCode() const
Definition netinfo.h:94
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Return the information about the NETINFO_ITEM in aList to display in the message panel.
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
Definition pad.h:61
static TOOL_ACTION runDRC
static TOOL_ACTION syncSelection
Sets selection to specified items, zooms to fit, if enabled.
Definition pcb_actions.h:59
static TOOL_ACTION syncSelectionWithNets
Sets selection to specified items with connected nets, zooms to fit, if enabled.
Definition pcb_actions.h:62
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
void StartCrossProbeFlash(const std::vector< BOARD_ITEM * > &aItems)
void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent) override
Receive #KIWAY_ROUTED_EVENT messages from other players.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString, wxWindow *aParent=nullptr)
void OnNetlistChanged(BOARD_NETLIST_UPDATER &aUpdater, bool *aRunDragCommand)
Called after netlist is updated.
void ExecuteRemoteCommand(const char *cmdline) override
Execute a remote command send by Eeschema via a socket, port KICAD_PCB_PORT_SERVICE_NUMBER (currently...
void SendCrossProbeItem(BOARD_ITEM *aSyncItem)
Send a message to the schematic editor so that it may move its cursor to an item with the same refere...
bool FetchNetlistFromSchematic(NETLIST &aNetlist, const wxString &aAnnotateMessage)
void SendSelectItemsToSch(const std::deque< EDA_ITEM * > &aItems, EDA_ITEM *aFocusItem, bool aForce)
Send a message to the schematic editor to try to find schematic counterparts of specified PCB items a...
std::vector< BOARD_ITEM * > FindItemsFromSyncSelection(std::string syncStr)
Used to find items by selection synchronization spec string.
PCB_DESIGN_BLOCK_PANE * m_designBlocksPane
bool SavePcbFile(const wxString &aFileName, bool addToHistory=true, bool aChangeProject=true)
Write the board data structures to a aFileName.
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 Eeschema for highlighting.
bool IsReference() const
Definition pcb_field.h:66
bool IsValue() const
Definition pcb_field.h:67
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:49
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:52
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a footprint library's libPath.
static const wxString ShowType(PCB_FILE_T aFileType)
Return a brief name for a plugin given aFileType enum.
The selection tool: currently supports:
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:126
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition project.cpp:183
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:418
const std::string & GetString()
Definition richio.h:441
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.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
#define CTL_OMIT_FILTERS
Omit the ki_fp_filters attribute in .kicad_xxx files.
Definition ctl_flags.h:41
#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_SCH
Definition eda_dde.h:46
@ FP_DNP
Definition footprint.h:89
@ FP_EXCLUDE_FROM_POS_FILES
Definition footprint.h:85
@ FP_BOARD_ONLY
Definition footprint.h:87
@ FP_EXCLUDE_FROM_BOM
Definition footprint.h:86
@ FRAME_FOOTPRINT_VIEWER
Definition frame_type.h:41
@ FRAME_SCH
Definition frame_type.h:30
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
@ FRAME_CVPCB
Definition frame_type.h:48
const wxChar *const traceCrossProbeFlash
Flag to enable debug output for cross-probe flash operations.
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_PCB_UPDATE_LINKS
Definition mail_type.h:49
@ MAIL_IMPORT_FILE
Definition mail_type.h:45
@ MAIL_CROSS_PROBE
Definition mail_type.h:35
@ MAIL_PCB_UPDATE
Definition mail_type.h:43
@ MAIL_SELECTION_FORCE
Definition mail_type.h:37
@ MAIL_RELOAD_PLUGINS
Definition mail_type.h:55
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:51
@ MAIL_PCB_SAVE
Definition mail_type.h:40
@ MAIL_SELECTION
Definition mail_type.h:36
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
@ MAIL_PCB_GET_NETLIST
Definition mail_type.h:48
Class to handle a set of BOARD_ITEMs.
void collectItemsForSyncParts(ItemContainer &aItems, std::set< wxString > &parts)
std::string FormatProbeItem(BOARD_ITEM *aItem)
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
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 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
std::string netlist
std::vector< std::vector< std::string > > table
wxLogTrace helper definitions.
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:104
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:83
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:79
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:80