59 m_chainsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
68 if( !
m_hint.fromRef.IsEmpty() )
71 if( !
m_hint.toRef.IsEmpty() )
81 [
this]( wxGridEvent& evt )
83 if( evt.GetCol() == 0 )
129 wxString::Format(
_(
"Chain created (%d total). Select another or close." ),
m_createdCount ) );
142 wxMessageBox(
_(
"Please select a chain from the list." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
149 wxString editedName =
m_chainsGrid->GetCellValue( gridRow, 0 );
151 if( !editedName.IsEmpty() )
152 m_rows[dataIdx].suggestedName = editedName;
162 wxMessageBox(
_(
"Please enter a name for the net chain." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
169 wxMessageBox(
_(
"Chain name cannot contain spaces, quotes, or parentheses." ),
170 _(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
178 wxMessageBox(
_(
"Connection graph not available." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
184 wxMessageBox( wxString::Format(
_(
"A net chain named '%s' already exists." ),
name ),
_(
"Create Net Chain" ),
185 wxOK | wxICON_ERROR,
this );
197 wxMessageBox(
_(
"Failed to create the net chain." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
203 std::set<SCH_SYMBOL*> symbols;
209 symbols.insert(
static_cast<SCH_SYMBOL*
>( fromItem ) );
212 symbols.insert(
static_cast<SCH_SYMBOL*
>( toItem ) );
222 wxMessageBox(
_(
"Failed to create the manual net chain." ),
_(
"Create Net Chain" ),
223 wxOK | wxICON_ERROR,
this );
241 int gridRow = aEvent.GetRow();
244 int dataIdx = ( gridRow >= 0 && gridRow < static_cast<int>(
m_filteredIndices.size() ) )
253 wxString editedName =
m_chainsGrid->GetCellValue( gridRow, 0 );
255 if( !editedName.IsEmpty() )
256 m_rows[dataIdx].suggestedName = editedName;
265 :
m_frame->GetCurrentSheet().LastScreen();
275 if( !
m_frame->Schematic().ConnectionGraph() )
296 if( aRunRecalculate )
299 graph->Recalculate(
m_frame->Schematic().BuildSheetListSortedByPageNumbers(),
true );
310 wxString toRef =
m_toComponent->GetValue().Trim().Trim(
false );
312 if( fromRef.IsEmpty() || toRef.IsEmpty() )
314 wxMessageBox(
_(
"Please select both a From and To component." ),
_(
"Find Path" ),
315 wxOK | wxICON_ERROR,
this );
319 if( fromRef == toRef )
321 wxMessageBox(
_(
"From and To must be different components." ),
_(
"Find Path" ),
322 wxOK | wxICON_ERROR,
this );
336 if( ref.GetRef() == fromRef && ref.GetSymbol() )
338 fromSym = ref.GetSymbol();
339 fromSheet = ref.GetSheetPath();
342 if( ref.GetRef() == toRef && ref.GetSymbol() )
344 toSym = ref.GetSymbol();
345 toSheet = ref.GetSheetPath();
349 if( !fromSym || !toSym )
351 wxMessageBox( wxString::Format(
_(
"Could not find component '%s' or '%s'." ),
353 _(
"Find Path" ), wxOK | wxICON_ERROR,
this );
368 std::set<wxString> nets;
371 std::vector<FOUND_CHAIN> foundChains;
372 std::set<SCH_NETCHAIN*> seenChains;
374 std::vector<SCH_PIN*> fromPins = fromSym->
GetPins( &fromSheet );
375 std::vector<SCH_PIN*> toPins = toSym->
GetPins( &toSheet );
377 for(
SCH_PIN* pinA : fromPins )
385 seenChains.insert(
chain );
389 fc.fromPin = fromRef + wxT(
":" ) + pinA->GetNumber();
390 fc.toPin = toRef + wxT(
":" ) + pinB->GetNumber();
391 fc.nets =
chain->GetNets();
392 foundChains.push_back( fc );
397 if( foundChains.empty() )
400 int answer = wxMessageBox(
401 wxString::Format(
_(
"No net chain path found between %s and %s through "
402 "passthrough components.\n\n"
403 "Would you like to force-create a manual chain link "
404 "between these components?" ),
406 _(
"Find Path" ), wxYES_NO | wxICON_QUESTION,
this );
408 if( answer == wxYES )
410 std::set<wxString> fromNets, toNets;
411 SCH_PIN* fromTerminalPin =
nullptr;
412 SCH_PIN* toTerminalPin =
nullptr;
416 if(
pin->Connection() && !
pin->Connection()->Name().IsEmpty() )
418 fromNets.insert(
pin->Connection()->Name() );
420 if( !fromTerminalPin )
421 fromTerminalPin =
pin;
427 if(
pin->Connection() && !
pin->Connection()->Name().IsEmpty() )
429 toNets.insert(
pin->Connection()->Name() );
436 if( !fromTerminalPin || !toTerminalPin )
438 wxMessageBox(
_(
"Selected components have no connected pins to anchor a manual chain." ),
439 _(
"Find Path" ), wxOK | wxICON_ERROR,
this );
461 row.
terminals = fromRef + wxT(
" \u2192 " ) + toRef;
462 row.
memberNets.insert( fromNets.begin(), fromNets.end() );
463 row.
memberNets.insert( toNets.begin(), toNets.end() );
465 m_rows.push_back( std::move( row ) );
470 _(
"Showing manual chain between %s and %s. Use Refresh to restore all." ),
478 std::set<wxString> committedNames;
483 committedNames.insert(
chain->GetName() );
486 std::vector<FOUND_CHAIN> uncommitted;
488 for(
const FOUND_CHAIN& fc : foundChains )
490 bool isCommitted =
false;
492 for(
const wxString& net : fc.nets )
496 if( committedNames.count( existing->GetName() ) )
505 uncommitted.push_back( fc );
508 if( uncommitted.empty() )
510 wxMessageBox( wxString::Format(
_(
"All %zu net chain paths between %s and %s are "
511 "already committed as net chains." ),
512 foundChains.size(), fromRef, toRef ),
513 _(
"Find Path" ), wxOK | wxICON_INFORMATION,
this );
523 for(
const FOUND_CHAIN& fc : uncommitted )
529 row.
terminals = fc.fromPin + wxT(
" \u2192 " ) + fc.toPin;
532 if( uncommitted.size() > 1 )
534 wxString pinNum = fc.fromPin.AfterLast(
':' );
535 row.
suggestedName = fromRef + wxT(
"_" ) + toRef + wxT(
"_" ) + pinNum;
538 m_rows.push_back( std::move( row ) );
546 _(
"Showing %zu path(s) between %s and %s. Use Refresh to restore all." ),
547 uncommitted.size(), fromRef, toRef ) );
559 std::set<wxString> refNames;
563 if( ref.GetSymbol() )
564 refNames.insert( ref.GetRef() );
567 for(
const wxString&
name : refNames )
584 std::set<wxString> committedNames;
589 committedNames.insert(
chain->GetName() );
598 bool alreadyCommitted =
false;
600 for(
const wxString& net :
chain->GetNets() )
604 if( committedNames.count( existing->GetName() ) )
606 alreadyCommitted =
true;
612 if( alreadyCommitted )
628 wxString terminalA =
chain->GetTerminalRef( 0 );
629 wxString terminalB =
chain->GetTerminalRef( 1 );
631 if( !
chain->GetTerminalPinNum( 0 ).IsEmpty() )
632 terminalA += wxT(
":" ) +
chain->GetTerminalPinNum( 0 );
634 if( !
chain->GetTerminalPinNum( 1 ).IsEmpty() )
635 terminalB += wxT(
":" ) +
chain->GetTerminalPinNum( 1 );
637 if( !terminalA.IsEmpty() || !terminalB.IsEmpty() )
638 row.
terminals = terminalA + wxT(
" → " ) + terminalB;
640 m_rows.push_back( std::move( row ) );
652 if( dataIdx >= 0 && dataIdx <
static_cast<int>(
m_rows.size() ) )
654 wxString edited =
m_chainsGrid->GetCellValue(
static_cast<int>( gi ), 0 );
656 if( !edited.IsEmpty() )
657 m_rows[dataIdx].suggestedName = edited;
675 int gridRow =
static_cast<int>( gi );
678 if( gridRow < m_chainsGrid->GetNumberRows()
679 && dataIdx >= 0 && dataIdx <
static_cast<int>(
m_rows.size() ) )
681 wxString edited =
m_chainsGrid->GetCellValue( gridRow, 0 );
683 if( !edited.IsEmpty() )
684 m_rows[dataIdx].suggestedName = edited;
695 for(
size_t i = 0; i <
m_rows.size(); ++i )
721 bool netMatch =
false;
725 if( net.Lower().Contains(
filter ) )
741 int r =
static_cast<int>( gi );
753 preview = wxT(
"[" ) + row.
terminals + wxT(
"] " );
757 if( !preview.IsEmpty() && preview.Last() !=
' ' )
758 preview += wxT(
", " );
782 if( aRow < 0 || aRow >=
static_cast<int>(
m_rows.size() ) )
804 wxArrayString sorted;
836 BOX2I highlightedBBox;
839 return highlightedBBox;
843 bool onCurrentSheet = aScreen ==
m_frame->GetCurrentSheet().LastScreen();
845 std::vector<EDA_ITEM*> itemsToRedraw;
847 auto recordHighlight = [&](
SCH_ITEM* aItem )
850 highlightedBBox = aItem->GetBoundingBox();
852 highlightedBBox.
Merge( aItem->GetBoundingBox() );
857 if( !item || !item->IsConnectable() )
865 bool anyPinHighlighted =
false;
871 if( pinConn && !aNets.empty() )
873 if( !
pin->IsBrightened() && aNets.count( pinConn->
Name() ) )
875 pin->SetBrightened();
877 anyPinHighlighted =
true;
879 else if(
pin->IsBrightened() && !aNets.count( pinConn->
Name() ) )
881 pin->ClearBrightened();
884 else if(
pin->IsBrightened() )
886 anyPinHighlighted =
true;
889 else if(
pin->IsBrightened() )
891 pin->ClearBrightened();
896 if( anyPinHighlighted )
897 recordHighlight( symbol );
903 if( itemConn && !aNets.empty() )
905 if( !item->IsBrightened() && aNets.count( itemConn->
Name() ) )
907 item->SetBrightened();
909 recordHighlight( item );
911 else if( item->IsBrightened() && !aNets.count( itemConn->
Name() ) )
913 item->ClearBrightened();
916 else if( item->IsBrightened() )
918 recordHighlight( item );
921 else if( item->IsBrightened() )
923 item->ClearBrightened();
929 itemsToRedraw.push_back( redrawItem );
932 if( !itemsToRedraw.empty() && view )
934 for(
EDA_ITEM* redrawItem : itemsToRedraw )
937 m_frame->GetCanvas()->Refresh();
940 return highlightedBBox;
961 if( targetRef.IsEmpty() )
968 if( targetRef.IsEmpty() )
972 if( !targetRef.IsEmpty() )
979 if( ref.GetRef() == targetRef && ref.GetSymbol() )
997 if( !item || !item->IsConnectable() )
1029 if( targetPath !=
m_frame->GetCurrentSheet() )
1042 selTool->ZoomFitCrossProbeBBox( bbox );
1066 if( !
m_hint.fromRef.IsEmpty() && !
m_hint.toRef.IsEmpty() )
1068 wxCommandEvent
dummy;
1073 wxString filterValue;
1076 if( !
m_hint.netName.IsEmpty() )
1078 filterValue =
m_hint.netName;
1079 hintLabel = wxString::Format(
_(
"net '%s'" ),
m_hint.netName );
1081 else if( !
m_hint.fromRef.IsEmpty() )
1083 filterValue =
m_hint.fromRef;
1084 hintLabel = wxString::Format(
_(
"component %s" ),
m_hint.fromRef );
1086 else if( !
m_hint.toRef.IsEmpty() )
1088 filterValue =
m_hint.toRef;
1089 hintLabel = wxString::Format(
_(
"component %s" ),
m_hint.toRef );
1098 wxCommandEvent
dummy;
1108 _(
"No uncommitted chains match the selected %s. Use Refresh to restore the full list." ),
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
constexpr size_type GetWidth() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
Calculate the connectivity of a schematic and generates netlists.
SCH_NETCHAIN * GetNetChainByName(const wxString &aName)
SCH_NETCHAIN * GetNetChainForNet(const wxString &aNet)
SCH_NETCHAIN * CreateNetChainFromPotential(SCH_NETCHAIN *aPotential, const wxString &aName)
Promote a potential net chain to an actual user net chain with the provided name.
const std::vector< std::unique_ptr< SCH_NETCHAIN > > & GetPotentialNetChains() const
Potential net chains are inferred groupings produced by RebuildNetChains() but not yet user-committed...
SCH_NETCHAIN * CreateManualNetChain(const wxString &aName, const std::set< class SCH_SYMBOL * > &aSymbols, const std::set< wxString > &aNets, const KIID &aTerminalPinA, const KIID &aTerminalPinB, const wxString &aRefA, const wxString &aPinNumA, const wxString &aRefB, const wxString &aPinNumB)
Commit a manually-defined net chain that the inferred-potential pass did not produce.
SCH_NETCHAIN * FindPotentialNetChainBetweenPins(SCH_PIN *aPinA, SCH_PIN *aPinB)
Locate a potential net chain that contains both pins (by subgraph net membership).
const std::vector< std::unique_ptr< SCH_NETCHAIN > > & GetCommittedNetChains() const
Return user-created (committed) net chains (legacy accessor retained under net-chain API).
wxStaticText * m_membersLabel
STD_BITMAP_BUTTON * m_findPathButton
DIALOG_CREATE_NET_CHAIN_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Create Net Chain"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxStaticText * m_manualLabel
wxStaticText * m_headerLabel
wxComboBox * m_toComponent
wxTextCtrl * m_filterInput
wxButton * m_sdbSizerCancel
STD_BITMAP_BUTTON * m_refreshButton
wxComboBox * m_fromComponent
wxListBox * m_membersListBox
void navigateAndHighlightChain(POTENTIAL_ROW &aRow)
Switch to the sheet owning aRow (if different from the current sheet), brighten the chain's nets ther...
bool TransferDataToWindow() override
BOX2I highlightChainNets(const std::set< wxString > &aNets, SCH_SCREEN *aScreen)
Walk aScreen and brighten/un-brighten items whose connection name is in aNets.
void applyFocusHint()
Apply the focus hint after rows are loaded — set the filter input, optionally trigger the existing tw...
void populateComponentCombos()
std::vector< POTENTIAL_ROW > m_rows
void recalculateAndReload(bool aRunRecalculate)
Tear down row state, optionally trigger a connectivity recalculation, then reload rows and refresh th...
void autoSelectFirstRow()
Position the grid cursor on the first filtered row, sync the name input, run the member-detail update...
SCH_SHEET_PATH m_lastHighlightedSheet
empty when no prior highlight
void OnChainSelected(wxGridEvent &aEvent) override
void OnRefreshClicked(wxCommandEvent &aEvent) override
std::vector< int > m_filteredIndices
indices into m_rows shown in grid
bool TransferDataFromWindow() override
void OnFindPathClicked(wxCommandEvent &aEvent) override
DIALOG_CREATE_NET_CHAIN(SCH_EDIT_FRAME *aParent, const FOCUS_HINT &aHint={})
void updateMemberDetail(int aRow)
~DIALOG_CREATE_NET_CHAIN() override
void OnFilterChanged(wxCommandEvent &aEvent) override
const SCH_SHEET_PATH & findSheetForRow(POTENTIAL_ROW &aRow)
Resolve and cache the sheet path to navigate to for aRow.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
An abstract base class for deriving all objects that can be added to a VIEW.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
static TOOL_ACTION changeSheet
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
A net chain is a collection of nets that are connected together through passive components.
const wxString & GetTerminalRef(int aIdx) const
static bool IsValidName(const wxString &aName)
const wxString & GetNumber() const
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
@ REPAINT
Item needs to be redrawn.
std::vector< FAB_LAYER_COLOR > dummy
Optional context derived from the user selection that opened the dialog.
Row backing data for the chains grid.
SCH_SHEET_PATH cachedSheet
Lazily-resolved sheet to navigate to when this row is selected.
KIID forceFromUuid
For force-created rows without a livePtr.
wxString terminals
e.g. "J1:1 -> J2:1"
std::set< wxString > memberNets
SCH_NETCHAIN * livePtr
null for force-created manual rows
const SHAPE_LINE_CHAIN chain