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) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <footprint.h>
21#include <pcb_edit_frame.h>
22#include <pcb_marker.h>
23#include <pcb_painter.h>
24#include <pcb_textbox.h>
25#include <pcb_text.h>
28#include <string_utils.h>
29#include <tool/tool_manager.h>
30#include <tools/pcb_actions.h>
31#include <zone.h>
32#include "search_handlers.h"
33
34
36{
37 std::vector<long> item = { aItemRow };
38 SelectItems( item );
39
41}
42
43
44void PCB_SEARCH_HANDLER::Sort( int aCol, bool aAscending )
45{
46 std::sort( m_hitlist.begin(), m_hitlist.end(),
47 [&]( BOARD_ITEM* a, BOARD_ITEM* b ) -> bool
48 {
49 // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
50 // to get the opposite sort. i.e. ~(a<b) != (a>b)
51 if( aAscending )
52 return StrNumCmp( getResultCell( a, aCol ), getResultCell( b, aCol ), true ) < 0;
53 else
54 return StrNumCmp( getResultCell( b, aCol ), getResultCell( a, aCol ), true ) < 0;
55 } );
56}
57
58
59void PCB_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
60{
61 std::vector<EDA_ITEM*> selectedItems;
62
63 for( long row : aItemRows )
64 {
65 if( row >= 0 && row < (long) m_hitlist.size() )
66 selectedItems.push_back( m_hitlist[row] );
67 }
68
70
71 if( selectedItems.size() )
73
74 m_frame->GetCanvas()->Refresh( false );
75}
76
77
79 PCB_SEARCH_HANDLER( wxT( "Footprints" ), aFrame )
80{
81 m_columns.emplace_back( wxT( "Reference" ), 1 );
82 m_columns.emplace_back( wxT( "Value" ), 2 );
83 m_columns.emplace_back( wxT( "Layer" ), 1 );
84 m_columns.emplace_back( wxT( "X" ), 1 );
85 m_columns.emplace_back( wxT( "Y" ), 1 );
86}
87
88
89int FOOTPRINT_SEARCH_HANDLER::Search( const wxString& aQuery )
90{
91 m_hitlist.clear();
92 BOARD* board = m_frame->GetBoard();
93
95 frp.findString = aQuery;
96
97 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
98 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
99
100 for( FOOTPRINT* fp : board->Footprints() )
101 {
102 if( aQuery.IsEmpty()
103 || fp->Reference().Matches( frp, nullptr )
104 || fp->Value().Matches( frp, nullptr ) )
105 {
106 m_hitlist.push_back( fp );
107 }
108 }
109
110 return (int) m_hitlist.size();
111}
112
113
115{
116 FOOTPRINT* fp = static_cast<FOOTPRINT*>( aItem );
117
118 if( aCol == 0 )
119 return fp->GetReference();
120 else if( aCol == 1 )
121 return UnescapeString( fp->GetValue() );
122 else if( aCol == 2 )
123 return fp->GetLayerName();
124 else if( aCol == 3 )
125 return m_frame->MessageTextFromValue( fp->GetX() );
126 else if( aCol == 4 )
127 return m_frame->MessageTextFromValue( fp->GetY() );
128
129 return wxEmptyString;
130}
131
132
134 PCB_SEARCH_HANDLER( wxT( "Zones" ), aFrame )
135{
136 m_columns.emplace_back( wxT( "Name" ), 2 );
137 m_columns.emplace_back( wxT( "Net" ), 1 );
138 m_columns.emplace_back( wxT( "Layer" ), 1 );
139 m_columns.emplace_back( wxT( "Priority" ), 1 );
140 m_columns.emplace_back( wxT( "X" ), 1 );
141 m_columns.emplace_back( wxT( "Y" ), 1 );
142}
143
144
145int ZONE_SEARCH_HANDLER::Search( const wxString& aQuery )
146{
147 m_hitlist.clear();
148 BOARD* board = m_frame->GetBoard();
149
150 EDA_SEARCH_DATA frp;
151 frp.findString = aQuery;
152
153 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
154 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
155
156 for( BOARD_ITEM* item : board->Zones() )
157 {
158 ZONE* zoneItem = dynamic_cast<ZONE*>( item );
159
160 if( zoneItem && ( aQuery.IsEmpty() || zoneItem->Matches( frp, nullptr ) ) )
161 m_hitlist.push_back( zoneItem );
162 }
163
164 return (int) m_hitlist.size();
165}
166
167
169{
170 ZONE* zone = static_cast<ZONE*>( aItem );
171
172 if( aCol == 0 )
173 return zone->GetZoneName();
174 if( aCol == 1 )
175 return UnescapeString( zone->GetNetname() );
176 else if( aCol == 2 )
177 {
178 wxArrayString layers;
179 BOARD* board = m_frame->GetBoard();
180
181 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
182 layers.Add( board->GetLayerName( layer ) );
183
184 return wxJoin( layers, ',' );
185 }
186 else if( aCol == 3 )
187 return wxString::Format( "%d", zone->GetAssignedPriority() );
188 else if( aCol == 4 )
189 return m_frame->MessageTextFromValue( zone->GetX() );
190 else if( aCol == 5 )
191 return m_frame->MessageTextFromValue( zone->GetY() );
192
193 return wxEmptyString;
194}
195
196
198 PCB_SEARCH_HANDLER( wxT( "Text" ), aFrame )
199{
200 m_columns.emplace_back( wxT( "Type" ), 1 );
201 m_columns.emplace_back( wxT( "Text" ), 3 );
202 m_columns.emplace_back( wxT( "Layer" ), 1 );
203 m_columns.emplace_back( wxT( "X" ), 1 );
204 m_columns.emplace_back( wxT( "Y" ), 1 );
205}
206
207
208int TEXT_SEARCH_HANDLER::Search( const wxString& aQuery )
209{
210 m_hitlist.clear();
211 BOARD* board = m_frame->GetBoard();
212
213 EDA_SEARCH_DATA frp;
214 frp.findString = aQuery;
215
216 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
217 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
218
219 for( BOARD_ITEM* item : board->Drawings() )
220 {
221 PCB_TEXT* textItem = dynamic_cast<PCB_TEXT*>( item );
222 PCB_TEXTBOX* textBoxItem = dynamic_cast<PCB_TEXTBOX*>( item );
223
224 if( textItem && ( aQuery.IsEmpty() || textItem->Matches( frp, nullptr ) ) )
225 m_hitlist.push_back( textItem );
226 else if( textBoxItem && ( aQuery.IsEmpty() || textBoxItem->Matches( frp, nullptr ) ) )
227 m_hitlist.push_back( textBoxItem );
228 }
229
230 return (int) m_hitlist.size();
231}
232
233
235{
236 if( aCol == 0 )
237 {
238 if( PCB_TEXT::ClassOf( aItem ) )
239 return _( "Text" );
240 else if( PCB_TEXTBOX::ClassOf( aItem ) )
241 return _( "Textbox" );
242 }
243 else if( aCol == 1 )
244 {
245 if( PCB_TEXT::ClassOf( aItem ) )
246 return UnescapeString( static_cast<PCB_TEXT*>( aItem )->GetText() );
247 else if( PCB_TEXTBOX::ClassOf( aItem ) )
248 return UnescapeString( static_cast<PCB_TEXTBOX*>( aItem )->GetText() );
249 }
250 if( aCol == 2 )
251 return aItem->GetLayerName();
252 else if( aCol == 3 )
253 return m_frame->MessageTextFromValue( aItem->GetX() );
254 else if( aCol == 4 )
255 return m_frame->MessageTextFromValue( aItem->GetY() );
256
257 return wxEmptyString;
258}
259
260
262 PCB_SEARCH_HANDLER( wxT( "Nets" ), aFrame )
263{
264 m_columns.emplace_back( wxT( "Name" ), 2 );
265 m_columns.emplace_back( wxT( "Class" ), 2 );
266}
267
268
269int NETS_SEARCH_HANDLER::Search( const wxString& aQuery )
270{
271 m_hitlist.clear();
272
273 EDA_SEARCH_DATA frp;
274 frp.findString = aQuery;
275
276 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
277 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
278
279 BOARD* board = m_frame->GetBoard();
280
281 for( NETINFO_ITEM* net : board->GetNetInfo() )
282 {
283 if( net && ( aQuery.IsEmpty() || net->Matches( frp, nullptr ) ) )
284 m_hitlist.push_back( net );
285 }
286
287 return (int) m_hitlist.size();
288}
289
290
292{
293 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( aItem );
294
295 if( net->GetNetCode() == 0 )
296 {
297 if( aCol == 0 )
298 return _( "No Net" );
299 else if( aCol == 1 )
300 return wxT( "" );
301 }
302
303 if( aCol == 0 )
304 return UnescapeString( net->GetNetname() );
305 else if( aCol == 1 )
306 return net->GetNetClass()->GetName();
307
308 return wxEmptyString;
309}
310
311
312void NETS_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
313{
315 ps->SetHighlight( false );
316
317 std::vector<NETINFO_ITEM*> selectedItems;
318
319 for( long row : aItemRows )
320 {
321 if( row >= 0 && row < (long) m_hitlist.size() )
322 {
323 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( m_hitlist[row] );
324
325 ps->SetHighlight( true, net->GetNetCode(), true );
326 }
327 }
328
331}
332
333
335{
336 m_frame->ShowBoardSetupDialog( _( "Net Classes" ) );
337}
338
339
341 PCB_SEARCH_HANDLER( wxT( "Ratsnest" ), aFrame )
342{
343 m_columns.emplace_back( wxT( "Name" ), 2 );
344 m_columns.emplace_back( wxT( "Class" ), 2 );
345}
346
347
348int RATSNEST_SEARCH_HANDLER::Search( const wxString& aQuery )
349{
350 m_hitlist.clear();
351
352 EDA_SEARCH_DATA frp;
353 frp.findString = aQuery;
354
355 // Try to handle whatever the user throws at us (substring, wildcards, regex, etc.)
356 frp.matchMode = EDA_SEARCH_MATCH_MODE::PERMISSIVE;
357
358 BOARD* board = m_frame->GetBoard();
359
360 for( NETINFO_ITEM* net : board->GetNetInfo() )
361 {
362 if( net == nullptr || !net->Matches( frp, nullptr ) )
363 continue;
364
365 RN_NET* rn = board->GetConnectivity()->GetRatsnestForNet( net->GetNetCode() );
366
367 if( rn && !rn->GetEdges().empty() )
368 m_hitlist.push_back( net );
369 }
370
371 return (int) m_hitlist.size();
372}
373
374
376{
377 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( aItem );
378
379 if( net->GetNetCode() == 0 )
380 {
381 if( aCol == 0 )
382 return _( "No Net" );
383 else if( aCol == 1 )
384 return wxT( "" );
385 }
386
387 if( aCol == 0 )
388 return UnescapeString( net->GetNetname() );
389 else if( aCol == 1 )
390 return net->GetNetClass()->GetName();
391
392 return wxEmptyString;
393}
394
395
396void RATSNEST_SEARCH_HANDLER::SelectItems( std::vector<long>& aItemRows )
397{
399 ps->SetHighlight( false );
400
401 std::vector<NETINFO_ITEM*> selectedItems;
402
403 for( long row : aItemRows )
404 {
405 if( row >= 0 && row < (long) m_hitlist.size() )
406 {
407 NETINFO_ITEM* net = static_cast<NETINFO_ITEM*>( m_hitlist[row] );
408
409 ps->SetHighlight( true, net->GetNetCode(), true );
410 }
411 }
412
415}
416
417
419{
420 m_frame->ShowBoardSetupDialog( _( "Net Classes" ) );
421}
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:102
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:271
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:803
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:820
ZONES & Zones()
Definition: board.h:319
FOOTPRINTS & Footprints()
Definition: board.h:313
DRAWINGS & Drawings()
Definition: board.h:316
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:501
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:433
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:575
const wxString & GetReference() const
Definition: footprint.h:553
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:757
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:212
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:411
const wxString GetName() const
Definition: netclass.h:65
Handle the data for a net.
Definition: netinfo.h:67
const wxString & GetNetname() const
Definition: netinfo.h:125
NETCLASS * GetNetClass()
Definition: netinfo.h:112
int GetNetCode() const
Definition: netinfo.h:119
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:164
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:75
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
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:94
std::vector< SCH_SEARCH_HIT > m_hitlist
std::vector< std::pair< wxString, int > > m_columns
Definition: search_pane.h:49
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
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
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 _(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