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
}
/**
* 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* wxStringSplit( wxString aString, wxChar aSplitter )
{
wxArrayString* list = new wxArrayString();
while( 1 )
{
int index = txt.Find( splitter );
int index = aString.Find( aSplitter );
if( index == wxNOT_FOUND )
break;
wxString tmp;
tmp = txt.Mid( 0, index );
txt = txt.Mid( index + 1, txt.size() - index );
tmp = aString.Mid( 0, index );
aString = aString.Mid( index + 1, aString.size() - index );
list->Add( tmp );
}
if( !txt.IsEmpty() )
if( !aString.IsEmpty() )
{
list->Add( txt );
list->Add( aString );
}
return list;
}
/**
* Function To_User_Unit
* Convert in inch or mm the variable "val" (double)given in internal units
......
......@@ -39,7 +39,8 @@
#include "general.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 )
......
......@@ -1059,7 +1059,7 @@
<property name="fg"></property>
<property name="font"></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="maximum_size"></property>
<property name="minimum_size"></property>
......@@ -1077,7 +1077,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick"></event>
<event name="OnButtonClick">OnReplace</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
......@@ -1100,7 +1100,7 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<event name="OnUpdateUI">OnUpdateReplaceUI</event>
</object>
</object>
<object class="sizeritem" expanded="0">
......@@ -1116,7 +1116,7 @@
<property name="fg"></property>
<property name="font"></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="maximum_size"></property>
<property name="minimum_size"></property>
......@@ -1134,7 +1134,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick"></event>
<event name="OnButtonClick">OnReplace</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
......@@ -1157,7 +1157,7 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<event name="OnUpdateUI">OnUpdateReplaceUI</event>
</object>
</object>
<object class="sizeritem" expanded="0">
......
......@@ -16,8 +16,10 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData,
if( aStyle & wxFR_REPLACEDIALOG )
{
SetTitle( _( "Find and Replace" ) );
m_staticReplace->Show( true );
m_comboReplace->Show( true );
m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented.
}
int flags = m_findReplaceData->GetFlags();
......@@ -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 )
{
aEvent.Enable( !m_checkWildcardMatch->GetValue() );
......@@ -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 )
{
SendEvent( wxEVT_COMMAND_FIND_CLOSE );
......@@ -101,13 +131,14 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
event.SetEventObject( this );
event.SetFindString( m_comboFind->GetValue() );
int flags = 0;
if ( HasFlag( wxFR_REPLACEDIALOG ) )
{
event.SetReplaceString( m_comboReplace->GetValue() );
flags |= FR_SEARCH_REPLACE;
}
int flags = 0;
if( m_radioForward->GetValue() )
flags |= wxFR_DOWN;
......@@ -117,7 +148,7 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
if( m_checkWholeWord->GetValue() )
flags |= wxFR_WHOLEWORD;
if( m_checkWildcardMatch->GetValue() )
if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() )
flags |= FR_MATCH_WILDCARD;
if( m_checkAllFields->GetValue() )
......@@ -152,6 +183,9 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType )
{
GetParent()->GetEventHandler()->ProcessEvent( event );
}
if( event.GetFlags() != flags )
m_findReplaceData->SetFlags( event.GetFlags() );
}
......
......@@ -20,7 +20,7 @@
/**
* 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
* 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
{
......@@ -44,7 +44,7 @@ enum SchematicFindReplaceFlags
/// Don't warp cursor to found item until the dialog is closed.
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,
/// Used by the search event handler to let the dialog know that a replaceable
......@@ -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 */
class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE
{
......@@ -60,9 +94,12 @@ protected:
// Handlers for DIALOG_SCH_FIND_BASE events.
void OnClose( wxCloseEvent& aEvent );
void OnUpdateFindUI( wxUpdateUIEvent& aEvent );
void OnUpdateReplaceUI( wxUpdateUIEvent& aEvent );
void OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent );
void OnUpdateWildcardUI( wxUpdateUIEvent& aEvent );
void OnFind( wxCommandEvent& aEvent );
void OnReplace( wxCommandEvent& aEvent );
void OnCancel( wxCommandEvent& aEvent );
void SendEvent( const wxEventType& aEventType );
......
......@@ -101,12 +101,12 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
m_buttonFind->SetDefault();
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();
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();
rightSizer->Add( m_buttonReplaceAll, 0, wxALL, 5 );
......@@ -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_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_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 );
}
......@@ -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_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_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 );
}
......@@ -61,6 +61,8 @@ class DIALOG_SCH_FIND_BASE : public wxDialog
virtual void OnUpdateWildcardUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnFind( wxCommandEvent& 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(); }
......
......@@ -297,60 +297,88 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
{
static SCH_ITEM* lastItem = NULL; /* last item found when searching a match
* note: the actual matched item can be a
* part of lastItem (for instance a field in a component
*/
static wxString sheetFoundIn;
static wxPoint lastItemPosition; // the actual position of the matched sub item
SCH_SHEET_LIST schematic;
wxString msg;
wxFindReplaceData searchCriteria;
bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
static wxPoint itemPosition; // the actual position of the matched item.
SCH_SHEET_LIST schematic;
wxString msg;
SCH_FIND_REPLACE_DATA searchCriteria;
bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
searchCriteria.SetFlags( aEvent.GetFlags() );
searchCriteria.SetFindString( aEvent.GetFindString() );
searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
{
sheetFoundIn = m_CurrentSheet->PathHumanReadable();
warpCursor = true;
}
else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
if( searchCriteria != m_foundItems.GetFindReplaceData() )
{
sheetFoundIn = m_CurrentSheet->PathHumanReadable();
lastItem = m_CurrentSheet->MatchNextItem( searchCriteria, lastItem, &lastItemPosition );
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
{
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
{
lastItem = schematic.MatchNextItem( searchCriteria, sheetFoundIn, lastItem,
&lastItemPosition );
if( searchCriteria.GetFlags() & wxFR_DOWN )
{
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() );
*m_CurrentSheet = *sheet;
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
{
sheetFoundIn = wxEmptyString;
aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
}
......@@ -360,4 +388,23 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( 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 @@
// Schematic editor:
#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_POWERPORT _( "Place a power port" )
#define HELP_PLACE_WIRE _( "Place a wire" )
......
......@@ -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)
void LIB_PIN::Show( int nestLevel, std::ostream& os )
......
......@@ -134,7 +134,7 @@ public:
char m_PinNamePositionOpt;
public:
LIB_PIN( LIB_COMPONENT * aParent );
LIB_PIN( LIB_COMPONENT* aParent );
LIB_PIN( const LIB_PIN& aPin );
~LIB_PIN() { }
......@@ -185,6 +185,11 @@ public:
*/
virtual void DisplayInfo( EDA_DRAW_FRAME* aFrame );
/**
* @copydoc EDA_ITEM::Matches()
*/
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
/**
* Function GetBoundingBox
* @return the boundary box for the pin in schematic coordinates.
......
......@@ -217,6 +217,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
text = AddHotkeyName( _( "&Find" ), s_Schematic_Hokeys_Descr, HK_FIND_ITEM );
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
editMenu->AppendSeparator();
AddMenuItem( editMenu,
......
/**
* @file sch_collectors.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
......@@ -26,6 +22,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file sch_collectors.cpp
*/
#include "general.h"
#include "transform.h"
#include "sch_collectors.h"
......@@ -314,3 +314,109 @@ bool SCH_COLLECTOR::IsDraggableJunction() const
return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 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.
*
......@@ -26,12 +22,17 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file sch_collectors.h
*/
#ifndef _SCH_COLLECTORS_H_
#define _SCH_COLLECTORS_H_
#include "class_collector.h"
#include "sch_item_struct.h"
#include "dialogs/dialog_schematic_find.h"
/**
......@@ -120,14 +121,7 @@ public:
}
/**
* Function 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;
* @copydoc INSPECTOR::Inspect()
*/
SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
......@@ -162,7 +156,7 @@ public:
* Function IsDraggableJunction
* tests to see if the collected items form a draggable junction.
* <p>
* Daggable juntions are defined as:
* Daggable junctions are defined as:
* <ul>
* <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>
......@@ -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_
......@@ -382,6 +382,9 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
wxString SCH_COMPONENT::GetPath( SCH_SHEET_PATH* sheet )
{
wxCHECK_MSG( sheet != NULL, wxEmptyString,
wxT( "Cannot get component path with invalid sheet object." ) );
wxString str;
str.Printf( wxT( "%8.8lX" ), m_TimeStamp );
......@@ -1533,68 +1536,9 @@ void SCH_COMPONENT::Rotate( wxPoint rotationPoint )
bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
wxPoint* aFindLocation )
{
// Search reference.
// 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;
}
}
}
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
// Components are searchable via the child field and pin item text.
return false;
}
......@@ -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.
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;
}
}
......
......@@ -408,6 +408,11 @@ public:
virtual bool operator <( const SCH_ITEM& aItem ) const;
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
#if defined(DEBUG)
/**
......
......@@ -358,6 +358,11 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint
bool match;
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
// components with multiple parts.
if( m_FieldId == REFERENCE && aAuxData != NULL )
......
......@@ -209,6 +209,11 @@ public:
virtual BITMAP_DEF GetMenuImage() const;
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
private:
virtual bool doHitTest( const wxPoint& aPoint, 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 )
bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_FileName, aSearchData ) )
{
if( aFindLocation )
......@@ -1033,15 +1035,15 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR* aInspector, const void* aTestData,
// If caller wants to inspect my type
if( stype == Type() )
{
if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) )
if( SEARCH_QUIT == aInspector->Inspect( this, NULL ) )
return SEARCH_QUIT;
}
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++ )
{
if( SEARCH_QUIT == aInspector->Inspect( &m_pins[ i ], aTestData ) )
if( SEARCH_QUIT == aInspector->Inspect( &m_pins[ i ], (void*) this ) )
return SEARCH_QUIT;
}
}
......
......@@ -599,6 +599,11 @@ public:
virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
#if defined(DEBUG)
// comment inherited by Doxygen from Base_Struct
......
......@@ -45,9 +45,6 @@
#include "dialogs/dialog_schematic_find.h"
static const wxString traceFindReplace( wxT( "KicadFindReplace" ) );
SCH_SHEET_PATH::SCH_SHEET_PATH()
{
for( int i = 0; i<DSLSZ; i++ )
......@@ -85,6 +82,7 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath
Pop();
}
schitem = schitem->Next();
}
......@@ -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 aSetVisible )
{
......@@ -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,
const wxString& aFootPrint, bool aSetVisible )
{
......
......@@ -33,6 +33,7 @@
#include "base_struct.h"
/** Info about complex hierarchies handling:
* A hierarchical schematic uses sheets (hierarchical sheets) included in a
* given sheet. Each sheet corresponds to a schematic drawing handled by a
......@@ -261,17 +262,6 @@ public:
*/
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 );
bool operator==( const SCH_SHEET_PATH& d1 ) const;
......@@ -439,25 +429,6 @@ public:
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
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
* 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 )
case 'I':
m_Shape = NET_INPUT;
break;
case 'O':
m_Shape = NET_OUTPUT;
break;
case 'B':
m_Shape = NET_BIDI;
break;
case 'T':
m_Shape = NET_TRISTATE;
break;
case 'U':
m_Shape = NET_UNSPECIFIED;
break;
......@@ -380,12 +384,15 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
case 'R' : /* pin on right side */
SetEdge( 1 );
break;
case 'T' : /* pin on top side */
SetEdge( 2 );
break;
case 'B' : /* pin on bottom side */
SetEdge( 3 );
break;
case 'L' : /* pin on left side */
default :
SetEdge( 0 );
......@@ -397,12 +404,17 @@ bool SCH_SHEET_PIN::Load( LINE_READER& aLine, wxString& aErrorMsg )
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( aFindLocation )
*aFindLocation = m_Pos;
*aFindLocation = GetBoundingBox().Centre();
return true;
}
......
......@@ -167,6 +167,8 @@ wxPoint SCH_TEXT::GetSchematicTextOffset() const
bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation )
{
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_Text, aSearchData ) )
{
EDA_RECT BoundaryBox = GetBoundingBox();
......
......@@ -328,6 +328,11 @@ public:
virtual BITMAP_DEF GetMenuImage() const { return add_line_label_xpm; }
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
......
......@@ -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_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
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_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem )
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
......@@ -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( wxID_ANY, SCH_EDIT_FRAME::OnFindSchematicItem )
EVT_FIND_REPLACE( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
EVT_FIND_REPLACE_ALL( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace )
END_EVENT_TABLE()
......@@ -185,12 +186,12 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father,
EDA_DRAW_FRAME( father, SCHEMATIC_FRAME, title, pos, size, style )
{
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_CurrentSheet = new SCH_SHEET_PATH();
m_CurrentSheet = new SCH_SHEET_PATH();
m_TextFieldSize = DEFAULT_SIZE_TEXT;
m_LibeditFrame = NULL; // Component editor frame.
m_ViewlibFrame = NULL; // Frame for browsing component libraries
m_LibeditFrame = NULL; // Component editor frame.
m_ViewlibFrame = NULL; // Frame for browsing component libraries
m_DefaultSchematicFileName = NAMELESS_PROJECT;
m_DefaultSchematicFileName += wxT( ".sch" );
m_ShowAllPins = false;
......@@ -203,6 +204,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father,
m_findReplaceData = new wxFindReplaceData( wxFR_DOWN );
m_undoItem = NULL;
m_hasAutoSave = true;
m_foundItemIndex = 0;
CreateScreens();
......@@ -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,
wxT( "Forgot to create find/replace data. Bad Programmer!" ) );
wxCHECK_RET( m_findReplaceData != NULL,
wxT( "Forgot to create find/replace data. Bad Programmer!" ) );
this->DrawPanel->m_IgnoreMouseEvents = true;
......@@ -661,7 +663,13 @@ void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& event )
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->SetReplaceEntries( m_replaceStringHistoryList );
......
......@@ -77,6 +77,9 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
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( wxID_REPLACE, wxEmptyString, KiBitmap( find_replace_xpm ),
// wxNullBitmap, wxITEM_NORMAL, _( "Find and replace text" ),
// HELP_REPLACE, NULL );
m_HToolBar->AddSeparator();
......
This diff is collapsed.
......@@ -22,6 +22,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_collector.h
* @brief COLLECTOR class definition.
*/
#ifndef COLLECTOR_H
#define COLLECTOR_H
......@@ -51,33 +56,48 @@ class COLLECTOR : public INSPECTOR
{
protected:
/// 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.
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.
wxPoint m_RefPos;
/// A point to test against, and that was used to make the collection.
wxPoint m_RefPos;
/// 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.
int m_TimeAtCollection;
int m_TimeAtCollection;
public:
COLLECTOR()
{
m_ScanTypes = 0;
m_ScanTypes = 0;
}
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
* returns the number of objects in the list
......@@ -108,29 +128,33 @@ public:
m_List.push_back( item );
}
/**
* Function Remove
* removes the item at item_position (first position is 0);
* @param ndx The index into the list.
* removes the item at \a aIndex (first position is 0);
* @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]
* is used for read only access and returns the object at index ndx.
* @param ndx The index into the list.
* is used for read only access and returns the object at \a aIndex.
* @param aIndex The index into the list.
* @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
return m_List[ ndx ];
if( (unsigned)aIndex < (unsigned)GetCount() ) // (unsigned) excludes aIndex<0 also
return m_List[ aIndex ];
return NULL;
}
/**
* Function BasePtr
* returns the address of the first element in the array. Only call this
......@@ -142,6 +166,7 @@ public:
return &m_List[0];
}
/**
* Function HasItem
* tests if \a aItem has already been collected.
......@@ -160,23 +185,26 @@ public:
return false;
}
/**
* Function SetScanTypes
* records the list of KICAD_T types to consider for collection by
* the Inspect() function.
* @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 )
{
m_ScanTypes = scanTypes;
}
void SetTimeNow()
{
m_TimeAtCollection = GetTimeStamp();
}
int GetTime()
{
return m_TimeAtCollection;
......@@ -206,32 +234,13 @@ public:
int dx = abs( aRefPos.x - m_RefPos.x );
int dy = abs( aRefPos.y - m_RefPos.y );
if( dx <= distMax && dy <= distMax
&& GetTimeStamp()-m_TimeAtCollection <= timeMax )
if( dx <= distMax && dy <= distMax && GetTimeStamp()-m_TimeAtCollection <= timeMax )
return true;
else
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
* scans an EDA_ITEM using this class's Inspector method, which does
......@@ -260,4 +269,3 @@ public:
};
#endif // COLLECTOR_H
......@@ -392,7 +392,7 @@ int ReturnValueFromTextCtrl( const wxTextCtrl& TextCtr,
* @param aString is the text to split
* @param aSplitter is the 'split' character
*/
wxArrayString* wxStringSplit( wxString txt, wxChar aSplitter );
wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter );
/**
* Function To_User_Unit
......
......@@ -61,6 +61,10 @@ typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS;
#endif
/// Flag to enable find and replace tracing using the WXTRACE environment variable.
extern const wxString traceFindReplace;
enum DANGLING_END_T {
UNKNOWN = 0,
WIRE_START_END,
......
......@@ -146,12 +146,16 @@ private:
SCH_ITEM* m_itemToRepeat; ///< Last item to insert by the repeat command.
int m_repeatLabelDelta; ///< Repeat label number increment step.
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.
wxString m_simulatorCommand; ///< Command line used to call the circuit
///< simulator (gnucap, spice, ...)
wxString m_netListerCommand; ///< Command line to call a custom net list
///< 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 wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
......
......@@ -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