diff --git a/common/lib_tree_model.cpp b/common/lib_tree_model.cpp index f7691a855b..b3e6e49b6a 100644 --- a/common/lib_tree_model.cpp +++ b/common/lib_tree_model.cpp @@ -156,7 +156,16 @@ LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* a m_LibId = aParent->m_LibId; m_Name = namePrefix + " " + aItem->GetUnitReference( aUnit ); - m_Desc = wxEmptyString; + + if( aItem->HasUnitDisplayName( aUnit ) ) + { + m_Desc = aItem->GetUnitDisplayName( aUnit ); + } + else + { + m_Desc = wxEmptyString; + } + m_MatchName = wxEmptyString; m_IntrinsicRank = -aUnit; diff --git a/eeschema/dialogs/dialog_symbol_properties.cpp b/eeschema/dialogs/dialog_symbol_properties.cpp index 25b05ba8f7..754306da51 100644 --- a/eeschema/dialogs/dialog_symbol_properties.cpp +++ b/eeschema/dialogs/dialog_symbol_properties.cpp @@ -481,7 +481,12 @@ bool DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow() m_symbol->UpdateUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) ); for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ ) - m_unitChoice->Append( LIB_SYMBOL::SubReference( ii, false ) ); + { + if( m_symbol->HasUnitDisplayName( ii ) ) + m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) ); + else + m_unitChoice->Append( LIB_SYMBOL::SubReference( ii, false ) ); + } if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() ) m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 ); diff --git a/eeschema/lib_symbol.cpp b/eeschema/lib_symbol.cpp index cdfea0c3ff..a8cc15d613 100644 --- a/eeschema/lib_symbol.cpp +++ b/eeschema/lib_symbol.cpp @@ -150,6 +150,8 @@ LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) : m_description = aSymbol.m_description; m_keyWords = aSymbol.m_keyWords; + aSymbol.CopyUnitDisplayNames( m_unitDisplayNames ); + ClearSelected(); for( const LIB_ITEM& oldItem : aSymbol.m_drawings ) @@ -206,6 +208,9 @@ const LIB_SYMBOL& LIB_SYMBOL::operator=( const LIB_SYMBOL& aSymbol ) m_description = aSymbol.m_description; m_keyWords = aSymbol.m_keyWords; + m_unitDisplayNames.clear(); + aSymbol.CopyUnitDisplayNames( m_unitDisplayNames ); + m_drawings.clear(); for( const LIB_ITEM& oldItem : aSymbol.m_drawings ) @@ -369,6 +374,16 @@ int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const return ( m_includeOnBoard ) ? 1 : -1; } + // Compare unit display names + if( m_unitDisplayNames < aRhs.m_unitDisplayNames ) + { + return -1; + } + else if( m_unitDisplayNames > aRhs.m_unitDisplayNames ) + { + return 1; + } + return 0; } @@ -379,6 +394,50 @@ wxString LIB_SYMBOL::GetUnitReference( int aUnit ) } +bool LIB_SYMBOL::HasUnitDisplayName( int aUnit ) +{ + return ( m_unitDisplayNames.count( aUnit ) == 1 ); +} + + +wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit ) +{ + if( HasUnitDisplayName( aUnit ) ) + { + return m_unitDisplayNames[aUnit]; + } + else + { + return wxString::Format( _( "Unit %s" ), GetUnitReference( aUnit ) ); + } +} + + +void LIB_SYMBOL::CopyUnitDisplayNames( std::map& aTarget ) const +{ + for( const auto& it : m_unitDisplayNames ) + { + aTarget[it.first] = it.second; + } +} + + +void LIB_SYMBOL::SetUnitDisplayName( int aUnit, const wxString& aName ) +{ + if( aUnit <= GetUnitCount() ) + { + if( aName.Length() > 0 ) + { + m_unitDisplayNames[aUnit] = aName; + } + else + { + m_unitDisplayNames.erase( aUnit ); + } + } +} + + void LIB_SYMBOL::SetName( const wxString& aName ) { m_name = aName; diff --git a/eeschema/lib_symbol.h b/eeschema/lib_symbol.h index a01c2909bf..2dc224bc25 100644 --- a/eeschema/lib_symbol.h +++ b/eeschema/lib_symbol.h @@ -526,6 +526,26 @@ public: */ wxString GetUnitReference( int aUnit ) override; + /** + * Return true if the given unit \a aUnit has a display name defined + */ + bool HasUnitDisplayName( int aUnit ) override; + + /** + * Return the user-defined display name for \a aUnit for symbols with units. + */ + wxString GetUnitDisplayName( int aUnit ) override; + + /** + * Copy all unit display names into the given map \a aTarget + */ + void CopyUnitDisplayNames( std::map& aTarget ) const; + + /** + * Set the user-defined display name for \a aUnit to \a aName for symbols with units. + */ + void SetUnitDisplayName( int aUnit, const wxString& aName ); + /** * @return true if the symbol has multiple units per symbol. * When true, the reference has a sub reference to identify symbol. @@ -731,6 +751,7 @@ private: static int m_subpartFirstId; ///< the ASCII char value to calculate the subpart ///< symbol id from the symbol number: only 'A', 'a' ///< or '1' can be used, other values have no sense. + std::map m_unitDisplayNames; }; #endif // CLASS_LIBENTRY_H diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp index 811645923e..7dacfcb403 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_lib_plugin_cache.cpp @@ -228,6 +228,13 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& a aFormatter.Print( aNestLevel + 1, "(symbol %s_%d_%d\"\n", name.c_str(), unit.m_unit, unit.m_convert ); + // if the unit has a display name, write that + if( aSymbol->HasUnitDisplayName( unit.m_unit ) ) + { + name = aSymbol->GetUnitDisplayName( unit.m_unit ); + aFormatter.Print( aNestLevel + 2, "(unit_name %s)\n", + aFormatter.Quotes( name ).c_str() ); + } // Enforce item ordering auto cmp = []( const LIB_ITEM* a, const LIB_ITEM* b ) diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index 34a0aafeb0..3b0fae19e3 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -168,6 +168,7 @@ LIB_SYMBOL* SCH_SEXPR_PARSER::ParseSymbol( LIB_SYMBOL_MAP& aSymbolLibMap, int aF long tmp; wxString name; wxString error; + wxString unitDisplayName; LIB_ITEM* item; std::unique_ptr symbol = std::make_unique( wxEmptyString ); @@ -335,6 +336,17 @@ LIB_SYMBOL* SCH_SEXPR_PARSER::ParseSymbol( LIB_SYMBOL_MAP& aSymbolLibMap, int aF switch( token ) { + case T_unit_name: + token = NextTok(); + + if( IsSymbol( token ) ) + { + unitDisplayName = FromUTF8(); + symbol->SetUnitDisplayName( m_unit, unitDisplayName ); + } + NeedRIGHT(); + break; + case T_arc: case T_bezier: case T_circle: diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index 8d24223258..c98c8efba0 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -147,6 +147,7 @@ SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId, // Inherit the include in bill of materials and board netlist settings from library symbol. m_inBom = aSymbol.GetIncludeInBom(); m_onBoard = aSymbol.GetIncludeOnBoard(); + } @@ -430,6 +431,22 @@ int SCH_SYMBOL::GetUnitCount() const } +wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit ) +{ + wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), LIB_SYMBOL::SubReference( aUnit ) ) ) ); + + return m_part->GetUnitDisplayName( aUnit ); +} + + +bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) +{ + wxCHECK( m_part, false ); + + return m_part->HasUnitDisplayName( aUnit ); +} + + void SCH_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) { LIB_SYMBOL_OPTIONS opts; diff --git a/eeschema/sch_symbol.h b/eeschema/sch_symbol.h index 45bdb1f1b0..4c40eb546d 100644 --- a/eeschema/sch_symbol.h +++ b/eeschema/sch_symbol.h @@ -240,6 +240,20 @@ public: */ void SetUnit( int aUnit ); + /** + * Return true if the given unit \a aUnit has a display name set. + * + * @return true if the display name of a unit is set, otherwise false. + */ + bool HasUnitDisplayName( int aUnit ); + + /** + * Return the display name for a given unit \a aUnit. + * + * @return the display name of a unit if set, or the ordinal name of the unit otherwise. + */ + wxString GetUnitDisplayName( int aUnit ); + /** * Change the unit number to \a aUnit without setting any internal flags. * This has meaning only for symbols made up of multiple units per package. diff --git a/eeschema/schematic.keywords b/eeschema/schematic.keywords index ee31ed1998..66fa50bf26 100644 --- a/eeschema/schematic.keywords +++ b/eeschema/schematic.keywords @@ -130,6 +130,7 @@ top tri_state type unit +unit_name unspecified uuid value diff --git a/eeschema/symbol_editor/menubar_symbol_editor.cpp b/eeschema/symbol_editor/menubar_symbol_editor.cpp index ac4263b7f0..2c70a39e1b 100644 --- a/eeschema/symbol_editor/menubar_symbol_editor.cpp +++ b/eeschema/symbol_editor/menubar_symbol_editor.cpp @@ -98,6 +98,7 @@ void SYMBOL_EDIT_FRAME::ReCreateMenuBar() editMenu->AppendSeparator(); editMenu->Add( EE_ACTIONS::pinTable ); + editMenu->Add( EE_ACTIONS::setUnitDisplayName ); editMenu->Add( EE_ACTIONS::updateSymbolFields ); diff --git a/eeschema/symbol_editor/symbol_edit_frame.cpp b/eeschema/symbol_editor/symbol_edit_frame.cpp index 126bb28077..43c0cb07f9 100644 --- a/eeschema/symbol_editor/symbol_edit_frame.cpp +++ b/eeschema/symbol_editor/symbol_edit_frame.cpp @@ -474,6 +474,12 @@ void SYMBOL_EDIT_FRAME::setupUIConditions() return m_symbol && m_symbol->IsMulti() && !m_symbol->UnitsLocked(); }; + auto hasMultipleUnitsCond = + [this]( const SELECTION& ) + { + return m_symbol && m_symbol->IsMulti(); + }; + auto syncedPinsModeCond = [this]( const SELECTION& ) { @@ -497,6 +503,8 @@ void SYMBOL_EDIT_FRAME::setupUIConditions() ACTION_CONDITIONS().Enable( demorganCond ).Check( demorganAlternateCond ) ); mgr->SetConditions( EE_ACTIONS::toggleSyncedPinsMode, ACTION_CONDITIONS().Enable( multiUnitModeCond ).Check( syncedPinsModeCond ) ); + mgr->SetConditions( EE_ACTIONS::setUnitDisplayName, + ACTION_CONDITIONS().Enable( isEditableCond && hasMultipleUnitsCond ) ); // Only enable a tool if the symbol is edtable #define EDIT_TOOL( tool ) ACTION_CONDITIONS().Enable( isEditableCond ).Check( cond.CurrentTool( tool ) ) @@ -594,9 +602,8 @@ void SYMBOL_EDIT_FRAME::RebuildSymbolUnitsList() { for( int i = 0; i < m_symbol->GetUnitCount(); i++ ) { - wxString sub = LIB_SYMBOL::SubReference( i+1, false ); - wxString unit = wxString::Format( _( "Unit %s" ), sub ); - m_unitSelectBox->Append( unit ); + wxString unitDisplayName = m_symbol->GetUnitDisplayName( i + 1 ); + m_unitSelectBox->Append( unitDisplayName ); } } @@ -1552,4 +1559,4 @@ void SYMBOL_EDIT_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aU eda_text->ClearBoundingBoxCache(); eda_text->ClearRenderCache(); } -} \ No newline at end of file +} diff --git a/eeschema/symbol_viewer_frame.cpp b/eeschema/symbol_viewer_frame.cpp index 0aaa809f43..ce8b6983a2 100644 --- a/eeschema/symbol_viewer_frame.cpp +++ b/eeschema/symbol_viewer_frame.cpp @@ -543,8 +543,7 @@ void SYMBOL_VIEWER_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent ) for( int ii = 0; ii < unit_count; ii++ ) { - wxString sub = LIB_SYMBOL::SubReference( ii + 1, false ); - wxString unit = wxString::Format( _( "Unit %s" ), sub ); + wxString unit = symbol->GetUnitDisplayName( ii + 1 ); m_unitChoice->Append( unit ); } diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index cb9e4c8d40..891c07476c 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -182,6 +182,10 @@ TOOL_ACTION EE_ACTIONS::updateSymbolFields( "eeschema.SymbolLibraryControl.updat _( "Update Symbol Fields..." ), _( "Update symbol to match changes made in parent symbol" ), BITMAPS::refresh ); +TOOL_ACTION EE_ACTIONS::setUnitDisplayName( "eeschema.SymbolLibraryControl.setUnitDisplayName", + AS_GLOBAL, 0, "", _( "Set Unit Display Name..." ), + _( "Set the display name for a unit" ) ); + TOOL_ACTION EE_ACTIONS::addSymbolToSchematic( "eeschema.SymbolLibraryControl.addSymbolToSchematic", AS_GLOBAL, 0, "", _( "Add Symbol to Schematic" ), _( "Add Symbol to Schematic" ), diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index 779832d27a..d7cf4cac8a 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -192,6 +192,7 @@ public: static TOOL_ACTION importSymbol; static TOOL_ACTION exportSymbol; static TOOL_ACTION updateSymbolFields; + static TOOL_ACTION setUnitDisplayName; // Hierarchy navigation static TOOL_ACTION changeSheet; diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 3dee1fa515..631a31de00 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -225,6 +225,18 @@ bool EE_SELECTION_TOOL::Init() static_cast( m_frame )->GetCurSymbol(); }; + auto symbolDisplayNameIsEditable = + [&]( const SELECTION& sel ) + { + if ( !m_isSymbolEditor ) + return false; + + SYMBOL_EDIT_FRAME* symEditFrame = dynamic_cast( m_frame ); + + return symEditFrame->GetCurSymbol() && symEditFrame->GetCurSymbol()->IsMulti() + && symEditFrame->IsSymbolEditable() && !symEditFrame->IsSymbolAlias(); + }; + auto& menu = m_menu.GetMenu(); menu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 ); @@ -260,6 +272,8 @@ bool EE_SELECTION_TOOL::Init() menu.AddSeparator( 400 ); menu.AddItem( EE_ACTIONS::symbolProperties, haveSymbol && EE_CONDITIONS::Empty, 400 ); menu.AddItem( EE_ACTIONS::pinTable, haveSymbol && EE_CONDITIONS::Empty, 400 ); + menu.AddItem( EE_ACTIONS::setUnitDisplayName, + haveSymbol && symbolDisplayNameIsEditable && EE_CONDITIONS::Empty, 400 ); menu.AddSeparator( 1000 ); m_frame->AddStandardSubMenus( m_menu ); diff --git a/eeschema/tools/symbol_editor_edit_tool.cpp b/eeschema/tools/symbol_editor_edit_tool.cpp index 7ab14f50aa..ae6764df7f 100644 --- a/eeschema/tools/symbol_editor_edit_tool.cpp +++ b/eeschema/tools/symbol_editor_edit_tool.cpp @@ -42,6 +42,7 @@ #include "symbol_editor_edit_tool.h" #include "dialog_lib_textbox_properties.h" #include "lib_textbox.h" +#include // for wxTextEntryDialog #include // for KiROUND SYMBOL_EDITOR_EDIT_TOOL::SYMBOL_EDITOR_EDIT_TOOL() : @@ -646,6 +647,47 @@ int SYMBOL_EDITOR_EDIT_TOOL::UpdateSymbolFields( const TOOL_EVENT& aEvent ) } +int SYMBOL_EDITOR_EDIT_TOOL::SetUnitDisplayName( const TOOL_EVENT& aEvent ) +{ + LIB_SYMBOL* symbol = m_frame->GetCurSymbol(); + + if( !symbol ) + return 0; + + int unitid = m_frame->GetUnit(); + + if( unitid == 0 ) + { + return -1; + } + + wxString promptText = wxString::Format( _( "Enter display name for unit %s" ), + symbol->GetUnitReference( unitid ) ); + wxString currentvalue; + + if( symbol->HasUnitDisplayName( unitid ) ) + { + currentvalue = symbol->GetUnitDisplayName( unitid ); + } + + wxTextEntryDialog dlg( m_frame, promptText, _( "Set Unit Display Name" ), currentvalue ); + + if( dlg.ShowModal() == wxID_OK ) + { + saveCopyInUndoList( symbol, UNDO_REDO::LIBEDIT ); + symbol->SetUnitDisplayName( unitid, dlg.GetValue() ); + m_frame->RebuildSymbolUnitsList(); + m_frame->OnModify(); + } + else + { + return -1; + } + + return 0; +} + + int SYMBOL_EDITOR_EDIT_TOOL::Undo( const TOOL_EVENT& aEvent ) { m_frame->GetSymbolFromUndoList(); @@ -854,4 +896,5 @@ void SYMBOL_EDITOR_EDIT_TOOL::setTransitions() Go( &SYMBOL_EDITOR_EDIT_TOOL::Properties, EE_ACTIONS::symbolProperties.MakeEvent() ); Go( &SYMBOL_EDITOR_EDIT_TOOL::PinTable, EE_ACTIONS::pinTable.MakeEvent() ); Go( &SYMBOL_EDITOR_EDIT_TOOL::UpdateSymbolFields, EE_ACTIONS::updateSymbolFields.MakeEvent() ); + Go( &SYMBOL_EDITOR_EDIT_TOOL::SetUnitDisplayName, EE_ACTIONS::setUnitDisplayName.MakeEvent() ); } diff --git a/eeschema/tools/symbol_editor_edit_tool.h b/eeschema/tools/symbol_editor_edit_tool.h index 3fab2fcedb..9947727727 100644 --- a/eeschema/tools/symbol_editor_edit_tool.h +++ b/eeschema/tools/symbol_editor_edit_tool.h @@ -47,6 +47,7 @@ public: int Properties( const TOOL_EVENT& aEvent ); int PinTable( const TOOL_EVENT& aEvent ); + int SetUnitDisplayName( const TOOL_EVENT& aEvent ); int UpdateSymbolFields( const TOOL_EVENT& aEvent ); int Undo( const TOOL_EVENT& aEvent ); diff --git a/include/lib_tree_item.h b/include/lib_tree_item.h index 58e26f2f5e..0015e0060b 100644 --- a/include/lib_tree_item.h +++ b/include/lib_tree_item.h @@ -76,6 +76,16 @@ public: * For items with units, return an identifier for unit x. */ virtual wxString GetUnitReference( int aUnit ) { return wxEmptyString; } + + /** + * For items with units, return a display name for unit x. + */ + virtual wxString GetUnitDisplayName( int aUnit ) { return wxEmptyString; } + + /** + * For items with units, return true if a display name is set for x. + */ + virtual bool HasUnitDisplayName( int aUnit ) { return false; } }; #endif //LIB_TREE_ITEM_H