Add selection filter dialog to GAL
Fixes: lp:1535805 * https://bugs.launchpad.net/kicad/+bug/1535805
This commit is contained in:
parent
6ba9a512b6
commit
c6046d6da2
|
@ -81,7 +81,7 @@ static bool InstallBlockCmdFrame( PCB_BASE_FRAME* parent, const wxString& title
|
|||
wxPoint oldpos = parent->GetCrossHairPosition();
|
||||
|
||||
parent->GetCanvas()->SetIgnoreMouseEvents( true );
|
||||
DIALOG_BLOCK_OPTIONS * dlg = new DIALOG_BLOCK_OPTIONS( parent, blockOpts, title );
|
||||
DIALOG_BLOCK_OPTIONS * dlg = new DIALOG_BLOCK_OPTIONS( parent, blockOpts, true, title );
|
||||
|
||||
int cmd = dlg->ShowModal();
|
||||
dlg->Destroy();
|
||||
|
|
|
@ -28,10 +28,16 @@
|
|||
|
||||
|
||||
DIALOG_BLOCK_OPTIONS::DIALOG_BLOCK_OPTIONS( PCB_BASE_FRAME* aParent,
|
||||
OPTIONS& aOptions, const wxString& aTitle ) :
|
||||
OPTIONS& aOptions, bool aShowLegacyOptions,
|
||||
const wxString& aTitle ) :
|
||||
DIALOG_BLOCK_OPTIONS_BASE( aParent, -1, aTitle ),
|
||||
m_options( aOptions )
|
||||
{
|
||||
if( !aShowLegacyOptions )
|
||||
{
|
||||
m_DrawBlockItems->Hide();
|
||||
}
|
||||
|
||||
m_Include_Modules->SetValue( m_options.includeModules );
|
||||
m_IncludeLockedModules->SetValue( m_options.includeLockedModules );
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
};
|
||||
|
||||
DIALOG_BLOCK_OPTIONS( PCB_BASE_FRAME* aParent, OPTIONS& aOptions,
|
||||
bool aShowLegacyOptions,
|
||||
const wxString& aTitle );
|
||||
|
||||
~DIALOG_BLOCK_OPTIONS()
|
||||
|
|
|
@ -69,6 +69,10 @@ public:
|
|||
|
||||
/// Selects all components on the same sheet.
|
||||
static TOOL_ACTION selectSameSheet;
|
||||
|
||||
/// Filters the items in the current selection (invokes dialog)
|
||||
static TOOL_ACTION filterSelection;
|
||||
|
||||
// Edit Tool
|
||||
/// Activation of the edit tool
|
||||
static TOOL_ACTION editActivate;
|
||||
|
|
|
@ -38,6 +38,7 @@ using namespace std::placeholders;
|
|||
#include <collectors.h>
|
||||
#include <confirm.h>
|
||||
#include <dialog_find.h>
|
||||
#include <dialog_block_options.h>
|
||||
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <view/view_controls.h>
|
||||
|
@ -99,6 +100,12 @@ TOOL_ACTION PCB_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
|
|||
TOOL_ACTION PCB_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_GET_AND_MOVE_FOOTPRINT ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::filterSelection( "pcbnew.InteractiveSelection.FilterSelection",
|
||||
AS_GLOBAL, MD_SHIFT + 'F',
|
||||
_( "Filter selection" ), _( "Filter the types of items in the selection" ),
|
||||
nullptr );
|
||||
|
||||
|
||||
|
||||
class SELECT_MENU: public CONTEXT_MENU
|
||||
{
|
||||
|
@ -106,6 +113,11 @@ public:
|
|||
SELECT_MENU()
|
||||
{
|
||||
SetTitle( _( "Select..." ) );
|
||||
|
||||
Add( PCB_ACTIONS::filterSelection );
|
||||
|
||||
AppendSeparator();
|
||||
|
||||
Add( PCB_ACTIONS::selectConnection );
|
||||
Add( PCB_ACTIONS::selectCopper );
|
||||
Add( PCB_ACTIONS::selectNet );
|
||||
|
@ -138,10 +150,21 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private implementation of firewalled private data
|
||||
*/
|
||||
class SELECTION_TOOL::PRIV
|
||||
{
|
||||
public:
|
||||
DIALOG_BLOCK_OPTIONS::OPTIONS m_filterOpts;
|
||||
};
|
||||
|
||||
|
||||
SELECTION_TOOL::SELECTION_TOOL() :
|
||||
PCB_TOOL( "pcbnew.InteractiveSelection" ),
|
||||
m_frame( NULL ), m_additive( false ), m_multiple( false ),
|
||||
m_locked( true ), m_menu( *this )
|
||||
m_locked( true ), m_menu( *this ),
|
||||
m_priv( std::make_unique<PRIV>() )
|
||||
{
|
||||
// Do not leave uninitialized members:
|
||||
m_preliminary = false;
|
||||
|
@ -522,6 +545,7 @@ void SELECTION_TOOL::SetTransitions()
|
|||
Go( &SELECTION_TOOL::UnselectItem, PCB_ACTIONS::unselectItem.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::find, PCB_ACTIONS::find.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::findMove, PCB_ACTIONS::findMove.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::filterSelection, PCB_ACTIONS::filterSelection.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::selectConnection, PCB_ACTIONS::selectConnection.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::selectCopper, PCB_ACTIONS::selectCopper.MakeEvent() );
|
||||
Go( &SELECTION_TOOL::selectNet, PCB_ACTIONS::selectNet.MakeEvent() );
|
||||
|
@ -914,6 +938,134 @@ int SELECTION_TOOL::findMove( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function itemIsIncludedByFilter()
|
||||
*
|
||||
* Determine if an item is included by the filter specified
|
||||
*
|
||||
* @return true if the parameter indicate the items should be selected
|
||||
* by this filter (i..e not filtered out)
|
||||
*/
|
||||
static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem,
|
||||
const BOARD& aBoard,
|
||||
const LSET& aTechnlLayerMask,
|
||||
const DIALOG_BLOCK_OPTIONS::OPTIONS& aBlockOpts )
|
||||
{
|
||||
bool include = true;
|
||||
const LAYER_ID layer = aItem.GetLayer();
|
||||
|
||||
// can skip without even checking item type
|
||||
if( !aBlockOpts.includeItemsOnInvisibleLayers
|
||||
&& !aBoard.IsLayerVisible( layer ) )
|
||||
{
|
||||
include = false;
|
||||
}
|
||||
|
||||
// if the item needsto be checked agains the options
|
||||
if( include )
|
||||
{
|
||||
switch( aItem.Type() )
|
||||
{
|
||||
case PCB_MODULE_T:
|
||||
{
|
||||
const auto& module = static_cast<const MODULE&>( aItem );
|
||||
|
||||
include = aBlockOpts.includeModules;
|
||||
|
||||
if( include && !aBlockOpts.includeLockedModules )
|
||||
{
|
||||
include = !module.IsLocked();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PCB_TRACE_T:
|
||||
{
|
||||
include = aBlockOpts.includeTracks;
|
||||
break;
|
||||
}
|
||||
case PCB_ZONE_AREA_T:
|
||||
{
|
||||
include = aBlockOpts.includeZones;
|
||||
break;
|
||||
}
|
||||
case PCB_LINE_T:
|
||||
case PCB_TARGET_T:
|
||||
case PCB_DIMENSION_T:
|
||||
{
|
||||
include = aTechnlLayerMask[layer];
|
||||
break;
|
||||
}
|
||||
case PCB_TEXT_T:
|
||||
{
|
||||
include = aBlockOpts.includePcbTexts
|
||||
&& aTechnlLayerMask[layer];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// no filterering, just select it
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return include;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the technical layers that are part of the given selection opts
|
||||
*/
|
||||
static LSET getFilteredLayerSet(
|
||||
const DIALOG_BLOCK_OPTIONS::OPTIONS& blockOpts )
|
||||
{
|
||||
LSET layerMask( Edge_Cuts );
|
||||
|
||||
if( blockOpts.includeItemsOnTechLayers )
|
||||
layerMask.set();
|
||||
|
||||
if( !blockOpts.includeBoardOutlineLayer )
|
||||
layerMask.set( Edge_Cuts, false );
|
||||
|
||||
return layerMask;
|
||||
}
|
||||
|
||||
|
||||
int SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& opts = m_priv->m_filterOpts;
|
||||
DIALOG_BLOCK_OPTIONS dlg( m_frame, opts, false, _( "Filter selection" ) );
|
||||
|
||||
const int cmd = dlg.ShowModal();
|
||||
|
||||
if( cmd != wxID_OK )
|
||||
return 0;
|
||||
|
||||
const auto& board = *getModel<BOARD>();
|
||||
const auto layerMask = getFilteredLayerSet( opts );
|
||||
|
||||
// copy current selection
|
||||
auto selection = m_selection.GetItems();
|
||||
|
||||
// clear current selection
|
||||
clearSelection();
|
||||
|
||||
// copy selection items from the saved selection
|
||||
// according to the dialog options
|
||||
for( auto item : selection )
|
||||
{
|
||||
bool include = itemIsIncludedByFilter( *item, board, layerMask, opts );
|
||||
|
||||
if( include )
|
||||
{
|
||||
select( item );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SELECTION_TOOL::clearSelection()
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
|
|
|
@ -293,6 +293,9 @@ private:
|
|||
///> Find an item and start moving.
|
||||
int findMove( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Invoke filter dialog and modify current selection
|
||||
int filterSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function clearSelection()
|
||||
* Clears the current selection.
|
||||
|
@ -407,6 +410,10 @@ private:
|
|||
|
||||
/// Menu model displayed by the tool.
|
||||
TOOL_MENU m_menu;
|
||||
|
||||
/// Private state (opaque pointer/compilation firewall)
|
||||
class PRIV;
|
||||
std::unique_ptr<PRIV> m_priv;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue