Commit d9e0ab02 authored by Wayne Stambaugh's avatar Wayne Stambaugh

Improve Eeschema find code and add initial replace plumbing.

* Replace Eeschema find code with a collector based implementation.
* Fixed a search bug when all subsequent searches of an item would ignore
  the remaining valid child items when an item had more than one child
  item that matched the search criteria.
* Add SCH_FIND_COLLECTOR class to find all items that meet the specified
  search criteria.
* Add SCH_FIND_COLLECT0R_DATA to keep track of information for all matching
  items.
* Use collector to iterate over the list of items that match the search
  criteria rather than trying to start at the last matched item.
* Remove unused searching methods from sheet path and sheet path list
  objects.
* Add replace and replace all functionality to Eeschema find dialog.
* Push matching methods down to EDA_ITEM class so they can be used by
  other derived objects.
* Add method to EDA_ITEM to test if item supports replacing.
* Add flag to find/replace data to support replace feature.
* Disable wild card matching check box when dialog is in replace mode as
  wild card replacement is not supported at this time.
* The usual Doxygen comment and coding policy fixes.
parent 6c2fcf7e
...@@ -410,39 +410,32 @@ int ReturnValueFromString( EDA_UNITS_T aUnit, const wxString& TextValue, int Int ...@@ -410,39 +410,32 @@ int ReturnValueFromString( EDA_UNITS_T aUnit, const wxString& TextValue, int Int
} }
/** wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter )
* Function wxStringSplit
* Split a String to a String List when founding 'splitter'
* @return the list
* @param txt : wxString : a String text
* @param splitter : wxChar : the 'split' character
*/
wxArrayString* wxStringSplit( wxString txt, wxChar splitter )
{ {
wxArrayString* list = new wxArrayString(); wxArrayString* list = new wxArrayString();
while( 1 ) while( 1 )
{ {
int index = txt.Find( splitter ); int index = aString.Find( aSplitter );
if( index == wxNOT_FOUND ) if( index == wxNOT_FOUND )
break; break;
wxString tmp; wxString tmp;
tmp = txt.Mid( 0, index ); tmp = aString.Mid( 0, index );
txt = txt.Mid( index + 1, txt.size() - index ); aString = aString.Mid( index + 1, aString.size() - index );
list->Add( tmp ); list->Add( tmp );
} }
if( !txt.IsEmpty() ) if( !aString.IsEmpty() )
{ {
list->Add( txt ); list->Add( aString );
} }
return list; return list;
} }
/** /**
* Function To_User_Unit * Function To_User_Unit
* Convert in inch or mm the variable "val" (double)given in internal units * Convert in inch or mm the variable "val" (double)given in internal units
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
#include "../eeschema/dialogs/dialog_schematic_find.h"
const wxString traceFindReplace( wxT( "KicadFindReplace" ) );
bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 ) bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 )
......
...@@ -1059,7 +1059,7 @@ ...@@ -1059,7 +1059,7 @@
<property name="fg"></property> <property name="fg"></property>
<property name="font"></property> <property name="font"></property>
<property name="hidden">1</property> <property name="hidden">1</property>
<property name="id">wxID_ANY</property> <property name="id">wxID_REPLACE</property>
<property name="label">&amp;Replace</property> <property name="label">&amp;Replace</property>
<property name="maximum_size"></property> <property name="maximum_size"></property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
...@@ -1077,7 +1077,7 @@ ...@@ -1077,7 +1077,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<event name="OnButtonClick"></event> <event name="OnButtonClick">OnReplace</event>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>
...@@ -1100,7 +1100,7 @@ ...@@ -1100,7 +1100,7 @@
<event name="OnRightUp"></event> <event name="OnRightUp"></event>
<event name="OnSetFocus"></event> <event name="OnSetFocus"></event>
<event name="OnSize"></event> <event name="OnSize"></event>
<event name="OnUpdateUI"></event> <event name="OnUpdateUI">OnUpdateReplaceUI</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
...@@ -1116,7 +1116,7 @@ ...@@ -1116,7 +1116,7 @@
<property name="fg"></property> <property name="fg"></property>
<property name="font"></property> <property name="font"></property>
<property name="hidden">1</property> <property name="hidden">1</property>
<property name="id">wxID_ANY</property> <property name="id">wxID_REPLACE_ALL</property>
<property name="label">Replace &amp;All</property> <property name="label">Replace &amp;All</property>
<property name="maximum_size"></property> <property name="maximum_size"></property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
...@@ -1134,7 +1134,7 @@ ...@@ -1134,7 +1134,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<event name="OnButtonClick"></event> <event name="OnButtonClick">OnReplace</event>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>
...@@ -1157,7 +1157,7 @@ ...@@ -1157,7 +1157,7 @@
<event name="OnRightUp"></event> <event name="OnRightUp"></event>
<event name="OnSetFocus"></event> <event name="OnSetFocus"></event>
<event name="OnSize"></event> <event name="OnSize"></event>
<event name="OnUpdateUI"></event> <event name="OnUpdateUI">OnUpdateReplaceUI</event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
......
...@@ -16,8 +16,10 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData, ...@@ -16,8 +16,10 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData,
if( aStyle & wxFR_REPLACEDIALOG ) if( aStyle & wxFR_REPLACEDIALOG )
{ {
SetTitle( _( "Find and Replace" ) );
m_staticReplace->Show( true ); m_staticReplace->Show( true );
m_comboReplace->Show( true ); m_comboReplace->Show( true );
m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented.
} }
int flags = m_findReplaceData->GetFlags(); int flags = m_findReplaceData->GetFlags();
...@@ -55,6 +57,13 @@ void DIALOG_SCH_FIND::OnUpdateFindUI( wxUpdateUIEvent& aEvent ) ...@@ -55,6 +57,13 @@ void DIALOG_SCH_FIND::OnUpdateFindUI( wxUpdateUIEvent& aEvent )
} }
void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() &&
(m_findReplaceData->GetFlags() | FR_REPLACE_ITEM_FOUND) );
}
void DIALOG_SCH_FIND::OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent ) void DIALOG_SCH_FIND::OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent )
{ {
aEvent.Enable( !m_checkWildcardMatch->GetValue() ); aEvent.Enable( !m_checkWildcardMatch->GetValue() );
...@@ -88,6 +97,27 @@ void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent ) ...@@ -88,6 +97,27 @@ void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
} }
void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
{
int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true );
if( index == wxNOT_FOUND )
{
m_comboReplace->Insert( m_comboReplace->GetValue(), 0 );
}
else if( index != 0 )
{
/* Move the search string to the top of the list if it isn't already there. */
wxString tmp = m_comboReplace->GetValue();
m_comboReplace->Delete( index );
m_comboReplace->Insert( tmp, 0 );
m_comboReplace->SetSelection( 0 );
}
SendEvent( wxEVT_COMMAND_FIND );
}
void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent ) void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent )
{ {
SendEvent( wxEVT_COMMAND_FIND_CLOSE ); SendEvent( wxEVT_COMMAND_FIND_CLOSE );
...@@ -101,13 +131,14 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) ...@@ -101,13 +131,14 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
event.SetEventObject( this ); event.SetEventObject( this );
event.SetFindString( m_comboFind->GetValue() ); event.SetFindString( m_comboFind->GetValue() );
int flags = 0;
if ( HasFlag( wxFR_REPLACEDIALOG ) ) if ( HasFlag( wxFR_REPLACEDIALOG ) )
{ {
event.SetReplaceString( m_comboReplace->GetValue() ); event.SetReplaceString( m_comboReplace->GetValue() );
flags |= FR_SEARCH_REPLACE;
} }
int flags = 0;
if( m_radioForward->GetValue() ) if( m_radioForward->GetValue() )
flags |= wxFR_DOWN; flags |= wxFR_DOWN;
...@@ -117,7 +148,7 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) ...@@ -117,7 +148,7 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
if( m_checkWholeWord->GetValue() ) if( m_checkWholeWord->GetValue() )
flags |= wxFR_WHOLEWORD; flags |= wxFR_WHOLEWORD;
if( m_checkWildcardMatch->GetValue() ) if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() )
flags |= FR_MATCH_WILDCARD; flags |= FR_MATCH_WILDCARD;
if( m_checkAllFields->GetValue() ) if( m_checkAllFields->GetValue() )
...@@ -152,6 +183,9 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) ...@@ -152,6 +183,9 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
{ {
GetParent()->GetEventHandler()->ProcessEvent( event ); GetParent()->GetEventHandler()->ProcessEvent( event );
} }
if( event.GetFlags() != flags )
m_findReplaceData->SetFlags( event.GetFlags() );
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
/** /**
* Define schematic specific find and replace dialog flags based on the enum entries * Define schematic specific find and replace dialog flags based on the enum entries
* in wxFindReplaceFlags. These flags are intended to be used as bit masks in the * in wxFindReplaceFlags. These flags are intended to be used as bit masks in the
* wxFindReplaceData::m_Flags member variable. The varialble is defined as a wxUint32. * wxFindReplaceData::m_Flags member variable. The variable is defined as a wxUint32.
*/ */
enum SchematicFindReplaceFlags enum SchematicFindReplaceFlags
{ {
...@@ -44,7 +44,7 @@ enum SchematicFindReplaceFlags ...@@ -44,7 +44,7 @@ enum SchematicFindReplaceFlags
/// Don't warp cursor to found item until the dialog is closed. /// Don't warp cursor to found item until the dialog is closed.
FR_NO_WARP_CURSOR = wxFR_MATCHCASE << 6, FR_NO_WARP_CURSOR = wxFR_MATCHCASE << 6,
/// Perform a search for a item that has repaceable text. /// Perform a search for a item that has replaceable text.
FR_SEARCH_REPLACE = wxFR_MATCHCASE << 7, FR_SEARCH_REPLACE = wxFR_MATCHCASE << 7,
/// Used by the search event handler to let the dialog know that a replaceable /// Used by the search event handler to let the dialog know that a replaceable
...@@ -53,6 +53,40 @@ enum SchematicFindReplaceFlags ...@@ -53,6 +53,40 @@ enum SchematicFindReplaceFlags
}; };
/**
* Class SCH_FIND_REPLACE_DATA
* adds missing useful comparison and assignment operators to the wxFindReplaceData object.
*/
class SCH_FIND_REPLACE_DATA : public wxFindReplaceData
{
public:
SCH_FIND_REPLACE_DATA& operator =( SCH_FIND_REPLACE_DATA& aFindReplaceData )
{
if( this == &aFindReplaceData )
return *this;
SetFlags( aFindReplaceData.GetFlags() );
SetFindString( aFindReplaceData.GetFindString() );
SetReplaceString( aFindReplaceData.GetReplaceString() );
return *this;
}
bool operator ==( SCH_FIND_REPLACE_DATA& aFindReplaceData )
{
return ( (GetFlags() == aFindReplaceData.GetFlags())
&& (GetFindString() == aFindReplaceData.GetFindString())
&& (GetReplaceString() == aFindReplaceData.GetReplaceString()) );
}
bool operator !=( SCH_FIND_REPLACE_DATA& aFindReplaceData )
{
return !( *this == aFindReplaceData );
}
};
/** Implementing DIALOG_SCH_FIND_BASE */ /** Implementing DIALOG_SCH_FIND_BASE */
class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE
{ {
...@@ -60,9 +94,12 @@ protected: ...@@ -60,9 +94,12 @@ protected:
// Handlers for DIALOG_SCH_FIND_BASE events. // Handlers for DIALOG_SCH_FIND_BASE events.
void OnClose( wxCloseEvent& aEvent ); void OnClose( wxCloseEvent& aEvent );
void OnUpdateFindUI( wxUpdateUIEvent& aEvent ); void OnUpdateFindUI( wxUpdateUIEvent& aEvent );
void OnUpdateReplaceUI( wxUpdateUIEvent& aEvent );
void OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent ); void OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent );
void OnUpdateWildcardUI( wxUpdateUIEvent& aEvent ); void OnUpdateWildcardUI( wxUpdateUIEvent& aEvent );
void OnFind( wxCommandEvent& aEvent ); void OnFind( wxCommandEvent& aEvent );
void OnReplace( wxCommandEvent& aEvent );
void OnCancel( wxCommandEvent& aEvent ); void OnCancel( wxCommandEvent& aEvent );
void SendEvent( const wxEventType& aEventType ); void SendEvent( const wxEventType& aEventType );
......
...@@ -101,12 +101,12 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con ...@@ -101,12 +101,12 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
m_buttonFind->SetDefault(); m_buttonFind->SetDefault();
rightSizer->Add( m_buttonFind, 0, wxALL|wxEXPAND, 6 ); rightSizer->Add( m_buttonFind, 0, wxALL|wxEXPAND, 6 );
m_buttonReplace = new wxButton( this, wxID_ANY, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplace->Hide(); m_buttonReplace->Hide();
rightSizer->Add( m_buttonReplace, 0, wxALL, 5 ); rightSizer->Add( m_buttonReplace, 0, wxALL, 5 );
m_buttonReplaceAll = new wxButton( this, wxID_ANY, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplaceAll->Hide(); m_buttonReplaceAll->Hide();
rightSizer->Add( m_buttonReplaceAll, 0, wxALL, 5 ); rightSizer->Add( m_buttonReplaceAll, 0, wxALL, 5 );
...@@ -130,6 +130,10 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con ...@@ -130,6 +130,10 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
m_checkWildcardMatch->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this ); m_checkWildcardMatch->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this );
m_buttonFind->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonFind->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this );
m_buttonFind->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this ); m_buttonFind->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this );
m_buttonReplace->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
m_buttonReplace->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
m_buttonReplaceAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
m_buttonReplaceAll->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this ); m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this );
} }
...@@ -143,6 +147,10 @@ DIALOG_SCH_FIND_BASE::~DIALOG_SCH_FIND_BASE() ...@@ -143,6 +147,10 @@ DIALOG_SCH_FIND_BASE::~DIALOG_SCH_FIND_BASE()
m_checkWildcardMatch->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this ); m_checkWildcardMatch->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this );
m_buttonFind->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonFind->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this );
m_buttonFind->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this ); m_buttonFind->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), NULL, this );
m_buttonReplace->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
m_buttonReplace->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
m_buttonReplaceAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this );
m_buttonReplaceAll->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this );
} }
...@@ -61,6 +61,8 @@ class DIALOG_SCH_FIND_BASE : public wxDialog ...@@ -61,6 +61,8 @@ class DIALOG_SCH_FIND_BASE : public wxDialog
virtual void OnUpdateWildcardUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnUpdateWildcardUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnFind( wxCommandEvent& event ) { event.Skip(); } virtual void OnFind( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateFindUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnUpdateFindUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnReplace( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateReplaceUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
......
...@@ -297,60 +297,88 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference, ...@@ -297,60 +297,88 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
{ {
static SCH_ITEM* lastItem = NULL; /* last item found when searching a match static wxPoint itemPosition; // the actual position of the matched item.
* note: the actual matched item can be a
* part of lastItem (for instance a field in a component SCH_SHEET_LIST schematic;
*/ wxString msg;
static wxString sheetFoundIn; SCH_FIND_REPLACE_DATA searchCriteria;
static wxPoint lastItemPosition; // the actual position of the matched sub item bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
SCH_SHEET_LIST schematic;
wxString msg;
wxFindReplaceData searchCriteria;
bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
searchCriteria.SetFlags( aEvent.GetFlags() ); searchCriteria.SetFlags( aEvent.GetFlags() );
searchCriteria.SetFindString( aEvent.GetFindString() ); searchCriteria.SetFindString( aEvent.GetFindString() );
searchCriteria.SetReplaceString( aEvent.GetReplaceString() ); searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE ) if( searchCriteria != m_foundItems.GetFindReplaceData() )
{
sheetFoundIn = m_CurrentSheet->PathHumanReadable();
warpCursor = true;
}
else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{ {
sheetFoundIn = m_CurrentSheet->PathHumanReadable(); if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
lastItem = m_CurrentSheet->MatchNextItem( searchCriteria, lastItem, &lastItemPosition ); {
warpCursor = true;
}
else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{
m_foundItemIndex = 0;
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
}
else
{
m_foundItemIndex = 0;
m_foundItems.Collect( searchCriteria );
}
} }
else else
{ {
lastItem = schematic.MatchNextItem( searchCriteria, sheetFoundIn, lastItem, if( searchCriteria.GetFlags() & wxFR_DOWN )
&lastItemPosition ); {
if( !(searchCriteria.GetFlags() & FR_SEARCH_WRAP)
&& (m_foundItemIndex == (m_foundItems.GetCount() - 1)) )
return;
m_foundItemIndex += 1;
if( (m_foundItemIndex >= m_foundItems.GetCount())
&& (searchCriteria.GetFlags() & FR_SEARCH_WRAP) )
m_foundItemIndex = 0;
}
else
{
if( !(searchCriteria.GetFlags() & FR_SEARCH_WRAP) && (m_foundItemIndex == 0) )
return;
m_foundItemIndex -= 1;
if( (m_foundItemIndex < 0) && (searchCriteria.GetFlags() & FR_SEARCH_WRAP) )
m_foundItemIndex = m_foundItems.GetCount() - 1;
}
} }
if( lastItem != NULL ) if( m_foundItems.GetCount() != 0 )
{ {
SCH_SHEET_PATH* sheet = schematic.GetSheet( sheetFoundIn ); SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex );
wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText( m_foundItemIndex ) );
SCH_SHEET_PATH* sheet = schematic.GetSheet( data.GetSheetPath() );
wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " + sheetFoundIn ) ); wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) +
data.GetSheetPath() );
if( sheet != GetSheet() ) if( sheet->PathHumanReadable() != GetSheet()->PathHumanReadable() )
{ {
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() ); sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
*m_CurrentSheet = *sheet; *m_CurrentSheet = *sheet;
m_CurrentSheet->UpdateAllScreenReferences(); m_CurrentSheet->UpdateAllScreenReferences();
} }
sheet->LastScreen()->SetCrossHairPosition( lastItemPosition ); sheet->LastScreen()->SetCrossHairPosition( data.GetPosition() );
RedrawScreen( lastItemPosition, warpCursor ); RedrawScreen( data.GetPosition(), warpCursor );
msg = lastItem->GetSelectMenuText() + _( " found in sheet " ) + sheetFoundIn; aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND );
msg = m_foundItems.GetText( m_foundItemIndex );
} }
else else
{ {
sheetFoundIn = wxEmptyString; aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) ); msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
} }
...@@ -360,4 +388,23 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) ...@@ -360,4 +388,23 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent ) void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
{ {
wxCHECK_RET( m_foundItems.IsValidIndex( m_foundItemIndex ),
wxT( "No last find item to replace text." ) );
SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex );
wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ),
GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ),
GetChars( m_foundItems.GetText( m_foundItemIndex ) ) );
OnFindSchematicItem( aEvent );
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL )
{
wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ),
GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ),
GetChars( m_foundItems.GetText( m_foundItemIndex ) ) );
OnFindSchematicItem( aEvent );
}
} }
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// Schematic editor: // Schematic editor:
#define HELP_FIND _( "Find components and texts" ) #define HELP_FIND _( "Find components and texts" )
#define HELP_REPLACE _( "Find and replace text in schematic items" )
#define HELP_PLACE_COMPONENTS _( "Place a component" ) #define HELP_PLACE_COMPONENTS _( "Place a component" )
#define HELP_PLACE_POWERPORT _( "Place a power port" ) #define HELP_PLACE_POWERPORT _( "Place a power port" )
#define HELP_PLACE_WIRE _( "Place a wire" ) #define HELP_PLACE_WIRE _( "Place a wire" )
......
...@@ -2142,6 +2142,29 @@ wxString LIB_PIN::GetSelectMenuText() const ...@@ -2142,6 +2142,29 @@ wxString LIB_PIN::GetSelectMenuText() const
} }
bool LIB_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS )
&& !( aSearchData.GetFlags() & FR_SEARCH_REPLACE ) )
return false;
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() );
if( EDA_ITEM::Matches( GetName(), aSearchData )
|| EDA_ITEM::Matches( GetNumberString(), aSearchData ) )
{
if( aFindLocation )
*aFindLocation = GetBoundingBox().Centre();
return true;
}
return false;
}
#if defined(DEBUG) #if defined(DEBUG)
void LIB_PIN::Show( int nestLevel, std::ostream& os ) void LIB_PIN::Show( int nestLevel, std::ostream& os )
......
...@@ -134,7 +134,7 @@ public: ...@@ -134,7 +134,7 @@ public:
char m_PinNamePositionOpt; char m_PinNamePositionOpt;
public: public:
LIB_PIN( LIB_COMPONENT * aParent ); LIB_PIN( LIB_COMPONENT* aParent );
LIB_PIN( const LIB_PIN& aPin ); LIB_PIN( const LIB_PIN& aPin );
~LIB_PIN() { } ~LIB_PIN() { }
...@@ -185,6 +185,11 @@ public: ...@@ -185,6 +185,11 @@ public:
*/ */
virtual void DisplayInfo( EDA_DRAW_FRAME* aFrame ); virtual void DisplayInfo( EDA_DRAW_FRAME* aFrame );
/**
* @copydoc EDA_ITEM::Matches()
*/
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
/** /**
* Function GetBoundingBox * Function GetBoundingBox
* @return the boundary box for the pin in schematic coordinates. * @return the boundary box for the pin in schematic coordinates.
......
...@@ -217,6 +217,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() ...@@ -217,6 +217,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
text = AddHotkeyName( _( "&Find" ), s_Schematic_Hokeys_Descr, HK_FIND_ITEM ); text = AddHotkeyName( _( "&Find" ), s_Schematic_Hokeys_Descr, HK_FIND_ITEM );
AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) ); AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) );
// Find/Replace
// AddMenuItem( editMenu, wxID_REPLACE, _( "Find and Re&place\tCtrl+Shift+F" ), HELP_REPLACE,
// KiBitmap( find_replace_xpm ) );
// Backannotate // Backannotate
editMenu->AppendSeparator(); editMenu->AppendSeparator();
AddMenuItem( editMenu, AddMenuItem( editMenu,
......
/**
* @file sch_collectors.cpp
*/
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
...@@ -26,6 +22,10 @@ ...@@ -26,6 +22,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file sch_collectors.cpp
*/
#include "general.h" #include "general.h"
#include "transform.h" #include "transform.h"
#include "sch_collectors.h" #include "sch_collectors.h"
...@@ -314,3 +314,109 @@ bool SCH_COLLECTOR::IsDraggableJunction() const ...@@ -314,3 +314,109 @@ bool SCH_COLLECTOR::IsDraggableJunction() const
return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1)) return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1))
|| ((wireMidPoint >= 2) && (junctionCount == 1)); || ((wireMidPoint >= 2) && (junctionCount == 1));
} }
SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex )
{
wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(),
wxT( "Attempt to get find data outside of list boundary." ) );
return m_data[ aIndex ];
}
wxString SCH_FIND_COLLECTOR::GetText( int aIndex )
{
wxCHECK_MSG( IsValidIndex( aIndex ), wxEmptyString,
wxT( "Cannot get found item at invalid index." ) );
SCH_FIND_COLLECTOR_DATA data = m_data[ aIndex ];
EDA_ITEM* foundItem = m_List[ aIndex ];
wxCHECK_MSG( foundItem != NULL, wxEmptyString, wxT( "Inavalid found item pointer." ) );
wxString msg;
if( data.GetParent() )
{
msg = _( "Child item " ) + foundItem->GetSelectMenuText() +
_( " of parent item " ) + data.GetParent()->GetSelectMenuText() +
_( " found in sheet " ) + data.GetSheetPath();
}
else
{
msg = _( "Item " ) + foundItem->GetSelectMenuText() + _( " found in sheet " ) +
data.GetSheetPath();
}
return msg;
}
SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
{
wxPoint position;
if( aItem->Matches( m_findReplaceData, m_sheetPath, &position ) )
{
if( aItem->Type() == LIB_PIN_T )
{
wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
// Pin hit testing is relative to the components position and orientation in the
// schematic. The hit test position must be converted to library coordinates.
SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
TRANSFORM transform = component->GetTransform();
position.y = -position.y;
position = transform.TransformCoordinate( position ) + component->GetPosition();
}
Append( aItem );
m_data.push_back( SCH_FIND_COLLECTOR_DATA( position, m_sheetPath->PathHumanReadable(),
(SCH_ITEM*) aTestData ) );
}
return SEARCH_CONTINUE;
}
void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData,
SCH_SHEET_PATH* aSheetPath )
{
if( m_findReplaceData == aFindReplaceData )
return;
m_findReplaceData = aFindReplaceData;
Empty(); // empty the collection just in case
m_data.clear();
if( aSheetPath )
{
m_sheetPath = aSheetPath;
EDA_ITEM::IterateForward( aSheetPath->LastDrawList(), this, NULL, m_ScanTypes );
}
else
{
SCH_SHEET_LIST schematic;
m_sheetPath = schematic.GetFirst();
while( m_sheetPath != NULL )
{
EDA_ITEM::IterateForward( m_sheetPath->LastDrawList(), this, NULL, m_ScanTypes );
m_sheetPath = schematic.GetNext();
}
}
if( m_List.size() != m_data.size() )
{
wxFAIL_MSG( wxT( "List size mismatch." ) );
m_List.clear();
m_data.clear();
}
for( unsigned i = 0; i < m_List.size(); i++ )
{
wxLogTrace( traceFindReplace, GetText( i ) );
}
}
/**
* @file sch_collectors.h
*/
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
...@@ -26,12 +22,17 @@ ...@@ -26,12 +22,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file sch_collectors.h
*/
#ifndef _SCH_COLLECTORS_H_ #ifndef _SCH_COLLECTORS_H_
#define _SCH_COLLECTORS_H_ #define _SCH_COLLECTORS_H_
#include "class_collector.h" #include "class_collector.h"
#include "sch_item_struct.h" #include "sch_item_struct.h"
#include "dialogs/dialog_schematic_find.h"
/** /**
...@@ -120,14 +121,7 @@ public: ...@@ -120,14 +121,7 @@ public:
} }
/** /**
* Function Inspect * @copydoc INSPECTOR::Inspect()
* is the examining function within the INSPECTOR which is passed to the
* Iterate function.
*
* @param aItem An EDA_ITEM to examine.
* @param aTestData is not used in this class.
* @return SEARCH_RESULT #SEARCH_QUIT if the iterator is to stop the scan,
* else #SEARCH_CONTINUE;
*/ */
SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL ); SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
...@@ -162,7 +156,7 @@ public: ...@@ -162,7 +156,7 @@ public:
* Function IsDraggableJunction * Function IsDraggableJunction
* tests to see if the collected items form a draggable junction. * tests to see if the collected items form a draggable junction.
* <p> * <p>
* Daggable juntions are defined as: * Daggable junctions are defined as:
* <ul> * <ul>
* <li> The intersection of three or more wire end points. </li> * <li> The intersection of three or more wire end points. </li>
* <li> The intersection of one or more wire end point and one wire mid point. </li> * <li> The intersection of one or more wire end point and one wire mid point. </li>
...@@ -175,4 +169,101 @@ public: ...@@ -175,4 +169,101 @@ public:
}; };
/**
* Class SCH_FIND_COLLECTOR_DATA
* is used as a data container for the associated item found by the #SCH_FIND_COLLECTOR
* object.
*/
class SCH_FIND_COLLECTOR_DATA
{
/// The position in drawing units of the found item.
wxPoint m_position;
/// The human readable sheet path @see SCH_SHEET_PATH::PathHumanReadable() of the found item.
wxString m_sheetPath;
/// The parent object if the item found is a child object.
SCH_ITEM* m_parent;
public:
SCH_FIND_COLLECTOR_DATA( const wxPoint& aPosition = wxDefaultPosition,
const wxString& aSheetPath = wxEmptyString,
SCH_ITEM* aParent = NULL )
: m_position( aPosition )
, m_sheetPath( aSheetPath )
, m_parent( aParent )
{ }
wxPoint GetPosition() const { return m_position; }
wxString GetSheetPath() const { return m_sheetPath; }
SCH_ITEM* GetParent() { return m_parent; }
};
/**
* Class SCH_FIND_COLLECTOR
* is used to iterate over all of the items in a schematic or sheet and collect all
* the items that match the given search criteria.
*/
class SCH_FIND_COLLECTOR : public COLLECTOR
{
/// Data associated with each found item.
std::vector< SCH_FIND_COLLECTOR_DATA > m_data;
/// The criteria used to test for matching items.
SCH_FIND_REPLACE_DATA m_findReplaceData;
/// The path of the sheet currently being iterated over.
SCH_SHEET_PATH* m_sheetPath;
public:
/**
* Constructor SCH_FIND_COLLECTOR
*/
SCH_FIND_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems )
{
SetScanTypes( aScanTypes );
}
/**
* Function GetFindData
* returns the data associated with the item found at \a aIndex.
*
* @param aIndex The list index of the data to return.
* @return The associated found item data at \a aIndex if \a aIndex is within the
* list limits. Otherwise an empty data item will be returned.
*/
SCH_FIND_COLLECTOR_DATA GetFindData( int aIndex );
/**
* Function GetFindReplaceData
*
* @return A reference to a #SCH_FIND_REPLACE_DATA object containing the current
* search criteria.
*/
SCH_FIND_REPLACE_DATA& GetFindReplaceData() { return m_findReplaceData; }
wxString GetText( int aIndex );
/**
* @copydoc INSPECTOR::Inspect()
*/
SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
/**
* Function Collect
* scans \a aSheetPath using this class's Inspector method for items matching
* \a aFindReplaceData.
*
* @param aFindReplaceData A #SCH_FIND_REPLACE_DATA object containing the search criteria.
* @param aSheetPath A pointer to a #SCH_SHEET_PATH object to test for matches. A NULL
* value searches the entire schematic hierarchy.
*/
void Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData, SCH_SHEET_PATH* aSheetPath = NULL );
};
#endif // _SCH_COLLECTORS_H_ #endif // _SCH_COLLECTORS_H_
...@@ -382,6 +382,9 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath, ...@@ -382,6 +382,9 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
wxString SCH_COMPONENT::GetPath( SCH_SHEET_PATH* sheet ) wxString SCH_COMPONENT::GetPath( SCH_SHEET_PATH* sheet )
{ {
wxCHECK_MSG( sheet != NULL, wxEmptyString,
wxT( "Cannot get component path with invalid sheet object." ) );
wxString str; wxString str;
str.Printf( wxT( "%8.8lX" ), m_TimeStamp ); str.Printf( wxT( "%8.8lX" ), m_TimeStamp );
...@@ -1533,68 +1536,9 @@ void SCH_COMPONENT::Rotate( wxPoint rotationPoint ) ...@@ -1533,68 +1536,9 @@ void SCH_COMPONENT::Rotate( wxPoint rotationPoint )
bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
wxPoint* aFindLocation ) wxPoint* aFindLocation )
{ {
// Search reference. wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
// reference is a special field because a part identifier is added
// in multi parts per package
// the .m_AddExtraText of the field must be set to add this identifier:
LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName );
if( GetField( REFERENCE )->Matches( aSearchData, aAuxData, aFindLocation ) )
return true;
if( GetField( VALUE )->Matches( aSearchData, aAuxData, aFindLocation ) )
return true;
if( aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS )
{
for( size_t i = VALUE + 1; i < m_Fields.size(); i++ )
{
if( GetField( i )->Matches( aSearchData, aAuxData, aFindLocation ) )
return true;
}
}
// Search for a match in pin name or pin number.
// @TODO: see if the Matches method must be made in LIB_PIN.
// when Matches method will be used in Libedit, this is the best
// Currently, Pins are tested here.
if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) )
return false;
if( Entry )
{
LIB_PINS pinList;
int unit = m_unit;
if( aAuxData != NULL )
unit = GetUnitSelection( (SCH_SHEET_PATH*) aAuxData );
Entry->GetPins( pinList, unit, m_convert );
// Search for a match in pinList
for( unsigned ii = 0; ii < pinList.size(); ii ++ )
{
LIB_PIN* pin = pinList[ii];
wxString pinNum;
pin->ReturnPinStringNum( pinNum );
if( SCH_ITEM::Matches( pin->GetName(), aSearchData )
|| SCH_ITEM::Matches( pinNum, aSearchData ) )
{
if( aFindLocation )
{
wxPoint pinpos = pin->GetPosition();
pinpos = m_transform.TransformCoordinate( pinpos );
*aFindLocation = pinpos + m_Pos;
}
return true;
}
}
}
// Components are searchable via the child field and pin item text.
return false; return false;
} }
...@@ -1716,7 +1660,7 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData ...@@ -1716,7 +1660,7 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData
// Test the bounding boxes of fields if they are visible and not empty. // Test the bounding boxes of fields if they are visible and not empty.
for( int ii = 0; ii < GetFieldCount(); ii++ ) for( int ii = 0; ii < GetFieldCount(); ii++ )
{ {
if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), aTestData ) ) if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), (void*) this ) )
return SEARCH_QUIT; return SEARCH_QUIT;
} }
} }
......
...@@ -408,6 +408,11 @@ public: ...@@ -408,6 +408,11 @@ public:
virtual bool operator <( const SCH_ITEM& aItem ) const; virtual bool operator <( const SCH_ITEM& aItem ) const;
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
#if defined(DEBUG) #if defined(DEBUG)
/** /**
......
...@@ -358,6 +358,11 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint ...@@ -358,6 +358,11 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint
bool match; bool match;
wxString text = GetText(); wxString text = GetText();
if( (m_FieldId > VALUE) && !(aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS) )
return false;
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() );
// Take sheet path into account which effects the reference field and the unit for // Take sheet path into account which effects the reference field and the unit for
// components with multiple parts. // components with multiple parts.
if( m_FieldId == REFERENCE && aAuxData != NULL ) if( m_FieldId == REFERENCE && aAuxData != NULL )
......
...@@ -209,6 +209,11 @@ public: ...@@ -209,6 +209,11 @@ public:
virtual BITMAP_DEF GetMenuImage() const; virtual BITMAP_DEF GetMenuImage() const;
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doHitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const; virtual bool doHitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const;
......
...@@ -927,6 +927,8 @@ void SCH_SHEET::Resize( const wxSize& aSize ) ...@@ -927,6 +927,8 @@ void SCH_SHEET::Resize( const wxSize& aSize )
bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_FileName, aSearchData ) ) if( SCH_ITEM::Matches( m_FileName, aSearchData ) )
{ {
if( aFindLocation ) if( aFindLocation )
...@@ -1033,15 +1035,15 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR* aInspector, const void* aTestData, ...@@ -1033,15 +1035,15 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR* aInspector, const void* aTestData,
// If caller wants to inspect my type // If caller wants to inspect my type
if( stype == Type() ) if( stype == Type() )
{ {
if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) ) if( SEARCH_QUIT == aInspector->Inspect( this, NULL ) )
return SEARCH_QUIT; return SEARCH_QUIT;
} }
else if( stype == SCH_SHEET_PIN_T ) else if( stype == SCH_SHEET_PIN_T )
{ {
// Test the bounding boxes of sheet labels. // Test the sheet labels.
for( size_t i = 0; i < m_pins.size(); i++ ) for( size_t i = 0; i < m_pins.size(); i++ )
{ {
if( SEARCH_QUIT == aInspector->Inspect( &m_pins[ i ], aTestData ) ) if( SEARCH_QUIT == aInspector->Inspect( &m_pins[ i ], (void*) this ) )
return SEARCH_QUIT; return SEARCH_QUIT;
} }
} }
......
...@@ -599,6 +599,11 @@ public: ...@@ -599,6 +599,11 @@ public:
virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems, virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath ); SCH_SHEET_PATH* aSheetPath );
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
#if defined(DEBUG) #if defined(DEBUG)
// comment inherited by Doxygen from Base_Struct // comment inherited by Doxygen from Base_Struct
......
...@@ -45,9 +45,6 @@ ...@@ -45,9 +45,6 @@
#include "dialogs/dialog_schematic_find.h" #include "dialogs/dialog_schematic_find.h"
static const wxString traceFindReplace( wxT( "KicadFindReplace" ) );
SCH_SHEET_PATH::SCH_SHEET_PATH() SCH_SHEET_PATH::SCH_SHEET_PATH()
{ {
for( int i = 0; i<DSLSZ; i++ ) for( int i = 0; i<DSLSZ; i++ )
...@@ -85,6 +82,7 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath ...@@ -85,6 +82,7 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath
Pop(); Pop();
} }
schitem = schitem->Next(); schitem = schitem->Next();
} }
...@@ -384,45 +382,6 @@ SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, ...@@ -384,45 +382,6 @@ SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem,
} }
SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData,
SCH_ITEM* aLastItem,
wxPoint* aFindLocation )
{
bool hasWrapped = false;
bool firstItemFound = false;
bool wrap = ( aSearchData.GetFlags() & FR_SEARCH_WRAP ) != 0;
SCH_ITEM* drawItem = LastDrawList();
while( drawItem != NULL )
{
if( aLastItem && !firstItemFound )
{
firstItemFound = ( drawItem == aLastItem );
}
else
{
if( drawItem->Matches( aSearchData, this, aFindLocation ) )
return drawItem;
}
drawItem = drawItem->Next();
if( drawItem == NULL && aLastItem && firstItemFound && wrap && !hasWrapped )
{
hasWrapped = true;
drawItem = LastDrawList();
}
else if( hasWrapped && aLastItem && firstItemFound && (drawItem == aLastItem) )
{
// Exit when wrapped around to the first item found.
drawItem = NULL;
}
}
return NULL;
}
bool SCH_SHEET_PATH::SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint, bool SCH_SHEET_PATH::SetComponentFootprint( const wxString& aReference, const wxString& aFootPrint,
bool aSetVisible ) bool aSetVisible )
{ {
...@@ -733,83 +692,6 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe ...@@ -733,83 +692,6 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe
} }
SCH_ITEM* SCH_SHEET_LIST::MatchNextItem( wxFindReplaceData& aSearchData,
wxString& aSheetFoundIn,
SCH_ITEM* aLastItem,
wxPoint* aFindLocation )
{
bool firstItemFound = false;
bool hasWrapped = false;
bool wrap = ( aSearchData.GetFlags() & FR_SEARCH_WRAP ) != 0;
SCH_ITEM* drawItem = NULL;
SCH_SHEET_PATH* sheet = GetFirst();
SCH_SHEET_PATH* sheetFirstItemFoundIn = NULL;
wxLogTrace( traceFindReplace, wxT( "Searching schematic for " ) + aSearchData.GetFindString() );
while( sheet != NULL )
{
wxLogTrace( traceFindReplace, wxT( "Searching sheet " + sheet->PathHumanReadable() ) );
drawItem = sheet->LastDrawList();
while( drawItem != NULL )
{
if( aLastItem && !firstItemFound )
{
if( aSheetFoundIn.IsEmpty() )
firstItemFound = (drawItem == aLastItem);
else
firstItemFound = ( (drawItem == aLastItem) &&
(sheet->PathHumanReadable() == aSheetFoundIn) );
if( firstItemFound )
{
sheetFirstItemFoundIn = sheet;
wxLogTrace( traceFindReplace, wxT( "First item %p found in sheet %s" ),
sheetFirstItemFoundIn,
GetChars( sheetFirstItemFoundIn->PathHumanReadable() ) );
}
}
else
{
// Search has wrapped all the way around to the first item found so stop.
if( hasWrapped && aLastItem && (aLastItem == drawItem)
&& (sheet == sheetFirstItemFoundIn ) )
{
wxLogTrace( traceFindReplace,
wxT( "Wrapped around to item %p in sheet %s" ),
sheetFirstItemFoundIn,
GetChars( sheetFirstItemFoundIn->PathHumanReadable() ) );
return NULL;
}
if( drawItem->Matches( aSearchData, sheet, aFindLocation ) )
{
aSheetFoundIn = sheet->PathHumanReadable();
return drawItem;
}
}
drawItem = drawItem->Next();
}
sheet = GetNext();
if( sheet == NULL && aLastItem && firstItemFound && wrap && !hasWrapped )
{
hasWrapped = true;
sheet = GetFirst();
}
}
return NULL;
}
bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference, bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference,
const wxString& aFootPrint, bool aSetVisible ) const wxString& aFootPrint, bool aSetVisible )
{ {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "base_struct.h" #include "base_struct.h"
/** Info about complex hierarchies handling: /** Info about complex hierarchies handling:
* A hierarchical schematic uses sheets (hierarchical sheets) included in a * A hierarchical schematic uses sheets (hierarchical sheets) included in a
* given sheet. Each sheet corresponds to a schematic drawing handled by a * given sheet. Each sheet corresponds to a schematic drawing handled by a
...@@ -261,17 +262,6 @@ public: ...@@ -261,17 +262,6 @@ public:
*/ */
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false );
/**
* Search this sheet path for the next item that matches the search criteria.
*
* @param aSearchData - Criteria to search item against.
* @param aLastItem - Find next item after aLastItem if not NULL.
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return If found, Returns the next schematic item. Otherwise, returns NULL.
*/
SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* aLastItem,
wxPoint * aFindLocation );
SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 ); SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 );
bool operator==( const SCH_SHEET_PATH& d1 ) const; bool operator==( const SCH_SHEET_PATH& d1 ) const;
...@@ -439,25 +429,6 @@ public: ...@@ -439,25 +429,6 @@ public:
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL, SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
SCH_ITEM* aLastItem = NULL, bool aWrap = true ); SCH_ITEM* aLastItem = NULL, bool aWrap = true );
/**
* Function MatchNextItem
* searches the entire schematic for the next item that matches the search criteria.
*
* @param aSearchData Criteria to search item against.
* @param aSheetFoundIn A reference to the sheet path the last item was found in. Use
* wxEmptyString to search from the beginning of the sheet list.
* This will be set to the human readable sheet path if an item
* is found.
* @param aLastItem Find next item after aLastItem if not NULL.
* @param aFindLocation A pointer to a wxPoint object to put the location of matched
* item into. It can be NULL.
* @return A SCH_ITEM pointer the next schematic item if found. Otherwise, returns NULL.
*/
SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData,
wxString& aSheetFoundIn,
SCH_ITEM* aLastItem,
wxPoint* aFindLocation );
/** /**
* Function SetFootprintField * Function SetFootprintField
* searches all the sheets for a component with \a aReference and set the footprint * searches all the sheets for a component with \a aReference and set the footprint
......
...@@ -361,15 +361,19 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg ) ...@@ -361,15 +361,19 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
case 'I': case 'I':
m_Shape = NET_INPUT; m_Shape = NET_INPUT;
break; break;
case 'O': case 'O':
m_Shape = NET_OUTPUT; m_Shape = NET_OUTPUT;
break; break;
case 'B': case 'B':
m_Shape = NET_BIDI; m_Shape = NET_BIDI;
break; break;
case 'T': case 'T':
m_Shape = NET_TRISTATE; m_Shape = NET_TRISTATE;
break; break;
case 'U': case 'U':
m_Shape = NET_UNSPECIFIED; m_Shape = NET_UNSPECIFIED;
break; break;
...@@ -380,12 +384,15 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg ) ...@@ -380,12 +384,15 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
case 'R' : /* pin on right side */ case 'R' : /* pin on right side */
SetEdge( 1 ); SetEdge( 1 );
break; break;
case 'T' : /* pin on top side */ case 'T' : /* pin on top side */
SetEdge( 2 ); SetEdge( 2 );
break; break;
case 'B' : /* pin on bottom side */ case 'B' : /* pin on bottom side */
SetEdge( 3 ); SetEdge( 3 );
break; break;
case 'L' : /* pin on left side */ case 'L' : /* pin on left side */
default : default :
SetEdge( 0 ); SetEdge( 0 );
...@@ -397,12 +404,17 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg ) ...@@ -397,12 +404,17 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
bool SCH_SHEET_PIN::Matches( wxFindReplaceData& aSearchData, bool SCH_SHEET_PIN::Matches( wxFindReplaceData& aSearchData,
void* aAuxData, wxPoint * aFindLocation ) void* aAuxData, wxPoint* aFindLocation )
{ {
wxCHECK_MSG( GetParent() != NULL, false,
wxT( "Sheet pin " ) + m_Text + wxT( " does not have a parent sheet!" ) );
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_Text, aSearchData ) ) if( SCH_ITEM::Matches( m_Text, aSearchData ) )
{ {
if( aFindLocation ) if( aFindLocation )
*aFindLocation = m_Pos; *aFindLocation = GetBoundingBox().Centre();
return true; return true;
} }
......
...@@ -167,6 +167,8 @@ wxPoint SCH_TEXT::GetSchematicTextOffset() const ...@@ -167,6 +167,8 @@ wxPoint SCH_TEXT::GetSchematicTextOffset() const
bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation ) bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_Text, aSearchData ) ) if( SCH_ITEM::Matches( m_Text, aSearchData ) )
{ {
EDA_RECT BoundaryBox = GetBoundingBox(); EDA_RECT BoundaryBox = GetBoundingBox();
......
...@@ -328,6 +328,11 @@ public: ...@@ -328,6 +328,11 @@ public:
virtual BITMAP_DEF GetMenuImage() const { return add_line_label_xpm; } virtual BITMAP_DEF GetMenuImage() const { return add_line_label_xpm; }
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; } virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
......
...@@ -122,9 +122,9 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) ...@@ -122,9 +122,9 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( ID_GET_NETLIST, SCH_EDIT_FRAME::OnCreateNetlist ) EVT_TOOL( ID_GET_NETLIST, SCH_EDIT_FRAME::OnCreateNetlist )
EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials ) EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems ) EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadStuffFile ) EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadStuffFile )
EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem ) EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem )
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp ) EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp ) EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout ) EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
...@@ -173,6 +173,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) ...@@ -173,6 +173,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_FIND_DRC_MARKER( wxID_ANY, SCH_EDIT_FRAME::OnFindDrcMarker ) EVT_FIND_DRC_MARKER( wxID_ANY, SCH_EDIT_FRAME::OnFindDrcMarker )
EVT_FIND( wxID_ANY, SCH_EDIT_FRAME::OnFindSchematicItem ) EVT_FIND( wxID_ANY, SCH_EDIT_FRAME::OnFindSchematicItem )
EVT_FIND_REPLACE( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace ) EVT_FIND_REPLACE( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
EVT_FIND_REPLACE_ALL( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
END_EVENT_TABLE() END_EVENT_TABLE()
...@@ -185,12 +186,12 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father, ...@@ -185,12 +186,12 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father,
EDA_DRAW_FRAME( father, SCHEMATIC_FRAME, title, pos, size, style ) EDA_DRAW_FRAME( father, SCHEMATIC_FRAME, title, pos, size, style )
{ {
m_FrameName = wxT( "SchematicFrame" ); m_FrameName = wxT( "SchematicFrame" );
m_Draw_Axis = FALSE; // true to show axis m_Draw_Axis = false; // true to show axis
m_Draw_Sheet_Ref = true; // true to show sheet references m_Draw_Sheet_Ref = true; // true to show sheet references
m_CurrentSheet = new SCH_SHEET_PATH(); m_CurrentSheet = new SCH_SHEET_PATH();
m_TextFieldSize = DEFAULT_SIZE_TEXT; m_TextFieldSize = DEFAULT_SIZE_TEXT;
m_LibeditFrame = NULL; // Component editor frame. m_LibeditFrame = NULL; // Component editor frame.
m_ViewlibFrame = NULL; // Frame for browsing component libraries m_ViewlibFrame = NULL; // Frame for browsing component libraries
m_DefaultSchematicFileName = NAMELESS_PROJECT; m_DefaultSchematicFileName = NAMELESS_PROJECT;
m_DefaultSchematicFileName += wxT( ".sch" ); m_DefaultSchematicFileName += wxT( ".sch" );
m_ShowAllPins = false; m_ShowAllPins = false;
...@@ -203,6 +204,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father, ...@@ -203,6 +204,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father,
m_findReplaceData = new wxFindReplaceData( wxFR_DOWN ); m_findReplaceData = new wxFindReplaceData( wxFR_DOWN );
m_undoItem = NULL; m_undoItem = NULL;
m_hasAutoSave = true; m_hasAutoSave = true;
m_foundItemIndex = 0;
CreateScreens(); CreateScreens();
...@@ -635,10 +637,10 @@ void SCH_EDIT_FRAME::OnCreateBillOfMaterials( wxCommandEvent& ) ...@@ -635,10 +637,10 @@ void SCH_EDIT_FRAME::OnCreateBillOfMaterials( wxCommandEvent& )
} }
void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& aEvent )
{ {
wxASSERT_MSG( m_findReplaceData != NULL, wxCHECK_RET( m_findReplaceData != NULL,
wxT( "Forgot to create find/replace data. Bad Programmer!" ) ); wxT( "Forgot to create find/replace data. Bad Programmer!" ) );
this->DrawPanel->m_IgnoreMouseEvents = true; this->DrawPanel->m_IgnoreMouseEvents = true;
...@@ -661,7 +663,13 @@ void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& event ) ...@@ -661,7 +663,13 @@ void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& event )
position = wxDefaultPosition; position = wxDefaultPosition;
} }
m_dlgFindReplace = new DIALOG_SCH_FIND( this, m_findReplaceData, position, m_findDialogSize ); int style = 0;
if( aEvent.GetId() == wxID_REPLACE )
style = wxFR_REPLACEDIALOG;
m_dlgFindReplace = new DIALOG_SCH_FIND( this, m_findReplaceData, position, m_findDialogSize,
style );
m_dlgFindReplace->SetFindEntries( m_findStringHistoryList ); m_dlgFindReplace->SetFindEntries( m_findStringHistoryList );
m_dlgFindReplace->SetReplaceEntries( m_replaceStringHistoryList ); m_dlgFindReplace->SetReplaceEntries( m_replaceStringHistoryList );
......
...@@ -77,6 +77,9 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() ...@@ -77,6 +77,9 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
msg = AddHotkeyName( HELP_FIND, s_Schematic_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT ); msg = AddHotkeyName( HELP_FIND, s_Schematic_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT );
m_HToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg ); m_HToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg );
// m_HToolBar->AddTool( wxID_REPLACE, wxEmptyString, KiBitmap( find_replace_xpm ),
// wxNullBitmap, wxITEM_NORMAL, _( "Find and replace text" ),
// HELP_REPLACE, NULL );
m_HToolBar->AddSeparator(); m_HToolBar->AddSeparator();
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/** /**
* @file base_struct.h * @file base_struct.h
* @brief Basic classes for most KiCad items. * @brief Basic classes for most KiCad items.
...@@ -37,7 +62,7 @@ enum KICAD_T { ...@@ -37,7 +62,7 @@ enum KICAD_T {
PCB_MODULE_TEXT_T, // a text in a footprint PCB_MODULE_TEXT_T, // a text in a footprint
PCB_MODULE_EDGE_T, // a footprint edge PCB_MODULE_EDGE_T, // a footprint edge
PCB_TRACE_T, // a track segment (segment on a copper layer) PCB_TRACE_T, // a track segment (segment on a copper layer)
PCB_VIA_T, // a via (like atrack segment on a copper layer) PCB_VIA_T, // a via (like a track segment on a copper layer)
PCB_ZONE_T, // a segment used to fill a zone area (segment on a PCB_ZONE_T, // a segment used to fill a zone area (segment on a
// copper layer) // copper layer)
PCB_MARKER_T, // a marker used to show something PCB_MARKER_T, // a marker used to show something
...@@ -48,7 +73,7 @@ enum KICAD_T { ...@@ -48,7 +73,7 @@ enum KICAD_T {
PCB_ITEM_LIST_T, // a list of board items PCB_ITEM_LIST_T, // a list of board items
// Schematic draw Items. The order of these items effects the sort order. // Schematic draw Items. The order of these items effects the sort order.
// It is currenlty ordered to mimic the old Eeschema locate behavior where // It is currently ordered to mimic the old Eeschema locate behavior where
// the smallest item is the selected item. // the smallest item is the selected item.
SCH_MARKER_T, SCH_MARKER_T,
SCH_JUNCTION_T, SCH_JUNCTION_T,
...@@ -143,8 +168,8 @@ public: ...@@ -143,8 +168,8 @@ public:
* @param testItem An EDA_ITEM to examine. * @param testItem An EDA_ITEM to examine.
* @param testData is arbitrary data needed by the inspector to determine * @param testData is arbitrary data needed by the inspector to determine
* if the EDA_ITEM under test meets its match criteria. * if the EDA_ITEM under test meets its match criteria.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, * @return SEARCH_RESULT SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE; * else SCAN_CONTINUE;
*/ */
SEARCH_RESULT virtual Inspect( EDA_ITEM* testItem, const void* testData ) = 0; SEARCH_RESULT virtual Inspect( EDA_ITEM* testItem, const void* testData ) = 0;
}; };
...@@ -187,7 +212,7 @@ public: ...@@ -187,7 +212,7 @@ public:
/** /**
* Function Normalize * Function Normalize
* ensures thatthe height ant width are positive. * ensures that the height ant width are positive.
*/ */
void Normalize(); void Normalize();
...@@ -351,8 +376,7 @@ public: ...@@ -351,8 +376,7 @@ public:
int m_Flags; // flags for editing and other uses. int m_Flags; // flags for editing and other uses.
unsigned long m_TimeStamp; // Time stamp used for logical links unsigned long m_TimeStamp; // Time stamp used for logical links
int m_Selected; /* Used by block commands, and selective int m_Selected; /* Used by block commands, and selective editing */
* editing */
// member used in undo/redo function // member used in undo/redo function
EDA_ITEM* m_Image; // Link to an image copy to save a copy of EDA_ITEM* m_Image; // Link to an image copy to save a copy of
...@@ -513,15 +537,15 @@ public: ...@@ -513,15 +537,15 @@ public:
* *
* @param listStart The first in a list of EDA_ITEMs to iterate over. * @param listStart The first in a list of EDA_ITEMs to iterate over.
* @param inspector Is an INSPECTOR to call on each object that is one of * @param inspector Is an INSPECTOR to call on each object that is one of
* the requested scanTypes. * the requested scanTypes.
* @param testData Is an aid to testFunc, and should be sufficient to * @param testData Is an aid to testFunc, and should be sufficient to allow
* allow it to fully determine if an item meets the match criteria, but it * it to fully determine if an item meets the match criteria,
* may also be used to collect output. * but it may also be used to collect output.
* @param scanTypes A KICAD_T array that is EOT * @param scanTypes A KICAD_T array that is EOT terminated, and provides both
* terminated, and provides both the order and interest level of of * the order and interest level of of the types of objects to
* the types of objects to be iterated over. * be iterated over.
* @return SEARCH_RESULT - SEARCH_QUIT if the called INSPECTOR returned * @return SEARCH_RESULT SEARCH_QUIT if the called INSPECTOR returned
* SEARCH_QUIT, else SCAN_CONTINUE; * SEARCH_QUIT, else SCAN_CONTINUE;
*/ */
static SEARCH_RESULT IterateForward( EDA_ITEM* listStart, static SEARCH_RESULT IterateForward( EDA_ITEM* listStart,
INSPECTOR* inspector, INSPECTOR* inspector,
...@@ -538,9 +562,9 @@ public: ...@@ -538,9 +562,9 @@ public:
* @param inspector An INSPECTOR instance to use in the inspection. * @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector. * @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order * @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT. * is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, * @return SEARCH_RESULT SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector. * else SCAN_CONTINUE, and determined by the inspector.
*/ */
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] ); const KICAD_T scanTypes[] );
...@@ -569,7 +593,7 @@ public: ...@@ -569,7 +593,7 @@ public:
/** /**
* Function GetMenuImage * Function GetMenuImage
* returns a pointer to an image to be used in menus. The default version returns * returns a pointer to an image to be used in menus. The default version returns
* the right arrow image. Overide this function to provide object specific menu * the right arrow image. Override this function to provide object specific menu
* images. * images.
* @return The menu image associated with the item. * @return The menu image associated with the item.
*/ */
...@@ -582,7 +606,7 @@ public: ...@@ -582,7 +606,7 @@ public:
* The base class returns false since many of the objects derived from EDA_ITEM * The base class returns false since many of the objects derived from EDA_ITEM
* do not have any text to search. * do not have any text to search.
* *
* @param aSearchData A reference to a wxFindReplaceData object containin the * @param aSearchData A reference to a wxFindReplaceData object containing the
* search criteria. * search criteria.
* @param aAuxData A pointer to optional data required for the search or NULL * @param aAuxData A pointer to optional data required for the search or NULL
* if not used. * if not used.
...@@ -600,7 +624,7 @@ public: ...@@ -600,7 +624,7 @@ public:
* Function Matches * Function Matches
* compares \a aText against search criteria in \a aSearchData. * compares \a aText against search criteria in \a aSearchData.
* *
* @param aText A referenc to a wxString object containing the string to test. * @param aText A reference to a wxString object containing the string to test.
* @param aSearchData The criteria to search against. * @param aSearchData The criteria to search against.
* @return True if \a aText matches the search criteria in \a aSearchData. * @return True if \a aText matches the search criteria in \a aSearchData.
*/ */
...@@ -643,7 +667,7 @@ public: ...@@ -643,7 +667,7 @@ public:
* Function Show * Function Show
* is used to output the object tree, currently for debugging only. * is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level * @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree. * of nesting of this object within the overall tree.
* @param os The ostream& to output to. * @param os The ostream& to output to.
*/ */
virtual void Show( int nestLevel, std::ostream& os ) const; virtual void Show( int nestLevel, std::ostream& os ) const;
...@@ -675,7 +699,7 @@ inline EDA_ITEM* new_clone( const EDA_ITEM& aItem ) { return aItem.Clone(); } ...@@ -675,7 +699,7 @@ inline EDA_ITEM* new_clone( const EDA_ITEM& aItem ) { return aItem.Clone(); }
/** /**
* Define list of drawing items for screens. * Define list of drawing items for screens.
* *
* The standard C++ containter was choosen so the pointer can be removed from a list without * The standard C++ container was chosen so the pointer can be removed from a list without
* it being destroyed. * it being destroyed.
*/ */
typedef std::vector< EDA_ITEM* > EDA_ITEMS; typedef std::vector< EDA_ITEM* > EDA_ITEMS;
...@@ -700,7 +724,7 @@ enum GRTextVertJustifyType { ...@@ -700,7 +724,7 @@ enum GRTextVertJustifyType {
enum GRTraceMode { enum GRTraceMode {
FILAIRE = 0, // segments are drawn as lines FILAIRE = 0, // segments are drawn as lines
FILLED, // normal mode: segments have thickness FILLED, // normal mode: segments have thickness
SKETCH // sketcg mode: segments have thickness, but are not SKETCH // sketch mode: segments have thickness, but are not
// filled // filled
}; };
...@@ -796,14 +820,13 @@ public: ...@@ -796,14 +820,13 @@ public:
/** /**
* Function Draw * Function Draw
* @param aPanel = the current DrawPanel * @param aPanel = the current DrawPanel
* @param aDC = the current Device Context * @param aDC = the current Device Context
* @param aOffset = draw offset (usually (0,0)) * @param aOffset = draw offset (usually (0,0))
* @param aColor = text color * @param aColor = text color
* @param aDrawMode = GR_OR, GR_XOR.., -1 to use the current mode. * @param aDrawMode = GR_OR, GR_XOR.., -1 to use the current mode.
* @param aDisplay_mode = FILAIRE, FILLED or SKETCH * @param aDisplay_mode = FILAIRE, FILLED or SKETCH
* @param aAnchor_color = anchor color ( UNSPECIFIED_COLOR = do * @param aAnchor_color = anchor color ( UNSPECIFIED_COLOR = do not draw anchor ).
* not draw anchor ).
*/ */
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor, const wxPoint& aOffset, EDA_Colors aColor,
...@@ -816,16 +839,15 @@ private: ...@@ -816,16 +839,15 @@ private:
* Function DrawOneLineOfText * Function DrawOneLineOfText
* Draw a single text line. * Draw a single text line.
* Used to draw each line of this EDA_TEXT, that can be multiline * Used to draw each line of this EDA_TEXT, that can be multiline
* @param aPanel = the current DrawPanel * @param aPanel = the current DrawPanel
* @param aDC = the current Device Context * @param aDC = the current Device Context
* @param aOffset = draw offset (usually (0,0)) * @param aOffset = draw offset (usually (0,0))
* @param aColor = text color * @param aColor = text color
* @param aDrawMode = GR_OR, GR_XOR.., -1 to use the current mode. * @param aDrawMode = GR_OR, GR_XOR.., -1 to use the current mode.
* @param aFillMode = FILAIRE, FILLED or SKETCH * @param aFillMode = FILAIRE, FILLED or SKETCH
* @param aAnchor_color = anchor color ( UNSPECIFIED_COLOR = do * @param aAnchor_color = anchor color ( UNSPECIFIED_COLOR = do not draw anchor ).
* not draw anchor ). * @param aText = the single line of text to draw.
* @param aText = the single line of text to draw. * @param aPos = the position of this line ).
* @param aPos = the position of this line ).
*/ */
void DrawOneLineOfText( EDA_DRAW_PANEL* aPanel, wxDC* aDC, void DrawOneLineOfText( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aOffset, EDA_Colors aColor, const wxPoint& aOffset, EDA_Colors aColor,
...@@ -868,14 +890,14 @@ public: ...@@ -868,14 +890,14 @@ public:
* useful in multiline texts to calculate the full text or a line area (for * useful in multiline texts to calculate the full text or a line area (for
* zones filling, locate functions....) * zones filling, locate functions....)
* @return the rect containing the line of text (i.e. the position and the * @return the rect containing the line of text (i.e. the position and the
* size of one line) * size of one line) this rectangle is calculated for 0 orient text.
* this rectangle is calculated for 0 orient text. if orient is not 0 the * If orientation is not 0 the rect must be rotated to match the
* rect must be rotated to match the physical area * physical area
* @param aLine : the line of text to consider. * @param aLine The line of text to consider.
* for single line text, aLine is unused * for single line text, aLine is unused
* If aLine == -1, the full area (considering all lines) is returned * If aLine == -1, the full area (considering all lines) is returned
* @param aThickness - Overrides the current thickness when greater than 0. * @param aThickness Overrides the current thickness when greater than 0.
* @param aInvertY - Invert the Y axis when calculating bounding box. * @param aInvertY Invert the Y axis when calculating bounding box.
*/ */
EDA_RECT GetTextBox( int aLine = -1, int aThickness = -1, bool aInvertY = false ) const; EDA_RECT GetTextBox( int aLine = -1, int aThickness = -1, bool aInvertY = false ) const;
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file class_collector.h
* @brief COLLECTOR class definition.
*/
#ifndef COLLECTOR_H #ifndef COLLECTOR_H
#define COLLECTOR_H #define COLLECTOR_H
...@@ -51,33 +56,48 @@ class COLLECTOR : public INSPECTOR ...@@ -51,33 +56,48 @@ class COLLECTOR : public INSPECTOR
{ {
protected: protected:
/// Which object types to scan /// Which object types to scan
const KICAD_T* m_ScanTypes; const KICAD_T* m_ScanTypes;
/// A place to hold collected objects without taking ownership of their memory. /// A place to hold collected objects without taking ownership of their memory.
std::vector<EDA_ITEM*> m_List; std::vector<EDA_ITEM*> m_List;
/// A point to test against, andt that was used to make the collection. /// A point to test against, and that was used to make the collection.
wxPoint m_RefPos; wxPoint m_RefPos;
/// A bounding box to test against, and that was used to make the collection. /// A bounding box to test against, and that was used to make the collection.
EDA_RECT m_RefBox; EDA_RECT m_RefBox;
/// The time at which the collection was made. /// The time at which the collection was made.
int m_TimeAtCollection; int m_TimeAtCollection;
public: public:
COLLECTOR() COLLECTOR()
{ {
m_ScanTypes = 0; m_ScanTypes = 0;
} }
virtual ~COLLECTOR() virtual ~COLLECTOR()
{ {
} }
/**
* Function IsValidIndex
* tests if \a aIndex is with the limits of the list of collected items.
*
* @param aIndex The index to test.
* @return True if \a aIndex is with the limits of the list of collected items,
* otherwise false.
*/
bool IsValidIndex( int aIndex )
{
return ( (unsigned) aIndex < m_List.size() );
}
/** /**
* Function GetCount * Function GetCount
* returns the number of objects in the list * returns the number of objects in the list
...@@ -108,29 +128,33 @@ public: ...@@ -108,29 +128,33 @@ public:
m_List.push_back( item ); m_List.push_back( item );
} }
/** /**
* Function Remove * Function Remove
* removes the item at item_position (first position is 0); * removes the item at \a aIndex (first position is 0);
* @param ndx The index into the list. * @param aIndex The index into the list.
*/ */
void Remove( int ndx ) void Remove( int aIndex )
{ {
m_List.erase( m_List.begin() + ndx ); m_List.erase( m_List.begin() + aIndex );
} }
/** /**
* Function operator[int] * Function operator[int]
* is used for read only access and returns the object at index ndx. * is used for read only access and returns the object at \a aIndex.
* @param ndx The index into the list. * @param aIndex The index into the list.
* @return EDA_ITEM* - or something derived from it, or NULL. * @return EDA_ITEM* - or something derived from it, or NULL.
*/ */
EDA_ITEM* operator[]( int ndx ) const EDA_ITEM* operator[]( int aIndex ) const
{ {
if( (unsigned)ndx < (unsigned)GetCount() ) // (unsigned) excludes ndx<0 also if( (unsigned)aIndex < (unsigned)GetCount() ) // (unsigned) excludes aIndex<0 also
return m_List[ ndx ]; return m_List[ aIndex ];
return NULL; return NULL;
} }
/** /**
* Function BasePtr * Function BasePtr
* returns the address of the first element in the array. Only call this * returns the address of the first element in the array. Only call this
...@@ -142,6 +166,7 @@ public: ...@@ -142,6 +166,7 @@ public:
return &m_List[0]; return &m_List[0];
} }
/** /**
* Function HasItem * Function HasItem
* tests if \a aItem has already been collected. * tests if \a aItem has already been collected.
...@@ -160,23 +185,26 @@ public: ...@@ -160,23 +185,26 @@ public:
return false; return false;
} }
/** /**
* Function SetScanTypes * Function SetScanTypes
* records the list of KICAD_T types to consider for collection by * records the list of KICAD_T types to consider for collection by
* the Inspect() function. * the Inspect() function.
* @param scanTypes An array of KICAD_T, terminated by EOT. No copy is * @param scanTypes An array of KICAD_T, terminated by EOT. No copy is
* is made of this array (so cannot come from caller's stack). * is made of this array (so cannot come from caller's stack).
*/ */
void SetScanTypes( const KICAD_T* scanTypes ) void SetScanTypes( const KICAD_T* scanTypes )
{ {
m_ScanTypes = scanTypes; m_ScanTypes = scanTypes;
} }
void SetTimeNow() void SetTimeNow()
{ {
m_TimeAtCollection = GetTimeStamp(); m_TimeAtCollection = GetTimeStamp();
} }
int GetTime() int GetTime()
{ {
return m_TimeAtCollection; return m_TimeAtCollection;
...@@ -206,32 +234,13 @@ public: ...@@ -206,32 +234,13 @@ public:
int dx = abs( aRefPos.x - m_RefPos.x ); int dx = abs( aRefPos.x - m_RefPos.x );
int dy = abs( aRefPos.y - m_RefPos.y ); int dy = abs( aRefPos.y - m_RefPos.y );
if( dx <= distMax && dy <= distMax if( dx <= distMax && dy <= distMax && GetTimeStamp()-m_TimeAtCollection <= timeMax )
&& GetTimeStamp()-m_TimeAtCollection <= timeMax )
return true; return true;
else else
return false; return false;
} }
/**
* Function Inspect
* is the examining function within the INSPECTOR which is passed to the
* Iterate function. It is used primarily for searching, but not limited to
* that. It can also collect or modify the scanned objects.
*
* @param testItem An EDA_ITEM to examine.
* @param testData is arbitrary data needed by the inspector to determine
* if the EDA_ITEM under test meets its match criteria.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE;
*
* implement in derived class:
SEARCH_RESULT virtual Inspect( EDA_ITEM* testItem,
const void* testData ) = 0;
*/
/** /**
* Function Collect * Function Collect
* scans an EDA_ITEM using this class's Inspector method, which does * scans an EDA_ITEM using this class's Inspector method, which does
...@@ -260,4 +269,3 @@ public: ...@@ -260,4 +269,3 @@ public:
}; };
#endif // COLLECTOR_H #endif // COLLECTOR_H
...@@ -392,7 +392,7 @@ int ReturnValueFromTextCtrl( const wxTextCtrl& TextCtr, ...@@ -392,7 +392,7 @@ int ReturnValueFromTextCtrl( const wxTextCtrl& TextCtr,
* @param aString is the text to split * @param aString is the text to split
* @param aSplitter is the 'split' character * @param aSplitter is the 'split' character
*/ */
wxArrayString* wxStringSplit( wxString txt, wxChar aSplitter ); wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter );
/** /**
* Function To_User_Unit * Function To_User_Unit
......
...@@ -61,6 +61,10 @@ typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS; ...@@ -61,6 +61,10 @@ typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS;
#endif #endif
/// Flag to enable find and replace tracing using the WXTRACE environment variable.
extern const wxString traceFindReplace;
enum DANGLING_END_T { enum DANGLING_END_T {
UNKNOWN = 0, UNKNOWN = 0,
WIRE_START_END, WIRE_START_END,
......
...@@ -146,12 +146,16 @@ private: ...@@ -146,12 +146,16 @@ private:
SCH_ITEM* m_itemToRepeat; ///< Last item to insert by the repeat command. SCH_ITEM* m_itemToRepeat; ///< Last item to insert by the repeat command.
int m_repeatLabelDelta; ///< Repeat label number increment step. int m_repeatLabelDelta; ///< Repeat label number increment step.
SCH_COLLECTOR m_collectedItems; ///< List of collected items. SCH_COLLECTOR m_collectedItems; ///< List of collected items.
SCH_FIND_COLLECTOR m_foundItems; ///< List of find/replace items.
SCH_ITEM* m_undoItem; ///< Copy of the current item being edited. SCH_ITEM* m_undoItem; ///< Copy of the current item being edited.
wxString m_simulatorCommand; ///< Command line used to call the circuit wxString m_simulatorCommand; ///< Command line used to call the circuit
///< simulator (gnucap, spice, ...) ///< simulator (gnucap, spice, ...)
wxString m_netListerCommand; ///< Command line to call a custom net list wxString m_netListerCommand; ///< Command line to call a custom net list
///< generator. ///< generator.
/// An index to the last find item in the found items list #m_foundItems.
int m_foundItemIndex;
static int m_lastSheetPinType; ///< Last sheet pin type. static int m_lastSheetPinType; ///< Last sheet pin type.
static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size. static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position. static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
*/ */
/** /**
* @file block.cpp * @file pcbnew/block.cpp
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment