Commit 175fab48 authored by Wayne Stambaugh's avatar Wayne Stambaugh

EESchema multiple item hit testing and other minor improvements.

* Add item clarification context menu to EESchema when multiple unresolved
  items are found at the current cross hair position.
* Add collector class SCH_COLLECTOR for supporting multiple item hit testing.
* Removed bit wise masked filtering from schematic item hit testing.
* Removed all old hit testing functions and methods scattered about the
  EESchema source code.
* Move terminal point test function into SCH_SCREEN object.
* Fixed bug in terminal point test when terminating a bus to a label.
* Define the < operator for sorting schematic items.
* Add area calculation method to EDA_Rect item.
* Add method for returning an item's bitmap for menu display purposes.
* Add method for returning an item's menu text for menu display purposes.
* Changed EDA_ITEMS container from boost::ptr_vector to std::vector.
* Factor coordinate string conversion code from EDA_DRAW_FRAME to function
  CoordinateToString().
parents 5f6cd454 628f874c
...@@ -125,6 +125,16 @@ SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR* inspector, const void* testData, ...@@ -125,6 +125,16 @@ SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR* inspector, const void* testData,
return SEARCH_CONTINUE; return SEARCH_CONTINUE;
} }
wxString EDA_ITEM::GetSelectMenuText() const
{
wxFAIL_MSG( wxT( "GetSelectMenuText() was not overridden for schematic item type " ) +
GetClass() );
return wxString( wxT( "Undefined menu text for " ) + GetClass() );
}
#if defined(DEBUG) #if defined(DEBUG)
...@@ -637,3 +647,9 @@ void EDA_Rect::Merge( const wxPoint& aPoint ) ...@@ -637,3 +647,9 @@ void EDA_Rect::Merge( const wxPoint& aPoint )
end.y = MAX( end.y, aPoint.y ); end.y = MAX( end.y, aPoint.y );
SetEnd( end ); SetEnd( end );
} }
double EDA_Rect::GetArea() const
{
return (double) GetWidth() * (double) GetHeight();
}
...@@ -708,6 +708,47 @@ const wxString& valeur_param( int valeur, wxString& buf_texte ) ...@@ -708,6 +708,47 @@ const wxString& valeur_param( int valeur, wxString& buf_texte )
} }
wxString CoordinateToString( int aValue, int aInternalUnits, bool aConvertToMils )
{
wxCHECK_MSG( (aInternalUnits == EESCHEMA_INTERNAL_UNIT)
|| (aInternalUnits == PCB_INTERNAL_UNIT),
wxString( _( "*** Bad Internal Units ***" ) ),
wxT( "Invalid interanl units value." ) );
wxString text;
const wxChar* format;
double value = To_User_Unit( g_UserUnit, aValue, aInternalUnits );
if( g_UserUnit == INCHES )
{
if( aConvertToMils )
{
format = ( aInternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.0f" ) : wxT( "%.1f" );
value *= 1000;
}
else
{
format = ( aInternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.3f" ) : wxT( "%.4f" );
}
}
else
{
format = ( aInternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.2f" ) : wxT( "%.3f" );
}
text.Printf( format, value );
if( g_UserUnit == INCHES )
text += ( aConvertToMils ) ? _( " mils" ) : _( " in" );
else
text += _( " mm" );
return text;
}
/* /*
* *
*/ */
......
...@@ -41,7 +41,7 @@ dialog_about::dialog_about(wxWindow *parent, AboutAppInfo& appInfo) ...@@ -41,7 +41,7 @@ dialog_about::dialog_about(wxWindow *parent, AboutAppInfo& appInfo)
CreateNotebooks(); CreateNotebooks();
GetSizer()->SetSizeHints(this); GetSizer()->SetSizeHints(this);
m_auiNotebook->Update(); m_auiNotebook->Update();
SetFocus();
Centre(); Centre();
} }
......
...@@ -808,33 +808,5 @@ void EDA_DRAW_FRAME::ClearMsgPanel( void ) ...@@ -808,33 +808,5 @@ void EDA_DRAW_FRAME::ClearMsgPanel( void )
wxString EDA_DRAW_FRAME::CoordinateToString( int aValue, bool aConvertToMils ) wxString EDA_DRAW_FRAME::CoordinateToString( int aValue, bool aConvertToMils )
{ {
wxString text; return ::CoordinateToString( aValue, m_InternalUnits, aConvertToMils );
const wxChar* format;
double value = To_User_Unit( g_UserUnit, aValue, m_InternalUnits );
if( g_UserUnit == INCHES )
{
if( aConvertToMils )
{
format = ( m_InternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.0f" ) : wxT( "%.1f" );
value *= 1000;
}
else
{
format = ( m_InternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.3f" ) : wxT( "%.4f" );
}
}
else
{
format = ( m_InternalUnits == EESCHEMA_INTERNAL_UNIT ) ? wxT( "%.2f" ) : wxT( "%.3f" );
}
text.Printf( format, value );
if( g_UserUnit == INCHES )
text += ( aConvertToMils ) ? _( " mils" ) : _( " in" );
else
text += _( " mm" );
return text;
} }
...@@ -17,6 +17,12 @@ ...@@ -17,6 +17,12 @@
#include "../eeschema/dialogs/dialog_schematic_find.h" #include "../eeschema/dialogs/dialog_schematic_find.h"
bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 )
{
return *aItem1 < *aItem2;
}
/* Constructor and destructor for SCH_ITEM */ /* Constructor and destructor for SCH_ITEM */
/* They are not inline because this creates problems with gcc at linking time /* They are not inline because this creates problems with gcc at linking time
* in debug mode * in debug mode
...@@ -38,18 +44,18 @@ SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) : ...@@ -38,18 +44,18 @@ SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) :
SCH_ITEM::~SCH_ITEM() SCH_ITEM::~SCH_ITEM()
{ {
// Do not let the connections container go out of scope with any ojbects or they // Do not let the connections container go out of scope with any objects or they
// will be deleted by the container will cause the EESchema to crash. These objects // will be deleted by the container will cause the EESchema to crash. These objects
// are owned by the sheet object container. // are owned by the sheet object container.
if( !m_connections.empty() ) if( !m_connections.empty() )
m_connections.release(); m_connections.clear();
} }
/** /**
* place the struct in m_drawList. * place the struct in m_drawList.
* if it is a new item, it it also put in undo list * if it is a new item, it it also put in undo list
* for an "old" item, saving it in undo list must be done before editiing, * for an "old" item, saving it in undo list must be done before editing,
* and not here! * and not here!
*/ */
void SCH_ITEM::Place( SCH_EDIT_FRAME* aFrame, wxDC* aDC ) void SCH_ITEM::Place( SCH_EDIT_FRAME* aFrame, wxDC* aDC )
...@@ -108,3 +114,10 @@ bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const ...@@ -108,3 +114,10 @@ bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const
return doIsConnected( aPosition ); return doIsConnected( aPosition );
} }
bool SCH_ITEM::operator < ( const SCH_ITEM& aItem ) const
{
wxCHECK_MSG( false, this->Type() < aItem.Type(),
wxT( "Less than operator not defined for " ) + GetClass() );
}
...@@ -425,6 +425,13 @@ int CrossProduct( wxPoint vectorA, wxPoint vectorB ) ...@@ -425,6 +425,13 @@ int CrossProduct( wxPoint vectorA, wxPoint vectorB )
} }
double GetLineLength( const wxPoint& aPointA, const wxPoint& aPointB )
{
return sqrt( pow( (double) aPointA.x - (double) aPointB.x, 2 ) +
pow( (double) aPointA.y - (double) aPointB.y, 2 ) );
}
double fsinus[3600] = double fsinus[3600] =
{ {
0.0000000000, 0.0017453284, 0.0034906514, 0.0052359638, 0.0000000000, 0.0017453284, 0.0034906514, 0.0052359638,
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "wxstruct.h" #include "wxstruct.h"
#include "common.h" #include "common.h"
#include "cvpcb.h" #include "cvpcb.h"
//#include "protos.h"
#include "class_drawpanel.h" #include "class_drawpanel.h"
#include "footprint_info.h" #include "footprint_info.h"
#include "cvstruct.h" #include "cvstruct.h"
...@@ -32,8 +31,8 @@ DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( PCB_BASE_F ...@@ -32,8 +31,8 @@ DIALOG_FOOTPRINTS_DISPLAY_OPTIONS::DIALOG_FOOTPRINTS_DISPLAY_OPTIONS( PCB_BASE_F
m_Parent = parent; m_Parent = parent;
initDialog(); initDialog();
m_sdbSizer1OK->SetDefault();
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
Centre(); Centre();
} }
......
...@@ -104,7 +104,6 @@ set(EESCHEMA_SRCS ...@@ -104,7 +104,6 @@ set(EESCHEMA_SRCS
lib_text.cpp lib_text.cpp
libfield.cpp libfield.cpp
load_one_schematic_file.cpp load_one_schematic_file.cpp
locate.cpp
menubar.cpp menubar.cpp
menubar_libedit.cpp menubar_libedit.cpp
netform.cpp netform.cpp
...@@ -116,6 +115,7 @@ set(EESCHEMA_SRCS ...@@ -116,6 +115,7 @@ set(EESCHEMA_SRCS
pinedit.cpp pinedit.cpp
plot.cpp plot.cpp
sch_bus_entry.cpp sch_bus_entry.cpp
sch_collectors.cpp
sch_component.cpp sch_component.cpp
sch_field.cpp sch_field.cpp
sch_junction.cpp sch_junction.cpp
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC ); static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC );
static bool IsTerminalPoint( SCH_SCREEN* screen, const wxPoint& pos, int layer );
static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos ); static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos );
SCH_ITEM* s_OldWiresList; SCH_ITEM* s_OldWiresList;
...@@ -169,7 +168,7 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type ) ...@@ -169,7 +168,7 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
/* Creates the new segment, or terminates the command /* Creates the new segment, or terminates the command
* if the end point is on a pin, junction or an other wire or bus */ * if the end point is on a pin, junction or an other wire or bus */
if( IsTerminalPoint( GetScreen(), cursorpos, oldsegment->GetLayer() ) ) if( GetScreen()->IsTerminalPoint( cursorpos, oldsegment->GetLayer() ) )
{ {
EndSegment( DC ); EndSegment( DC );
return; return;
...@@ -572,98 +571,3 @@ void IncrementLabelMember( wxString& name ) ...@@ -572,98 +571,3 @@ void IncrementLabelMember( wxString& name )
name.Remove( ii ); name << number; name.Remove( ii ); name << number;
} }
} }
/* Return true if pos can be a terminal point for a wire or a bus
* i.e. :
* for a WIRE, if at pos is found:
* - a junction
* - or a pin
* - or an other wire
*
* - for a BUS, if at pos is found:
* - a BUS
*/
static bool IsTerminalPoint( SCH_SCREEN* screen, const wxPoint& pos, int layer )
{
EDA_ITEM* item;
LIB_PIN* pin;
SCH_COMPONENT* LibItem = NULL;
SCH_SHEET_PIN* pinsheet;
wxPoint itempos;
switch( layer )
{
case LAYER_BUS:
item = screen->GetItem( pos, 0, BUS_T );
if( item )
return true;
pinsheet = screen->GetSheetLabel( pos );
if( pinsheet && IsBusLabel( pinsheet->m_Text ) )
{
itempos = pinsheet->m_Pos;
if( (itempos.x == pos.x) && (itempos.y == pos.y) )
return true;
}
break;
case LAYER_NOTES:
item = screen->GetItem( pos, 0, DRAW_ITEM_T );
if( item )
return true;
break;
case LAYER_WIRE:
item = screen->GetItem( pos, MAX( g_DrawDefaultLineThickness, 3 ),
BUS_ENTRY_T | JUNCTION_T );
if( item )
return true;
pin = screen->GetPin( pos, &LibItem );
if( pin && LibItem )
{
// Calculate the exact position of the connection point of the pin,
// depending on orientation of the component.
itempos = LibItem->GetScreenCoord( pin->GetPosition() );
itempos.x += LibItem->m_Pos.x;
itempos.y += LibItem->m_Pos.y;
if( ( itempos.x == pos.x ) && ( itempos.y == pos.y ) )
return true;
}
item = screen->GetItem( pos, 0, WIRE_T );
if( item )
return true;
item = screen->GetItem( pos, 0, LABEL_T );
if( item && (item->Type() != SCH_TEXT_T)
&& ( ( (SCH_GLOBALLABEL*) item )->m_Pos.x == pos.x )
&& ( ( (SCH_GLOBALLABEL*) item )->m_Pos.y == pos.y ) )
return true;
pinsheet = screen->GetSheetLabel( pos );
if( pinsheet && !IsBusLabel( pinsheet->m_Text ) )
{
itempos = pinsheet->m_Pos;
if( ( itempos.x == pos.x ) && ( itempos.y == pos.y ) )
return true;
}
break;
default:
break;
}
return false;
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "eeschema_id.h" #include "eeschema_id.h"
#include "general.h" #include "general.h"
#include "hotkeys.h"
#include "protos.h" #include "protos.h"
#include "libeditframe.h" #include "libeditframe.h"
#include "viewlib_frame.h" #include "viewlib_frame.h"
...@@ -22,29 +23,8 @@ ...@@ -22,29 +23,8 @@
#include "sch_component.h" #include "sch_component.h"
/** SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
* Function LocateAndShowItem int aHotKeyCommandId )
* search the schematic at \a aPosition in logical (drawing) units for any item.
* <p>
* The search is first performed at \a aPosition which may be off grid. If no item is
* found at \a aPosition, the search is repeated for the nearest grid position to \a
* aPosition.
*
* The search order is as follows:
* <ul>
* <li>Marker</li>
* <li>No Connect</li>
* <li>Junction</li>
* <li>Wire, bus, or entry</li>
* <li>Label</li>
* <li>Pin</li>
* <li>Component</li>
* </ul></p>
* @param aPosition The wxPoint on the schematic to search.
* @param aIncludePin = true to search for pins, false to ignore them
* @return A SCH_ITEM pointer on the item or NULL if no item found
*/
SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aIncludePin )
{ {
SCH_ITEM* item; SCH_ITEM* item;
wxString msg; wxString msg;
...@@ -52,13 +32,26 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc ...@@ -52,13 +32,26 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc
SCH_COMPONENT* LibItem = NULL; SCH_COMPONENT* LibItem = NULL;
wxPoint gridPosition = GetScreen()->GetNearestGridPosition( aPosition ); wxPoint gridPosition = GetScreen()->GetNearestGridPosition( aPosition );
item = LocateItem( aPosition, aIncludePin ); // Check the on grid position first. There is more likely to be multple items on
// grid than off grid.
item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
if( !item && aPosition != gridPosition ) // If the user aborted the clarification context menu, don't show it again at the
item = LocateItem( gridPosition, aIncludePin ); // off grid position.
if( !item && DrawPanel->m_AbortRequest )
{
DrawPanel->m_AbortRequest = false;
return NULL;
}
if( !item && (aPosition != gridPosition) )
item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
if( !item ) if( !item )
{
DrawPanel->m_AbortRequest = false; // Just in case the user aborted the context menu.
return NULL; return NULL;
}
/* Cross probing to pcbnew if a pin or a component is found */ /* Cross probing to pcbnew if a pin or a component is found */
switch( item->Type() ) switch( item->Type() )
...@@ -70,22 +63,16 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc ...@@ -70,22 +63,16 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc
break; break;
case SCH_COMPONENT_T: case SCH_COMPONENT_T:
Pin = GetScreen()->GetPin( GetScreen()->GetCrossHairPosition(), &LibItem );
if( Pin )
break; // Priority is probing a pin first
LibItem = (SCH_COMPONENT*) item; LibItem = (SCH_COMPONENT*) item;
SendMessageToPCBNEW( item, LibItem ); SendMessageToPCBNEW( item, LibItem );
break; break;
default:
Pin = GetScreen()->GetPin( GetScreen()->GetCrossHairPosition(), &LibItem );
break;
case LIB_PIN_T: case LIB_PIN_T:
Pin = (LIB_PIN*) item; Pin = (LIB_PIN*) item;
break; break;
default:
;
} }
if( Pin ) if( Pin )
...@@ -105,134 +92,74 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc ...@@ -105,134 +92,74 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, bool aInc
} }
/** SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
* Function LocateItem int aHotKeyCommandId )
* searches for an item at \a aPosition.
* @param aPosition The wxPoint location where to search.
* @param aIncludePin True to search for pins, false to ignore them.
* @return The SCH_ITEM pointer of the item or NULL if no item found.
*/
SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, bool aIncludePin )
{ {
SCH_ITEM* item; SCH_ITEM* item = NULL;
LIB_PIN* Pin;
SCH_COMPONENT* LibItem;
wxString Text;
wxString msg;
item = GetScreen()->GetItem( aPosition, 0, MARKER_T );
if( item )
{
item->DisplayInfo( this );
return item;
}
item = GetScreen()->GetItem( aPosition, 0, NO_CONNECT_T ); m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
if( item ) if( m_collectedItems.GetCount() == 0 )
{ {
ClearMsgPanel(); ClearMsgPanel();
return item;
} }
else if( m_collectedItems.GetCount() == 1 )
item = GetScreen()->GetItem( aPosition, 0, JUNCTION_T );
if( item )
{ {
ClearMsgPanel(); item = m_collectedItems[0];
return item; GetScreen()->SetCurItem( item );
} }
else
item = GetScreen()->GetItem( aPosition, MAX( g_DrawDefaultLineThickness, 3 ),
WIRE_T | BUS_T | BUS_ENTRY_T );
if( item ) // We have found a wire: Search for a connected pin at the same location
{ {
Pin = GetScreen()->GetPin( aPosition, &LibItem ); // There are certain combinations of items that do not need clarification such as
// a corner were two lines meet or all the items form a junction.
if( Pin ) if( aHotKeyCommandId )
{ {
Pin->DisplayInfo( this ); switch( aHotKeyCommandId )
{
if( LibItem ) case HK_DRAG:
AppendMsgPanel( LibItem->GetRef( GetSheet() ), if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false ) )
LibItem->GetField( VALUE )->m_Text, DARKCYAN ); {
item = m_collectedItems[0];
GetScreen()->SetCurItem( item );
} }
else default:
ClearMsgPanel(); ;
return item;
} }
item = GetScreen()->GetItem( aPosition, 0, DRAW_ITEM_T );
if( item )
{
ClearMsgPanel();
return item;
} }
item = GetScreen()->GetItem( aPosition, 0, FIELD_T ); if( item == NULL )
if( item )
{ {
wxASSERT( item->Type() == SCH_FIELD_T ); wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
wxT( "Select item clarification context menu size limit exceeded." ) );
SCH_FIELD* Field = (SCH_FIELD*) item; wxMenu selectMenu;
LibItem = (SCH_COMPONENT*) Field->GetParent(); wxMenuItem* title = new wxMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ) );
LibItem->DisplayInfo( this );
return item; selectMenu.Append( title );
} selectMenu.AppendSeparator();
item = GetScreen()->GetItem( aPosition, 0, LABEL_T | TEXT_T );
if( item ) for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
{ {
ClearMsgPanel(); wxString text = m_collectedItems[i]->GetSelectMenuText();
return item; const char** xpm = m_collectedItems[i]->GetMenuImage();
ADD_MENUITEM( &selectMenu, ID_SCH_SELECT_ITEM_START + i, text, xpm );
} }
/* search for a pin */ // Set to NULL in case user aborts the clarification context menu.
Pin = GetScreen()->GetPin( aPosition, &LibItem ); GetScreen()->SetCurItem( NULL );
DrawPanel->m_AbortRequest = true; // Changed to false if an item is selected
if( Pin ) PopupMenu( &selectMenu );
{ DrawPanel->MoveCursorToCrossHair();
Pin->DisplayInfo( this ); item = GetScreen()->GetCurItem();
if( LibItem )
AppendMsgPanel( LibItem->GetRef( GetSheet() ),
LibItem->GetField( VALUE )->m_Text, DARKCYAN );
if( aIncludePin )
return LibItem;
} }
item = GetScreen()->GetItem( aPosition, 0, COMPONENT_T );
if( item )
{
item = LocateSmallestComponent( GetScreen() );
LibItem = (SCH_COMPONENT*) item;
LibItem->DisplayInfo( this );
return item;
} }
item = GetScreen()->GetItem( aPosition, 0, SHEET_T );
if( item ) if( item )
{ item->DisplayInfo( this );
( (SCH_SHEET*) item )->DisplayInfo( this ); else
return item; ClearMsgPanel();
}
item = GetScreen()->GetItem( aPosition );
if( item )
return item; return item;
ClearMsgPanel();
return NULL;
} }
......
...@@ -25,6 +25,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection ) ...@@ -25,6 +25,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection )
{ {
SCH_ITEM* item; SCH_ITEM* item;
EDA_ITEM* tmp; EDA_ITEM* tmp;
EDA_ITEMS list;
PICKED_ITEMS_LIST pickList; PICKED_ITEMS_LIST pickList;
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
wxPoint pos = screen->GetCrossHairPosition(); wxPoint pos = screen->GetCrossHairPosition();
...@@ -33,24 +34,19 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection ) ...@@ -33,24 +34,19 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection )
screen->ClearDrawingState(); screen->ClearDrawingState();
screen->BreakSegmentsOnJunctions(); screen->BreakSegmentsOnJunctions();
// Save the list entry point of this screen if( screen->GetNode( pos, list ) == 0 )
SCH_ITEM* savedItems = screen->GetDrawItems(); return;
item = screen->GetDrawItems();
while( item && ( item = screen->GetItem( pos, 0, JUNCTION_T | WIRE_T | BUS_T ) ) != NULL ) for( size_t i = 0; i < list.size(); i++ )
{ {
item = (SCH_ITEM*) list[ i ];
item->SetFlags( SELECTEDNODE | STRUCT_DELETED ); item->SetFlags( SELECTEDNODE | STRUCT_DELETED );
/* Put this structure in the picked list: */ /* Put this structure in the picked list: */
ITEM_PICKER picker( item, UR_DELETED ); ITEM_PICKER picker( item, UR_DELETED );
pickList.PushItem( picker ); pickList.PushItem( picker );
item = item->Next();
screen->SetDrawItems( item );
} }
screen->SetDrawItems( savedItems ); // Restore the list entry point.
/* Mark all wires, junctions, .. connected to one of the item to delete /* Mark all wires, junctions, .. connected to one of the item to delete
*/ */
if( DeleteFullConnection ) if( DeleteFullConnection )
...@@ -172,7 +168,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection ) ...@@ -172,7 +168,7 @@ void SCH_EDIT_FRAME::DeleteConnection( bool DeleteFullConnection )
if( item->Type() != SCH_LABEL_T ) if( item->Type() != SCH_LABEL_T )
continue; continue;
tmp = screen->GetItem( ( (SCH_TEXT*) item )->m_Pos, 0, WIRE_T | BUS_T ); tmp = screen->GetWireOrBus( ( (SCH_TEXT*) item )->m_Pos );
if( tmp && tmp->GetFlags() & STRUCT_DELETED ) if( tmp && tmp->GetFlags() & STRUCT_DELETED )
{ {
...@@ -199,42 +195,23 @@ bool SCH_EDIT_FRAME::DeleteItemAtCrossHair( wxDC* DC ) ...@@ -199,42 +195,23 @@ bool SCH_EDIT_FRAME::DeleteItemAtCrossHair( wxDC* DC )
{ {
SCH_ITEM* item; SCH_ITEM* item;
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
bool item_deleted = false;
item = screen->GetItem( screen->GetCrossHairPosition(), 0, MARKER_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, JUNCTION_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, NO_CONNECT_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, BUS_ENTRY_T );
if( item == NULL ) item = LocateItem( screen->GetCrossHairPosition(), SCH_COLLECTOR::ParentItems );
item = screen->GetItem( screen->GetCrossHairPosition(), 0, WIRE_T | BUS_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, DRAW_ITEM_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, TEXT_T | LABEL_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, COMPONENT_T );
if( item == NULL )
item = screen->GetItem( screen->GetCrossHairPosition(), 0, SHEET_T );
if( item ) if( item )
{ {
bool itemHasConnections = item->IsConnectable();
GetScreen()->SetCurItem( NULL );
SetRepeatItem( NULL ); SetRepeatItem( NULL );
DeleteItem( item ); DeleteItem( item );
if( itemHasConnections )
screen->TestDanglingEnds( DrawPanel, DC ); screen->TestDanglingEnds( DrawPanel, DC );
OnModify(); OnModify();
item_deleted = true; return true;
} }
return item_deleted; return false;
} }
...@@ -77,13 +77,17 @@ void DialogLabelEditor::InitDialog() ...@@ -77,13 +77,17 @@ void DialogLabelEditor::InitDialog()
break; break;
case SCH_HIERARCHICAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T:
SetTitle( _( "Hierarchal Label Properties" ) ); SetTitle( _( "Hierarchical Label Properties" ) );
break; break;
case SCH_LABEL_T: case SCH_LABEL_T:
SetTitle( _( "Label Properties" ) ); SetTitle( _( "Label Properties" ) );
break; break;
case SCH_SHEET_LABEL_T:
SetTitle( _( "Hierarchical Sheet Pin Properties." ) );
break;
default: default:
SetTitle( _( "Text Properties" ) ); SetTitle( _( "Text Properties" ) );
m_textLabel->Disconnect( wxEVT_COMMAND_TEXT_ENTER, m_textLabel->Disconnect( wxEVT_COMMAND_TEXT_ENTER,
......
...@@ -80,98 +80,91 @@ void SCH_EDIT_FRAME::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC ) ...@@ -80,98 +80,91 @@ void SCH_EDIT_FRAME::StartMoveCmpField( SCH_FIELD* aField, wxDC* DC )
/* /*
* Edit a field: text and size * Edit a field: text and size
*/ */
void SCH_EDIT_FRAME::EditCmpFieldText( SCH_FIELD* Field, wxDC* DC ) void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField, wxDC* aDC )
{ {
wxCHECK_RET( aField != NULL && aField->Type() == SCH_FIELD_T,
wxT( "Invalid schemaitic field type. " ) );
int fieldNdx, flag; int fieldNdx, flag;
LIB_COMPONENT* Entry; SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
if( Field == NULL ) wxCHECK_RET( component != NULL && component->Type() == SCH_COMPONENT_T,
{ wxT( "Invalid schematic field parent item." ) );
DisplayError( this, _( "No Field To Edit" ), 10 );
return;
}
SCH_COMPONENT* Cmp = (SCH_COMPONENT*) Field->GetParent(); LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() );
fieldNdx = Field->m_FieldId; wxCHECK_RET( entry != NULL, wxT( "Library entry for component <" ) +
component->GetLibName() + wxT( "> could not be found." ) );
if( fieldNdx == VALUE ) fieldNdx = aField->GetId();
{
Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() );
if( Entry && Entry->IsPower() ) if( fieldNdx == VALUE && entry->IsPower() )
{ {
DisplayInfoMessage( this, _( "Part is a POWER, value cannot be \ DisplayInfoMessage( this, _( "The component is a POWER, it's value cannot be \
modified!\nYou must create a new power" ) ); modified!\n\nYou must create a new power component with the value." ) );
return; return;
} }
}
flag = 0; flag = 0;
if( fieldNdx == REFERENCE )
{
Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() );
if( Entry != NULL ) if( fieldNdx == REFERENCE && entry->GetPartCount() > 1 )
{
if( Entry->GetPartCount() > 1 )
flag = 1; flag = 1;
}
}
/* save old cmp in undo list if not already in edit, or moving ... */ /* save old cmp in undo list if not already in edit, or moving ... */
if( Field->m_Flags == 0 ) if( aField->GetFlags() == 0 )
SaveCopyInUndoList( Cmp, UR_CHANGED ); SaveCopyInUndoList( component, UR_CHANGED );
wxString newtext = Field->m_Text; wxString newtext = aField->m_Text;
DrawPanel->m_IgnoreMouseEvents = TRUE; DrawPanel->m_IgnoreMouseEvents = true;
wxString title = _( "Field: " ) + Field->m_Name; wxString title = _( "Field " ) + aField->m_Name;
wxTextEntryDialog dlg( this, wxEmptyString , title, newtext ); wxTextEntryDialog dlg( this, wxEmptyString , title, newtext );
int diag = dlg.ShowModal(); int diag = dlg.ShowModal();
DrawPanel->MoveCursorToCrossHair();
DrawPanel->m_IgnoreMouseEvents = false;
newtext = dlg.GetValue( ); newtext = dlg.GetValue( );
newtext.Trim( true ); newtext.Trim( true );
newtext.Trim( false ); newtext.Trim( false );
DrawPanel->MoveCursorToCrossHair(); if ( diag != wxID_OK || newtext == aField->GetText() )
DrawPanel->m_IgnoreMouseEvents = FALSE;
if ( diag != wxID_OK )
return; // cancelled by user return; // cancelled by user
Field->m_AddExtraText = flag; aField->m_AddExtraText = flag;
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), g_XorMode ); aField->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
if( !newtext.IsEmpty() ) if( !newtext.IsEmpty() )
{ {
if( Field->m_Text.IsEmpty() ) if( aField->m_Text.IsEmpty() )
{ {
Field->m_Pos = Cmp->m_Pos; aField->m_Pos = component->m_Pos;
Field->m_Size.x = Field->m_Size.y = m_TextFieldSize; aField->m_Size.x = aField->m_Size.y = m_TextFieldSize;
} }
Field->m_Text = newtext;
aField->m_Text = newtext;
if( fieldNdx == REFERENCE ) if( fieldNdx == REFERENCE )
{ {
Cmp->SetRef( GetSheet(), newtext ); component->SetRef( GetSheet(), newtext );
} }
} }
else else
{ {
if( fieldNdx == REFERENCE ) if( fieldNdx == REFERENCE )
{ {
DisplayError( this, _( "Reference needed !, No change" ) ); DisplayError( this, _( "The reference field cannot be empty! No change" ) );
} }
else if( fieldNdx == VALUE ) else if( fieldNdx == VALUE )
{ {
DisplayError( this, _( "Value needed !, No change" ) ); DisplayError( this, _( "The value field cannot be empty! No change" ) );
} }
else else
{ {
Field->m_Text = wxT( "~" ); aField->m_Text = wxT( "~" );
} }
} }
Field->Draw( DrawPanel, DC, wxPoint( 0, 0 ), g_XorMode ); aField->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
Cmp->DisplayInfo( this ); component->DisplayInfo( this );
OnModify(); OnModify();
} }
...@@ -284,12 +277,12 @@ void SCH_EDIT_FRAME::RotateCmpField( SCH_FIELD* Field, wxDC* DC ) ...@@ -284,12 +277,12 @@ void SCH_EDIT_FRAME::RotateCmpField( SCH_FIELD* Field, wxDC* DC )
/****************************************************************************/ /****************************************************************************/
void SCH_EDIT_FRAME::EditComponentReference( SCH_COMPONENT* Cmp, wxDC* DC ) void SCH_EDIT_FRAME::EditComponentReference( SCH_COMPONENT* Cmp, wxDC* DC )
{ {
wxCHECK_RET( Cmp != NULL && Cmp->Type() == SCH_COMPONENT_T,
wxT( "Invalid schematic component item." ) );
LIB_COMPONENT* Entry; LIB_COMPONENT* Entry;
int flag = 0; int flag = 0;
if( Cmp == NULL )
return;
Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() ); Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() );
if( Entry == NULL ) if( Entry == NULL )
...@@ -331,12 +324,12 @@ void SCH_EDIT_FRAME::EditComponentReference( SCH_COMPONENT* Cmp, wxDC* DC ) ...@@ -331,12 +324,12 @@ void SCH_EDIT_FRAME::EditComponentReference( SCH_COMPONENT* Cmp, wxDC* DC )
/*****************************************************************************/ /*****************************************************************************/
void SCH_EDIT_FRAME::EditComponentValue( SCH_COMPONENT* Cmp, wxDC* DC ) void SCH_EDIT_FRAME::EditComponentValue( SCH_COMPONENT* Cmp, wxDC* DC )
{ {
wxCHECK_RET( Cmp != NULL && Cmp->Type() == SCH_COMPONENT_T,
wxT( "Invalid schematic component item." ) );
wxString message; wxString message;
LIB_COMPONENT* Entry; LIB_COMPONENT* Entry;
if( Cmp == NULL )
return;
Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() ); Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() );
if( Entry == NULL ) if( Entry == NULL )
...@@ -373,12 +366,12 @@ void SCH_EDIT_FRAME::EditComponentValue( SCH_COMPONENT* Cmp, wxDC* DC ) ...@@ -373,12 +366,12 @@ void SCH_EDIT_FRAME::EditComponentValue( SCH_COMPONENT* Cmp, wxDC* DC )
void SCH_EDIT_FRAME::EditComponentFootprint( SCH_COMPONENT* Cmp, wxDC* DC ) void SCH_EDIT_FRAME::EditComponentFootprint( SCH_COMPONENT* Cmp, wxDC* DC )
{ {
wxCHECK_RET( Cmp != NULL && Cmp->Type() == SCH_COMPONENT_T,
wxT( "Invalid schematic component item." ) );
wxString message; wxString message;
LIB_COMPONENT* Entry; LIB_COMPONENT* Entry;
if( Cmp == NULL )
return;
Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() ); Entry = CMP_LIBRARY::FindLibraryComponent( Cmp->GetLibName() );
if( Entry == NULL ) if( Entry == NULL )
......
...@@ -78,19 +78,7 @@ void SCH_EDIT_FRAME::StartMoveTexte( SCH_TEXT* aTextItem, wxDC* aDC ) ...@@ -78,19 +78,7 @@ void SCH_EDIT_FRAME::StartMoveTexte( SCH_TEXT* aTextItem, wxDC* aDC )
void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC ) void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC )
{ {
if( aTextItem == NULL ) wxCHECK_RET( aTextItem != NULL, wxT( "Invalid schematic text item." ) );
aTextItem = (SCH_TEXT*) GetScreen()->GetItem( GetScreen()->GetCrossHairPosition(), 0,
TEXT_T | LABEL_T );
if( aTextItem == NULL )
return;
/* save old text in undo list if is not already in edit */
if( aTextItem->GetFlags() == 0 )
SaveCopyInUndoList( aTextItem, UR_CHANGED );
/* Erase old text */
DrawPanel->CrossHairOff( aDC );
aTextItem->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
int orient; int orient;
...@@ -100,15 +88,22 @@ void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC ) ...@@ -100,15 +88,22 @@ void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem, wxDC* aDC )
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T:
case SCH_TEXT_T: case SCH_TEXT_T:
orient = aTextItem->GetOrientation() + 1; orient = ( aTextItem->GetOrientation() + 1 ) & 3;
orient &= 3;
aTextItem->SetOrientation( orient );
break; break;
default: default:
break; wxFAIL_MSG( wxT( "Invalid schematic item <" ) + aTextItem->GetClass() +
wxT( "> passed to SCH_EDIT_FRAME::ChangeTextOrient()" ) );
return;
} }
// Save current text orientation in undo list if is not already in edit.
if( aTextItem->GetFlags() == 0 )
SaveCopyInUndoList( aTextItem, UR_CHANGED );
DrawPanel->CrossHairOff( aDC );
aTextItem->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
aTextItem->SetOrientation( orient );
OnModify(); OnModify();
aTextItem->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode ); aTextItem->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
DrawPanel->CrossHairOn( aDC ); DrawPanel->CrossHairOn( aDC );
......
...@@ -4,6 +4,15 @@ ...@@ -4,6 +4,15 @@
#include "id.h" #include "id.h"
/**
* The maximum number of items in the clarify selection context menu. It is
* highly unlikely that there would ever be more than 10 items at the current
* cursor. Increase this number if that ever becomes a problem.
*/
#define MAX_SELECT_ITEM_IDS 10
/** /**
* Command IDs for the schematic editor. * Command IDs for the schematic editor.
* *
...@@ -138,6 +147,9 @@ enum id_eeschema_frm ...@@ -138,6 +147,9 @@ enum id_eeschema_frm
ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE, ID_POPUP_SCH_ROTATE_CMP_COUNTERCLOCKWISE,
ID_POPUP_SCH_ORIENT_NORMAL_CMP, ID_POPUP_SCH_ORIENT_NORMAL_CMP,
ID_SCH_SELECT_ITEM_START,
ID_SCH_SELECT_ITEM_END = ID_SCH_SELECT_ITEM_START + MAX_SELECT_ITEM_IDS,
// Schematic editor commmands. These are command IDs that are generated by multiple // Schematic editor commmands. These are command IDs that are generated by multiple
// events (menus, toolbar, context menu, etc.) that result in the same event handler. // events (menus, toolbar, context menu, etc.) that result in the same event handler.
ID_CANCEL_CURRENT_COMMAND, ID_CANCEL_CURRENT_COMMAND,
......
...@@ -247,18 +247,12 @@ static void ShowWhileMoving( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& a ...@@ -247,18 +247,12 @@ static void ShowWhileMoving( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& a
void SCH_EDIT_FRAME::OnChangeComponentOrientation( wxCommandEvent& aEvent ) void SCH_EDIT_FRAME::OnChangeComponentOrientation( wxCommandEvent& aEvent )
{ {
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
SCH_ITEM* item = screen->GetCurItem();
// Ensure the struct is a component (could be a struct of a wxCHECK_RET( item != NULL && item->Type() == SCH_COMPONENT_T,
// component, like Field, text..) wxT( "Cannot change orientation of invalid schematic item." ) );
if( screen->GetCurItem() == NULL || screen->GetCurItem()->Type() != SCH_COMPONENT_T )
{
screen->SetCurItem( LocateSmallestComponent( screen ) );
if( screen->GetCurItem() == NULL || screen->GetCurItem()->Type() != SCH_COMPONENT_T )
return;
}
SCH_COMPONENT* component = (SCH_COMPONENT*) screen->GetCurItem(); SCH_COMPONENT* component = (SCH_COMPONENT*) item;
int orientation; int orientation;
...@@ -287,8 +281,8 @@ void SCH_EDIT_FRAME::OnChangeComponentOrientation( wxCommandEvent& aEvent ) ...@@ -287,8 +281,8 @@ void SCH_EDIT_FRAME::OnChangeComponentOrientation( wxCommandEvent& aEvent )
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
if( screen->GetCurItem()->GetFlags() == 0 ) if( component->GetFlags() == 0 )
SaveCopyInUndoList( screen->GetCurItem(), UR_CHANGED ); SaveCopyInUndoList( item, UR_CHANGED );
INSTALL_UNBUFFERED_DC( dc, DrawPanel ); INSTALL_UNBUFFERED_DC( dc, DrawPanel );
...@@ -348,28 +342,16 @@ static void ExitPlaceCmp( EDA_DRAW_PANEL* Panel, wxDC* DC ) ...@@ -348,28 +342,16 @@ static void ExitPlaceCmp( EDA_DRAW_PANEL* Panel, wxDC* DC )
void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
{ {
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
SCH_ITEM* item = screen->GetCurItem();
if( screen->GetCurItem() == NULL ) wxCHECK_RET( item != NULL && item->Type() == SCH_COMPONENT_T,
return; wxT( "Cannot select unit of invalid schematic item." ) );
INSTALL_UNBUFFERED_DC( dc, DrawPanel ); INSTALL_UNBUFFERED_DC( dc, DrawPanel );
// Verify the selected item is a component, it may be part of a component such as a field
// or text item.
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T )
{
screen->SetCurItem( LocateSmallestComponent( screen ) );
if( screen->GetCurItem() == NULL )
return;
}
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
SCH_COMPONENT* component = (SCH_COMPONENT*) screen->GetCurItem(); SCH_COMPONENT* component = (SCH_COMPONENT*) item;
wxCHECK_RET( (component != NULL) && (component->Type() == SCH_COMPONENT_T),
wxT( "Cannot select unit for invalid component." ) );
int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1; int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1;
...@@ -414,7 +396,7 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) ...@@ -414,7 +396,7 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
else else
component->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); component->Draw( DrawPanel, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
GetScreen()->TestDanglingEnds( DrawPanel, &dc ); screen->TestDanglingEnds( DrawPanel, &dc );
OnModify(); OnModify();
} }
......
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "drawtxt.h" #include "drawtxt.h"
#include "plot_common.h" #include "plot_common.h"
#include "wxEeschemaStruct.h" #include "wxEeschemaStruct.h"
#include "bitmaps.h"
#include "general.h" #include "general.h"
#include "protos.h" #include "protos.h"
...@@ -18,8 +19,8 @@ ...@@ -18,8 +19,8 @@
#include "class_libentry.h" #include "class_libentry.h"
#include "lib_pin.h" #include "lib_pin.h"
#include "transform.h" #include "transform.h"
#include "sch_component.h"
#include "bitmaps.h"
/** /**
* Note: The following name lists are sentence capitalized per the GNOME UI * Note: The following name lists are sentence capitalized per the GNOME UI
...@@ -1875,6 +1876,20 @@ const char*** LIB_PIN::GetStyleSymbols() ...@@ -1875,6 +1876,20 @@ const char*** LIB_PIN::GetStyleSymbols()
return s_icons_Pins_Shapes; return s_icons_Pins_Shapes;
} }
const char** LIB_PIN::GetMenuImage() const
{
return s_icons_Pins_Electrical_Type[m_type];
}
wxString LIB_PIN::GetSelectMenuText() const
{
wxString tmp = _( "Pin " );
return tmp << GetNumberString() << wxT( ", " ) << GetTypeString() << wxT( ", " )
<< wxGetTranslation( pin_style_names[ GetStyleCodeIndex( m_shape ) ] );;
}
#if defined(DEBUG) #if defined(DEBUG)
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "lib_draw_item.h" #include "lib_draw_item.h"
class SCH_COMPONENT;
#define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of pins */ #define TARGET_PIN_DIAM 12 /* Circle diameter drawn at the active end of pins */
...@@ -134,12 +136,15 @@ public: ...@@ -134,12 +136,15 @@ public:
virtual bool Save( FILE* aFile ); virtual bool Save( FILE* aFile );
virtual bool Load( char* aLine, wxString& aErrorMsg ); virtual bool Load( char* aLine, wxString& aErrorMsg );
/** /**
* Test if the given point is within the bounds of this object. * Function HitTest
* * verifies that \a aRefPos within the bounds of this pin attached to \a aComponent.
* <p>
* The coordinates of the pin are calculated relative to \a aComponent if not NULL.
* Otherwise, the pin coordinates are relative to the library anchor position.
* </p>
* @param aRefPos A wxPoint to test * @param aRefPos A wxPoint to test
* @return - true if a hit, else false * @return True \a aRefPos lies within the pin bounding box else false.
*/ */
virtual bool HitTest( const wxPoint& aRefPos ); virtual bool HitTest( const wxPoint& aRefPos );
...@@ -445,6 +450,10 @@ public: ...@@ -445,6 +450,10 @@ public:
*/ */
static const char*** GetElectricalTypeSymbols(); static const char*** GetElectricalTypeSymbols();
virtual const char** GetMenuImage() const;
virtual wxString GetSelectMenuText() const;
protected: protected:
virtual LIB_DRAW_ITEM* DoGenCopy(); virtual LIB_DRAW_ITEM* DoGenCopy();
......
/******************************************************/
/* Routines for locating an element of a schematic. */
/******************************************************/
#include "fctsys.h"
#include "common.h"
#include "trigo.h"
#include "macros.h"
#include "class_sch_screen.h"
#include "general.h"
#include "protos.h"
#include "class_library.h"
#include "sch_bus_entry.h"
#include "sch_marker.h"
#include "sch_junction.h"
#include "sch_component.h"
#include "sch_line.h"
#include "sch_no_connect.h"
#include "sch_polyline.h"
#include "sch_sheet.h"
#include "lib_pin.h"
#include "template_fieldnames.h"
/**
* Search the smaller (considering its area) component under the mouse
* cursor or the pcb cursor
*
* If more than 1 component is found, a pointer to the smaller component is
* returned
*/
SCH_COMPONENT* LocateSmallestComponent( SCH_SCREEN* Screen )
{
double area = 0.0; // Quiet compiler
EDA_Rect rect;
PICKED_ITEMS_LIST itemList;
SCH_COMPONENT* component = NULL;
SCH_COMPONENT* lastcomponent = NULL;
if( Screen->GetItems( Screen->RefPos( true ), itemList, COMPONENT_T ) == 0 )
{
if( Screen->GetItems( Screen->GetCrossHairPosition(), itemList, COMPONENT_T ) == 0 )
return NULL;
}
if( itemList.GetCount() == 1 )
return (SCH_COMPONENT*) itemList.GetPickedItem( 0 );
for( size_t i = 0; i < itemList.GetCount(); i++ )
{
component = (SCH_COMPONENT*) itemList.GetPickedItem( i );
if( lastcomponent == NULL ) // First component
{
lastcomponent = component;
rect = lastcomponent->GetBoundingBox();
area = ABS( (double) rect.GetWidth() * (double) rect.GetHeight() );
}
else
{
rect = component->GetBoundingBox();
double tmp = ABS( (double) rect.GetWidth() * (double) rect.GetHeight() );
if( area > tmp ) // a smaller component is found
{
area = tmp;
lastcomponent = component;
}
}
}
return lastcomponent;
}
...@@ -80,9 +80,9 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -80,9 +80,9 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) ) if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) )
break; break;
item = LocateAndShowItem( aPosition ); item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsOnly );
if( item && ( item->Type() == SCH_SHEET_T ) ) if( item )
{ {
m_CurrentSheet->Push( (SCH_SHEET*) item ); m_CurrentSheet->Push( (SCH_SHEET*) item );
DisplayCurrentSheet(); DisplayCurrentSheet();
...@@ -241,7 +241,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -241,7 +241,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
case ID_IMPORT_HLABEL_BUTT: case ID_IMPORT_HLABEL_BUTT:
case ID_SHEET_LABEL_BUTT: case ID_SHEET_LABEL_BUTT:
if( ( item == NULL ) || ( item->GetFlags() == 0 ) ) if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
item = LocateAndShowItem( aPosition ); item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsAndSheetLabels );
if( item == NULL ) if( item == NULL )
break; break;
...@@ -345,7 +345,7 @@ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -345,7 +345,7 @@ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
break; break;
case SCH_FIELD_T: case SCH_FIELD_T:
EditCmpFieldText( (SCH_FIELD*) item, aDC ); EditComponentFieldText( (SCH_FIELD*) item, aDC );
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
break; break;
......
...@@ -50,7 +50,7 @@ static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_ ...@@ -50,7 +50,7 @@ static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_
*/ */
bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
{ {
SCH_ITEM* DrawStruct = (SCH_ITEM*) GetScreen()->GetCurItem(); SCH_ITEM* item = GetScreen()->GetCurItem();
bool BlockActive = GetScreen()->IsBlockActive(); bool BlockActive = GetScreen()->IsBlockActive();
// Do not start a block command on context menu. // Do not start a block command on context menu.
...@@ -64,24 +64,22 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -64,24 +64,22 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
} }
// Try to locate items at cursor position. // Try to locate items at cursor position.
if( (DrawStruct == NULL) || (DrawStruct->GetFlags() == 0) ) if( (item == NULL) || (item->GetFlags() == 0) )
{ {
DrawStruct = LocateAndShowItem( aPosition, false ); item = LocateAndShowItem( aPosition, SCH_COLLECTOR::AllItemsButPins );
if( DrawStruct && (DrawStruct->Type() == SCH_SHEET_T) ) // If the clarify item selection context menu is aborted, don't show the context menu.
if( item == NULL && DrawPanel->m_AbortRequest )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) DrawStruct; DrawPanel->m_AbortRequest = false;
SCH_SHEET_PIN* slabel = sheet->GetLabel( GetScreen()->GetCrossHairPosition() ); return false;
if( slabel )
DrawStruct = slabel;
} }
} }
// If Command in progress: add "cancel" and "end tool" menu // If Command in progress: add "cancel" and "end tool" menu
if( GetToolId() != ID_NO_TOOL_SELECTED ) if( GetToolId() != ID_NO_TOOL_SELECTED )
{ {
if( DrawStruct && DrawStruct->GetFlags() ) if( item && item->GetFlags() )
{ {
ADD_MENUITEM( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), cancel_xpm ); ADD_MENUITEM( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), cancel_xpm );
} }
...@@ -93,29 +91,25 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -93,29 +91,25 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
} }
else else
{ {
if( DrawStruct && DrawStruct->GetFlags() ) if( item && item->GetFlags() )
{ {
ADD_MENUITEM( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), cancel_xpm ); ADD_MENUITEM( PopMenu, ID_CANCEL_CURRENT_COMMAND, _( "Cancel" ), cancel_xpm );
PopMenu->AppendSeparator(); PopMenu->AppendSeparator();
} }
} }
if( DrawStruct == NULL ) if( item == NULL )
{ {
if( GetSheet()->Last() != g_RootSheet ) if( GetSheet()->Last() != g_RootSheet )
{
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, _( "Leave Sheet" ), leave_sheet_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, _( "Leave Sheet" ), leave_sheet_xpm );
PopMenu->AppendSeparator(); PopMenu->AppendSeparator();
}
return true; return true;
} }
GetScreen()->SetCurItem( DrawStruct ); int flags = item->GetFlags();
bool is_new = (flags & IS_NEW) ? true : false;
int flags = DrawStruct->GetFlags();
bool is_new = (flags & IS_NEW) ? TRUE : FALSE;
switch( DrawStruct->Type() ) switch( item->Type() )
{ {
case SCH_NO_CONNECT_T: case SCH_NO_CONNECT_T:
...@@ -123,7 +117,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -123,7 +117,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
break; break;
case SCH_JUNCTION_T: case SCH_JUNCTION_T:
AddMenusForJunction( PopMenu, (SCH_JUNCTION*) DrawStruct, this ); AddMenusForJunction( PopMenu, (SCH_JUNCTION*) item, this );
break; break;
case SCH_BUS_ENTRY_T: case SCH_BUS_ENTRY_T:
...@@ -134,7 +128,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -134,7 +128,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_xpm );
} }
if( GetBusEntryShape( (SCH_BUS_ENTRY*) DrawStruct ) == '\\' ) if( GetBusEntryShape( (SCH_BUS_ENTRY*) item ) == '\\' )
PopMenu->Append( ID_POPUP_SCH_ENTRY_SELECT_SLASH, _( "Set Bus Entry /" ) ); PopMenu->Append( ID_POPUP_SCH_ENTRY_SELECT_SLASH, _( "Set Bus Entry /" ) );
else else
PopMenu->Append( ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH, _( "Set Bus Entry \\" ) ); PopMenu->Append( ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH, _( "Set Bus Entry \\" ) );
...@@ -142,57 +136,42 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -142,57 +136,42 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
break; break;
case SCH_MARKER_T: case SCH_MARKER_T:
AddMenusForMarkers( PopMenu, (SCH_MARKER*) DrawStruct, this ); AddMenusForMarkers( PopMenu, (SCH_MARKER*) item, this );
break; break;
case SCH_TEXT_T: case SCH_TEXT_T:
AddMenusForText( PopMenu, (SCH_TEXT*) DrawStruct ); AddMenusForText( PopMenu, (SCH_TEXT*) item );
break; break;
case SCH_LABEL_T: case SCH_LABEL_T:
AddMenusForLabel( PopMenu, (SCH_LABEL*) DrawStruct ); AddMenusForLabel( PopMenu, (SCH_LABEL*) item );
break; break;
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
AddMenusForGLabel( PopMenu, (SCH_GLOBALLABEL*) DrawStruct ); AddMenusForGLabel( PopMenu, (SCH_GLOBALLABEL*) item );
break; break;
case SCH_HIERARCHICAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T:
AddMenusForHLabel( PopMenu, (SCH_HIERLABEL*) DrawStruct ); AddMenusForHLabel( PopMenu, (SCH_HIERLABEL*) item );
break; break;
case SCH_FIELD_T: case SCH_FIELD_T:
{ AddMenusForComponentField( PopMenu, (SCH_FIELD*) item );
AddMenusForComponentField( PopMenu, (SCH_FIELD*) DrawStruct );
if( flags )
break;
// Many fields are inside a component. If this is the case, add the
// component menu
SCH_COMPONENT* Component = LocateSmallestComponent( GetScreen() );
if( Component )
{
PopMenu->AppendSeparator();
AddMenusForComponent( PopMenu, Component );
}
}
break; break;
case SCH_COMPONENT_T: case SCH_COMPONENT_T:
AddMenusForComponent( PopMenu, (SCH_COMPONENT*) DrawStruct ); AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item );
break; break;
case SCH_LINE_T: case SCH_LINE_T:
switch( DrawStruct->GetLayer() ) switch( item->GetLayer() )
{ {
case LAYER_WIRE: case LAYER_WIRE:
AddMenusForWire( PopMenu, (SCH_LINE*) DrawStruct, this ); AddMenusForWire( PopMenu, (SCH_LINE*) item, this );
break; break;
case LAYER_BUS: case LAYER_BUS:
AddMenusForBus( PopMenu, (SCH_LINE*) DrawStruct, this ); AddMenusForBus( PopMenu, (SCH_LINE*) item, this );
break; break;
default: default:
...@@ -204,17 +183,17 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) ...@@ -204,17 +183,17 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
break; break;
case SCH_SHEET_T: case SCH_SHEET_T:
AddMenusForHierchicalSheet( PopMenu, (SCH_SHEET*) DrawStruct ); AddMenusForHierchicalSheet( PopMenu, (SCH_SHEET*) item );
break; break;
case SCH_SHEET_LABEL_T: case SCH_SHEET_LABEL_T:
AddMenusForPinSheet( PopMenu, (SCH_SHEET_PIN*) DrawStruct ); AddMenusForPinSheet( PopMenu, (SCH_SHEET_PIN*) item );
break; break;
default: default:
wxString msg; wxString msg;
msg.Printf( wxT( "SCH_EDIT_FRAME::OnRightClick Error: unknown DrawType %d" ), msg.Printf( wxT( "SCH_EDIT_FRAME::OnRightClick Error: unknown DrawType %d" ),
DrawStruct->Type() ); item->Type() );
DisplayError( this, msg ); DisplayError( this, msg );
break; break;
} }
...@@ -495,15 +474,14 @@ void AddMenusForJunction( wxMenu* PopMenu, SCH_JUNCTION* Junction, SCH_EDIT_FRAM ...@@ -495,15 +474,14 @@ void AddMenusForJunction( wxMenu* PopMenu, SCH_JUNCTION* Junction, SCH_EDIT_FRAM
if( !is_new ) if( !is_new )
{ {
if( screen->GetItem( screen->GetCrossHairPosition(), 0, if( screen->GetWire( screen->GetCrossHairPosition(), EXCLUDE_END_POINTS_T ) )
WIRE_T | BUS_T | EXCLUDE_ENDPOINTS_T ) )
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm );
} }
msg = AddHotkeyName( _( "Delete Junction" ), s_Schematic_Hokeys_Descr, HK_DELETE ); msg = AddHotkeyName( _( "Delete Junction" ), s_Schematic_Hokeys_Descr, HK_DELETE );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE, msg, delete_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE, msg, delete_xpm );
if( screen->GetItem( screen->GetCrossHairPosition(), 0, WIRE_T | BUS_T ) ) if( screen->GetWireOrBus( screen->GetCrossHairPosition() ) )
{ {
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ), delete_node_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ), delete_node_xpm );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ), ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ),
...@@ -534,8 +512,9 @@ void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame ) ...@@ -534,8 +512,9 @@ void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame )
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ), ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ),
delete_connection_xpm ); delete_connection_xpm );
if( screen->GetItem( screen->GetCrossHairPosition(), 0, SCH_LINE* line = screen->GetWireOrBus( screen->GetCrossHairPosition() );
WIRE_T | BUS_T | EXCLUDE_ENDPOINTS_T ) )
if( line && !line->IsEndPoint( screen->GetCrossHairPosition() ) )
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm );
PopMenu->AppendSeparator(); PopMenu->AppendSeparator();
......
...@@ -67,12 +67,6 @@ void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList ); ...@@ -67,12 +67,6 @@ void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList );
*/ */
SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct, bool aClone = false ); SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct, bool aClone = false );
/*************/
/* LOCATE.CPP */
/*************/
SCH_COMPONENT* LocateSmallestComponent( SCH_SCREEN* Screen );
/***************/ /***************/
/* EEREDRAW.CPP */ /* EEREDRAW.CPP */
......
...@@ -224,11 +224,17 @@ void SCH_BUS_ENTRY::GetConnectionPoints( vector< wxPoint >& aPoints ) const ...@@ -224,11 +224,17 @@ void SCH_BUS_ENTRY::GetConnectionPoints( vector< wxPoint >& aPoints ) const
} }
bool SCH_BUS_ENTRY::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_BUS_ENTRY::GetSelectMenuText() const
{ {
if( !( aFilter & BUS_ENTRY_T ) ) if( m_Layer == LAYER_WIRE )
return false; return wxString( _( "Bus to Wire Entry" ) );
return wxString( _( "Bus to Bus Entry" ) );
}
bool SCH_BUS_ENTRY::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TestSegmentHit( aPoint, m_Pos, m_End(), aAccuracy ); return TestSegmentHit( aPoint, m_Pos, m_End(), aAccuracy );
} }
......
...@@ -107,8 +107,12 @@ public: ...@@ -107,8 +107,12 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_entry_xpm; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 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
*/
#include "general.h"
#include "transform.h"
#include "sch_collectors.h"
#include "sch_component.h"
#include "sch_line.h"
const KICAD_T SCH_COLLECTOR::AllItems[] = {
SCH_MARKER_T,
SCH_JUNCTION_T,
SCH_NO_CONNECT_T,
SCH_BUS_ENTRY_T,
SCH_LINE_T,
SCH_POLYLINE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T,
LIB_PIN_T,
SCH_SHEET_LABEL_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::AllItemsButPins[] = {
SCH_MARKER_T,
SCH_JUNCTION_T,
SCH_NO_CONNECT_T,
SCH_BUS_ENTRY_T,
SCH_LINE_T,
SCH_POLYLINE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T,
SCH_SHEET_LABEL_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::EditableItems[] = {
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T,
SCH_SHEET_LABEL_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::MovableItems[] = {
SCH_MARKER_T,
// SCH_JUNCTION_T,
SCH_NO_CONNECT_T,
SCH_BUS_ENTRY_T,
// SCH_LINE_T,
SCH_POLYLINE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T,
SCH_SHEET_LABEL_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::DraggableItems[] = {
SCH_JUNCTION_T,
SCH_BUS_ENTRY_T,
SCH_LINE_T,
SCH_POLYLINE_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_COMPONENT_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::RotatableItems[] = {
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T,
EOT
};
const KICAD_T SCH_COLLECTOR::ParentItems[] = {
SCH_MARKER_T,
SCH_JUNCTION_T,
SCH_NO_CONNECT_T,
SCH_BUS_ENTRY_T,
SCH_LINE_T,
SCH_POLYLINE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T,
SCH_COMPONENT_T,
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::ComponentsOnly[] = {
SCH_COMPONENT_T,
EOT
};
const KICAD_T SCH_COLLECTOR::SheetsOnly[] = {
SCH_SHEET_T,
EOT
};
const KICAD_T SCH_COLLECTOR::SheetsAndSheetLabels[] = {
SCH_SHEET_LABEL_T,
SCH_SHEET_T,
EOT
};
SEARCH_RESULT SCH_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
{
if( aItem->Type() != LIB_PIN_T && !aItem->HitTest( m_RefPos ) )
return SEARCH_CONTINUE;
// Pins have special hit testing requirements that are relative to their parent
// SCH_COMPONENT item.
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().InverseTransform();
wxPoint position = transform.TransformCoordinate( m_RefPos - component->m_Pos );
position.y *= -1; // Y axis polarity in schematic is inverted from library.
if( !aItem->HitTest( position ) )
return SEARCH_CONTINUE;
}
Append( aItem );
return SEARCH_CONTINUE;
}
void SCH_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[],
const wxPoint& aPosition )
{
Empty(); // empty the collection just in case
SetScanTypes( aFilterList );
// remember where the snapshot was taken from and pass refPos to the Inspect() function.
SetRefPos( aPosition );
EDA_ITEM::IterateForward( aItem, this, NULL, m_ScanTypes );
}
bool SCH_COLLECTOR::IsCorner() const
{
if( GetCount() != 2 )
return false;
if( (m_List[0]->Type() == SCH_LINE_T) && (m_List[1]->Type() == SCH_LINE_T) )
return true;
if( (m_List[0]->Type() == SCH_LINE_T) && (m_List[1]->Type() == SCH_BUS_ENTRY_T) )
return true;
if( (m_List[0]->Type() == SCH_BUS_ENTRY_T) && (m_List[1]->Type() == SCH_LINE_T) )
return true;
return false;
}
bool SCH_COLLECTOR::IsNode( bool aIncludePins ) const
{
for( size_t i = 0; i < m_List.size(); i++ )
{
SCH_ITEM* item = (SCH_ITEM*) m_List[ i ];
KICAD_T type = item->Type();
if( type == SCH_JUNCTION_T )
continue;
if( type == SCH_LINE_T )
{
if( item->GetLayer() != LAYER_WIRE )
return false;
continue;
}
if( type == LIB_PIN_T )
{
if( !aIncludePins )
return false;
continue;
}
// Any other item types indicate that this collection is not a node.
return false;
}
return true;
}
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-20011 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
*/
#ifndef _SCH_COLLECTORS_H_
#define _SCH_COLLECTORS_H_
#include "class_collector.h"
#include "sch_item_struct.h"
/**
* Class SCH_COLLECTOR
*/
class SCH_COLLECTOR : public COLLECTOR
{
public:
/**
* A scan list for all schematic items.
*/
static const KICAD_T AllItems[];
/**
* A scan list for all editable schematic items.
*/
static const KICAD_T EditableItems[];
/**
* A scan list for all movable schematic items.
*/
static const KICAD_T MovableItems[];
/**
* A scan list for all draggable schematic items.
*/
static const KICAD_T DraggableItems[];
/**
* A scan list for all rotatable schematic items.
*/
static const KICAD_T RotatableItems[];
/**
* A scan list for only parent schematic items.
*/
static const KICAD_T ParentItems[];
/**
* A scan list for all schematic items except pins.
*/
static const KICAD_T AllItemsButPins[];
/**
* A scan list for schematic component items only.
*/
static const KICAD_T ComponentsOnly[];
/**
* A scan list for schematic sheet items only.
*/
static const KICAD_T SheetsOnly[];
/**
* A scan list for schematic sheet and sheet label items.
*/
static const KICAD_T SheetsAndSheetLabels[];
/**
* Constructor SCH_COLLECTOR
*/
SCH_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems )
{
SetScanTypes( aScanTypes );
}
/**
* Operator []
* overloads COLLECTOR::operator[](int) to return a SCH_ITEM* instead of
* an EDA_ITEM* type.
* @param aIndex The index into the list.
* @return SCH_ITEM* at \a aIndex or NULL.
*/
SCH_ITEM* operator[]( int aIndex ) const
{
if( (unsigned)aIndex < (unsigned)GetCount() )
return (SCH_ITEM*) m_List[ aIndex ];
return NULL;
}
/**
* 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;
*/
SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL );
/**
* Function Collect
* scans a SCH_ITEM using this class's Inspector method, which does the collection.
* @param aItem A SCH_ITEM to scan.
* @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
* what is to be collected and the priority order of the resulting
* collection.
* @param aPosition A wxPoint to use in hit-testing.
*/
void Collect( SCH_ITEM* aItem, const KICAD_T aScanList[], const wxPoint& aPositiion );
/**
* Function IsCorner
* tests if the collected items forms as corner of two line segments.
* @return True if the collected items form a corner of two line segments.
*/
bool IsCorner() const;
/**
* Function IsNode
* tests if the collected items form a node.
*
* @param aIncludePins Indicate if component pin items should be included in the test.
* @return True if the collected items form a node.
*/
bool IsNode( bool aIncludePins = true ) const;
};
#endif // _SCH_COLLECTORS_H_
...@@ -326,22 +326,6 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath, ...@@ -326,22 +326,6 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
} }
wxString SCH_COMPONENT::ReturnFieldName( int aFieldNdx ) const
{
SCH_FIELD* field = GetField( aFieldNdx );
if( field )
{
if( !field->m_Name.IsEmpty() )
return field->m_Name;
else
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aFieldNdx );
}
return wxEmptyString;
}
wxString SCH_COMPONENT::GetPath( SCH_SHEET_PATH* sheet ) wxString SCH_COMPONENT::GetPath( SCH_SHEET_PATH* sheet )
{ {
wxString str; wxString str;
...@@ -865,7 +849,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) ...@@ -865,7 +849,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os )
{ {
// for now, make it look like XML: // for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
<< " ref=\"" << TO_UTF8( ReturnFieldName( 0 ) ) << " ref=\"" << TO_UTF8( GetField( 0 )->GetName() )
<< '"' << " chipName=\"" << '"' << " chipName=\""
<< TO_UTF8( m_ChipName ) << '"' << m_Pos << TO_UTF8( m_ChipName ) << '"' << m_Pos
<< " layer=\"" << m_Layer << " layer=\"" << m_Layer
...@@ -879,7 +863,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) ...@@ -879,7 +863,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os )
if( !value.IsEmpty() ) if( !value.IsEmpty() )
{ {
NestedSpace( nestLevel + 1, os ) << "<field" << " name=\"" NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
<< TO_UTF8( ReturnFieldName( i ) ) << TO_UTF8( GetField( i )->GetName() )
<< '"' << " value=\"" << '"' << " value=\""
<< TO_UTF8( value ) << "\"/>\n"; << TO_UTF8( value ) << "\"/>\n";
} }
...@@ -1405,18 +1389,7 @@ EDA_Rect SCH_COMPONENT::GetBodyBoundingBox() const ...@@ -1405,18 +1389,7 @@ EDA_Rect SCH_COMPONENT::GetBodyBoundingBox() const
EDA_Rect SCH_COMPONENT::GetBoundingBox() const EDA_Rect SCH_COMPONENT::GetBoundingBox() const
{ {
EDA_Rect bBox = GetBodyBoundingBox(); return GetBodyBoundingBox();
// Include BoundingBoxes of fields if they are visible and not empty.
for( int ii = 0; ii < GetFieldCount(); ii++ )
{
if( !GetField( ii )->IsVisible() || GetField( ii )->IsVoid() )
continue;
bBox.Merge( GetField( ii )->GetBoundingBox() );
}
return bBox;
} }
...@@ -1672,34 +1645,88 @@ LIB_DRAW_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aTy ...@@ -1672,34 +1645,88 @@ LIB_DRAW_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aTy
} }
bool SCH_COMPONENT::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_COMPONENT::GetSelectMenuText() const
{ {
EDA_Rect bBox; wxString tmp = _( "Component " );
return tmp << m_ChipName << wxT( ", " ) << GetField( REFERENCE )->GetText();
}
if( aFilter & FIELD_T ) SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData,
const KICAD_T aFilterTypes[] )
{
KICAD_T stype;
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
{
// If caller wants to inspect component type or and component children types.
if( stype == Type() )
{
if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) )
return SEARCH_QUIT;
}
else if( stype == SCH_FIELD_T )
{ {
// 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( !GetField( ii )->IsVisible() || GetField( ii )->IsVoid() ) if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), aTestData ) )
continue; return SEARCH_QUIT;
}
}
else if( stype == LIB_PIN_T )
{
LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( m_ChipName );
bBox = GetField( ii )->GetBoundingBox(); if( component != NULL )
bBox.Inflate( aAccuracy ); {
LIB_PIN_LIST pins;
if( bBox.Contains( aPoint ) ) component->GetPins( pins, m_unit, m_convert );
return true;
for( size_t i = 0; i < pins.size(); i++ )
{
if( SEARCH_QUIT == aInspector->Inspect( pins[ i ], (void*) this ) )
return SEARCH_QUIT;
}
}
} }
} }
if( aFilter & COMPONENT_T ) return SEARCH_CONTINUE;
{ }
bBox = GetBodyBoundingBox();
bool SCH_COMPONENT::operator <( const SCH_ITEM& aItem ) const
{
if( Type() != aItem.Type() )
return Type() < aItem.Type();
SCH_COMPONENT* component = (SCH_COMPONENT*) &aItem;
EDA_Rect rect = GetBodyBoundingBox();
if( rect.GetArea() != component->GetBodyBoundingBox().GetArea() )
return rect.GetArea() < component->GetBodyBoundingBox().GetArea();
if( m_Pos.x != component->m_Pos.x )
return m_Pos.x < component->m_Pos.x;
if( m_Pos.y != component->m_Pos.y )
return m_Pos.y < component->m_Pos.y;
return false;
}
bool SCH_COMPONENT::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
EDA_Rect bBox = GetBodyBoundingBox();
bBox.Inflate( aAccuracy ); bBox.Inflate( aAccuracy );
if( bBox.Contains( aPoint ) ) if( bBox.Contains( aPoint ) )
return true; return true;
}
return false; return false;
} }
......
...@@ -193,13 +193,6 @@ public: ...@@ -193,13 +193,6 @@ public:
//-----<Fields>----------------------------------------------------------- //-----<Fields>-----------------------------------------------------------
/**
* Function ReturnFieldName
* returns the Field name given a field index like (REFERENCE, VALUE ..)
* @return wxString - the field name or wxEmptyString if invalid field index.
*/
wxString ReturnFieldName( int aFieldNdx ) const;
/** /**
* Function GetField * Function GetField
* returns a field. * returns a field.
...@@ -353,6 +346,9 @@ public: ...@@ -353,6 +346,9 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
/** /**
* Function GetDrawItem(). * Function GetDrawItem().
* Return the component library item at \a aPosition that is part of this component. * Return the component library item at \a aPosition that is part of this component.
...@@ -362,6 +358,13 @@ public: ...@@ -362,6 +358,13 @@ public:
* @return A pointer to the component library object if found, otherwise NULL. * @return A pointer to the component library object if found, otherwise NULL.
*/ */
LIB_DRAW_ITEM* GetDrawItem( const wxPoint& aPosition, KICAD_T aType = TYPE_NOT_INIT ); LIB_DRAW_ITEM* GetDrawItem( const wxPoint& aPosition, KICAD_T aType = TYPE_NOT_INIT );
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_component_xpm; }
virtual bool operator <( const SCH_ITEM& aItem ) const;
#if defined(DEBUG) #if defined(DEBUG)
/** /**
...@@ -376,7 +379,7 @@ public: ...@@ -376,7 +379,7 @@ public:
#endif #endif
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual bool doIsConnected( const wxPoint& aPosition ) const; virtual bool doIsConnected( const wxPoint& aPosition ) const;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
......
...@@ -447,10 +447,42 @@ void SCH_FIELD::Rotate( wxPoint rotationPoint ) ...@@ -447,10 +447,42 @@ void SCH_FIELD::Rotate( wxPoint rotationPoint )
} }
bool SCH_FIELD::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_FIELD::GetSelectMenuText() const
{
wxString tmp = _( "Field " );
return tmp + GetName();
}
wxString SCH_FIELD::GetName() const
{
if( !m_Name.IsEmpty() )
return m_Name;
else
return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_FieldId );
}
const char** SCH_FIELD::GetMenuImage() const
{
if( m_FieldId == REFERENCE )
return (const char**) edit_comp_ref_xpm;
if( m_FieldId == VALUE )
return (const char**) edit_comp_value_xpm;
if( m_FieldId == FOOTPRINT )
return (const char**) edit_comp_footprint_xpm;
return (const char**) edit_text_xpm;
}
bool SCH_FIELD::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{ {
// Do not hit test hidden or empty fields. // Do not hit test hidden or empty fields.
if( !(aFilter & FIELD_T) || !IsVisible() || IsVoid() ) if( !IsVisible() || IsVoid() )
return false; return false;
EDA_Rect rect = GetBoundingBox(); EDA_Rect rect = GetBoundingBox();
...@@ -464,7 +496,7 @@ bool SCH_FIELD::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aF ...@@ -464,7 +496,7 @@ bool SCH_FIELD::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aF
bool SCH_FIELD::doHitTest( const EDA_Rect& aRect, bool aContained, int aAccuracy ) const bool SCH_FIELD::doHitTest( const EDA_Rect& aRect, bool aContained, int aAccuracy ) const
{ {
// Do not hit test hidden fields. // Do not hit test hidden fields.
if( !IsVisible() ) if( !IsVisible() || IsVoid() )
return false; return false;
EDA_Rect rect = aRect; EDA_Rect rect = aRect;
......
...@@ -50,6 +50,16 @@ public: ...@@ -50,6 +50,16 @@ public:
return wxT( "SCH_FIELD" ); return wxT( "SCH_FIELD" );
} }
/**
* Function GetName
* returns the field name. If the field name is emply, the default field name is
* returned. Field names are VALUE, REFERENCE, etc.
* @return The name of the field.
*/
wxString GetName() const;
int GetId() const { return m_FieldId; }
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ); void Place( SCH_EDIT_FRAME* frame, wxDC* DC );
EDA_Rect GetBoundingBox() const; EDA_Rect GetBoundingBox() const;
...@@ -161,10 +171,14 @@ public: ...@@ -161,10 +171,14 @@ public:
* @return True if this field text matches the search criteria. * @return True if this field text matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData,
void* aAuxData, wxPoint * aFindLocation ); void* aAuxData, wxPoint* aFindLocation );
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const;
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
...@@ -177,11 +177,8 @@ void SCH_JUNCTION::Show( int nestLevel, std::ostream& os ) ...@@ -177,11 +177,8 @@ void SCH_JUNCTION::Show( int nestLevel, std::ostream& os )
#endif #endif
bool SCH_JUNCTION::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const bool SCH_JUNCTION::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{ {
if( !( aFilter & JUNCTION_T ) )
return false;
EDA_Rect rect = GetBoundingBox(); EDA_Rect rect = GetBoundingBox();
rect.Inflate( aAccuracy ); rect.Inflate( aAccuracy );
......
...@@ -91,12 +91,16 @@ public: ...@@ -91,12 +91,16 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual wxString GetSelectMenuText() const { return wxString( _( "Junction" ) ); }
virtual const char** GetMenuImage() const { return (const char**) add_junction_xpm; }
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
#endif #endif
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual bool doIsConnected( const wxPoint& aPosition ) const; virtual bool doIsConnected( const wxPoint& aPosition ) const;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
......
...@@ -108,6 +108,12 @@ EDA_Rect SCH_LINE::GetBoundingBox() const ...@@ -108,6 +108,12 @@ EDA_Rect SCH_LINE::GetBoundingBox() const
} }
double SCH_LINE::GetLength() const
{
return GetLineLength( m_Start, m_End );
}
bool SCH_LINE::Save( FILE* aFile ) const bool SCH_LINE::Save( FILE* aFile ) const
{ {
bool success = true; bool success = true;
...@@ -411,31 +417,75 @@ void SCH_LINE::GetConnectionPoints( vector< wxPoint >& aPoints ) const ...@@ -411,31 +417,75 @@ void SCH_LINE::GetConnectionPoints( vector< wxPoint >& aPoints ) const
} }
bool SCH_LINE::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_LINE::GetSelectMenuText() const
{ {
if( !( aFilter & ( DRAW_ITEM_T | WIRE_T | BUS_T ) ) ) wxString menuText;
return false;
if( ( ( aFilter & DRAW_ITEM_T ) && ( m_Layer == LAYER_NOTES ) ) switch( m_Layer )
|| ( ( aFilter & WIRE_T ) && ( m_Layer == LAYER_WIRE ) )
|| ( ( aFilter & BUS_T ) && ( m_Layer == LAYER_BUS ) ) )
{ {
if( !TestSegmentHit( aPoint, m_Start, m_End, aAccuracy ) ) case LAYER_NOTES:
return false; menuText = _( "Graphic Line " );
break;
if( ( aFilter & EXCLUDE_ENDPOINTS_T ) && IsEndPoint( aPoint ) ) case LAYER_WIRE:
return false; menuText = _( "Wire " );
break;
if( ( aFilter & ENDPOINTS_ONLY_T ) && !IsEndPoint( aPoint ) ) case LAYER_BUS:
return false; menuText = _( "Bus " );
break;
return true; default:
menuText = _( "Line on Unkown Layer " );
} }
menuText << wxT( "from (" ) << CoordinateToString( m_Start.x, EESCHEMA_INTERNAL_UNIT )
<< wxT( "," ) << CoordinateToString( m_Start.y, EESCHEMA_INTERNAL_UNIT )
<< wxT( ")" );
menuText << wxT( " to (" ) << CoordinateToString( m_End.x, EESCHEMA_INTERNAL_UNIT )
<< wxT( "," ) << CoordinateToString( m_End.y, EESCHEMA_INTERNAL_UNIT ) << wxT( ")" );
return menuText;
}
const char** SCH_LINE::GetMenuImage() const
{
if( m_Layer == LAYER_NOTES )
return (const char**) add_dashed_line_xpm;
else if( m_Layer == LAYER_WIRE )
return (const char**) add_line_xpm;
return (const char**) add_bus_xpm;
}
bool SCH_LINE::operator <( const SCH_ITEM& aItem ) const
{
if( Type() != aItem.Type() )
return Type() < aItem.Type();
SCH_LINE* line = (SCH_LINE*) &aItem;
if( GetLength() != line->GetLength() )
return GetLength() < line->GetLength();
if( m_Start.x != line->m_Start.x )
return m_Start.x < line->m_Start.x;
if( m_Start.y != line->m_Start.y )
return m_Start.y < line->m_Start.y;
return false; return false;
} }
bool SCH_LINE::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TestSegmentHit( aPoint, m_Start, m_End, aAccuracy );
}
bool SCH_LINE::doHitTest( const EDA_Rect& aRect, bool aContained, int aAccuracy ) const bool SCH_LINE::doHitTest( const EDA_Rect& aRect, bool aContained, int aAccuracy ) const
{ {
EDA_Rect rect = aRect; EDA_Rect rect = aRect;
......
...@@ -54,6 +54,12 @@ public: ...@@ -54,6 +54,12 @@ public:
*/ */
EDA_Rect GetBoundingBox() const; EDA_Rect GetBoundingBox() const;
/**
* Function GetLength
* @return The length of the line segment.
*/
double GetLength() const;
virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, virtual void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
int aDrawMode, int aColor = -1 ); int aDrawMode, int aColor = -1 );
...@@ -127,12 +133,18 @@ public: ...@@ -127,12 +133,18 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const;
virtual bool operator <( const SCH_ITEM& aItem ) const;
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const; void Show( int nestLevel, std::ostream& os ) const;
#endif #endif
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual bool doIsConnected( const wxPoint& aPosition ) const; virtual bool doIsConnected( const wxPoint& aPosition ) const;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
......
...@@ -195,11 +195,8 @@ bool SCH_MARKER::IsSelectStateChanged( const wxRect& aRect ) ...@@ -195,11 +195,8 @@ bool SCH_MARKER::IsSelectStateChanged( const wxRect& aRect )
} }
bool SCH_MARKER::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const bool SCH_MARKER::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{ {
if( !( aFilter & MARKER_T ) )
return false;
return HitTestMarker( aPoint ); return HitTestMarker( aPoint );
} }
...@@ -97,12 +97,16 @@ public: ...@@ -97,12 +97,16 @@ public:
virtual bool IsSelectStateChanged( const wxRect& aRect ); virtual bool IsSelectStateChanged( const wxRect& aRect );
virtual wxString GetSelectMenuText() const { return wxString( _( "ERC Marker" ) ); }
virtual const char** GetMenuImage() const { return (const char**) erc_xpm; }
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
#endif #endif
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
...@@ -157,11 +157,8 @@ bool SCH_NO_CONNECT::doIsConnected( const wxPoint& aPosition ) const ...@@ -157,11 +157,8 @@ bool SCH_NO_CONNECT::doIsConnected( const wxPoint& aPosition ) const
return m_Pos == aPosition; return m_Pos == aPosition;
} }
bool SCH_NO_CONNECT::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const bool SCH_NO_CONNECT::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{ {
if( !( aFilter & NO_CONNECT_T ) )
return false;
int delta = ( ( m_Size.x + g_DrawDefaultLineThickness ) / 2 ) + aAccuracy; int delta = ( ( m_Size.x + g_DrawDefaultLineThickness ) / 2 ) + aAccuracy;
wxPoint dist = aPoint - m_Pos; wxPoint dist = aPoint - m_Pos;
......
...@@ -94,9 +94,13 @@ public: ...@@ -94,9 +94,13 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual wxString GetSelectMenuText() const { return wxString( _( "No Connect" ) ); }
virtual const char** GetMenuImage() const { return (const char**) noconn_button; }
private: private:
virtual bool doIsConnected( const wxPoint& aPosition ) const; virtual bool doIsConnected( const wxPoint& aPosition ) const;
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
...@@ -205,11 +205,47 @@ void SCH_POLYLINE::Rotate( wxPoint rotationPoint ) ...@@ -205,11 +205,47 @@ void SCH_POLYLINE::Rotate( wxPoint rotationPoint )
} }
bool SCH_POLYLINE::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_POLYLINE::GetSelectMenuText() const
{ {
if( !( aFilter & ( DRAW_ITEM_T | WIRE_T | BUS_T ) ) ) wxString menuText;
return false;
switch( m_Layer )
{
case LAYER_NOTES:
menuText = _( "Graphic Polyline " );
break;
case LAYER_WIRE:
menuText = _( "Polyline Wire " );
break;
case LAYER_BUS:
menuText = _( "Polyline Bus " );
break;
default:
menuText = _( "Polyline on Unkown Layer " );
}
menuText += wxString::Format( _( "with %d Points" ), m_PolyPoints.size() );
return menuText;
}
const char** SCH_POLYLINE::GetMenuImage() const
{
if( m_Layer == LAYER_NOTES )
return (const char**) add_dashed_line_xpm;
else if( m_Layer == LAYER_WIRE )
return (const char**) add_line_xpm;
return (const char**) add_bus_xpm;
}
bool SCH_POLYLINE::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
for( size_t i = 0; i < m_PolyPoints.size() - 1; i++ ) for( size_t i = 0; i < m_PolyPoints.size() - 1; i++ )
{ {
if( TestSegmentHit( aPoint, m_PolyPoints[i], m_PolyPoints[i + 1], aAccuracy ) ) if( TestSegmentHit( aPoint, m_PolyPoints[i], m_PolyPoints[i + 1], aAccuracy ) )
......
...@@ -94,8 +94,12 @@ public: ...@@ -94,8 +94,12 @@ public:
virtual void Rotate( wxPoint rotationPoint ); virtual void Rotate( wxPoint rotationPoint );
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const;
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
This diff is collapsed.
...@@ -965,11 +965,42 @@ void SCH_SHEET::GetConnectionPoints( vector< wxPoint >& aPoints ) const ...@@ -965,11 +965,42 @@ void SCH_SHEET::GetConnectionPoints( vector< wxPoint >& aPoints ) const
} }
bool SCH_SHEET::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR* aInspector, const void* aTestData,
const KICAD_T aFilterTypes[] )
{ {
if( !( aFilter & SHEET_T ) ) KICAD_T stype;
return false;
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
{
// If caller wants to inspect my type
if( stype == Type() )
{
if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) )
return SEARCH_QUIT;
}
else if( stype == SCH_SHEET_LABEL_T )
{
// Test the bounding boxes of sheet labels.
for( size_t i = 0; i < m_labels.size(); i++ )
{
if( SEARCH_QUIT == aInspector->Inspect( &m_labels[ i ], aTestData ) )
return SEARCH_QUIT;
}
}
}
return SEARCH_CONTINUE;
}
wxString SCH_SHEET::GetSelectMenuText() const
{
return wxString( _( "Hierarchical Sheet " ) ) + m_SheetName;
}
bool SCH_SHEET::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
EDA_Rect rect = GetBoundingBox(); EDA_Rect rect = GetBoundingBox();
rect.Inflate( aAccuracy ); rect.Inflate( aAccuracy );
......
...@@ -49,6 +49,8 @@ private: ...@@ -49,6 +49,8 @@ private:
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
public: public:
SCH_SHEET_PIN( SCH_SHEET* parent, SCH_SHEET_PIN( SCH_SHEET* parent,
const wxPoint& pos = wxPoint( 0, 0 ), const wxPoint& pos = wxPoint( 0, 0 ),
...@@ -77,8 +79,7 @@ public: ...@@ -77,8 +79,7 @@ public:
* @param aCorner_list = a buffer to fill with polygon corners coordinates * @param aCorner_list = a buffer to fill with polygon corners coordinates
* @param aPos = Position of the shape * @param aPos = Position of the shape
*/ */
virtual void CreateGraphicShape( std::vector <wxPoint>& aCorner_list, virtual void CreateGraphicShape( std::vector <wxPoint>& aCorner_list, const wxPoint& aPos );
const wxPoint& aPos );
void SwapData( SCH_SHEET_PIN* copyitem ); void SwapData( SCH_SHEET_PIN* copyitem );
...@@ -184,6 +185,10 @@ public: ...@@ -184,6 +185,10 @@ public:
virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ); virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsConnectable() const { return true; } virtual bool IsConnectable() const { return true; }
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_hierar_pin_xpm; }
}; };
...@@ -486,13 +491,13 @@ public: ...@@ -486,13 +491,13 @@ public:
* Function GetSheetNamePosition * Function GetSheetNamePosition
* @return the position of the anchor of sheet name text * @return the position of the anchor of sheet name text
*/ */
wxPoint GetSheetNamePosition (); wxPoint GetSheetNamePosition();
/** /**
* Function GetFileNamePosition * Function GetFileNamePosition
* @return the position of the anchor of filename text * @return the position of the anchor of filename text
*/ */
wxPoint GetFileNamePosition (); wxPoint GetFileNamePosition();
virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ); virtual void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList );
...@@ -506,6 +511,16 @@ public: ...@@ -506,6 +511,16 @@ public:
virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const; virtual void GetConnectionPoints( vector< wxPoint >& aPoints ) const;
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const
{
return (const char**) add_hierarchical_subsheet_xpm;
}
#if defined(DEBUG) #if defined(DEBUG)
// comment inherited by Doxygen from Base_Struct // comment inherited by Doxygen from Base_Struct
...@@ -525,7 +540,7 @@ protected: ...@@ -525,7 +540,7 @@ protected:
void renumberLabels(); void renumberLabels();
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
...@@ -459,6 +459,22 @@ void SCH_SHEET_PIN::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) ...@@ -459,6 +459,22 @@ void SCH_SHEET_PIN::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
} }
wxString SCH_SHEET_PIN::GetSelectMenuText() const
{
return wxString( _( "Hierarchical Sheet Label " ) ) + GetText();
}
bool SCH_SHEET_PIN::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
EDA_Rect rect = GetBoundingBox();
rect.Inflate( aAccuracy );
return rect.Contains( aPoint );
}
#if defined(DEBUG) #if defined(DEBUG)
void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os ) void SCH_SHEET_PIN::Show( int nestLevel, std::ostream& os )
......
...@@ -620,11 +620,20 @@ EDA_Rect SCH_TEXT::GetBoundingBox() const ...@@ -620,11 +620,20 @@ EDA_Rect SCH_TEXT::GetBoundingBox() const
} }
bool SCH_TEXT::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_TEXT::GetSelectMenuText() const
{ {
if( !( aFilter & TEXT_T ) ) wxString tmp = GetText();
return false; tmp.Replace( wxT( "\n" ), wxT( " " ) );
tmp.Replace( wxT( "\r" ), wxT( " " ) );
tmp.Replace( wxT( "\t" ), wxT( " " ) );
tmp =( tmp.Length() > 15 ) ? tmp.Left( 12 ) + wxT( "..." ) : tmp;
return wxString( _( "Graphic Text " ) ) + tmp;
}
bool SCH_TEXT::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TextHitTest( aPoint, aAccuracy ); return TextHitTest( aPoint, aAccuracy );
} }
...@@ -846,11 +855,16 @@ EDA_Rect SCH_LABEL::GetBoundingBox() const ...@@ -846,11 +855,16 @@ EDA_Rect SCH_LABEL::GetBoundingBox() const
} }
bool SCH_LABEL::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_LABEL::GetSelectMenuText() const
{ {
if( !( aFilter & LABEL_T ) ) wxString tmp = ( GetText().Length() > 15 ) ? GetText().Left( 12 ) + wxT( "..." ) : GetText();
return false;
return wxString( _( "Label " ) ) + tmp;
}
bool SCH_LABEL::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TextHitTest( aPoint, aAccuracy ); return TextHitTest( aPoint, aAccuracy );
} }
...@@ -1272,11 +1286,16 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox() const ...@@ -1272,11 +1286,16 @@ EDA_Rect SCH_GLOBALLABEL::GetBoundingBox() const
} }
bool SCH_GLOBALLABEL::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_GLOBALLABEL::GetSelectMenuText() const
{ {
if( !( aFilter & LABEL_T ) ) wxString tmp = ( GetText().Length() > 15 ) ? GetText().Left( 12 ) + wxT( "..." ) : GetText();
return false;
return wxString( _( "Global Label " ) ) + tmp;
}
bool SCH_GLOBALLABEL::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TextHitTest( aPoint, aAccuracy ); return TextHitTest( aPoint, aAccuracy );
} }
...@@ -1622,10 +1641,15 @@ void SCH_HIERLABEL::Rotate( wxPoint rotationPoint ) ...@@ -1622,10 +1641,15 @@ void SCH_HIERLABEL::Rotate( wxPoint rotationPoint )
} }
bool SCH_HIERLABEL::doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const wxString SCH_HIERLABEL::GetSelectMenuText() const
{ {
if( !( aFilter & LABEL_T ) ) wxString tmp = ( GetText().Length() > 15 ) ? GetText().Left( 12 ) + wxT( "..." ) : GetText();
return false;
return wxString( _( "Hierarchical Label " ) ) + tmp;
}
bool SCH_HIERLABEL::doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
return TextHitTest( aPoint, aAccuracy ); return TextHitTest( aPoint, aAccuracy );
} }
...@@ -202,12 +202,16 @@ public: ...@@ -202,12 +202,16 @@ public:
virtual bool CanIncrementLabel() const { return true; } virtual bool CanIncrementLabel() const { return true; }
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_text_xpm; }
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
#endif #endif
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) 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;
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
...@@ -292,8 +296,13 @@ public: ...@@ -292,8 +296,13 @@ public:
virtual bool IsConnectable() const { return true; } virtual bool IsConnectable() const { return true; }
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_line_label_xpm; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
...@@ -391,8 +400,13 @@ public: ...@@ -391,8 +400,13 @@ public:
virtual bool IsConnectable() const { return true; } virtual bool IsConnectable() const { return true; }
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_glabel_xpm; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
...@@ -492,8 +506,13 @@ public: ...@@ -492,8 +506,13 @@ public:
virtual bool IsConnectable() const { return true; } virtual bool IsConnectable() const { return true; }
virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) add_hierarchical_label_xpm; }
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const; virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const;
virtual bool doIsConnected( const wxPoint& aPosition ) const { return m_Pos == aPosition; }
virtual EDA_ITEM* doClone() const; virtual EDA_ITEM* doClone() const;
}; };
......
This diff is collapsed.
...@@ -127,6 +127,10 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) ...@@ -127,6 +127,10 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_MENU_RANGE( ID_POPUP_SCH_MIROR_X_CMP, ID_POPUP_SCH_ORIENT_NORMAL_CMP, EVT_MENU_RANGE( ID_POPUP_SCH_MIROR_X_CMP, ID_POPUP_SCH_ORIENT_NORMAL_CMP,
SCH_EDIT_FRAME::OnChangeComponentOrientation ) SCH_EDIT_FRAME::OnChangeComponentOrientation )
// Multple item selection context menu commands.
EVT_MENU_RANGE( ID_SCH_SELECT_ITEM_START, ID_SCH_SELECT_ITEM_END,
SCH_EDIT_FRAME::OnSelectItem )
/* Handle user interface update events. */ /* Handle user interface update events. */
EVT_UPDATE_UI( wxID_CUT, SCH_EDIT_FRAME::OnUpdateBlockSelected ) EVT_UPDATE_UI( wxID_CUT, SCH_EDIT_FRAME::OnUpdateBlockSelected )
EVT_UPDATE_UI( wxID_COPY, SCH_EDIT_FRAME::OnUpdateBlockSelected ) EVT_UPDATE_UI( wxID_COPY, SCH_EDIT_FRAME::OnUpdateBlockSelected )
...@@ -712,3 +716,18 @@ void SCH_EDIT_FRAME::SVG_Print( wxCommandEvent& event ) ...@@ -712,3 +716,18 @@ void SCH_EDIT_FRAME::SVG_Print( wxCommandEvent& event )
frame.ShowModal(); frame.ShowModal();
} }
void SCH_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
int index = id - ID_SCH_SELECT_ITEM_START;
if( (id >= ID_SCH_SELECT_ITEM_START && id <= ID_SCH_SELECT_ITEM_END)
&& (index >= 0 && index < m_collectedItems.GetCount()) )
{
SCH_ITEM* item = m_collectedItems[index];
DrawPanel->m_AbortRequest = false;
GetScreen()->SetCurItem( item );
}
}
...@@ -127,9 +127,6 @@ int SCH_EDIT_FRAME::Edit_PinSheet( SCH_SHEET_PIN* aLabel, wxDC* aDC ) ...@@ -127,9 +127,6 @@ int SCH_EDIT_FRAME::Edit_PinSheet( SCH_SHEET_PIN* aLabel, wxDC* aDC )
if( aLabel == NULL ) if( aLabel == NULL )
return wxID_CANCEL; return wxID_CANCEL;
if( aDC )
aLabel->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
DIALOG_SCH_EDIT_SHEET_PIN dlg( this ); DIALOG_SCH_EDIT_SHEET_PIN dlg( this );
dlg.SetLabelName( aLabel->m_Text ); dlg.SetLabelName( aLabel->m_Text );
...@@ -151,6 +148,9 @@ int SCH_EDIT_FRAME::Edit_PinSheet( SCH_SHEET_PIN* aLabel, wxDC* aDC ) ...@@ -151,6 +148,9 @@ int SCH_EDIT_FRAME::Edit_PinSheet( SCH_SHEET_PIN* aLabel, wxDC* aDC )
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
return wxID_CANCEL; return wxID_CANCEL;
if( aDC )
aLabel->Draw( DrawPanel, aDC, wxPoint( 0, 0 ), g_XorMode );
aLabel->m_Text = dlg.GetLabelName(); aLabel->m_Text = dlg.GetLabelName();
aLabel->m_Size.y = ReturnValueFromString( g_UserUnit, dlg.GetTextHeight(), m_InternalUnits ); aLabel->m_Size.y = ReturnValueFromString( g_UserUnit, dlg.GetTextHeight(), m_InternalUnits );
aLabel->m_Size.x = ReturnValueFromString( g_UserUnit, dlg.GetTextWidth(), m_InternalUnits ); aLabel->m_Size.x = ReturnValueFromString( g_UserUnit, dlg.GetTextWidth(), m_InternalUnits );
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define BASE_STRUCT_H #define BASE_STRUCT_H
#include "colors.h" #include "colors.h"
#include "bitmaps.h"
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
...@@ -45,21 +46,23 @@ enum KICAD_T { ...@@ -45,21 +46,23 @@ enum KICAD_T {
TYPE_ZONE_CONTAINER, // a zone area TYPE_ZONE_CONTAINER, // a zone area
TYPE_BOARD_ITEM_LIST, // a list of board items TYPE_BOARD_ITEM_LIST, // a list of board items
// Draw Items in schematic // Schematic draw Items. The order of these items effects the sort order.
SCH_POLYLINE_T, // It is currenlty ordered to mimic the old EESchema locate behavior where
// the smallest item is the selected item.
SCH_MARKER_T,
SCH_JUNCTION_T, SCH_JUNCTION_T,
SCH_NO_CONNECT_T,
SCH_BUS_ENTRY_T,
SCH_LINE_T,
SCH_POLYLINE_T,
SCH_TEXT_T, SCH_TEXT_T,
SCH_LABEL_T, SCH_LABEL_T,
SCH_GLOBAL_LABEL_T, SCH_GLOBAL_LABEL_T,
SCH_HIERARCHICAL_LABEL_T, SCH_HIERARCHICAL_LABEL_T,
SCH_FIELD_T,
SCH_COMPONENT_T, SCH_COMPONENT_T,
SCH_LINE_T,
SCH_BUS_ENTRY_T,
SCH_SHEET_T,
SCH_SHEET_LABEL_T, SCH_SHEET_LABEL_T,
SCH_MARKER_T, SCH_SHEET_T,
SCH_NO_CONNECT_T,
SCH_FIELD_T,
// General // General
SCH_SCREEN_T, SCH_SCREEN_T,
...@@ -275,6 +278,13 @@ public: ...@@ -275,6 +278,13 @@ public:
* @param aPoint The point to merge with the rectangle. * @param aPoint The point to merge with the rectangle.
*/ */
void Merge( const wxPoint& aPoint ); void Merge( const wxPoint& aPoint );
/**
* Function GetArea
* returns the area of the rectangle.
* @return The area of the rectangle.
*/
double GetArea() const;
}; };
...@@ -519,7 +529,6 @@ public: ...@@ -519,7 +529,6 @@ public:
const void* testData, const void* testData,
const KICAD_T scanTypes[] ); const KICAD_T scanTypes[] );
/** /**
* Function Visit * Function Visit
* may be re-implemented for each derived class in order to handle * may be re-implemented for each derived class in order to handle
...@@ -537,7 +546,6 @@ public: ...@@ -537,7 +546,6 @@ public:
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[] );
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.
...@@ -548,6 +556,26 @@ public: ...@@ -548,6 +556,26 @@ public:
return wxT( "EDA_ITEM" ); return wxT( "EDA_ITEM" );
} }
/**
* Function GetSelectMenuText
* returns the text to display to be used in the selection clarification context menu
* when multiple items are found at the current cursor position. The default version
* of this function raises an assertion in the debug mode and returns a string to
* indicate that it was not overridden to provide the object specific text.
*
* @return The menu text string.
*/
virtual wxString GetSelectMenuText() const;
/**
* Function GetMenuImage
* 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
* images.
* @return The menu image associated with the item.
*/
virtual const char** GetMenuImage() const { return (const char**) right_xpm; }
#if defined(DEBUG) #if defined(DEBUG)
...@@ -576,7 +604,7 @@ public: ...@@ -576,7 +604,7 @@ public:
/** /**
* Function new_clone * Function new_clone
* provides cloning capabilities for all Boost pointer containers of EDA_ITEMs. * provides cloning capabilities for all Boost pointer containers of EDA_ITEM pointers.
* *
* @param aItem EDA_ITEM to clone. * @param aItem EDA_ITEM to clone.
* @return Clone of \a aItem. * @return Clone of \a aItem.
...@@ -587,10 +615,10 @@ inline EDA_ITEM* new_clone( const EDA_ITEM& aItem ) { return aItem.Clone(); } ...@@ -587,10 +615,10 @@ 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 Boost containter was choosen over the statand C++ contain because you can detach * The standard C++ containter was choosen so the pointer can be removed from a list without
* the pointer from a list with the release method. * it being destroyed.
*/ */
typedef boost::ptr_vector< EDA_ITEM > EDA_ITEMS; typedef std::vector< EDA_ITEM* > EDA_ITEMS;
// Graphic Text justify: // Graphic Text justify:
......
...@@ -142,6 +142,23 @@ public: ...@@ -142,6 +142,23 @@ public:
return &m_List[0]; return &m_List[0];
} }
/**
* Function HasItem
* tests if \a aItem has already been collected.
*
* @param aItem The EDA_ITEM* to be tested.
* @return True if \a aItem is already collected.
*/
bool HasItem( const EDA_ITEM* aItem ) const
{
for( size_t i = 0; i < m_List.size(); i++ )
{
if( m_List[i] == aItem )
return true;
}
return false;
}
/** /**
* Function SetScanTypes * Function SetScanTypes
...@@ -159,6 +176,7 @@ public: ...@@ -159,6 +176,7 @@ public:
{ {
m_TimeAtCollection = GetTimeStamp(); m_TimeAtCollection = GetTimeStamp();
} }
int GetTime() int GetTime()
{ {
return m_TimeAtCollection; return m_TimeAtCollection;
......
...@@ -101,7 +101,7 @@ public: ...@@ -101,7 +101,7 @@ public:
* @see EDA_DRAW_FRAME::GetGridColor() for the color of the grid. * @see EDA_DRAW_FRAME::GetGridColor() for the color of the grid.
* @param aDC The device context to draw the grid. * @param aDC The device context to draw the grid.
*/ */
void DrawGrid( wxDC* DC ); void DrawGrid( wxDC* aDC );
/** /**
* Function DrawAuxiliaryAxis * Function DrawAuxiliaryAxis
......
...@@ -9,12 +9,23 @@ ...@@ -9,12 +9,23 @@
#include "sch_item_struct.h" #include "sch_item_struct.h"
#include "class_base_screen.h" #include "class_base_screen.h"
#include "../eeschema/general.h"
class LIB_PIN; class LIB_PIN;
class SCH_COMPONENT; class SCH_COMPONENT;
class SCH_SHEET_PATH; class SCH_SHEET_PATH;
class SCH_SHEET_PIN; class SCH_SHEET_PIN;
class SCH_LINE; class SCH_LINE;
class SCH_TEXT;
enum SCH_LINE_TEST_T
{
ENTIRE_LENGTH_T,
END_POINTS_ONLY_T,
EXCLUDE_END_POINTS_T
};
/* Max number of sheets in a hierarchy project: */ /* Max number of sheets in a hierarchy project: */
...@@ -30,7 +41,7 @@ class SCH_SCREEN : public BASE_SCREEN ...@@ -30,7 +41,7 @@ class SCH_SCREEN : public BASE_SCREEN
* Function addConnectedItemsToBlock * Function addConnectedItemsToBlock
* add items connected at \a aPosition to the block pick list. * add items connected at \a aPosition to the block pick list.
* <p> * <p>
* This method tests all connectable unselected items in the screen that are connected to * This method tests all connectible unselected items in the screen that are connected to
* \a aPosition and adds them to the block selection pick list. This is used when a block * \a aPosition and adds them to the block selection pick list. This is used when a block
* drag is being performed to ensure connections to items in the block are not lost. * drag is being performed to ensure connections to items in the block are not lost.
*</p> *</p>
...@@ -84,39 +95,15 @@ public: ...@@ -84,39 +95,15 @@ public:
void FreeDrawList(); void FreeDrawList();
/** /**
* Function GetItems * Function GetItem
* adds all items found at \a aPosition to \a aItemList. Please note that \a aItemList
* will own the item pointers added to it. Do not allow it to go out of scope without
* first calling the release() method. Otherwise, the pointer will be deleted and
* EESchema will crash.
* @param aPosition The position to test.
* @param aItemList The list to place items into.
* @return The number of items found at \a aPosition.
*/
int GetItems( const wxPoint& aPosition, SCH_ITEMS& aItemList ) const;
/**
* Function FindItem
* checks \a aPosition within a distance of \a aAccuracy for items of type \a aFilter. * checks \a aPosition within a distance of \a aAccuracy for items of type \a aFilter.
* @param aPosition Position in drawing units. * @param aPosition Position in drawing units.
* @param aAccuracy The maximum distance within \a Position to check for an item. * @param aAccuracy The maximum distance within \a Position to check for an item.
* @param aFilter The type of items to find. * @param aType The type of item to find or #NOT_USED to find any item type.
* @return The item found that meets the search criteria or NULL if none found. * @return The item found that meets the search criteria or NULL if none found.
*/ */
SCH_ITEM* GetItem( const wxPoint& aPosition, int aAccuracy = 0, SCH_ITEM* GetItem( const wxPoint& aPosition, int aAccuracy = 0,
int aFilter = NO_FILTER_T ) const; KICAD_T aType = NOT_USED ) const;
/**
* Function GetItems
* checks \a aPosition within a distance of \a aAccuracy for items of type \a aFilter.
* @param aPosition Position in drawing units.
* @param aItemList The list to add found items to.
* @param aAccuracy The maximum distance within \a Position to check for an item.
* @param aFilter The type of items to find.
* @return The number of items found that meets the search criteria.
*/
int GetItems( const wxPoint& aPosition, PICKED_ITEMS_LIST& aItemList, int aAccuracy = 0,
int aFilter = NO_FILTER_T ) const;
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { }; void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
...@@ -150,6 +137,15 @@ public: ...@@ -150,6 +137,15 @@ public:
void AddToDrawList( SCH_ITEM* st ); void AddToDrawList( SCH_ITEM* st );
/**
* Function SchematicCleanUp
* performs routine schematic cleaning including breaking wire and buses and
* deleting identical objects superimposed on top of each other.
*
* @param aCanvas The window to draw on.
* @param aDC The device context used for drawing to \a aCanvas.
* @return True if any schematic clean up was performed.
*/
bool SchematicCleanUp( EDA_DRAW_PANEL* aCanvas = NULL, wxDC* aDC = NULL ); bool SchematicCleanUp( EDA_DRAW_PANEL* aCanvas = NULL, wxDC* aDC = NULL );
/** /**
...@@ -167,8 +163,8 @@ public: ...@@ -167,8 +163,8 @@ public:
* them with a copy. Old item must be put in undo list, and the new ones can be * them with a copy. Old item must be put in undo list, and the new ones can be
* modified by clean up safely. If an abort command is made, old wires must be put * modified by clean up safely. If an abort command is made, old wires must be put
* in GetDrawItems(), and copies must be deleted. This is because previously stored * in GetDrawItems(), and copies must be deleted. This is because previously stored
* undo commands can handle pointers on wires or busses, and we do not delete wires or * undo commands can handle pointers on wires or buses, and we do not delete wires or
* busses, we must put they in undo list. * buss-es, we must put they in undo list.
* *
* Because cleanup delete and/or modify bus and wires, the it is easier is to put * Because cleanup delete and/or modify bus and wires, the it is easier is to put
* all wires in undo list and use a new copy of wires for cleanup. * all wires in undo list and use a new copy of wires for cleanup.
...@@ -187,7 +183,6 @@ public: ...@@ -187,7 +183,6 @@ public:
* add all wires and junctions connected to \a aSegment which are not connected any * add all wires and junctions connected to \a aSegment which are not connected any
* component pin to \a aItemList. * component pin to \a aItemList.
* @param aSegment The segment to test for connections. * @param aSegment The segment to test for connections.
* @param aItemList List of items to add connections.
*/ */
void MarkConnections( SCH_LINE* aSegment ); void MarkConnections( SCH_LINE* aSegment );
...@@ -257,7 +252,18 @@ public: ...@@ -257,7 +252,18 @@ public:
* @param aPosition The position to test. * @param aPosition The position to test.
* @return True if a junction is required at \a aPosition. * @return True if a junction is required at \a aPosition.
*/ */
bool IsJunctionNeeded( const wxPoint& aPosition ) const; bool IsJunctionNeeded( const wxPoint& aPosition );
/**
* Function IsTerminalPoint
* tests if \a aPosition is a connection point on \a aLayer.
*
* @param aPosition Position to test.
* @param aLayer The layer type to test against. Valid layer types are #LAYER_NOTES,
* #LAYER_BUS, and #LAYER_WIRE.
* @return True if \a Position is a connection point on \a aLayer.
*/
bool IsTerminalPoint( const wxPoint& aPosition, int aLayer );
/** /**
* Function GetPin * Function GetPin
...@@ -292,7 +298,64 @@ public: ...@@ -292,7 +298,64 @@ public:
* adds all schematic sheet and component object in the screen to \a aItems. * adds all schematic sheet and component object in the screen to \a aItems.
* @param aItems Hierarchical item list to fill. * @param aItems Hierarchical item list to fill.
*/ */
void GetHierarchicalItems( std::vector <SCH_ITEM*>& aItems ); void GetHierarchicalItems( EDA_ITEMS& aItems );
/**
* Function GetNode
* returns all the items at \a aPosition that form a node.
*
* @param aPosition The wxPoint to test for node items.
* @param aList A #EDA_ITEMS container to place the items found.
* @return The number of node items found at \a aPosition.
*/
int GetNode( const wxPoint& aPosition, EDA_ITEMS& aList );
/**
* Function GetWireOrBus
* returns a wire or bus item located at \a aPosition.
*
* @param aPosition The wxPoint to test for node items.
* @return The SCH_LINE* of the wire or bus item found at \a aPosition or NULL if item not
* found.
*/
SCH_LINE* GetWireOrBus( const wxPoint& aPosition );
/**
* Function GetLine
* returns a line item located at \a aPosition.
*
* @param aPosition The wxPoint to test for a line item.
* @param aAccuracy Amount to inflate the item hit test bounding box.
* @param aLayer The layer the line is drawn upon.
* @param aSearchType Additional line test criteria.
* @return The SCH_LINE* of the wire item found at \a aPosition or NULL if item not
* found.
*/
SCH_LINE* GetLine( const wxPoint& aPosition, int aAccuracy = 0, int aLayer = LAYER_NOTES,
SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T );
SCH_LINE* GetWire( const wxPoint& aPosition, int aAccuracy = 0,
SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T )
{
return GetLine( aPosition, aAccuracy, LAYER_WIRE, aSearchType );
}
SCH_LINE* GetBus( const wxPoint& aPosition, int aAccuracy = 0,
SCH_LINE_TEST_T aSearchType = ENTIRE_LENGTH_T )
{
return GetLine( aPosition, aAccuracy, LAYER_BUS, aSearchType );
}
/**
* Function GetLabel
* returns a label item located at \a aPosition.
*
* @param aPosition The wxPoint to test for label items.
* @param aAccuracy Amount to inflate the item hit test bounding box.
* @return The SCH_TEXT* of the label item found at \a aPosition or NULL if item not
* found.
*/
SCH_TEXT* GetLabel( const wxPoint& aPosition, int aAccuracy = 0 );
/** /**
* Function SelectBlockItems * Function SelectBlockItems
...@@ -370,7 +433,7 @@ public: ...@@ -370,7 +433,7 @@ public:
* Function DeleteAllMarkers * Function DeleteAllMarkers
* deletes all electronic rules check markers of \a aMarkerType from all the screens in * deletes all electronic rules check markers of \a aMarkerType from all the screens in
* the list. * the list.
* @param aType Type of markers to be deleted. * @param aMarkerType Type of markers to be deleted.
*/ */
void DeleteAllMarkers( int aMarkerType ); void DeleteAllMarkers( int aMarkerType );
......
...@@ -301,6 +301,20 @@ int GetCommandOptions( const int argc, const char** argv, ...@@ -301,6 +301,20 @@ int GetCommandOptions( const int argc, const char** argv,
*/ */
const wxString& valeur_param( int valeur, wxString& buf_texte ); const wxString& valeur_param( int valeur, wxString& buf_texte );
/**
* Function CoordinateToString
* is a helper to convert the integer coordinate \a aValue to a string in inches,
* millimeters, or unscaled units according to the current user units setting.
*
* @param aValue The coordinate to convert.
* @param aInternalUnits The internal units of the application. #EESCHEMA_INTERNAL_UNIT
* and #PCB_INTERNAL_UNIT are the only valid value.
* @param aConvertToMils Convert inch values to mils if true. This setting has no effect if
* the current user unit is millimeters.
* @return The converted string for display in user interface elements.
*/
wxString CoordinateToString( int aValue, int aInternalUnits, bool aConvertToMils = false );
/** /**
* Returns the units symbol. * Returns the units symbol.
* *
......
...@@ -22,28 +22,6 @@ typedef SCH_ITEMS::iterator SCH_ITEMS_ITR; ...@@ -22,28 +22,6 @@ typedef SCH_ITEMS::iterator SCH_ITEMS_ITR;
typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS; typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS;
// Schematic item filter mask for hit test objects in schematic editor.
enum SCH_FILTER_T {
COMPONENT_T = 0x0001,
WIRE_T = 0X0002,
BUS_T = 0x0004,
BUS_ENTRY_T = 0x0008,
JUNCTION_T = 0x0010,
DRAW_ITEM_T = 0x0020,
TEXT_T = 0x0040,
LABEL_T = 0x0080,
SHEET_T = 0x0100,
MARKER_T = 0x0200,
NO_CONNECT_T = 0x0400,
SHEET_LABEL_T = 0x0800,
FIELD_T = 0x1000,
EXCLUDE_ENDPOINTS_T = 0x2000,
ENDPOINTS_ONLY_T = 0x4000,
PIN_T = 0x8000,
NO_FILTER_T = 0xFFFF
};
/* used to calculate the pen size from default value /* used to calculate the pen size from default value
* the actual pen size is default value * BUS_WIDTH_EXPAND * the actual pen size is default value * BUS_WIDTH_EXPAND
*/ */
...@@ -147,7 +125,7 @@ public: ...@@ -147,7 +125,7 @@ public:
/** /**
* Function Move * Function Move
* moves the item by \a aMoveVector to a new position. * moves the item by \a aMoveVector to a new position.
* @param aMoveVector = the deplacement vector * @param aMoveVector = the displacement vector
*/ */
virtual void Move( const wxPoint& aMoveVector ) = 0; virtual void Move( const wxPoint& aMoveVector ) = 0;
...@@ -248,7 +226,7 @@ public: ...@@ -248,7 +226,7 @@ public:
* True is be return anytime the select state changes. If you need to know the * True is be return anytime the select state changes. If you need to know the
* the current selection state, use the IsSelected() method. * the current selection state, use the IsSelected() method.
* *
* @param aRect - Rectange to test against. * @param aRect - Rectangle to test against.
*/ */
virtual bool IsSelectStateChanged( const wxRect& aRect ) { return false; } virtual bool IsSelectStateChanged( const wxRect& aRect ) { return false; }
...@@ -275,7 +253,7 @@ public: ...@@ -275,7 +253,7 @@ public:
* The vector release method is used to prevent the item pointers from being deleted. * The vector release method is used to prevent the item pointers from being deleted.
* Do not use the vector erase method on the connection list. * Do not use the vector erase method on the connection list.
*/ */
void ClearConnections() { m_connections.release(); } void ClearConnections() { m_connections.clear(); }
/** /**
* Function IsConnected * Function IsConnected
...@@ -286,19 +264,19 @@ public: ...@@ -286,19 +264,19 @@ public:
*/ */
bool IsConnected( const wxPoint& aPoint ) const; bool IsConnected( const wxPoint& aPoint ) const;
virtual bool HitTest( const wxPoint& aPosition ) { return HitTest( aPosition, 0 ); }
/** /**
* Function HitTest * Function HitTest
* tests if \a aPoint is contained within or on the bounding box of an item. * tests if \a aPoint is contained within or on the bounding box of an item.
* *
* @param aPoint - Point to test. * @param aPoint - Point to test.
* @param aAccuracy - Increase the item bounding box by this amount. * @param aAccuracy - Increase the item bounding box by this amount.
* @param aFilter - Mask to provide more granular hit testing. See enum SCH_FILTER_T. * @return True if \a aPoint is within the item bounding box.
* @return True if \a aPoint is within the item and meets the filter criteria.
*/ */
bool HitTest( const wxPoint& aPoint, int aAccuracy = 0, bool HitTest( const wxPoint& aPoint, int aAccuracy = 0 ) const
SCH_FILTER_T aFilter = NO_FILTER_T ) const
{ {
return doHitTest( aPoint, aAccuracy, aFilter ); return doHitTest( aPoint, aAccuracy );
} }
/** /**
...@@ -317,6 +295,8 @@ public: ...@@ -317,6 +295,8 @@ public:
virtual bool CanIncrementLabel() const { return false; } virtual bool CanIncrementLabel() const { return false; }
virtual bool operator <( const SCH_ITEM& aItem ) const;
/** /**
* @note - The DoXXX() functions below are used to enforce the interface while retaining * @note - The DoXXX() functions below are used to enforce the interface while retaining
* the ability of change the implementation behavior of derived classes. See * the ability of change the implementation behavior of derived classes. See
...@@ -324,7 +304,7 @@ public: ...@@ -324,7 +304,7 @@ public:
* http://www.gotw.ca/publications/mill18.htm. * http://www.gotw.ca/publications/mill18.htm.
*/ */
private: private:
virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy, SCH_FILTER_T aFilter ) const virtual bool doHitTest( const wxPoint& aPoint, int aAccuracy ) const
{ {
return false; return false;
} }
...@@ -337,4 +317,8 @@ private: ...@@ -337,4 +317,8 @@ private:
virtual bool doIsConnected( const wxPoint& aPosition ) const { return false; } virtual bool doIsConnected( const wxPoint& aPosition ) const { return false; }
}; };
extern bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 );
#endif /* SCH_ITEM_STRUCT_H */ #endif /* SCH_ITEM_STRUCT_H */
...@@ -27,30 +27,30 @@ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); ...@@ -27,30 +27,30 @@ bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY );
//! @param linePointA Point on line //! @param linePointA Point on line
//! @param linePointB Point on line //! @param linePointB Point on line
//! @param referencePoint Reference point //! @param referencePoint Reference point
double DistanceLinePoint(wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint); double DistanceLinePoint( wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint );
//! @brief Euclidean norm of a 2D vector //! @brief Euclidean norm of a 2D vector
//! @param vector Two-dimensional vector //! @param vector Two-dimensional vector
//! @return Euclidean norm of the vector //! @return Euclidean norm of the vector
double EuclideanNorm(wxPoint vector); double EuclideanNorm( wxPoint vector );
//! @brief Vector between two points //! @brief Vector between two points
//! @param startPoint The start point //! @param startPoint The start point
//! @param endPoint The end point //! @param endPoint The end point
//! @return Vector between the points //! @return Vector between the points
wxPoint TwoPointVector(wxPoint startPoint, wxPoint endPoint); wxPoint TwoPointVector( wxPoint startPoint, wxPoint endPoint );
//! @brief Test, if two points are near each other //! @brief Test, if two points are near each other
//! @param pointA First point //! @param pointA First point
//! @param pointB Second point //! @param pointB Second point
//! @param threshold The maximum distance //! @param threshold The maximum distance
//! @return True or false //! @return True or false
bool HitTestPoints(wxPoint pointA, wxPoint pointB, double threshold); bool HitTestPoints( wxPoint pointA, wxPoint pointB, double threshold );
//! @brief Determine the cross product //! @brief Determine the cross product
//! @param vectorA Two-dimensional vector //! @param vectorA Two-dimensional vector
//! @param vectorB Two-dimensional vector //! @param vectorB Two-dimensional vector
int CrossProduct(wxPoint vectorA, wxPoint vectorB); int CrossProduct( wxPoint vectorA, wxPoint vectorB );
/** /**
...@@ -62,9 +62,14 @@ int CrossProduct(wxPoint vectorA, wxPoint vectorB); ...@@ -62,9 +62,14 @@ int CrossProduct(wxPoint vectorA, wxPoint vectorB);
* @param aEnd is the second end-point of the line segment * @param aEnd is the second end-point of the line segment
* @param aDist = maximum distance for hit * @param aDist = maximum distance for hit
*/ */
bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist );
int aDist );
/**
* Function GetLineLength
* returns the length of a line segment defined by \a aPointA and \a aPointB.
* @return Length of a line.
*/
double GetLineLength( const wxPoint& aPointA, const wxPoint& aPointB );
/*******************/ /*******************/
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "template_fieldnames.h" #include "template_fieldnames.h"
#include "block_commande.h" #include "block_commande.h"
#include "class_sch_screen.h" #include "class_sch_screen.h"
#include "sch_collectors.h"
class LIB_EDIT_FRAME; class LIB_EDIT_FRAME;
...@@ -94,6 +95,7 @@ private: ...@@ -94,6 +95,7 @@ private:
BLOCK_SELECTOR m_blockItems; ///< List of selected items. BLOCK_SELECTOR m_blockItems; ///< List of selected items.
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.
public: public:
SCH_EDIT_FRAME( wxWindow* father, SCH_EDIT_FRAME( wxWindow* father,
...@@ -204,24 +206,52 @@ public: ...@@ -204,24 +206,52 @@ public:
void OnSelectOptionToolbar( wxCommandEvent& event ); void OnSelectOptionToolbar( wxCommandEvent& event );
int BestZoom(); int BestZoom();
SCH_ITEM* LocateAndShowItem( const wxPoint& aPosition, bool aIncludePin = true ); /**
SCH_ITEM* LocateItem( const wxPoint& aPosition, bool aIncludePin ); * Function LocateAndShowItem
* checks the schematic at \a aPosition in logical (drawing) units for a item
* matching \a aFilterList and \a aGuide.
* <p>
* The search is first performed at the nearest grid position to \a aPosition. If no
* item if found on grid, then \a aPosition is tested for any items. If the item found
* can be cross probed, a message is send to PCBNew and the selected item is highlighted
* in PCB editor.
* </p>
* @param aPosition The wxPoint on the schematic to search.
* @param aFilterList A list of #KICAD_T types to to filter.
* @param aHotKeyCommandId A hot key command ID for performing additional tests when
* multiple items are found at \a aPosition.
* @return A SCH_ITEM pointer of the item found or NULL if no item found
*/
SCH_ITEM* LocateAndShowItem( const wxPoint& aPosition,
const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
int aHotKeyCommandId = 0 );
/**
* Function LocateItem
* checks for items at \a aPosition matching \a aFilter.
* <p>
* If multiple items are located at \a aPosition, a context menu is displayed to clarify
* which item the user intended to select. If the user aborts the context menu, NULL is
* returned and the abort request flag will be set to true. Make sure to clear this flag
* before attempting to display any other context menus.
* </p>
*
* @param aPosition The wxPoint location where to search.
* @param aFilterList A list of #KICAD_T types to to filter.
* @param aHotKeyCommandId A hot key command ID for performing additional tests when
* multiple items are found at \a aPosition.
* @return The SCH_ITEM pointer of the item found or NULL if no item found.
*/
SCH_ITEM* LocateItem( const wxPoint& aPosition,
const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
int aHotKeyCommandId = 0 );
/** /**
* Function DeleteItemAtCrossHair * Function DeleteItemAtCrossHair
* delete the item found under the cross hair. * delete the item found under the cross hair. If multiple items are found at the
* <p> * cross hair position, a context menu is displayed to clarify which item to delete.
* If more than one item found, the priority order is: * See LocateItem() for more information on locating multiple items.
* <ol> *
* Marker
* Junction
* No connect
* Wire or bus
* Graphic item
* Text
* Component
* Sheet
* </ol></p>
* @param aDC The device context to update if and item is deleted. * @param aDC The device context to update if and item is deleted.
* @return True if an item was deleted. * @return True if an item was deleted.
*/ */
...@@ -440,6 +470,8 @@ private: ...@@ -440,6 +470,8 @@ private:
void OnSetOptions( wxCommandEvent& event ); void OnSetOptions( wxCommandEvent& event );
void OnCancelCurrentCommand( wxCommandEvent& aEvent ); void OnCancelCurrentCommand( wxCommandEvent& aEvent );
void OnSelectItem( wxCommandEvent& aEvent );
/* edition events functions */ /* edition events functions */
void OnCopySchematicItemRequest( wxCommandEvent& event ); void OnCopySchematicItemRequest( wxCommandEvent& event );
...@@ -552,13 +584,11 @@ private: ...@@ -552,13 +584,11 @@ private:
void OnSelectUnit( wxCommandEvent& aEvent ); void OnSelectUnit( wxCommandEvent& aEvent );
void ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC ); void ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC );
void SetInitCmp( SCH_COMPONENT* DrawComponent, wxDC* DC ); void SetInitCmp( SCH_COMPONENT* DrawComponent, wxDC* DC );
void EditComponentReference( SCH_COMPONENT* DrawLibItem, void EditComponentReference( SCH_COMPONENT* DrawLibItem, wxDC* DC );
wxDC* DC );
void EditComponentValue( SCH_COMPONENT* DrawLibItem, wxDC* DC ); void EditComponentValue( SCH_COMPONENT* DrawLibItem, wxDC* DC );
void EditComponentFootprint( SCH_COMPONENT* DrawLibItem, void EditComponentFootprint( SCH_COMPONENT* DrawLibItem, wxDC* DC );
wxDC* DC );
void StartMoveCmpField( SCH_FIELD* Field, wxDC* DC ); void StartMoveCmpField( SCH_FIELD* Field, wxDC* DC );
void EditCmpFieldText( SCH_FIELD* Field, wxDC* DC ); void EditComponentFieldText( SCH_FIELD* aField, wxDC* aDC );
void RotateCmpField( SCH_FIELD* Field, wxDC* DC ); void RotateCmpField( SCH_FIELD* Field, wxDC* DC );
void PasteListOfItems( wxDC* DC ); void PasteListOfItems( wxDC* DC );
......
...@@ -191,20 +191,23 @@ public: ...@@ -191,20 +191,23 @@ public:
virtual void SetLanguage( wxCommandEvent& event ); virtual void SetLanguage( wxCommandEvent& event );
/** /**
* function GetFileFromHistory * Function GetFileFromHistory
* Fetch the file name from the file history list. * fetches the file name from the file history list.
* @param aFileHistory = the wxFileHistory in use. If null, * @param cmdId The command ID associated with the \a aFileHistory object.
* the main application file history is used * @param type Please document me!
* @param aFileHistory The wxFileHistory in use. If null, the main application file
* history is used
* @return a wxString containing the selected filename * @return a wxString containing the selected filename
*/ */
wxString GetFileFromHistory( int cmdId, const wxString& type, wxString GetFileFromHistory( int cmdId, const wxString& type,
wxFileHistory * aFileHistory = NULL); wxFileHistory* aFileHistory = NULL);
/** /**
* Function UpdateFileHistory * Function UpdateFileHistory
* Update the list of recent opened files. * ypdates the list of recently opened files.
* @param aFileHistory = the wxFileHistory in use. If NULL, * @param FullFileName The full file name including the path.
* the main application file history is used * @param aFileHistory The wxFileHistory in use. If NULL, the main application file
* history is used.
*/ */
void UpdateFileHistory( const wxString& FullFileName, void UpdateFileHistory( const wxString& FullFileName,
wxFileHistory * aFileHistory = NULL ); wxFileHistory * aFileHistory = NULL );
......
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