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 )
506 for(
const auto& [groupName, groupItem] :
model->getGroupDataViewItems() )
514 wxDataViewItemArray sel;
517 std::vector<int> prev_selected_netcodes;
518 prev_selected_netcodes.reserve( sel.GetCount() );
520 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
523 prev_selected_netcodes.push_back( item->
GetNetCode() );
529 if( wxDataViewColumn* sorting_column =
m_netsList->GetSortingColumn() )
533 sorting_column_id =
static_cast<int>( sorting_column->GetModelColumn() );
534 sort_order_asc = sorting_column->IsSortOrderAscending();
538 sorting_column->UnsetAsSortKey();
555 std::vector<NETINFO_ITEM*> netCodes;
560 netCodes.emplace_back( ni );
563 std::ranges::sort( netCodes,
585 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
590 [&groupName](
const std::pair<wxString, wxDataViewItem>& item )
592 return groupName == item.first;
595 auto tableItem = std::ranges::find_if( groupItems, pred );
597 if( tableItem != groupItems.end() )
607 for(
const int& nc : prev_selected_netcodes )
609 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( nc ) )
611 const std::unique_ptr<LIST_ITEM>& list_item = *r.value();
612 sel.Add( wxDataViewItem( list_item.get() ) );
650 bool matched =
false;
653 if( filterString.Length() == 0 )
657 if( !matched && cfg->
filter_by_netclass && netClassName.Find( filterString ) != wxNOT_FOUND )
661 if( !matched && cfg->
filter_by_net_name && netName.Find( filterString ) != wxNOT_FOUND )
668 matched = !netName.StartsWith( wxT(
"UNCONNECTED-(" ) );
689 const auto type_bits = std::bitset<MAX_STRUCT_TYPE_ID>().set(
PCB_TRACE_T )
694 std::vector<CN_ITEM*> cn_items;
695 cn_items.reserve( 1024 );
697 for(
CN_ITEM* cn_item :
m_board->GetConnectivity()->GetConnectivityAlgo()->ItemList() )
699 if( cn_item->Valid() && type_bits[cn_item->Parent()->Type()] )
700 cn_items.push_back( cn_item );
709std::vector<std::unique_ptr<PCB_NET_INSPECTOR_PANEL::LIST_ITEM>>
712 std::vector<std::unique_ptr<LIST_ITEM>> results;
715 std::vector<NETINFO_ITEM*> netCodes( aNetCodes );
716 std::set<wxString> chains;
720 if( !net->GetNetChain().IsEmpty() )
721 chains.insert( net->GetNetChain() );
724 if( !chains.empty() )
728 if( chains.count( net->GetNetChain() ) )
729 netCodes.push_back( net );
732 std::sort( netCodes.begin(), netCodes.end(),
735 return a->GetNetCode() < b->GetNetCode();
737 netCodes.erase( std::unique( netCodes.begin(), netCodes.end() ), netCodes.end() );
746 std::unordered_map<int, std::vector<LENGTH_DELAY_CALCULATION_ITEM>> netItemsMap;
747 std::vector<NETINFO_ITEM*> foundNets;
749 auto itemItr = conItems.begin();
750 auto netCodeItr = netCodes.begin();
752 while( itemItr != conItems.end() && netCodeItr != netCodes.end() )
754 const int curNetCode = ( *netCodeItr )->GetNetCode();
755 const int curItemNetCode = ( *itemItr )->Net();
757 if( curItemNetCode == curNetCode )
759 if( foundNets.empty() || foundNets.back() != *netCodeItr )
760 foundNets.emplace_back( *netCodeItr );
764 netItemsMap[curItemNetCode].emplace_back( std::move( lengthItem ) );
767 else if( curItemNetCode < curNetCode )
770 while( itemItr != conItems.end() && ( *itemItr )->Net() < curNetCode )
773 else if( curItemNetCode > curNetCode )
776 while( netCodeItr != netCodes.end() && curItemNetCode > ( *netCodeItr )->GetNetCode() )
783 std::mutex resultsMutex;
786 auto resultsFuture =
tp.submit_loop(
788 [&,
this, calc](
const int i )
790 int netCode = foundNets[i]->GetNetCode();
792 constexpr PATH_OPTIMISATIONS opts = { .OptimiseVias = true,
794 .OptimiseTracesInPads = true,
795 .InferViaInPad = false };
798 netItemsMap[netCode],
806 if( aIncludeZeroPadNets || lengthDetails.NumPads > 0 )
808 std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( foundNets[i] );
810 new_item->SetPadCount( lengthDetails.NumPads );
811 new_item->SetLayerCount( m_board->GetCopperLayerCount() );
812 new_item->SetPadDieLength( lengthDetails.PadToDieLength );
813 new_item->SetPadDieDelay( lengthDetails.PadToDieDelay );
814 new_item->SetViaCount( lengthDetails.NumVias );
815 new_item->SetViaLength( lengthDetails.ViaLength );
816 new_item->SetViaDelay( lengthDetails.ViaDelay );
817 new_item->SetLayerWireLengths( *lengthDetails.LayerLengths );
822 int64_t unroutedLength = 0;
824 if( RN_NET* rnNet = m_board->GetConnectivity()->GetRatsnestForNet( netCode ) )
825 unroutedLength = rnNet->GetTotalAirlineLength();
827 new_item->SetUnroutedLength( unroutedLength );
829 if( m_showTimeDomainDetails )
830 new_item->SetLayerWireDelays( *lengthDetails.LayerDelays );
832 new_item->SetNetChainName( foundNets[i]->GetNetChain() );
834 std::scoped_lock lock( resultsMutex );
835 results.emplace_back( std::move( new_item ) );
841 std::map<wxString, int64_t> netChainLengths;
842 std::map<wxString, int64_t> netChainDelays;
844 for(
const std::unique_ptr<LIST_ITEM>& item : results )
846 if( !item->GetNetChainName().IsEmpty() )
848 netChainLengths[item->GetNetChainName()] += item->GetTotalLength();
850 if( m_showTimeDomainDetails )
851 netChainDelays[item->GetNetChainName()] += item->GetTotalDelay();
856 std::map<wxString, double> chainDelayPerIU;
858 auto delayPerIUFor = [&](
const wxString& aChain ) ->
double
860 auto it = chainDelayPerIU.find( aChain );
862 if( it != chainDelayPerIU.end() )
866 chainDelayPerIU.emplace( aChain, perIU );
870 for(
FOOTPRINT* fp : m_board->Footprints() )
872 std::vector<PAD*> chainPads;
874 for(
PAD*
pad : fp->Pads() )
876 if(
pad->GetNet() && !
pad->GetNet()->GetNetChain().IsEmpty() )
877 chainPads.push_back(
pad );
880 for(
size_t i = 0; i < chainPads.size(); ++i )
882 for(
size_t j = i + 1; j < chainPads.size(); ++j )
890 VECTOR2I p1 = chainPads[i]->GetPosition();
891 VECTOR2I p2 = chainPads[j]->GetPosition();
892 int64_t dx = p1.
x - p2.
x;
893 int64_t dy = p1.
y - p2.
y;
894 int64_t dist =
KiROUND( std::hypot( (
double) dx, (
double) dy ) );
897 netChainLengths[
chain] += dist;
899 if( m_showTimeDomainDetails )
906 for( std::unique_ptr<LIST_ITEM>& item : results )
908 if( !item->GetNetChainName().IsEmpty() )
910 item->SetNetChainLength( netChainLengths[item->GetNetChainName()] );
912 if( m_showTimeDomainDetails )
913 item->SetNetChainDelay( netChainDelays[item->GetNetChainName()] );
930 return wxString::Format( wxT(
"%.3d" ), aNet->
GetNetCode() );
942 return wxString::Format( wxT(
"%u" ), aValue );
948 return m_frame->MessageTextFromValue( aValue,
955 return m_frame->MessageTextFromValue( aValue,
966 wxDataViewItemArray sel;
1008 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1021 if( !IsShownOnScreen() )
1025 if( aBoardItems.size()
1026 >
static_cast<size_t>(
ADVANCED_CFG::GetCfg().m_NetInspectorBulkUpdateOptimisationThreshold ) )
1032 std::vector<NETINFO_ITEM*> changedNets;
1040 changedNets.emplace_back( net );
1044 changedNets.emplace_back( i->GetNet() );
1048 for(
const PAD*
pad : footprint->Pads() )
1051 changedNets.emplace_back(
pad->GetNet() );
1056 std::ranges::sort( changedNets,
1071 std::vector<NETINFO_ITEM*> netsToUpdate;
1072 std::unordered_set<NETINFO_ITEM*> netsToDelete;
1077 netsToDelete.insert( net );
1081 netsToUpdate.emplace_back( net );
1084 wxWindowUpdateLocker updateLocker(
m_netsList );
1086 std::vector<std::unique_ptr<LIST_ITEM>> newListItems =
calculateNets( aNets,
true );
1088 for( std::unique_ptr<LIST_ITEM>& newListItem : newListItems )
1091 netsToDelete.erase( newListItem->GetNet() );
1093 std::optional<LIST_ITEM_ITER> curNetRow =
m_dataModel->findItem( newListItem->GetNetCode() );
1107 const std::unique_ptr<LIST_ITEM>& curListItem = *curNetRow.value();
1109 if( curListItem->GetNetName() != newListItem->GetNetName() )
1117 curListItem->SetPadCount( newListItem->GetPadCount() );
1118 curListItem->SetPadDieLength( newListItem->GetPadDieLength() );
1119 curListItem->SetPadDieDelay( newListItem->GetPadDieDelay() );
1120 curListItem->SetViaCount( newListItem->GetViaCount() );
1121 curListItem->SetViaLength( newListItem->GetViaLength() );
1122 curListItem->SetViaDelay( newListItem->GetViaDelay() );
1123 curListItem->SetUnroutedLength( newListItem->GetUnroutedLength() );
1124 curListItem->SetLayerWireLengths( newListItem->GetLayerWireLengths() );
1125 curListItem->SetNetChainName( newListItem->GetNetChainName() );
1126 curListItem->SetNetChainLength( newListItem->GetNetChainLength() );
1127 curListItem->SetNetChainDelay( newListItem->GetNetChainDelay() );
1130 curListItem->SetLayerWireDelays( newListItem->GetLayerWireDelays() );
1144 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1157 if( !IsShownOnScreen() )
1166 const std::vector<BOARD_ITEM*> item{ aBoardItem };
1178 std::vector<BOARD_ITEM*>& aAddedItems,
1179 std::vector<BOARD_ITEM*>& aRemovedItems,
1180 std::vector<BOARD_ITEM*>& aChangedItems )
1182 if( !IsShownOnScreen() )
1185 std::vector<BOARD_ITEM*> allItems{ aAddedItems.begin(), aAddedItems.end() };
1186 allItems.insert( allItems.end(), aRemovedItems.begin(), aRemovedItems.end() );
1187 allItems.insert( allItems.end(), aChangedItems.begin(), aChangedItems.end() );
1197 if( !
m_board->IsHighLightNetON() )
1203 const std::set<int>& selected_codes =
m_board->GetHighLightNetCodes();
1205 wxDataViewItemArray new_selection;
1206 new_selection.Alloc( selected_codes.size() );
1208 for(
const int code : selected_codes )
1210 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( code ) )
1211 new_selection.Add( wxDataViewItem( &***r ) );
1216 if( !new_selection.IsEmpty() )
1217 m_netsList->EnsureVisible( new_selection.Item( 0 ) );
1237 bool multipleSelections =
false;
1240 if(
m_netsList->GetSelectedItemsCount() == 1 )
1246 if(
m_netsList->GetSelectedItemsCount() > 1 )
1247 multipleSelections =
true;
1254 wxEmptyString, wxITEM_NORMAL );
1257 wxMenuItem* clearHighlighting =
new wxMenuItem( &menu,
ID_CLEAR_HIGHLIGHTING,
_(
"Clear Net Highlighting" ),
1258 wxEmptyString, wxITEM_NORMAL );
1259 menu.Append( clearHighlighting );
1264 if( selected_codes.size() == 0 )
1265 clearHighlighting->Enable(
false );
1267 menu.AppendSeparator();
1269 wxMenuItem* renameNet =
new wxMenuItem( &menu,
ID_RENAME_NET,
_(
"Rename Selected Net..." ), wxEmptyString,
1271 menu.Append( renameNet );
1273 wxMenuItem* deleteNet =
new wxMenuItem( &menu,
ID_DELETE_NET,
_(
"Delete Selected Net" ), wxEmptyString,
1275 menu.Append( deleteNet );
1277 menu.AppendSeparator();
1279 wxMenuItem* addNet =
new wxMenuItem( &menu,
ID_ADD_NET,
_(
"Add Net..." ), wxEmptyString, wxITEM_NORMAL );
1280 menu.Append( addNet );
1282 if( !selItem && !multipleSelections )
1285 deleteNet->Enable(
false );
1286 renameNet->Enable(
false );
1290 if( multipleSelections || selItem->
GetIsGroup() )
1292 highlightNet->SetItemLabel(
_(
"Highlight Selected Nets" ) );
1293 renameNet->Enable(
false );
1294 deleteNet->SetItemLabel(
_(
"Delete Selected Nets" ) );
1298 menu.AppendSeparator();
1301 _(
"Remove Selected Custom Group" ),
1302 wxEmptyString, wxITEM_NORMAL );
1303 menu.Append( removeSelectedGroup );
1306 removeSelectedGroup->Enable(
false );
1323 wxString newGroupName;
1327 wxStaticText*
help =
new wxStaticText( &dlg, wxID_ANY,
_(
"(Use /.../ to indicate a regular expression.)" ) );
1331 dlg.GetSizer()->SetSizeHints( &dlg );
1338 if( newGroupName ==
"" )
1342 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1344 return rule->GetPattern() == newGroupName;
1360 m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings()->SetHighlight(
false );
1361 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1362 m_frame->GetCanvas()->Refresh();
1383 menu.AppendSeparator();
1398 if(
m_netsList->GetSelectedItemsCount() == 1 )
1407 wxEmptyString, wxITEM_CHECK );
1408 menu.Append( filterByNetName );
1409 filterByNetName->Check( cfg.filter_by_net_name );
1412 wxEmptyString, wxITEM_CHECK );
1413 menu.Append( filterByNetclass );
1414 filterByNetclass->Check( cfg.filter_by_netclass );
1416 menu.AppendSeparator();
1426 wxEmptyString, wxITEM_CHECK );
1427 menu.Append( groupNetclass );
1431 _(
"Group by Net Chain" ),
1432 wxEmptyString, wxITEM_CHECK );
1433 menu.Append( groupSignal );
1436 menu.AppendSeparator();
1438 wxMenuItem* addGroup =
new wxMenuItem( &menu,
ID_ADD_GROUP,
_(
"Add Custom Group..." ),
1439 wxEmptyString, wxITEM_NORMAL );
1440 menu.Append( addGroup );
1443 _(
"Remove Selected Custom Group" ),
1444 wxEmptyString, wxITEM_NORMAL );
1445 menu.Append( removeSelectedGroup );
1448 removeSelectedGroup->Enable(
false );
1450 wxMenuItem* removeCustomGroups =
new wxMenuItem( &menu,
ID_REMOVE_GROUPS,
_(
"Remove All Custom Groups" ),
1451 wxEmptyString, wxITEM_NORMAL );
1452 menu.Append( removeCustomGroups );
1455 menu.AppendSeparator();
1458 wxEmptyString, wxITEM_CHECK );
1459 menu.Append( showZeroNetPads );
1463 wxEmptyString, wxITEM_CHECK );
1464 menu.Append( showUnconnectedNets );
1467 menu.AppendSeparator();
1470 _(
"Show Time Domain Details" ),
1471 wxEmptyString, wxITEM_CHECK );
1472 menu.Append( showTimeDomainDetails );
1475 menu.AppendSeparator();
1479 wxEmptyString, wxITEM_NORMAL );
1482 menu.AppendSeparator();
1485 wxMenu* colsMenu =
new wxMenu();
1487 menu.AppendSubMenu( colsMenu,
_(
"Show / Hide Columns" ) );
1500 wxEmptyString, wxITEM_CHECK );
1502 target->Append( opt );
1503 opt->Check( !col->IsHidden() );
1506 target->AppendSeparator();
1511 wxEmptyString, wxITEM_CHECK );
1513 target->Append( opt );
1514 opt->Check( !col->IsHidden() );
1521 bool saveAndRebuild =
true;
1523 switch( event.GetId() )
1583 saveAndRebuild =
false;
1588 saveAndRebuild =
false;
1593 saveAndRebuild =
false;
1600 saveAndRebuild =
false;
1604 for(
unsigned int i = 0; i <
m_netsList->GetColumnCount(); ++i )
1607 saveAndRebuild =
false;
1616 col->SetWidth( std::max( col->GetWidth(), 10 ) );
1617 col->SetHidden( !col->IsHidden() );
1622 if( saveAndRebuild )
1632 if(
m_netsList->GetSelectedItemsCount() == 1 )
1636 if( selItem->GetIsGroup() )
1638 const wxString groupName = selItem->GetGroupName();
1640 [&]( std::unique_ptr<EDA_COMBINED_MATCHER>& rule )
1642 return rule->GetPattern() == groupName;
1658 wxFileDialog dlg(
this,
_(
"Save Net Inspector Report File" ),
"",
"",
1660 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1664 if( dlg.ShowModal() == wxID_CANCEL )
1667 wxTextFile f( dlg.GetPath() );
1682 txt += wxString::Format(
_(
"%s (%s)" ),
1688 txt += col.csv_name;
1691 txt += wxT(
"\";" );
1697 const unsigned int num_rows =
m_dataModel->itemCount();
1699 for(
unsigned int row = 0; row < num_rows; row++ )
1703 if( i.GetIsGroup() || i.GetNetCode() == 0 )
1711 txt +=
'"' +
m_dataModel->valueAt( col.num, row ).GetString() + wxT(
"\";" );
1713 txt +=
m_dataModel->valueAt( col.num, row ).GetString() +
';';
1744 wxDataViewItemArray sel;
1749 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1756 renderSettings->
SetHighlight(
true, ( *c )->GetNetCode(),
true );
1769 m_frame->GetCanvas()->GetView()->UpdateAllLayersColor();
1770 m_frame->GetCanvas()->Refresh();
1792 wxString newNetName;
1805 if(
m_board->FindNet( newNetName ) )
1807 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), newNetName ) );
1808 newNetName = wxEmptyString;
1827 if(
m_netsList->GetSelectedItemsCount() == 1 )
1837 wxString shortNetName;
1839 if( fullNetName.Contains( wxT(
"/" ) ) )
1841 netPath = fullNetName.BeforeLast(
'/' ) +
'/';
1842 shortNetName = fullNetName.AfterLast(
'/' );
1846 shortNetName = fullNetName;
1860 unescapedShortName = dlg.
GetValue();
1862 if( unescapedShortName.IsEmpty() )
1869 fullNetName = netPath + shortNetName;
1871 if(
m_board->FindNet( shortNetName ) ||
m_board->FindNet( fullNetName ) )
1873 DisplayError(
this, wxString::Format(
_(
"Net name '%s' is already in use." ), unescapedShortName ) );
1874 unescapedShortName = wxEmptyString;
1884 if( boardItem->GetNet() == net )
1900 boardItem->SetNet( net );
1905 if( std::optional<LIST_ITEM_ITER> r =
m_dataModel->findItem( net ) )
1906 m_netsList->Select( wxDataViewItem( r.value()->get() ) );
1914 m_frame->GetCanvas()->Refresh();
1924 wxDataViewItemArray sel;
1927 auto delete_one = [
this](
const LIST_ITEM* i )
1929 if( i->GetPadCount() == 0
1930 ||
IsOK(
this, wxString::Format(
_(
"Net '%s' is in use. Delete anyway?" ), i->GetNetName() ) ) )
1934 int removedCode = i->GetNetCode();
1936 m_frame->GetCanvas()->GetView()->UpdateAllItemsConditionally(
1941 if( boardItem && boardItem->GetNetCode() == removedCode )
1948 text->ClearRenderCache();
1949 text->ClearBoundingBoxCache();
1956 m_board->Remove( i->GetNet() );
1963 for(
unsigned int i = 0; i < sel.GetCount(); ++i )
1970 &&
IsOK(
this, wxString::Format(
_(
"Delete all nets in group '%s'?" ), ii->
GetGroupName() ) ) )
1974 std::vector<const LIST_ITEM*> children;
2022 bool displayed =
false;
2024 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount() && !displayed; ++ii )
2026 if(
m_netsList->GetColumn( ii )->GetWidth() > 0 )
2048 wxDataViewColumn* sortingCol =
m_netsList->GetSortingColumn();
2049 cfg.sorting_column = sortingCol ?
static_cast<int>( sortingCol->GetModelColumn() ) : -1;
2050 cfg.sort_order_asc = sortingCol ? sortingCol->IsSortOrderAscending() :
true;
2053 cfg.col_order.resize(
m_dataModel->columnCount() );
2054 cfg.col_widths.resize(
m_dataModel->columnCount() );
2055 cfg.col_hidden.resize(
m_dataModel->columnCount() );
2057 for(
unsigned int ii = 0; ii <
m_dataModel->columnCount(); ++ii )
2059 cfg.col_order[ii] = (int)
m_netsList->GetColumn( ii )->GetModelColumn();
2060 cfg.col_widths[ii] =
m_netsList->GetColumn( ii )->GetWidth();
2061 cfg.col_hidden[ii] =
m_netsList->GetColumn( ii )->IsHidden();
2065 cfg.expanded_rows.clear();
2066 std::vector<std::pair<wxString, wxDataViewItem>> groupItems =
m_dataModel->getGroupDataViewItems();
2068 for( std::pair<wxString, wxDataViewItem>& item : groupItems )
2071 cfg.expanded_rows.push_back( item.first );
2075 cfg.custom_group_rules.clear();
2078 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)
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 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.