Move SanitizePads to CLIENT_SELECTION_FILTER architecture.
This not only reduces the number of different mechanisms, but will also reduce (yet again) the number of Clarify Selection pop-ups (because the CLIENT_SELECTION_FILTER runs before the pop-up, while SanitizePads ran after it). Fixes: lp:1710451 * https://bugs.launchpad.net/kicad/+bug/1710451 (cherry picked from commit e50a993)
This commit is contained in:
parent
31aebe6920
commit
05ef6f05d1
|
@ -260,31 +260,6 @@ SELECTION& GERBVIEW_SELECTION_TOOL::GetSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SELECTION& GERBVIEW_SELECTION_TOOL::RequestSelection( int aFlags )
|
|
||||||
{
|
|
||||||
std::vector<EDA_ITEM*> removed_items;
|
|
||||||
if( m_selection.Empty() )
|
|
||||||
{
|
|
||||||
m_toolMgr->RunAction( GERBVIEW_ACTIONS::selectionCursor, true, 0 );
|
|
||||||
m_selection.SetIsHover( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Be careful with iterators: items can be removed from list that invalidate iterators.
|
|
||||||
for( auto item : m_selection )
|
|
||||||
{
|
|
||||||
if( ( aFlags & SELECTION_EDITABLE ) && item->Type() == PCB_MARKER_T )
|
|
||||||
removed_items.push_back( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now safely remove the items from the selection
|
|
||||||
for( auto item : removed_items )
|
|
||||||
unselect( static_cast<EDA_ITEM *>( item ) );
|
|
||||||
|
|
||||||
return m_selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GERBVIEW_SELECTION_TOOL::toggleSelection( EDA_ITEM* aItem )
|
void GERBVIEW_SELECTION_TOOL::toggleSelection( EDA_ITEM* aItem )
|
||||||
{
|
{
|
||||||
if( aItem->IsSelected() )
|
if( aItem->IsSelected() )
|
||||||
|
|
|
@ -72,14 +72,6 @@ public:
|
||||||
*/
|
*/
|
||||||
SELECTION& GetSelection();
|
SELECTION& GetSelection();
|
||||||
|
|
||||||
/**
|
|
||||||
* Function RequestSelection()
|
|
||||||
*
|
|
||||||
* Returns the current selection set, filtered according to aFlags.
|
|
||||||
* If the set is empty, performs the legacy-style hover selection.
|
|
||||||
*/
|
|
||||||
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT );
|
|
||||||
|
|
||||||
inline TOOL_MENU& GetToolMenu()
|
inline TOOL_MENU& GetToolMenu()
|
||||||
{
|
{
|
||||||
return m_menu;
|
return m_menu;
|
||||||
|
|
|
@ -231,21 +231,5 @@ enum SELECTION_LOCK_FLAGS
|
||||||
SELECTION_LOCKED = 2
|
SELECTION_LOCKED = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selection type flags for RequestSelection()
|
|
||||||
enum SELECTION_TYPE_FLAGS
|
|
||||||
{
|
|
||||||
// Items that can be deleted (but not necessarily modified, eg. DRC markers)
|
|
||||||
SELECTION_DELETABLE = 1,
|
|
||||||
// Items that can be edited (moved, rotated, properties)
|
|
||||||
SELECTION_EDITABLE = 2,
|
|
||||||
// Remove pads without a host module
|
|
||||||
SELECTION_SANITIZE_PADS = 4,
|
|
||||||
// Request a hover-only selection
|
|
||||||
SELECTION_HOVER = 8,
|
|
||||||
// Select locked parts without asking the user
|
|
||||||
SELECTION_FORCE_UNLOCK = 16,
|
|
||||||
|
|
||||||
SELECTION_DEFAULT = 0x7
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -259,6 +259,56 @@ static wxPoint getAnchorPoint( const SELECTION &selection, const MOVE_PARAMETERS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void filterItems( GENERAL_COLLECTOR& aCollector, bool sanitizePads, bool ensureEditable )
|
||||||
|
{
|
||||||
|
// Iterate from the back so we don't have to worry about removals.
|
||||||
|
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
BOARD_ITEM* item = aCollector[ i ];
|
||||||
|
|
||||||
|
if( sanitizePads && item->Type() == PCB_PAD_T )
|
||||||
|
{
|
||||||
|
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
||||||
|
|
||||||
|
// case 1: module (or its pads) are locked
|
||||||
|
if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
|
||||||
|
{
|
||||||
|
aCollector.Remove( item );
|
||||||
|
|
||||||
|
if( !mod->IsLocked() && !aCollector.HasItem( mod ) )
|
||||||
|
aCollector.Append( mod );
|
||||||
|
}
|
||||||
|
|
||||||
|
// case 2: selection contains both the module and its pads - remove the pads
|
||||||
|
if( mod && aCollector.HasItem( mod ) )
|
||||||
|
aCollector.Remove( item );
|
||||||
|
}
|
||||||
|
else if( ensureEditable && item->Type() == PCB_MARKER_T )
|
||||||
|
{
|
||||||
|
aCollector.Remove( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SanitizePadsEnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
|
||||||
|
{
|
||||||
|
filterItems( aCollector, true, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SanitizePadsFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
|
||||||
|
{
|
||||||
|
filterItems( aCollector, true, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector )
|
||||||
|
{
|
||||||
|
filterItems( aCollector, false, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EDIT_TOOL::EDIT_TOOL() :
|
EDIT_TOOL::EDIT_TOOL() :
|
||||||
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
|
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
|
||||||
m_dragging( false )
|
m_dragging( false )
|
||||||
|
@ -286,6 +336,13 @@ bool EDIT_TOOL::Init()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
|
|
||||||
|
m_defaultSelectionFilter = SanitizePadsEnsureEditableFilter;
|
||||||
|
|
||||||
|
if( editFrame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||||
|
m_defaultSelectionFilter = EnsureEditableFilter;
|
||||||
|
|
||||||
auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
|
auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
|
||||||
return m_editModules;
|
return m_editModules;
|
||||||
};
|
};
|
||||||
|
@ -388,7 +445,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
// Be sure that there is at least one item that we can modify. If nothing was selected before,
|
// Be sure that there is at least one item that we can modify. If nothing was selected before,
|
||||||
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
||||||
auto& selection = m_selectionTool->RequestSelection( SELECTION_DEFAULT );
|
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -643,10 +700,9 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
|
|
||||||
const auto& selection = m_selectionTool->RequestSelection(
|
const auto& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
SELECTION_EDITABLE | SELECTION_DELETABLE | SELECTION_FORCE_UNLOCK );
|
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Tracks & vias are treated in a special way:
|
// Tracks & vias are treated in a special way:
|
||||||
|
@ -689,7 +745,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||||
|
|
||||||
auto& selection = m_selectionTool->RequestSelection();
|
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -760,7 +816,7 @@ static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
|
||||||
|
|
||||||
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto& selection = m_selectionTool->RequestSelection();
|
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -834,7 +890,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto& selection = m_selectionTool->RequestSelection();
|
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -875,7 +931,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// get a copy instead of reference (as we're going to clear the selectio before removing items)
|
// get a copy instead of reference (as we're going to clear the selectio before removing items)
|
||||||
auto selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
|
auto selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -909,7 +965,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const auto& selection = m_selectionTool->RequestSelection();
|
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -966,7 +1022,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
|
bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
|
||||||
|
|
||||||
// Be sure that there is at least one item that we can modify
|
// Be sure that there is at least one item that we can modify
|
||||||
const auto& selection = m_selectionTool->RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
|
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1111,7 +1167,7 @@ private:
|
||||||
|
|
||||||
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const auto& selection = m_selectionTool->RequestSelection();
|
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1139,7 +1195,7 @@ void EDIT_TOOL::FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector
|
||||||
|
|
||||||
int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const auto& selection = m_selectionTool->RequestSelection( 0, FootprintFilter );
|
const auto& selection = m_selectionTool->RequestSelection( FootprintFilter );
|
||||||
|
|
||||||
bool updateMode = aEvent.IsAction( &PCB_ACTIONS::updateFootprints );
|
bool updateMode = aEvent.IsAction( &PCB_ACTIONS::updateFootprints );
|
||||||
|
|
||||||
|
@ -1323,7 +1379,7 @@ bool EDIT_TOOL::updateModificationPoint( SELECTION& aSelection )
|
||||||
|
|
||||||
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const auto& selection = m_selectionTool->RequestSelection( 0, FootprintFilter );
|
const auto& selection = m_selectionTool->RequestSelection( FootprintFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1388,7 +1444,7 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
std::vector<MSG_PANEL_ITEM> msgItems = { item1 };
|
std::vector<MSG_PANEL_ITEM> msgItems = { item1 };
|
||||||
|
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection();
|
SELECTION& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -28,13 +28,26 @@
|
||||||
|
|
||||||
#include <math/vector2d.h>
|
#include <math/vector2d.h>
|
||||||
#include <tools/pcb_tool.h>
|
#include <tools/pcb_tool.h>
|
||||||
|
#include <tools/selection_tool.h>
|
||||||
|
|
||||||
|
|
||||||
class BOARD_COMMIT;
|
class BOARD_COMMIT;
|
||||||
class BOARD_ITEM;
|
class BOARD_ITEM;
|
||||||
class SELECTION_TOOL;
|
|
||||||
class CONNECTIVITY_DATA;
|
class CONNECTIVITY_DATA;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SanitizePadsEnsureEditableFilter
|
||||||
|
*
|
||||||
|
* A CLIENT_SELECTION_FILTER which promotes pad selections to their parent modules and
|
||||||
|
* excludes non-editable items (such as markers).
|
||||||
|
*/
|
||||||
|
void SanitizePadsEnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||||
|
|
||||||
|
void SanitizePadsFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||||
|
|
||||||
|
void EnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class EDIT_TOOL
|
* Class EDIT_TOOL
|
||||||
*
|
*
|
||||||
|
@ -172,6 +185,8 @@ private:
|
||||||
///> Selection tool used for obtaining selected items
|
///> Selection tool used for obtaining selected items
|
||||||
SELECTION_TOOL* m_selectionTool;
|
SELECTION_TOOL* m_selectionTool;
|
||||||
|
|
||||||
|
CLIENT_SELECTION_FILTER m_defaultSelectionFilter;
|
||||||
|
|
||||||
///> Flag determining if anything is being dragged right now
|
///> Flag determining if anything is being dragged right now
|
||||||
bool m_dragging;
|
bool m_dragging;
|
||||||
|
|
||||||
|
@ -191,21 +206,6 @@ private:
|
||||||
bool changeTrackWidthOnClick( const SELECTION& selection );
|
bool changeTrackWidthOnClick( const SELECTION& selection );
|
||||||
bool pickCopyReferencePoint( VECTOR2I& aP );
|
bool pickCopyReferencePoint( VECTOR2I& aP );
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function hoverSelection()
|
|
||||||
*
|
|
||||||
* If there are no items currently selected, it tries to choose the
|
|
||||||
* item that is under he cursor or displays a disambiguation menu
|
|
||||||
* if there are multiple items.
|
|
||||||
*
|
|
||||||
* @param aSanitize sanitize selection using SanitizeSelection()
|
|
||||||
* @return true if the eventual selection contains any items, or
|
|
||||||
* false if it fails to select any items.
|
|
||||||
*/
|
|
||||||
bool hoverSelection( bool aSanitize = true );
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<BOARD_COMMIT> m_commit;
|
std::unique_ptr<BOARD_COMMIT> m_commit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -797,10 +797,8 @@ static bool deleteItem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||||
wxCHECK( selectionTool, false );
|
wxCHECK( selectionTool, false );
|
||||||
|
|
||||||
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
|
||||||
selectionTool->SanitizeSelection();
|
|
||||||
|
|
||||||
const SELECTION& selection = selectionTool->GetSelection();
|
const SELECTION& selection = selectionTool->RequestSelection( SanitizePadsFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "placement_tool.h"
|
#include "placement_tool.h"
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
|
#include "edit_tool.h"
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
|
@ -252,7 +253,7 @@ int ALIGN_DISTRIBUTE_TOOL::checkLockedStatus( const SELECTION &selection ) const
|
||||||
int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -292,7 +293,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -347,7 +348,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
|
||||||
int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -402,7 +403,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignRight( const TOOL_EVENT& aEvent )
|
||||||
int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -442,7 +443,7 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -483,7 +484,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
||||||
int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection( SELECTION_EDITABLE );
|
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -524,8 +525,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
||||||
int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
SELECTION& selection = m_selectionTool->RequestSelection( SanitizePadsEnsureEditableFilter );
|
||||||
SELECTION_EDITABLE | SELECTION_SANITIZE_PADS );
|
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -611,8 +611,7 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersHorizontally( ALIGNMENT_RECTS &it
|
||||||
int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
SELECTION& selection = m_selectionTool->RequestSelection( SanitizePadsEnsureEditableFilter );
|
||||||
SELECTION_EDITABLE | SELECTION_SANITIZE_PADS );
|
|
||||||
|
|
||||||
if( selection.Size() <= 1 )
|
if( selection.Size() <= 1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@ using namespace std::placeholders;
|
||||||
#include "position_relative_tool.h"
|
#include "position_relative_tool.h"
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
|
#include "edit_tool.h"
|
||||||
#include "picker_tool.h"
|
#include "picker_tool.h"
|
||||||
|
|
||||||
#include <dialogs/dialog_position_relative.h>
|
#include <dialogs/dialog_position_relative.h>
|
||||||
|
@ -84,7 +85,7 @@ bool POSITION_RELATIVE_TOOL::Init()
|
||||||
|
|
||||||
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
const auto& selection = m_selectionTool->RequestSelection();
|
const auto& selection = m_selectionTool->RequestSelection( SanitizePadsEnsureEditableFilter );
|
||||||
|
|
||||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -119,10 +120,8 @@ static bool selectPRitem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||||
wxCHECK( positionRelativeTool, false );
|
wxCHECK( positionRelativeTool, false );
|
||||||
|
|
||||||
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
|
||||||
selectionTool->SanitizeSelection();
|
|
||||||
|
|
||||||
const SELECTION& selection = selectionTool->GetSelection();
|
const SELECTION& selection = selectionTool->RequestSelection( SanitizePadsFilter );
|
||||||
|
|
||||||
if( selection.Empty() )
|
if( selection.Empty() )
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -380,34 +380,33 @@ SELECTION& SELECTION_TOOL::GetSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SELECTION& SELECTION_TOOL::RequestSelection( int aFlags, CLIENT_SELECTION_FILTER aClientFilter )
|
SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter )
|
||||||
{
|
{
|
||||||
std::vector<EDA_ITEM*> removed_items;
|
|
||||||
bool selectionEmpty = m_selection.Empty();
|
bool selectionEmpty = m_selection.Empty();
|
||||||
m_selection.SetIsHover( selectionEmpty );
|
m_selection.SetIsHover( selectionEmpty );
|
||||||
|
|
||||||
if( selectionEmpty )
|
if( selectionEmpty )
|
||||||
{
|
{
|
||||||
if( aFlags & SELECTION_FORCE_UNLOCK )
|
|
||||||
m_locked = false;
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, aClientFilter );
|
||||||
m_selection.ClearReferencePoint();
|
m_selection.ClearReferencePoint();
|
||||||
}
|
}
|
||||||
|
else if( aClientFilter )
|
||||||
// Be careful with iterators: items can be removed from list that invalidate iterators.
|
|
||||||
for( auto item : m_selection )
|
|
||||||
{
|
{
|
||||||
if( ( aFlags & SELECTION_EDITABLE ) && item->Type() == PCB_MARKER_T )
|
GENERAL_COLLECTOR collector;
|
||||||
removed_items.push_back( item );
|
|
||||||
|
for( auto item : m_selection.Items() )
|
||||||
|
collector.Append( item );
|
||||||
|
|
||||||
|
aClientFilter( VECTOR2I(), collector );
|
||||||
|
|
||||||
|
clearSelection();
|
||||||
|
|
||||||
|
for( int i = 0; i < collector.GetCount(); ++i )
|
||||||
|
{
|
||||||
|
m_additive = true;
|
||||||
|
toggleSelection( collector[ i ] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now safely remove the items from the selection
|
|
||||||
for( auto item : removed_items )
|
|
||||||
unselect( static_cast<BOARD_ITEM *>( item ) );
|
|
||||||
|
|
||||||
if( aFlags & SELECTION_SANITIZE_PADS )
|
|
||||||
SanitizeSelection();
|
|
||||||
|
|
||||||
return m_selection;
|
return m_selection;
|
||||||
}
|
}
|
||||||
|
@ -2228,58 +2227,6 @@ int SELECTION_TOOL::updateSelection( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SELECTION_TOOL::SanitizeSelection()
|
|
||||||
{
|
|
||||||
std::set<BOARD_ITEM*> rejected;
|
|
||||||
std::set<BOARD_ITEM*> added;
|
|
||||||
|
|
||||||
if( !m_editModules )
|
|
||||||
{
|
|
||||||
for( auto i : m_selection )
|
|
||||||
{
|
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
|
||||||
if( item->Type() == PCB_PAD_T )
|
|
||||||
{
|
|
||||||
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
|
||||||
|
|
||||||
// case 1: module (or its pads) are locked
|
|
||||||
if( mod && ( mod->PadsLocked() || mod->IsLocked() ) )
|
|
||||||
{
|
|
||||||
rejected.insert( item );
|
|
||||||
|
|
||||||
if( !mod->IsLocked() && !mod->IsSelected() )
|
|
||||||
added.insert( mod );
|
|
||||||
}
|
|
||||||
|
|
||||||
// case 2: multi-item selection contains both the module and its pads - remove the pads
|
|
||||||
if( mod && m_selection.Contains( mod ) )
|
|
||||||
rejected.insert( item );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !rejected.empty() )
|
|
||||||
{
|
|
||||||
for( BOARD_ITEM* item : rejected )
|
|
||||||
unselect( item );
|
|
||||||
|
|
||||||
// Inform other potentially interested tools
|
|
||||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !added.empty() )
|
|
||||||
{
|
|
||||||
for( BOARD_ITEM* item : added )
|
|
||||||
select( item );
|
|
||||||
|
|
||||||
// Inform other potentially interested tools
|
|
||||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
||||||
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
||||||
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
||||||
|
|
|
@ -94,8 +94,7 @@ public:
|
||||||
* and aClientFilter.
|
* and aClientFilter.
|
||||||
* If the set is empty, performs the legacy-style hover selection.
|
* If the set is empty, performs the legacy-style hover selection.
|
||||||
*/
|
*/
|
||||||
SELECTION& RequestSelection( int aFlags = SELECTION_DEFAULT,
|
SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter );
|
||||||
CLIENT_SELECTION_FILTER aClientFilter = NULL );
|
|
||||||
|
|
||||||
|
|
||||||
inline TOOL_MENU& GetToolMenu()
|
inline TOOL_MENU& GetToolMenu()
|
||||||
|
@ -112,10 +111,6 @@ public:
|
||||||
///> Clear current selection event handler.
|
///> Clear current selection event handler.
|
||||||
int ClearSelection( const TOOL_EVENT& aEvent );
|
int ClearSelection( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
///> Makes sure a group selection does not contain items that would cause
|
|
||||||
///> conflicts when moving/rotating together (e.g. a footprint and one of the same footprint's pads)
|
|
||||||
bool SanitizeSelection();
|
|
||||||
|
|
||||||
///> Item selection event handler.
|
///> Item selection event handler.
|
||||||
int SelectItem( const TOOL_EVENT& aEvent );
|
int SelectItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue