From e8e0b07223c53236067a90640d82d0382fefb309 Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Tue, 28 Jan 2025 14:58:28 +0000 Subject: [PATCH] Honour on-the-fly language changes. Fixes https://gitlab.com/kicad/code/kicad/-/issues/19773 --- common/lib_tree_model.cpp | 29 +++++---- common/lib_tree_model_adapter.cpp | 27 ++++++-- eeschema/sch_edit_frame.cpp | 8 +++ eeschema/widgets/design_block_pane.cpp | 61 ++++++++++++++++--- eeschema/widgets/design_block_pane.h | 7 +++ .../widgets/panel_design_block_chooser.cpp | 19 +++--- eeschema/widgets/panel_design_block_chooser.h | 15 +++-- eeschema/widgets/panel_symbol_chooser.cpp | 6 +- include/lib_tree_model.h | 5 +- include/lib_tree_model_adapter.h | 17 ++---- pcbnew/widgets/panel_footprint_chooser.cpp | 3 +- 11 files changed, 142 insertions(+), 55 deletions(-) diff --git a/common/lib_tree_model.cpp b/common/lib_tree_model.cpp index 10705ccabe..61e8c19d28 100644 --- a/common/lib_tree_model.cpp +++ b/common/lib_tree_model.cpp @@ -87,17 +87,16 @@ bool LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& a return aNode1.m_Type < aNode2.m_Type; // Recently used sorts at top - if( aNode1.m_Name.StartsWith( wxT( "-- " ) ) ) + if( aNode1.m_IsRecentlyUsedGroup ) { - if( aNode2.m_Name.StartsWith( wxT( "-- " ) ) ) + if( aNode2.m_IsRecentlyUsedGroup ) { - // Make sure -- Recently Used is always at the top - // Start by checking the name of aNode2, because we - // want to satisfy the irreflexive property of the - // strict weak ordering. - if( aNode2.m_Name.StartsWith( wxT( "-- Recently Used" ) ) ) + // Make sure "-- Recently Used" is always at the top + // Start by checking the name of aNode2, because we want to satisfy the irreflexive + // property of the strict weak ordering. + if( aNode2.m_IsRecentlyUsedGroup ) return false; - else if( aNode1.m_Name.StartsWith( wxT( "-- Recently Used" ) ) ) + else if( aNode1.m_IsRecentlyUsedGroup ) return true; return aNode1.m_IntrinsicRank > aNode2.m_IntrinsicRank; @@ -136,7 +135,9 @@ LIB_TREE_NODE::LIB_TREE_NODE() m_Pinned( false ), m_PinCount( 0 ), m_Unit( 0 ), - m_IsRoot( false ) + m_IsRoot( false ), + m_IsRecentlyUsedGroup( false ), + m_IsAlreadyPlacedGroup( false ) {} @@ -359,12 +360,18 @@ LIB_TREE_NODE_LIBRARY& LIB_TREE_NODE_ROOT::AddLib( wxString const& aName, wxStri } -void LIB_TREE_NODE_ROOT::RemoveLib( wxString const& aName ) +void LIB_TREE_NODE_ROOT::RemoveGroup( bool aRecentlyUsedGroup, bool aAlreadyPlacedGroup ) { m_Children.erase( std::remove_if( m_Children.begin(), m_Children.end(), [&]( std::unique_ptr<LIB_TREE_NODE>& aNode ) { - return aNode->m_Name == aName; + if( aRecentlyUsedGroup && aNode->m_IsRecentlyUsedGroup ) + return true; + + if( aAlreadyPlacedGroup && aNode->m_IsAlreadyPlacedGroup ) + return true; + + return false; } ), m_Children.end() ); } diff --git a/common/lib_tree_model_adapter.cpp b/common/lib_tree_model_adapter.cpp index 598b68b579..f4f558a698 100644 --- a/common/lib_tree_model_adapter.cpp +++ b/common/lib_tree_model_adapter.cpp @@ -232,9 +232,10 @@ LIB_TREE_NODE_LIBRARY& LIB_TREE_MODEL_ADAPTER::DoAddLibraryNode( const wxString& } -void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( const wxString& aNodeName, const wxString& aDesc, - const std::vector<LIB_TREE_ITEM*>& aItemList, - bool pinned, bool presorted ) +LIB_TREE_NODE_LIBRARY& LIB_TREE_MODEL_ADAPTER::DoAddLibrary( const wxString& aNodeName, + const wxString& aDesc, + const std::vector<LIB_TREE_ITEM*>& aItemList, + bool pinned, bool presorted ) { LIB_TREE_NODE_LIBRARY& lib_node = DoAddLibraryNode( aNodeName, aDesc, pinned ); @@ -242,12 +243,14 @@ void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( const wxString& aNodeName, const wxSt lib_node.AddItem( item ); lib_node.AssignIntrinsicRanks( presorted ); + + return lib_node; } -void LIB_TREE_MODEL_ADAPTER::DoRemoveLibrary( const wxString& aNodeName ) +void LIB_TREE_MODEL_ADAPTER::RemoveGroup( bool aRecentGroup, bool aPlacedGroup ) { - m_tree.RemoveLib( aNodeName ); + m_tree.RemoveGroup( aRecentGroup, aPlacedGroup ); } @@ -409,6 +412,20 @@ void LIB_TREE_MODEL_ADAPTER::UnpinLibrary( LIB_TREE_NODE* aTreeNode ) } +void LIB_TREE_MODEL_ADAPTER::ShowChangedLanguage() +{ + recreateColumns(); + + for( const std::unique_ptr<LIB_TREE_NODE>& lib: m_tree.m_Children ) + { + if( lib->m_IsRecentlyUsedGroup ) + lib->m_Name = wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ); + else if( lib->m_IsAlreadyPlacedGroup ) + lib->m_Name = wxT( "-- " ) + _( "Already Placed" ) + wxT( " --" ); + } +} + + wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader, bool aTranslate ) { wxString translatedHeader = aTranslate ? wxGetTranslation( aHeader ) : aHeader; diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 71118780bf..29224da69d 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -2196,9 +2196,17 @@ void SCH_EDIT_FRAME::ShowChangedLanguage() // tooltips in toolbars RecreateToolbars(); + // For some obscure reason, the AUI manager hides the first modified pane. + // So force show panes + wxAuiPaneInfo& design_blocks_pane_info = m_auimgr.GetPane( m_designBlocksPane ); + bool panel_shown = design_blocks_pane_info.IsShown(); + design_blocks_pane_info.Caption( _( "Design Blocks" ) ); + design_blocks_pane_info.Show( panel_shown ); + m_auimgr.GetPane( m_hierarchy ).Caption( _( "Schematic Hierarchy" ) ); m_auimgr.GetPane( m_selectionFilterPanel ).Caption( _( "Selection Filter" ) ); m_auimgr.GetPane( m_propertiesPanel ).Caption( _( "Properties" ) ); + m_auimgr.GetPane( m_designBlocksPane ).Caption( _( "Design Blocks" ) ); m_auimgr.Update(); m_hierarchy->UpdateHierarchyTree(); diff --git a/eeschema/widgets/design_block_pane.cpp b/eeschema/widgets/design_block_pane.cpp index f88017d54e..d949d973e7 100644 --- a/eeschema/widgets/design_block_pane.cpp +++ b/eeschema/widgets/design_block_pane.cpp @@ -37,13 +37,16 @@ #include <ee_actions.h> #include <tool/tool_manager.h> -static const wxString REPEATED_PLACEMENT = _( "Place repeated copies" ); -static const wxString PLACE_AS_SHEET = _( "Place as sheet" ); -static const wxString KEEP_ANNOTATIONS = _( "Keep annotations" ); + +// Do not make these static wxStrings; they need to respond to language changes +#define REPEATED_PLACEMENT _( "Place repeated copies" ) +#define PLACE_AS_SHEET _( "Place as sheet" ) +#define KEEP_ANNOTATIONS _( "Keep annotations" ) DESIGN_BLOCK_PANE::DESIGN_BLOCK_PANE( SCH_EDIT_FRAME* aParent, const LIB_ID* aPreselect, std::vector<LIB_ID>& aHistoryList ) : - WX_PANEL( aParent ), m_frame( aParent ) + WX_PANEL( aParent ), + m_frame( aParent ) { wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); m_chooserPanel = new PANEL_DESIGN_BLOCK_CHOOSER( aParent, this, aHistoryList, @@ -62,14 +65,9 @@ DESIGN_BLOCK_PANE::DESIGN_BLOCK_PANE( SCH_EDIT_FRAME* aParent, const LIB_ID* aPr wxBoxSizer* cbSizer = new wxBoxSizer( wxVERTICAL ); m_repeatedPlacement = new wxCheckBox( this, wxID_ANY, REPEATED_PLACEMENT ); - m_repeatedPlacement->SetToolTip( _( "Place copies of the design block on subsequent clicks." ) ); - m_placeAsSheet = new wxCheckBox( this, wxID_ANY, PLACE_AS_SHEET ); - m_placeAsSheet->SetToolTip( _( "Place the design block as a new sheet." ) ); - m_keepAnnotations = new wxCheckBox( this, wxID_ANY, KEEP_ANNOTATIONS ); - m_keepAnnotations->SetToolTip( _( "Preserve reference designators in the source schematic. " - "Otherwise, clear then reannotate according to settings." ) ); + setLabelsAndTooltips(); UpdateCheckboxes(); // Set all checkbox handlers to the same function @@ -88,6 +86,49 @@ DESIGN_BLOCK_PANE::DESIGN_BLOCK_PANE( SCH_EDIT_FRAME* aParent, const LIB_ID* aPr Layout(); Bind( wxEVT_CHAR_HOOK, &PANEL_DESIGN_BLOCK_CHOOSER::OnChar, m_chooserPanel ); + m_frame->Bind( EDA_LANG_CHANGED, &DESIGN_BLOCK_PANE::OnLanguageChanged, this ); +} + + +DESIGN_BLOCK_PANE::~DESIGN_BLOCK_PANE() +{ + m_frame->Unbind( EDA_LANG_CHANGED, &DESIGN_BLOCK_PANE::OnLanguageChanged, this ); +} + + +void DESIGN_BLOCK_PANE::setLabelsAndTooltips() +{ + if( m_repeatedPlacement ) + { + m_repeatedPlacement->SetLabel( REPEATED_PLACEMENT ); + m_repeatedPlacement->SetToolTip( _( "Place copies of the design block on subsequent " + "clicks." ) ); + } + + if( m_placeAsSheet ) + { + m_placeAsSheet->SetLabel( PLACE_AS_SHEET ); + m_placeAsSheet->SetToolTip( _( "Place the design block as a new sheet." ) ); + } + + if( m_keepAnnotations ) + { + m_keepAnnotations->SetLabel( KEEP_ANNOTATIONS ); + m_keepAnnotations->SetToolTip( _( "Preserve reference designators in the source " + "schematic. Otherwise, clear then reannotate according " + "to settings." ) ); + } +} + + +void DESIGN_BLOCK_PANE::OnLanguageChanged( wxCommandEvent& aEvent ) +{ + if( m_chooserPanel ) + m_chooserPanel->ShowChangedLanguage(); + + setLabelsAndTooltips(); + + aEvent.Skip(); } diff --git a/eeschema/widgets/design_block_pane.h b/eeschema/widgets/design_block_pane.h index 07a4505604..99d48e847e 100644 --- a/eeschema/widgets/design_block_pane.h +++ b/eeschema/widgets/design_block_pane.h @@ -50,6 +50,8 @@ public: DESIGN_BLOCK_PANE( SCH_EDIT_FRAME* aParent, const LIB_ID* aPreselect, std::vector<LIB_ID>& aHistoryList ); + ~DESIGN_BLOCK_PANE() override; + /** * To be called after this dialog returns from ShowModal(). * @@ -78,6 +80,11 @@ public: PANEL_DESIGN_BLOCK_CHOOSER* GetDesignBlockPanel() const { return m_chooserPanel; } +protected: + void setLabelsAndTooltips(); + + virtual void OnLanguageChanged( wxCommandEvent& aEvent ); + protected: PANEL_DESIGN_BLOCK_CHOOSER* m_chooserPanel; diff --git a/eeschema/widgets/panel_design_block_chooser.cpp b/eeschema/widgets/panel_design_block_chooser.cpp index ceca6d3225..3ebb03c88c 100644 --- a/eeschema/widgets/panel_design_block_chooser.cpp +++ b/eeschema/widgets/panel_design_block_chooser.cpp @@ -28,15 +28,11 @@ #include <design_block_preview_widget.h> #include <kiface_base.h> #include <sch_edit_frame.h> -#include <project_sch.h> #include <widgets/lib_tree.h> #include <settings/settings_manager.h> #include <project/project_file.h> -#include <eeschema_settings.h> #include <dialogs/html_message_box.h> #include <string_utils.h> -#include <wx/button.h> -#include <wx/clipbrd.h> #include <wx/log.h> #include <wx/panel.h> #include <wx/sizer.h> @@ -182,6 +178,13 @@ PANEL_DESIGN_BLOCK_CHOOSER::~PANEL_DESIGN_BLOCK_CHOOSER() } +void PANEL_DESIGN_BLOCK_CHOOSER::ShowChangedLanguage() +{ + if( m_tree ) + m_tree->ShowChangedLanguage(); +} + + void PANEL_DESIGN_BLOCK_CHOOSER::OnChar( wxKeyEvent& aEvent ) { if( aEvent.GetKeyCode() == WXK_ESCAPE ) @@ -386,9 +389,7 @@ void PANEL_DESIGN_BLOCK_CHOOSER::addDesignBlockToHistory( const LIB_ID& aLibId ) void PANEL_DESIGN_BLOCK_CHOOSER::rebuildHistoryNode() { - wxString history = wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ); - - m_adapter->DoRemoveLibrary( history ); + m_adapter->RemoveGroup( true, false ); // Build the history list std::vector<LIB_TREE_ITEM*> historyInfos; @@ -403,7 +404,9 @@ void PANEL_DESIGN_BLOCK_CHOOSER::rebuildHistoryNode() historyInfos.push_back( fp_info ); } - m_adapter->DoAddLibrary( history, wxEmptyString, historyInfos, false, true ); + m_adapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString, + historyInfos, false, true ) + .m_IsRecentlyUsedGroup = true; } diff --git a/eeschema/widgets/panel_design_block_chooser.h b/eeschema/widgets/panel_design_block_chooser.h index 307fb46cde..19e5ab8673 100644 --- a/eeschema/widgets/panel_design_block_chooser.h +++ b/eeschema/widgets/panel_design_block_chooser.h @@ -76,6 +76,8 @@ public: LIB_TREE* GetLibTree() { return m_tree; } + void ShowChangedLanguage(); + protected: static constexpr int DBLCLICK_DELAY = 100; // milliseconds @@ -98,21 +100,22 @@ protected: void displayErrors( wxTopLevelWindow* aWindow ); +protected: static wxString g_designBlockSearchString; - wxTimer* m_dbl_click_timer; - wxTimer* m_open_libs_timer; - wxSplitterWindow* m_vsplitter; + wxTimer* m_dbl_click_timer; + wxTimer* m_open_libs_timer; + wxSplitterWindow* m_vsplitter; wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> m_adapter; - LIB_TREE* m_tree; - DESIGN_BLOCK_PREVIEW_WIDGET* m_preview; + LIB_TREE* m_tree; + DESIGN_BLOCK_PREVIEW_WIDGET* m_preview; SCH_EDIT_FRAME* m_frame; std::function<void()> m_selectHandler; - std::vector<LIB_ID> m_historyList; + std::vector<LIB_ID> m_historyList; }; #endif /* PANEL_DESIGN_BLOCK_CHOOSER_H */ diff --git a/eeschema/widgets/panel_symbol_chooser.cpp b/eeschema/widgets/panel_symbol_chooser.cpp index 4c3f98fdf0..99a7069923 100644 --- a/eeschema/widgets/panel_symbol_chooser.cpp +++ b/eeschema/widgets/panel_symbol_chooser.cpp @@ -169,13 +169,15 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP processList( aAlreadyPlaced, already_placed_storage, already_placed ); adapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString, - history_list, false, true ); + history_list, false, true ) + .m_IsRecentlyUsedGroup = true; if( !aHistoryList.empty() ) adapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit ); adapter->DoAddLibrary( wxT( "-- " ) + _( "Already Placed" ) + wxT( " --" ), wxEmptyString, - already_placed, false, true ); + already_placed, false, true ) + .m_IsAlreadyPlacedGroup = true; const std::vector< wxString > libNicknames = libs->GetLogicalLibs(); diff --git a/include/lib_tree_model.h b/include/lib_tree_model.h index e0a0b602f0..4ebcb087ca 100644 --- a/include/lib_tree_model.h +++ b/include/lib_tree_model.h @@ -147,6 +147,9 @@ public: LIB_ID m_LibId; // LIB_ID determined by the parent library nickname and alias name. int m_Unit; // Actual unit, or zero bool m_IsRoot; // Indicates if the symbol is a root symbol instead of an alias. + + bool m_IsRecentlyUsedGroup; + bool m_IsAlreadyPlacedGroup; }; @@ -288,7 +291,7 @@ public: /** * Remove a library node from the root. */ - void RemoveLib( wxString const& aName ); + void RemoveGroup( bool aRecentlyUsedGroup, bool aAlreadyPlacedGroup ); /** * Clear the tree diff --git a/include/lib_tree_model_adapter.h b/include/lib_tree_model_adapter.h index 418e27ac70..82a594ba35 100644 --- a/include/lib_tree_model_adapter.h +++ b/include/lib_tree_model_adapter.h @@ -181,16 +181,14 @@ public: * @param aDesc the description field of the parent node * @param aItemList list of symbols */ - void DoAddLibrary( const wxString& aNodeName, const wxString& aDesc, - const std::vector<LIB_TREE_ITEM*>& aItemList, - bool pinned, bool presorted ); + LIB_TREE_NODE_LIBRARY& DoAddLibrary( const wxString& aNodeName, const wxString& aDesc, + const std::vector<LIB_TREE_ITEM*>& aItemList, + bool pinned, bool presorted ); /** - * Remove the library by name. - * - * @param aNodeName the name of the library to remove + * Remove one of the system groups from the library. */ - void DoRemoveLibrary( const wxString& aNodeName ); + void RemoveGroup( bool aRecentlyUsedGroup, bool aAlreadyPlacedGroup ); std::vector<wxString> GetAvailableColumns() const { return m_availableColumns; } @@ -318,10 +316,7 @@ public: void PinLibrary( LIB_TREE_NODE* aTreeNode ); void UnpinLibrary( LIB_TREE_NODE* aTreeNode ); - void ShowChangedLanguage() - { - recreateColumns(); - } + void ShowChangedLanguage(); protected: /** diff --git a/pcbnew/widgets/panel_footprint_chooser.cpp b/pcbnew/widgets/panel_footprint_chooser.cpp index 1800c6b39d..cce079af7c 100644 --- a/pcbnew/widgets/panel_footprint_chooser.cpp +++ b/pcbnew/widgets/panel_footprint_chooser.cpp @@ -94,7 +94,8 @@ PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopL } adapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString, - historyInfos, false, true ); + historyInfos, false, true ) + .m_IsRecentlyUsedGroup = true; if( historyInfos.size() ) adapter->SetPreselectNode( historyInfos[0]->GetLIB_ID(), 0 );