diff --git a/common/widgets/net_selector.cpp b/common/widgets/net_selector.cpp index bd0ce3d1c5..3dd7bcf5a9 100644 --- a/common/widgets/net_selector.cpp +++ b/common/widgets/net_selector.cpp @@ -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; diff --git a/include/pcb_base_frame.h b/include/pcb_base_frame.h index 0e554655a3..6ee8075426 100644 --- a/include/pcb_base_frame.h +++ b/include/pcb_base_frame.h @@ -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 diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index d0b8a2e16a..e49dded7e3 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -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; diff --git a/pcbnew/footprint_edit_frame.h b/pcbnew/footprint_edit_frame.h index 8c0ec1a07e..a0db4ac51c 100644 --- a/pcbnew/footprint_edit_frame.h +++ b/pcbnew/footprint_edit_frame.h @@ -478,6 +478,12 @@ public: */ bool OpenProjectFiles( const std::vector& 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. */ diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index e393e20671..d7802e7b86 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -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 ) diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index cc2c32f614..35fc93c7d6 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -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 ); diff --git a/pcbnew/load_select_footprint.cpp b/pcbnew/load_select_footprint.cpp index 8e4dad7986..32f517e1b5 100644 --- a/pcbnew/load_select_footprint.cpp +++ b/pcbnew/load_select_footprint.cpp @@ -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; diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index f7a3a48f8f..8b5442e81c 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -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 ); } } diff --git a/pcbnew/pcb_base_frame.cpp b/pcbnew/pcb_base_frame.cpp index ce2ec4c511..e1b6d8907f 100644 --- a/pcbnew/pcb_base_frame.cpp +++ b/pcbnew/pcb_base_frame.cpp @@ -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 ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 2aac4911f7..b933448f56 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -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( 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(); - - 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(); - 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(); - 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() == (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; diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index d5454adbaa..4d3b926a35 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -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; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 591cd84fb0..d54f120fde 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -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; diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index dfcad89c1a..1612f37383 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -183,90 +183,18 @@ ALIGNMENT_RECTS GetBoundingBoxes( const SELECTION &sel ) } -void ALIGN_DISTRIBUTE_TOOL::filterPadsWithModules( SELECTION &selection ) -{ - std::set rejected; - for( auto i : selection ) - { - auto item = static_cast( i ); - if( item->Type() == PCB_PAD_T ) - { - MODULE* mod = static_cast( 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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 ); diff --git a/pcbnew/tools/placement_tool.h b/pcbnew/tools/placement_tool.h index 40fc28b9e9..3d4752029b 100644 --- a/pcbnew/tools/placement_tool.h +++ b/pcbnew/tools/placement_tool.h @@ -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. * diff --git a/pcbnew/tools/position_relative_tool.cpp b/pcbnew/tools/position_relative_tool.cpp index f519d3990f..c366dfe752 100644 --- a/pcbnew/tools/position_relative_tool.cpp +++ b/pcbnew/tools/position_relative_tool.cpp @@ -80,15 +80,12 @@ bool POSITION_RELATIVE_TOOL::Init() int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent ) { PCB_BASE_FRAME* editFrame = getEditFrame(); - 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 diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index da3d2e3a0b..9410970762 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -752,16 +752,7 @@ int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent ) { CLIENT_SELECTION_FILTER aClientFilter = aEvent.Parameter(); - 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( 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;