pcbnew: Locked deletion prompting

Instead of a nag screen for locked items, we allow first the unlocked
items to be deleted and then, with a repeated request, the locked items.

This adds a popup cursor window informing the user of the option for
repeating the delete

Fixes: lp:1806507
* https://bugs.launchpad.net/kicad/+bug/1806507
This commit is contained in:
Seth Hillbrand 2018-12-12 17:22:27 -08:00
parent 9ef3997e1e
commit 1c99784e92
4 changed files with 55 additions and 8 deletions

View File

@ -213,7 +213,7 @@ void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
EDIT_TOOL::EDIT_TOOL() :
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
m_dragging( false )
m_dragging( false ), m_lockedSelected( false )
{
}
@ -553,8 +553,10 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
{
break; // Finish
}
} while( ( evt = Wait() ) ); //Should be assignment not equality test
m_lockedSelected = false;
controls->ForceCursorPosition( false );
controls->ShowCursor( false );
controls->SetSnapping( false );
@ -864,26 +866,36 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() )
return 0;
std::vector<BOARD_ITEM*> lockedItems;
// get a copy instead of reference (as we're going to clear the selection before removing items)
auto selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } );
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } );
// is this "alternative" remove?
bool isHover = selectionCopy.IsHover();
const bool isAlt = aEvent.Parameter<intptr_t>() == (int) PCB_ACTIONS::REMOVE_FLAGS::ALT;
// in "alternative" mode, deletion is not just a simple list of selected items,
// it removes whole tracks, not just segments
if( isAlt && selectionCopy.IsHover()
if( isAlt && isHover
&& ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
{
m_toolMgr->RunAction( PCB_ACTIONS::expandSelectedConnection, true );
selectionCopy = m_selectionTool->GetSelection();
}
if( selectionCopy.Empty() )
return 0;
if( !m_lockedSelected )
{
// Second RequestSelection removes locked items but keeps a copy of their pointers
selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED ); }, &lockedItems );
}
// As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -919,6 +931,29 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
m_commit->Push( _( "Delete" ) );
if( !m_lockedSelected && lockedItems.size() > 0 )
{
///> Popup nag for deleting locked items
STATUS_TEXT_POPUP statusPopup( frame() );
m_lockedSelected = true;
m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &lockedItems );
statusPopup.SetText( _( "Delete again to remove locked items" ) );
statusPopup.Expire( 2000 );
statusPopup.Popup();
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
Activate();
while( m_lockedSelected && statusPopup.IsShown() )
{
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
Wait();
}
}
m_lockedSelected = false;
return 0;
}

View File

@ -29,6 +29,7 @@
#include <math/vector2d.h>
#include <tools/pcb_tool.h>
#include <tools/selection_tool.h>
#include <status_popup.h>
class BOARD_COMMIT;
@ -48,7 +49,6 @@ class CONNECTIVITY_DATA;
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags );
/**
* Class EDIT_TOOL
*
@ -193,6 +193,9 @@ private:
///> Flag determining if anything is being dragged right now
bool m_dragging;
///> Flag determining whether we are prompting for locked removal
bool m_lockedSelected;
///> Last cursor position (needed for getModificationPoint() to avoid changes
///> of edit reference point).
VECTOR2I m_cursor;

View File

@ -395,7 +395,8 @@ static EDA_RECT getRect( const BOARD_ITEM* aItem )
}
SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter )
SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter,
std::vector<BOARD_ITEM*>* aFiltered )
{
bool selectionEmpty = m_selection.Empty();
m_selection.SetIsHover( selectionEmpty );
@ -429,6 +430,12 @@ SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilt
std::set_difference( m_selection.begin(), m_selection.end(), collector.begin(), collector.end(),
std::back_inserter( diff ) );
if( aFiltered )
{
for( auto item : diff )
aFiltered->push_back( static_cast<BOARD_ITEM*>( item ) );
}
/**
* Once we find the adjustments to m_selection that are required by the client filter, we
* apply them both

View File

@ -93,8 +93,10 @@ public:
* Returns the current selection set, filtered according to aFlags
* and aClientFilter.
* If the set is empty, performs the legacy-style hover selection.
* @param aFiltered is an optional vector, that is filled with items removed by the filter
*/
SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter );
SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter,
std::vector<BOARD_ITEM*>* aFiltered = NULL );
inline TOOL_MENU& GetToolMenu()