KiCad PCB EDA Suite
sch_collectors.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) 2011-2016 Wayne Stambaugh <stambaughw@verizon.net>
5  * Copyright (C) 2004-2016 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 
29 #include <macros.h>
30 
31 #include <sch_sheet_path.h>
32 #include <transform.h>
33 #include <sch_collectors.h>
34 #include <sch_component.h>
35 #include <sch_line.h>
36 #include <sch_bus_entry.h>
37 
38 
45  SCH_LINE_T,
47  SCH_TEXT_T,
53  LIB_PIN_T,
56  EOT
57 };
58 
59 
66  SCH_LINE_T,
68  SCH_TEXT_T,
76  EOT
77 };
78 
79 
81  SCH_TEXT_T,
90  SCH_LINE_T,
91  EOT
92 };
93 
96  EOT
97 };
98 
101  EOT
102 };
103 
106  EOT
107 };
108 
109 
111  SCH_MARKER_T,
116 // SCH_LINE_T,
117  SCH_BITMAP_T,
118  SCH_TEXT_T,
119  SCH_LABEL_T,
122  SCH_FIELD_T,
125  SCH_SHEET_T,
126  EOT
127 };
128 
129 
134  SCH_LINE_T,
135  SCH_LABEL_T,
139  SCH_SHEET_T,
140  EOT
141 };
142 
143 
145  SCH_TEXT_T,
146  SCH_LABEL_T,
149  SCH_FIELD_T,
151  SCH_SHEET_T,
152  SCH_BITMAP_T,
153  EOT
154 };
155 
156 
158  SCH_MARKER_T,
163  SCH_LINE_T,
164  SCH_TEXT_T,
165  SCH_LABEL_T,
170  SCH_SHEET_T,
171  SCH_BITMAP_T,
172  EOT
173 };
174 
175 
178  EOT
179 };
180 
181 
183  SCH_SHEET_T,
184  EOT
185 };
186 
187 
190  SCH_SHEET_T,
191  EOT
192 };
193 
194 
197  SCH_BITMAP_T,
198  SCH_SHEET_T,
199  EOT
200 };
201 
202 
204  SCH_TEXT_T,
205  SCH_LABEL_T,
209  EOT
210 };
211 
212 
214  SCH_TEXT_T,
215  SCH_LABEL_T,
219  SCH_SHEET_T,
220  SCH_BITMAP_T,
221  SCH_FIELD_T,
222  SCH_MARKER_T,
223  EOT
224 };
225 
226 
228 {
229  if( aItem->Type() != LIB_PIN_T && !aItem->HitTest( m_RefPos ) )
230  return SEARCH_CONTINUE;
231 
232  // Pins have special hit testing requirements that are relative to their parent
233  // SCH_COMPONENT item.
234  if( aItem->Type() == LIB_PIN_T )
235  {
236  wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
237  SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
238 
239  // Pin hit testing is relative to the components position and orientation in the
240  // schematic. The hit test position must be converted to library coordinates.
241  SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
242  TRANSFORM transform = component->GetTransform().InverseTransform();
243  wxPoint position = transform.TransformCoordinate( m_RefPos - component->GetPosition() );
244 
245  position.y *= -1; // Y axis polarity in schematic is inverted from library.
246 
247  if( !aItem->HitTest( position ) )
248  return SEARCH_CONTINUE;
249  }
250 
251  Append( aItem );
252 
253  return SEARCH_CONTINUE;
254 }
255 
256 
257 void SCH_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[],
258  const wxPoint& aPosition )
259 {
260  Empty(); // empty the collection just in case
261 
262  SetScanTypes( aFilterList );
263 
264  // remember where the snapshot was taken from and pass refPos to the Inspect() function.
265  SetRefPos( aPosition );
266 
268 }
269 
270 
272 {
273  if( GetCount() != 2 )
274  return false;
275 
276  bool is_busentry0 = (dynamic_cast<SCH_BUS_ENTRY_BASE*>( m_List[0] ) != NULL);
277  bool is_busentry1 = (dynamic_cast<SCH_BUS_ENTRY_BASE*>( m_List[1] ) != NULL);
278 
279  if( (m_List[0]->Type() == SCH_LINE_T) && (m_List[1]->Type() == SCH_LINE_T) )
280  return ( ( SCH_LINE* ) m_List[0])->GetLayer() == ( ( SCH_LINE* ) m_List[1])->GetLayer();
281 
282  if( (m_List[0]->Type() == SCH_LINE_T) && is_busentry1 )
283  return true;
284 
285  if( is_busentry0 && (m_List[1]->Type() == SCH_LINE_T) )
286  return true;
287 
288  return false;
289 }
290 
291 
292 bool SCH_COLLECTOR::IsNode( bool aIncludePins ) const
293 {
294  for( size_t i = 0; i < m_List.size(); i++ )
295  {
296  SCH_ITEM* item = (SCH_ITEM*) m_List[ i ];
297  KICAD_T type = item->Type();
298 
299  if( type == SCH_JUNCTION_T )
300  continue;
301 
302  if( type == SCH_LINE_T )
303  {
304  if( item->GetLayer() != LAYER_WIRE )
305  return false;
306 
307  continue;
308  }
309 
310  if( type == LIB_PIN_T )
311  {
312  if( !aIncludePins )
313  return false;
314 
315  continue;
316  }
317 
318  // Any other item types indicate that this collection is not a node.
319  return false;
320  }
321 
322  return true;
323 }
324 
325 
327 {
328  for( size_t i = 0; i < m_List.size(); i++ )
329  if( ( (SCH_ITEM*) m_List[ i ] )->Type() == SCH_JUNCTION_T )
330  return true;
331 
332  return false;
333 }
334 
335 
341 {
342 public:
344  SCH_ITEM( nullptr, NOT_USED )
345  {}
346 
347  wxString GetSelectMenuText() const override { return _( "(Deleted Item)" ); }
348  wxString GetClass() const override { return wxT( "DELETED_SCH_ITEM" ); }
349 
350  // define pure virtuals:
351  wxPoint GetPosition() const override { return wxPoint(); }
352  void SetPosition( const wxPoint& ) override {}
353  void Draw( EDA_DRAW_PANEL* , wxDC* , const wxPoint& , GR_DRAWMODE , COLOR4D ) override {}
354 
355 #if defined(DEBUG)
356  void Show( int , std::ostream& ) const override {}
357 #endif
358 
359  void Move( const wxPoint& ) override {}
360  void MirrorY( int ) override {}
361  void MirrorX( int ) override {}
362  void Rotate( wxPoint ) override {}
363 };
364 
365 
367 
368 
370 {
371  if( (unsigned)ndx >= (unsigned)GetCount() )
372  return NULL;
373 
374  // Do not simply return m_List[ ndx ] as it might have been deleted. Instead
375  // treat it as a weak reference and search the sheets for an item with the same
376  // pointer value.
377 
378  void* weakRef = m_List[ ndx ];
379 
380  for( unsigned i = 0; i < m_sheetPaths.size(); i++ )
381  {
382  for( EDA_ITEM* item = m_sheetPaths[ i ].LastDrawList(); item; item = item->Next() )
383  {
384  if( (void*) item == weakRef )
385  return (SCH_ITEM*) item;
386  }
387  }
388 
389  return &g_DeletedSchItem;
390 }
391 
392 
394 {
395  return GetItem( ndx );
396 }
397 
398 
400 {
401  bool retv = false;
402 
403  wxUint32 flags = m_findReplaceData.GetFlags();
404 
405  if( GetCount() == 0 )
406  return true;
407 
408  if( !(flags & FR_SEARCH_WRAP) || (flags & FR_SEARCH_REPLACE) )
409  {
410  if( flags & wxFR_DOWN )
411  {
412  if( m_foundIndex >= GetCount() )
413  retv = true;
414  }
415  else
416  {
417  if( m_foundIndex < 0 )
418  retv = true;
419  }
420  }
421 
422  return retv;
423 }
424 
425 
426 #if defined(DEBUG)
427 
428 void SCH_FIND_COLLECTOR::dump()
429 {
430  int tmp = m_foundIndex;
431 
432  wxLogTrace( traceFindReplace, wxT( "%d items found to replace %s with %s." ),
433  GetCount(), GetChars( m_findReplaceData.GetFindString() ),
434  GetChars( m_findReplaceData.GetReplaceString() ) );
435 
436  for( m_foundIndex = 0; m_foundIndex < GetCount(); m_foundIndex++ )
437  wxLogTrace( traceFindReplace, wxT( " " ) + GetText() );
438 
439  m_foundIndex = tmp;
440 }
441 
442 #endif
443 
444 
446 {
447  wxUint32 flags = m_findReplaceData.GetFlags();
448 
449  if( flags & wxFR_DOWN )
450  {
451  if( m_foundIndex < GetCount() )
452  m_foundIndex += 1;
453  if( (m_foundIndex >= GetCount()) && (flags & FR_SEARCH_WRAP) )
454  m_foundIndex = 0;
455  }
456  else
457  {
458  if( m_foundIndex >= 0 )
459  m_foundIndex -= 1;
460  if( (m_foundIndex < 0) && (flags & FR_SEARCH_WRAP) )
461  m_foundIndex = GetCount() - 1;
462  }
463 }
464 
465 
467 {
468  wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(),
469  wxT( "Attempt to get find data outside of list boundary." ) );
470 
471  return m_data[ aIndex ];
472 }
473 
474 
476 {
477  wxCHECK_MSG( (GetCount() != 0) && IsValidIndex( m_foundIndex ), wxEmptyString,
478  wxT( "Cannot get found item at invalid index." ) );
479 
480  SCH_FIND_COLLECTOR_DATA data = m_data[ m_foundIndex ];
481  EDA_ITEM* foundItem = GetItem( m_foundIndex );
482 
483  wxString msg;
484 
485  if( data.GetParent() )
486  {
487  msg.Printf( _( "Child item %s of parent item %s found in sheet %s" ),
488  GetChars( foundItem->GetSelectMenuText() ),
489  GetChars( data.GetParent()->GetSelectMenuText() ),
490  GetChars( data.GetSheetPath() ) );
491  }
492  else
493  {
494  msg.Printf( _( "Item %s found in sheet %s" ),
495  GetChars( foundItem->GetSelectMenuText() ),
496  GetChars( data.GetSheetPath() ) );
497  }
498 
499  return msg;
500 }
501 
502 
504 {
505  if( PassedEnd() )
506  return NULL;
507 
508  aData = m_data[ m_foundIndex ];
509  return GetItem( m_foundIndex );
510 }
511 
512 
514 {
515  if( PassedEnd() )
516  return false;
517 
518  wxCHECK_MSG( IsValidIndex( m_foundIndex ), false,
519  wxT( "Invalid replace list index in SCH_FIND_COLLECTOR." ) );
520 
521  EDA_ITEM* item = GetItem( m_foundIndex );
522 
523  bool replaced = item->Replace( m_findReplaceData, aSheetPath );
524 
525  return replaced;
526 }
527 
528 
530 {
531  wxPoint position;
532 
533  if( aItem->Matches( m_findReplaceData, m_currentSheetPath, &position ) )
534  {
535  if( aItem->Type() == LIB_PIN_T )
536  {
537  wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
538  SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
539 
540  // Pin positions are relative to their parent component's position and
541  // orientation in the schematic. The pin's position must be converted
542  // schematic coordinates.
543  SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
544  TRANSFORM transform = component->GetTransform();
545  position.y = -position.y;
546  position = transform.TransformCoordinate( position ) + component->GetPosition();
547  }
548 
549  Append( aItem );
550  m_data.push_back( SCH_FIND_COLLECTOR_DATA( position,
551  m_currentSheetPath->PathHumanReadable(),
552  (SCH_ITEM*) aTestData ) );
553  }
554 
555  return SEARCH_CONTINUE;
556 }
557 
558 
559 void SCH_FIND_COLLECTOR::SetReplaceString( const wxString &aReplaceString )
560 {
561  m_findReplaceData.SetReplaceString( aReplaceString );
562 }
563 
564 
566  SCH_SHEET_PATH* aSheetPath )
567 {
568  if( !IsSearchRequired( aFindReplaceData ) && !m_List.empty() && !m_forceSearch )
569  return;
570 
571  m_findReplaceData = aFindReplaceData;
572  Empty(); // empty the collection just in case
573  m_data.clear();
574  m_foundIndex = 0;
575  m_sheetPaths.clear();
576  SetForceSearch( false );
577 
578  if( aSheetPath )
579  {
580  m_currentSheetPath = aSheetPath;
581  m_sheetPaths.push_back( *m_currentSheetPath );
583  }
584  else
585  {
586  SCH_SHEET_LIST schematic( g_RootSheet );
587 
588  for( unsigned i = 0; i < schematic.size(); i++ )
589  {
590  m_currentSheetPath = &schematic[i];
591  m_sheetPaths.push_back( *m_currentSheetPath );
592  EDA_ITEM::IterateForward( m_currentSheetPath->LastDrawList(), m_inspector, NULL, m_ScanTypes );
593  }
594  }
595 
596 #if defined(DEBUG)
597  dump();
598 #endif
599 
600  if( m_List.size() != m_data.size() )
601  {
602  wxFAIL_MSG( wxT( "List size mismatch." ) );
603  m_List.clear();
604  m_data.clear();
605  }
606 }
607 
608 
610 {
611  // The Vist() function only visits the testItem if its type was in the
612  // the scanList, so therefore we can collect anything given to us here.
613  Append( aItem );
614 
615  return SEARCH_CONTINUE;
616 }
617 
618 
619 void SCH_TYPE_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[] )
620 {
621  Empty(); // empty the collection
622 
623  SetScanTypes( aFilterList );
624 
626 }
SCH_ITEM * LastDrawList() const
Function LastDrawList.
void Empty()
Function Empty sets the list to empty.
Definition: collector.h:116
SCH_ITEM * operator[](int ndx) const
Class SCH_SHEET_LIST.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:107
KICAD_T Type() const
Function Type()
Definition: base_struct.h:227
SCH_ITEM * GetItem(int ndx) const
static const KICAD_T ParentItems[]
A scan list for only parent schematic items.
static SEARCH_RESULT IterateForward(EDA_ITEM *listStart, INSPECTOR inspector, void *testData, const KICAD_T scanTypes[])
Function IterateForward walks through the object tree calling the inspector() on each object type req...
static const KICAD_T SheetsAndSheetLabels[]
A scan list for schematic sheet and sheet label items.
TRANSFORM & GetTransform() const
static const KICAD_T RotatableItems[]
A scan list for all rotatable schematic items.
SEARCH_RESULT Inspect(EDA_ITEM *aItem, void *aTestData) override
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
static const KICAD_T AllItems[]
A scan list for all schematic items.
bool IsValidIndex(int aIndex)
Function IsValidIndex tests if aIndex is with the limits of the list of collected items...
Definition: collector.h:98
static const KICAD_T DoubleClickItems[]
A scan list for schematic items that react to a double-click.
bool Replace(wxFindReplaceData &aSearchData, wxString &aText)
Helper function used in search and replace dialog Function Replace performs a text replace on aText u...
void SetScanTypes(const KICAD_T *scanTypes)
Function SetScanTypes records the list of KICAD_T types to consider for collection by the Inspect() f...
Definition: collector.h:208
wxString GetSheetPath() const
the 3d code uses this value
Definition: typeinfo.h:80
virtual bool Matches(wxFindReplaceData &aSearchData, void *aAuxData, wxPoint *aFindLocation)
Function Matches compares the item against the search criteria in aSearchData.
Definition: base_struct.h:429
SEARCH_RESULT Inspect(EDA_ITEM *testItem, void *testData) override
Function Inspect is the examining function within the INSPECTOR which is passed to the Iterate functi...
void Collect(SCH_ITEM *aItem, const KICAD_T aFilterList[], const wxPoint &aPosition)
Function Collect scans a SCH_ITEM using this class&#39;s Inspector method, which does the collection...
static const KICAD_T ComponentsOnly[]
A scan list for schematic component items only.
wxPoint GetPosition() const override
Function GetPosition.
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
const wxString traceFindReplace
Flag to enable find and replace debug tracing.
Definition: base_struct.cpp:58
Wrap around the beginning or end of search list.
EDA_ITEM * Next() const
Definition: base_struct.h:235
static const KICAD_T AllItemsButPins[]
A scan list for all schematic items except pins.
Class SCH_FIND_COLLECTOR_DATA is used as a data container for the associated item found by the SCH_FI...
static const KICAD_T MovableItems[]
A scan list for all movable schematic items.
virtual wxString GetSelectMenuText() const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void Move(const wxPoint &) override
Function Move moves the item by aMoveVector to a new position.
DELETED_SCH_ITEM g_DeletedSchItem
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
This file contains miscellaneous commonly used macros and functions.
void Append(EDA_ITEM *item)
Function Append adds an item to the end of the list.
Definition: collector.h:126
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:41
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
static const KICAD_T CmpFieldValueOnly[]
A scan list for a specific editable field: Value.
SCH_ITEM * GetParent() const
INSPECTOR_FUNC m_inspector
a class common bridge into the polymorphic Inspect()
Definition: collector.h:60
A singleton item of this class is returned for a weak reference that no longer exists.
Class for tranforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
bool IsDraggableJunction() const
Function IsDraggableJunction tests to see if the collected items form a draggable junction...
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:55
void SetRefPos(const wxPoint &aRefPos)
Definition: collector.h:223
SCH_FIND_COLLECTOR_DATA GetFindData(int aIndex)
Function GetFindData returns the data associated with the item found at aIndex.
bool IsCorner() const
Function IsCorner tests if the collected items forms as corner of two line segments.
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
void UpdateIndex()
Function UpdateIndex updates the list index according to the current find and replace criteria...
bool ReplaceItem(SCH_SHEET_PATH *aSheetPath=NULL)
Function ReplaceItem performs a string replace of the item at the current index.
static const KICAD_T CmpFieldFootprintOnly[]
A scan list for a specific editable field: Footprint.
void Rotate(wxPoint) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
virtual bool HitTest(const wxPoint &aPosition) const
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
Definition: base_struct.h:317
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
Class SCH_SHEET_PATH.
void Draw(EDA_DRAW_PANEL *, wxDC *, const wxPoint &, GR_DRAWMODE, COLOR4D) override
Function Draw Draw a schematic item.
static const KICAD_T EditableItems[]
A scan list for all editable schematic items.
bool IsNode(bool aIncludePins=true) const
Function IsNode tests if the collected items form a node.
Definition the SCH_COMPONENT class for Eeschema.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void SetReplaceString(const wxString &aReplaceString)
Update the replace string without changing anything else.
static const KICAD_T DraggableItems[]
A scan list for all draggable schematic items.
void MirrorX(int) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Segment description base class to describe items which have 2 end points (track, wire, draw line ...)
Definition: sch_line.h:41
void Collect(SCH_FIND_REPLACE_DATA &aFindReplaceData, SCH_SHEET_PATH *aSheetPath=NULL)
Function Collect scans aSheetPath using this class&#39;s Inspector method for items matching aFindReplace...
static const KICAD_T CmpFieldReferenceOnly[]
A scan list for a specific editable field: Reference.
Class SCH_FIND_REPLACE_DATA adds missing useful comparison and assignment operators to the wxFindRepl...
Perform a search for a item that has replaceable text.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
static const KICAD_T CopyableItems[]
A scan list for schematic items that can be copied/duplicated.
wxPoint GetPosition() const override
Function GetPosition.
SEARCH_RESULT Inspect(EDA_ITEM *aItem, void *aTestData) override
void Collect(SCH_ITEM *aBoard, const KICAD_T aScanList[])
Function Collect scans a BOARD_ITEM using this class&#39;s Inspector method, which does the collection...
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:180
static const KICAD_T SheetsOnly[]
A scan list for schematic sheet items only.
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
void MirrorY(int) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
wxPoint m_RefPos
A point to test against, and that was used to make the collection.
Definition: collector.h:69
wxString GetText()
Function GetText()
SEARCH_RESULT
Definition: base_struct.h:82
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::vector< EDA_ITEM * > m_List
A place to hold collected objects without taking ownership of their memory.
Definition: collector.h:66
const KICAD_T * m_ScanTypes
Which object types to scan.
Definition: collector.h:63
bool PassedEnd() const
Function PassedEnd tests if m_foundIndex is beyond the end of the list give the current find/replace ...
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
wxString GetClass() const override
Function GetClass returns the class name.
static const KICAD_T OrientableItems[]
A scan list for schematic items that can be mirrored.
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:58
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void SetPosition(const wxPoint &) override
Function SetPosition set the schematic item position to aPosition.