diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 5be124bcfb..d9bbb9859c 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -2165,6 +2165,12 @@ void BOARD::OnItemsChanged( std::vector& aItems ) } +void BOARD::OnRatsnestChanged() +{ + InvokeListeners( &BOARD_LISTENER::OnBoardRatsnestChanged, *this ); +} + + void BOARD::ResetNetHighLight() { m_highLight.Clear(); diff --git a/pcbnew/board.h b/pcbnew/board.h index 1dcc5a4976..c9d64d71c1 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -250,6 +250,7 @@ public: virtual void OnBoardItemChanged( BOARD& aBoard, BOARD_ITEM* aBoardItem ) { } virtual void OnBoardItemsChanged( BOARD& aBoard, std::vector& aBoardItem ) { } virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) { } + virtual void OnBoardRatsnestChanged( BOARD& aBoard ) { } }; @@ -1137,6 +1138,11 @@ public: */ void OnItemsChanged( std::vector& aItems ); + /** + * Notify the board and its listeners that the ratsnest has been recomputed. + */ + void OnRatsnestChanged(); + /** * Consistency check of internal m_groups structure. * diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index e8a4fc5edd..6e5d580a10 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -454,6 +454,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) if( frame ) frame->GetCanvas()->RedrawRatsnest(); + + board->OnRatsnestChanged(); } if( solderMaskDirty ) @@ -665,6 +667,7 @@ void BOARD_COMMIT::Revert() { connectivity->RecalculateRatsnest(); board->UpdateRatsnestExclusions(); + board->OnRatsnestChanged(); } PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); diff --git a/pcbnew/ratsnest/ratsnest.cpp b/pcbnew/ratsnest/ratsnest.cpp index 7232de88b1..5b90a73bfc 100644 --- a/pcbnew/ratsnest/ratsnest.cpp +++ b/pcbnew/ratsnest/ratsnest.cpp @@ -36,6 +36,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( bool aDisplayStatus ) { GetBoard()->GetConnectivity()->RecalculateRatsnest(); GetBoard()->UpdateRatsnestExclusions(); + GetBoard()->OnRatsnestChanged(); if( aDisplayStatus ) SetMsgPanel( m_pcb ); diff --git a/pcbnew/widgets/pcb_search_pane.cpp b/pcbnew/widgets/pcb_search_pane.cpp index de8f8b854d..42820a4ad4 100644 --- a/pcbnew/widgets/pcb_search_pane.cpp +++ b/pcbnew/widgets/pcb_search_pane.cpp @@ -45,6 +45,7 @@ PCB_SEARCH_PANE::PCB_SEARCH_PANE( PCB_EDIT_FRAME* aFrame ) : AddSearcher( new FOOTPRINT_SEARCH_HANDLER( aFrame ) ); AddSearcher( new ZONE_SEARCH_HANDLER( aFrame ) ); AddSearcher( new NETS_SEARCH_HANDLER( aFrame ) ); + AddSearcher( new RATSNEST_SEARCH_HANDLER( aFrame ) ); AddSearcher( new TEXT_SEARCH_HANDLER( aFrame ) ); } @@ -142,3 +143,12 @@ void PCB_SEARCH_PANE::OnBoardItemsChanged( BOARD& aBoard, std::vector& aBoardItems ) override; virtual void OnBoardHighlightNetChanged( BOARD& aBoard ) override; + virtual void OnBoardRatsnestChanged( BOARD& aBoard ) override; private: void onUnitsChanged( wxCommandEvent& event ); @@ -50,4 +51,4 @@ private: BOARD* m_brd; }; -#endif \ No newline at end of file +#endif diff --git a/pcbnew/widgets/search_handlers.cpp b/pcbnew/widgets/search_handlers.cpp index 2613055bed..97e0282b5c 100644 --- a/pcbnew/widgets/search_handlers.cpp +++ b/pcbnew/widgets/search_handlers.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -333,3 +335,87 @@ void NETS_SEARCH_HANDLER::ActivateItem( long aItemRow ) { m_frame->ShowBoardSetupDialog( _( "Net Classes" ) ); } + + +RATSNEST_SEARCH_HANDLER::RATSNEST_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ) : + PCB_SEARCH_HANDLER( wxT( "Ratsnest" ), aFrame ) +{ + m_columns.emplace_back( wxT( "Name" ), 2 ); + m_columns.emplace_back( wxT( "Class" ), 2 ); +} + + +int RATSNEST_SEARCH_HANDLER::Search( const wxString& aQuery ) +{ + m_hitlist.clear(); + + EDA_SEARCH_DATA frp; + frp.findString = aQuery; + + // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.) + frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE; + + BOARD* board = m_frame->GetBoard(); + + for( NETINFO_ITEM* net : board->GetNetInfo() ) + { + if( net == nullptr || !net->Matches( frp, nullptr ) ) + continue; + + RN_NET* rn = board->GetConnectivity()->GetRatsnestForNet( net->GetNetCode() ); + + if( rn && !rn->GetEdges().empty() ) + m_hitlist.push_back( net ); + } + + return (int) m_hitlist.size(); +} + + +wxString RATSNEST_SEARCH_HANDLER::getResultCell( BOARD_ITEM* aItem, int aCol ) +{ + NETINFO_ITEM* net = static_cast( aItem ); + + if( net->GetNetCode() == 0 ) + { + if( aCol == 0 ) + return _( "No Net" ); + else if( aCol == 1 ) + return wxT( "" ); + } + + if( aCol == 0 ) + return UnescapeString( net->GetNetname() ); + else if( aCol == 1 ) + return net->GetNetClass()->GetName(); + + return wxEmptyString; +} + + +void RATSNEST_SEARCH_HANDLER::SelectItems( std::vector& aItemRows ) +{ + RENDER_SETTINGS* ps = m_frame->GetCanvas()->GetView()->GetPainter()->GetSettings(); + ps->SetHighlight( false ); + + std::vector selectedItems; + + for( long row : aItemRows ) + { + if( row >= 0 && row < (long) m_hitlist.size() ) + { + NETINFO_ITEM* net = static_cast( m_hitlist[row] ); + + ps->SetHighlight( true, net->GetNetCode(), true ); + } + } + + m_frame->GetCanvas()->GetView()->UpdateAllLayersColor(); + m_frame->GetCanvas()->Refresh(); +} + + +void RATSNEST_SEARCH_HANDLER::ActivateItem( long aItemRow ) +{ + m_frame->ShowBoardSetupDialog( _( "Net Classes" ) ); +} diff --git a/pcbnew/widgets/search_handlers.h b/pcbnew/widgets/search_handlers.h index e559a29ad0..2cbd620ec5 100644 --- a/pcbnew/widgets/search_handlers.h +++ b/pcbnew/widgets/search_handlers.h @@ -105,4 +105,18 @@ private: wxString getResultCell( BOARD_ITEM* aItem, int aCol ) override; }; + +class RATSNEST_SEARCH_HANDLER : public PCB_SEARCH_HANDLER +{ +public: + RATSNEST_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ); + + int Search( const wxString& aQuery ) override; + void SelectItems( std::vector& aItemRows ) override; + void ActivateItem( long aItemRow ) override; + +private: + wxString getResultCell( BOARD_ITEM* aItem, int aCol ) override; +}; + #endif