KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/widgets/search_handlers.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 CERN
5 * Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <footprint.h>
22#include <pcb_edit_frame.h>
23#include <pcb_marker.h>
24#include <pcb_painter.h>
25#include <pcb_textbox.h>
26#include <pcb_text.h>
27#include <pcb_dimension.h>
29#include <string_utils.h>
30#include <tool/tool_manager.h>
31#include <tools/pcb_actions.h>
32#include <zone.h>
33#include "search_handlers.h"
34
35
37{
38 std::vector<long> item = { aItemRow };
39 SelectItems( item );
40
42}
43
44
45void PCB_SEARCH_HANDLER::Sort( int aCol, bool aAscending )
46{
47 std::sort( m_hitlist.begin(), m_hitlist.end(),
48 [&]( BOARD_ITEM* a, BOARD_ITEM* b ) -> bool
49 {
50 // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
51 // to get the opposite sort. i.e. ~(a<b) != (a>b)
52 if( aAscending )
53 return StrNumCmp( getResultCell( a, aCol ), getResultCell( b, aCol ), true ) < 0;
54 else
55 return StrNumCmp( getResultCell( b, aCol ), getResultCell( a, aCol ), true ) < 0;
56 } );
57}
58
59
60void PCB_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
61{
62 std::vector<EDA_ITEM*> selectedItems;
63
64 for( long row : aItemRows )
65 {
66 if( row >= 0 && row < (long) m_hitlist.size() )
67 selectedItems.push_back( m_hitlist[row] );
68 }
69
71
72 if( selectedItems.size() )
74
75 m_frame->GetCanvas()->Refresh( false );
76}
77
78
80 PCB_SEARCH_HANDLER( _HKI( "Footprints" ), aFrame )
81{
82 m_columns.emplace_back( _HKI( "Reference" ), 2, wxLIST_FORMAT_LEFT );
83 m_columns.emplace_back( _HKI( "Value" ), 8, wxLIST_FORMAT_LEFT );
84 m_columns.emplace_back( _HKI( "Layer" ), 3, wxLIST_FORMAT_CENTER );
85 m_columns.emplace_back( wxT( "X" ), 3, wxLIST_FORMAT_CENTER );
86 m_columns.emplace_back( wxT( "Y" ), 3, wxLIST_FORMAT_CENTER );
87}
88
89
90int FOOTPRINT_SEARCH_HANDLER::Search( const wxString& aQuery )
91{
92 m_hitlist.clear();
93 BOARD* board = m_frame->GetBoard();
94
95 if( board == nullptr )
96 return 0;
97
99 frp.findString = aQuery;
100
101 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
102 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
103
104 for( FOOTPRINT* fp : board->Footprints() )
105 {
106 if( aQuery.IsEmpty()
107 || fp->Reference().Matches( frp, nullptr )
108 || fp->Value().Matches( frp, nullptr ) )
109 {
110 m_hitlist.push_back( fp );
111 }
112 }
113
114 return (int) m_hitlist.size();
115}
116
117
119{
120 FOOTPRINT* fp = static_cast<FOOTPRINT*>( aItem );
121
122 if( aCol == 0 )
123 return fp->GetReference();
124 else if( aCol == 1 )
125 return UnescapeString( fp->GetValue() );
126 else if( aCol == 2 )
127 return fp->GetLayerName();
128 else if( aCol == 3 )
130 else if( aCol == 4 )
132
133 return wxEmptyString;
134}
135
136
138 PCB_SEARCH_HANDLER( _HKI( "Zones" ), aFrame )
139{
140 m_columns.emplace_back( _HKI( "Name" ), 6, wxLIST_FORMAT_LEFT );
141 m_columns.emplace_back( _HKI( "Net" ), 6, wxLIST_FORMAT_LEFT);
142 m_columns.emplace_back( _HKI( "Layer" ), 3, wxLIST_FORMAT_CENTER );
143 m_columns.emplace_back( _HKI( "Priority" ), 2, wxLIST_FORMAT_CENTER );
144 m_columns.emplace_back( wxT( "X" ), 3, wxLIST_FORMAT_CENTER );
145 m_columns.emplace_back( wxT( "Y" ), 3, wxLIST_FORMAT_CENTER );
146}
147
148
149int ZONE_SEARCH_HANDLER::Search( const wxString& aQuery )
150{
151 m_hitlist.clear();
152 BOARD* board = m_frame->GetBoard();
153
154 EDA_SEARCH_DATA frp;
155 frp.findString = aQuery;
156
157 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
158 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
159
160 for( BOARD_ITEM* item : board->Zones() )
161 {
162 ZONE* zoneItem = dynamic_cast<ZONE*>( item );
163
164 if( zoneItem && ( aQuery.IsEmpty() || zoneItem->Matches( frp, nullptr ) ) )
165 m_hitlist.push_back( zoneItem );
166 }
167
168 return (int) m_hitlist.size();
169}
170
171
173{
174 ZONE* zone = static_cast<ZONE*>( aItem );
175
176 if( aCol == 0 )
177 return zone->GetZoneName();
178 else if( aCol == 1 )
179 return UnescapeString( zone->GetNetname() );
180 else if( aCol == 2 )
181 {
182 wxArrayString layers;
183 BOARD* board = m_frame->GetBoard();
184
185 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
186 layers.Add( board->GetLayerName( layer ) );
187
188 return wxJoin( layers, ',' );
189 }
190 else if( aCol == 3 )
191 return wxString::Format( "%d", zone->GetAssignedPriority() );
192 else if( aCol == 4 )
194 else if( aCol == 5 )
196
197
198 return wxEmptyString;
199}
200
201
203 PCB_SEARCH_HANDLER( _HKI( "Text" ), aFrame )
204{
205 m_columns.emplace_back( _HKI( "Type" ), 2, wxLIST_FORMAT_LEFT );
206 m_columns.emplace_back( _HKI( "Text" ), 12, wxLIST_FORMAT_LEFT );
207 m_columns.emplace_back( _HKI( "Layer" ), 3, wxLIST_FORMAT_CENTER );
208 m_columns.emplace_back( wxT( "X" ), 3, wxLIST_FORMAT_CENTER );
209 m_columns.emplace_back( wxT( "Y" ), 3, wxLIST_FORMAT_CENTER );
210}
211
212
213int TEXT_SEARCH_HANDLER::Search( const wxString& aQuery )
214{
215 m_hitlist.clear();
216 BOARD* board = m_frame->GetBoard();
217
218 EDA_SEARCH_DATA frp;
219 frp.findString = aQuery;
220
221 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
222 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
223
224 for( BOARD_ITEM* item : board->Drawings() )
225 {
226 PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item );
227 PCB_TEXTBOX* textBoxItem = dynamic_cast<PCB_TEXTBOX*>( item );
228
229 if( textItem && ( aQuery.IsEmpty() || textItem->Matches( frp, nullptr ) ) )
230 m_hitlist.push_back( textItem );
231 else if( textBoxItem && ( aQuery.IsEmpty() || textBoxItem->Matches( frp, nullptr ) ) )
232 m_hitlist.push_back( textBoxItem );
233 }
234
235 return (int) m_hitlist.size();
236}
237
238
240{
241 if( aCol == 0 )
242 {
243 if( PCB_TEXT::ClassOf( aItem ) )
244 return _( "Text" );
245 else if( PCB_TEXTBOX::ClassOf( aItem ) )
246 return _( "Textbox" );
247 else if( dynamic_cast<PCB_DIMENSION_BASE*>( aItem ) )
248 return _( "Dimension" );
249 }
250 else if( aCol == 1 )
251 {
252 if( PCB_TEXT::ClassOf( aItem ) )
253 return UnescapeString( static_cast<PCB_TEXT*>( aItem )->GetText() );
254 else if( PCB_TEXTBOX::ClassOf( aItem ) )
255 return UnescapeString( static_cast<PCB_TEXTBOX*>( aItem )->GetText() );
256 else if( PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem ) )
257 return UnescapeString( dimension->GetText() );
258 }
259 else if( aCol == 2 )
260 return aItem->GetLayerName();
261 else if( aCol == 3 )
262 return m_frame->MessageTextFromCoord( aItem->GetX(), ORIGIN_TRANSFORMS::ABS_X_COORD );
263 else if( aCol == 4 )
264 return m_frame->MessageTextFromCoord( aItem->GetY(), ORIGIN_TRANSFORMS::ABS_Y_COORD );
265
266 return wxEmptyString;
267}
268
269
271 PCB_SEARCH_HANDLER( _HKI( "Nets" ), aFrame )
272{
273 m_columns.emplace_back( _HKI( "Name" ), 6, wxLIST_FORMAT_LEFT );
274 m_columns.emplace_back( _HKI( "Class" ), 6, wxLIST_FORMAT_LEFT );
275}
276
277
278int NETS_SEARCH_HANDLER::Search( const wxString& aQuery )
279{
280 m_hitlist.clear();
281
282 EDA_SEARCH_DATA frp;
283 frp.findString = aQuery;
284
285 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
286 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
287
288 BOARD* board = m_frame->GetBoard();
289
290 for( NETINFO_ITEM* net : board->GetNetInfo() )
291 {
292 if( net && ( aQuery.IsEmpty() || net->Matches( frp, nullptr ) ) )
293 m_hitlist.push_back( net );
294 }
295
296 return (int) m_hitlist.size();
297}
298
299
301{
302 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( aItem );
303
304 if( net->GetNetCode() == 0 )
305 {
306 if( aCol == 0 )
307 return _( "No Net" );
308 else if( aCol == 1 )
309 return wxT( "" );
310 }
311
312 if( aCol == 0 )
313 return UnescapeString( net->GetNetname() );
314 else if( aCol == 1 )
315 return net->GetNetClass()->GetName();
316
317 return wxEmptyString;
318}
319
320
321void NETS_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
322{
324 ps->SetHighlight( false );
325
326 std::vector<NETINFO_ITEM*> selectedItems;
327
328 for( long row : aItemRows )
329 {
330 if( row >= 0 && row < (long) m_hitlist.size() )
331 {
332 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( m_hitlist[row] );
333
334 ps->SetHighlight( true, net->GetNetCode(), true );
335 }
336 }
337
340}
341
342
344{
345 m_frame->ShowBoardSetupDialog( _( "Net Classes" ) );
346}
347
348
350 PCB_SEARCH_HANDLER( _HKI( "Ratsnest" ), aFrame )
351{
352 m_columns.emplace_back( _HKI( "Name" ), 6, wxLIST_FORMAT_LEFT );
353 m_columns.emplace_back( _HKI( "Class" ), 6, wxLIST_FORMAT_LEFT );
354}
355
356
357int RATSNEST_SEARCH_HANDLER::Search( const wxString& aQuery )
358{
359 m_hitlist.clear();
360
361 EDA_SEARCH_DATA frp;
362 frp.findString = aQuery;
363
364 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
365 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
366
367 BOARD* board = m_frame->GetBoard();
368
369 for( NETINFO_ITEM* net : board->GetNetInfo() )
370 {
371 if( net == nullptr || !net->Matches( frp, nullptr ) )
372 continue;
373
374 RN_NET* rn = board->GetConnectivity()->GetRatsnestForNet( net->GetNetCode() );
375
376 if( rn && !rn->GetEdges().empty() )
377 m_hitlist.push_back( net );
378 }
379
380 return (int) m_hitlist.size();
381}
382
383
385{
386 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( aItem );
387
388 if( net->GetNetCode() == 0 )
389 {
390 if( aCol == 0 )
391 return _( "No Net" );
392 else if( aCol == 1 )
393 return wxT( "" );
394 }
395
396 if( aCol == 0 )
397 return UnescapeString( net->GetNetname() );
398 else if( aCol == 1 )
399 return net->GetNetClass()->GetName();
400
401 return wxEmptyString;
402}
403
404
405void RATSNEST_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
406{
408 ps->SetHighlight( false );
409
410 std::vector<NETINFO_ITEM*> selectedItems;
411
412 for( long row : aItemRows )
413 {
414 if( row >= 0 && row < (long) m_hitlist.size() )
415 {
416 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( m_hitlist[row] );
417
418 ps->SetHighlight( true, net->GetNetCode(), true );
419 }
420 }
421
424}
425
426
428{
429 m_frame->ShowBoardSetupDialog( _( "Net Classes" ) );
430}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
int GetY() const
Definition: board_item.h:101
int GetX() const
Definition: board_item.h:95
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:103
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:832
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:850
ZONES & Zones()
Definition: board.h:324
FOOTPRINTS & Footprints()
Definition: board.h:318
DRAWINGS & Drawings()
Definition: board.h:321
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:539
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:441
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
FOOTPRINT_SEARCH_HANDLER(PCB_EDIT_FRAME *aFrame)
int Search(const wxString &aQuery) override
wxString getResultCell(BOARD_ITEM *aItem, int aCol) override
const wxString & GetValue() const
Definition: footprint.h:603
const wxString & GetReference() const
Definition: footprint.h:581
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void SetHighlight(bool aEnabled, int aNetcode=-1, bool aMulti=false)
Turns on/off highlighting.
void UpdateAllLayersColor()
Apply the new coloring scheme to all layers.
Definition: view.cpp:758
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:418
const wxString GetName() const
Definition: netclass.h:62
Handle the data for a net.
Definition: netinfo.h:56
const wxString & GetNetname() const
Definition: netinfo.h:114
NETCLASS * GetNetClass()
Definition: netinfo.h:101
int GetNetCode() const
Definition: netinfo.h:108
void ActivateItem(long aItemRow) override
int Search(const wxString &aQuery) override
NETS_SEARCH_HANDLER(PCB_EDIT_FRAME *aFrame)
wxString getResultCell(BOARD_ITEM *aItem, int aCol) override
void SelectItems(std::vector< long > &aItemRows) override
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:174
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:76
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
wxString MessageTextFromCoord(int aValue, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType) const
Abstract dimension API.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
The main frame for Pcbnew.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
void ActivateItem(long aItemRow) override
void SelectItems(std::vector< long > &aItemRows) override
void Sort(int aCol, bool aAscending) override
std::vector< BOARD_ITEM * > m_hitlist
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
static bool ClassOf(const EDA_ITEM *aItem)
Definition: pcb_textbox.h:46
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: pcb_text.cpp:113
static bool ClassOf(const EDA_ITEM *aItem)
Definition: pcb_text.h:49
wxString getResultCell(BOARD_ITEM *aItem, int aCol) override
RATSNEST_SEARCH_HANDLER(PCB_EDIT_FRAME *aFrame)
int Search(const wxString &aQuery) override
void SelectItems(std::vector< long > &aItemRows) override
void ActivateItem(long aItemRow) override
Describe ratsnest for a single net.
Definition: ratsnest_data.h:63
const std::vector< CN_EDGE > & GetEdges() const
Definition: ratsnest_data.h:96
std::vector< SCH_SEARCH_HIT > m_hitlist
std::vector< std::tuple< wxString, int, wxListColumnFormat > > m_columns
Definition: search_pane.h:53
TEXT_SEARCH_HANDLER(SCH_EDIT_FRAME *aFrame)
int Search(const wxString &aQuery) override
wxString getResultCell(const SCH_SEARCH_HIT &hit, int aCol) override
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
ZONE_SEARCH_HANDLER(PCB_EDIT_FRAME *aFrame)
wxString getResultCell(BOARD_ITEM *aItem, int aCol) override
int Search(const wxString &aQuery) override
Handle a list of polygons defining a copper zone.
Definition: zone.h:72
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: zone.h:134
const wxString & GetZoneName() const
Definition: zone.h:131
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.h:129
unsigned GetAssignedPriority() const
Definition: zone.h:119
#define _HKI(x)
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
Class that computes missing connections on a PCB.
wxString UnescapeString(const wxString &aSource)
EDA_SEARCH_MATCH_MODE matchMode