1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 #ifndef COLLECTORS_H
26 #define COLLECTORS_H
27 
28 
29 /*
30  *  This module contains a number of COLLECTOR implementations which are used
31  *  to augment the functionality of class PCB_EDIT_FRAME.
32  */
33 
34 
35 #include <collector.h>
36 #include <layer_ids.h>              // LAYER_COUNT, layer defs
37 #include <view/view.h>
38 #include <board_item.h>
39 
40 
41 
42 /**
43  * An abstract base class whose derivatives may be passed to a GENERAL_COLLECTOR,
44  * telling GENERAL_COLLECTOR what should be collected (aside from HitTest()ing
45  * and KICAD_T scanTypes[], information which are provided to the GENERAL_COLLECTOR
46  * through attributes or arguments separately).
47  * <p>
48  * A justification for this class is to keep the structural storage details of
49  * the program's "global preferences" or "configuration options" out of
50  * GENERAL_COLLECTOR::Inspect().  This class carries all the necessary details
51  * in with it to the Inspect() call. The constructors or other functions of
52  * this class's derivatives are then the only place where knowledge of the
53  * specific structure of the global preference storage is needed.  Thus,
54  * GENERAL_COLLECTOR::Inspect() can be kept as simple as possible, and insulated
55  * from changes in global preference storage (and even then it is
56  * not simple enough).
57  * </p>
58  * This class introduces the notion of layer locking.
59  */
60 class COLLECTORS_GUIDE
61 {
62 public:
~COLLECTORS_GUIDE()63     virtual     ~COLLECTORS_GUIDE() {}
64 
65     /**
66      * @return true if the given layer is locked, else false.
67      */
68     virtual     bool IsLayerLocked( PCB_LAYER_ID layer ) const = 0;
69 
70     /**
71      * @return true if the given layer is visible, else false.
72      */
73     virtual     bool IsLayerVisible( PCB_LAYER_ID layer ) const = 0;
74 
75     /**
76      * @return true if should ignore locked layers, else false.
77      */
78     virtual     bool IgnoreLockedLayers() const = 0;
79 
80     /**
81      * @return true if should ignore non-visible layers, else false.
82      */
83     virtual     bool IgnoreNonVisibleLayers() const = 0;
84 
85     /**
86      * @return the preferred layer for HitTest()ing.
87      */
88     virtual     PCB_LAYER_ID GetPreferredLayer() const = 0;
89 
90     /**
91      * Provide wildcard behavior regarding the preferred layer.
92      *
93      * @return true if should ignore preferred layer, else false.
94      */
95     virtual     bool IgnorePreferredLayer() const = 0;
96 
97     /**
98      * @return true if should ignore locked items, else false.
99      */
100     virtual     bool IgnoreLockedItems() const = 0;
101 
102     /**
103      * Determine if the secondary criteria or 2nd choice items should be included.
104      *
105      * @return true if should include, else false.
106      */
107     virtual     bool IncludeSecondary() const = 0;
108 
109     /**
110      * @return true if footprint texts marked as "no show" should be ignored.
111      */
112     virtual     bool IgnoreHiddenFPText() const = 0;
113 
114     /**
115      * @return true if should ignore footprint text on back layers
116      */
117     virtual     bool IgnoreFPTextOnBack() const = 0;
118 
119     /**
120      * @return true if should ignore footprint text on front layers.
121      */
122     virtual     bool IgnoreFPTextOnFront() const = 0;
123 
124     /**
125      * @return true if should ignore FOOTPRINTs on Back Side.
126      */
127     virtual     bool IgnoreFootprintsOnBack() const = 0;
128 
129     /**
130      * @return true if should ignore FOOTPRINTs on Front Side.
131      */
132     virtual     bool IgnoreFootprintsOnFront() const = 0;
133 
134     /**
135      * @return true if should ignore Pads on Back Side.
136      */
137     virtual     bool IgnorePadsOnBack() const = 0;
138 
139     /**
140      * @return true if should ignore PADSs on Front Side.
141      */
142     virtual     bool IgnorePadsOnFront() const = 0;
143 
144     /**
145      * @return true if should ignore through-hole PADSs.
146      */
147     virtual     bool IgnoreThroughHolePads() const = 0;
148 
149     /**
150      * @return true if should ignore PADSs on Front side and Back side.
151      */
IgnorePads()152     virtual     bool IgnorePads() const
153     {
154         return IgnorePadsOnFront() && IgnorePadsOnBack() && IgnoreThroughHolePads();
155     }
156 
157     /**
158      * @return true if should ignore footprint values.
159      */
160     virtual     bool IgnoreFPValues() const = 0;
161 
162     /**
163      * @return true if should ignore footprint references.
164      */
165     virtual     bool IgnoreFPReferences() const = 0;
166 
167     /**
168      * @return true if should ignore through-hole vias
169      */
170     virtual     bool IgnoreThroughVias() const = 0;
171 
172     /**
173      * @return true if should ignore blind/buried vias
174      */
175     virtual     bool IgnoreBlindBuriedVias() const = 0;
176 
177     /**
178      * @return true if should ignore micro vias
179      */
180     virtual     bool IgnoreMicroVias() const = 0;
181 
182     /**
183      * @return true if should ignore tracks
184      */
185     virtual     bool IgnoreTracks() const = 0;
186 
187     /**
188      * @return true if should ignore the interiors of zones
189      */
190     virtual     bool IgnoreZoneFills() const = 0;
191 
192     virtual     double OnePixelInIU() const = 0;
193 
194     /**
195      * @return true if Inspect() should use BOARD_ITEM::HitTest()
196      *         or false if Inspect() should use BOARD_ITEM::BoundsTest().
197     virtual     bool UseHitTesting() const = 0;
198      */
199 };
200 
201 
202 
203 /**
204  * Collect #BOARD_ITEM objects.
205  *
206  * All this object really does is override the [] operator and return a #BOARD_ITEM instead
207  * of a #EDA_ITEM.  Derive all board collector objects from this class instead of the base
208  * #COLLECTOR object.
209  *
210  * @see class COLLECTOR
211  */
212 class PCB_COLLECTOR : public COLLECTOR
213 {
214 public:
215     /**
216      * Overload the COLLECTOR::operator[](int) to return a #BOARD_ITEM instead of an #EDA_ITEM.
217      *
218      * @param ndx The index into the list.
219      * @return a board item or NULL.
220      */
221     BOARD_ITEM* operator[]( int ndx ) const override
222     {
223         if( (unsigned)ndx < (unsigned)GetCount() )
224             return (BOARD_ITEM*) m_list[ ndx ];
225 
226         return nullptr;
227     }
228 };
229 
230 
231 /**
232  * Used when the right click button is pressed, or when the select tool is in effect.
233  * This class can be used by window classes such as PCB_EDIT_FRAME.
234  *
235  * Philosophy: this class knows nothing of the context in which a BOARD is used
236  * and that means it knows nothing about which layers are visible or current,
237  * but can handle those concerns by the SetPreferredLayer() function and the
238  * SetLayerSet() function.
239  */
240 class GENERAL_COLLECTOR : public PCB_COLLECTOR
241 {
242 protected:
243     /**
244      * A place to hold collected objects which don't match precisely the search
245      * criteria, but would be acceptable if nothing else is found.
246      * "2nd" choice, which will be appended to the end of COLLECTOR's prime
247      * "list" at the end of the search.
248      */
249     std::vector<BOARD_ITEM*>    m_List2nd;
250 
251     /**
252      * Determine which items are to be collected by Inspect().
253      */
254     const COLLECTORS_GUIDE*     m_Guide;
255 
256     /**
257      * The number of items that were originally in the primary list before the
258      * m_List2nd was concatenated onto the end of it.
259      */
260     int                         m_PrimaryLength;
261 
262 public:
263 
264     /**
265      * A scan list for all editable board items
266      */
267     static const KICAD_T AllBoardItems[];
268 
269     /**
270      * A scan list for zones outlines only
271      */
272     static const KICAD_T Zones[];
273 
274     /**
275      * A scan list for all primary board items, omitting items which are subordinate to
276      * a FOOTPRINT, such as PAD and FP_TEXT.
277      */
278     static const KICAD_T BoardLevelItems[];
279 
280     /**
281      * A scan list for only FOOTPRINTs
282      */
283     static const KICAD_T Footprints[];
284 
285     /**
286      * A scan list for PADs, TRACKs, or VIAs
287      */
288     static const KICAD_T PadsOrTracks[];
289 
290     /**
291      * A scan list for primary footprint items.
292      */
293     static const KICAD_T FootprintItems[];
294 
295     /**
296      * A scan list for only TRACKs
297      */
298     static const KICAD_T Tracks[];
299 
300     /**
301      * A scan list for TRACKs, VIAs, FOOTPRINTs
302      */
303     static const KICAD_T LockableItems[];
304 
305     /**
306      * A scan list for dimensions
307      */
308     static const KICAD_T Dimensions[];
309 
310     /**
311      * A scan list for items that can be dragged
312      */
313     static const KICAD_T DraggableItems[];
314 
GENERAL_COLLECTOR()315     GENERAL_COLLECTOR()
316     {
317         m_Guide = nullptr;
318         m_PrimaryLength = 0;
319         SetScanTypes( AllBoardItems );
320     }
321 
Empty2nd()322     void Empty2nd()
323     {
324         m_List2nd.clear();
325     }
326 
Append2nd(BOARD_ITEM * item)327     void Append2nd( BOARD_ITEM* item )
328     {
329         m_List2nd.push_back( item );
330     }
331 
332     /**
333      * Record which COLLECTORS_GUIDE to use.
334      *
335      * @param aGuide Which guide to use in the collection.
336      */
SetGuide(const COLLECTORS_GUIDE * aGuide)337     void SetGuide( const COLLECTORS_GUIDE* aGuide ) { m_Guide = aGuide; }
338 
GetGuide()339     const COLLECTORS_GUIDE* GetGuide() const { return m_Guide; }
340 
341     /**
342      * @return The number of items which met the primary search criteria
343      */
GetPrimaryCount()344     int GetPrimaryCount() { return m_PrimaryLength; }
345 
346     /**
347      * The examining function within the INSPECTOR which is passed to the Iterate function.
348      *
349      * Search and collect all the objects which match the test data.
350      *
351      * @param testItem An EDA_ITEM to examine.
352      * @param testData is not used in this class.
353      * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
354      *         else SCAN_CONTINUE;
355      */
356     SEARCH_RESULT Inspect( EDA_ITEM* testItem, void* testData )  override;
357 
358     /**
359      * Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
360      *
361      * @param aItem A BOARD_ITEM to scan, may be a BOARD or FOOTPRINT, or whatever.
362      * @param aScanList A list of KICAD_Ts with a terminating EOT, that specs
363      *  what is to be collected and the priority order of the resultant
364      *  collection in "m_list".
365      * @param aRefPos A wxPoint to use in hit-testing.
366      * @param aGuide The COLLECTORS_GUIDE to use in collecting items.
367      */
368     void Collect( BOARD_ITEM* aItem, const KICAD_T aScanList[],
369                   const wxPoint& aRefPos, const COLLECTORS_GUIDE& aGuide );
370 };
371 
372 
373 /**
374  * A general implementation of a COLLECTORS_GUIDE.  One of its constructors is
375  * entitled to grab information from the program's global preferences.
376  */
377 class GENERAL_COLLECTORS_GUIDE : public COLLECTORS_GUIDE
378 {
379 public:
380 
381     /**
382      * Grab stuff from global preferences and uses reasonable defaults.
383      *
384      * Add more constructors as needed.
385      *
386      * @param aVisibleLayerMask is the current visible layers (bit mask).
387      * @param aPreferredLayer is the layer to search first.
388      */
GENERAL_COLLECTORS_GUIDE(LSET aVisibleLayerMask,PCB_LAYER_ID aPreferredLayer,KIGFX::VIEW * aView)389     GENERAL_COLLECTORS_GUIDE( LSET aVisibleLayerMask, PCB_LAYER_ID aPreferredLayer,
390                               KIGFX::VIEW* aView )
391     {
392         VECTOR2I one( 1, 1 );
393 
394         m_preferredLayer            = aPreferredLayer;
395         m_ignorePreferredLayer      = false;
396         m_visibleLayers             = aVisibleLayerMask;
397         m_ignoreLockedLayers        = true;
398         m_ignoreNonVisibleLayers    = true;
399         m_ignoreLockedItems         = false;
400 
401 #if defined(USE_MATCH_LAYER)
402         m_includeSecondary          = false;
403 #else
404         m_includeSecondary          = true;
405 #endif
406 
407         m_ignoreHiddenFPText        = true; // g_ModuleTextNOVColor;
408         m_ignoreFPTextOnBack        = true;
409         m_ignoreFPTextOnFront       = false;
410         m_ignoreFootprintsOnBack    = true; // !Show_footprints_Cmp;
411         m_ignoreFootprintsOnFront   = false;
412 
413         m_ignorePadsOnFront         = false;
414         m_ignorePadsOnBack          = false;
415         m_ignoreThroughHolePads     = false;
416 
417         m_ignoreFPValues            = false;
418         m_ignoreFPReferences        = false;
419 
420         m_ignoreThroughVias         = false;
421         m_ignoreBlindBuriedVias     = false;
422         m_ignoreMicroVias           = false;
423         m_ignoreTracks              = false;
424         m_ignoreZoneFills           = true;
425 
426         m_onePixelInIU              = abs( aView->ToWorld( one, false ).x );
427     }
428 
429     /**
430      * @return true if the given layer is locked, else false.
431      */
IsLayerLocked(PCB_LAYER_ID aLayerId)432     bool IsLayerLocked( PCB_LAYER_ID aLayerId ) const override
433     {
434         return m_lockedLayers[aLayerId];
435     }
436 
SetLayerLocked(PCB_LAYER_ID aLayerId,bool isLocked)437     void SetLayerLocked( PCB_LAYER_ID aLayerId, bool isLocked )
438     {
439         m_lockedLayers.set( aLayerId, isLocked );
440     }
441 
442     /**
443      * @return true if the given layer is visible, else false.
444      */
IsLayerVisible(PCB_LAYER_ID aLayerId)445     bool IsLayerVisible( PCB_LAYER_ID aLayerId ) const override
446     {
447         return m_visibleLayers[aLayerId];
448     }
SetLayerVisible(PCB_LAYER_ID aLayerId,bool isVisible)449     void SetLayerVisible( PCB_LAYER_ID aLayerId, bool isVisible )
450     {
451         m_visibleLayers.set( aLayerId, isVisible );
452     }
SetLayerVisibleBits(LSET aLayerBits)453     void SetLayerVisibleBits( LSET aLayerBits ) { m_visibleLayers = aLayerBits; }
454 
455     /**
456      * @return true if should ignore locked layers, else false.
457      */
IgnoreLockedLayers()458     bool IgnoreLockedLayers() const override        { return m_ignoreLockedLayers; }
SetIgnoreLockedLayers(bool ignore)459     void SetIgnoreLockedLayers( bool ignore )       { m_ignoreLockedLayers = ignore; }
460 
461     /**
462      * @return true if should ignore non-visible layers, else false.
463      */
IgnoreNonVisibleLayers()464     bool IgnoreNonVisibleLayers() const override    { return m_ignoreNonVisibleLayers; }
SetIgnoreNonVisibleLayers(bool ignore)465     void SetIgnoreNonVisibleLayers( bool ignore )   { m_ignoreLockedLayers = ignore; }
466 
467     /**
468      * @return int - the preferred layer for HitTest()ing.
469      */
GetPreferredLayer()470     PCB_LAYER_ID GetPreferredLayer() const override    { return m_preferredLayer; }
SetPreferredLayer(PCB_LAYER_ID aLayer)471     void SetPreferredLayer( PCB_LAYER_ID aLayer )      { m_preferredLayer = aLayer; }
472 
473     /**
474      * Provide wildcard behavior regarding the preferred layer.
475      *
476      * @return true if should ignore preferred layer, else false.
477      */
IgnorePreferredLayer()478     bool IgnorePreferredLayer() const override      { return  m_ignorePreferredLayer; }
SetIgnorePreferredLayer(bool ignore)479     void SetIgnorePreferredLayer( bool ignore )     { m_ignorePreferredLayer = ignore; }
480 
481     /**
482      * @return true if should ignore locked items, else false.
483      */
IgnoreLockedItems()484     bool IgnoreLockedItems() const override         { return m_ignoreLockedItems; }
SetIgnoreLockedItems(bool ignore)485     void SetIgnoreLockedItems( bool ignore )        { m_ignoreLockedItems = ignore; }
486 
487     /**
488      * Determine if the secondary criteria, or 2nd choice items should be included.
489      *
490      * @return true if should include, else false.
491      */
IncludeSecondary()492     bool IncludeSecondary() const override { return m_includeSecondary; }
SetIncludeSecondary(bool include)493     void SetIncludeSecondary( bool include ) { m_includeSecondary = include; }
494 
495     /**
496      * @return true if MTexts marked as "no show" should be ignored.
497      */
IgnoreHiddenFPText()498     bool IgnoreHiddenFPText() const override { return m_ignoreHiddenFPText; }
SetIgnoreMTextsMarkedNoShow(bool ignore)499     void SetIgnoreMTextsMarkedNoShow( bool ignore ) { m_ignoreHiddenFPText = ignore; }
500 
501     /**
502      * @return true if should ignore MTexts on back layers
503      */
IgnoreFPTextOnBack()504     bool IgnoreFPTextOnBack() const override { return m_ignoreFPTextOnBack; }
SetIgnoreMTextsOnBack(bool ignore)505     void SetIgnoreMTextsOnBack( bool ignore ) { m_ignoreFPTextOnBack = ignore; }
506 
507     /**
508      * @return true if should ignore MTexts on front layers
509      */
IgnoreFPTextOnFront()510     bool IgnoreFPTextOnFront() const override { return m_ignoreFPTextOnFront; }
SetIgnoreMTextsOnFront(bool ignore)511     void SetIgnoreMTextsOnFront( bool ignore ) { m_ignoreFPTextOnFront = ignore; }
512 
513     /**
514      * @return true if should ignore MODULEs on the back side
515      */
IgnoreFootprintsOnBack()516     bool IgnoreFootprintsOnBack() const override { return m_ignoreFootprintsOnBack; }
SetIgnoreModulesOnBack(bool ignore)517     void SetIgnoreModulesOnBack( bool ignore ) { m_ignoreFootprintsOnBack = ignore; }
518 
519     /**
520      * @return true if should ignore MODULEs on component layer.
521      */
IgnoreFootprintsOnFront()522     bool IgnoreFootprintsOnFront() const override { return m_ignoreFootprintsOnFront; }
SetIgnoreModulesOnFront(bool ignore)523     void SetIgnoreModulesOnFront( bool ignore ) { m_ignoreFootprintsOnFront = ignore; }
524 
525     /**
526      * @return true if should ignore Pads on Back Side.
527      */
IgnorePadsOnBack()528     bool IgnorePadsOnBack() const override { return m_ignorePadsOnBack; }
SetIgnorePadsOnBack(bool ignore)529     void SetIgnorePadsOnBack(bool ignore) { m_ignorePadsOnBack = ignore; }
530 
531     /**
532      * @return true if should ignore PADSs on Front Side.
533      */
IgnorePadsOnFront()534     bool IgnorePadsOnFront() const override { return m_ignorePadsOnFront; }
SetIgnorePadsOnFront(bool ignore)535     void SetIgnorePadsOnFront(bool ignore) { m_ignorePadsOnFront = ignore; }
536 
537     /**
538      * @return true if should ignore through-hole PADSs.
539      */
IgnoreThroughHolePads()540     bool IgnoreThroughHolePads() const override { return m_ignoreThroughHolePads; }
SetIgnoreThroughHolePads(bool ignore)541     void SetIgnoreThroughHolePads(bool ignore) { m_ignoreThroughHolePads = ignore; }
542 
543     /**
544      * @return true if should ignore footprints values.
545      */
IgnoreFPValues()546     bool IgnoreFPValues() const override { return m_ignoreFPValues; }
SetIgnoreModulesVals(bool ignore)547     void SetIgnoreModulesVals(bool ignore) { m_ignoreFPValues = ignore; }
548 
549     /**
550      * @return true if should ignore footprints references.
551      */
IgnoreFPReferences()552     bool IgnoreFPReferences() const override { return m_ignoreFPReferences; }
SetIgnoreModulesRefs(bool ignore)553     void SetIgnoreModulesRefs(bool ignore) { m_ignoreFPReferences = ignore; }
554 
IgnoreThroughVias()555     bool IgnoreThroughVias() const override { return m_ignoreThroughVias; }
SetIgnoreThroughVias(bool ignore)556     void SetIgnoreThroughVias( bool ignore ) { m_ignoreThroughVias = ignore; }
557 
IgnoreBlindBuriedVias()558     bool IgnoreBlindBuriedVias() const override { return m_ignoreBlindBuriedVias; }
SetIgnoreBlindBuriedVias(bool ignore)559     void SetIgnoreBlindBuriedVias( bool ignore ) { m_ignoreBlindBuriedVias = ignore; }
560 
IgnoreMicroVias()561     bool IgnoreMicroVias() const override { return m_ignoreMicroVias; }
SetIgnoreMicroVias(bool ignore)562     void SetIgnoreMicroVias( bool ignore ) { m_ignoreMicroVias = ignore; }
563 
IgnoreTracks()564     bool IgnoreTracks() const override { return m_ignoreTracks; }
SetIgnoreTracks(bool ignore)565     void SetIgnoreTracks( bool ignore ) { m_ignoreTracks = ignore; }
566 
IgnoreZoneFills()567     bool IgnoreZoneFills() const override { return m_ignoreZoneFills; }
SetIgnoreZoneFills(bool ignore)568     void SetIgnoreZoneFills( bool ignore ) { m_ignoreZoneFills = ignore; }
569 
OnePixelInIU()570     double OnePixelInIU() const override { return m_onePixelInIU; }
SetOnePixelInIU(double aValue)571     void SetOnePixelInIU( double aValue ) { m_onePixelInIU = aValue; }
572 
573 private:
574     // the storage architecture here is not important, since this is only
575     // a carrier object and its functions are what is used, and data only indirectly.
576 
577     PCB_LAYER_ID m_preferredLayer;
578     bool    m_ignorePreferredLayer;
579 
580     LSET    m_lockedLayers;                  ///< bit-mapped layer locked bits
581     bool    m_ignoreLockedLayers;
582 
583     LSET    m_visibleLayers;                 ///< bit-mapped layer visible bits
584     bool    m_ignoreNonVisibleLayers;
585 
586     bool    m_ignoreLockedItems;
587     bool    m_includeSecondary;
588 
589     bool    m_ignoreHiddenFPText;
590     bool    m_ignoreFPTextOnBack;
591     bool    m_ignoreFPTextOnFront;
592     bool    m_ignoreFootprintsOnBack;
593     bool    m_ignoreFootprintsOnFront;
594     bool    m_ignorePadsOnFront;
595     bool    m_ignorePadsOnBack;
596     bool    m_ignoreThroughHolePads;
597     bool    m_ignoreFPValues;
598     bool    m_ignoreFPReferences;
599     bool    m_ignoreThroughVias;
600     bool    m_ignoreBlindBuriedVias;
601     bool    m_ignoreMicroVias;
602     bool    m_ignoreTracks;
603     bool    m_ignoreZoneFills;
604 
605     double  m_onePixelInIU;
606 };
607 
608 
609 /**
610  * Collect all #BOARD_ITEM objects of a given set of #KICAD_T type(s).
611  *
612  * @see class COLLECTOR
613  */
614 class PCB_TYPE_COLLECTOR : public PCB_COLLECTOR
615 {
616 public:
617 
618     /**
619      * The examining function within the INSPECTOR which is passed to the Iterate function.
620      *
621      * @param testItem An EDA_ITEM to examine.
622      * @param testData is not used in this class.
623      * @return SEARCH_QUIT if the Iterator is to stop the scan, else SCAN_CONTINUE;
624      */
625     SEARCH_RESULT Inspect( EDA_ITEM* testItem, void* testData ) override;
626 
627     /**
628      * Collect #BOARD_ITEM objects using this class's Inspector method, which does the collection.
629      *
630      * @param aBoard The BOARD_ITEM to scan.
631      * @param aScanList The KICAD_Ts to gather up.
632      */
633     void Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] );
634 };
635 
636 
637 /**
638  * Collect all #BOARD_ITEM objects on a given layer.
639  *
640  * This only uses the primary object layer for comparison.
641  */
642 class PCB_LAYER_COLLECTOR : public PCB_COLLECTOR
643 {
644 public:
645     PCB_LAYER_COLLECTOR( PCB_LAYER_ID aLayerId = UNDEFINED_LAYER ) :
m_layer_id(aLayerId)646         m_layer_id( aLayerId )
647     {
648     }
649 
SetLayerId(PCB_LAYER_ID aLayerId)650     void SetLayerId( PCB_LAYER_ID aLayerId ) { m_layer_id = aLayerId; }
651 
652     /**
653      * The examining function within the INSPECTOR which is passed to the iterate function.
654      *
655      * @param testItem An EDA_ITEM to examine.
656      * @param testData is not used in this class.
657      * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
658      *   else SCAN_CONTINUE;
659      */
660     SEARCH_RESULT Inspect( EDA_ITEM* testItem, void* testData ) override;
661 
662     /**
663      * Test a BOARD_ITEM using this class's Inspector method, which does the collection.
664      *
665      * @param aBoard The BOARD_ITEM to scan.
666      * @param aScanList The KICAD_Ts to gather up.
667      */
668     void Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] );
669 
670 private:
671     PCB_LAYER_ID m_layer_id;
672 };
673 
674 #endif // COLLECTORS_H
675