Move lock checks to CLIENT_SELECTION_FILTER.
Also checks render item visibility as well as layer visibility when making selections. Fixes: lp:1066220 * https://bugs.launchpad.net/kicad/+bug/1066220 Fixes: lp:1541756 * https://bugs.launchpad.net/kicad/+bug/1541756
This commit is contained in:
parent
686f1b878b
commit
37f7faf433
|
@ -262,11 +262,13 @@ NET_SELECTOR::NET_SELECTOR( wxWindow *parent, wxWindowID id,
|
|||
m_netSelectorPopup( nullptr )
|
||||
{ }
|
||||
|
||||
|
||||
void NET_SELECTOR::DoSetPopupControl( wxComboPopup* aPopup )
|
||||
{
|
||||
m_popup = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void NET_SELECTOR::OnButtonClick()
|
||||
{
|
||||
wxRect comboRect = GetScreenRect();
|
||||
|
@ -287,11 +289,13 @@ void NET_SELECTOR::OnButtonClick()
|
|||
SetSelectedNetcode( popup->GetSelectedNetcode() );
|
||||
}
|
||||
|
||||
|
||||
void NET_SELECTOR::SetNetInfo( NETINFO_LIST* aNetInfoList )
|
||||
{
|
||||
m_netinfoList = aNetInfoList;
|
||||
}
|
||||
|
||||
|
||||
void NET_SELECTOR::SetSelectedNetcode( int aNetcode )
|
||||
{
|
||||
m_netcode = aNetcode;
|
||||
|
@ -311,17 +315,20 @@ void NET_SELECTOR::SetSelectedNetcode( int aNetcode )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void NET_SELECTOR::SetIndeterminate()
|
||||
{
|
||||
m_netcode = -1;
|
||||
SetValue( INDETERMINATE );
|
||||
}
|
||||
|
||||
|
||||
bool NET_SELECTOR::IsIndeterminate()
|
||||
{
|
||||
return m_netcode == -1;
|
||||
}
|
||||
|
||||
|
||||
int NET_SELECTOR::GetSelectedNetcode()
|
||||
{
|
||||
return m_netcode;
|
||||
|
|
|
@ -422,7 +422,7 @@ public:
|
|||
* @param module
|
||||
* @param aDC (can be NULL ) = the current Device Context, to draw the new footprint
|
||||
*/
|
||||
void AddModuleToBoard( MODULE* module, wxDC* aDC = nullptr );
|
||||
virtual void AddModuleToBoard( MODULE* module );
|
||||
|
||||
/**
|
||||
* Function SelectFootprintFromLibBrowser
|
||||
|
|
|
@ -402,14 +402,22 @@ void FOOTPRINT_EDIT_FRAME::restoreLastFootprint()
|
|||
MODULE* module = loadFootprint( id );
|
||||
|
||||
if( module )
|
||||
{
|
||||
m_footprintNameWhenLoaded = curFootprintName;
|
||||
GetBoard()->Add( module );
|
||||
}
|
||||
AddModuleToBoard( module );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::AddModuleToBoard( MODULE* aFootprint )
|
||||
{
|
||||
m_footprintNameWhenLoaded = aFootprint->GetFPID().GetLibItemName();
|
||||
|
||||
// Pads are always editable in Footprint Editor
|
||||
aFootprint->SetPadsLocked( false );
|
||||
|
||||
PCB_BASE_EDIT_FRAME::AddModuleToBoard( aFootprint );
|
||||
}
|
||||
|
||||
|
||||
const wxChar* FOOTPRINT_EDIT_FRAME::GetFootprintEditorFrameName()
|
||||
{
|
||||
return FOOTPRINT_EDIT_FRAME_NAME;
|
||||
|
|
|
@ -478,6 +478,12 @@ public:
|
|||
*/
|
||||
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override;
|
||||
|
||||
/**
|
||||
* Override from PCB_BASE_EDIT_FRAME which adds a module to the editor's dummy board,
|
||||
* NOT to the user's PCB.
|
||||
*/
|
||||
void AddModuleToBoard( MODULE* module ) override;
|
||||
|
||||
/**
|
||||
* Allows Modedit to install its preferences panel into the preferences dialog.
|
||||
*/
|
||||
|
|
|
@ -297,7 +297,6 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
SetCrossHairPosition( wxPoint( 0, 0 ) );
|
||||
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
|
||||
AddModuleToBoard( module );
|
||||
|
||||
// Initialize data relative to nets and netclasses (for a new
|
||||
|
@ -359,8 +358,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
SetCrossHairPosition( wxPoint( 0, 0 ) );
|
||||
|
||||
// Add the new object to board
|
||||
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
|
||||
GetBoard()->Add( module, ADD_APPEND );
|
||||
AddModuleToBoard( module );
|
||||
|
||||
// Initialize data relative to nets and netclasses (for a new
|
||||
// module the defaults are used)
|
||||
|
@ -509,7 +507,6 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
SetCrossHairPosition( wxPoint( 0, 0 ) );
|
||||
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
|
||||
AddModuleToBoard( module );
|
||||
|
||||
if( GetBoard()->m_Modules )
|
||||
|
|
|
@ -321,8 +321,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module( const wxString& aName )
|
|||
module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
|
||||
|
||||
// Insert footprint in list
|
||||
m_footprintNameWhenLoaded = module->GetFPID().GetLibItemName();
|
||||
GetBoard()->Add( module );
|
||||
AddModuleToBoard( module );
|
||||
|
||||
// Display info :
|
||||
SetMsgPanel( module );
|
||||
|
|
|
@ -121,8 +121,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
|
|||
newModule->ClearFlags();
|
||||
newModule->RunOnChildren( std::bind( &clearModuleItemFlags, _1 ) );
|
||||
|
||||
m_footprintNameWhenLoaded = newModule->GetFPID().GetLibItemName();
|
||||
GetBoard()->Add( newModule );
|
||||
AddModuleToBoard( newModule );
|
||||
|
||||
// Clear references to any net info, because the footprint editor
|
||||
// does know any thing about nets handled by the current edited board.
|
||||
|
@ -271,41 +270,6 @@ MODULE* PCB_BASE_FRAME::SelectFootprintFromLibTree( bool aAllowBrowser )
|
|||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::AddModuleToBoard( MODULE* module, wxDC* aDC )
|
||||
{
|
||||
if( module )
|
||||
{
|
||||
GetBoard()->Add( module, ADD_APPEND );
|
||||
|
||||
module->SetFlags( IS_NEW );
|
||||
module->SetLink( 0 );
|
||||
|
||||
if( IsGalCanvasActive() )
|
||||
module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
|
||||
else
|
||||
module->SetPosition( GetCrossHairPosition() );
|
||||
|
||||
module->SetTimeStamp( GetNewTimeStamp() );
|
||||
GetBoard()->m_Status_Pcb = 0;
|
||||
|
||||
// Put it on FRONT layer,
|
||||
// (Can be stored flipped if the lib is an archive built from a board)
|
||||
if( module->IsFlipped() )
|
||||
module->Flip( module->GetPosition() );
|
||||
|
||||
// Place it in orientation 0,
|
||||
// even if it is not saved with orientation 0 in lib
|
||||
// (Can happen if the lib is an archive built from a board)
|
||||
Rotate_Module( NULL, module, 0, false );
|
||||
|
||||
//RecalculateAllTracksNetcode();
|
||||
|
||||
if( aDC )
|
||||
module->Draw( m_canvas, aDC, GR_OR );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MODULE* PCB_BASE_FRAME::LoadFootprint( const LIB_ID& aFootprintId )
|
||||
{
|
||||
MODULE* module = NULL;
|
||||
|
|
|
@ -369,7 +369,11 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
if( module )
|
||||
{
|
||||
m_canvas->MoveCursorToCrossHair();
|
||||
AddModuleToBoard( module, aDC );
|
||||
AddModuleToBoard( module );
|
||||
|
||||
if( aDC )
|
||||
module->Draw( m_canvas, aDC, GR_OR );
|
||||
|
||||
StartMoveModule( module, aDC, false );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,6 +212,36 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
|
|||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::AddModuleToBoard( MODULE* module )
|
||||
{
|
||||
if( module )
|
||||
{
|
||||
GetBoard()->Add( module, ADD_APPEND );
|
||||
|
||||
module->SetFlags( IS_NEW );
|
||||
module->SetLink( 0 );
|
||||
|
||||
if( IsGalCanvasActive() )
|
||||
module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
|
||||
else
|
||||
module->SetPosition( GetCrossHairPosition() );
|
||||
|
||||
module->SetTimeStamp( GetNewTimeStamp() );
|
||||
GetBoard()->m_Status_Pcb = 0;
|
||||
|
||||
// Put it on FRONT layer,
|
||||
// (Can be stored flipped if the lib is an archive built from a board)
|
||||
if( module->IsFlipped() )
|
||||
module->Flip( module->GetPosition() );
|
||||
|
||||
// Place it in orientation 0,
|
||||
// even if it is not saved with orientation 0 in lib
|
||||
// (Can happen if the lib is an archive built from a board)
|
||||
module->SetOrientation( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
|
||||
{
|
||||
wxASSERT( m_Pcb );
|
||||
|
|
|
@ -169,14 +169,19 @@ TOOL_ACTION PCB_ACTIONS::cutToClipboard( "pcbnew.InteractiveEdit.CutToClipboard"
|
|||
_( "Cut" ), _( "Cut selected content to clipboard" ),
|
||||
cut_xpm );
|
||||
|
||||
void filterItems( GENERAL_COLLECTOR& aCollector, bool sanitizePads, bool ensureEditable )
|
||||
|
||||
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
|
||||
{
|
||||
// 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 )
|
||||
if( ( aFlags & EXCLUDE_LOCKED ) && item->IsLocked() )
|
||||
{
|
||||
aCollector.Remove( item );
|
||||
}
|
||||
else if( item->Type() == PCB_PAD_T )
|
||||
{
|
||||
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
||||
|
||||
|
@ -193,7 +198,7 @@ void filterItems( GENERAL_COLLECTOR& aCollector, bool sanitizePads, bool ensureE
|
|||
if( mod && aCollector.HasItem( mod ) )
|
||||
aCollector.Remove( item );
|
||||
}
|
||||
else if( ensureEditable && item->Type() == PCB_MARKER_T )
|
||||
else if( ( aFlags & EXCLUDE_TRANSIENTS ) && item->Type() == PCB_MARKER_T )
|
||||
{
|
||||
aCollector.Remove( item );
|
||||
}
|
||||
|
@ -201,24 +206,6 @@ void filterItems( GENERAL_COLLECTOR& aCollector, bool sanitizePads, bool ensureE
|
|||
}
|
||||
|
||||
|
||||
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() :
|
||||
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
|
||||
m_dragging( false )
|
||||
|
@ -246,14 +233,6 @@ bool EDIT_TOOL::Init()
|
|||
return false;
|
||||
}
|
||||
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
m_defaultSelectionFilter = SanitizePadsEnsureEditableFilter;
|
||||
|
||||
// Allow pad editing in Footprint Editor
|
||||
if( editFrame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||
m_defaultSelectionFilter = EnsureEditableFilter;
|
||||
|
||||
auto editingModuleCondition = [ this ] ( const SELECTION& aSelection ) {
|
||||
return m_editModules;
|
||||
};
|
||||
|
@ -356,7 +335,9 @@ 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,
|
||||
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
|
||||
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -622,10 +603,9 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
const auto& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
const auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
// Tracks & vias are treated in a special way:
|
||||
if( ( SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Tracks ) )( selection ) )
|
||||
|
@ -665,14 +645,13 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
updateModificationPoint( selection );
|
||||
const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
|
||||
|
||||
|
@ -742,10 +721,9 @@ static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
|
|||
|
||||
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -822,10 +800,9 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
|
||||
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -869,10 +846,9 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
|||
return 0;
|
||||
|
||||
// get a copy instead of reference (as we're going to clear the selection before removing items)
|
||||
auto selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
auto selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
// is this "alternative" remove?
|
||||
const bool isAlt = aEvent.Parameter<intptr_t>() == (int) PCB_ACTIONS::REMOVE_FLAGS::ALT;
|
||||
|
@ -930,10 +906,9 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
|||
|
||||
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
const auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -1007,7 +982,9 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
|
||||
|
||||
// Be sure that there is at least one item that we can modify
|
||||
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
const auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -1152,7 +1129,9 @@ private:
|
|||
|
||||
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
const auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -1436,7 +1415,9 @@ int EDIT_TOOL::doCopyToClipboard( bool withAnchor )
|
|||
|
||||
Activate();
|
||||
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 1;
|
||||
|
|
|
@ -36,16 +36,16 @@ class BOARD_ITEM;
|
|||
class CONNECTIVITY_DATA;
|
||||
|
||||
/**
|
||||
* Function SanitizePadsEnsureEditableFilter
|
||||
* Function EditToolSelectionFilter
|
||||
*
|
||||
* A CLIENT_SELECTION_FILTER which promotes pad selections to their parent modules and
|
||||
* excludes non-editable items (such as markers).
|
||||
* optionally excludes locked items and/or transient items (such as markers).
|
||||
*/
|
||||
void SanitizePadsEnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||
|
||||
void SanitizePadsFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||
#define EXCLUDE_LOCKED 0x0002
|
||||
#define EXCLUDE_TRANSIENTS 0x0004
|
||||
|
||||
void EnsureEditableFilter( const VECTOR2I&, GENERAL_COLLECTOR& items );
|
||||
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -189,8 +189,6 @@ private:
|
|||
///> Selection tool used for obtaining selected items
|
||||
SELECTION_TOOL* m_selectionTool;
|
||||
|
||||
CLIENT_SELECTION_FILTER m_defaultSelectionFilter;
|
||||
|
||||
///> Flag determining if anything is being dragged right now
|
||||
bool m_dragging;
|
||||
|
||||
|
|
|
@ -798,7 +798,9 @@ static bool deleteItem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
|||
|
||||
aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
const SELECTION& selection = selectionTool->RequestSelection( SanitizePadsFilter );
|
||||
const SELECTION& selection = selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED ); } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return true;
|
||||
|
|
|
@ -183,90 +183,18 @@ ALIGNMENT_RECTS GetBoundingBoxes( const SELECTION &sel )
|
|||
}
|
||||
|
||||
|
||||
void ALIGN_DISTRIBUTE_TOOL::filterPadsWithModules( SELECTION &selection )
|
||||
{
|
||||
std::set<BOARD_ITEM*> rejected;
|
||||
for( auto i : selection )
|
||||
{
|
||||
auto item = static_cast<BOARD_ITEM*>( i );
|
||||
if( item->Type() == PCB_PAD_T )
|
||||
{
|
||||
MODULE* mod = static_cast<MODULE*>( item->GetParent() );
|
||||
|
||||
// selection contains both the module and its pads - remove the pads
|
||||
if( mod && selection.Contains( mod ) )
|
||||
rejected.insert( item );
|
||||
}
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* item : rejected )
|
||||
selection.Remove( item );
|
||||
}
|
||||
|
||||
|
||||
int ALIGN_DISTRIBUTE_TOOL::checkLockedStatus( const SELECTION &selection ) const
|
||||
{
|
||||
SELECTION moving_items( selection );
|
||||
|
||||
// Remove the anchor from the list
|
||||
moving_items.Remove( moving_items.Front() );
|
||||
|
||||
bool containsLocked = false;
|
||||
|
||||
// Check if the selection contains locked items
|
||||
for( const auto& item : moving_items )
|
||||
{
|
||||
switch ( item->Type() )
|
||||
{
|
||||
case PCB_MODULE_T:
|
||||
if( static_cast< MODULE* >( item )->IsLocked() )
|
||||
containsLocked = true;
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
case PCB_MODULE_EDGE_T:
|
||||
case PCB_MODULE_TEXT_T:
|
||||
if( static_cast< MODULE* >( item->GetParent() )->IsLocked() )
|
||||
containsLocked = true;
|
||||
break;
|
||||
|
||||
default: // suppress warnings
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( containsLocked )
|
||||
{
|
||||
KIDIALOG dlg( getEditFrame< PCB_EDIT_FRAME >(),
|
||||
_( "Selection contains locked items. Do you want to continue?" ),
|
||||
_( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
|
||||
dlg.SetOKLabel( _( "Continue" ) );
|
||||
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
return SELECTION_LOCK_OVERRIDE;
|
||||
else
|
||||
return SELECTION_LOCKED;
|
||||
}
|
||||
|
||||
return SELECTION_UNLOCKED;
|
||||
}
|
||||
|
||||
|
||||
int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortTopmostY );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -296,17 +224,15 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
|||
int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortBottommostY );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -351,17 +277,15 @@ int ALIGN_DISTRIBUTE_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
|
|||
int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortLeftmostX );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -406,17 +330,15 @@ int ALIGN_DISTRIBUTE_TOOL::AlignRight( const TOOL_EVENT& aEvent )
|
|||
int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortRightmostX );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -446,17 +368,15 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
|||
int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortCenterX );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -487,17 +407,15 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
|||
int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
filterPadsWithModules( selection );
|
||||
|
||||
auto itemsToAlign = GetBoundingBoxes( selection );
|
||||
std::sort( itemsToAlign.begin(), itemsToAlign.end(), SortCenterY );
|
||||
if( checkLockedStatus( selection ) == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
@ -528,14 +446,13 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
|||
int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
||||
|
@ -614,14 +531,13 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersHorizontally( ALIGNMENT_RECTS &it
|
|||
int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
SELECTION& selection = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( selection.Size() <= 1 )
|
||||
return 0;
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
BOARD_COMMIT commit( frame );
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
|
||||
|
|
|
@ -119,11 +119,6 @@ private:
|
|||
|
||||
CONTEXT_MENU* m_placementMenu;
|
||||
|
||||
/**
|
||||
* Remove pads from a multi-unit select that also includes the pads' parents
|
||||
*/
|
||||
void filterPadsWithModules( SELECTION &selection );
|
||||
|
||||
/**
|
||||
* Check a selection to ensure locks are valid for alignment.
|
||||
*
|
||||
|
|
|
@ -80,15 +80,12 @@ bool POSITION_RELATIVE_TOOL::Init()
|
|||
int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
|
||||
CLIENT_SELECTION_FILTER filter = SanitizePadsEnsureEditableFilter;
|
||||
|
||||
// Allow pad editing in Footprint Editor
|
||||
if( editFrame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||
filter = EnsureEditableFilter;
|
||||
const auto& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
const auto& selection = m_selectionTool->RequestSelection( filter );
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED || selection.Empty() )
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
m_selection = selection;
|
||||
|
@ -148,7 +145,9 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
|
|||
picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
const SELECTION& sel = m_selectionTool->RequestSelection( EnsureEditableFilter );
|
||||
const SELECTION& sel = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
|
||||
{ EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
|
||||
|
||||
if( sel.Empty() )
|
||||
return true; // still looking for an item
|
||||
|
|
|
@ -752,16 +752,7 @@ int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
CLIENT_SELECTION_FILTER aClientFilter = aEvent.Parameter<CLIENT_SELECTION_FILTER>();
|
||||
|
||||
if( m_selection.Empty() ) // Try to find an item that could be modified
|
||||
{
|
||||
selectCursor( true, aClientFilter );
|
||||
|
||||
if( CheckLock() == SELECTION_LOCKED )
|
||||
{
|
||||
clearSelection();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
selectCursor( false, aClientFilter );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1691,10 +1682,28 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
|
|||
|
||||
if( aItem->Type() == PCB_PAD_T )
|
||||
{
|
||||
// In editor, pads are selectable if any draw layer is visible
|
||||
|
||||
auto pad = static_cast<const D_PAD*>( aItem );
|
||||
|
||||
// Check render mode (from the Items tab) first
|
||||
switch( pad->GetAttribute() )
|
||||
{
|
||||
case PAD_ATTRIB_STANDARD:
|
||||
case PAD_ATTRIB_HOLE_NOT_PLATED:
|
||||
if( !board()->IsElementVisible( LAYER_PADS_TH ) )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PAD_ATTRIB_CONN:
|
||||
case PAD_ATTRIB_SMD:
|
||||
if( pad->IsOnLayer( F_Cu ) && !board()->IsElementVisible( LAYER_PAD_FR ) )
|
||||
return false;
|
||||
else if( pad->IsOnLayer( B_Cu ) && !board()->IsElementVisible( LAYER_PAD_BK ) )
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, pads are selectable if any draw layer is visible
|
||||
|
||||
// Shortcut: check copper layer visibility
|
||||
if( board()->IsLayerVisible( F_Cu ) && pad->IsOnLayer( F_Cu ) )
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue