From 4325f4e0388f2fe64ea10e13b013dc54df0a3d9e Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 28 Aug 2023 12:29:47 +0100 Subject: [PATCH] ADDED: alternate pin functions in context menu. Fixes https://gitlab.com/kicad/code/kicad/-/issues/12852 --- .../dialogs/dialog_pin_properties_base.cpp | 5 +- .../dialogs/dialog_pin_properties_base.fbp | 2 +- eeschema/dialogs/dialog_pin_properties_base.h | 2 +- eeschema/eeschema_id.h | 9 +- eeschema/picksymbol.cpp | 17 ++++ eeschema/sch_edit_frame.h | 2 + eeschema/sch_symbol.cpp | 7 +- eeschema/tools/ee_selection_tool.cpp | 29 +++++- eeschema/tools/ee_selection_tool.h | 1 + eeschema/tools/sch_drawing_tools.cpp | 6 +- eeschema/tools/sch_edit_tool.cpp | 89 ++++++++++++++++--- eeschema/tools/sch_move_tool.cpp | 6 +- 12 files changed, 148 insertions(+), 27 deletions(-) diff --git a/eeschema/dialogs/dialog_pin_properties_base.cpp b/eeschema/dialogs/dialog_pin_properties_base.cpp index 7e00809b1b..4ec7dd6971 100644 --- a/eeschema/dialogs/dialog_pin_properties_base.cpp +++ b/eeschema/dialogs/dialog_pin_properties_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -185,7 +185,7 @@ DIALOG_PIN_PROPERTIES_BASE::DIALOG_PIN_PROPERTIES_BASE( wxWindow* parent, wxWind wxBoxSizer* bLowerSizer; bLowerSizer = new wxBoxSizer( wxVERTICAL ); - m_alternatesTurndown = new wxCollapsiblePane( this, wxID_ANY, _("Alternate pin definitions"), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE ); + m_alternatesTurndown = new wxCollapsiblePane( this, wxID_ANY, _("Alternate pin function definitions"), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE|wxCP_NO_TLW_RESIZE ); m_alternatesTurndown->Collapse( true ); wxBoxSizer* bAlternatesSizer; @@ -313,4 +313,3 @@ DIALOG_PIN_PROPERTIES_BASE::~DIALOG_PIN_PROPERTIES_BASE() m_deleteAlternate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PIN_PROPERTIES_BASE::OnDeleteAlternate ), NULL, this ); } - diff --git a/eeschema/dialogs/dialog_pin_properties_base.fbp b/eeschema/dialogs/dialog_pin_properties_base.fbp index d6f0228389..9ff82e3b00 100644 --- a/eeschema/dialogs/dialog_pin_properties_base.fbp +++ b/eeschema/dialogs/dialog_pin_properties_base.fbp @@ -2191,7 +2191,7 @@ 0 0 wxID_ANY - Alternate pin definitions + Alternate pin function definitions 0 diff --git a/eeschema/dialogs/dialog_pin_properties_base.h b/eeschema/dialogs/dialog_pin_properties_base.h index 3c03c11894..de6cb14d4c 100644 --- a/eeschema/dialogs/dialog_pin_properties_base.h +++ b/eeschema/dialogs/dialog_pin_properties_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index 6b40066848..39019f738d 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -35,6 +35,8 @@ */ #define MAX_UNIT_COUNT_PER_PACKAGE 676 +#define MAX_ALT_PIN_FUNCTION_ITEMS 1024 + /** * While it would seem that an unfold-from-bus menu with over 100 items would be * hard to deal with, we've already had one user who wants 256. @@ -78,11 +80,14 @@ enum id_eeschema_frm ID_POPUP_SCH_UNFOLD_BUS_END = ID_POPUP_SCH_UNFOLD_BUS + MAX_BUS_UNFOLD_MENU_ITEMS, // Unit select context menus command IDs. - ID_POPUP_SCH_SELECT_UNIT_CMP, + ID_POPUP_SCH_SELECT_UNIT, ID_POPUP_SCH_SELECT_UNIT1, // ... leave room for MAX_UNIT_COUNT_PER_PACKAGE IDs , // to select one unit among MAX_UNIT_COUNT_PER_PACKAGE in popup menu - ID_POPUP_SCH_SELECT_UNIT_SYM_MAX = ID_POPUP_SCH_SELECT_UNIT1 + MAX_UNIT_COUNT_PER_PACKAGE + ID_POPUP_SCH_SELECT_UNIT_END = ID_POPUP_SCH_SELECT_UNIT1 + MAX_UNIT_COUNT_PER_PACKAGE, + + ID_POPUP_SCH_ALT_PIN_FUNCTION, + ID_POPUP_SCH_ALT_PIN_FUNCTION_END = ID_POPUP_SCH_ALT_PIN_FUNCTION + MAX_ALT_PIN_FUNCTION_ITEMS }; diff --git a/eeschema/picksymbol.cpp b/eeschema/picksymbol.cpp index 33181459c2..d740da17df 100644 --- a/eeschema/picksymbol.cpp +++ b/eeschema/picksymbol.cpp @@ -308,3 +308,20 @@ void SCH_EDIT_FRAME::ConvertPart( SCH_SYMBOL* aSymbol ) commit.Push( _( "Convert Symbol" ) ); } + + +void SCH_EDIT_FRAME::SetAltPinFunction( SCH_PIN* aPin, const wxString& aFunction ) +{ + if( !aPin ) + return; + + SCH_COMMIT commit( m_toolManager ); + commit.Modify( aPin, GetScreen() ); + + if( aFunction == aPin->GetName() ) + aPin->SetAlt( wxEmptyString ); + else + aPin->SetAlt( aFunction ); + + commit.Push( _( "Set Alternate Pin Function" ) ); +} diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 3b8cf0c53e..fd1706fb74 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -646,6 +646,8 @@ public: void SelectUnit( SCH_SYMBOL* aSymbol, int aUnit ); + void SetAltPinFunction( SCH_PIN* aPin, const wxString& aFunction ); + /* Undo - redo */ /** diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index c98622bd2d..728e2b4acc 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -175,7 +175,7 @@ SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) : m_DNP = aSymbol.m_DNP; if( aSymbol.m_part ) - SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part.get() ) ); + SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part ) ); const_cast( m_Uuid ) = aSymbol.m_Uuid; @@ -188,6 +188,11 @@ SCH_SYMBOL::SCH_SYMBOL( const SCH_SYMBOL& aSymbol ) : for( SCH_FIELD& field : m_fields ) field.SetParent( this ); + m_pins.clear(); + + for( const std::unique_ptr& pin : aSymbol.m_pins ) + m_pins.emplace_back( std::make_unique( this, pin->GetNumber(), pin->GetAlt() ) ); + m_fieldsAutoplaced = aSymbol.m_fieldsAutoplaced; m_schLibSymbolName = aSymbol.m_schLibSymbolName; } diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 56b8be1455..f0e06d9b08 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -110,6 +110,20 @@ SELECTION_CONDITION EE_CONDITIONS::SingleMultiUnitSymbol = []( const SELECTION& }; +SELECTION_CONDITION EE_CONDITIONS::SingleMultiFunctionPin = []( const SELECTION& aSel ) +{ + if( aSel.GetSize() == 1 ) + { + SCH_PIN* pin = dynamic_cast( aSel.Front() ); + + if( pin && pin->GetLibPin() ) + return !pin->GetLibPin()->GetAlternates().empty(); + } + + return false; +}; + + SELECTION_CONDITION EE_CONDITIONS::SingleNonExcludedMarker = []( const SELECTION& aSel ) { if( aSel.CountType( SCH_MARKER_T ) != 1 ) @@ -573,15 +587,24 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) m_disambiguateTimer.Stop(); // context sub-menu selection? Handle unit selection or bus unfolding - if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT_CMP - && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_SYM_MAX ) + if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT + && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_END ) { SCH_SYMBOL* symbol = dynamic_cast( m_selection.Front() ); - int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT_CMP; + int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT; if( symbol ) static_cast( m_frame )->SelectUnit( symbol, unit ); } + else if( *evt->GetCommandId() >= ID_POPUP_SCH_ALT_PIN_FUNCTION + && *evt->GetCommandId() <= ID_POPUP_SCH_ALT_PIN_FUNCTION_END ) + { + SCH_PIN* pin = dynamic_cast( m_selection.Front() ); + wxString alt = *evt->Parameter(); + + if( pin ) + static_cast( m_frame )->SetAltPinFunction( pin, alt ); + } else if( *evt->GetCommandId() >= ID_POPUP_SCH_UNFOLD_BUS && *evt->GetCommandId() <= ID_POPUP_SCH_UNFOLD_BUS_END ) { diff --git a/eeschema/tools/ee_selection_tool.h b/eeschema/tools/ee_selection_tool.h index bdd5479e6c..c34bb9e1ed 100644 --- a/eeschema/tools/ee_selection_tool.h +++ b/eeschema/tools/ee_selection_tool.h @@ -50,6 +50,7 @@ public: static SELECTION_CONDITION SingleSymbolOrPower; static SELECTION_CONDITION SingleDeMorganSymbol; static SELECTION_CONDITION SingleMultiUnitSymbol; + static SELECTION_CONDITION SingleMultiFunctionPin; static SELECTION_CONDITION SingleNonExcludedMarker; static SELECTION_CONDITION MultipleSymbolsOrPower; }; diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 35692a17c7..b8997bcc15 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -419,10 +419,10 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent ) } else if( evt->Category() == TC_COMMAND && evt->Action() == TA_CHOICE_MENU_CHOICE ) { - if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT_CMP - && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_SYM_MAX ) + if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT + && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_END ) { - int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT_CMP; + int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT; if( symbol ) { diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index f28e0317ea..85e89b3016 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -94,8 +94,8 @@ private: if( !symbol ) { - Append( ID_POPUP_SCH_SELECT_UNIT_CMP, _( "no symbol selected" ), wxEmptyString ); - Enable( ID_POPUP_SCH_SELECT_UNIT_CMP, false ); + Append( ID_POPUP_SCH_SELECT_UNIT, _( "no symbol selected" ), wxEmptyString ); + Enable( ID_POPUP_SCH_SELECT_UNIT, false ); return; } @@ -103,8 +103,8 @@ private: if( !symbol->GetLibSymbolRef() || symbol->GetLibSymbolRef()->GetUnitCount() < 2 ) { - Append( ID_POPUP_SCH_SELECT_UNIT_CMP, _( "symbol is not multi-unit" ), wxEmptyString ); - Enable( ID_POPUP_SCH_SELECT_UNIT_CMP, false ); + Append( ID_POPUP_SCH_SELECT_UNIT, _( "symbol is not multi-unit" ), wxEmptyString ); + Enable( ID_POPUP_SCH_SELECT_UNIT, false ); return; } @@ -113,14 +113,78 @@ private: wxString num_unit; num_unit.Printf( _( "Unit %s" ), LIB_SYMBOL::SubReference( ii + 1, false ) ); - wxMenuItem * item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString, - wxITEM_CHECK ); - if( unit == ii + 1 ) - item->Check(true); + wxMenuItem* item = Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString, + wxITEM_CHECK ); - // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_SYM_MAX + if( unit == ii + 1 ) + item->Check( true ); + + // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_END // See eeschema_id to modify this value. - if( ii >= (ID_POPUP_SCH_SELECT_UNIT_SYM_MAX - ID_POPUP_SCH_SELECT_UNIT1) ) + if( ii >= ( ID_POPUP_SCH_SELECT_UNIT_END - ID_POPUP_SCH_SELECT_UNIT1) ) + break; // We have used all IDs for these submenus + } + } +}; + + +class ALT_PIN_FUNCTION_MENU : public ACTION_MENU +{ +public: + ALT_PIN_FUNCTION_MENU() : + ACTION_MENU( true ) + { + SetIcon( BITMAPS::component_select_unit ); + SetTitle( _( "Alternate Pin Functions" ) ); + } + +protected: + ACTION_MENU* create() const override + { + return new ALT_PIN_FUNCTION_MENU(); + } + +private: + void update() override + { + EE_SELECTION_TOOL* selTool = getToolManager()->GetTool(); + EE_SELECTION& selection = selTool->GetSelection(); + SCH_PIN* pin = dynamic_cast( selection.Front() ); + + Clear(); + + if( !pin ) + { + Append( ID_POPUP_SCH_SELECT_UNIT, _( "no pin selected" ), wxEmptyString ); + Enable( ID_POPUP_SCH_SELECT_UNIT, false ); + return; + } + + if( !pin->GetLibPin() || pin->GetLibPin()->GetAlternates().empty() ) + { + Append( ID_POPUP_SCH_SELECT_UNIT, _( "no alternate pin functions defined" ), wxEmptyString ); + Enable( ID_POPUP_SCH_SELECT_UNIT, false ); + return; + } + + wxMenuItem* item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION, pin->GetName(), wxEmptyString, + wxITEM_CHECK ); + + if( pin->GetAlt().IsEmpty() ) + item->Check( true ); + + int ii = 1; + + for( const auto& [ name, definition ] : pin->GetLibPin()->GetAlternates() ) + { + item = Append( ID_POPUP_SCH_ALT_PIN_FUNCTION + ii, name, wxEmptyString, wxITEM_CHECK ); + + if( name == pin->GetAlt() ) + item->Check( true ); + + // The ID max for these submenus is ID_POPUP_SCH_ALT_PIN_FUNCTION_END + // See eeschema_id to modify this value. + if( ++ii >= ( ID_POPUP_SCH_ALT_PIN_FUNCTION_END - ID_POPUP_SCH_SELECT_UNIT ) ) break; // We have used all IDs for these submenus } } @@ -606,6 +670,11 @@ bool SCH_EDIT_TOOL::Init() m_selectionTool->GetToolMenu().RegisterSubMenu( symUnitMenu3 ); selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 ); + std::shared_ptr altPinMenu = std::make_shared(); + altPinMenu->SetTool( m_selectionTool ); + m_selectionTool->GetToolMenu().RegisterSubMenu( altPinMenu ); + selToolMenu.AddMenu( altPinMenu.get(), E_C::SingleMultiFunctionPin, 1 ); + selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, E_C::SingleSymbolOrPower && E_C::Idle, 200 ); selToolMenu.AddItem( EE_ACTIONS::changeSymbol, E_C::SingleSymbolOrPower, 200 ); selToolMenu.AddItem( EE_ACTIONS::updateSymbol, E_C::SingleSymbolOrPower, 200 ); diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 0ec559f00f..17e7bdc9c7 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -825,11 +825,11 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm } else if( evt->Action() == TA_CHOICE_MENU_CHOICE ) { - if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT_CMP - && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_SYM_MAX ) + if( *evt->GetCommandId() >= ID_POPUP_SCH_SELECT_UNIT + && *evt->GetCommandId() <= ID_POPUP_SCH_SELECT_UNIT_END ) { SCH_SYMBOL* symbol = dynamic_cast( selection.Front() ); - int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT_CMP; + int unit = *evt->GetCommandId() - ID_POPUP_SCH_SELECT_UNIT; if( symbol ) {