Add "Select All" in schematic & layout disambiguation popup menu

ADDED: "Select All" in schematic editor disambiguation menu
ADDED: "Select All" in layout edtor disambiguation menu

Fixes https://gitlab.com/kicad/code/kicad/-/issues/3877
This commit is contained in:
Mikołaj Wielgus 2020-05-24 23:35:04 +00:00 committed by Ian McInerney
parent 77a6550ba9
commit ecec7192fc
4 changed files with 170 additions and 62 deletions

View File

@ -328,7 +328,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( 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<LIB_EDIT_FRAME*>( 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<int> 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 );

View File

@ -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 );

View File

@ -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<EE_SELECTION_TOOL>();
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<EE_SELECTION_TOOL>();
EDA_ITEM* item = selTool->SelectPoint( aPosition, fieldsAndComponents );
EDA_ITEM* item;
selTool->SelectPoint( aPosition, fieldsAndComponents, &item );
if( !item )
return false;

View File

@ -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<int> 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 );