47#include <wx/wupdlock.h>
48#include <wx/filedlg.h>
170 const std::vector<std::function<void(
void )>> add_col{
174 wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
175 wxDATAVIEW_COL_RESIZABLE|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_LEFT,
187 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
192 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
193 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
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 );
216 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
217 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
223 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
229 wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_REORDERABLE
230 | wxDATAVIEW_COL_SORTABLE );
235 wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
236 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
256 const int totalNumColumns = (int) add_col.size() +
m_board->GetCopperLayerCount();
258 if( (
int) cfg->
col_order.size() != totalNumColumns
259 || (
int) cfg->
col_hidden.size() != totalNumColumns )
261 cfg->
col_order.resize( totalNumColumns );
264 for(
int i = 0; i < totalNumColumns; ++i )
274 if( col_order_set.size() != cfg->
col_order.size() )
276 for( std::size_t i = 0; i < cfg->
col_order.size(); ++i )
277 cfg->
col_order[i] =
static_cast<int>( i );
293 const int addModelColumn = i;
295 if( addModelColumn >= (
int) add_col.size() )
298 m_columns[addModelColumn], wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER,
299 wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_REORDERABLE|wxDATAVIEW_COL_SORTABLE );
323 constexpr int margins = 15;
324 constexpr int extra_width = 30;
326 int headerWidth = GetTextExtent(
m_columns[aModelColumn].display_name ).x;
327 headerWidth += ( aModelColumn ==
COLUMN_NAME ) ? extra_width : margins;
335 if( !aCol || aCol->IsHidden() )
338 const unsigned int modelCol = aCol->GetModelColumn();
343 constexpr int margins = 15;
344 constexpr int extra_width = 30;
345 const bool isNameCol = ( modelCol ==
COLUMN_NAME );
346 const int padding = isNameCol ? extra_width : margins;
351 for(
unsigned int row = 0; row <
m_dataModel->itemCount(); ++row )
353 wxVariant value =
m_dataModel->valueAt( modelCol, row );
354 int textWidth = GetTextExtent( value.GetString() ).x + padding;
355 maxWidth = std::max( maxWidth, textWidth );
363 wxVariant childValue =
m_dataModel->valueForItem( *it, modelCol );
364 int childWidth = GetTextExtent( childValue.GetString() ).x + padding;
367 childWidth += indent;
369 maxWidth = std::max( maxWidth, childWidth );
374 aCol->SetWidth( maxWidth );
384 int minValueWidth = GetTextExtent( wxT(
"00000,000 mm" ) ).x;
385 int minNumberWidth = GetTextExtent( wxT(
"000" ) ).x;
386 int minNameWidth = GetTextExtent( wxT(
"MMMMMMMMMMMM" ) ).x;
392 constexpr int margins = 15;
393 constexpr int extra_width = 30;
395 auto getTargetWidth =
400 case COLUMN_NAME:
return minNameWidth + extra_width;
404 default:
return minValueWidth + margins;
410 for(
size_t i = 0; i <
m_columns.size(); ++i )
412 const int modelColumn = cfg->
col_order[i];
413 int titleSize = GetTextExtent(
m_columns[modelColumn].display_name ).x;
414 titleSize = modelColumn ==
COLUMN_NAME ? titleSize + extra_width : titleSize + margins;
415 const int valSize = getTargetWidth( modelColumn );
416 m_netsList->GetColumn( i )->SetWidth( std::max( titleSize, valSize ) );
424 for(
size_t ii = 0; ii <
m_columns.size(); ++ii )
426 const int modelCol =
static_cast<int>(
m_netsList->GetColumn( ii )->GetModelColumn() );
430 m_netsList->GetColumn( ii )->SetWidth( std::max( newWidth, minWidth ) );
441 if( sortingColumnId != -1 )
445 col->SetSortOrder( sortOrderAsc );
457 for(
unsigned int i = 0; i <
m_netsList->GetColumnCount(); ++i )
459 wxDataViewColumn* col =
m_netsList->GetColumn( i );
461 if(
static_cast<int>( col->GetModelColumn() ) == columnId )
507 for(
const auto& [groupName, groupItem] :
model->getGroupDataViewItems() )
515 wxDataViewItemArray sel;
518 std::vector<int> prev_selected_netcodes;
519 prev_selected_netcodes.reserve( sel.GetCount() );
521 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
524 prev_selected_netcodes.push_back( item->
GetNetCode() );
530 if( wxDataViewColumn* sorting_column =
m_netsList->GetSortingColumn() )
534 sorting_column_id =
static_cast<int>( sorting_column->GetModelColumn() );
535 sort_order_asc = sorting_column->IsSortOrderAscending();
539 sorting_column->UnsetAsSortKey();
556 std::vector<NETINFO_ITEM*> netCodes;
561 netCodes.emplace_back( ni );
564 std::ranges::sort( netCodes,
586 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
591 [&groupName](
const std::pair<wxString, wxDataViewItem>& item )
593 return groupName == item.first;
596 auto tableItem = std::ranges::find_if( groupItems, pred );
598 if( tableItem != groupItems.end() )
608 for(
const int& nc : prev_selected_netcodes )
610 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( nc ) )
612 const std::unique_ptr<LIST_ITEM>& list_item = *r.value();
613 sel.Add( wxDataViewItem( list_item.get() ) );
651 bool matched =
false;
654 if( filterString.Length() == 0 )
658 if( !matched && cfg->
filter_by_netclass && netClassName.Find( filterString ) != wxNOT_FOUND )
662 if( !matched && cfg->
filter_by_net_name && netName.Find( filterString ) != wxNOT_FOUND )
669 matched = !netName.StartsWith( wxT(
"UNCONNECTED-(" ) );
690 const auto type_bits = std::bitset<MAX_STRUCT_TYPE_ID>().set(
PCB_TRACE_T )
695 std::vector<CN_ITEM*> cn_items;
696 cn_items.reserve( 1024 );
698 for(
CN_ITEM* cn_item :
m_board->GetConnectivity()->GetConnectivityAlgo()->ItemList() )
700 if( cn_item->Valid() && type_bits[cn_item->Parent()->Type()] )
701 cn_items.push_back( cn_item );
710std::vector<std::unique_ptr<PCB_NET_INSPECTOR_PANEL::LIST_ITEM>>
713 std::vector<std::unique_ptr<LIST_ITEM>> results;
716 std::vector<NETINFO_ITEM*> netCodes( aNetCodes );
717 std::set<wxString> chains;
721 if( !net->GetNetChain().IsEmpty() )
722 chains.insert( net->GetNetChain() );
725 if( !chains.empty() )
729 if( chains.count( net->GetNetChain() ) )
730 netCodes.push_back( net );
733 std::sort( netCodes.begin(), netCodes.end(),
736 return a->GetNetCode() < b->GetNetCode();
738 netCodes.erase( std::unique( netCodes.begin(), netCodes.end() ), netCodes.end() );
747 std::unordered_map<int, std::vector<LENGTH_DELAY_CALCULATION_ITEM>> netItemsMap;
748 std::vector<NETINFO_ITEM*> foundNets;
750 auto itemItr = conItems.begin();
751 auto netCodeItr = netCodes.begin();
753 while( itemItr != conItems.end() && netCodeItr != netCodes.end() )
755 const int curNetCode = ( *netCodeItr )->GetNetCode();
756 const int curItemNetCode = ( *itemItr )->Net();
758 if( curItemNetCode == curNetCode )
760 if( foundNets.empty() || foundNets.back() != *netCodeItr )
761 foundNets.emplace_back( *netCodeItr );
765 netItemsMap[curItemNetCode].emplace_back( std::move( lengthItem ) );
768 else if( curItemNetCode < curNetCode )
771 while( itemItr != conItems.end() && ( *itemItr )->Net() < curNetCode )
774 else if( curItemNetCode > curNetCode )
777 while( netCodeItr != netCodes.end() && curItemNetCode > ( *netCodeItr )->GetNetCode() )
784 std::mutex resultsMutex;
787 auto resultsFuture =
tp.submit_loop(
789 [&,
this, calc](
const int i )
791 int netCode = foundNets[i]->GetNetCode();
793 constexpr PATH_OPTIMISATIONS opts = { .OptimiseVias = true,
795 .OptimiseTracesInPads = true,
796 .InferViaInPad = false };
799 netItemsMap[netCode],
807 if( aIncludeZeroPadNets || lengthDetails.NumPads > 0 )
809 std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( foundNets[i] );
811 new_item->SetPadCount( lengthDetails.NumPads );
812 new_item->SetLayerCount( m_board->GetCopperLayerCount() );
813 new_item->SetPadDieLength( lengthDetails.PadToDieLength );
814 new_item->SetPadDieDelay( lengthDetails.PadToDieDelay );
815 new_item->SetViaCount( lengthDetails.NumVias );
816 new_item->SetViaLength( lengthDetails.ViaLength );
817 new_item->SetViaDelay( lengthDetails.ViaDelay );
818 new_item->SetLayerWireLengths( *lengthDetails.LayerLengths );
823 int64_t unroutedLength = 0;
825 if( RN_NET* rnNet = m_board->GetConnectivity()->GetRatsnestForNet( netCode ) )
826 unroutedLength = rnNet->GetTotalAirlineLength();
828 new_item->SetUnroutedLength( unroutedLength );
830 if( m_showTimeDomainDetails )
831 new_item->SetLayerWireDelays( *lengthDetails.LayerDelays );
833 new_item->SetNetChainName( foundNets[i]->GetNetChain() );
835 std::scoped_lock lock( resultsMutex );
836 results.emplace_back( std::move( new_item ) );
842 std::map<wxString, int64_t> netChainLengths;
843 std::map<wxString, int64_t> netChainDelays;
845 for(
const std::unique_ptr<LIST_ITEM>& item : results )
847 if( !item->GetNetChainName().IsEmpty() )
849 netChainLengths[item->GetNetChainName()] += item->GetTotalLength();
851 if( m_showTimeDomainDetails )
852 netChainDelays[item->GetNetChainName()] += item->GetTotalDelay();
857 std::map<wxString, double> chainDelayPerIU;
859 auto delayPerIUFor = [&](
const wxString& aChain ) ->
double
861 auto it = chainDelayPerIU.find( aChain );
863 if( it != chainDelayPerIU.end() )
867 chainDelayPerIU.emplace( aChain, perIU );
871 for(
FOOTPRINT* fp : m_board->Footprints() )
873 std::vector<PAD*> chainPads;
875 for(
PAD*
pad : fp->Pads() )
877 if(
pad->GetNet() && !
pad->GetNet()->GetNetChain().IsEmpty() )
878 chainPads.push_back(
pad );
881 for(
size_t i = 0; i < chainPads.size(); ++i )
883 for(
size_t j = i + 1; j < chainPads.size(); ++j )
891 VECTOR2I p1 = chainPads[i]->GetPosition();
892 VECTOR2I p2 = chainPads[j]->GetPosition();
893 int64_t dx = p1.
x - p2.
x;
894 int64_t dy = p1.
y - p2.
y;
895 int64_t dist =
KiROUND( std::hypot( (
double) dx, (
double) dy ) );
898 netChainLengths[
chain] += dist;
900 if( m_showTimeDomainDetails )
907 for( std::unique_ptr<LIST_ITEM>& item : results )
909 if( !item->GetNetChainName().IsEmpty() )
911 item->SetNetChainLength( netChainLengths[item->GetNetChainName()] );
913 if( m_showTimeDomainDetails )
914 item->SetNetChainDelay( netChainDelays[item->GetNetChainName()] );
931 return wxString::Format( wxT(
"%.3d" ), aNet->
GetNetCode() );
943 return wxString::Format( wxT(
"%u" ), aValue );
949 return m_frame->MessageTextFromValue( aValue,
956 return m_frame->MessageTextFromValue( aValue,
967 wxDataViewItemArray sel;
1013 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1026 if( !IsShownOnScreen() )
1030 if( aBoardItems.size()
1031 >
static_cast<size_t>(
ADVANCED_CFG::GetCfg().m_NetInspectorBulkUpdateOptimisationThreshold ) )
1037 std::vector<NETINFO_ITEM*> changedNets;
1045 changedNets.emplace_back( net );
1049 changedNets.emplace_back( i->GetNet() );
1053 for(
const PAD*
pad : footprint->Pads() )
1056 changedNets.emplace_back(
pad->GetNet() );
1061 std::ranges::sort( changedNets,
1076 std::vector<NETINFO_ITEM*> netsToUpdate;
1077 std::unordered_set<NETINFO_ITEM*> netsToDelete;
1082 netsToDelete.insert( net );
1086 netsToUpdate.emplace_back( net );
1089 wxWindowUpdateLocker updateLocker(
m_netsList );
1091 std::vector<std::unique_ptr<LIST_ITEM>> newListItems =
calculateNets( aNets,
true );
1093 for( std::unique_ptr<LIST_ITEM>& newListItem : newListItems )
1096 netsToDelete.erase( newListItem->GetNet() );
1098 std::optional<LIST_ITEM_ITER> curNetRow =
m_dataModel->findItem( newListItem->GetNetCode() );
1112 const std::unique_ptr<LIST_ITEM>& curListItem = *curNetRow.value();
1114 if( curListItem->GetNetName() != newListItem->GetNetName() )
1122 curListItem->SetPadCount( newListItem->GetPadCount() );
1123 curListItem->SetPadDieLength( newListItem->GetPadDieLength() );
1124 curListItem->SetPadDieDelay( newListItem->GetPadDieDelay() );
1125 curListItem->SetViaCount( newListItem->GetViaCount() );
1126 curListItem->SetViaLength( newListItem->GetViaLength() );
1127 curListItem->SetViaDelay( newListItem->GetViaDelay() );
1128 curListItem->SetUnroutedLength( newListItem->GetUnroutedLength() );
1129 curListItem->SetLayerWireLengths( newListItem->GetLayerWireLengths() );
1130 curListItem->SetNetChainName( newListItem->GetNetChainName() );
1131 curListItem->SetNetChainLength( newListItem->GetNetChainLength() );
1132 curListItem->SetNetChainDelay( newListItem->GetNetChainDelay() );
1135 curListItem->SetLayerWireDelays( newListItem->GetLayerWireDelays() );
1149 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1162 if( !IsShownOnScreen() )
1171 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1183 std::vector<BOARD_ITEM*>& aAddedItems,
1184 std::vector<BOARD_ITEM*>& aRemovedItems,
1185 std::vector<BOARD_ITEM*>& aChangedItems )
1187 if( !IsShownOnScreen() )
1190 std::vector<BOARD_ITEM*> allItems{ aAddedItems.begin(), aAddedItems.end() };
1191 allItems.insert( allItems.end(), aRemovedItems.begin(), aRemovedItems.end() );
1192 allItems.insert( allItems.end(), aChangedItems.begin(), aChangedItems.end() );
1202 if( !
m_board->IsHighLightNetON() )
1208 const std::set<int>& selected_codes =
m_board->GetHighLightNetCodes();
1210 wxDataViewItemArray new_selection;
1211 new_selection.Alloc( selected_codes.size() );
1213 for(
const int code : selected_codes )
1215 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( code ) )
1216 new_selection.Add( wxDataViewItem( &***r ) );
1221 if( !new_selection.IsEmpty() )
1222 m_netsList->EnsureVisible( new_selection.Item( 0 ) );
1252 bool multipleSelections =
false;
1255 if(
m_netsList->GetSelectedItemsCount() == 1 )
1261 if(
m_netsList->GetSelectedItemsCount() > 1 )
1262 multipleSelections =
true;
1269 wxEmptyString, wxITEM_NORMAL );
1272 wxMenuItem* clearHighlighting =
new wxMenuItem( &menu,
ID_CLEAR_HIGHLIGHTING,
_(
"Clear Net Highlighting" ),
1273 wxEmptyString, wxITEM_NORMAL );
1274 menu.Append( clearHighlighting );
1279 if( selected_codes.size() == 0 )
1280 clearHighlighting->Enable(
false );
1282 menu.AppendSeparator();
1284 wxMenuItem* renameNet =
new wxMenuItem( &menu,
ID_RENAME_NET,
_(
"Rename Selected Net..." ), wxEmptyString,
1286 menu.Append( renameNet );
1288 wxMenuItem* deleteNet =
new wxMenuItem( &menu,
ID_DELETE_NET,
_(
"Delete Selected Net" ), wxEmptyString,
1290 menu.Append( deleteNet );
1292 menu.AppendSeparator();
1294 wxMenuItem* addNet =
new wxMenuItem( &menu,
ID_ADD_NET,
_(
"Add Net..." ), wxEmptyString, wxITEM_NORMAL );
1295 menu.Append( addNet );
1297 if( !selItem && !multipleSelections )
1300 deleteNet->Enable(
false );
1301 renameNet->Enable(
false );
1305 if( multipleSelections || selItem->
GetIsGroup() )
1307 highlightNet->SetItemLabel(
_(
"Highlight Selected Nets" ) );
1308 renameNet->Enable(
false );
1309 deleteNet->SetItemLabel(
_(
"Delete Selected Nets" ) );
1313 menu.AppendSeparator();
1316 _(
"Remove Selected Custom Group" ),
1317 wxEmptyString, wxITEM_NORMAL );
1318 menu.Append( removeSelectedGroup );
1321 removeSelectedGroup->Enable(
false );
1338 wxString newGroupName;
1342 wxStaticText*
help =
new wxStaticText( &dlg, wxID_ANY,
_(
"(Use /.../ to indicate a regular expression.)" ) );
1346 dlg.GetSizer()->SetSizeHints( &dlg );
1353 if( newGroupName ==
"" )
1357 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1359 return rule->GetPattern() == newGroupName;
1375 m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings()->SetHighlight(
false );
1376 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1377 m_frame->GetCanvas()->Refresh();
1398 menu.AppendSeparator();
1413 if(
m_netsList->GetSelectedItemsCount() == 1 )
1422 wxEmptyString, wxITEM_CHECK );
1423 menu.Append( filterByNetName );
1424 filterByNetName->Check( cfg.filter_by_net_name );
1427 wxEmptyString, wxITEM_CHECK );
1428 menu.Append( filterByNetclass );
1429 filterByNetclass->Check( cfg.filter_by_netclass );
1431 menu.AppendSeparator();
1441 wxEmptyString, wxITEM_CHECK );
1442 menu.Append( groupNetclass );
1446 _(
"Group by Net Chain" ),
1447 wxEmptyString, wxITEM_CHECK );
1448 menu.Append( groupSignal );
1451 menu.AppendSeparator();
1453 wxMenuItem* addGroup =
new wxMenuItem( &menu,
ID_ADD_GROUP,
_(
"Add Custom Group..." ),
1454 wxEmptyString, wxITEM_NORMAL );
1455 menu.Append( addGroup );
1458 _(
"Remove Selected Custom Group" ),
1459 wxEmptyString, wxITEM_NORMAL );
1460 menu.Append( removeSelectedGroup );
1463 removeSelectedGroup->Enable(
false );
1465 wxMenuItem* removeCustomGroups =
new wxMenuItem( &menu,
ID_REMOVE_GROUPS,
_(
"Remove All Custom Groups" ),
1466 wxEmptyString, wxITEM_NORMAL );
1467 menu.Append( removeCustomGroups );
1470 menu.AppendSeparator();
1473 wxEmptyString, wxITEM_CHECK );
1474 menu.Append( showZeroNetPads );
1478 wxEmptyString, wxITEM_CHECK );
1479 menu.Append( showUnconnectedNets );
1482 menu.AppendSeparator();
1485 _(
"Show Time Domain Details" ),
1486 wxEmptyString, wxITEM_CHECK );
1487 menu.Append( showTimeDomainDetails );
1490 menu.AppendSeparator();
1494 wxEmptyString, wxITEM_NORMAL );
1497 menu.AppendSeparator();
1500 wxMenu* colsMenu =
new wxMenu();
1502 menu.AppendSubMenu( colsMenu,
_(
"Show / Hide Columns" ) );
1515 wxEmptyString, wxITEM_CHECK );
1517 target->Append( opt );
1518 opt->Check( !col->IsHidden() );
1521 target->AppendSeparator();
1526 wxEmptyString, wxITEM_CHECK );
1528 target->Append( opt );
1529 opt->Check( !col->IsHidden() );
1536 bool saveAndRebuild =
true;
1538 switch( event.GetId() )
1598 saveAndRebuild =
false;
1603 saveAndRebuild =
false;
1608 saveAndRebuild =
false;
1615 saveAndRebuild =
false;
1619 for(
unsigned int i = 0; i <
m_netsList->GetColumnCount(); ++i )
1622 saveAndRebuild =
false;
1631 col->SetWidth( std::max( col->GetWidth(), 10 ) );
1632 col->SetHidden( !col->IsHidden() );
1637 if( saveAndRebuild )
1647 if(
m_netsList->GetSelectedItemsCount() == 1 )
1651 if( selItem->GetIsGroup() )
1653 const wxString groupName = selItem->GetGroupName();
1655 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1657 return rule->GetPattern() == groupName;
1673 wxFileDialog dlg(
this,
_(
"Save Net Inspector Report File" ),
"",
"",
1675 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1679 if( dlg.ShowModal() == wxID_CANCEL )
1682 wxTextFile f( dlg.GetPath() );
1697 txt += wxString::Format(
_(
"%s (%s)" ),
1703 txt += col.csv_name;
1706 txt += wxT(
"\";" );
1712 const unsigned int num_rows =
m_dataModel->itemCount();
1714 for(
unsigned int row = 0; row < num_rows; row++ )
1718 if( i.GetIsGroup() || i.GetNetCode() == 0 )
1726 txt +=
'"' +
m_dataModel->valueAt( col.num, row ).GetString() + wxT(
"\";" );
1728 txt +=
m_dataModel->valueAt( col.num, row ).GetString() +
';';
1759 wxDataViewItemArray sel;
1764 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1771 renderSettings->
SetHighlight(
true, ( *c )->GetNetCode(),
true );
1784 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1785 m_frame->GetCanvas()->Refresh();
1807 wxString newNetName;
1820 if(
m_board->FindNet( newNetName ) )
1822 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), newNetName ) );
1823 newNetName = wxEmptyString;
1842 if(
m_netsList->GetSelectedItemsCount() == 1 )
1852 wxString shortNetName;
1854 if( fullNetName.Contains( wxT(
"/" ) ) )
1856 netPath = fullNetName.BeforeLast(
'/' ) +
'/';
1857 shortNetName = fullNetName.AfterLast(
'/' );
1861 shortNetName = fullNetName;
1875 unescapedShortName = dlg.
GetValue();
1877 if( unescapedShortName.IsEmpty() )
1884 fullNetName = netPath + shortNetName;
1886 if(
m_board->FindNet( shortNetName ) ||
m_board->FindNet( fullNetName ) )
1888 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), unescapedShortName ) );
1889 unescapedShortName = wxEmptyString;
1899 if( boardItem->GetNet() == net )
1915 boardItem->SetNet( net );
1920 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( net ) )
1921 m_netsList->Select( wxDataViewItem( r.value()->get() ) );
1929 m_frame->GetCanvas()->Refresh();
1939 wxDataViewItemArray sel;
1942 auto delete_one = [
this](
const LIST_ITEM* i )
1944 if( i->GetPadCount() == 0
1945 ||
IsOK(
this, wxString::Format(
_(
"Net '%s' is in use. Delete anyway?" ), i->GetNetName() ) ) )
1949 int removedCode = i->GetNetCode();
1951 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
1956 if( boardItem && boardItem->GetNetCode() == removedCode )
1963 text->ClearRenderCache();
1964 text->ClearBoundingBoxCache();
1971 m_board->Remove( i->GetNet() );
1978 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1985 &&
IsOK(
this, wxString::Format(
_(
"Delete all nets in group '%s'?" ), ii->
GetGroupName() ) ) )
1989 std::vector<const LIST_ITEM*> children;
2037 bool displayed =
false;
2039 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount() && !displayed; ++ii )
2041 if(
m_netsList->GetColumn( ii )->GetWidth() > 0 )
2063 wxDataViewColumn* sortingCol =
m_netsList->GetSortingColumn();
2064 cfg.sorting_column = sortingCol ?
static_cast<int>( sortingCol->GetModelColumn() ) : -1;
2065 cfg.sort_order_asc = sortingCol ? sortingCol->IsSortOrderAscending() :
true;
2068 cfg.col_order.resize(
m_dataModel->columnCount() );
2069 cfg.col_widths.resize(
m_dataModel->columnCount() );
2070 cfg.col_hidden.resize(
m_dataModel->columnCount() );
2072 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount(); ++ii )
2074 cfg.col_order[ii] = (int)
m_netsList->GetColumn( ii )->GetModelColumn();
2075 cfg.col_widths[ii] =
m_netsList->GetColumn( ii )->GetWidth();
2076 cfg.col_hidden[ii] =
m_netsList->GetColumn( ii )->IsHidden();
2080 cfg.expanded_rows.clear();
2081 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
2083 for( std::pair<wxString, wxDataViewItem>& item : groupItems )
2086 cfg.expanded_rows.push_back( item.first );
2090 cfg.custom_group_rules.clear();
2093 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_CONNECTED_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)
WX_DATAVIEWCTRL * 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, const double aDefaultBridgeUnitDelay)
Pick a single per-IU-per-mm delay for a given chain.
PGM_BASE & Pgm()
The global program "get" accessor.
Class that computes missing connections on a PCB.
static bool highlightNet(TOOL_MANAGER *aToolMgr, const SCH_SHEET_PATH &aSheetPath, 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
JSON_SCHEMA_VALIDATOR validator(schema)
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.