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>
50#include <gal/painter.h>
51#include <pcb_painter.h>
52#include <pcb_edit_frame.h>
53#include <pcbnew_settings.h>
54#include <render_settings.h>
55#include <richio.h>
56#include <tool/tool_manager.h>
57#include <tools/pcb_actions.h>
59#include <trace_helpers.h>
62#include <widgets/kistatusbar.h>
63#include <project_pcb.h>
69#include <reporter.h>
71#include <pcb_io/pcb_io_mgr.h>
72#include <pgm_base.h>
75#include <unordered_set>
76
77#include <wx/filename.h>
78#include <wx/log.h>
79#include <wx/msgdlg.h>
80
81
82using namespace kiapi::common::commands;
83
84/* Execute a remote command sent via a socket on port KICAD_PCB_PORT_SERVICE_NUMBER
85 *
86 * Commands are:
87 *
88 * $NET: "net name" Highlight the given net
89 * $NETS: "net name 1,net name 2" Highlight all given nets
90 * $CLEAR Clear existing highlight
91 *
92 * $CONFIG Show the Manage Footprint Libraries dialog
93 * $CUSTOM_RULES Show the "Custom Rules" page of the Board Setup dialog
94 * $DRC Show the DRC dialog
95 */
96void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
97{
98 char line[1024];
99 char* idcmd;
100 char* text;
101 int netcode = -1;
102 bool multiHighlight = false;
103 BOARD* pcb = GetBoard();
104
106
107 KIGFX::VIEW* view = m_toolManager->GetView();
108 KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
109
110 strncpy( line, cmdline, sizeof(line) - 1 );
111 line[sizeof(line) - 1] = 0;
112
113 idcmd = strtok( line, " \n\r" );
114 text = strtok( nullptr, "\"\n\r" );
115
116 if( idcmd == nullptr )
117 return;
118
119 if( strcmp( idcmd, "$CONFIG" ) == 0 )
120 {
122 return;
123 }
124 else if( strcmp( idcmd, "$CUSTOM_RULES" ) == 0 )
125 {
126 ShowBoardSetupDialog( _( "Custom Rules" ) );
127 return;
128 }
129 else if( strcmp( idcmd, "$DRC" ) == 0 )
130 {
132 return;
133 }
134 else if( strcmp( idcmd, "$CLEAR" ) == 0 )
135 {
136 auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
137
138 bool hadHighlight = renderSettings->IsHighlightEnabled();
139 bool hadChain = pcbRender && !pcbRender->GetHighlightedNetChain().IsEmpty();
140
141 if( hadHighlight )
142 renderSettings->SetHighlight( false );
143
144 if( hadChain )
145 pcbRender->SetHighlightedNetChain( wxString() );
146
147 if( hadHighlight || hadChain )
148 view->UpdateAllLayersColor();
149
150 if( pcb->IsHighLightNetON() )
151 {
152 pcb->ResetNetHighLight();
153 SetMsgPanel( pcb );
154 }
155
156 GetCanvas()->Refresh();
157 return;
158 }
159 else if( strcmp( idcmd, "$NET:" ) == 0 )
160 {
161 if( !crossProbingSettings.auto_highlight )
162 return;
163
164 wxString net_name = From_UTF8( text );
165
166 NETINFO_ITEM* netinfo = pcb->FindNet( net_name );
167
168 if( netinfo )
169 {
170 netcode = netinfo->GetNetCode();
171
172 std::vector<MSG_PANEL_ITEM> items;
173 netinfo->GetMsgPanelInfo( this, items );
174 SetMsgPanel( items );
175
176 // If the incoming net belongs to a net chain, promote the single-net
177 // highlight into a multi-net highlight covering every chain member so
178 // the PCB mirrors the chain highlight happening on the schematic side.
179 const wxString& chainName = netinfo->GetNetChain();
180
181 if( !chainName.IsEmpty() )
182 {
183 pcb->SetHighLightNet( netcode );
184 renderSettings->SetHighlight( true, netcode );
185 multiHighlight = true;
186
187 for( NETINFO_ITEM* candidate : pcb->GetNetInfo() )
188 {
189 if( !candidate || candidate == netinfo )
190 continue;
191
192 if( candidate->GetNetChain() == chainName )
193 {
194 pcb->SetHighLightNet( candidate->GetNetCode(), true );
195 renderSettings->SetHighlight( true, candidate->GetNetCode(), true );
196 }
197 }
198
199 if( auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings ) )
200 pcbRender->SetHighlightedNetChain( chainName );
201
202 netcode = -1;
203 }
204 }
205
206 // fall through to highlighting section
207 }
208 else if( strcmp( idcmd, "$NETS:" ) == 0 )
209 {
210 if( !crossProbingSettings.auto_highlight )
211 return;
212
213 wxStringTokenizer netsTok = wxStringTokenizer( From_UTF8( text ), ",", wxTOKEN_STRTOK );
214 bool first = true;
215
216 while( netsTok.HasMoreTokens() )
217 {
218 NETINFO_ITEM* netinfo = pcb->FindNet( netsTok.GetNextToken().Trim( true ).Trim( false ) );
219
220 if( netinfo )
221 {
222 if( first )
223 {
224 // TODO: Once buses are included in netlist, show bus name
225 std::vector<MSG_PANEL_ITEM> items;
226 netinfo->GetMsgPanelInfo( this, items );
227 SetMsgPanel( items );
228 first = false;
229
230 pcb->SetHighLightNet( netinfo->GetNetCode() );
231 renderSettings->SetHighlight( true, netinfo->GetNetCode() );
232 multiHighlight = true;
233 }
234 else
235 {
236 pcb->SetHighLightNet( netinfo->GetNetCode(), true );
237 renderSettings->SetHighlight( true, netinfo->GetNetCode(), true );
238 }
239 }
240 }
241
242 netcode = -1;
243
244 // fall through to highlighting section
245 }
246
247 BOX2I bbox;
248
249 if( netcode > 0 || multiHighlight )
250 {
251 if( !multiHighlight )
252 {
253 renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
254 pcb->SetHighLightNet( netcode );
255 }
256 else
257 {
258 // Just pick the first one for area calculation
259 netcode = *pcb->GetHighLightNetCodes().begin();
260 }
261
262 pcb->HighLightON();
263
264 auto merge_area =
265 [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
266 {
267 if( aItem->GetNetCode() == netcode )
268 bbox.Merge( aItem->GetBoundingBox() );
269 };
270
271 if( crossProbingSettings.center_on_items )
272 {
273 for( ZONE* zone : pcb->Zones() )
274 merge_area( zone );
275
276 for( PCB_TRACK* track : pcb->Tracks() )
277 merge_area( track );
278
279 for( FOOTPRINT* fp : pcb->Footprints() )
280 {
281 for( PAD* p : fp->Pads() )
282 merge_area( p );
283 }
284 }
285 }
286 else
287 {
288 renderSettings->SetHighlight( false );
289 }
290
291 if( crossProbingSettings.center_on_items && bbox.GetWidth() != 0 && bbox.GetHeight() != 0 )
292 {
293 if( crossProbingSettings.zoom_to_fit )
294 GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
295
296 FocusOnLocation( bbox.Centre() );
297 }
298
299 view->UpdateAllLayersColor();
300
301 // Ensure the display is refreshed, because in some installs the refresh is done only
302 // when the gal canvas has the focus, and that is not the case when crossprobing from
303 // Eeschema:
304 GetCanvas()->Refresh();
305}
306
307
308void PCB_EDIT_FRAME::HandleRemoteNetHighlight( const std::vector<wxString>& aNetNames )
309{
310 NETINFO_ITEM* netinfo;
311 int netcode = -1;
312 bool multiHighlight = false;
313 BOARD* pcb = GetBoard();
314
316 KIGFX::VIEW* view = m_toolManager->GetView();
317 KIGFX::RENDER_SETTINGS* renderSettings = view->GetPainter()->GetSettings();
318
319 if( aNetNames.empty() || ( aNetNames.size() == 1 && aNetNames[0].empty() ) )
320 {
321 auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
322
323 bool hadHighlight = renderSettings->IsHighlightEnabled();
324 bool hadChain = pcbRender && !pcbRender->GetHighlightedNetChain().IsEmpty();
325
326 if( hadHighlight )
327 renderSettings->SetHighlight( false );
328
329 if( hadChain )
330 pcbRender->SetHighlightedNetChain( wxString() );
331
332 if( hadHighlight || hadChain )
333 view->UpdateAllLayersColor();
334
335 if( pcb->IsHighLightNetON() )
336 {
337 pcb->ResetNetHighLight();
338 SetMsgPanel( pcb );
339 }
340
341 GetCanvas()->Refresh();
342 return;
343 }
344
345 if( aNetNames.size() == 1 && ( netinfo = pcb->FindNet( aNetNames[0] ) ) != nullptr )
346 {
347 netcode = netinfo->GetNetCode();
348
349 std::vector<MSG_PANEL_ITEM> items;
350 netinfo->GetMsgPanelInfo( this, items );
351 SetMsgPanel( items );
352
353 // If the incoming net belongs to a net chain, promote the single-net
354 // highlight into a multi-net highlight covering every chain member so
355 // the PCB mirrors the chain highlight happening on the schematic side.
356 const wxString& chainName = netinfo->GetNetChain();
357
358 if( !chainName.IsEmpty() )
359 {
360 pcb->SetHighLightNet( netcode );
361 renderSettings->SetHighlight( true, netcode );
362 multiHighlight = true;
363
364 for( NETINFO_ITEM* candidate : pcb->GetNetInfo() )
365 {
366 if( !candidate || candidate == netinfo )
367 continue;
368
369 if( candidate->GetNetChain() == chainName )
370 {
371 pcb->SetHighLightNet( candidate->GetNetCode(), true );
372 renderSettings->SetHighlight( true, candidate->GetNetCode(), true );
373 }
374 }
375
376 if( auto* pcbRender = dynamic_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings ) )
377 pcbRender->SetHighlightedNetChain( chainName );
378
379 netcode = -1;
380 }
381 }
382 else
383 {
384 bool first = true;
385
386 for( const wxString& netName : aNetNames )
387 {
388 netinfo = pcb->FindNet( netName );
389
390 if( netinfo )
391 {
392 if( first )
393 {
394 // TODO: Once buses are included in netlist, show bus name
395 std::vector<MSG_PANEL_ITEM> items;
396 netinfo->GetMsgPanelInfo( this, items );
397 SetMsgPanel( items );
398 first = false;
399
400 pcb->SetHighLightNet( netinfo->GetNetCode() );
401 renderSettings->SetHighlight( true, netinfo->GetNetCode() );
402 multiHighlight = true;
403 }
404 else
405 {
406 pcb->SetHighLightNet( netinfo->GetNetCode(), true );
407 renderSettings->SetHighlight( true, netinfo->GetNetCode(), true );
408 }
409 }
410 }
411
412 netcode = -1;
413 }
414
415 BOX2I bbox;
416
417 if( netcode > 0 || multiHighlight )
418 {
419 if( !multiHighlight )
420 {
421 renderSettings->SetHighlight( ( netcode >= 0 ), netcode );
422 pcb->SetHighLightNet( netcode );
423 }
424 else
425 {
426 // Just pick the first one for area calculation
427 netcode = *pcb->GetHighLightNetCodes().begin();
428 }
429
430 pcb->HighLightON();
431
432 auto merge_area =
433 [netcode, &bbox]( BOARD_CONNECTED_ITEM* aItem )
434 {
435 if( aItem->GetNetCode() == netcode )
436 bbox.Merge( aItem->GetBoundingBox() );
437 };
438
439 if( crossProbingSettings.center_on_items )
440 {
441 for( ZONE* zone : pcb->Zones() )
442 merge_area( zone );
443
444 for( PCB_TRACK* track : pcb->Tracks() )
445 merge_area( track );
446
447 for( FOOTPRINT* fp : pcb->Footprints() )
448 {
449 for( PAD* p : fp->Pads() )
450 merge_area( p );
451 }
452 }
453 }
454 else
455 {
456 renderSettings->SetHighlight( false );
457 }
458
459 if( crossProbingSettings.center_on_items && bbox.GetWidth() != 0 && bbox.GetHeight() != 0 )
460 {
461 if( crossProbingSettings.zoom_to_fit )
462 GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->ZoomFitCrossProbeBBox( bbox );
463
464 FocusOnLocation( bbox.Centre() );
465 }
466
467 view->UpdateAllLayersColor();
468
469 // Ensure the display is refreshed, because in some installs the refresh is done only
470 // when the gal canvas has the focus, and that is not the case when crossprobing from
471 // Eeschema:
472 GetCanvas()->Refresh();
473}
474
475
476static bool selectionSpecFromItem( const EDA_ITEM* aItem, SelectionSpec& aSpec )
477{
478 switch( aItem->Type() )
479 {
480 case PCB_FOOTPRINT_T:
481 {
482 const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( aItem );
483 aSpec.mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
484 return true;
485 }
486
487 case PCB_PAD_T:
488 {
489 const PAD* pad = static_cast<const PAD*>( aItem );
490
491 if( const FOOTPRINT* footprint = pad->GetParentFootprint() )
492 {
493 aSpec.mutable_pad()->set_reference( footprint->GetReference().ToUTF8() );
494 aSpec.mutable_pad()->set_number( pad->GetNumber().ToUTF8() );
495 return true;
496 }
497
498 break;
499 }
500
501 default:
502 break;
503 }
504
505 return false;
506}
507
508
509void PCB_EDIT_FRAME::SendSelectItemsToSch( const std::deque<EDA_ITEM*>& aItems, EDA_ITEM* aFocusItem, bool aForce )
510{
511 SyncSelection sync;
512
513 if( aFocusItem )
514 {
515 SelectionSpec focusSpec;
516
517 if( selectionSpecFromItem( aFocusItem, focusSpec ) )
518 {
519 sync.set_mode( SyncSelectionMode::SSM_ITEMS_AND_NETS );
520 sync.mutable_focus_item()->CopyFrom( focusSpec );
521 sync.mutable_items()->Add()->CopyFrom( focusSpec );
522 }
523 }
524
525 std::vector<EDA_ITEM*> collectedItems;
526
527 for( EDA_ITEM* item : aItems )
528 {
529 if( item->Type() == PCB_GROUP_T )
530 {
531 static_cast<const PCB_GROUP*>( item )->RunOnChildren(
532 [&]( BOARD_ITEM* aChild )
533 {
534 if( aChild->Type() == PCB_FOOTPRINT_T || aChild->Type() == PCB_PAD_T )
535 collectedItems.push_back( aChild );
537 }
538 else if( item->Type() == PCB_FOOTPRINT_T || item->Type() == PCB_PAD_T )
539 {
540 collectedItems.push_back( item );
541 }
542 }
543
544 for( EDA_ITEM* item : collectedItems )
545 selectionSpecFromItem( item, *sync.add_items() );
546
547 if( sync.items_size() == 0 )
548 return;
549
550 sync.set_context( aForce ? SyncSelectionContext::SSC_EXPLICIT : SyncSelectionContext::SSC_IMPLICIT );
551
552 if( Kiface().IsSingle() )
553 {
555 }
556 else
557 {
558 std::string payload;
559 kiapi::common::PackKiwayApiMessage( sync, payload );
560 Kiway().ExpressMail( FRAME_SCH, MAIL_SELECTION, payload, this );
561 }
562}
563
564
565void PCB_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
566{
567 kiapi::common::commands::HighlightNets message;
568
569 message.add_net_name( aNetName.ToUTF8() );
570
571 if( Kiface().IsSingle() )
572 {
574 }
575 else
576 {
577 std::string payload;
579 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, payload, this );
580 }
581}
582
583
585{
586 if( !aSyncItem )
587 {
588 SendCrossProbeNetName( wxEmptyString );
589 return;
590 }
591
592 kiapi::common::commands::FocusOnItem message;
593 SelectionSpec* spec = message.mutable_focus_item();
594
595 switch( aSyncItem->Type() )
596 {
597 case PCB_FOOTPRINT_T:
598 {
599 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aSyncItem );
600 spec->mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
601 break;
602 }
603
604 case PCB_PAD_T:
605 {
606 PAD* pad = static_cast<PAD*>( aSyncItem );
607 FOOTPRINT* footprint = pad->GetParentFootprint();
608
609 spec->mutable_pad()->set_reference( footprint->GetReference().ToUTF8() );
610 spec->mutable_pad()->set_number( pad->GetNumber().ToUTF8() );
611 break;
612 }
613
614 case PCB_FIELD_T:
615 {
616 PCB_FIELD* field = static_cast<PCB_FIELD*>( aSyncItem );
617 FOOTPRINT* footprint = field->GetParentFootprint();
618 spec->mutable_footprint()->set_reference( footprint->GetReference().ToUTF8() );
619 break;
620 }
621
622 default:
623 break;
624 }
625
626 if( Kiface().IsSingle() )
627 {
629 }
630 else
631 {
632 std::string payload;
634 Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, payload, this );
635 }
636}
637
638
640{
641 if( m_lastSchematicSheetPath == aPath )
642 return;
643
645
646 wxCommandEvent event( EDA_EVT_PCB_LAST_SCH_SHEET_CHANGED, GetId() );
647 event.SetEventObject( this );
648 wxPostEvent( this, event );
649}
650
651
653{
654 std::string& payload = mail.GetPayload();
655
656 switch( mail.Command() )
657 {
659 SetLastSchematicSheetPath( KIID_PATH( wxString::FromUTF8( payload.c_str() ) ) );
660 break;
661
663 {
666
667 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
668 {
669 if( footprint->GetAttributes() & FP_BOARD_ONLY )
670 continue; // Don't add board-only footprints to the netlist
671
672 COMPONENT* component = new COMPONENT( footprint->GetFPID(), footprint->GetReference(),
673 footprint->GetValue(), footprint->GetPath(), {} );
674
675 for( PAD* pad : footprint->Pads() )
676 {
677 const wxString& netname = pad->GetShortNetname();
678
679 if( !netname.IsEmpty() )
680 component->AddNet( pad->GetNumber(), netname, pad->GetPinFunction(), pad->GetPinType() );
681 }
682
683 nlohmann::ordered_map<wxString, wxString> fields;
684
685 for( PCB_FIELD* field : footprint->GetFields() )
686 {
687 wxCHECK2( field, continue );
688
689 fields[field->GetUntranslatedName()] = field->GetText();
690 }
691
692 component->SetFields( fields );
693
694 // Add DNP and exclusion properties
695 std::map<wxString, wxString> properties;
696
697 if( footprint->GetAttributes() & FP_DNP )
698 properties.emplace( "dnp", "" );
699
700 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_BOM )
701 properties.emplace( "exclude_from_bom", "" );
702
703 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_SIM )
704 properties.emplace( "exclude_from_sim", "" );
705
706 if( footprint->GetAttributes() & FP_EXCLUDE_FROM_POS_FILES )
707 properties.emplace( "exclude_from_pos_files", "" );
708
709 component->SetProperties( properties );
710
711 netlist.AddComponent( component );
712 }
713
714 netlist.Format( "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS );
715 payload = sf.GetString();
716 break;
717 }
718
720 try
721 {
723 FetchNetlistFromSchematic( netlist, wxEmptyString );
724
725 BOARD_NETLIST_UPDATER updater( this, GetBoard() );
726 updater.SetWillDrag( false );
727 updater.SetLookupByTimestamp( false );
728 updater.SetDeleteUnusedFootprints( false );
729 updater.SetReplaceFootprints( false );
730 updater.SetTransferGroups( false );
731 updater.UpdateNetlist( netlist );
732
733 bool dummy;
734 OnNetlistChanged( updater, &dummy );
735 }
736 catch( const IO_ERROR& )
737 {
738 assert( false ); // should never happen
739 return;
740 }
741
742 break;
743
745 {
746 std::stringstream ss( payload );
747 std::string file;
748
749 // First line of payload is the source project directory.
750 std::string srcProjDir;
751 std::getline( ss, srcProjDir, '\n' );
752
753 std::vector<wxString> libraries;
754
755 while( std::getline( ss, file, '\n' ) )
756 libraries.push_back( wxString::FromUTF8( file ) );
757
758 RegisterLocalFootprintLibraries( Prj(), wxString::FromUTF8( srcProjDir ), libraries,
760
764
765 break;
766 }
767
768 // Handled as API messages
769 case MAIL_CROSS_PROBE:
770 case MAIL_SELECTION:
771 if( ApiRequest request; request.ParseFromString( payload ) )
772 m_apiHandler->Handle( request );
773
774 break;
775
776 case MAIL_PCB_UPDATE:
778 break;
779
781 {
782 // an empty payload skips the schematic's annotation prompt, and reading the reply here avoids the
783 // dialogs of the update command, so an import never waits on the user
784 std::string netlistText;
785
786 Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_GET_NETLIST, netlistText, this );
787
788 if( netlistText.empty() )
789 {
790 WXLOG_REPORTER::GetInstance().Report( _( "The schematic gave no netlist, so the board nets keep their "
791 "names.\n" ),
793 break;
794 }
795
797
798 try
799 {
800 KICAD_NETLIST_READER reader( new STRING_LINE_READER( netlistText, _( "Eeschema netlist" ) ), &netlist );
801 reader.LoadNetlist();
802 }
803 catch( const IO_ERROR& ioe )
804 {
805 WXLOG_REPORTER::GetInstance().Report( wxString::Format( _( "The schematic netlist could not be read, so "
806 "the board nets keep their names: %s\n" ),
807 ioe.What() ),
809 break;
810 }
811
812 int renamed = ReconcileImportedReferences( *GetBoard(), netlist );
813
815
816 int filled = FillImportedFootprintFields( *GetBoard(), netlist );
817
818 if( renamed > 0 || result.m_renamed > 0 || result.m_unconnectedAssigned > 0 || filled > 0 )
819 OnModify();
820
821 // the fields were changed behind the view's back, so it is rebuilt from the board
822 if( filled > 0 )
823 {
824 for( FOOTPRINT* footprint : GetBoard()->Footprints() )
825 footprint->InvalidateGeometryCaches();
826
828 GetCanvas()->Refresh();
829 }
830
831 break;
832 }
833
837 break;
838
839 case MAIL_IMPORT_FILE:
840 {
841 // Extract file format type and path (plugin type, path and properties keys, values separated with \n)
842 std::stringstream ss( payload );
843 char delim = '\n';
844
845 std::string formatStr;
846 wxCHECK( std::getline( ss, formatStr, delim ), /* void */ );
847
848 std::string fnameStr;
849 wxCHECK( std::getline( ss, fnameStr, delim ), /* void */ );
850 wxASSERT( !fnameStr.empty() );
851
852 int importFormat;
853
854 try
855 {
856 importFormat = std::stoi( formatStr );
857 }
858 catch( std::invalid_argument& )
859 {
860 wxFAIL;
861 importFormat = -1;
862 }
863
864 std::map<std::string, UTF8> props;
865
866 std::string key, value;
867
868 do
869 {
870 if( !std::getline( ss, key, delim ) )
871 break;
872
873 if( !std::getline( ss, value, delim ) )
874 break;
875
876 props.emplace( key, value );
877
878 } while( true );
879
880 payload.clear();
881
882 if( importFormat >= 0 && importFile( fnameStr, importFormat, props.empty() ? nullptr : &props ) )
883 payload = "success";
884
885 break;
886 }
887
890 break;
891
892 case MAIL_PCB_SAVE:
893 if( SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ) )
894 payload = "success";
895
896 break;
897
898 case MAIL_PCB_RELOAD:
899 {
900 // A git operation rewrote files on disk. Reload the board so the editor matches.
901 wxString file = Prj().AbsolutePath( GetBoard()->GetFileName() );
902
903 if( file.IsEmpty() )
904 break;
905
906 // A non-empty payload lists the files the operation changed. When the board is not
907 // among them, there is nothing to reload.
908 if( !payload.empty() )
909 {
910 wxArrayString changed = wxSplit( wxString::FromUTF8( payload.c_str() ), '\n' );
911 bool mine = false;
912 wxString boardFile = wxFileName( file ).GetFullPath();
913
914 for( const wxString& changedFile : changed )
915 {
916 if( !changedFile.IsEmpty() && boardFile == wxFileName( changedFile ).GetFullPath() )
917 {
918 mine = true;
919 break;
920 }
921 }
922
923 if( !mine )
924 break;
925 }
926
927 // Neither choice is safe without asking: reloading discards the unsaved edits, keeping
928 // them means the next save overwrites what arrived.
929 if( IsContentModified() )
930 {
931 wxMessageDialog dlg( this,
932 _( "The board changed on disk while you were editing it.\n\n"
933 "Reloading loses your unsaved edits. Keeping them means your "
934 "next save overwrites the changes that just arrived. To get those "
935 "back later, use Discard Changes on the file in the Version Control "
936 "panel, which drops your edits to it." ),
937 _( "Board Changed on Disk" ), wxYES_NO | wxNO_DEFAULT | wxICON_WARNING | wxCENTER );
938 dlg.SetYesNoLabels( _( "&Reload" ), _( "&Keep My Edits" ) );
939
940 if( dlg.ShowModal() != wxID_YES )
941 break;
942 }
943
945 break;
946 }
947
949 // The settings were reread, but every net caches its resolved netclass, so routing would
950 // keep the old widths and clearances until they resynchronize.
953
954 if( !GetBoard()->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
955 wxLogTrace( traceGit, wxS( "Could not load component class assignment rules" ) );
956
959
961 GetCanvas()->Refresh();
962 break;
963
964 case MAIL_RELOAD_LIB:
965 {
966 m_designBlocksPane->RefreshLibs();
967
968 // Show any footprint library load errors in the status bar
969 if( KISTATUSBAR* statusBar = dynamic_cast<KISTATUSBAR*>( GetStatusBar() ) )
970 {
972 statusBar->AddWarningMessages( "load", adapter->GetLibraryLoadErrors() );
973 }
974
975 break;
976 }
977
978 // many many others.
979 default:
980 ;
981 }
982}
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
static TOOL_ACTION updatePcbFromSchematic
Definition actions.h:260
static TOOL_ACTION pluginsReload
Definition actions.h:294
static TOOL_ACTION showFootprintLibTable
Definition actions.h:283
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:85
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 SetWillDrag(bool aWillDrag)
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:411
const NETINFO_LIST & GetNetInfo() const
Definition board.h:1217
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:3893
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition board.cpp:2797
const ZONES & Zones() const
Definition board.h:469
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition board.cpp:3221
void ResetNetHighLight()
Reset all high light data to the init state.
Definition board.cpp:3884
const FOOTPRINTS & Footprints() const
Definition board.h:465
const TRACKS & Tracks() const
Definition board.h:463
bool IsHighLightNetON() const
Definition board.h:855
void HighLightON(bool aValue=true)
Enable or disable net highlighting.
Definition board.cpp:3908
void SynchronizeTuningProfileProperties()
Ensure that all time domain properties providers are in sync with current settings.
Definition board.cpp:3175
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...
const wxString & GetReference() const
Definition footprint.h:793
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
Read the new s-expression based KiCad netlist format.
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
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:94
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:68
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition view.cpp:1172
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition view.cpp:2475
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:242
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:499
std::vector< KI_ERROR > GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
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
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the KIGFX::VIEW instance used in the panel.
void DisplayBoard(BOARD *aBoard, PROGRESS_REPORTER *aReporter=nullptr)
Add all items from the current board to the VIEW, so they can be displayed by GAL.
void OnModify() override
Must be called after a board change to set the modified flag.
std::unique_ptr< API_HANDLER_PCB > m_apiHandler
void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent) override
Receive KIWAY_MAIL_EVENT messages from other players.
bool ReloadFromDisk()
Reload the board from disk.
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...
bool IsContentModified() const override
Get if the current board has been modified but not saved.
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
The selection tool: currently supports:
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
void IncrementNetclassesTicker()
Definition project.h:115
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition project.cpp:500
void IncrementTextVarsTicker()
Definition project.h:112
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:430
const std::string & GetString()
Definition richio.h:453
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition richio.h:225
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.
static REPORTER & GetInstance()
Definition reporter.cpp:324
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
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition cvpcb.cpp:165
#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
std::map< wxString, wxString > ImportedFootprintIds(const BOARD &aBoard)
Map each board reference to the full LIB_ID of its footprint.
@ 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 traceGit
Flag to enable Git debugging output.
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
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition idf_helpers.h:37
std::vector< wxString > RegisterLocalFootprintLibraries(PROJECT &aProject, const wxString &aSourceProjectDir, const std::vector< wxString > &aLibraries, REPORTER &aReporter)
Register the footprint libraries a source project names in the project footprint library table.
int ReconcileImportedReferences(BOARD &aBoard, NETLIST &aNetlist)
Give an imported board footprint the reference its schematic symbol uses.
int FillImportedFootprintFields(BOARD &aBoard, NETLIST &aNetlist)
Copy what an imported board footprint lacks from the schematic symbol it is linked to.
NET_RECONCILE_RESULT ReconcileImportedNetNames(BOARD &aBoard, NETLIST &aNetlist, REPORTER &aReporter)
Give each net of an imported board the name its schematic uses.
PROJECT & Prj()
Definition kicad.cpp:737
@ 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:56
@ MAIL_PCB_GET_FOOTPRINT_IDS
Definition mail_type.h:65
@ MAIL_PCB_RELOAD
Definition mail_type.h:62
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:50
@ MAIL_PCB_RECONCILE_NETS
Definition mail_type.h:66
@ MAIL_PCB_SAVE
Definition mail_type.h:39
@ MAIL_PCB_PROJECT_SETTINGS_CHANGED
Definition mail_type.h:64
@ MAIL_SCH_GET_NETLIST
Definition mail_type.h:45
@ MAIL_SELECTION
Definition mail_type.h:36
@ MAIL_RELOAD_LIB
Definition mail_type.h:55
@ MAIL_SCH_SHEET_CHANGED
Definition mail_type.h:59
@ MAIL_PCB_GET_NETLIST
Definition mail_type.h:47
wxString JoinTaggedMap(const char *aTag, const std::map< wxString, wxString > &aPairs)
Encode a string map as a single property value led by a tag.
constexpr char FOOTPRINT_ID_MAP_TAG[]
Leading field marking a value as an encoded map from reference to footprint LIB_ID.
@ ALL
All except INITIAL_ADD.
Definition view_item.h:55
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)
see class PGM_BASE
@ RPT_SEVERITY_INFO
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.
Outcome of naming the nets of an imported board after the nets of its schematic.
std::string netlist
wxString result
Test unit parsing edge cases and error handling.
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