diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index ce62293566..e375625f70 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -328,7 +328,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) if( auto schframe = dynamic_cast( m_frame ) ) schframe->FocusOnItem( nullptr ); - SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, false, + SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, nullptr, false, m_additive, m_subtractive, m_exclusive_or ); } @@ -341,7 +341,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) !m_selection.GetBoundingBox().Contains( wxPoint( evt->Position() ) ) ) { ClearSelection(); - SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, &selectionCancelled ); + SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr, + &selectionCancelled ); m_selection.SetIsHover( true ); } @@ -453,9 +454,9 @@ EE_SELECTION& EE_SELECTION_TOOL::GetSelection() } -EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList, - bool* aSelectionCancelledFlag, bool aCheckLocked, - bool aAdd, bool aSubtract, bool aExclusiveOr ) +bool EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList, + EDA_ITEM** aItem, bool* aSelectionCancelledFlag, bool aCheckLocked, bool aAdd, + bool aSubtract, bool aExclusiveOr ) { EE_COLLECTOR collector; @@ -466,7 +467,7 @@ EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* auto part = static_cast( m_frame )->GetCurPart(); if( !part ) - return nullptr; + return false; collector.Collect( part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit, m_convert ); } @@ -523,32 +524,49 @@ EDA_ITEM* EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* if( aSelectionCancelledFlag ) *aSelectionCancelledFlag = true; - return nullptr; + return false; } } if( !aAdd && !aSubtract && !aExclusiveOr ) ClearSelection(); - if( collector.GetCount() == 1 ) - { - EDA_ITEM* item = collector[ 0 ]; + bool anyAdded = false; + bool anySubtracted = false; - if( aSubtract || ( aExclusiveOr && item->IsSelected() ) ) + if( collector.GetCount() > 0 ) + { + for( int i = 0; i < collector.GetCount(); ++i ) { - unselect( item ); - m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); - return nullptr; - } - else - { - select( item ); - m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); - return item; + if( aSubtract || ( aExclusiveOr && collector[i]->IsSelected() ) ) + { + unselect( collector[i] ); + anySubtracted = false; + } + else + { + select( collector[i] ); + anySubtracted = true; + } } } - return nullptr; + if( anyAdded ) + { + m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); + + if( aItem && collector.GetCount() == 1 ) + *aItem = collector[0]; + + return true; + } + else if( anySubtracted ) + { + m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); + return true; + } + + return false; } @@ -1075,6 +1093,7 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) { EDA_ITEM* current = nullptr; ACTION_MENU menu( true ); + bool selectAll = false; int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() ); @@ -1084,10 +1103,13 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) EDA_ITEM* item = ( *aCollector )[i]; text = item->GetSelectMenuText( m_frame->GetUserUnits() ); - wxString menuText = wxString::Format("&%d. %s", i + 1, text ); + wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 ); menu.Add( menuText, i + 1, item->GetMenuImage() ); } + menu.AppendSeparator(); + menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_schematic_xpm ); + if( aCollector->m_MenuTitle.Length() ) menu.SetTitle( aCollector->m_MenuTitle ); @@ -1099,8 +1121,15 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) { if( evt->Action() == TA_CHOICE_MENU_UPDATE ) { - if( current ) + if( selectAll ) + { + for( int i = 0; i < aCollector->GetCount(); ++i ) + unhighlight( ( *aCollector )[i], BRIGHTENED ); + } + else if( current ) + { unhighlight( current, BRIGHTENED ); + } int id = *evt->GetCommandId(); @@ -1114,19 +1143,48 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) { current = nullptr; } + + // User has pointed on the "Select All" option + if( id == limit + 1 ) + { + for( int i = 0; i < aCollector->GetCount(); ++i ) + highlight( ( *aCollector )[i], BRIGHTENED ); + selectAll = true; + } + else + { + selectAll = false; + } } else if( evt->Action() == TA_CHOICE_MENU_CHOICE ) { - if( current ) + if( selectAll ) + { + for( int i = 0; i < aCollector->GetCount(); ++i ) + unhighlight( ( *aCollector )[i], BRIGHTENED ); + } + else if( current ) unhighlight( current, BRIGHTENED ); OPT id = evt->GetCommandId(); + // User has selected the "Select All" option + if( id == limit + 1 ) + { + selectAll = true; + current = nullptr; + } // User has selected an item, so this one will be returned - if( id && ( *id > 0 ) ) + else if( id && ( *id > 0 ) && ( *id <= limit ) ) + { + selectAll = false; current = ( *aCollector )[*id - 1]; + } else + { + selectAll = false; current = nullptr; + } break; } @@ -1135,7 +1193,9 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) m_frame->GetCanvas()->Refresh(); } - if( current ) + if( selectAll ) + return true; + else if( current ) { unhighlight( current, BRIGHTENED ); diff --git a/eeschema/tools/ee_selection_tool.h b/eeschema/tools/ee_selection_tool.h index ee3a66e116..c96400d067 100644 --- a/eeschema/tools/ee_selection_tool.h +++ b/eeschema/tools/ee_selection_tool.h @@ -91,19 +91,21 @@ public: EE_SELECTION& RequestSelection( const KICAD_T* aFilterList = EE_COLLECTOR::AllItems ); /** - * Function selectPoint() - * Selects an item pointed by the parameter aWhere. If there is more than one item at that - * place, there is a menu displayed that allows one to choose the item. + * Function SelectPoint() + * Selects one or all items pointed by the parameter aWhere. + * If there is more than one item at that place, + * there is a menu displayed that allows one to choose the item or all of them. * * @param aWhere is the place where the item should be selected. + * @param aItem is set to the newly selected item if only one was selected, otherwise is unchanged. * @param aSelectionCancelledFlag allows the function to inform its caller that a selection * was cancelled (for instance, by clicking outside of the disambiguation menu). - * @param aCheckLocked indicates if locked items should be excluded + * @param aCheckLocked indicates if locked items should be excluded. */ - EDA_ITEM* SelectPoint( const VECTOR2I& aWhere, - const KICAD_T* aFilterList = EE_COLLECTOR::AllItems, - bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false, - bool aAdd = false, bool aSubtract = false, bool aExclusiveOr = false ); + bool SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList = EE_COLLECTOR::AllItems, + EDA_ITEM** aItem = nullptr, bool* aSelectionCancelledFlag = nullptr, + bool aCheckLocked = false, bool aAdd = false, bool aSubtract = false, + bool aExclusiveOr = false ); int AddItemToSel( const TOOL_EVENT& aEvent ); void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false ); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 502a936915..03849e2678 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -631,7 +631,8 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent ) [this, simFrame] ( const VECTOR2D& aPosition ) { EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); - EDA_ITEM* item = selTool->SelectPoint( aPosition, wiresAndPins ); + EDA_ITEM* item; + selTool->SelectPoint( aPosition, wiresAndPins, &item ); if( !item ) return false; @@ -755,7 +756,8 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent ) [this] ( const VECTOR2D& aPosition ) { EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); - EDA_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents ); + EDA_ITEM* item; + selTool->SelectPoint( aPosition, fieldsAndComponents, &item ); if( !item ) return false; diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 546c0e88cd..1945169136 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -405,7 +405,6 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag, GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide(); GENERAL_COLLECTOR collector; auto& displayOpts = m_frame->GetDisplayOptions(); - bool cleared = false; guide.SetIgnoreZoneFills( displayOpts.m_DisplayZonesMode != 0 ); @@ -454,31 +453,40 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag, { // Don't fire an event now as it will end up redundant if we fire a SelectedEvent // or an UnselectedEvent. - cleared = true; - ClearSelection( true ); + ClearSelection( true /*quiet mode*/ ); } } - if( collector.GetCount() == 1 ) + bool anyAdded = false; + bool anySubtracted = false; + + if( collector.GetCount() > 0 ) { - BOARD_ITEM* item = collector[ 0 ]; - - if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) ) + for( int i = 0; i < collector.GetCount(); ++i ) { - unselect( item ); - m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); - return false; - } - else - { - select( item ); - m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); - return true; + if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) ) + { + unselect( collector[i] ); + anySubtracted = true; + } + else + { + select( collector[i] ); + anyAdded = true; + } } } - if( cleared ) - m_toolMgr->ProcessEvent( EVENTS::ClearedEvent ); + if( anyAdded ) + { + m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); + return true; + } + else if( anySubtracted ) + { + m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); + return true; + } return false; } @@ -1159,7 +1167,7 @@ void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem ) // Don't fire an event now; most of the time it will be redundant as we're about to // fire a SelectedEvent. cleared = true; - ClearSelection( true /*quiet mode*/ ); + ClearSelection( true /*quiet mode*/ ); } if( aItem ) @@ -1359,6 +1367,7 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr BOARD_ITEM* current = nullptr; PCBNEW_SELECTION highlightGroup; ACTION_MENU menu( true ); + bool selectAll = false; highlightGroup.SetLayer( LAYER_SELECT_OVERLAY ); getView()->Add( &highlightGroup ); @@ -1371,10 +1380,13 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr BOARD_ITEM* item = ( *aCollector )[i]; text = item->GetSelectMenuText( m_frame->GetUserUnits() ); - wxString menuText = wxString::Format("&%d. %s", i + 1, text ); + wxString menuText = wxString::Format( "&%d. %s\t%d", i + 1, text, i + 1 ); menu.Add( menuText, i + 1, item->GetMenuImage() ); } + menu.AppendSeparator(); + menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_xpm ); + if( aTitle.Length() ) menu.SetTitle( aTitle ); @@ -1386,7 +1398,12 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr { if( evt->Action() == TA_CHOICE_MENU_UPDATE ) { - if( current ) + if( selectAll ) + { + for( int i = 0; i < aCollector->GetCount(); ++i ) + unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup ); + } + else if( current ) unhighlight( current, BRIGHTENED, &highlightGroup ); int id = *evt->GetCommandId(); @@ -1398,29 +1415,56 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr highlight( current, BRIGHTENED, &highlightGroup ); } else + current = nullptr; + + // User has pointed on the "Select All" option + if( id == limit + 1 ) { - current = NULL; + for( int i = 0; i < aCollector->GetCount(); ++i ) + highlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup ); + selectAll = true; } + else + selectAll = false; } else if( evt->Action() == TA_CHOICE_MENU_CHOICE ) { - if( current ) + if( selectAll ) + { + for( int i = 0; i < aCollector->GetCount(); ++i ) + unhighlight( ( *aCollector )[i], BRIGHTENED, &highlightGroup ); + } + else if( current ) unhighlight( current, BRIGHTENED, &highlightGroup ); OPT id = evt->GetCommandId(); + // User has selected the "Select All" option + if( id == limit + 1 ) + { + selectAll = true; + current = nullptr; + } // User has selected an item, so this one will be returned - if( id && ( *id > 0 ) ) + else if( id && ( *id > 0 ) && ( *id <= limit ) ) + { + selectAll = false; current = ( *aCollector )[*id - 1]; + } else - current = NULL; + { + selectAll = false; + current = nullptr; + } break; } } getView()->Remove( &highlightGroup ); - if( current ) + if( selectAll ) + return true; + else if( current ) { aCollector->Empty(); aCollector->Append( current );