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 ) ) if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
schframe->FocusOnItem( nullptr ); 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 ); 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() ) ) ) !m_selection.GetBoundingBox().Contains( wxPoint( evt->Position() ) ) )
{ {
ClearSelection(); ClearSelection();
SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, &selectionCancelled ); SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr,
&selectionCancelled );
m_selection.SetIsHover( true ); 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 EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
bool* aSelectionCancelledFlag, bool aCheckLocked, EDA_ITEM** aItem, bool* aSelectionCancelledFlag, bool aCheckLocked, bool aAdd,
bool aAdd, bool aSubtract, bool aExclusiveOr ) bool aSubtract, bool aExclusiveOr )
{ {
EE_COLLECTOR collector; 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(); auto part = static_cast<LIB_EDIT_FRAME*>( m_frame )->GetCurPart();
if( !part ) if( !part )
return nullptr; return false;
collector.Collect( part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit, m_convert ); 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 ) if( aSelectionCancelledFlag )
*aSelectionCancelledFlag = true; *aSelectionCancelledFlag = true;
return nullptr; return false;
} }
} }
if( !aAdd && !aSubtract && !aExclusiveOr ) if( !aAdd && !aSubtract && !aExclusiveOr )
ClearSelection(); ClearSelection();
if( collector.GetCount() == 1 ) bool anyAdded = false;
{ bool anySubtracted = false;
EDA_ITEM* item = collector[ 0 ];
if( aSubtract || ( aExclusiveOr && item->IsSelected() ) ) if( collector.GetCount() > 0 )
{
for( int i = 0; i < collector.GetCount(); ++i )
{ {
unselect( item ); if( aSubtract || ( aExclusiveOr && collector[i]->IsSelected() ) )
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); {
return nullptr; unselect( collector[i] );
} anySubtracted = false;
else }
{ else
select( item ); {
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); select( collector[i] );
return item; 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; EDA_ITEM* current = nullptr;
ACTION_MENU menu( true ); ACTION_MENU menu( true );
bool selectAll = false;
int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() ); 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]; EDA_ITEM* item = ( *aCollector )[i];
text = item->GetSelectMenuText( m_frame->GetUserUnits() ); 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.Add( menuText, i + 1, item->GetMenuImage() );
} }
menu.AppendSeparator();
menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_schematic_xpm );
if( aCollector->m_MenuTitle.Length() ) if( aCollector->m_MenuTitle.Length() )
menu.SetTitle( aCollector->m_MenuTitle ); 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( 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 ); unhighlight( current, BRIGHTENED );
}
int id = *evt->GetCommandId(); int id = *evt->GetCommandId();
@ -1114,19 +1143,48 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
{ {
current = nullptr; 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 ) 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 ); unhighlight( current, BRIGHTENED );
OPT<int> id = evt->GetCommandId(); 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 // 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]; current = ( *aCollector )[*id - 1];
}
else else
{
selectAll = false;
current = nullptr; current = nullptr;
}
break; break;
} }
@ -1135,7 +1193,9 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector )
m_frame->GetCanvas()->Refresh(); m_frame->GetCanvas()->Refresh();
} }
if( current ) if( selectAll )
return true;
else if( current )
{ {
unhighlight( current, BRIGHTENED ); unhighlight( current, BRIGHTENED );

View File

@ -91,19 +91,21 @@ public:
EE_SELECTION& RequestSelection( const KICAD_T* aFilterList = EE_COLLECTOR::AllItems ); EE_SELECTION& RequestSelection( const KICAD_T* aFilterList = EE_COLLECTOR::AllItems );
/** /**
* Function selectPoint() * Function SelectPoint()
* Selects an item pointed by the parameter aWhere. If there is more than one item at that * Selects one or all items pointed by the parameter aWhere.
* place, there is a menu displayed that allows one to choose the item. * 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 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 * @param aSelectionCancelledFlag allows the function to inform its caller that a selection
* was cancelled (for instance, by clicking outside of the disambiguation menu). * 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, bool SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList = EE_COLLECTOR::AllItems,
const KICAD_T* aFilterList = EE_COLLECTOR::AllItems, EDA_ITEM** aItem = nullptr, bool* aSelectionCancelledFlag = nullptr,
bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false, bool aCheckLocked = false, bool aAdd = false, bool aSubtract = false,
bool aAdd = false, bool aSubtract = false, bool aExclusiveOr = false ); bool aExclusiveOr = false );
int AddItemToSel( const TOOL_EVENT& aEvent ); int AddItemToSel( const TOOL_EVENT& aEvent );
void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false ); 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 ) [this, simFrame] ( const VECTOR2D& aPosition )
{ {
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>(); 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 ) if( !item )
return false; return false;
@ -755,7 +756,8 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
[this] ( const VECTOR2D& aPosition ) [this] ( const VECTOR2D& aPosition )
{ {
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>(); 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 ) if( !item )
return false; return false;

View File

@ -405,7 +405,6 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide(); GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
GENERAL_COLLECTOR collector; GENERAL_COLLECTOR collector;
auto& displayOpts = m_frame->GetDisplayOptions(); auto& displayOpts = m_frame->GetDisplayOptions();
bool cleared = false;
guide.SetIgnoreZoneFills( displayOpts.m_DisplayZonesMode != 0 ); 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 // Don't fire an event now as it will end up redundant if we fire a SelectedEvent
// or an UnselectedEvent. // or an UnselectedEvent.
cleared = true; ClearSelection( true /*quiet mode*/ );
ClearSelection( true );
} }
} }
if( collector.GetCount() == 1 ) bool anyAdded = false;
bool anySubtracted = false;
if( collector.GetCount() > 0 )
{ {
BOARD_ITEM* item = collector[ 0 ]; for( int i = 0; i < collector.GetCount(); ++i )
if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
{ {
unselect( item ); if( m_subtractive || ( m_exclusive_or && collector[i]->IsSelected() ) )
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); {
return false; unselect( collector[i] );
} anySubtracted = true;
else }
{ else
select( item ); {
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); select( collector[i] );
return true; anyAdded = true;
}
} }
} }
if( cleared ) if( anyAdded )
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent ); {
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
return true;
}
else if( anySubtracted )
{
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
return true;
}
return false; 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 // Don't fire an event now; most of the time it will be redundant as we're about to
// fire a SelectedEvent. // fire a SelectedEvent.
cleared = true; cleared = true;
ClearSelection( true /*quiet mode*/ ); ClearSelection( true /*quiet mode*/ );
} }
if( aItem ) if( aItem )
@ -1359,6 +1367,7 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
BOARD_ITEM* current = nullptr; BOARD_ITEM* current = nullptr;
PCBNEW_SELECTION highlightGroup; PCBNEW_SELECTION highlightGroup;
ACTION_MENU menu( true ); ACTION_MENU menu( true );
bool selectAll = false;
highlightGroup.SetLayer( LAYER_SELECT_OVERLAY ); highlightGroup.SetLayer( LAYER_SELECT_OVERLAY );
getView()->Add( &highlightGroup ); getView()->Add( &highlightGroup );
@ -1371,10 +1380,13 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
BOARD_ITEM* item = ( *aCollector )[i]; BOARD_ITEM* item = ( *aCollector )[i];
text = item->GetSelectMenuText( m_frame->GetUserUnits() ); 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.Add( menuText, i + 1, item->GetMenuImage() );
} }
menu.AppendSeparator();
menu.Add( _( "Select &All\tA" ), limit + 1, net_highlight_xpm );
if( aTitle.Length() ) if( aTitle.Length() )
menu.SetTitle( aTitle ); menu.SetTitle( aTitle );
@ -1386,7 +1398,12 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
{ {
if( evt->Action() == TA_CHOICE_MENU_UPDATE ) 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 ); unhighlight( current, BRIGHTENED, &highlightGroup );
int id = *evt->GetCommandId(); int id = *evt->GetCommandId();
@ -1398,29 +1415,56 @@ bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxStr
highlight( current, BRIGHTENED, &highlightGroup ); highlight( current, BRIGHTENED, &highlightGroup );
} }
else 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 ) 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 ); unhighlight( current, BRIGHTENED, &highlightGroup );
OPT<int> id = evt->GetCommandId(); 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 // 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]; current = ( *aCollector )[*id - 1];
}
else else
current = NULL; {
selectAll = false;
current = nullptr;
}
break; break;
} }
} }
getView()->Remove( &highlightGroup ); getView()->Remove( &highlightGroup );
if( current ) if( selectAll )
return true;
else if( current )
{ {
aCollector->Empty(); aCollector->Empty();
aCollector->Append( current ); aCollector->Append( current );