/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "search_handlers.h" PCB_SEARCH_HANDLER::PCB_SEARCH_HANDLER( wxString aName, PCB_EDIT_FRAME* aFrame ) : SEARCH_HANDLER( aName ), m_frame( aFrame ) { } void PCB_SEARCH_HANDLER::ActivateItem( long aItemRow ) { std::vector item = { aItemRow }; SelectItems( item ); m_frame->GetToolManager()->RunAction( PCB_ACTIONS::properties ); } FOOTPRINT_SEARCH_HANDLER::FOOTPRINT_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ) : PCB_SEARCH_HANDLER( wxT( "Footprints" ), aFrame ) { m_columns.emplace_back( wxT( "Reference" ), 1 ); m_columns.emplace_back( wxT( "Value" ), 2 ); m_columns.emplace_back( wxT( "Layer" ), 1 ); m_columns.emplace_back( wxT( "X" ), 1 ); m_columns.emplace_back( wxT( "Y" ), 1 ); } int FOOTPRINT_SEARCH_HANDLER::Search( const wxString& aQuery ) { m_hitlist.clear(); BOARD* board = m_frame->GetBoard(); 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; for( FOOTPRINT* fp : board->Footprints() ) { if( aQuery.IsEmpty() || fp->Reference().Matches( frp, nullptr ) || fp->Value().Matches( frp, nullptr ) ) { m_hitlist.push_back( fp ); } } return (int) m_hitlist.size(); } wxString FOOTPRINT_SEARCH_HANDLER::GetResultCell( int aRow, int aCol ) { FOOTPRINT* fp = m_hitlist[aRow]; if( aCol == 0 ) return fp->GetReference(); else if( aCol == 1 ) return UnescapeString( fp->GetValue() ); else if( aCol == 2 ) return fp->GetLayerName(); else if( aCol == 3 ) return m_frame->MessageTextFromValue( fp->GetX() ); else if( aCol == 4 ) return m_frame->MessageTextFromValue( fp->GetY() ); return wxEmptyString; } void FOOTPRINT_SEARCH_HANDLER::SelectItems( std::vector& aItemRows ) { std::vector selectedItems; for( long row : aItemRows ) { if( row >= 0 && row < (long) m_hitlist.size() ) { FOOTPRINT* fp = m_hitlist[row]; selectedItems.push_back( fp ); } } m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear ); if( selectedItems.size() ) { EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() ); m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectItems, &selItems ); } m_frame->GetCanvas()->Refresh( false ); } ZONE_SEARCH_HANDLER::ZONE_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ) : PCB_SEARCH_HANDLER( wxT( "Zones" ), aFrame ) { m_columns.emplace_back( wxT( "Name" ), 2 ); m_columns.emplace_back( wxT( "Net" ), 1 ); m_columns.emplace_back( wxT( "Layer" ), 1 ); m_columns.emplace_back( wxT( "Priority" ), 1 ); m_columns.emplace_back( wxT( "X" ), 1 ); m_columns.emplace_back( wxT( "Y" ), 1 ); } int ZONE_SEARCH_HANDLER::Search( const wxString& aQuery ) { m_hitlist.clear(); BOARD* board = m_frame->GetBoard(); 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; for( BOARD_ITEM* item : board->Zones() ) { ZONE* zoneItem = dynamic_cast( item ); if( zoneItem && ( aQuery.IsEmpty() || zoneItem->Matches( frp, nullptr ) ) ) m_hitlist.push_back( zoneItem ); } return (int) m_hitlist.size(); } wxString ZONE_SEARCH_HANDLER::GetResultCell( int aRow, int aCol ) { ZONE* zone = m_hitlist[aRow]; if( aCol == 0 ) return zone->GetZoneName(); if( aCol == 1 ) return UnescapeString( zone->GetNetname() ); else if( aCol == 2 ) { wxArrayString layers; BOARD* board = m_frame->GetBoard(); for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) layers.Add( board->GetLayerName( layer ) ); return wxJoin( layers, ',' ); } else if( aCol == 3 ) return wxString::Format( "%d", zone->GetAssignedPriority() ); else if( aCol == 4 ) return m_frame->MessageTextFromValue( zone->GetX() ); else if( aCol == 5 ) return m_frame->MessageTextFromValue( zone->GetY() ); return wxEmptyString; } void ZONE_SEARCH_HANDLER::SelectItems( std::vector& aItemRows ) { std::vector selectedItems; for( long row : aItemRows ) { if( row >= 0 && row < (long) m_hitlist.size() ) { ZONE* zone = m_hitlist[row]; selectedItems.push_back( zone ); } } m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear ); if( selectedItems.size() ) { EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() ); m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectItems, &selItems ); } m_frame->GetCanvas()->Refresh( false ); } TEXT_SEARCH_HANDLER::TEXT_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ) : PCB_SEARCH_HANDLER( wxT( "Text" ), aFrame ) { m_columns.emplace_back( wxT( "Type" ), 1 ); m_columns.emplace_back( wxT( "Text" ), 3 ); m_columns.emplace_back( wxT( "Layer" ), 1 ); m_columns.emplace_back( wxT( "X" ), 1 ); m_columns.emplace_back( wxT( "Y" ), 1 ); } int TEXT_SEARCH_HANDLER::Search( const wxString& aQuery ) { m_hitlist.clear(); BOARD* board = m_frame->GetBoard(); 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; for( BOARD_ITEM* item : board->Drawings() ) { PCB_TEXT* textItem = dynamic_cast( item ); PCB_TEXTBOX* textBoxItem = dynamic_cast( item ); if( textItem && ( aQuery.IsEmpty() || textItem->Matches( frp, nullptr ) ) ) m_hitlist.push_back( textItem ); else if( textBoxItem && ( aQuery.IsEmpty() || textBoxItem->Matches( frp, nullptr ) ) ) m_hitlist.push_back( textBoxItem ); } return (int) m_hitlist.size(); } wxString TEXT_SEARCH_HANDLER::GetResultCell( int aRow, int aCol ) { BOARD_ITEM* text = m_hitlist[aRow]; if( aCol == 0 ) { if( PCB_TEXT::ClassOf( text ) ) return _( "Text" ); else if( PCB_TEXTBOX::ClassOf( text ) ) return _( "Textbox" ); } else if( aCol == 1 ) { if( PCB_TEXT::ClassOf( text ) ) return UnescapeString( static_cast( text )->GetText() ); else if( PCB_TEXTBOX::ClassOf( text ) ) return UnescapeString( static_cast( text )->GetText() ); } if( aCol == 2 ) return text->GetLayerName(); else if( aCol == 3 ) return m_frame->MessageTextFromValue( text->GetX() ); else if( aCol == 4 ) return m_frame->MessageTextFromValue( text->GetY() ); return wxEmptyString; } void TEXT_SEARCH_HANDLER::SelectItems( std::vector& aItemRows ) { std::vector selectedItems; for( long row : aItemRows ) { if( row >= 0 && row < (long) m_hitlist.size() ) { BOARD_ITEM* text = m_hitlist[row]; selectedItems.push_back( text ); } } m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear ); if( selectedItems.size() ) { EDA_ITEMS selItems( selectedItems.begin(), selectedItems.end() ); m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectItems, &selItems ); } m_frame->GetCanvas()->Refresh( false ); } NETS_SEARCH_HANDLER::NETS_SEARCH_HANDLER( PCB_EDIT_FRAME* aFrame ) : PCB_SEARCH_HANDLER( wxT( "Nets" ), aFrame ) { m_columns.emplace_back( wxT( "Name" ), 2 ); m_columns.emplace_back( wxT( "Class" ), 2 ); } int NETS_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 && ( aQuery.IsEmpty() || net->Matches( frp, nullptr ) ) ) m_hitlist.push_back( net ); } return (int) m_hitlist.size(); } wxString NETS_SEARCH_HANDLER::GetResultCell( int aRow, int aCol ) { NETINFO_ITEM* net = m_hitlist[aRow]; 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 NETS_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 = m_hitlist[row]; ps->SetHighlight( true, net->GetNetCode(), true ); } } m_frame->GetCanvas()->GetView()->UpdateAllLayersColor(); m_frame->GetCanvas()->Refresh(); } void NETS_SEARCH_HANDLER::ActivateItem( long aItemRow ) { m_frame->ShowBoardSetupDialog( _( "Net Classes" ) ); }