KiCad PCB EDA Suite
find.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) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2018 KiCad Developers, see change_log.txt for contributors.
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 
31 /*
32  * Search a text (text, value, reference) within a component or
33  * search a component in libraries, a marker ...,
34  * in current sheet or whole the project
35  */
36 #include <fctsys.h>
37 #include <pgm_base.h>
38 #include <sch_draw_panel.h>
39 #include <confirm.h>
40 #include <kicad_string.h>
41 #include <gestfich.h>
42 #include <sch_edit_frame.h>
43 #include <base_units.h>
44 #include <trace_helpers.h>
45 #include <sch_view.h>
46 #include <general.h>
47 #include <class_library.h>
48 #include <lib_pin.h>
49 #include <sch_marker.h>
50 #include <sch_component.h>
51 #include <sch_sheet.h>
52 #include <sch_sheet_path.h>
53 #include <symbol_lib_table.h>
54 
55 #include <kicad_device_context.h>
56 
58 
59 
60 void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
61 {
62  static SCH_MARKER* lastMarker = NULL;
63 
64  wxString msg;
65  SCH_SHEET_LIST schematic( g_RootSheet );
66  SCH_SHEET_PATH* sheetFoundIn = NULL;
67  bool wrap = ( event.GetFlags() & FR_SEARCH_WRAP ) != 0;
68  bool warpCursor = ( ( event.GetId() == wxEVT_COMMAND_FIND_CLOSE ) ||
69  !( event.GetFlags() & FR_NO_WARP_CURSOR ) );
70 
71  if( event.GetFlags() & FR_CURRENT_SHEET_ONLY )
72  {
73  sheetFoundIn = m_CurrentSheet;
74  lastMarker = (SCH_MARKER*) m_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
75  }
76  else
77  {
78  lastMarker = (SCH_MARKER*) schematic.FindNextItem( SCH_MARKER_T, &sheetFoundIn,
79  lastMarker, wrap );
80  }
81 
82  if( lastMarker != NULL )
83  {
84  if( *sheetFoundIn != *m_CurrentSheet )
85  {
86  sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
87  *m_CurrentSheet = *sheetFoundIn;
89  }
90 
91  SetCrossHairPosition( lastMarker->GetPosition() );
92 
93 
94  CenterScreen( lastMarker->GetPosition(), warpCursor );
95 
96  msg.Printf( _( "Design rule check marker found in sheet %s at %s, %s" ),
97  sheetFoundIn->Path(),
99  MessageTextFromValue( m_UserUnits, lastMarker->GetPosition().y ) );
100  SetStatusText( msg );
101  }
102  else
103  {
104  SetStatusText( _( "No more markers were found." ) );
105  }
106 }
107 
108 
109 SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
110  bool aSearchHierarchy,
111  SCH_SEARCH_T aSearchType,
112  const wxString& aSearchText )
113 {
114  SCH_SHEET_PATH* sheet = NULL;
115  SCH_SHEET_PATH* sheetWithComponentFound = NULL;
116  SCH_ITEM* item = NULL;
117  SCH_COMPONENT* Component = NULL;
118  wxPoint pos;
119  bool notFound = true;
120  LIB_PIN* pin;
121  SCH_SHEET_LIST sheetList( g_RootSheet );
122 
123  if( !aSearchHierarchy )
124  sheetList.push_back( *m_CurrentSheet );
125  else
126  sheetList.BuildSheetList( g_RootSheet );
127 
128  for( SCH_SHEET_PATHS_ITER it = sheetList.begin(); it != sheetList.end(); ++it )
129  {
130  sheet = &(*it);
131  item = (*it).LastDrawList();
132 
133  for( ; ( item != NULL ) && ( notFound == true ); item = item->Next() )
134  {
135  if( item->Type() != SCH_COMPONENT_T )
136  continue;
137 
138  SCH_COMPONENT* pSch = (SCH_COMPONENT*) item;
139 
140  if( aReference.CmpNoCase( pSch->GetRef( sheet ) ) == 0 )
141  {
142  Component = pSch;
143  sheetWithComponentFound = sheet;
144 
145  switch( aSearchType )
146  {
147  default:
148  case FIND_COMPONENT_ONLY: // Find component only
149  notFound = false;
150  pos = pSch->GetPosition();
151  break;
152 
153  case FIND_PIN: // find a pin
154  pos = pSch->GetPosition(); // temporary: will be changed if the pin is found.
155  pin = pSch->GetPin( aSearchText );
156 
157  if( pin == NULL )
158  break;
159 
160  notFound = false;
161  pos += pin->GetPosition();
162  break;
163 
164  case FIND_REFERENCE: // find reference
165  notFound = false;
166  pos = pSch->GetField( REFERENCE )->GetPosition();
167  break;
168 
169  case FIND_VALUE: // find value
170  pos = pSch->GetPosition();
171 
172  if( aSearchText.CmpNoCase( pSch->GetField( VALUE )->GetShownText() ) != 0 )
173  break;
174 
175  notFound = false;
176  pos = pSch->GetField( VALUE )->GetPosition();
177  break;
178  }
179  }
180  }
181 
182  if( notFound == false )
183  break;
184  }
185 
186  if( Component )
187  {
188  sheet = sheetWithComponentFound;
189 
190  if( *sheet != *m_CurrentSheet )
191  {
192  sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
193  *m_CurrentSheet = *sheet;
195  }
196 
197  wxPoint delta;
198  pos -= Component->GetPosition();
199  delta = Component->GetTransform().TransformCoordinate( pos );
200  pos = delta + Component->GetPosition();
201 
202  SetCrossHairPosition( pos );
203  CenterScreen( pos, false );
204  }
205 
206  /* Print diag */
207  wxString msg_item;
208  wxString msg;
209 
210  switch( aSearchType )
211  {
212  default:
213  case FIND_COMPONENT_ONLY: msg_item = _( "component" ); break;
214  case FIND_PIN: msg_item.Printf( _( "pin %s" ), aSearchText ); break;
215  case FIND_REFERENCE: msg_item.Printf( _( "reference %s" ), aSearchText ); break;
216  case FIND_VALUE: msg_item.Printf( _( "value %s" ), aSearchText ); break;
217  case FIND_FIELD: msg_item.Printf( _( "field %s" ), aSearchText ); break;
218  }
219 
220  if( Component )
221  {
222  if( !notFound )
223  msg.Printf( _( "%s %s found" ), aReference, msg_item );
224  else
225  msg.Printf( _( "%s found but %s not found" ), aReference, msg_item );
226  }
227  else
228  msg.Printf( _( "Component %s not found" ), aReference );
229 
230  SetStatusText( msg );
231 
232  return item;
233 }
234 
235 
237 {
238  int mod_hash = Prj().SchSymbolLibTable()->GetModifyHash();
239 
240  // the cache is obsolete whenever any library changes.
241  if( mod_hash != m_foundItems.GetLibHash() )
242  {
244  m_foundItems.SetLibHash( mod_hash );
245  return true;
246  }
247  else if( m_foundItems.IsSearchRequired( aSearchCriteria ) )
248  return true;
249  else
250  return false;
251 }
252 
253 
254 void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
255 {
256  SCH_FIND_REPLACE_DATA searchCriteria;
258 
259  searchCriteria.SetFlags( aEvent.GetFlags() );
260  searchCriteria.SetFindString( aEvent.GetFindString() );
261  searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
262 
263  if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
264  {
265  if( m_foundItems.GetCount() == 0 )
266  return;
267  }
268  else if( IsSearchCacheObsolete( searchCriteria ) )
269  {
270  if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
271  {
272  m_foundItems.Collect( searchCriteria, m_CurrentSheet );
273  }
274  else
275  {
276  m_foundItems.Collect( searchCriteria );
277  }
278  }
279  else
280  {
281  EDA_ITEM* currentItem = m_foundItems.GetItem( data );
282 
283  if( currentItem != NULL )
284  currentItem->SetForceVisible( false );
285 
287  }
288 
289  updateFindReplaceView( aEvent );
290 }
291 
292 
293 void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
294 {
295  SCH_ITEM* item;
296  SCH_SHEET_PATH* sheet;
297  SCH_SHEET_LIST schematic( g_RootSheet );
299  SCH_FIND_REPLACE_DATA searchCriteria;
300 
301  searchCriteria.SetFlags( aEvent.GetFlags() );
302  searchCriteria.SetFindString( aEvent.GetFindString() );
303  searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
304  m_foundItems.SetReplaceString( aEvent.GetReplaceString() );
305 
306  if( IsSearchCacheObsolete( searchCriteria ) )
307  {
308  if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
309  {
310  m_foundItems.Collect( searchCriteria, m_CurrentSheet );
311  }
312  else
313  {
314  m_foundItems.Collect( searchCriteria );
315  }
316  }
317 
318  if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL )
319  {
320  while( ( item = (SCH_ITEM*) m_foundItems.GetItem( data ) ) != NULL )
321  {
322  SCH_ITEM* undoItem = data.GetParent();
323 
324  // Don't save child items in undo list.
325  if( undoItem == NULL )
326  undoItem = item;
327 
328  SetUndoItem( undoItem );
329 
330  sheet = schematic.GetSheetByPath( data.GetSheetPath() );
331 
332  wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + data.GetSheetPath() );
333 
334  if( m_foundItems.ReplaceItem( sheet ) )
335  {
336  GetCanvas()->GetView()->Update( undoItem, KIGFX::ALL );
337  OnModify();
338  SaveUndoItemInUndoList( undoItem );
339  updateFindReplaceView( aEvent );
340  }
341 
343 
344  if( m_foundItems.PassedEnd() )
345  break;
346  }
347  }
348  else
349  {
350  item = (SCH_ITEM*) m_foundItems.GetItem( data );
351 
352  wxCHECK_RET( item != NULL, wxT( "Invalid replace item in find collector list." ) );
353 
354  SCH_ITEM* undoItem = data.GetParent();
355 
356  if( undoItem == NULL )
357  undoItem = item;
358 
359  SetUndoItem( undoItem );
360 
361  sheet = schematic.GetSheetByPath( data.GetSheetPath() );
362 
363  wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + data.GetSheetPath() );
364 
365  if( m_foundItems.ReplaceItem( sheet ) )
366  {
367  GetCanvas()->GetView()->Update( undoItem, KIGFX::ALL );
368  OnModify();
369  SaveUndoItemInUndoList( undoItem );
370  updateFindReplaceView( aEvent );
371 
372  // A single replace is part of the search; it does not dirty it.
373  m_foundItems.SetForceSearch( false );
374  }
375 
377  }
378 
379  // End the replace if we are at the end if the list. This prevents an infinite loop if
380  // wrap search is selected and all of the items have been replaced with a value that
381  // still satisfies the search criteria.
382  if( m_foundItems.PassedEnd() )
383  aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
384 }
385 
386 
387 void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent )
388 {
389  wxString msg;
390  SCH_SHEET_LIST schematic( g_RootSheet );
392  bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
393 
394  if( m_foundItems.GetItem( data ) != NULL )
395  {
396  wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText( MILLIMETRES ) );
397 
398  SCH_SHEET_PATH* sheet = schematic.GetSheetByPath( data.GetSheetPath() );
399 
400  wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) +
401  data.GetSheetPath() );
402 
403  SCH_ITEM* item = (SCH_ITEM*)m_foundItems.GetItem( data );
404 
405  // Make the item temporarily visible just in case it's hide flag is set. This
406  // has no effect on objects that don't support hiding. If this is a close find
407  // dialog event, clear the temporary visibility flag.
408  if( item )
409  {
410  if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
411  item->SetForceVisible( false );
412  else if( item->Type() == SCH_FIELD_T && !( (SCH_FIELD*) item )->IsVisible() )
413  item->SetForceVisible( true );
414  }
415 
416  if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
417  {
418  sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
419  *m_CurrentSheet = *sheet;
421  SetScreen( sheet->LastScreen() );
422  sheet->LastScreen()->TestDanglingEnds();
423  }
424 
426  CenterScreen( data.GetPosition(), warpCursor );
427 
429 
430  if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
431  aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND );
432  }
433  else
434  {
435  if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
436  aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
437 
438  msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
439  }
440 
441  *m_findReplaceStatus = msg;
442  SetStatusText( msg );
443 }
Definition of the SCH_SHEET class for Eeschema.
void OnFindDrcMarker(wxFindDialogEvent &event)
Definition: find.cpp:60
Class SCH_SHEET_LIST.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:114
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
Class SCH_FIELD instances are attached to a component and provide a place for the component&#39;s value...
Definition: sch_field.h:56
SCH_ITEM * GetItem(int ndx) const
wxString * m_findReplaceStatus
const wxChar *const traceFindReplace
Flag to enable find and replace debug tracing.
TRANSFORM & GetTransform() const
bool IsSearchRequired(const SCH_FIND_REPLACE_DATA &aFindReplaceData)
Function IsSearchRequired checks the current collector state against aFindReplaceData to see if a new...
SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER
This file is part of the common library TODO brief description.
SCH_ITEM * FindNextItem(KICAD_T aType, SCH_SHEET_PATH **aSheetFound=NULL, SCH_ITEM *aLastItem=NULL, bool aWrap=true)
Function FindNextItem searches the entire schematic for the next schematic object.
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen* and ...
virtual void SetScreen(BASE_SCREEN *aScreen) override
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_marker.h:106
int CountSheets()
Count the number of sheets found in "this" sheet includeing all of the subsheets. ...
Definition: sch_sheet.cpp:640
wxString GetSheetPath() const
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_field.cpp:558
SCH_FIND_COLLECTOR m_foundItems
List of find/replace items.
Find a component in the schematic.
Find an item by it&#39;s value field.
Used by the search event handler to let the dialog know that a replaceable item has been found...
LIB_PIN * GetPin(const wxString &number)
Find a symbol pin by number.
SCH_SCREEN * LastScreen() const
Function LastScreen.
Wrap around the beginning or end of search list.
void DisplayCurrentSheet()
Draw the current sheet on the display.
Definition: hierarch.cpp:265
SCH_SHEET_PATH * GetSheetByPath(const wxString &aPath, bool aHumanReadable=true)
Function GetSheetByPath returns a sheet matching the path name in aPath.
Item needs to be redrawn.
Definition: view_item.h:61
void UpdateAllScreenReferences()
Function UpdateAllScreenReferences updates the reference and the m_Multi parameter (part selection) f...
Class SCH_FIND_COLLECTOR_DATA is used as a data container for the associated item found by the SCH_FI...
int GetLibHash() const
SCH_ITEM * Next() const
Field Reference of part, i.e. "IC21".
Find a component pin in the schematic.
static const int delta[8][2]
Definition: solve.cpp:112
SCH_ITEM * FindComponentAndItem(const wxString &aReference, bool aSearchHierarchy, SCH_SEARCH_T aSearchType, const wxString &aSearchText)
Finds a component in the schematic and an item in this component.
Definition: find.cpp:109
void SaveUndoItemInUndoList(SCH_ITEM *aItem)
Swap the cloned item in member variable m_undoItem with aItem and saves it to the undo list then swap...
void updateFindReplaceView(wxFindDialogEvent &aEvent)
Definition: find.cpp:387
wxString Path() const
Function Path the path uses the time stamps which do not changes even when editing sheet parameters a...
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:148
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
SCH_SHEET_PATH * m_CurrentSheet
which sheet we are presently working on.
void SetLibHash(int aHash)
void OnFindSchematicItem(wxFindDialogEvent &aEvent)
Find an item in the schematic matching the search criteria in aEvent.
Definition: find.cpp:254
wxPoint GetPosition() const
SCH_ITEM * GetParent() const
a helper to handle the real device context used in KiCad
void SetForceSearch(bool doSearch=true)
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:56
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
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.
Subclass of DIALOG_SCH_FIND_BASE, which is generated by wxFormBuilder.
void SetForceVisible(bool aEnable)
Function SetForceVisible is used to set and cleag force visible flag used to force the item to be dra...
Definition: base_struct.h:285
wxString PathHumanReadable() const
Function PathHumanReadable returns the sheet path in a human readable form, i.e.
SCH_DRAW_PANEL * GetCanvas() const override
wxLogTrace helper definitions.
virtual bool SetZoom(double iu_per_du)
Function SetZoom adjusts the current zoom factor.
Class SCH_SHEET_PATH.
bool IsSearchCacheObsolete(const SCH_FIND_REPLACE_DATA &aSearchCriteria)
Definition: find.cpp:236
Search the current sheet only.
void BuildSheetList(SCH_SHEET *aSheet)
Function BuildSheetList builds the list of sheets and their sheet path from aSheet.
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1521
KIGFX::SCH_VIEW * GetView() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
SCH_ITEM * FindNextItem(KICAD_T aType, SCH_ITEM *aLastItem=NULL, bool aWrap=false) const
Find the next schematic item in this sheet object.
wxPoint GetPosition() const override
Return the current draw object position.
Definition: lib_pin.h:463
Find a component field.
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
see class PGM_BASE
void SetReplaceString(const wxString &aReplaceString)
Update the replace string without changing anything else.
SCH_SEARCH_T
Schematic search type used by the socket link with Pcbnew.
Don&#39;t warp cursor to found item until the dialog is closed.
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...
Class SCH_FIND_REPLACE_DATA adds missing useful comparison and assignment operators to the wxFindRepl...
Find an item by it&#39;s reference designator.
Perform a search for a item that has replaceable text.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
wxPoint GetPosition() const override
Function GetPosition.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
wxString GetText(EDA_UNITS_T aUnits)
Function GetText()
virtual void CenterScreen(const wxPoint &aCenterPoint, bool aWarpPointer)
void SetUndoItem(const SCH_ITEM *aItem)
Clone aItem which can be used to restore the state of the item being edited when the user cancels the...
Definition for part library class.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Set the screen cross hair position to aPosition in logical (drawing) units.
EDA_UNITS_T m_UserUnits
Definition: draw_frame.h:120
#define VALUE
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...
void OnFindReplace(wxFindDialogEvent &aEvent)
Perform a search and replace of text in an item in the schematic matching the search and replace crit...
Definition: find.cpp:293