45#include <wx/wupdlock.h>
46#include <wx/filedlg.h>
164 const std::vector<std::function<void(
void )>> add_col{
168 wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
169 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
174 wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
175 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
180 wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
181 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
186 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
187 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
193 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
198 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
199 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
204 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
205 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
210 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
211 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
217 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
222 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
223 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
243 const int totalNumColumns = (int) add_col.size() +
m_board->GetCopperLayerCount();
245 if( (
int) cfg->
col_order.size() != totalNumColumns
246 || (
int) cfg->
col_hidden.size() != totalNumColumns )
248 cfg->
col_order.resize( totalNumColumns );
251 for(
int i = 0; i < totalNumColumns; ++i )
261 if( col_order_set.size() != cfg->
col_order.size() )
263 for( std::size_t i = 0; i < cfg->
col_order.size(); ++i )
264 cfg->
col_order[i] =
static_cast<int>( i );
280 const int addModelColumn = i;
282 if( addModelColumn >= (
int) add_col.size() )
285 m_columns[addModelColumn], wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
286 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
310 constexpr int margins = 15;
311 constexpr int extra_width = 30;
313 int headerWidth = GetTextExtent(
m_columns[aModelColumn].display_name ).x;
314 headerWidth += ( aModelColumn ==
COLUMN_NAME ) ? extra_width : margins;
322 if( !aCol || aCol->IsHidden() )
325 const unsigned int modelCol = aCol->GetModelColumn();
330 constexpr int margins = 15;
331 constexpr int extra_width = 30;
332 const bool isNameCol = ( modelCol ==
COLUMN_NAME );
333 const int padding = isNameCol ? extra_width : margins;
338 for(
unsigned int row = 0; row <
m_dataModel->itemCount(); ++row )
340 wxVariant value =
m_dataModel->valueAt( modelCol, row );
341 int textWidth = GetTextExtent( value.GetString() ).x + padding;
342 maxWidth = std::max( maxWidth, textWidth );
350 wxVariant childValue =
m_dataModel->valueForItem( *it, modelCol );
351 int childWidth = GetTextExtent( childValue.GetString() ).x + padding;
354 childWidth += indent;
356 maxWidth = std::max( maxWidth, childWidth );
361 aCol->SetWidth( maxWidth );
371 int minValueWidth = GetTextExtent( wxT(
"00000,000 mm" ) ).x;
372 int minNumberWidth = GetTextExtent( wxT(
"000" ) ).x;
373 int minNameWidth = GetTextExtent( wxT(
"MMMMMMMMMMMM" ) ).x;
379 constexpr int margins = 15;
380 constexpr int extra_width = 30;
382 auto getTargetWidth =
387 case COLUMN_NAME:
return minNameWidth + extra_width;
391 default:
return minValueWidth + margins;
397 for(
size_t i = 0; i <
m_columns.size(); ++i )
399 const int modelColumn = cfg->
col_order[i];
400 int titleSize = GetTextExtent(
m_columns[modelColumn].display_name ).x;
401 titleSize = modelColumn ==
COLUMN_NAME ? titleSize + extra_width : titleSize + margins;
402 const int valSize = getTargetWidth( modelColumn );
403 m_netsList->GetColumn( i )->SetWidth( std::max( titleSize, valSize ) );
411 for(
size_t ii = 0; ii <
m_columns.size(); ++ii )
413 const int modelCol =
static_cast<int>(
m_netsList->GetColumn( ii )->GetModelColumn() );
417 m_netsList->GetColumn( ii )->SetWidth( std::max( newWidth, minWidth ) );
428 if( sortingColumnId != -1 )
432 col->SetSortOrder( sortOrderAsc );
444 for(
unsigned int i = 0; i <
m_netsList->GetColumnCount(); ++i )
446 wxDataViewColumn* col =
m_netsList->GetColumn( i );
448 if(
static_cast<int>( col->GetModelColumn() ) == columnId )
493 for(
const auto& [groupName, groupItem] :
model->getGroupDataViewItems() )
501 wxDataViewItemArray sel;
504 std::vector<int> prev_selected_netcodes;
505 prev_selected_netcodes.reserve( sel.GetCount() );
507 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
510 prev_selected_netcodes.push_back( item->
GetNetCode() );
516 if( wxDataViewColumn* sorting_column =
m_netsList->GetSortingColumn() )
520 sorting_column_id =
static_cast<int>( sorting_column->GetModelColumn() );
521 sort_order_asc = sorting_column->IsSortOrderAscending();
525 sorting_column->UnsetAsSortKey();
542 std::vector<NETINFO_ITEM*> netCodes;
547 netCodes.emplace_back( ni );
550 std::ranges::sort( netCodes,
572 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
577 [&groupName](
const std::pair<wxString, wxDataViewItem>& item )
579 return groupName == item.first;
582 auto tableItem = std::ranges::find_if( groupItems, pred );
584 if( tableItem != groupItems.end() )
594 for(
const int& nc : prev_selected_netcodes )
596 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( nc ) )
598 const std::unique_ptr<LIST_ITEM>& list_item = *r.value();
599 sel.Add( wxDataViewItem( list_item.get() ) );
637 bool matched =
false;
640 if( filterString.Length() == 0 )
644 if( !matched && cfg->
filter_by_netclass && netClassName.Find( filterString ) != wxNOT_FOUND )
648 if( !matched && cfg->
filter_by_net_name && netName.Find( filterString ) != wxNOT_FOUND )
655 matched = !netName.StartsWith( wxT(
"UNCONNECTED-(" ) );
676 const auto type_bits = std::bitset<MAX_STRUCT_TYPE_ID>().set(
PCB_TRACE_T )
681 std::vector<CN_ITEM*> cn_items;
682 cn_items.reserve( 1024 );
684 for(
CN_ITEM* cn_item :
m_board->GetConnectivity()->GetConnectivityAlgo()->ItemList() )
686 if( cn_item->Valid() && type_bits[cn_item->Parent()->Type()] )
687 cn_items.push_back( cn_item );
696std::vector<std::unique_ptr<PCB_NET_INSPECTOR_PANEL::LIST_ITEM>>
699 std::vector<std::unique_ptr<LIST_ITEM>> results;
707 std::unordered_map<int, std::vector<LENGTH_DELAY_CALCULATION_ITEM>> netItemsMap;
708 std::vector<NETINFO_ITEM*> foundNets;
710 auto itemItr = conItems.begin();
711 auto netCodeItr = aNetCodes.begin();
713 while( itemItr != conItems.end() && netCodeItr != aNetCodes.end() )
715 const int curNetCode = ( *netCodeItr )->GetNetCode();
716 const int curItemNetCode = ( *itemItr )->Net();
718 if( curItemNetCode == curNetCode )
720 if( foundNets.empty() || foundNets.back() != *netCodeItr )
721 foundNets.emplace_back( *netCodeItr );
725 netItemsMap[curItemNetCode].emplace_back( std::move( lengthItem ) );
728 else if( curItemNetCode < curNetCode )
731 while( itemItr != conItems.end() && ( *itemItr )->Net() < curNetCode )
734 else if( curItemNetCode > curNetCode )
737 while( netCodeItr != aNetCodes.end() && curItemNetCode > ( *netCodeItr )->GetNetCode() )
744 std::mutex resultsMutex;
747 auto resultsFuture =
tp.submit_loop(
749 [&,
this, calc](
const int i )
751 int netCode = foundNets[i]->GetNetCode();
753 constexpr PATH_OPTIMISATIONS opts = { .OptimiseVias = true,
755 .OptimiseTracesInPads = true,
756 .InferViaInPad = false };
759 netItemsMap[netCode],
767 if( aIncludeZeroPadNets || lengthDetails.NumPads > 0 )
769 std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( foundNets[i] );
771 new_item->SetPadCount( lengthDetails.NumPads );
772 new_item->SetLayerCount( m_board->GetCopperLayerCount() );
773 new_item->SetPadDieLength( lengthDetails.PadToDieLength );
774 new_item->SetPadDieDelay( lengthDetails.PadToDieDelay );
775 new_item->SetViaCount( lengthDetails.NumVias );
776 new_item->SetViaLength( lengthDetails.ViaLength );
777 new_item->SetViaDelay( lengthDetails.ViaDelay );
778 new_item->SetLayerWireLengths( *lengthDetails.LayerLengths );
780 if( m_showTimeDomainDetails )
781 new_item->SetLayerWireDelays( *lengthDetails.LayerDelays );
783 new_item->SetNetChainName( foundNets[i]->GetNetChain() );
784 new_item->SetNetChainLength( lengthDetails.TotalLength() );
785 new_item->SetNetChainDelay( lengthDetails.TotalDelay() );
787 std::scoped_lock lock( resultsMutex );
788 results.emplace_back( std::move( new_item ) );
794 std::map<wxString, int64_t> netChainLengths;
795 std::map<wxString, int64_t> netChainDelays;
797 for(
const std::unique_ptr<LIST_ITEM>& item : results )
799 if( !item->GetNetChainName().IsEmpty() )
801 netChainLengths[item->GetNetChainName()] += item->GetTotalLength();
803 if( m_showTimeDomainDetails )
804 netChainDelays[item->GetNetChainName()] += item->GetTotalDelay();
809 std::map<wxString, double> chainDelayPerIU;
811 auto delayPerIUFor = [&](
const wxString& aChain ) ->
double
813 auto it = chainDelayPerIU.find( aChain );
815 if( it != chainDelayPerIU.end() )
819 chainDelayPerIU.emplace( aChain, perIU );
823 for(
FOOTPRINT* fp : m_board->Footprints() )
825 std::vector<PAD*> chainPads;
827 for(
PAD*
pad : fp->Pads() )
829 if(
pad->GetNet() && !
pad->GetNet()->GetNetChain().IsEmpty() )
830 chainPads.push_back(
pad );
833 for(
size_t i = 0; i < chainPads.size(); ++i )
835 for(
size_t j = i + 1; j < chainPads.size(); ++j )
843 VECTOR2I p1 = chainPads[i]->GetPosition();
844 VECTOR2I p2 = chainPads[j]->GetPosition();
845 int64_t dx = p1.
x - p2.
x;
846 int64_t dy = p1.
y - p2.
y;
847 int64_t dist =
KiROUND( std::hypot( (
double) dx, (
double) dy ) );
850 netChainLengths[
chain] += dist;
852 if( m_showTimeDomainDetails )
859 for( std::unique_ptr<LIST_ITEM>& item : results )
861 if( !item->GetNetChainName().IsEmpty() )
863 item->SetNetChainLength( netChainLengths[item->GetNetChainName()] );
865 if( m_showTimeDomainDetails )
866 item->SetNetChainDelay( netChainDelays[item->GetNetChainName()] );
883 return wxString::Format( wxT(
"%.3d" ), aNet->
GetNetCode() );
895 return wxString::Format( wxT(
"%u" ), aValue );
901 return m_frame->MessageTextFromValue( aValue,
908 return m_frame->MessageTextFromValue( aValue,
919 wxDataViewItemArray sel;
961 const std::vector<BOARD_ITEM*> item{ aBoardItem };
974 if( !IsShownOnScreen() )
978 if( aBoardItems.size()
985 std::vector<NETINFO_ITEM*> changedNets;
993 changedNets.emplace_back( net );
997 changedNets.emplace_back( i->GetNet() );
1001 for(
const PAD*
pad : footprint->Pads() )
1004 changedNets.emplace_back(
pad->GetNet() );
1009 std::ranges::sort( changedNets,
1024 std::vector<NETINFO_ITEM*> netsToUpdate;
1025 std::unordered_set<NETINFO_ITEM*> netsToDelete;
1030 netsToDelete.insert( net );
1034 netsToUpdate.emplace_back( net );
1037 wxWindowUpdateLocker updateLocker(
m_netsList );
1039 std::vector<std::unique_ptr<LIST_ITEM>> newListItems =
calculateNets( aNets,
true );
1041 for( std::unique_ptr<LIST_ITEM>& newListItem : newListItems )
1044 netsToDelete.erase( newListItem->GetNet() );
1046 std::optional<LIST_ITEM_ITER> curNetRow =
m_dataModel->findItem( newListItem->GetNetCode() );
1060 const std::unique_ptr<LIST_ITEM>& curListItem = *curNetRow.value();
1062 if( curListItem->GetNetName() != newListItem->GetNetName() )
1070 curListItem->SetPadCount( newListItem->GetPadCount() );
1071 curListItem->SetPadDieLength( newListItem->GetPadDieLength() );
1072 curListItem->SetPadDieDelay( newListItem->GetPadDieDelay() );
1073 curListItem->SetViaCount( newListItem->GetViaCount() );
1074 curListItem->SetViaLength( newListItem->GetViaLength() );
1075 curListItem->SetViaDelay( newListItem->GetViaDelay() );
1076 curListItem->SetLayerWireLengths( newListItem->GetLayerWireLengths() );
1077 curListItem->SetNetChainName( newListItem->GetNetChainName() );
1078 curListItem->SetNetChainLength( newListItem->GetNetChainLength() );
1079 curListItem->SetNetChainDelay( newListItem->GetNetChainDelay() );
1082 curListItem->SetLayerWireDelays( newListItem->GetLayerWireDelays() );
1096 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1109 if( !IsShownOnScreen() )
1118 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1130 std::vector<BOARD_ITEM*>& aAddedItems,
1131 std::vector<BOARD_ITEM*>& aRemovedItems,
1132 std::vector<BOARD_ITEM*>& aChangedItems )
1134 if( !IsShownOnScreen() )
1137 std::vector<BOARD_ITEM*> allItems{ aAddedItems.begin(), aAddedItems.end() };
1138 allItems.insert( allItems.end(), aRemovedItems.begin(), aRemovedItems.end() );
1139 allItems.insert( allItems.end(), aChangedItems.begin(), aChangedItems.end() );
1149 if( !
m_board->IsHighLightNetON() )
1155 const std::set<int>& selected_codes =
m_board->GetHighLightNetCodes();
1157 wxDataViewItemArray new_selection;
1158 new_selection.Alloc( selected_codes.size() );
1160 for(
const int code : selected_codes )
1162 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( code ) )
1163 new_selection.Add( wxDataViewItem( &***r ) );
1168 if( !new_selection.IsEmpty() )
1169 m_netsList->EnsureVisible( new_selection.Item( 0 ) );
1189 bool multipleSelections =
false;
1192 if(
m_netsList->GetSelectedItemsCount() == 1 )
1198 if(
m_netsList->GetSelectedItemsCount() > 1 )
1199 multipleSelections =
true;
1206 wxEmptyString, wxITEM_NORMAL );
1209 wxMenuItem* clearHighlighting =
new wxMenuItem( &menu,
ID_CLEAR_HIGHLIGHTING,
_(
"Clear Net Highlighting" ),
1210 wxEmptyString, wxITEM_NORMAL );
1211 menu.Append( clearHighlighting );
1216 if( selected_codes.size() == 0 )
1217 clearHighlighting->Enable(
false );
1219 menu.AppendSeparator();
1221 wxMenuItem* renameNet =
new wxMenuItem( &menu,
ID_RENAME_NET,
_(
"Rename Selected Net..." ), wxEmptyString,
1223 menu.Append( renameNet );
1225 wxMenuItem* deleteNet =
new wxMenuItem( &menu,
ID_DELETE_NET,
_(
"Delete Selected Net" ), wxEmptyString,
1227 menu.Append( deleteNet );
1229 menu.AppendSeparator();
1231 wxMenuItem* addNet =
new wxMenuItem( &menu,
ID_ADD_NET,
_(
"Add Net..." ), wxEmptyString, wxITEM_NORMAL );
1232 menu.Append( addNet );
1234 if( !selItem && !multipleSelections )
1237 deleteNet->Enable(
false );
1238 renameNet->Enable(
false );
1242 if( multipleSelections || selItem->
GetIsGroup() )
1244 highlightNet->SetItemLabel(
_(
"Highlight Selected Nets" ) );
1245 renameNet->Enable(
false );
1246 deleteNet->SetItemLabel(
_(
"Delete Selected Nets" ) );
1250 menu.AppendSeparator();
1253 _(
"Remove Selected Custom Group" ),
1254 wxEmptyString, wxITEM_NORMAL );
1255 menu.Append( removeSelectedGroup );
1258 removeSelectedGroup->Enable(
false );
1275 wxString newGroupName;
1279 wxStaticText*
help =
new wxStaticText( &dlg, wxID_ANY,
_(
"(Use /.../ to indicate a regular expression.)" ) );
1283 dlg.GetSizer()->SetSizeHints( &dlg );
1290 if( newGroupName ==
"" )
1294 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1296 return rule->GetPattern() == newGroupName;
1312 m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings()->SetHighlight(
false );
1313 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1314 m_frame->GetCanvas()->Refresh();
1335 menu.AppendSeparator();
1350 if(
m_netsList->GetSelectedItemsCount() == 1 )
1359 wxEmptyString, wxITEM_CHECK );
1360 menu.Append( filterByNetName );
1361 filterByNetName->Check( cfg.filter_by_net_name );
1364 wxEmptyString, wxITEM_CHECK );
1365 menu.Append( filterByNetclass );
1366 filterByNetclass->Check( cfg.filter_by_netclass );
1368 menu.AppendSeparator();
1378 wxEmptyString, wxITEM_CHECK );
1379 menu.Append( groupNetclass );
1383 _(
"Group by Net Chain" ),
1384 wxEmptyString, wxITEM_CHECK );
1385 menu.Append( groupSignal );
1388 menu.AppendSeparator();
1390 wxMenuItem* addGroup =
new wxMenuItem( &menu,
ID_ADD_GROUP,
_(
"Add Custom Group..." ),
1391 wxEmptyString, wxITEM_NORMAL );
1392 menu.Append( addGroup );
1395 _(
"Remove Selected Custom Group" ),
1396 wxEmptyString, wxITEM_NORMAL );
1397 menu.Append( removeSelectedGroup );
1400 removeSelectedGroup->Enable(
false );
1402 wxMenuItem* removeCustomGroups =
new wxMenuItem( &menu,
ID_REMOVE_GROUPS,
_(
"Remove All Custom Groups" ),
1403 wxEmptyString, wxITEM_NORMAL );
1404 menu.Append( removeCustomGroups );
1407 menu.AppendSeparator();
1410 wxEmptyString, wxITEM_CHECK );
1411 menu.Append( showZeroNetPads );
1415 wxEmptyString, wxITEM_CHECK );
1416 menu.Append( showUnconnectedNets );
1419 menu.AppendSeparator();
1422 _(
"Show Time Domain Details" ),
1423 wxEmptyString, wxITEM_CHECK );
1424 menu.Append( showTimeDomainDetails );
1427 menu.AppendSeparator();
1431 wxEmptyString, wxITEM_NORMAL );
1434 menu.AppendSeparator();
1437 wxMenu* colsMenu =
new wxMenu();
1439 menu.AppendSubMenu( colsMenu,
_(
"Show / Hide Columns" ) );
1452 wxEmptyString, wxITEM_CHECK );
1454 target->Append( opt );
1455 opt->Check( !col->IsHidden() );
1458 target->AppendSeparator();
1463 wxEmptyString, wxITEM_CHECK );
1465 target->Append( opt );
1466 opt->Check( !col->IsHidden() );
1473 bool saveAndRebuild =
true;
1475 switch( event.GetId() )
1535 saveAndRebuild =
false;
1540 saveAndRebuild =
false;
1545 saveAndRebuild =
false;
1552 saveAndRebuild =
false;
1556 for(
unsigned int i = 0; i <
m_netsList->GetColumnCount(); ++i )
1559 saveAndRebuild =
false;
1568 col->SetWidth( std::max( col->GetWidth(), 10 ) );
1569 col->SetHidden( !col->IsHidden() );
1574 if( saveAndRebuild )
1584 if(
m_netsList->GetSelectedItemsCount() == 1 )
1588 if( selItem->GetIsGroup() )
1590 const wxString groupName = selItem->GetGroupName();
1592 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1594 return rule->GetPattern() == groupName;
1610 wxFileDialog dlg(
this,
_(
"Save Net Inspector Report File" ),
"",
"",
1612 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1616 if( dlg.ShowModal() == wxID_CANCEL )
1619 wxTextFile f( dlg.GetPath() );
1634 txt += wxString::Format(
_(
"%s (%s)" ),
1640 txt += col.csv_name;
1643 txt += wxT(
"\";" );
1649 const unsigned int num_rows =
m_dataModel->itemCount();
1651 for(
unsigned int row = 0; row < num_rows; row++ )
1655 if( i.GetIsGroup() || i.GetNetCode() == 0 )
1663 txt +=
'"' +
m_dataModel->valueAt( col.num, row ).GetString() + wxT(
"\";" );
1665 txt +=
m_dataModel->valueAt( col.num, row ).GetString() +
';';
1696 wxDataViewItemArray sel;
1701 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1708 renderSettings->
SetHighlight(
true, ( *c )->GetNetCode(),
true );
1721 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1722 m_frame->GetCanvas()->Refresh();
1744 wxString newNetName;
1757 if(
m_board->FindNet( newNetName ) )
1759 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), newNetName ) );
1760 newNetName = wxEmptyString;
1779 if(
m_netsList->GetSelectedItemsCount() == 1 )
1789 wxString shortNetName;
1791 if( fullNetName.Contains( wxT(
"/" ) ) )
1793 netPath = fullNetName.BeforeLast(
'/' ) +
'/';
1794 shortNetName = fullNetName.AfterLast(
'/' );
1798 shortNetName = fullNetName;
1812 unescapedShortName = dlg.
GetValue();
1814 if( unescapedShortName.IsEmpty() )
1821 fullNetName = netPath + shortNetName;
1823 if(
m_board->FindNet( shortNetName ) ||
m_board->FindNet( fullNetName ) )
1825 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), unescapedShortName ) );
1826 unescapedShortName = wxEmptyString;
1836 if( boardItem->GetNet() == net )
1852 boardItem->SetNet( net );
1857 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( net ) )
1858 m_netsList->Select( wxDataViewItem( r.value()->get() ) );
1866 m_frame->GetCanvas()->Refresh();
1876 wxDataViewItemArray sel;
1879 auto delete_one = [
this](
const LIST_ITEM* i )
1881 if( i->GetPadCount() == 0
1882 ||
IsOK(
this, wxString::Format(
_(
"Net '%s' is in use. Delete anyway?" ), i->GetNetName() ) ) )
1886 int removedCode = i->GetNetCode();
1888 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
1893 if( boardItem && boardItem->GetNetCode() == removedCode )
1900 text->ClearRenderCache();
1901 text->ClearBoundingBoxCache();
1908 m_board->Remove( i->GetNet() );
1915 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1922 &&
IsOK(
this, wxString::Format(
_(
"Delete all nets in group '%s'?" ), ii->
GetGroupName() ) ) )
1926 std::vector<const LIST_ITEM*> children;
1974 bool displayed =
false;
1976 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount() && !displayed; ++ii )
1978 if(
m_netsList->GetColumn( ii )->GetWidth() > 0 )
2000 wxDataViewColumn* sortingCol =
m_netsList->GetSortingColumn();
2001 cfg.sorting_column = sortingCol ?
static_cast<int>( sortingCol->GetModelColumn() ) : -1;
2002 cfg.sort_order_asc = sortingCol ? sortingCol->IsSortOrderAscending() :
true;
2005 cfg.col_order.resize(
m_dataModel->columnCount() );
2006 cfg.col_widths.resize(
m_dataModel->columnCount() );
2007 cfg.col_hidden.resize(
m_dataModel->columnCount() );
2009 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount(); ++ii )
2011 cfg.col_order[ii] = (int)
m_netsList->GetColumn( ii )->GetModelColumn();
2012 cfg.col_widths[ii] =
m_netsList->GetColumn( ii )->GetWidth();
2013 cfg.col_hidden[ii] =
m_netsList->GetColumn( ii )->IsHidden();
2017 cfg.expanded_rows.clear();
2018 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
2020 for( std::pair<wxString, wxDataViewItem>& item : groupItems )
2023 cfg.expanded_rows.push_back( item.first );
2027 cfg.custom_group_rules.clear();
2030 cfg.custom_group_rules.push_back( rule->GetPattern() );
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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...
Information pertinent to a Pcbnew printed circuit board.
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
An abstract base class for deriving all objects that can be added to a VIEW.
Lightweight class which holds a pad, via, or a routed trace outline.
Class which calculates lengths (and associated routing statistics) in a BOARD context.
LENGTH_DELAY_STATS CalculateLengthDetails(std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, PATH_OPTIMISATIONS aOptimisations, const PAD *aStartPad=nullptr, const PAD *aEndPad=nullptr, LENGTH_DELAY_LAYER_OPT aLayerOpt=LENGTH_DELAY_LAYER_OPT::NO_LAYER_DETAIL, LENGTH_DELAY_DOMAIN_OPT aDomain=LENGTH_DELAY_DOMAIN_OPT::NO_DELAY_DETAIL, LENGTH_DELAY_ITEM_DETAILS *aPerItemLengthDelays=nullptr) const
Calculates the electrical length of the given items.
LENGTH_DELAY_CALCULATION_ITEM GetLengthCalculationItem(const BOARD_CONNECTED_ITEM *aBoardItem) const
Return a LENGTH_CALCULATION_ITEM constructed from the given BOARD_CONNECTED_ITEM.
A collection of nets and the parameters used to route or test these nets.
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Handle the data for a net.
const wxString & GetNetChain() const
void SetNetname(const wxString &aNewName)
Set the long netname to aNetName, the short netname to the last token in the long netname's path,...
const wxString & GetNetname() const
NET_INSPECTOR_PANEL(wxWindow *parent, EDA_BASE_FRAME *aFrame, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1, -1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxDataViewCtrl * m_netsList
wxSearchCtrl * m_searchCtrl
The main frame for Pcbnew.
Data model for display in the Net Inspector panel.
Primary data item for entries in the Net Inspector list.
auto ChildrenBegin() const
unsigned int ChildrenCount() const
const wxString & GetGroupName() const
NETINFO_ITEM * GetNet() const
void OnBoardItemRemoved(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
void OnBoardHighlightNetChanged(BOARD &aBoard) override
void generateReport()
Generates a CSV report from currently disaplyed data.
PCB_NET_INSPECTOR_PANEL(wxWindow *parent, PCB_EDIT_FRAME *aFrame)
int getMinColumnWidth(int aModelColumn) const
Computes the minimum display width for a column based on its header text.
void onDeleteSelectedNet()
Deletes a selected net.
bool restoreSortColumn(int sortingColumnId, bool sortOrderAsc) const
Sets the sort column in the grid to that showing the given model ID column.
void OnBoardItemsChanged(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
void adjustListColumnSizes(PANEL_NET_INSPECTOR_SETTINGS *cfg) const
Adjust the sizing of list columns.
BOARD * m_board
Parent BOARD.
void OnSearchTextChanged(wxCommandEvent &event) override
void updateDisplayedRowValues(const std::optional< LIST_ITEM_ITER > &aRow) const
Refreshes displayed data for the given rows.
void onAddNet()
Adds a new user-specified net to the board.
PCB_EDIT_FRAME * m_frame
Owning edit frame.
void OnBoardItemsRemoved(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
void onClearHighlighting()
Clears highlighting from nets.
void onContextMenuSelection(wxCommandEvent &event)
Handle a net row(s) context menu selection.
static wxString formatNetCode(const NETINFO_ITEM *aNet)
void OnBoardChanged() override
Update panel when board is changed.
void generateShowHideColumnMenu(wxMenu *target)
Generates a sub-menu for the show / hide columns submenu.
std::vector< std::unique_ptr< LIST_ITEM > > calculateNets(const std::vector< NETINFO_ITEM * > &aNetCodes, bool aIncludeZeroPadNets) const
Calculates the length statistics for each given netcode.
void autosizeColumn(wxDataViewColumn *aCol)
Auto-sizes a column to fit both its header text and content.
wxDataViewColumn * m_contextMenuColumn
Tracks which column the header context menu was opened for.
bool m_showTimeDomainDetails
static wxString formatCount(unsigned int aValue)
std::vector< std::unique_ptr< EDA_COMBINED_MATCHER > > m_custom_group_rules
Custom net grouping rules.
std::vector< CN_ITEM * > relevantConnectivityItems() const
Fetches an ordered (by NetCode) list of all board connectivity items.
bool m_showUnconnectedNets
void highlightSelectedNets()
Highlight the currently selected net.
void updateNets(const std::vector< NETINFO_ITEM * > &aNets) const
Updates displayed statistics for the given nets.
void OnHeaderContextMenu(wxDataViewEvent &event)
void OnBoardItemsAdded(BOARD &aBoard, std::vector< BOARD_ITEM * > &aBoardItems) override
void OnLanguageChangedImpl() override
Reloads strings on an application language change.
void onAddGroup()
Adds a custom display grouping of nets.
void OnNetsListContextMenu(wxDataViewEvent &event)
void OnBoardNetSettingsChanged(BOARD &aBoard) override
void OnBoardCompositeUpdate(BOARD &aBoard, std::vector< BOARD_ITEM * > &aAddedItems, std::vector< BOARD_ITEM * > &aRemovedItems, std::vector< BOARD_ITEM * > &aChangedItems) override
void OnNetsListItemActivated(wxDataViewEvent &event)
void OnColumnSorted(wxDataViewEvent &event)
void onRemoveSelectedGroup()
Removes a custom display grouping.
@ ID_SHOW_UNCONNECTED_NETS
@ ID_REMOVE_SELECTED_GROUP
@ ID_HIGHLIGHT_SELECTED_NETS
@ ID_SHOW_TIME_DOMAIN_DETAILS
virtual ~PCB_NET_INSPECTOR_PANEL()
void buildColumns()
Build the required columns in the net inspector grid.
void OnBoardItemAdded(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
void OnParentSetupChanged() override
Updates the netlist based on global board changes (e.g.
bool netFilterMatches(NETINFO_ITEM *aNet, PANEL_NET_INSPECTOR_SETTINGS *cfg=nullptr) const
Filter to determine whether a board net should be included in the net inspector.
void OnConfigButton(wxCommandEvent &event) override
void buildNetsList(bool rebuildColumns=false)
Rebuilds the net inspector list, removing all previous entries.
wxString formatLength(int64_t aValue) const
void SaveSettings() override
Persist the net inspector configuration to project / global settings.
void onRenameSelectedNet()
Renames a selected net.
void onUnitsChanged(wxCommandEvent &event)
Handle an application-level change of units.
void OnExpandCollapseRow(wxCommandEvent &event)
void updateBoardItems(const std::vector< BOARD_ITEM * > &aBoardItems)
Unified handling of added / deleted / modified board items.
wxString formatDelay(int64_t aValue) const
wxObjectDataPtr< DATA_MODEL > m_dataModel
The bound data model to display.
wxDataViewColumn * getDisplayedColumnForModelField(int columnId) const
Fetches the displayed grid view column for the given model column ID.
static wxString formatNetName(const NETINFO_ITEM *aNet)
void OnBoardItemChanged(BOARD &aBoard, BOARD_ITEM *aBoardItem) override
std::vector< COLUMN_DESC > m_columns
All displayed (or hidden) columns.
@ COLUMN_NET_CHAIN_LENGTH
void OnShowPanel() override
Prepare the panel when shown in the editor.
virtual SETTINGS_MANAGER & GetSettingsManager() const
The project local settings are things that are attached to a particular project, but also might be pa...
PANEL_NET_INSPECTOR_SETTINGS m_NetInspectorPanel
The state of the net inspector panel.
virtual PROJECT_LOCAL_SETTINGS & GetLocalSettings() const
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
wxBoxSizer * m_ContentSizer
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
void SetTextValidator(const wxTextValidator &validator)
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
#define CANDIDATE
flag indicating that the structure is connected
Abstract pattern-matching tool and implementations.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
@ REPAINT
Item needs to be redrawn.
@ GEOMETRY
Position or shape has changed.
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
double ChainBridgingDelayPerMm(const BOARD *aBoard, const wxString &aNetChain)
Pick a single per-IU-per-mm delay for a given chain.
PGM_BASE & Pgm()
The global program "get" accessor.
static bool highlightNet(TOOL_MANAGER *aToolMgr, const VECTOR2D &aPosition)
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
Holds length measurement result details and statistics.
bool operator()(const CN_ITEM *a, const CN_ITEM *b) const
bool operator()(int a, const CN_ITEM *b) const
bool operator()(const CN_ITEM *a, int b) const
Persisted state for the net inspector panel.
std::vector< int > col_order
std::vector< bool > col_hidden
std::vector< wxString > expanded_rows
std::vector< int > col_widths
bool show_time_domain_details
std::vector< wxString > custom_group_rules
const SHAPE_LINE_CHAIN chain
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Custom text control validator definitions.
VECTOR2< int32_t > VECTOR2I
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.