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 <api/api_handler_pcb.h>
31#include <wx/tokenzr.h>
32#include <api/api_utils.h>
33#include <api/common/commands/cross_probe_commands.pb.h>
35#include <board.h>
37#include <fmt.h>
38#include <footprint.h>
39#include <pad.h>
40#include <pcb_track.h>
41#include <pcb_group.h>
42#include <zone.h>
43#include <collectors.h>
44#include <kiface_base.h>
45#include <kiway_mail.h>
46#include <string_utils.h>
49#include <gal/painter.h>
50#include <pcb_painter.h>
51#include <pcb_edit_frame.h>
52#include <pcbnew_settings.h>
53#include <render_settings.h>
54#include <richio.h>
55#include <tool/tool_manager.h>
56#include <tools/pcb_actions.h>
58#include <trace_helpers.h>
61#include <widgets/kistatusbar.h>
62#include <project_pcb.h>
64#include <pcb_io/pcb_io_mgr.h>
65#include <pgm_base.h>
68#include <wx/filename.h>
69#include <wx/log.h>
70
71
72using namespace kiapi::common::commands;
73
74/* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER
75 *
76 * Commands are:
77 *
78 * $NET: "net name" Highlight the given net
79 * $NETS: "net name 1,net name 2" Highlight all given nets
80 * $CLEAR Clear existing highlight
81 *
82 * $CONFIG Show the Manage Footprint Libraries dialog
83 * $CUSTOM_RULES Show the "Custom Rules" page of the Board Setup dialog
84 * $DRC Show the DRC dialog
85 */
86void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
87{
88 char line[1024];
89 char* idcmd;
90 char* text;
91 int netcode = -1;
92 bool multiHighlight = false;
93 BOARD* pcb = GetBoard();
94
96
97 KIGFX::VIEW* view = m_toolManager->GetView();
98 KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
99
100 strncpy( line, cmdline, sizeof(line) - 1 );
101 line[sizeof(line) - 1] = 0;
102
103 idcmd = strtok( line, " \n\r" );
104 text = strtok( nullptr, "\"\n\r" );
105
106 if( idcmd == nullptr )
107 return;
108
109 if( strcmp( idcmd, "$CONFIG" ) == 0 )
110 {
112 return;
113 }
114 else if( strcmp( idcmd, "$CUSTOM_RULES" ) == 0 )
115 {
116 ShowBoardSetupDialog( _( "Custom Rules" ) );
117 return;
118 }
119 else if( strcmp( idcmd, "$DRC" ) == 0 )
120 {
122 return;
123 }
124 else if( strcmp( idcmd, "$CLEAR" ) == 0 )
125 {
126 auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
127
128 bool hadHighlight = renderSettings->IsHighlightEnabled();
129 bool hadChain = pcbRender && !pcbRender->GetHighlightedNetChain().IsEmpty();
130
131 if( hadHighlight )
132 renderSettings->SetHighlight( false );
133
134 if( hadChain )
135 pcbRender->SetHighlightedNetChain( wxString() );
136
137 if( hadHighlight || hadChain )
138 view->UpdateAllLayersColor();
139
140 if( pcb->IsHighLightNetON() )
141 {
142 pcb->ResetNetHighLight();
143 SetMsgPanel( pcb );
144 }
145
146 GetCanvas()->Refresh();
147 return;
148 }
149 else if( strcmp( idcmd, "$NET:" ) == 0 )
150 {
151 if( !crossProbingSettings.auto_highlight )
152 return;
153
154 wxString net_name = From_UTF8( text );
155
156 NETINFO_ITEM* netinfo = pcb->FindNet( net_name );
157
158 if( netinfo )
159 {
160 netcode = netinfo->GetNetCode();
161
162 std::vector<MSG_PANEL_ITEM> items;
163 netinfo->GetMsgPanelInfo( this, items );
164 SetMsgPanel( items );
165
166 // If the incoming net belongs to a net chain, promote the single-net
167 // highlight into a multi-net highlight covering every chain member so
168 // the PCB mirrors the chain highlight happening on the schematic side.
169 const wxString& chainName = netinfo->GetNetChain();
170
171 if( !chainName.IsEmpty() )
172 {
173 pcb->SetHighLightNet( netcode );
174 renderSettings->SetHighlight( true, netcode );
175 multiHighlight = true;
176
177 for( NETINFO_ITEM* candidate : pcb->GetNetInfo() )
178 {
179 if( !candidate || candidate == netinfo )
180 continue;
181
182 if( candidate->GetNetChain() == chainName )
183 {
184 pcb->SetHighLightNet( candidate->GetNetCode(), true );
185 renderSettings->SetHighlight( true, candidate->GetNetCode(), true );
186 }
187 }
188
189 if( auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings ) )
190 pcbRender->SetHighlightedNetChain( chainName );
191
192 netcode = -1;
193 }
194 }
195
196 // fall through to highlighting section
197 }
198 else if( strcmp( idcmd, "$NETS:" ) == 0 )
199 {
200 if( !crossProbingSettings.auto_highlight )
201 return;
202
203 wxStringTokenizer netsTok = wxStringTokenizer( From_UTF8( text ), ",", wxTOKEN_STRTOK );
204 bool first = true;
205
206 while( netsTok.HasMoreTokens() )
207 {
208 NETINFO_ITEM* netinfo = pcb->FindNet( netsTok.GetNextToken().Trim( true ).Trim( false ) );
209
210 if( netinfo )
211 {
212 if( first )
213 {
214 // TODO: Once buses are included in netlist, show bus name
215 std::vector<MSG_PANEL_ITEM> items;
216 netinfo->GetMsgPanelInfo( this, items );
217 SetMsgPanel( items );
218 first = false;
219
220 pcb->SetHighLightNet( netinfo->GetNetCode() );
221 renderSettings->SetHighlight( true, netinfo->GetNetCode() );
222 multiHighlight = true;
223 }
224 else
225 {
226 pcb->SetHighLightNet( netinfo->GetNetCode(), true );
227 renderSettings->SetHighlight( true, netinfo->GetNetCode(), true );
228 }
229 }
230 }
231
232 netcode = -1;
233
234 // fall through to highlighting section
235 }
236
237 BOX2I bbox;
238
239 if( netcode > 0 || multiHighlight )
240 {
241 if( !multiHighlight )
242 {
243 renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
244 pcb->SetHighLightNet( netcode );
245 }
246 else
247 {
248 // Just pick the first one for area calculation
249 netcode = *pcb->GetHighLightNetCodes().begin();
250 }
251
252 pcb->HighLightON();
253
254 auto merge_area =
255 [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
256 {
257 if( aItem->GetNetCode() == netcode )
258 bbox.Merge( aItem->GetBoundingBox() );
259 };
260
261 if( crossProbingSettings.center_on_items )
262 {
263 for( ZONE* zone : pcb->Zones() )
264 merge_area( zone );
265
266 for( PCB_TRACK* track : pcb->Tracks() )
267 merge_area( track );
268
269 for( FOOTPRINT* fp : pcb->Footprints() )
270 {
271 for( PAD* p : fp->Pads() )
272 merge_area( p );
273 }
274 }
275 }
276 else
277 {
278 renderSettings->SetHighlight( false );
279 }
280
281 if( crossProbingSettings.center_on_items && bbox.GetWidth() != 0 && bbox.GetHeight() != 0 )
282 {
283 if( crossProbingSettings.zoom_to_fit )
284 GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
285
286 FocusOnLocation( bbox.Centre() );
287 }
288
289 view->UpdateAllLayersColor();
290
291 // Ensure the display is refreshed, because in some installs the refresh is done only
292 // when the gal canvas has the focus, and that is not the case when crossprobing from
293 // Eeschema:
294 GetCanvas()->Refresh();
295}
296
297
298void PCB_EDIT_FRAME::HandleRemoteNetHighlight( const std::vector<wxString>& aNetNames )
299{
300 NETINFO_ITEM* netinfo;
301 int netcode = -1;
302 bool multiHighlight = false;
303 BOARD* pcb = GetBoard();
304
306 KIGFX::VIEW* view = m_toolManager->GetView();
307 KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
308
309 if( aNetNames.empty() || ( aNetNames.size() == 1 && aNetNames[0].empty() ) )
310 {
311 auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
312
313 bool hadHighlight = renderSettings->IsHighlightEnabled();
314 bool hadChain = pcbRender && !pcbRender->GetHighlightedNetChain().IsEmpty();
315
316 if( hadHighlight )
317 renderSettings->SetHighlight( false );
318
319 if( hadChain )
320 pcbRender->SetHighlightedNetChain( wxString() );
321
322 if( hadHighlight || hadChain )
323 view->UpdateAllLayersColor();
324
325 if( pcb->IsHighLightNetON() )
326 {
327 pcb->ResetNetHighLight();
328 SetMsgPanel( pcb );
329 }
330
331 GetCanvas()->Refresh();
332 return;
333 }
334
335 if( aNetNames.size() == 1 && ( netinfo = pcb->FindNet( aNetNames[0] ) ) != nullptr )
336 {
337 netcode = netinfo->GetNetCode();
338
339 std::vector<MSG_PANEL_ITEM> items;
340 netinfo->GetMsgPanelInfo( this, items );
341 SetMsgPanel( items );
342
343 // If the incoming net belongs to a net chain, promote the single-net
344 // highlight into a multi-net highlight covering every chain member so
345 // the PCB mirrors the chain highlight happening on the schematic side.
346 const wxString& chainName = netinfo->GetNetChain();
347
348 if( !chainName.IsEmpty() )
349 {
350 pcb->SetHighLightNet( netcode );
351 renderSettings->SetHighlight( true, netcode );
352 multiHighlight = true;
353
354 for( NETINFO_ITEM* candidate : pcb->GetNetInfo() )
355 {
356 if( !candidate || candidate == netinfo )
357 continue;
358
359 if( candidate->GetNetChain() == chainName )
360 {
361 pcb->SetHighLightNet( candidate->GetNetCode(), true );
362 renderSettings->SetHighlight( true, candidate->GetNetCode(), true );
363 }
364 }
365
366 if( auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings ) )
367 pcbRender->SetHighlightedNetChain( chainName );
368
369 netcode = -1;
370 }
371 }
372 else
373 {
374 bool first = true;
375
376 for( const wxString& netName : aNetNames )
377 {
378 netinfo = pcb->FindNet( netName );
379
380 if( netinfo )
381 {
382 if( first )
383 {
384 // TODO: Once buses are included in netlist, show bus name
385 std::vector<MSG_PANEL_ITEM> items;
386 netinfo->GetMsgPanelInfo( this, items );
387 SetMsgPanel( items );
388 first = false;
389
390 pcb->SetHighLightNet( netinfo->GetNetCode() );
391 renderSettings->SetHighlight( true, netinfo->GetNetCode() );
392 multiHighlight = true;
393 }
394 else
395 {
396 pcb->SetHighLightNet( netinfo->GetNetCode(), true );
397 renderSettings->SetHighlight( true, netinfo->GetNetCode(), true );
398 }
399 }
400 }
401
402 netcode = -1;
403 }
404
405 BOX2I bbox;
406
407 if( netcode > 0 || multiHighlight )
408 {
409 if( !multiHighlight )
410 {
411 renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
412 pcb->SetHighLightNet( netcode );
413 }
414 else
415 {
416 // Just pick the first one for area calculation
417 netcode = *pcb->GetHighLightNetCodes().begin();
418 }
419
420 pcb->HighLightON();
421
422 auto merge_area =
423 [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
424 {
425 if( aItem->GetNetCode() == netcode )
426 bbox.Merge( aItem->GetBoundingBox() );
427 };
428
429 if( crossProbingSettings.center_on_items )
430 {
431 for( ZONE* zone : pcb->Zones() )
432 merge_area( zone );
433
434 for( PCB_TRACK* track : pcb->Tracks() )
435 merge_area( track );
436
437 for( FOOTPRINT* fp : pcb->Footprints() )
438 {
439 for( PAD* p : fp->Pads() )
440 merge_area( p );
441 }
442 }
443 }
444 else
445 {
446 renderSettings->SetHighlight( false );
447 }
448
449 if( crossProbingSettings.center_on_items && bbox.GetWidth() != 0 && bbox.GetHeight() != 0 )
450 {
451 if( crossProbingSettings.zoom_to_fit )
452 GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
453
454 FocusOnLocation( bbox.Centre() );
455 }
456
457 view->UpdateAllLayersColor();
458
459 // Ensure the display is refreshed, because in some installs the refresh is done only
460 // when the gal canvas has the focus, and that is not the case when crossprobing from
461 // Eeschema:
462 GetCanvas()->Refresh();
463}
464
465
466static bool selectionSpecFromItem( const EDA_ITEM* aItem, SelectionSpec& aSpec )
467{
468 switch( aItem->Type() )
469 {
470 case PCB_FOOTPRINT_T:
471 {
472 const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( aItem );
473 aSpec.mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
474 return true;
475 }
476
477 case PCB_PAD_T:
478 {
479 const PAD* pad = static_cast<const PAD*>( aItem );
480
481 if( const FOOTPRINT* footprint = pad->GetParentFootprint() )
482 {
483 aSpec.mutable_pad()->set_reference( footprint->GetReference().ToUTF8() );
484 aSpec.mutable_pad()->set_number( pad->GetNumber().ToUTF8() );
485 return true;
486 }
487
488 break;
489 }
490
491 default:
492 break;
493 }
494
495 return false;
496}
497
498
499void PCB_EDIT_FRAME::SendSelectItemsToSch( const std::deque<EDA_ITEM*>& aItems,
500 EDA_ITEM* aFocusItem, bool aForce )
501{
502 SyncSelection sync;
503
504 if( aFocusItem )
505 {
506 SelectionSpec focusSpec;
507
508 if( selectionSpecFromItem( aFocusItem, focusSpec ) )
509 {
510 sync.set_mode( SyncSelectionMode::SSM_ITEMS_AND_NETS );
511 sync.mutable_focus_item()->CopyFrom( focusSpec );
512 sync.mutable_items()->Add()->CopyFrom( focusSpec );
513 }
514 }
515
516 std::vector<EDA_ITEM*> collectedItems;
517
518 for( EDA_ITEM* item : aItems )
519 {
520 if( item->Type() == PCB_GROUP_T )
521 {
522 static_cast<const PCB_GROUP*>( item )->RunOnChildren(
523 [&]( BOARD_ITEM* aChild )
524 {
525 if( aChild->Type() == PCB_FOOTPRINT_T || aChild->Type() == PCB_PAD_T )
526 collectedItems.push_back( aChild );
528 }
529 else if( item->Type() == PCB_FOOTPRINT_T || item->Type() == PCB_PAD_T )
530 {
531 collectedItems.push_back( item );
532 }
533 }
534
535 for( EDA_ITEM* item : collectedItems )
536 selectionSpecFromItem( item, *sync.add_items() );
537
538 if( sync.items_size() == 0 )
539 return;
540
541 sync.set_context( aForce ? SyncSelectionContext::SSC_EXPLICIT : SyncSelectionContext::SSC_IMPLICIT );
542
543 if( Kiface().IsSingle() )
544 {
546 }
547 else
548 {
549 std::string payload;
550 kiapi::common::PackKiwayApiMessage( sync, payload );
551 Kiway().ExpressMail( FRAME_SCH, MAIL_SELECTION, payload, this );
552 }
553}
554
555
556void PCB_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
557{
558 kiapi::common::commands::HighlightNets message;
559
560 message.add_net_name( aNetName.ToUTF8() );
561
562 if( Kiface().IsSingle() )
563 {
565 }
566 else
567 {
568 std::string payload;
570 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, payload, this );
571 }
572}
573
574
576{
577 if( !aSyncItem )
578 {
579 SendCrossProbeNetName( wxEmptyString );
580 return;
581 }
582
583 kiapi::common::commands::FocusOnItem message;
584 SelectionSpec* spec = message.mutable_focus_item();
585
586 switch( aSyncItem->Type() )
587 {
588 case PCB_FOOTPRINT_T:
589 {
590 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aSyncItem );
591 spec->mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
592 break;
593 }
594
595 case PCB_PAD_T:
596 {
597 PAD* pad = static_cast<PAD*>( aSyncItem );
598 FOOTPRINT* footprint = pad->GetParentFootprint();
599
600 spec->mutable_pad()->set_reference( footprint->GetReference().ToUTF8() );
601 spec->mutable_pad()->set_number( pad->GetNumber().ToUTF8() );
602 break;
603 }
604
605 case PCB_FIELD_T:
606 {
607 PCB_FIELD* field = static_cast<PCB_FIELD*>( aSyncItem );
608 FOOTPRINT* footprint = field->GetParentFootprint();
609 spec->mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
610 break;
611 }
612
613 default:
614 break;
615 }
616
617 if( Kiface().IsSingle() )
618 {
620 }
621 else
622 {
623 std::string payload;
625 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, payload, this );
626 }
627}
628
629
631{
632 if( m_lastSchematicSheetPath == aPath )
633 return;
634
636
637 wxCommandEvent event( EDA_EVT_PCB_LAST_SCH_SHEET_CHANGED, GetId() );
638 event.SetEventObject( this );
639 wxPostEvent( this, event );
640}
641
642
644{
645 std::string& payload = mail.GetPayload();
646
647 switch( mail.Command() )
648 {
650 SetLastSchematicSheetPath( KIID_PATH( wxString::FromUTF8( payload.c_str() ) ) );
651 break;
652
654 {
657
658 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
659 {
660 if( footprint->GetAttributes() & FP_BOARD_ONLY )
661 continue; // Don't add board-only footprints to the netlist
662
663 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
664 footprint->GetValue(), footprint->GetPath(), {} );
665
666 for( PAD* pad : footprint->Pads() )
667 {
668 const wxString& netname = pad->GetShortNetname();
669
670 if( !netname.IsEmpty() )
671 {
672 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(),
673 pad->GetPinType() );
674 }
675 }
676
677 nlohmann::ordered_map<wxString, wxString> fields;
678
679 for( PCB_FIELD* field : footprint->GetFields() )
680 {
681 wxCHECK2( field, continue );
682
683 fields[field->GetUntranslatedName()] = field->GetText();
684 }
685
686 component->SetFields( fields );
687
688 // Add DNP and exclusion properties
689 std::map<wxString, wxString> properties;
690
691 if( footprint->GetAttributes() & FP_DNP )
692 properties.emplace( "dnp", "" );
693
694 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_BOM )
695 properties.emplace( "exclude_from_bom", "" );
696
697 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_SIM )
698 properties.emplace( "exclude_from_sim", "" );
699
700 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES )
701 properties.emplace( "exclude_from_pos_files", "" );
702
703 component->SetProperties( properties );
704
705 netlist.AddComponent( component );
706 }
707
708 netlist.Format( "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS );
709 payload = sf.GetString();
710 break;
711 }
712
714 try
715 {
717 FetchNetlistFromSchematic( netlist, wxEmptyString );
718
719 BOARD_NETLIST_UPDATER updater( this, GetBoard() );
720 updater.SetLookupByTimestamp( false );
721 updater.SetDeleteUnusedFootprints( false );
722 updater.SetReplaceFootprints( false );
723 updater.SetTransferGroups( false );
724 updater.UpdateNetlist( netlist );
725
726 bool dummy;
727 OnNetlistChanged( updater, &dummy );
728 }
729 catch( const IO_ERROR& )
730 {
731 assert( false ); // should never happen
732 return;
733 }
734
735 break;
736
738 {
739 std::stringstream ss( payload );
740 std::string file;
741
744 std::optional<LIBRARY_TABLE*> optTable = manager.Table( LIBRARY_TABLE_TYPE::FOOTPRINT,
746
747 wxCHECK_RET( optTable.has_value(), "Could not load footprint lib table." );
748 LIBRARY_TABLE* table = optTable.value();
749
750 wxString projectPath = Prj().GetProjectPath();
751
752 // First line of payload is the source project directory.
753 std::string srcProjDir;
754 std::getline( ss, srcProjDir, '\n' );
755
756 wxString srcProjectPath = wxString::FromUTF8( srcProjDir );
757 std::vector<wxString> toLoad;
758
759 while( std::getline( ss, file, '\n' ) )
760 {
761 if( file.empty() )
762 continue;
763
764 wxFileName fn( wxString::FromUTF8( file ) );
766
767 if( type == PCB_IO_MGR::FILE_TYPE_NONE )
768 {
769 wxLogTrace( "KIWAY", "Unknown file type: %s", fn.GetFullPath() );
770 continue;
771 }
772
773 // Only libraries that live under the source project are relocated; a plain path
774 // prefix would also match a sibling directory sharing the project name's stem.
775 wxFileName relFn( fn );
776 bool isProjectLocal =
777 !srcProjectPath.IsEmpty() && relFn.MakeRelativeTo( srcProjectPath )
778 && !relFn.IsAbsolute()
779 && !relFn.GetFullPath().StartsWith( wxS( ".." ) );
780
781 wxString libTableUri;
782
783 if( isProjectLocal )
784 {
785 // Copy a project-local library into the KiCad project directory and reference it
786 // with a project-relative path so the fp-lib-table stays portable.
787 if( !fn.FileExists() )
788 continue;
789
790 wxFileName projectFn( projectPath, fn.GetFullName() );
791
792 if( fn.GetFullPath() != projectFn.GetFullPath() && !projectFn.FileExists()
793 && !wxCopyFile( fn.GetFullPath(), projectFn.GetFullPath(), false ) )
794 {
795 wxLogError( _( "Error copying footprint library '%s'." ), fn.GetFullPath() );
796 continue;
797 }
798
799 libTableUri = wxS( "${KIPRJMOD}/" ) + fn.GetFullName();
800 }
801 else
802 {
803 // External library referenced by absolute path. Preserve the original path.
804 libTableUri = fn.GetFullPath();
805 }
806
807 if( !table->HasRow( fn.GetName() ) )
808 {
809 LIBRARY_TABLE_ROW& row = table->InsertRow();
810 row.SetNickname( fn.GetName() );
811 row.SetURI( libTableUri );
812 row.SetType( PCB_IO_MGR::ShowType( type ) );
813 toLoad.emplace_back( fn.GetName() );
814 }
815 }
816
817 if( !toLoad.empty() )
818 {
819 bool success = true;
820
821 table->Save().map_error(
822 [&]( const LIBRARY_ERROR& aError )
823 {
824 wxLogError( wxT( "Error saving project library table:\n\n" ) + aError.message );
825 success = false;
826 } );
827
828 if( success )
829 {
830 manager.AbortAsyncLoads();
832
833 for( const wxString& nick : toLoad )
834 adapter->LoadOne( nick );
835 }
836 }
837
841
842 break;
843 }
844
845 // Handled as API messages
846 case MAIL_CROSS_PROBE:
847 case MAIL_SELECTION:
848 if( ApiRequest request; request.ParseFromString( payload.c_str() ) )
849 m_apiHandler->Handle( request );
850
851 break;
852
853 case MAIL_PCB_UPDATE:
855 break;
856
857 case MAIL_IMPORT_FILE:
858 {
859 // Extract file format type and path (plugin type, path and properties keys, values separated with \n)
860 std::stringstream ss( payload );
861 char delim = '\n';
862
863 std::string formatStr;
864 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
865
866 std::string fnameStr;
867 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
868 wxASSERT( !fnameStr.empty() );
869
870 int importFormat;
871
872 try
873 {
874 importFormat = std::stoi( formatStr );
875 }
876 catch( std::invalid_argument& )
877 {
878 wxFAIL;
879 importFormat = -1;
880 }
881
882 std::map<std::string, UTF8> props;
883
884 std::string key, value;
885 do
886 {
887 if( !std::getline( ss, key, delim ) )
888 break;
889
890 if( !std::getline( ss, value, delim ) )
891 break;
892
893 props.emplace( key, value );
894
895 } while( true );
896
897 if( importFormat >= 0 )
898 importFile( fnameStr, importFormat, props.empty() ? nullptr : &props );
899
900 break;
901 }
902
905 break;
906
907 case MAIL_PCB_SAVE:
908 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
909 payload = "success";
910
911 break;
912
913 case MAIL_RELOAD_LIB:
914 {
915 m_designBlocksPane->RefreshLibs();
916
917 // Show any footprint library load errors in the status bar
918 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
919 {
921 statusBar->AddWarningMessages( "load", adapter->GetLibraryLoadErrors() );
922 }
923
924 break;
925 }
926
927 // many many others.
928 default:
929 ;
930 }
931}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
static TOOL_ACTION updatePcbFromSchematic
Definition actions.h:260
static TOOL_ACTION pluginsReload
Definition actions.h:293
static TOOL_ACTION showFootprintLibTable
Definition actions.h:282
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:84
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:410
const NETINFO_LIST & GetNetInfo() const
Definition board.h:1215
const std::set< int > & GetHighLightNetCodes() const
Definition board.h:839
void SetHighLightNet(int aNetCode, bool aMulti=false)
Select the netcode to be highlighted.
Definition board.cpp:4077
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:3001
const ZONES & Zones() const
Definition board.h:468
void ResetNetHighLight()
Reset all high light data to the init state.
Definition board.cpp:4068
const FOOTPRINTS & Footprints() const
Definition board.h:464
const TRACKS & Tracks() const
Definition board.h:462
bool IsHighLightNetON() const
Definition board.h:855
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition board.cpp:4092
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr Vec Centre() const
Definition box2.h:94
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:594
constexpr size_type GetHeight() const
Definition box2.h:212
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)
static bool SendToFrame(FRAME_T aTarget, const google::protobuf::Message &aRequest)
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:98
KICAD_T Type() const
Returns the type of object.
Definition eda_item.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:909
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:84
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:884
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:227
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:34
std::string & GetPayload()
Return the payload, which can be any text but it typically self identifying s-expression.
Definition kiway_mail.h:52
MAIL_T Command()
Returns the MAIL_T associated with this mail.
Definition kiway_mail.h:44
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:486
std::vector< KI_ERROR > 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:50
const wxString & GetNetChain() const
Definition netinfo.h:122
int GetNetCode() const
Definition netinfo.h:104
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
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
std::unique_ptr< API_HANDLER_PCB > m_apiHandler
void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent) override
Receive KIWAY_MAIL_EVENT messages from other players.
void SetLastSchematicSheetPath(const KIID_PATH &aPath)
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString, wxWindow *aParent=nullptr)
void OnNetlistChanged(BOARD_NETLIST_UPDATER &aUpdater, bool *aRunDragCommand)
Called after netlist is updated.
KIID_PATH m_lastSchematicSheetPath
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...
void HandleRemoteNetHighlight(const std::vector< wxString > &aNetNames)
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.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition pcb_group.h:51
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:125
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:430
const std::string & GetString()
Definition richio.h:453
TOOL_MANAGER * m_toolManager
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
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)
@ RECURSE
Definition eda_item.h:51
@ FP_DNP
Definition footprint.h:92
@ FP_EXCLUDE_FROM_POS_FILES
Definition footprint.h:88
@ FP_BOARD_ONLY
Definition footprint.h:90
@ FP_EXCLUDE_FROM_BOM
Definition footprint.h:89
@ FP_EXCLUDE_FROM_SIM
Definition footprint.h:93
@ 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
std::string message
static wxString From_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition idf_helpers.h:44
PROJECT & Prj()
Definition kicad.cpp:733
@ MAIL_PCB_UPDATE_LINKS
Definition mail_type.h:48
@ MAIL_IMPORT_FILE
Definition mail_type.h:44
@ MAIL_CROSS_PROBE
Definition mail_type.h:35
@ MAIL_PCB_UPDATE
Definition mail_type.h:42
@ MAIL_RELOAD_PLUGINS
Definition mail_type.h:55
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:50
@ MAIL_PCB_SAVE
Definition mail_type.h:39
@ MAIL_SELECTION
Definition mail_type.h:36
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
@ MAIL_SCH_SHEET_CHANGED
Definition mail_type.h:58
@ MAIL_PCB_GET_NETLIST
Definition mail_type.h:47
KICOMMON_API bool PackKiwayApiMessage(const google::protobuf::Message &aMessage, std::string &aBytes)
Class to handle a set of BOARD_ITEMs.
static bool selectionSpecFromItem(const EDA_ITEM *aItem, SelectionSpec &aSpec)
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
KIWAY Kiway(KFCTL_STANDALONE)
std::vector< FAB_LAYER_COLOR > dummy
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
wxLogTrace helper definitions.
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition typeinfo.h:103
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:82
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:78
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79