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();
} }
......
...@@ -259,20 +259,22 @@ struct Ki_HotkeyInfoSectionDescriptor s_Viewlib_Hokeys_Descr[] = ...@@ -259,20 +259,22 @@ struct Ki_HotkeyInfoSectionDescriptor s_Viewlib_Hokeys_Descr[] =
*/ */
void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem ) void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
{ {
if( aHotKey == 0 )
return;
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
cmd.SetEventObject( this ); cmd.SetEventObject( this );
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
// itemInEdit == false means no item currently edited. We can ask for editing a new item // itemInEdit == false means no item currently edited. We can ask for editing a new item
bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags(); bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags();
// notBusy == true means no item currently edited and no other command in progress // notBusy == true means no item currently edited and no other command in progress
// We can change active tool and ask for editing a new item // We can change active tool and ask for editing a new item
bool notBusy = (!itemInEdit) && (screen->m_BlockLocate.m_State == STATE_NO_BLOCK); bool notBusy = (!itemInEdit) && (screen->m_BlockLocate.m_State == STATE_NO_BLOCK);
if( aHotKey == 0 )
return;
/* Convert lower to upper case (the usual toupper function has problem /* Convert lower to upper case (the usual toupper function has problem
* with non ascii codes like function keys */ * with non ascii codes like function keys */
if( (aHotKey >= 'a') && (aHotKey <= 'z') ) if( (aHotKey >= 'a') && (aHotKey <= 'z') )
...@@ -340,13 +342,9 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -340,13 +342,9 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
break; break;
case HK_DELETE: case HK_DELETE:
if( notBusy) if( notBusy )
{
DeleteItemAtCrossHair( aDC ); DeleteItemAtCrossHair( aDC );
OnModify();
GetScreen()->SetCurItem( NULL );
GetScreen()->TestDanglingEnds( DrawPanel, aDC );
}
break; break;
case HK_REPEAT_LAST: case HK_REPEAT_LAST:
...@@ -449,7 +447,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -449,7 +447,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
if( notBusy ) if( notBusy )
{ {
if( GetToolId() != ID_WIRETOBUS_ENTRY_BUTT ) if( GetToolId() != ID_WIRETOBUS_ENTRY_BUTT )
SetToolID( ID_WIRETOBUS_ENTRY_BUTT, wxCURSOR_PENCIL, _( "Add Wire to Bus entry" ) ); SetToolID( ID_WIRETOBUS_ENTRY_BUTT, wxCURSOR_PENCIL, _( "Add Wire to Bus Entry" ) );
OnLeftClick( aDC, aPosition ); OnLeftClick( aDC, aPosition );
} }
...@@ -459,7 +457,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -459,7 +457,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
if( notBusy ) if( notBusy )
{ {
if( GetToolId() != ID_BUSTOBUS_ENTRY_BUTT ) if( GetToolId() != ID_BUSTOBUS_ENTRY_BUTT )
SetToolID( ID_BUSTOBUS_ENTRY_BUTT, wxCURSOR_PENCIL, _( "Add Bus to Bus entry" ) ); SetToolID( ID_BUSTOBUS_ENTRY_BUTT, wxCURSOR_PENCIL, _( "Add Bus to Bus Entry" ) );
OnLeftClick( aDC, aPosition ); OnLeftClick( aDC, aPosition );
} }
...@@ -552,7 +550,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -552,7 +550,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
if( notBusy ) if( notBusy )
{ {
if( GetToolId() != ID_NOCONN_BUTT ) if( GetToolId() != ID_NOCONN_BUTT )
SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, _( "Add \"NoNonnect\" Flags" ) ); SetToolID( ID_NOCONN_BUTT, wxCURSOR_PENCIL, _( "Add \"No Connect\" Flag" ) );
OnLeftClick( aDC, aPosition ); OnLeftClick( aDC, aPosition );
} }
...@@ -568,22 +566,12 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -568,22 +566,12 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
if( aItem == NULL ) if( aItem == NULL )
{ {
// Find the schematic object to rotate under the cursor // Find the schematic object to rotate under the cursor
aItem = LocateAndShowItem( aPosition, false ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::RotatableItems );
if( aItem == NULL )
break;
if( aItem->Type() == SCH_COMPONENT_T )
aItem = LocateSmallestComponent( GetScreen() );
if( aItem == NULL ) if( aItem == NULL )
break; break;
} }
if( aItem )
{
GetScreen()->SetCurItem( (SCH_ITEM*) aItem );
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case SCH_SHEET_T: //TODO allow sheet rotate on hotkey case SCH_SHEET_T: //TODO allow sheet rotate on hotkey
...@@ -610,7 +598,6 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -610,7 +598,6 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
default: default:
; ;
} }
}
break; break;
...@@ -622,7 +609,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -622,7 +609,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
} }
if( aItem == NULL ) if( aItem == NULL )
aItem = LocateSmallestComponent( GetScreen() ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
if( aItem ) if( aItem )
{ {
...@@ -640,7 +627,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -640,7 +627,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
} }
if( aItem == NULL ) if( aItem == NULL )
aItem = LocateSmallestComponent( GetScreen() ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
if( aItem ) if( aItem )
{ {
...@@ -652,7 +639,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -652,7 +639,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component) case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
if( aItem == NULL ) if( aItem == NULL )
aItem = LocateSmallestComponent( GetScreen() ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
if( aItem ) if( aItem )
{ {
...@@ -663,71 +650,81 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -663,71 +650,81 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
break; break;
case HK_DRAG: // Start drag
case HK_MOVE_COMPONENT_OR_ITEM: // Start move component or other schematic item
case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label case HK_COPY_COMPONENT_OR_LABEL: // Duplicate component or text/label
if( itemInEdit ) if( itemInEdit )
break; break;
if( aItem == NULL ) if( aItem == NULL )
{ {
// For a drag or copy command, try to find first a component: aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::MovableItems );
if( aItem == NULL && HK_Descr->m_Idcommand != HK_MOVE_COMPONENT_OR_ITEM )
aItem = LocateSmallestComponent( GetScreen() );
// If no component, find the schematic object to move/drag or copy under the cursor
if( aItem == NULL )
aItem = LocateAndShowItem( aPosition, false );
if( aItem == NULL ) if( aItem == NULL )
break; break;
}
if( aItem->Type() == SCH_COMPONENT_T ) cmd.SetId( HK_Descr->m_IdMenuEvent );
aItem = LocateSmallestComponent( GetScreen() ); wxPostEvent( this, cmd );
break;
if( aItem == NULL ) case HK_DRAG: // Start drag
if( itemInEdit )
break; break;
if( aItem->Type() == SCH_SHEET_T ) if( aItem == NULL )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) aItem; aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::DraggableItems,
// If it's a sheet, then check if a pinsheet is under the cursor HK_Descr->m_Idcommand );
SCH_SHEET_PIN* slabel = sheet->GetLabel( GetScreen()->GetCrossHairPosition() );
if( slabel ) if( aItem == NULL )
aItem = slabel; break;
} }
if( aItem->Type() == SCH_JUNCTION_T ) if( aItem->GetFlags() == 0 )
{
switch( aItem->Type() )
{
// select the correct event for moving an schematic object
// and add it to the event queue
case SCH_COMPONENT_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
cmd.SetId( HK_Descr->m_IdMenuEvent );
wxPostEvent( this, cmd );
break;
case SCH_BUS_ENTRY_T:
case SCH_LINE_T:
if( ((SCH_ITEM*) aItem )->GetLayer() != LAYER_BUS )
{ {
// If it's a junction, pick the underlying wire instead cmd.SetId( ID_POPUP_SCH_DRAG_WIRE_REQUEST );
aItem = screen->GetItem( screen->GetCrossHairPosition(), 0, WIRE_T ); wxPostEvent( this, cmd );
} }
if( aItem == NULL )
break; break;
default:
;
}
} }
if( HK_Descr->m_Idcommand == HK_COPY_COMPONENT_OR_LABEL )
{
GetScreen()->SetCurItem( (SCH_ITEM*) aItem );
wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent );
wxPostEvent( this, event );
break; break;
}
if( aItem && (aItem->GetFlags() == 0) )
case HK_MOVE_COMPONENT_OR_ITEM: // Start move component or other schematic item
if( itemInEdit )
break;
if( aItem == NULL )
{ {
GetScreen()->SetCurItem( (SCH_ITEM*) aItem ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::MovableItems,
HK_Descr->m_Idcommand );
// Create the events for moving a component or other schematic item if( aItem == NULL )
wxCommandEvent eventMoveItem( wxEVT_COMMAND_TOOL_CLICKED, break;
ID_POPUP_SCH_MOVE_ITEM_REQUEST ); }
wxCommandEvent eventMovePinsheet( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_MOVE_PINSHEET );
wxCommandEvent eventDragWire( wxEVT_COMMAND_TOOL_CLICKED,
ID_POPUP_SCH_DRAG_WIRE_REQUEST );
if( aItem->GetFlags() == 0 )
{
switch( aItem->Type() ) switch( aItem->Type() )
{ {
// select the correct event for moving an schematic object // select the correct event for moving an schematic object
...@@ -737,30 +734,28 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -737,30 +734,28 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T:
cmd.SetId( HK_Descr->m_IdMenuEvent );
wxPostEvent( this, cmd );
break;
case SCH_TEXT_T: case SCH_TEXT_T:
case SCH_FIELD_T: case SCH_FIELD_T:
case SCH_BUS_ENTRY_T: case SCH_BUS_ENTRY_T:
if( HK_Descr->m_Idcommand != HK_DRAG ) cmd.SetId( HK_Descr->m_IdMenuEvent );
wxPostEvent( this, eventMoveItem ); wxPostEvent( this, cmd );
break; break;
case SCH_SHEET_LABEL_T: case SCH_SHEET_LABEL_T:
if( HK_Descr->m_Idcommand != HK_DRAG ) cmd.SetId( ID_POPUP_SCH_MOVE_PINSHEET );
wxPostEvent( this, eventMovePinsheet ); wxPostEvent( this, cmd );
break; break;
case SCH_LINE_T: case SCH_LINE_T:
if( ( (SCH_ITEM*) aItem )->GetLayer() == LAYER_WIRE ) /**
* @todo Determine why moving bus lines are not handled here.
*/
if( ((SCH_ITEM*) aItem )->GetLayer() != LAYER_BUS )
{ {
if( HK_Descr->m_Idcommand == HK_DRAG ) cmd.SetId( ID_POPUP_SCH_MOVE_ITEM_REQUEST );
wxPostEvent( this, eventDragWire ); wxPostEvent( this, cmd );
else
wxPostEvent( this, eventMoveItem );
} }
break; break;
default: default:
...@@ -777,20 +772,12 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -777,20 +772,12 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
if( aItem == NULL ) if( aItem == NULL )
{ {
aItem = screen->GetItem( screen->GetCrossHairPosition(), 0, aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::EditableItems );
COMPONENT_T | TEXT_T | LABEL_T | SHEET_T );
if( aItem == NULL )
break;
if( aItem->Type() == SCH_COMPONENT_T )
aItem = LocateSmallestComponent( GetScreen() );
if( aItem == NULL ) if( aItem == NULL )
break; break;
} }
if( aItem )
{
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case SCH_COMPONENT_T: case SCH_COMPONENT_T:
...@@ -798,11 +785,15 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -798,11 +785,15 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
break; break;
case SCH_SHEET_T: case SCH_SHEET_T:
GetScreen()->SetCurItem( (SCH_ITEM*) aItem );
cmd.SetId( ID_POPUP_SCH_EDIT_SHEET ); cmd.SetId( ID_POPUP_SCH_EDIT_SHEET );
wxPostEvent( this, cmd ); wxPostEvent( this, cmd );
break; break;
case SCH_SHEET_LABEL_T:
cmd.SetId( ID_POPUP_SCH_EDIT_PINSHEET );
wxPostEvent( this, cmd );
break;
case SCH_TEXT_T: case SCH_TEXT_T:
case SCH_LABEL_T: case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T: case SCH_GLOBAL_LABEL_T:
...@@ -810,10 +801,32 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -810,10 +801,32 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
EditSchematicText( (SCH_TEXT*) aItem ); EditSchematicText( (SCH_TEXT*) aItem );
break; break;
case SCH_FIELD_T:
switch( ( (SCH_FIELD*) aItem )->GetId() )
{
case REFERENCE:
EditComponentReference( (SCH_COMPONENT*)aItem->GetParent(), aDC );
break;
case VALUE:
EditComponentValue( (SCH_COMPONENT*) aItem->GetParent(), aDC );
break;
case FOOTPRINT:
EditComponentFootprint( (SCH_COMPONENT*) aItem->GetParent(), aDC );
break;
default:
/**
* @todo Not sure exactly why there are functions specific to the reference,
* value, and footprint fields when the EditComponentFieldText() function
* seems like it was designed to handle any field. This should probably be
* cleaned up.
*/
EditComponentFieldText( (SCH_FIELD*) aItem, aDC );
}
default: default:
; ;
} }
}
break; break;
case HK_EDIT_COMPONENT_VALUE: case HK_EDIT_COMPONENT_VALUE:
...@@ -821,12 +834,11 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -821,12 +834,11 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
break; break;
if( aItem == NULL ) if( aItem == NULL )
aItem = LocateSmallestComponent( GetScreen() ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
if( aItem ) if( aItem )
{
EditComponentValue( (SCH_COMPONENT*) aItem, aDC ); EditComponentValue( (SCH_COMPONENT*) aItem, aDC );
}
break; break;
case HK_EDIT_COMPONENT_FOOTPRINT: case HK_EDIT_COMPONENT_FOOTPRINT:
...@@ -834,12 +846,11 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -834,12 +846,11 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
break; break;
if( aItem == NULL ) if( aItem == NULL )
aItem = LocateSmallestComponent( GetScreen() ); aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
if( aItem ) if( aItem )
{
EditComponentFootprint( (SCH_COMPONENT*) aItem, aDC ); EditComponentFootprint( (SCH_COMPONENT*) aItem, aDC );
}
break; break;
} }
} }
...@@ -852,6 +863,9 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -852,6 +863,9 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
*/ */
void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem ) void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
{ {
if( aHotKey == 0 )
return;
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
wxCommandEvent toolCmd( wxEVT_COMMAND_TOOL_CLICKED ); wxCommandEvent toolCmd( wxEVT_COMMAND_TOOL_CLICKED );
...@@ -859,9 +873,6 @@ void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -859,9 +873,6 @@ void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
bool itemInEdit = GetScreen()->GetCurItem() && GetScreen()->GetCurItem()->GetFlags(); bool itemInEdit = GetScreen()->GetCurItem() && GetScreen()->GetCurItem()->GetFlags();
if( aHotKey == 0 )
return;
/* Convert lower to upper case (the usual toupper function has problem /* Convert lower to upper case (the usual toupper function has problem
* with non ascii codes like function keys */ * with non ascii codes like function keys */
if( (aHotKey >= 'a') && (aHotKey <= 'z') ) if( (aHotKey >= 'a') && (aHotKey <= 'z') )
...@@ -880,7 +891,6 @@ void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, ...@@ -880,7 +891,6 @@ void LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
default: default:
case HK_NOT_FOUND: case HK_NOT_FOUND:
return; return;
break;
case HK_HELP: // Display Current hotkey list case HK_HELP: // Display Current hotkey list
DisplayHotkeyList( this, s_Libedit_Hokeys_Descr ); DisplayHotkeyList( this, s_Libedit_Hokeys_Descr );
......
...@@ -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;
}; };
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "sch_no_connect.h" #include "sch_no_connect.h"
#include "sch_sheet.h" #include "sch_sheet.h"
#include "sch_component.h" #include "sch_component.h"
#include "sch_collectors.h"
#include "sch_text.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
...@@ -117,9 +119,6 @@ void SCH_SCREEN::FreeDrawList() ...@@ -117,9 +119,6 @@ void SCH_SCREEN::FreeDrawList()
} }
/* If found in GetDrawItems(), remove DrawStruct from GetDrawItems().
* DrawStruct is not deleted or modified
*/
void SCH_SCREEN::RemoveFromDrawList( SCH_ITEM * DrawStruct ) void SCH_SCREEN::RemoveFromDrawList( SCH_ITEM * DrawStruct )
{ {
if( DrawStruct == GetDrawItems() ) if( DrawStruct == GetDrawItems() )
...@@ -210,41 +209,14 @@ void SCH_SCREEN::AddToDrawList( SCH_ITEM* st ) ...@@ -210,41 +209,14 @@ void SCH_SCREEN::AddToDrawList( SCH_ITEM* st )
} }
int SCH_SCREEN::GetItems( const wxPoint& aPosition, SCH_ITEMS& aItemList ) const SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
if( item->HitTest( aPosition ) )
aItemList.push_back( item );
}
return aItemList.size();
}
int SCH_SCREEN::GetItems( const wxPoint& aPosition, PICKED_ITEMS_LIST& aItemList,
int aAccuracy, int aFilter ) const
{ {
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{ {
if( item->HitTest( aPosition, aAccuracy, (SCH_FILTER_T) aFilter ) ) if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) )
{ return item;
ITEM_PICKER picker( (EDA_ITEM*) item );
aItemList.PushItem( picker );
}
}
return aItemList.GetCount();
}
SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, int aFilter ) const if( (aType == SCH_FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
if( item->HitTest( aPosition, aAccuracy, (SCH_FILTER_T) aFilter ) )
{
if( (aFilter & FIELD_T) && (item->Type() == SCH_COMPONENT_T) )
{ {
SCH_COMPONENT* component = (SCH_COMPONENT*) item; SCH_COMPONENT* component = (SCH_COMPONENT*) item;
...@@ -255,11 +227,18 @@ SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, int aFil ...@@ -255,11 +227,18 @@ SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, int aFil
if( field->HitTest( aPosition, aAccuracy ) ) if( field->HitTest( aPosition, aAccuracy ) )
return (SCH_ITEM*) field; return (SCH_ITEM*) field;
} }
if( !(aFilter & COMPONENT_T) )
return NULL;
} }
else if( (aType == SCH_SHEET_LABEL_T) && (item->Type() == SCH_SHEET_T) )
{
SCH_SHEET* sheet = (SCH_SHEET*)item;
SCH_SHEET_PIN* label = sheet->GetLabel( aPosition );
if( label )
return (SCH_ITEM*) label;
}
else if( (item->Type() == aType) && item->HitTest( aPosition, aAccuracy ) )
{
return item; return item;
} }
} }
...@@ -374,14 +353,14 @@ void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment ) ...@@ -374,14 +353,14 @@ void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment )
} }
bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition ) const bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition )
{ {
if( GetItem( aPosition, 0, JUNCTION_T ) ) if( GetItem( aPosition, 0, SCH_JUNCTION_T ) )
return false; return false;
if( GetItem( aPosition, 0, WIRE_T | EXCLUDE_ENDPOINTS_T ) ) if( GetWire( aPosition, 0, EXCLUDE_END_POINTS_T ) )
{ {
if( GetItem( aPosition, 0, WIRE_T | ENDPOINTS_ONLY_T ) ) if( GetWire( aPosition, 0, END_POINTS_ONLY_T ) )
return true; return true;
if( GetPin( aPosition, NULL, true ) ) if( GetPin( aPosition, NULL, true ) )
...@@ -392,10 +371,74 @@ bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition ) const ...@@ -392,10 +371,74 @@ bool SCH_SCREEN::IsJunctionNeeded( const wxPoint& aPosition ) const
} }
/* Routine cleaning: bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
* - Includes segments or buses aligned in only 1 segment {
* - Detects identical objects superimposed wxCHECK_MSG( aLayer == LAYER_NOTES || aLayer == LAYER_BUS || aLayer == LAYER_WIRE, false,
*/ wxT( "Invalid layer type passed to SCH_SCREEN::IsTerminalPoint()." ) );
SCH_SHEET_PIN* label;
SCH_TEXT* text;
switch( aLayer )
{
case LAYER_BUS:
if( GetBus( aPosition ) )
return true;
label = GetSheetLabel( aPosition );
if( label && IsBusLabel( label->m_Text ) && label->IsConnected( aPosition ) )
return true;
text = GetLabel( aPosition );
if( text && IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
&& (text->Type() != SCH_LABEL_T) )
return true;
break;
case LAYER_NOTES:
if( GetLine( aPosition ) )
return true;
break;
case LAYER_WIRE:
if( GetItem( aPosition, MAX( g_DrawDefaultLineThickness, 3 ), SCH_BUS_ENTRY_T ) )
return true;
if( GetItem( aPosition, MAX( g_DrawDefaultLineThickness, 3 ), SCH_JUNCTION_T ) )
return true;
if( GetPin( aPosition, NULL, true ) )
return true;
if( GetWire( aPosition ) )
return true;
text = GetLabel( aPosition );
if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
return true;
label = GetSheetLabel( aPosition );
if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->m_Text ) )
return true;
break;
default:
break;
}
return false;
}
bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
{ {
SCH_ITEM* DrawList, * TstDrawList; SCH_ITEM* DrawList, * TstDrawList;
...@@ -445,12 +488,6 @@ bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) ...@@ -445,12 +488,6 @@ bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
} }
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.sch" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool SCH_SCREEN::Save( FILE* aFile ) const bool SCH_SCREEN::Save( FILE* aFile ) const
{ {
// Creates header // Creates header
...@@ -572,7 +609,12 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen ...@@ -572,7 +609,12 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen
} }
if( pin && aEndPointOnly && ( component->GetPinPhysicalPosition( pin ) != aPosition ) ) if( pin && aEndPointOnly && ( component->GetPinPhysicalPosition( pin ) != aPosition ) )
{
wxPoint endpt = component->GetPinPhysicalPosition( pin );
wxLogDebug( wxString::Format( wxT( "Pin end point at (%d, %d) not (%d, %d )." ),
endpt.x, endpt.y, aPosition.x, aPosition.y ) );
pin = NULL; pin = NULL;
}
if( aComponent ) if( aComponent )
*aComponent = component; *aComponent = component;
...@@ -633,7 +675,7 @@ void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) ...@@ -633,7 +675,7 @@ void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
} }
void SCH_SCREEN::GetHierarchicalItems( std::vector <SCH_ITEM*>& aItems ) void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems )
{ {
SCH_ITEM* item = GetDrawItems(); SCH_ITEM* item = GetDrawItems();
...@@ -810,16 +852,15 @@ bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint ) ...@@ -810,16 +852,15 @@ bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint )
SCH_LINE* segment; SCH_LINE* segment;
SCH_LINE* newSegment; SCH_LINE* newSegment;
bool brokenSegments = false; bool brokenSegments = false;
SCH_FILTER_T filter = ( SCH_FILTER_T ) ( WIRE_T | BUS_T | EXCLUDE_ENDPOINTS_T );
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{ {
if( item->Type() != SCH_LINE_T ) if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) )
continue; continue;
segment = (SCH_LINE*) item; segment = (SCH_LINE*) item;
if( !segment->HitTest( aPoint, 0, filter ) ) if( !segment->HitTest( aPoint, 0 ) || segment->IsEndPoint( aPoint ) )
continue; continue;
// Break the segment at aPoint and create a new segment. // Break the segment at aPoint and create a new segment.
...@@ -862,6 +903,95 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() ...@@ -862,6 +903,95 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions()
} }
int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList )
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
if( item->Type() == SCH_LINE_T && item->HitTest( aPosition )
&& (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
{
aList.push_back( item );
}
else if( item->Type() == SCH_JUNCTION_T && item->HitTest( aPosition ) )
{
aList.push_back( item );
}
}
return (int) aList.size();
}
SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition )
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition )
&& (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) )
{
return (SCH_LINE*) item;
}
}
return NULL;
}
SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer,
SCH_LINE_TEST_T aSearchType )
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
if( item->Type() != SCH_LINE_T )
continue;
if( item->GetLayer() != aLayer )
continue;
if( !item->HitTest( aPosition, aAccuracy ) )
continue;
switch( aSearchType )
{
case ENTIRE_LENGTH_T:
return (SCH_LINE*) item;
case EXCLUDE_END_POINTS_T:
if( !( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
return (SCH_LINE*) item;
break;
case END_POINTS_ONLY_T:
if( ( (SCH_LINE*) item )->IsEndPoint( aPosition ) )
return (SCH_LINE*) item;
}
}
return NULL;
}
SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy )
{
for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() )
{
switch( item->Type() )
{
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIERARCHICAL_LABEL_T:
if( item->HitTest( aPosition, aAccuracy ) )
return (SCH_TEXT*) item;
default:
;
}
}
return NULL;
}
/******************************************************************/ /******************************************************************/
/* Class SCH_SCREENS to handle the list of screens in a hierarchy */ /* Class SCH_SCREENS to handle the list of screens in a hierarchy */
/******************************************************************/ /******************************************************************/
...@@ -870,7 +1000,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() ...@@ -870,7 +1000,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions()
* Function SortByTimeStamp * Function SortByTimeStamp
* sorts a list of schematic items by time stamp and type. * sorts a list of schematic items by time stamp and type.
*/ */
static bool SortByTimeStamp( const SCH_ITEM* item1, const SCH_ITEM* item2 ) static bool SortByTimeStamp( const EDA_ITEM* item1, const EDA_ITEM* item2 )
{ {
int ii = item1->m_TimeStamp - item2->m_TimeStamp; int ii = item1->m_TimeStamp - item2->m_TimeStamp;
...@@ -989,7 +1119,7 @@ void SCH_SCREENS::SchematicCleanUp() ...@@ -989,7 +1119,7 @@ void SCH_SCREENS::SchematicCleanUp()
int SCH_SCREENS::ReplaceDuplicateTimeStamps() int SCH_SCREENS::ReplaceDuplicateTimeStamps()
{ {
std::vector <SCH_ITEM*> items; EDA_ITEMS items;
SCH_ITEM* item; SCH_ITEM* item;
for( size_t i = 0; i < m_screens.size(); i++ ) for( size_t i = 0; i < m_screens.size(); i++ )
...@@ -1004,9 +1134,10 @@ int SCH_SCREENS::ReplaceDuplicateTimeStamps() ...@@ -1004,9 +1134,10 @@ int SCH_SCREENS::ReplaceDuplicateTimeStamps()
for( size_t ii = 0; ii < items.size() - 1; ii++ ) for( size_t ii = 0; ii < items.size() - 1; ii++ )
{ {
item = items[ii]; item = (SCH_ITEM*)items[ii];
SCH_ITEM* nextItem = (SCH_ITEM*)items[ii + 1];
SCH_ITEM* nextItem = items[ii + 1];
if( item->m_TimeStamp == nextItem->m_TimeStamp ) if( item->m_TimeStamp == nextItem->m_TimeStamp )
{ {
count++; count++;
......
...@@ -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;
}; };
......
...@@ -30,6 +30,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -30,6 +30,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
int id = event.GetId(); int id = event.GetId();
wxPoint pos; wxPoint pos;
SCH_SCREEN* screen = GetScreen(); SCH_SCREEN* screen = GetScreen();
SCH_ITEM* item = screen->GetCurItem();
pos = wxGetMousePosition(); pos = wxGetMousePosition();
...@@ -126,12 +127,12 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -126,12 +127,12 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_ENTRY_SELECT_SLASH: case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
SetBusEntryShape( &dc, (SCH_BUS_ENTRY*) screen->GetCurItem(), '/' ); SetBusEntryShape( &dc, (SCH_BUS_ENTRY*) item, '/' );
break; break;
case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH: case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
SetBusEntryShape( &dc, (SCH_BUS_ENTRY*) screen->GetCurItem(), '\\' ); SetBusEntryShape( &dc, (SCH_BUS_ENTRY*) item, '\\' );
break; break;
case ID_POPUP_CANCEL_CURRENT_COMMAND: case ID_POPUP_CANCEL_CURRENT_COMMAND:
...@@ -150,12 +151,12 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -150,12 +151,12 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_SCH_EDIT_TEXT: case ID_POPUP_SCH_EDIT_TEXT:
EditSchematicText( (SCH_TEXT*) screen->GetCurItem() ); EditSchematicText( (SCH_TEXT*) item );
break; break;
case ID_POPUP_SCH_ROTATE_TEXT: case ID_POPUP_SCH_ROTATE_TEXT:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
ChangeTextOrient( (SCH_TEXT*) screen->GetCurItem(), &dc ); ChangeTextOrient( (SCH_TEXT*) item, &dc );
break; break;
case ID_POPUP_SCH_SET_SHAPE_TEXT: case ID_POPUP_SCH_SET_SHAPE_TEXT:
...@@ -165,11 +166,11 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -165,11 +166,11 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_ROTATE_FIELD: case ID_POPUP_SCH_ROTATE_FIELD:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
RotateCmpField( (SCH_FIELD*) screen->GetCurItem(), &dc ); RotateCmpField( (SCH_FIELD*) item, &dc );
break; break;
case ID_POPUP_SCH_EDIT_FIELD: case ID_POPUP_SCH_EDIT_FIELD:
EditCmpFieldText( (SCH_FIELD*) screen->GetCurItem(), &dc ); EditComponentFieldText( (SCH_FIELD*) item, &dc );
break; break;
case ID_POPUP_SCH_DELETE_NODE: case ID_POPUP_SCH_DELETE_NODE:
...@@ -196,18 +197,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -196,18 +197,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_SCH_DELETE_CMP: case ID_POPUP_SCH_DELETE_CMP:
if( screen->GetCurItem() == NULL )
break;
// Ensure the struct is a component (could be a struct of a
// component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) );
case ID_POPUP_SCH_DELETE: case ID_POPUP_SCH_DELETE:
{
SCH_ITEM* item = screen->GetCurItem();
if( item == NULL ) if( item == NULL )
break; break;
...@@ -217,34 +207,33 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -217,34 +207,33 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
screen->TestDanglingEnds( DrawPanel, &dc ); screen->TestDanglingEnds( DrawPanel, &dc );
SetSheetNumberAndCount(); SetSheetNumberAndCount();
OnModify(); OnModify();
}
break; break;
case ID_POPUP_SCH_END_SHEET: case ID_POPUP_SCH_END_SHEET:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
screen->GetCurItem()->Place( this, &dc ); item->Place( this, &dc );
break; break;
case ID_POPUP_SCH_RESIZE_SHEET: case ID_POPUP_SCH_RESIZE_SHEET:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
ReSizeSheet( (SCH_SHEET*) screen->GetCurItem(), &dc ); ReSizeSheet( (SCH_SHEET*) item, &dc );
screen->TestDanglingEnds( DrawPanel, &dc ); screen->TestDanglingEnds( DrawPanel, &dc );
break; break;
case ID_POPUP_SCH_EDIT_SHEET: case ID_POPUP_SCH_EDIT_SHEET:
if( EditSheet( (SCH_SHEET*) screen->GetCurItem(), &dc ) ) if( EditSheet( (SCH_SHEET*) item, &dc ) )
OnModify(); OnModify();
break; break;
case ID_POPUP_IMPORT_GLABEL: case ID_POPUP_IMPORT_GLABEL:
if( screen->GetCurItem() && screen->GetCurItem()->Type() == SCH_SHEET_T ) if( item != NULL && item->Type() == SCH_SHEET_T )
screen->SetCurItem( Import_PinSheet( (SCH_SHEET*) screen->GetCurItem(), &dc ) ); screen->SetCurItem( Import_PinSheet( (SCH_SHEET*) item, &dc ) );
break; break;
case ID_POPUP_SCH_CLEANUP_SHEET: case ID_POPUP_SCH_CLEANUP_SHEET:
if( screen->GetCurItem() && screen->GetCurItem()->Type() == SCH_SHEET_T ) if( item != NULL && item->Type() == SCH_SHEET_T )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) screen->GetCurItem(); SCH_SHEET* sheet = (SCH_SHEET*) item;
if( !sheet->HasUndefinedLabels() ) if( !sheet->HasUndefinedLabels() )
{ {
...@@ -265,35 +254,21 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -265,35 +254,21 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_SCH_EDIT_PINSHEET: case ID_POPUP_SCH_EDIT_PINSHEET:
Edit_PinSheet( (SCH_SHEET_PIN*) screen->GetCurItem(), &dc ); Edit_PinSheet( (SCH_SHEET_PIN*) item, &dc );
break; break;
case ID_POPUP_SCH_MOVE_PINSHEET: case ID_POPUP_SCH_MOVE_PINSHEET:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
StartMove_PinSheet( (SCH_SHEET_PIN*) screen->GetCurItem(), &dc ); StartMove_PinSheet( (SCH_SHEET_PIN*) item, &dc );
break; break;
case ID_POPUP_SCH_DRAG_CMP_REQUEST: case ID_POPUP_SCH_DRAG_CMP_REQUEST:
case ID_POPUP_SCH_MOVE_CMP_REQUEST: case ID_POPUP_SCH_MOVE_CMP_REQUEST:
// Ensure the struct is a component (could be a struct of a
// component, like Field, text..) or a hierarchical sheet
// or a label
if( (screen->GetCurItem()->Type() != SCH_COMPONENT_T)
&& (screen->GetCurItem()->Type() != SCH_LABEL_T)
&& (screen->GetCurItem()->Type() != SCH_GLOBAL_LABEL_T)
&& (screen->GetCurItem()->Type() != SCH_HIERARCHICAL_LABEL_T)
&& (screen->GetCurItem()->Type() != SCH_SHEET_T) )
screen->SetCurItem( LocateSmallestComponent( screen ) );
if( screen->GetCurItem() == NULL )
break;
// fall through
case ID_POPUP_SCH_MOVE_ITEM_REQUEST: case ID_POPUP_SCH_MOVE_ITEM_REQUEST:
case ID_POPUP_SCH_DRAG_WIRE_REQUEST:
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
if( id == ID_POPUP_SCH_DRAG_CMP_REQUEST ) if( (id == ID_POPUP_SCH_DRAG_CMP_REQUEST) || (id == ID_POPUP_SCH_DRAG_WIRE_REQUEST) )
{ {
// The easiest way to handle a drag component or sheet command // The easiest way to handle a drag component or sheet command
// is to simulate a block drag command // is to simulate a block drag command
...@@ -308,39 +283,16 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -308,39 +283,16 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
} }
} }
else else
Process_Move_Item( (SCH_ITEM*) screen->GetCurItem(), &dc ); Process_Move_Item( item, &dc );
break;
case ID_POPUP_SCH_DRAG_WIRE_REQUEST:
DrawPanel->MoveCursorToCrossHair();
// The easiest way to handle a drag component is to simulate a block drag command
if( screen->m_BlockLocate.m_State == STATE_NO_BLOCK )
{
if( !HandleBlockBegin( &dc, BLOCK_DRAG, screen->GetCrossHairPosition() ) )
break;
// Ensure the block selection contains the segment, or one end of
// the segment. The initial rect is only one point (w = h = 2)
// The rect contains one or 0 ends.
// If one end is selected, this is a drag Node
// if no ends selected the current segment is dragged
screen->m_BlockLocate.Inflate( 1 );
HandleBlockEnd( &dc );
}
break; break;
case ID_POPUP_SCH_EDIT_CMP: case ID_POPUP_SCH_EDIT_CMP:
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) ); InstallCmpeditFrame( this, (SCH_COMPONENT*) item );
if( screen->GetCurItem() == NULL )
break;
InstallCmpeditFrame( this, (SCH_COMPONENT*) screen->GetCurItem() );
break; break;
case ID_POPUP_SCH_INIT_CMP: case ID_POPUP_SCH_INIT_CMP:
...@@ -351,39 +303,27 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -351,39 +303,27 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item != NULL && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) ); EditComponentValue( (SCH_COMPONENT*) item, &dc );
if( screen->GetCurItem() == NULL )
break;
EditComponentValue( (SCH_COMPONENT*) screen->GetCurItem(), &dc );
break; break;
case ID_POPUP_SCH_EDIT_REF_CMP: case ID_POPUP_SCH_EDIT_REF_CMP:
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item != NULL && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) ); EditComponentReference( (SCH_COMPONENT*) item, &dc );
if( screen->GetCurItem() == NULL )
break;
EditComponentReference( (SCH_COMPONENT*) screen->GetCurItem(), &dc );
break; break;
case ID_POPUP_SCH_EDIT_FOOTPRINT_CMP: case ID_POPUP_SCH_EDIT_FOOTPRINT_CMP:
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) ); EditComponentFootprint( (SCH_COMPONENT*) item, &dc );
if( screen->GetCurItem() == NULL )
break;
EditComponentFootprint( (SCH_COMPONENT*) screen->GetCurItem(), &dc );
break; break;
...@@ -391,28 +331,22 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -391,28 +331,22 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) ); {
if( screen->GetCurItem() == NULL )
break;
DrawPanel->MoveCursorToCrossHair(); DrawPanel->MoveCursorToCrossHair();
ConvertPart( (SCH_COMPONENT*) screen->GetCurItem(), &dc ); ConvertPart( (SCH_COMPONENT*) item, &dc );
}
break; break;
case ID_POPUP_SCH_DISPLAYDOC_CMP: case ID_POPUP_SCH_DISPLAYDOC_CMP:
// Ensure the struct is a component (could be a piece of a // Ensure the struct is a component (could be a piece of a
// component, like Field, text..) // component, like Field, text..)
if( screen->GetCurItem()->Type() != SCH_COMPONENT_T ) if( item && item->Type() == SCH_COMPONENT_T )
screen->SetCurItem( LocateSmallestComponent( screen ) );
if( screen->GetCurItem() )
{ {
LIB_ALIAS* LibEntry; LIB_ALIAS* LibEntry;
LibEntry = CMP_LIBRARY::FindLibraryEntry( LibEntry = CMP_LIBRARY::FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetLibName() );
( (SCH_COMPONENT*) screen->GetCurItem() )->GetLibName() );
if( LibEntry && LibEntry->GetDocFileName() != wxEmptyString ) if( LibEntry && LibEntry->GetDocFileName() != wxEmptyString )
{ {
...@@ -423,15 +357,13 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -423,15 +357,13 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_SCH_ENTER_SHEET: case ID_POPUP_SCH_ENTER_SHEET:
{
EDA_ITEM* item = screen->GetCurItem();
if( item && (item->Type() == SCH_SHEET_T) ) if( item && (item->Type() == SCH_SHEET_T) )
{ {
m_CurrentSheet->Push( (SCH_SHEET*) item ); m_CurrentSheet->Push( (SCH_SHEET*) item );
DisplayCurrentSheet(); DisplayCurrentSheet();
} }
}
break; break;
case ID_POPUP_SCH_LEAVE_SHEET: case ID_POPUP_SCH_LEAVE_SHEET:
...@@ -499,17 +431,20 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -499,17 +431,20 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_ADD_GLABEL: case ID_POPUP_SCH_ADD_GLABEL:
screen->SetCurItem( CreateNewText( &dc, id == ID_POPUP_SCH_ADD_LABEL ? screen->SetCurItem( CreateNewText( &dc, id == ID_POPUP_SCH_ADD_LABEL ?
LAYER_LOCLABEL : LAYER_GLOBLABEL ) ); LAYER_LOCLABEL : LAYER_GLOBLABEL ) );
if( screen->GetCurItem() ) item = screen->GetCurItem();
if( item )
{ {
( (SCH_ITEM*) screen->GetCurItem() )->Place( this, &dc ); item->Place( this, &dc );
screen->TestDanglingEnds( DrawPanel, &dc ); screen->TestDanglingEnds( DrawPanel, &dc );
screen->SetCurItem( NULL ); screen->SetCurItem( NULL );
} }
break; break;
case ID_POPUP_SCH_GETINFO_MARKER: case ID_POPUP_SCH_GETINFO_MARKER:
if( screen->GetCurItem() && screen->GetCurItem()->Type() == SCH_MARKER_T ) if( item && item->Type() == SCH_MARKER_T )
( (SCH_MARKER*) screen->GetCurItem() )->DisplayMarkerInfo( this ); ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );
break; break;
......
...@@ -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