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 )
102 :
m_frame->GetCurrentSheet() );
128 wxString::Format(
_(
"Chain created (%d total). Select another or close." ),
m_createdCount ) );
141 wxMessageBox(
_(
"Please select a chain from the list." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
148 wxString editedName =
m_chainsGrid->GetCellValue( gridRow, 0 );
150 if( !editedName.IsEmpty() )
151 m_rows[dataIdx].suggestedName = editedName;
161 wxMessageBox(
_(
"Please enter a name for the net chain." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
168 wxMessageBox(
_(
"Chain name cannot contain spaces, quotes, or parentheses." ),
169 _(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
173 auto& chains =
m_frame->Schematic().NetChains();
175 if( chains.GetNetChainByName(
name ) )
177 wxMessageBox( wxString::Format(
_(
"A net chain named '%s' already exists." ),
name ),
_(
"Create Net Chain" ),
178 wxOK | wxICON_ERROR,
this );
190 wxMessageBox(
_(
"Failed to create the net chain." ),
_(
"Create Net Chain" ), wxOK | wxICON_ERROR,
this );
196 std::set<SCH_SYMBOL*> symbols;
202 symbols.insert(
static_cast<SCH_SYMBOL*
>( fromItem ) );
205 symbols.insert(
static_cast<SCH_SYMBOL*
>( toItem ) );
215 wxMessageBox(
_(
"Failed to create the manual net chain." ),
_(
"Create Net Chain" ),
216 wxOK | wxICON_ERROR,
this );
234 int gridRow = aEvent.GetRow();
237 int dataIdx = ( gridRow >= 0 && gridRow < static_cast<int>(
m_filteredIndices.size() ) )
246 wxString editedName =
m_chainsGrid->GetCellValue( gridRow, 0 );
248 if( !editedName.IsEmpty() )
249 m_rows[dataIdx].suggestedName = editedName;
258 :
m_frame->GetCurrentSheet() );
285 if( aRunRecalculate )
286 m_frame->Schematic().RebuildConnectivity();
296 wxString toRef =
m_toComponent->GetValue().Trim().Trim(
false );
298 if( fromRef.IsEmpty() || toRef.IsEmpty() )
300 wxMessageBox(
_(
"Please select both a From and To component." ),
_(
"Find Path" ),
301 wxOK | wxICON_ERROR,
this );
305 if( fromRef == toRef )
307 wxMessageBox(
_(
"From and To must be different components." ),
_(
"Find Path" ),
308 wxOK | wxICON_ERROR,
this );
322 if( ref.GetRef() == fromRef && ref.GetSymbol() )
324 fromSym = ref.GetSymbol();
325 fromSheet = ref.GetSheetPath();
328 if( ref.GetRef() == toRef && ref.GetSymbol() )
330 toSym = ref.GetSymbol();
331 toSheet = ref.GetSheetPath();
335 if( !fromSym || !toSym )
337 wxMessageBox( wxString::Format(
_(
"Could not find component '%s' or '%s'." ),
339 _(
"Find Path" ), wxOK | wxICON_ERROR,
this );
343 auto& chains =
m_frame->Schematic().NetChains();
351 std::set<wxString> nets;
354 std::vector<FOUND_CHAIN> foundChains;
355 std::set<SCH_NETCHAIN*> seenChains;
357 std::vector<SCH_PIN*> fromPins = fromSym->
GetPins( &fromSheet );
358 std::vector<SCH_PIN*> toPins = toSym->
GetPins( &toSheet );
368 seenChains.insert(
chain );
372 fc.fromPin = fromRef + wxT(
":" ) +
pinA->GetNumber();
373 fc.toPin = toRef + wxT(
":" ) + pinB->GetNumber();
374 fc.nets =
chain->GetNets();
375 foundChains.push_back( fc );
380 if( foundChains.empty() )
383 int answer = wxMessageBox(
384 wxString::Format(
_(
"No net chain path found between %s and %s through "
385 "passthrough components.\n\n"
386 "Would you like to force-create a manual chain link "
387 "between these components?" ),
389 _(
"Find Path" ), wxYES_NO | wxICON_QUESTION,
this );
391 if( answer == wxYES )
393 std::set<wxString> fromNets, toNets;
394 SCH_PIN* fromTerminalPin =
nullptr;
395 SCH_PIN* toTerminalPin =
nullptr;
399 const auto name =
pin->GetConnectionName( &fromSheet );
403 fromNets.insert( *
name );
405 if( !fromTerminalPin )
406 fromTerminalPin =
pin;
412 const auto name =
pin->GetConnectionName( &toSheet );
416 toNets.insert( *
name );
423 if( !fromTerminalPin || !toTerminalPin )
425 wxMessageBox(
_(
"Selected components have no connected pins to anchor a manual chain." ),
426 _(
"Find Path" ), wxOK | wxICON_ERROR,
this );
448 row.
terminals = fromRef + wxT(
" \u2192 " ) + toRef;
449 row.
memberNets.insert( fromNets.begin(), fromNets.end() );
450 row.
memberNets.insert( toNets.begin(), toNets.end() );
452 m_rows.push_back( std::move( row ) );
457 _(
"Showing manual chain between %s and %s. Use Refresh to restore all." ),
465 std::set<wxString> committedNames;
467 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : chains.GetCommittedNetChains() )
470 committedNames.insert(
chain->GetName() );
473 std::vector<FOUND_CHAIN> uncommitted;
475 for(
const FOUND_CHAIN& fc : foundChains )
477 bool isCommitted =
false;
479 for(
const wxString& net : fc.nets )
481 if(
SCH_NETCHAIN* existing = chains.GetNetChainForNet( net ) )
483 if( committedNames.count( existing->GetName() ) )
492 uncommitted.push_back( fc );
495 if( uncommitted.empty() )
497 wxMessageBox( wxString::Format(
_(
"All %zu net chain paths between %s and %s are "
498 "already committed as net chains." ),
499 foundChains.size(), fromRef, toRef ),
500 _(
"Find Path" ), wxOK | wxICON_INFORMATION,
this );
510 for(
const FOUND_CHAIN& fc : uncommitted )
516 row.
terminals = fc.fromPin + wxT(
" \u2192 " ) + fc.toPin;
519 if( uncommitted.size() > 1 )
521 wxString pinNum = fc.fromPin.AfterLast(
':' );
522 row.
suggestedName = fromRef + wxT(
"_" ) + toRef + wxT(
"_" ) + pinNum;
525 m_rows.push_back( std::move( row ) );
533 _(
"Showing %zu path(s) between %s and %s. Use Refresh to restore all." ),
534 uncommitted.size(), fromRef, toRef ) );
546 std::set<wxString> refNames;
550 if( ref.GetSymbol() )
551 refNames.insert( ref.GetRef() );
554 for(
const wxString&
name : refNames )
566 auto& chains =
m_frame->Schematic().NetChains();
568 std::set<wxString> committedNames;
570 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : chains.GetCommittedNetChains() )
573 committedNames.insert(
chain->GetName() );
576 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : chains.GetPotentialNetChains() )
582 bool alreadyCommitted =
false;
584 for(
const wxString& net :
chain->GetNets() )
586 if(
SCH_NETCHAIN* existing = chains.GetNetChainForNet( net ) )
588 if( committedNames.count( existing->GetName() ) )
590 alreadyCommitted =
true;
596 if( alreadyCommitted )
612 wxString terminalA =
chain->GetTerminalRef( 0 );
613 wxString terminalB =
chain->GetTerminalRef( 1 );
615 if( !
chain->GetTerminalPinNum( 0 ).IsEmpty() )
616 terminalA += wxT(
":" ) +
chain->GetTerminalPinNum( 0 );
618 if( !
chain->GetTerminalPinNum( 1 ).IsEmpty() )
619 terminalB += wxT(
":" ) +
chain->GetTerminalPinNum( 1 );
621 if( !terminalA.IsEmpty() || !terminalB.IsEmpty() )
622 row.
terminals = terminalA + wxT(
" → " ) + terminalB;
624 m_rows.push_back( std::move( row ) );
636 if( dataIdx >= 0 && dataIdx <
static_cast<int>(
m_rows.size() ) )
638 wxString edited =
m_chainsGrid->GetCellValue(
static_cast<int>( gi ), 0 );
640 if( !edited.IsEmpty() )
641 m_rows[dataIdx].suggestedName = edited;
659 int gridRow =
static_cast<int>( gi );
662 if( gridRow < m_chainsGrid->GetNumberRows()
663 && dataIdx >= 0 && dataIdx <
static_cast<int>(
m_rows.size() ) )
665 wxString edited =
m_chainsGrid->GetCellValue( gridRow, 0 );
667 if( !edited.IsEmpty() )
668 m_rows[dataIdx].suggestedName = edited;
679 for(
size_t i = 0; i <
m_rows.size(); ++i )
705 bool netMatch =
false;
709 if( net.Lower().Contains(
filter ) )
725 int r =
static_cast<int>( gi );
737 preview = wxT(
"[" ) + row.
terminals + wxT(
"] " );
741 if( !preview.IsEmpty() && preview.Last() !=
' ' )
742 preview += wxT(
", " );
766 if( aRow < 0 || aRow >=
static_cast<int>(
m_rows.size() ) )
788 wxArrayString sorted;
821 BOX2I highlightedBBox;
825 return highlightedBBox;
829 bool onCurrentSheet = screen ==
m_frame->GetCurrentSheet().LastScreen();
831 std::vector<EDA_ITEM*> itemsToRedraw;
833 auto recordHighlight = [&](
SCH_ITEM* aItem )
836 highlightedBBox = aItem->GetBoundingBox();
838 highlightedBBox.
Merge( aItem->GetBoundingBox() );
843 if( !item || !item->IsConnectable() )
851 bool anyPinHighlighted =
false;
855 const auto pinConn =
pin->GetConnectionName( &aPath );
857 if( pinConn && !aNets.empty() )
859 if( !
pin->IsBrightened() && aNets.count( *pinConn ) )
861 pin->SetBrightened();
863 anyPinHighlighted =
true;
865 else if(
pin->IsBrightened() && !aNets.count( *pinConn ) )
867 pin->ClearBrightened();
870 else if(
pin->IsBrightened() )
872 anyPinHighlighted =
true;
875 else if(
pin->IsBrightened() )
877 pin->ClearBrightened();
882 if( anyPinHighlighted )
883 recordHighlight( symbol );
887 const auto itemConn = item->GetConnectionName( &aPath );
889 if( itemConn && !aNets.empty() )
891 if( !item->IsBrightened() && aNets.count( *itemConn ) )
893 item->SetBrightened();
895 recordHighlight( item );
897 else if( item->IsBrightened() && !aNets.count( *itemConn ) )
899 item->ClearBrightened();
902 else if( item->IsBrightened() )
904 recordHighlight( item );
907 else if( item->IsBrightened() )
909 item->ClearBrightened();
915 itemsToRedraw.push_back( redrawItem );
918 if( !itemsToRedraw.empty() && view )
920 for(
EDA_ITEM* redrawItem : itemsToRedraw )
923 m_frame->GetCanvas()->Refresh();
926 return highlightedBBox;
947 if( targetRef.IsEmpty() )
954 if( targetRef.IsEmpty() )
958 if( !targetRef.IsEmpty() )
965 if( ref.GetRef() == targetRef && ref.GetSymbol() )
983 if( !item || !item->IsConnectable() )
986 if(
const auto conn = item->GetConnectionName( &
path ) )
1015 if( targetPath !=
m_frame->GetCurrentSheet() )
1027 selTool->ZoomFitCrossProbeBBox( bbox );
1051 if( !
m_hint.fromRef.IsEmpty() && !
m_hint.toRef.IsEmpty() )
1053 wxCommandEvent
dummy;
1058 wxString filterValue;
1061 if( !
m_hint.netName.IsEmpty() )
1063 filterValue =
m_hint.netName;
1064 hintLabel = wxString::Format(
_(
"net '%s'" ),
m_hint.netName );
1066 else if( !
m_hint.fromRef.IsEmpty() )
1068 filterValue =
m_hint.fromRef;
1069 hintLabel = wxString::Format(
_(
"component %s" ),
m_hint.fromRef );
1071 else if( !
m_hint.toRef.IsEmpty() )
1073 filterValue =
m_hint.toRef;
1074 hintLabel = wxString::Format(
_(
"component %s" ),
m_hint.toRef );
1083 wxCommandEvent
dummy;
1093 _(
"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
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
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
BOX2I highlightChainNets(const std::set< wxString > &aNets, const SCH_SHEET_PATH &aPath)
Walk aPath and brighten/un-brighten items whose connection name is in aNets.
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
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...
SCH_SCREEN * LastScreen()
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