1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2014 CERN
5 * Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
6 * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26 #ifndef __KICAD_TYPEINFO_H
27 #define __KICAD_TYPEINFO_H
28
29
30 #ifndef SWIG
31 #include <type_traits>
32
33 /**
34 * Check if the type of aObject is T.
35 *
36 * @param aObject the object for type check.
37 * @return true, if aObject type equals T.
38 */
39 template <class T, class I>
IsA(const I * aObject)40 bool IsA( const I* aObject )
41 {
42 return aObject && std::remove_pointer<T>::type::ClassOf( aObject );
43 }
44
45 template <class T, class I>
IsA(const I & aObject)46 bool IsA( const I& aObject )
47 {
48 return std::remove_pointer<T>::type::ClassOf( &aObject );
49 }
50
51 /**
52 * A lightweight dynamic downcast.
53 *
54 * Cast \a aObject to type Casted*. Uses #EDA_ITEM::Type() and #EDA_ITEM::ClassOf() to
55 * check if type matches.
56 *
57 * @param aObject object to be casted.
58 * @return down-casted object or NULL if type doesn't match Casted.
59 */
60 template<class Casted, class From>
dyn_cast(From aObject)61 Casted dyn_cast( From aObject )
62 {
63 if( std::remove_pointer<Casted>::type::ClassOf ( aObject ) )
64 return static_cast<Casted>( aObject );
65
66 return nullptr;
67 }
68
69 class EDA_ITEM;
70
71 #endif // SWIG
72
73
74 /**
75 * The set of class identification values stored in #EDA_ITEM::m_structType
76 */
77 enum KICAD_T
78 {
79 NOT_USED = -1, ///< the 3d code uses this value
80
81 EOT = 0, ///< search types array terminator (End Of Types)
82
83 TYPE_NOT_INIT = 0,
84 PCB_T,
85 SCREEN_T, ///< not really an item, used to identify a screen
86
87 // Items in pcb
88 PCB_FOOTPRINT_T, ///< class FOOTPRINT, a footprint
89 PCB_PAD_T, ///< class PAD, a pad in a footprint
90 PCB_SHAPE_T, ///< class PCB_SHAPE, a segment not on copper layers
91 PCB_TEXT_T, ///< class PCB_TEXT, text on a layer
92 PCB_FP_TEXT_T, ///< class FP_TEXT, text in a footprint
93 PCB_FP_SHAPE_T, ///< class FP_SHAPE, a footprint edge
94 PCB_FP_ZONE_T, ///< class ZONE, managed by a footprint
95 PCB_TRACE_T, ///< class PCB_TRACK, a track segment (segment on a copper layer)
96 PCB_VIA_T, ///< class PCB_VIA, a via (like a track segment on a copper layer)
97 PCB_ARC_T, ///< class PCB_ARC, an arc track segment on a copper layer
98 PCB_MARKER_T, ///< class PCB_MARKER, a marker used to show something
99 PCB_DIMENSION_T, ///< class PCB_DIMENSION_BASE: abstract dimension meta-type
100 PCB_DIM_ALIGNED_T, ///< class PCB_DIM_ALIGNED, a linear dimension (graphic item)
101 PCB_DIM_LEADER_T, ///< class PCB_DIM_LEADER, a leader dimension (graphic item)
102 PCB_DIM_CENTER_T, ///< class PCB_DIM_CENTER, a center point marking (graphic item)
103 PCB_DIM_ORTHOGONAL_T, ///< class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
104 PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item)
105 PCB_ZONE_T, ///< class ZONE, a copper pour area
106 PCB_ITEM_LIST_T, ///< class BOARD_ITEM_LIST, a list of board items
107 PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net
108 PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs
109
110 PCB_LOCATE_STDVIA_T,
111 PCB_LOCATE_UVIA_T,
112 PCB_LOCATE_BBVIA_T,
113 PCB_LOCATE_TEXT_T,
114 PCB_LOCATE_GRAPHIC_T,
115 PCB_LOCATE_HOLE_T,
116 PCB_LOCATE_PTH_T,
117 PCB_LOCATE_NPTH_T,
118 PCB_LOCATE_BOARD_EDGE_T,
119
120 // Schematic draw Items. The order of these items effects the sort order.
121 // It is currently ordered to mimic the old Eeschema locate behavior where
122 // the smallest item is the selected item.
123 SCH_MARKER_T,
124 SCH_JUNCTION_T,
125 SCH_NO_CONNECT_T,
126 SCH_BUS_WIRE_ENTRY_T,
127 SCH_BUS_BUS_ENTRY_T,
128 SCH_LINE_T,
129 SCH_BITMAP_T,
130 SCH_TEXT_T,
131 SCH_LABEL_T,
132 SCH_GLOBAL_LABEL_T,
133 SCH_HIER_LABEL_T,
134 SCH_FIELD_T,
135 SCH_SYMBOL_T,
136 SCH_SHEET_PIN_T,
137 SCH_SHEET_T,
138 SCH_PIN_T,
139
140 // Be prudent with these types:
141 // they should be used only to locate a specific field type among SCH_FIELD_Ts
142 // N.B. If you add a type here, be sure to add it below to the BaseType()
143 SCH_FIELD_LOCATE_REFERENCE_T,
144 SCH_FIELD_LOCATE_VALUE_T,
145 SCH_FIELD_LOCATE_FOOTPRINT_T,
146 SCH_FIELD_LOCATE_DATASHEET_T,
147
148 // Same for picking wires and buses from SCH_LINE_T items
149 SCH_LINE_LOCATE_WIRE_T,
150 SCH_LINE_LOCATE_BUS_T,
151 SCH_LINE_LOCATE_GRAPHIC_LINE_T,
152
153 // Same for picking labels attached to wires and/or buses
154 SCH_LABEL_LOCATE_WIRE_T,
155 SCH_LABEL_LOCATE_BUS_T,
156
157 // Same for picking symbols which are power symbols
158 SCH_SYMBOL_LOCATE_POWER_T,
159
160 // matches any type
161 SCH_LOCATE_ANY_T,
162
163 // General
164 SCH_SCREEN_T,
165
166 SCHEMATIC_T,
167
168 /*
169 * Draw items in library symbol.
170 *
171 * The order of these items effects the sort order for items inside the
172 * "DRAW/ENDDRAW" section of the symbol definition in a library file.
173 * If you add a new draw item, type, please make sure you add it so the
174 * sort order is logical.
175 */
176 LIB_SYMBOL_T,
177 LIB_ALIAS_T,
178 LIB_SHAPE_T,
179 LIB_TEXT_T,
180 LIB_PIN_T,
181
182 /*
183 * Fields are not saved inside the "DRAW/ENDDRAW". Add new draw item
184 * types before this line.
185 */
186 LIB_FIELD_T,
187
188 /*
189 * For GerbView: item types:
190 */
191 GERBER_LAYOUT_T,
192 GERBER_DRAW_ITEM_T,
193 GERBER_IMAGE_T,
194
195 /*
196 * For Pl_Editor: item types:
197 */
198 WSG_LINE_T,
199 WSG_RECT_T,
200 WSG_POLY_T,
201 WSG_TEXT_T,
202 WSG_BITMAP_T,
203 WSG_PAGE_T,
204
205 // serialized layout used in undo/redo commands
206 WS_PROXY_UNDO_ITEM_T, // serialized layout used in undo/redo commands
207 WS_PROXY_UNDO_ITEM_PLUS_T, // serialized layout plus page and title block settings
208
209 /*
210 * FOR PROJECT::_ELEMs
211 */
212 SYMBOL_LIB_TABLE_T,
213 FP_LIB_TABLE_T,
214 SYMBOL_LIBS_T,
215 SEARCH_STACK_T,
216 S3D_CACHE_T,
217
218 // End value
219 MAX_STRUCT_TYPE_ID
220 };
221
222 /**
223 * Return the underlying type of the given type.
224 *
225 * This is useful for finding the element type given one of the "non-type" types such as
226 * SCH_LINE_LOCATE_WIRE_T.
227 *
228 * @param aType Given type to resolve.
229 * @return Base type.
230 */
BaseType(const KICAD_T aType)231 constexpr KICAD_T BaseType( const KICAD_T aType )
232 {
233 switch( aType )
234 {
235 case SCH_FIELD_LOCATE_REFERENCE_T:
236 case SCH_FIELD_LOCATE_VALUE_T:
237 case SCH_FIELD_LOCATE_FOOTPRINT_T:
238 case SCH_FIELD_LOCATE_DATASHEET_T:
239 return SCH_FIELD_T;
240
241 case SCH_LINE_LOCATE_WIRE_T:
242 case SCH_LINE_LOCATE_BUS_T:
243 case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
244 return SCH_LINE_T;
245
246 case SCH_LABEL_LOCATE_WIRE_T:
247 case SCH_LABEL_LOCATE_BUS_T:
248 return SCH_LABEL_T;
249
250 case SCH_SYMBOL_LOCATE_POWER_T:
251 return SCH_SYMBOL_T;
252
253 case PCB_LOCATE_HOLE_T:
254 case PCB_LOCATE_PTH_T:
255 case PCB_LOCATE_NPTH_T:
256 return PCB_LOCATE_HOLE_T;
257
258 case PCB_DIM_ALIGNED_T:
259 case PCB_DIM_CENTER_T:
260 case PCB_DIM_ORTHOGONAL_T:
261 case PCB_DIM_LEADER_T:
262 return PCB_DIMENSION_T;
263
264 default:
265 return aType;
266 }
267 }
268
IsNullType(const KICAD_T aType)269 constexpr bool IsNullType( const KICAD_T aType )
270 {
271 return aType <= 0;
272 }
273
IsInstantiableType(const KICAD_T aType)274 constexpr bool IsInstantiableType( const KICAD_T aType )
275 {
276 if( IsNullType( aType ) )
277 return false;
278
279 switch( aType )
280 {
281 case SCH_LOCATE_ANY_T:
282
283 case SCH_FIELD_LOCATE_REFERENCE_T:
284 case SCH_FIELD_LOCATE_VALUE_T:
285 case SCH_FIELD_LOCATE_FOOTPRINT_T:
286 case SCH_FIELD_LOCATE_DATASHEET_T:
287
288 case SCH_LINE_LOCATE_WIRE_T:
289 case SCH_LINE_LOCATE_BUS_T:
290 case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
291
292 case SCH_LABEL_LOCATE_WIRE_T:
293 case SCH_LABEL_LOCATE_BUS_T:
294
295 case SCH_SYMBOL_LOCATE_POWER_T:
296
297 case PCB_LOCATE_STDVIA_T:
298 case PCB_LOCATE_UVIA_T:
299 case PCB_LOCATE_BBVIA_T:
300 case PCB_LOCATE_TEXT_T:
301 case PCB_LOCATE_GRAPHIC_T:
302 case PCB_LOCATE_HOLE_T:
303 case PCB_LOCATE_PTH_T:
304 case PCB_LOCATE_NPTH_T:
305 case PCB_LOCATE_BOARD_EDGE_T:
306
307 case PCB_DIMENSION_T:
308
309 case SCH_SCREEN_T:
310 case PCB_ITEM_LIST_T:
311 return false;
312
313 default:
314 break;
315 }
316
317 return true;
318
319 }
320
IsEeschemaType(const KICAD_T aType)321 constexpr bool IsEeschemaType( const KICAD_T aType )
322 {
323 switch( aType )
324 {
325 case SCH_MARKER_T:
326 case SCH_JUNCTION_T:
327 case SCH_NO_CONNECT_T:
328 case SCH_BUS_WIRE_ENTRY_T:
329 case SCH_BUS_BUS_ENTRY_T:
330 case SCH_LINE_T:
331 case SCH_BITMAP_T:
332 case SCH_TEXT_T:
333 case SCH_LABEL_T:
334 case SCH_GLOBAL_LABEL_T:
335 case SCH_HIER_LABEL_T:
336 case SCH_FIELD_T:
337 case SCH_SYMBOL_T:
338 case SCH_SHEET_PIN_T:
339 case SCH_SHEET_T:
340 case SCH_PIN_T:
341
342 case SCH_FIELD_LOCATE_REFERENCE_T:
343 case SCH_FIELD_LOCATE_VALUE_T:
344 case SCH_FIELD_LOCATE_FOOTPRINT_T:
345 case SCH_FIELD_LOCATE_DATASHEET_T:
346
347 case SCH_LINE_LOCATE_WIRE_T:
348 case SCH_LINE_LOCATE_BUS_T:
349 case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
350
351 case SCH_LABEL_LOCATE_WIRE_T:
352 case SCH_LABEL_LOCATE_BUS_T:
353
354 case SCH_SYMBOL_LOCATE_POWER_T:
355 case SCH_LOCATE_ANY_T:
356
357 case SCH_SCREEN_T:
358 case SCHEMATIC_T:
359
360 case LIB_SYMBOL_T:
361 case LIB_ALIAS_T:
362 case LIB_SHAPE_T:
363 case LIB_TEXT_T:
364 case LIB_PIN_T:
365
366 case LIB_FIELD_T:
367 return true;
368
369 default:
370 return false;
371 }
372 }
373
IsPcbnewType(const KICAD_T aType)374 constexpr bool IsPcbnewType( const KICAD_T aType )
375 {
376 switch( aType )
377 {
378 case PCB_T:
379
380 case PCB_FOOTPRINT_T:
381 case PCB_PAD_T:
382 case PCB_SHAPE_T:
383 case PCB_TEXT_T:
384 case PCB_FP_TEXT_T:
385 case PCB_FP_SHAPE_T:
386 case PCB_FP_ZONE_T:
387 case PCB_TRACE_T:
388 case PCB_VIA_T:
389 case PCB_ARC_T:
390 case PCB_MARKER_T:
391 case PCB_DIMENSION_T:
392 case PCB_DIM_ALIGNED_T:
393 case PCB_DIM_LEADER_T:
394 case PCB_DIM_CENTER_T:
395 case PCB_DIM_ORTHOGONAL_T:
396 case PCB_TARGET_T:
397 case PCB_ZONE_T:
398 case PCB_ITEM_LIST_T:
399 case PCB_NETINFO_T:
400 case PCB_GROUP_T:
401
402 case PCB_LOCATE_STDVIA_T:
403 case PCB_LOCATE_UVIA_T:
404 case PCB_LOCATE_BBVIA_T:
405 case PCB_LOCATE_TEXT_T:
406 case PCB_LOCATE_GRAPHIC_T:
407 case PCB_LOCATE_HOLE_T:
408 case PCB_LOCATE_PTH_T:
409 case PCB_LOCATE_NPTH_T:
410 case PCB_LOCATE_BOARD_EDGE_T:
411 return true;
412
413 default:
414 return false;
415 }
416 }
417
IsGerbviewType(const KICAD_T aType)418 constexpr bool IsGerbviewType( const KICAD_T aType )
419 {
420 switch( aType )
421 {
422 case GERBER_LAYOUT_T:
423 case GERBER_DRAW_ITEM_T:
424 case GERBER_IMAGE_T:
425 return true;
426
427 default:
428 return false;
429 }
430 }
431
IsPageLayoutEditorType(const KICAD_T aType)432 constexpr bool IsPageLayoutEditorType( const KICAD_T aType )
433 {
434 switch( aType )
435 {
436 case WSG_LINE_T:
437 case WSG_RECT_T:
438 case WSG_POLY_T:
439 case WSG_TEXT_T:
440 case WSG_BITMAP_T:
441 case WSG_PAGE_T:
442
443 case WS_PROXY_UNDO_ITEM_T:
444 case WS_PROXY_UNDO_ITEM_PLUS_T:
445 return true;
446
447 default:
448 return false;
449 }
450 }
451
IsMiscType(const KICAD_T aType)452 constexpr bool IsMiscType( const KICAD_T aType )
453 {
454 switch( aType )
455 {
456 case SCREEN_T:
457
458 case SYMBOL_LIB_TABLE_T:
459 case FP_LIB_TABLE_T:
460 case SYMBOL_LIBS_T:
461 case SEARCH_STACK_T:
462 case S3D_CACHE_T:
463 return true;
464
465 default:
466 return false;
467 }
468 }
469
IsTypeCorrect(KICAD_T aType)470 constexpr bool IsTypeCorrect( KICAD_T aType )
471 {
472 return IsNullType( aType )
473 || IsEeschemaType( aType )
474 || IsPcbnewType( aType )
475 || IsGerbviewType( aType )
476 || IsPageLayoutEditorType( aType )
477 || IsMiscType( aType );
478 }
479
IsTypeAvailable(KICAD_T aType)480 constexpr bool IsTypeAvailable( KICAD_T aType )
481 {
482 if( !IsInstantiableType( aType ) )
483 return false;
484
485 if( IsEeschemaType( aType ) )
486 {
487 #ifdef EESCHEMA
488 return true;
489 #endif // EESCHEMA
490 }
491
492 if( IsPcbnewType( aType ) )
493 {
494 #ifdef PCBNEW
495 return true;
496 #endif // PCBNEW
497 }
498
499 if( IsGerbviewType( aType ) )
500 {
501 #ifdef GERBVIEW
502 return true;
503 #endif // GERBVIEW
504 }
505
506 if( IsPageLayoutEditorType( aType ) )
507 {
508 #ifdef PL_EDITOR
509 return true;
510 #endif // PL_EDITOR
511 }
512
513 return false;
514 }
515
516 #endif // __KICAD_TYPEINFO_H
517