From ca91c27852cf3cf355482318d2dfcc71099266d5 Mon Sep 17 00:00:00 2001 From: John Beard Date: Wed, 8 Feb 2017 23:45:56 +0800 Subject: [PATCH] Adjust pad sub-menu enablements The apply settings and push settings options now take account of the validity of the global pad settings when deciding whether to show or not. Global pad push now requires a source pad and doesn't push from the global pad setting when there is no selection. The whole submenu is hidden when there are no enabled items. Fixes: lp:1664016 * https://bugs.launchpad.net/kicad/+bug/1664016 --- common/tool/context_menu.cpp | 19 +++++++ include/tool/context_menu.h | 7 +++ pcbnew/tools/pad_tool.cpp | 99 +++++++++++++++++++++++++++--------- pcbnew/tools/pad_tool.h | 6 +++ 4 files changed, 106 insertions(+), 25 deletions(-) diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index 0ed81f56f6..23d31e4dd9 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -187,6 +187,25 @@ void CONTEXT_MENU::Clear() } +bool CONTEXT_MENU::HasEnabledItems() const +{ + bool hasEnabled = false; + + auto& items = GetMenuItems(); + + for( auto item : items ) + { + if( item->IsEnabled() && !item->IsSeparator() ) + { + hasEnabled = true; + break; + } + } + + return hasEnabled; +} + + void CONTEXT_MENU::UpdateAll() { try diff --git a/include/tool/context_menu.h b/include/tool/context_menu.h index ab9051f725..387f35273b 100644 --- a/include/tool/context_menu.h +++ b/include/tool/context_menu.h @@ -111,6 +111,13 @@ public: */ void Clear(); + /** + * Function HasEnabledItems(); + * + * Returns true if the menu has any enabled items + */ + bool HasEnabledItems() const; + /** * Function GetSelected() * Returns the position of selected item. If the returned value is negative, that means that diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index 97626082c0..19236aa156 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -44,7 +44,11 @@ class PAD_CONTEXT_MENU : public CONTEXT_MENU { public: - PAD_CONTEXT_MENU() + + using SHOW_FUNCTOR = std::function; + + PAD_CONTEXT_MENU( SHOW_FUNCTOR aHaveGlobalPadSetting): + m_haveGlobalPadSettings( aHaveGlobalPadSetting ) { SetIcon( pad_xpm ); SetTitle( _( "Pads" ) ); @@ -58,36 +62,56 @@ protected: CONTEXT_MENU* create() const override { - return new PAD_CONTEXT_MENU(); + return new PAD_CONTEXT_MENU( m_haveGlobalPadSettings ); } private: + struct ENABLEMENTS + { + bool canImport; + bool canExport; + bool canPush; + }; + + ENABLEMENTS getEnablements( const SELECTION& aSelection ) + { + using S_C = SELECTION_CONDITIONS; + ENABLEMENTS enablements; + + auto anyPadSel = S_C::HasType( PCB_PAD_T ); + + auto singlePadSel = S_C::Count( 1 ) + && S_C::OnlyType( PCB_PAD_T ); + + // Apply pads enabled when any pads selected (it applies to each one + // individually), plus need a valid global pad setting + enablements.canImport = m_haveGlobalPadSettings() + && ( anyPadSel )( aSelection ); + + // Copy pads item enabled only when there is a single pad selected + // (otherwise how would we know which one to copy?) + enablements.canExport = ( singlePadSel )( aSelection ); + + // Push pads available when there is a single pad to push from + enablements.canPush = ( singlePadSel ) ( aSelection ); + + return enablements; + } + void update() override { auto selTool = getToolManager()->GetTool(); const SELECTION& selection = selTool->GetSelection(); - auto anyPadSel = SELECTION_CONDITIONS::HasType( PCB_PAD_T ); + auto enablements = getEnablements( selection ); - auto singlePadSel = SELECTION_CONDITIONS::Count( 1 ) - && SELECTION_CONDITIONS::OnlyType( PCB_PAD_T ); - auto emptySel = SELECTION_CONDITIONS::Count( 0 ); - - // Apply pads enabled when any pads selected (it applies to each one - // individually) - const bool canImport = ( anyPadSel )( selection ); - Enable( getMenuId( COMMON_ACTIONS::applyPadSettings ), canImport ); - - // Copy pads item enabled only when there is a single pad selected - // (otherwise how would we know which one to copy?) - const bool canExport = ( singlePadSel )( selection ); - Enable( getMenuId( COMMON_ACTIONS::copyPadSettings ), canExport ); - - // Push pads available when nothing selected, or a single pad - const bool canPush = ( singlePadSel || emptySel ) ( selection ); - Enable( getMenuId( COMMON_ACTIONS::pushPadSettings ), canPush ); + Enable( getMenuId( COMMON_ACTIONS::applyPadSettings ), enablements.canImport ); + Enable( getMenuId( COMMON_ACTIONS::copyPadSettings ), enablements.canExport ); + Enable( getMenuId( COMMON_ACTIONS::pushPadSettings ), enablements.canPush ); } + + SHOW_FUNCTOR m_haveGlobalPadSettings; }; @@ -106,9 +130,29 @@ void PAD_TOOL::Reset( RESET_REASON aReason ) } +bool PAD_TOOL::hasMasterPadSettings() +{ + auto& frame = *getEditFrame(); + D_PAD& masterPad = frame.GetDesignSettings().m_Pad_Master; + return masterPad.GetParent() != nullptr; +} + + +bool PAD_TOOL::haveFootprints() +{ + auto& board = *getModel(); + return board.m_Modules.GetCount() > 0; +} + + bool PAD_TOOL::Init() { - auto contextMenu = std::make_shared(); + // functor to report if the current frame has master pad settings + std::function haveMasterPad = [this] () { + return hasMasterPadSettings(); + }; + + auto contextMenu = std::make_shared( haveMasterPad ); contextMenu->SetTool( this ); SELECTION_TOOL* selTool = m_toolMgr->GetTool(); @@ -120,10 +164,15 @@ bool PAD_TOOL::Init() toolMenu.AddSubMenu( contextMenu ); - // show menu when any pads selected, or nothing selected - // (push settings works on no selection) - auto showCond = SELECTION_CONDITIONS::HasType( PCB_PAD_T ) - || SELECTION_CONDITIONS::Count( 0 ); + SELECTION_CONDITION canShowMenuCond = [this, contextMenu] ( const SELECTION& aSel ) { + contextMenu->UpdateAll(); + return haveFootprints() && contextMenu->HasEnabledItems(); + }; + + // show menu when there is a footprint, and the menu has any items + auto showCond = canShowMenuCond && + ( SELECTION_CONDITIONS::HasType( PCB_PAD_T ) + || SELECTION_CONDITIONS::Count( 0 ) ); menu.AddMenu( contextMenu.get(), false, showCond ); } diff --git a/pcbnew/tools/pad_tool.h b/pcbnew/tools/pad_tool.h index 1c0ffb4f8a..1854c26086 100644 --- a/pcbnew/tools/pad_tool.h +++ b/pcbnew/tools/pad_tool.h @@ -50,6 +50,12 @@ public: void SetTransitions() override; private: + ///> Determine if the frame has a valid master pad setting + bool hasMasterPadSettings(); + + ///> Determine if there are any footprints on the board + bool haveFootprints(); + ///> Apply pad settings from board design settings to a pad int applyPadSettings( const TOOL_EVENT& aEvent );