Logic improvements and fixes for wire segment selection states.

This commit is contained in:
Jeff Young 2019-05-01 21:15:51 +01:00
parent c09817e08c
commit 29f1787af2
6 changed files with 162 additions and 206 deletions

View File

@ -235,7 +235,8 @@ bool SCH_DRAWING_TOOL::Init()
};
auto idleCondition = [] ( const SELECTION& aSel ) {
return ( aSel.Empty() || dynamic_cast<SCH_ITEM*>( aSel.Front() )->GetEditFlags() == 0 );
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
return ( !item || !item->GetEditFlags() );
};
auto idleBusOrLineToolCondition = ( busToolCondition || lineToolCondition ) && idleCondition;
@ -244,18 +245,13 @@ bool SCH_DRAWING_TOOL::Init()
&& SELECTION_CONDITIONS::OnlyTypes( wireOrBusTypes );
auto drawingSegmentsCondition = [] ( const SELECTION& aSel ) {
return ( aSel.GetSize() >= 1
&& dynamic_cast<SCH_LINE*>( aSel.Front() )
&& dynamic_cast<SCH_LINE*>( aSel.Front() )->GetEditFlags() );
SCH_ITEM* item = (SCH_ITEM*) aSel.Front();
return ( item && item->Type() == SCH_LINE_T && item->GetEditFlags() );
};
auto singleSheetCondition = SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyType( SCH_SHEET_T );
auto belowRootSheetCondition = [] ( const SELECTION& aSel ) {
return g_CurrentSheet->Last() != g_RootSheet;
};
auto& ctxMenu = m_menu.GetMenu();
// cancel current tool goes in main context menu at the top if present
@ -331,12 +327,6 @@ int SCH_DRAWING_TOOL::AddHierLabel( const TOOL_EVENT& aEvent )
}
int SCH_DRAWING_TOOL::ImportHierLable( const TOOL_EVENT& aEvent )
{
}
int SCH_DRAWING_TOOL::doAddItem( KICAD_T aType )
{
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
@ -419,7 +409,6 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
getModel<SCH_SCREEN>()->SetCurItem( nullptr );
m_view->ClearPreview();
m_view->ClearHiddenFlags();
delete aComponent;
aComponent = nullptr;
}
@ -465,19 +454,16 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER
m_frame->SetRepeatItem( aComponent );
m_frame->GetScreen()->SetCurItem( aComponent );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, aComponent );
m_view->ClearPreview();
m_view->AddToPreview( aComponent->Clone() );
m_controls->SetCursorPosition( cursorPos, false );
m_selectionTool->AddItemToSel( aComponent );
}
else
{
m_view->ClearPreview();
m_frame->AddItemToScreenAndUndoList( aComponent );
aComponent = nullptr;
m_view->ClearPreview();
}
}
else if( evt->IsClick( BUT_RIGHT ) )
@ -516,7 +502,6 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
Activate();
@ -540,7 +525,6 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
getModel<SCH_SCREEN>()->SetCurItem( nullptr );
m_view->ClearPreview();
m_view->ClearHiddenFlags();
delete image;
image = nullptr;
}
@ -554,33 +538,29 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
{
if( !image )
{
m_frame->GetCanvas()->SetIgnoreMouseEvents( true );
wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
_( "Image Files " ) + wxImage::GetImageExtWildcard(), wxFD_OPEN );
m_frame->GetCanvas()->SetIgnoreMouseEvents( true );
if( dlg.ShowModal() != wxID_OK )
continue;
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
// Restore cursor after dialog
m_frame->GetCanvas()->MoveCursorToCrossHair();
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
wxString fullFilename = dlg.GetPath();
if( !wxFileExists( fullFilename ) )
if( wxFileExists( fullFilename ) )
image = new SCH_BITMAP( (wxPoint)cursorPos );
if( !image || !image->ReadImageFile( fullFilename ) )
{
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
continue;
}
image = new SCH_BITMAP( (wxPoint)cursorPos );
if( !image->ReadImageFile( fullFilename ) )
{
wxMessageBox( _( "Couldn't load image from \"%s\"" ), fullFilename );
image = nullptr;
delete image;
image = nullptr;
continue;
}
@ -589,18 +569,16 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
m_frame->GetScreen()->SetCurItem( image );
m_view->ClearPreview();
m_view->AddToPreview( image->Clone() );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, image );
m_selectionTool->AddItemToSel( image );
m_controls->SetCursorPosition( cursorPos, false );
}
else
{
m_view->ClearPreview();
m_frame->AddItemToScreenAndUndoList( image );
image = nullptr;
m_view->ClearPreview();
}
}
else if( evt->IsClick( BUT_RIGHT ) )
@ -775,7 +753,6 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
Activate();
@ -791,7 +768,6 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
getModel<SCH_SCREEN>()->SetCurItem( nullptr );
m_view->ClearPreview();
m_view->ClearHiddenFlags();
delete item;
item = nullptr;
}
@ -838,17 +814,17 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
wxFAIL_MSG( "doTwoClickPlace(): unknown type" );
}
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
// Restore cursor after dialog
m_frame->GetCanvas()->MoveCursorToCrossHair();
m_frame->GetCanvas()->SetIgnoreMouseEvents( false );
if( item )
{
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, item );
item->SetFlags( IS_MOVED );
item->SetFlags( IS_NEW | IS_MOVED );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
m_selectionTool->AddItemToSel( item );
}
m_controls->SetCursorPosition( cursorPos, false );
@ -857,11 +833,10 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
// ... and second click places:
else
{
m_view->ClearPreview();
m_frame->AddItemToScreenAndUndoList( item );
item = nullptr;
m_view->ClearPreview();
}
}
else if( evt->IsClick( BUT_RIGHT ) )
@ -874,7 +849,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
}
else if( TOOL_EVT_UTILS::IsSelectionEvent( evt.get() ) )
{
// This happens if our text was replaced out from under us by CovertTextType()
// This happens if our text was replaced out from under us by ConvertTextType()
SELECTION& selection = m_selectionTool->GetSelection();
if( selection.GetSize() == 1 )
@ -907,6 +882,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
int SCH_DRAWING_TOOL::StartWire( const TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _( "Add wire" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
SCH_LINE* segment = startSegments( LAYER_WIRE, m_frame->GetCrossHairPosition() );
@ -921,6 +897,8 @@ int SCH_DRAWING_TOOL::DrawWire( const TOOL_EVENT& aEvent )
else
{
m_frame->SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _( "Add wire" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
return doDrawSegments( LAYER_WIRE, nullptr );
}
}
@ -929,6 +907,7 @@ int SCH_DRAWING_TOOL::DrawWire( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::StartBus( const TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_BUS_BUTT, wxCURSOR_PENCIL, _( "Add bus" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
SCH_LINE* segment = startSegments( LAYER_BUS, m_frame->GetCrossHairPosition() );
@ -943,6 +922,8 @@ int SCH_DRAWING_TOOL::DrawBus( const TOOL_EVENT& aEvent )
else
{
m_frame->SetToolID( ID_BUS_BUTT, wxCURSOR_PENCIL, _( "Add bus" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
return doDrawSegments( LAYER_BUS, nullptr );
}
}
@ -991,6 +972,7 @@ int SCH_DRAWING_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
int SCH_DRAWING_TOOL::StartLines( const TOOL_EVENT& aEvent)
{
m_frame->SetToolID( ID_LINE_COMMENT_BUTT, wxCURSOR_PENCIL, _( "Add lines" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetCanvas()->MoveCursorToCrossHair();
SCH_LINE* segment = startSegments( LAYER_NOTES, m_frame->GetCrossHairPosition() );
@ -1005,6 +987,8 @@ int SCH_DRAWING_TOOL::DrawLines( const TOOL_EVENT& aEvent)
else
{
m_frame->SetToolID( ID_LINE_COMMENT_BUTT, wxCURSOR_PENCIL, _( "Add lines" ) );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
return doDrawSegments( LAYER_NOTES, nullptr );
}
}
@ -1014,69 +998,6 @@ int SCH_DRAWING_TOOL::DrawLines( const TOOL_EVENT& aEvent)
static DLIST<SCH_LINE> s_wires;
/**
* In a contiguous list of wires, remove wires that backtrack over the previous
* wire. Example:
*
* Wire is added:
* ---------------------------------------->
*
* A second wire backtracks over it:
* -------------------<====================>
*
* RemoveBacktracks is called:
* ------------------->
*/
static void RemoveBacktracks( DLIST<SCH_LINE>& aWires )
{
SCH_LINE* next = nullptr;
std::vector<SCH_LINE*> last_lines;
for( SCH_LINE* line = aWires.GetFirst(); line; line = next )
{
next = line->Next();
if( line->IsNull() )
{
delete s_wires.Remove( line );
continue;
}
if( !last_lines.empty() )
{
SCH_LINE* last_line = last_lines[last_lines.size() - 1];
bool contiguous = ( last_line->GetEndPoint() == line->GetStartPoint() );
bool backtracks = IsPointOnSegment( last_line->GetStartPoint(),
last_line->GetEndPoint(), line->GetEndPoint() );
bool total_backtrack = ( last_line->GetStartPoint() == line->GetEndPoint() );
if( contiguous && backtracks )
{
if( total_backtrack )
{
delete s_wires.Remove( last_line );
delete s_wires.Remove( line );
last_lines.pop_back();
}
else
{
last_line->SetEndPoint( line->GetEndPoint() );
delete s_wires.Remove( line );
}
}
else
{
last_lines.push_back( line );
}
}
else
{
last_lines.push_back( line );
}
}
}
/**
* A helper function to find any sheet pins at the specified position.
*/
@ -1170,9 +1091,7 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
bool forceHV = m_frame->GetForceHVLines();
SCH_SCREEN* screen = m_frame->GetScreen();
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
Activate();
@ -1202,7 +1121,6 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
m_view->ClearPreview();
m_view->ShowPreview( false );
m_view->ClearHiddenFlags();
// Clear flags used in edit functions.
screen->ClearDrawingState();
@ -1269,14 +1187,13 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
else
{
aSegment->SetEndPoint( cursorPos );
aSegment->ClearFlags( IS_NEW );
aSegment->SetFlags( SELECTED );
// Create a new segment, and chain it after the current new segment.
// Create a new segment, and chain it after the current segment.
aSegment = new SCH_LINE( *aSegment );
aSegment->SetFlags( IS_NEW );
aSegment->SetFlags( IS_NEW | IS_MOVED );
aSegment->SetStartPoint( cursorPos );
s_wires.PushBack( aSegment );
m_selectionTool->AddItemToSel( aSegment, true /*quiet mode*/ );
screen->SetCurItem( aSegment );
}
}
@ -1361,8 +1278,9 @@ SCH_LINE* SCH_DRAWING_TOOL::startSegments( int aType, const wxPoint& aPos )
case LAYER_BUS: segment = new SCH_LINE( aPos, LAYER_BUS ); break;
}
segment->SetFlags( IS_NEW );
segment->SetFlags( IS_NEW | IS_MOVED );
s_wires.PushBack( segment );
m_selectionTool->AddItemToSel( segment, true /*quiet mode*/ );
m_frame->GetScreen()->SetCurItem( segment );
// We need 2 segments to go from a given start pin to an end point when the
@ -1370,8 +1288,9 @@ SCH_LINE* SCH_DRAWING_TOOL::startSegments( int aType, const wxPoint& aPos )
if( forceHV )
{
segment = new SCH_LINE( *segment );
segment->SetFlags( IS_NEW );
segment->SetFlags( IS_NEW | IS_MOVED );
s_wires.PushBack( segment );
m_selectionTool->AddItemToSel( segment, true /*quiet mode*/ );
m_frame->GetScreen()->SetCurItem( segment );
}
@ -1379,12 +1298,80 @@ SCH_LINE* SCH_DRAWING_TOOL::startSegments( int aType, const wxPoint& aPos )
}
/**
* In a contiguous list of wires, remove wires that backtrack over the previous
* wire. Example:
*
* Wire is added:
* ---------------------------------------->
*
* A second wire backtracks over it:
* -------------------<====================>
*
* RemoveBacktracks is called:
* ------------------->
*/
static void removeBacktracks( DLIST<SCH_LINE>& aWires )
{
SCH_LINE* next = nullptr;
std::vector<SCH_LINE*> last_lines;
for( SCH_LINE* line = aWires.GetFirst(); line; line = next )
{
next = line->Next();
if( line->IsNull() )
{
delete s_wires.Remove( line );
continue;
}
if( !last_lines.empty() )
{
SCH_LINE* last_line = last_lines[last_lines.size() - 1];
bool contiguous = ( last_line->GetEndPoint() == line->GetStartPoint() );
bool backtracks = IsPointOnSegment( last_line->GetStartPoint(),
last_line->GetEndPoint(), line->GetEndPoint() );
bool total_backtrack = ( last_line->GetStartPoint() == line->GetEndPoint() );
if( contiguous && backtracks )
{
if( total_backtrack )
{
delete s_wires.Remove( last_line );
delete s_wires.Remove( line );
last_lines.pop_back();
}
else
{
last_line->SetEndPoint( line->GetEndPoint() );
delete s_wires.Remove( line );
}
}
else
{
last_lines.push_back( line );
}
}
else
{
last_lines.push_back( line );
}
}
}
void SCH_DRAWING_TOOL::finishSegments()
{
// Clear selection when done so that a new wire can be started.
// NOTE: this must be done before RemoveBacktracks is called or we might end up with
// freed selected items.
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
PICKED_ITEMS_LIST itemList;
// Remove segments backtracking over others
RemoveBacktracks( s_wires );
removeBacktracks( s_wires );
// Collect the possible connection points for the new lines
std::vector< wxPoint > connections;
@ -1496,14 +1483,13 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet )
{
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
if( aSheet )
{
m_frame->SetUndoItem( aSheet );
m_frame->SaveCopyInUndoList( aSheet, UR_CHANGED );
aSheet->SetFlags( IS_RESIZED );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, aSheet );
m_selectionTool->AddItemToSel( aSheet, true /*quiet mode; should already be selected*/ );
m_view->Hide( aSheet );
m_view->AddToPreview( aSheet->Clone() );
@ -1522,28 +1508,17 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet )
{
m_view->ClearPreview();
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_frame->GetScreen()->SetCurItem( nullptr );
if( m_frame->GetToolId() == ID_POPUP_SCH_RESIZE_SHEET )
{
if( dynamic_cast<SCH_SHEET*>( m_frame->GetUndoItem() ) )
{
delete aSheet;
aSheet = (SCH_SHEET*)m_frame->GetUndoItem();
m_frame->SetUndoItem( nullptr );
}
m_frame->AddToScreen( aSheet );
aSheet->ClearFlags();
m_view->Hide( aSheet, false );
m_frame->GetScreen()->SetCurItem( nullptr );
m_frame->RollbackSchematicFromUndo();
break; // resize sheet is a single-shot command, not a reusable tool
}
else if( aSheet )
{
delete aSheet;
aSheet = nullptr;
m_frame->GetScreen()->SetCurItem( nullptr );
}
else
break;
@ -1551,21 +1526,9 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet )
if( evt->IsActivate() )
break; // exit unconditionally
}
else if( evt->IsClick( BUT_LEFT ) )
else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &SCH_ACTIONS::finishSheet ) )
{
if( m_frame->GetToolId() == ID_POPUP_SCH_RESIZE_SHEET )
{
m_frame->SaveUndoItemInUndoList( aSheet );
m_frame->OnModify();
m_view->ClearPreview();
m_view->Hide( aSheet, false );
m_frame->RefreshItem( aSheet );
m_frame->GetScreen()->SetCurItem( nullptr );
break; // resize sheet is a single-shot command; when we're done we're done
}
else if( !aSheet )
if( !aSheet && !evt->IsAction( &SCH_ACTIONS::finishSheet ) )
{
aSheet = new SCH_SHEET( (wxPoint) cursorPos );
@ -1575,30 +1538,30 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet )
aSheet->SetScreen( NULL );
sizeSheet( aSheet, cursorPos );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, aSheet );
m_selectionTool->AddItemToSel( aSheet );
m_view->ClearPreview();
m_view->AddToPreview( aSheet->Clone() );
m_frame->SetRepeatItem( nullptr );
m_frame->GetScreen()->SetCurItem( aSheet );
}
else
else if( aSheet )
{
aSheet = nullptr;
m_view->ClearPreview();
m_frame->GetScreen()->SetCurItem( nullptr );
}
}
else if( evt->IsAction( &SCH_ACTIONS::finishSheet ) )
{
if( aSheet )
{
m_frame->AddItemToScreenAndUndoList( aSheet );
aSheet = nullptr;
m_view->ClearPreview();
if( !aSheet->IsNew() )
{
m_view->Hide( aSheet, false );
m_frame->RefreshItem( aSheet );
m_frame->OnModify();
}
aSheet = nullptr;
m_frame->GetScreen()->SetCurItem( nullptr );
if( m_frame->GetToolId() == ID_POPUP_SCH_RESIZE_SHEET )
break; // resize sheet is a single-shot command; when we're done we're done
}
}
else if( evt->IsMotion() )

View File

@ -187,16 +187,8 @@ bool SCH_EDIT_TOOL::Init()
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
SCH_DRAWING_TOOL* drawingTool = m_toolMgr->GetTool<SCH_DRAWING_TOOL>();
if( !m_selectionTool )
{
DisplayError( NULL, _( "eeshema.InteractiveSelection tool is not available" ) );
return false;
}
else if( !drawingTool )
{
DisplayError( NULL, _( "eeshema.InteractiveDrawing tool is not available" ) );
return false;
}
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
wxASSERT_MSG( drawingTool, "eeshema.InteractiveDrawing tool is not available" );
auto activeToolCondition = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED );
@ -777,7 +769,7 @@ void SCH_EDIT_TOOL::selectConnectedDragItems( SCH_ITEM* aSourceItem, wxPoint aPo
if( doSelect )
{
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, item );
m_selectionTool->AddItemToSel( item, true /*quiet mode*/ );
saveCopyInUndoList( item, UR_CHANGED, true );
}
}
@ -1247,7 +1239,7 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
m_frame->AddToScreen( newItem );
m_frame->SaveCopyInUndoList( newItem, UR_NEW );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, newItem );
m_selectionTool->AddItemToSel( newItem );
if( performDrag )
{

View File

@ -64,11 +64,7 @@ bool SCH_INSPECTION_TOOL::Init()
m_frame = getEditFrame<SCH_EDIT_FRAME>();
m_selectionTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
if( !m_selectionTool )
{
DisplayError( NULL, _( "eeshema.InteractiveSelection tool is not available" ) );
return false;
}
wxASSERT_MSG( m_selectionTool, "eeshema.InteractiveSelection tool is not available" );
auto singleMarkerCondition = SELECTION_CONDITIONS::OnlyType( SCH_MARKER_T )
&& SELECTION_CONDITIONS::Count( 1 );

View File

@ -54,7 +54,7 @@ TOOL_ACTION SCH_ACTIONS::selectNode( "eeschema.InteractiveSelection.SelectNode",
TOOL_ACTION SCH_ACTIONS::selectConnection( "eeschema.InteractiveSelection.SelectConnection",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SELECT_CONNECTION ),
_( "Select Node" ), _( "Select a connection item under the cursor" ), nullptr );
_( "Select Connection" ), _( "Select a complete connection" ), nullptr );
TOOL_ACTION SCH_ACTIONS::selectionMenu( "eeschema.InteractiveSelection.SelectionMenu",
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
@ -565,18 +565,21 @@ int SCH_SELECTION_TOOL::AddItemsToSel( const TOOL_EVENT& aEvent )
int SCH_SELECTION_TOOL::AddItemToSel( const TOOL_EVENT& aEvent )
{
// Check if there is an item to be selected
SCH_ITEM* item = aEvent.Parameter<SCH_ITEM*>();
AddItemToSel( aEvent.Parameter<SCH_ITEM*>() );
return 0;
}
if( item )
void SCH_SELECTION_TOOL::AddItemToSel( SCH_ITEM* aItem, bool aQuietMode )
{
if( aItem )
{
select( item );
select( aItem );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
if( !aQuietMode )
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
}
return 0;
}
@ -598,18 +601,21 @@ int SCH_SELECTION_TOOL::RemoveItemsFromSel( const TOOL_EVENT& aEvent )
int SCH_SELECTION_TOOL::RemoveItemFromSel( const TOOL_EVENT& aEvent )
{
// Check if there is an item to be selected
SCH_ITEM* item = aEvent.Parameter<SCH_ITEM*>();
RemoveItemFromSel( aEvent.Parameter<SCH_ITEM*>() );
return 0;
}
if( item )
void SCH_SELECTION_TOOL::RemoveItemFromSel( SCH_ITEM* aItem, bool aQuietMode )
{
if( aItem )
{
unselect( item );
unselect( aItem );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
if( !aQuietMode )
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
}
return 0;
}
@ -789,9 +795,6 @@ void SCH_SELECTION_TOOL::toggleSelection( SCH_ITEM* aItem, bool aForce )
void SCH_SELECTION_TOOL::select( SCH_ITEM* aItem )
{
if( aItem->IsSelected() )
return;
highlight( aItem, SELECTED, &m_selection );
if( m_frame )
@ -812,9 +815,6 @@ void SCH_SELECTION_TOOL::select( SCH_ITEM* aItem )
void SCH_SELECTION_TOOL::unselect( SCH_ITEM* aItem )
{
if( !aItem->IsSelected() )
return;
unhighlight( aItem, SELECTED, &m_selection );
if( m_frame && m_frame->GetScreen()->GetCurItem() == aItem )

View File

@ -91,9 +91,11 @@ public:
bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false );
int AddItemToSel( const TOOL_EVENT& aEvent );
void AddItemToSel( SCH_ITEM* aItem, bool aQuietMode = false );
int AddItemsToSel( const TOOL_EVENT& aEvent );
int RemoveItemFromSel( const TOOL_EVENT& aEvent );
void RemoveItemFromSel( SCH_ITEM* aItem, bool aQuietMode = false );
int RemoveItemsFromSel( const TOOL_EVENT& aEvent );
///> Find (but don't select) node under cursor

View File

@ -73,6 +73,9 @@ public:
virtual void Add( EDA_ITEM* aItem )
{
// We're not sorting here; this is just a time-optimized way to do an
// inclusion check. std::lower_bound will return the first i >= aItem
// and the second i > aItem check rules out i == aItem.
ITER i = std::lower_bound( m_items.begin(), m_items.end(), aItem );
if( i == m_items.end() || *i > aItem )