From 34c70a51ea77ffdc654f5525a91e7ceba23e03b3 Mon Sep 17 00:00:00 2001
From: Marek Roszko <mark.roszko@gmail.com>
Date: Sun, 10 Apr 2022 22:01:41 -0400
Subject: [PATCH] Stop leaking submenu items

Our menu bar code is interestingly complex. But we were throwing away newly made menu items to the void in the cases of constructed on the fly submenus
---
 3d-viewer/3d_viewer/3d_menubar.cpp             |  2 +-
 common/tool/action_menu.cpp                    |  4 ++--
 eeschema/menubar.cpp                           |  6 +++---
 .../symbol_editor/menubar_symbol_editor.cpp    |  4 ++--
 gerbview/menubar.cpp                           |  2 +-
 include/tool/action_menu.h                     |  3 ++-
 kicad/menubar.cpp                              | 12 ++++++------
 pagelayout_editor/menubar.cpp                  |  2 +-
 pcbnew/menubar_footprint_editor.cpp            | 10 +++++-----
 pcbnew/menubar_pcb_editor.cpp                  | 18 +++++++++---------
 10 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/3d-viewer/3d_viewer/3d_menubar.cpp b/3d-viewer/3d_viewer/3d_menubar.cpp
index b73db43f59..a765119b6b 100644
--- a/3d-viewer/3d_viewer/3d_menubar.cpp
+++ b/3d-viewer/3d_viewer/3d_menubar.cpp
@@ -138,7 +138,7 @@ void EDA_3D_VIEWER_FRAME::CreateMenuBar()
     gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
     gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid,   ACTION_MENU::CHECK);
 
-    prefsMenu->Add( gridSubmenu );
+    prefsMenu->Add( gridSubmenu, false );
 
     //-- Menubar -------------------------------------------------------------
     //
diff --git a/common/tool/action_menu.cpp b/common/tool/action_menu.cpp
index 79925aa5c0..54a733ef41 100644
--- a/common/tool/action_menu.cpp
+++ b/common/tool/action_menu.cpp
@@ -181,9 +181,9 @@ wxMenuItem* ACTION_MENU::Add( const TOOL_ACTION& aAction, bool aIsCheckmarkEntry
 }
 
 
-wxMenuItem* ACTION_MENU::Add( ACTION_MENU* aMenu )
+wxMenuItem* ACTION_MENU::Add( ACTION_MENU* aMenu, bool aClone )
 {
-    ACTION_MENU* menuCopy = aMenu->Clone();
+    ACTION_MENU* menuCopy = aClone ? aMenu->Clone() : aMenu;
     m_submenus.push_back( menuCopy );
 
     wxASSERT_MSG( !menuCopy->m_title.IsEmpty(), "Set a title for ACTION_MENU using SetTitle()" );
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index 5910cdb2b0..55f14c8233 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -107,7 +107,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
                         BITMAPS::import_document );
 
     submenuImport->Add( EE_ACTIONS::importFPAssignments, ACTION_MENU::NORMAL, _( "Footprint Assignments..." ) );
-    fileMenu->Add( submenuImport );
+    fileMenu->Add( submenuImport, false );
 
 
     // Export submenu
@@ -116,7 +116,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
     submenuExport->SetIcon( BITMAPS::export_file );
     submenuExport->Add( EE_ACTIONS::drawSheetOnClipboard, ACTION_MENU::NORMAL, _( "Drawing to Clipboard" ) );
     submenuExport->Add( EE_ACTIONS::exportNetlist,        ACTION_MENU::NORMAL, _( "Netlist..." ) );
-    fileMenu->Add( submenuExport );
+    fileMenu->Add( submenuExport, false );
 
     fileMenu->AppendSeparator();
     fileMenu->Add( EE_ACTIONS::schematicSetup );
@@ -184,7 +184,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::inchesUnits,        ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::milsUnits,          ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits,   ACTION_MENU::CHECK );
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->Add( ACTIONS::toggleCursorStyle,      ACTION_MENU::CHECK );
 
diff --git a/eeschema/symbol_editor/menubar_symbol_editor.cpp b/eeschema/symbol_editor/menubar_symbol_editor.cpp
index ac4263b7f0..9104016d68 100644
--- a/eeschema/symbol_editor/menubar_symbol_editor.cpp
+++ b/eeschema/symbol_editor/menubar_symbol_editor.cpp
@@ -70,7 +70,7 @@ void SYMBOL_EDIT_FRAME::ReCreateMenuBar()
     submenuExport->Add( EE_ACTIONS::exportSymbol,      ACTION_MENU::NORMAL, _( "Symbol..." ) );
     submenuExport->Add( EE_ACTIONS::exportSymbolView,  ACTION_MENU::NORMAL, _( "View as PNG..." ) );
     submenuExport->Add( EE_ACTIONS::exportSymbolAsSVG, ACTION_MENU::NORMAL, _( "Symbol as SVG..." ) );
-    fileMenu->Add( submenuExport );
+    fileMenu->Add( submenuExport, false );
 
     fileMenu->AppendSeparator();
     fileMenu->Add( EE_ACTIONS::symbolProperties );
@@ -125,7 +125,7 @@ void SYMBOL_EDIT_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::inchesUnits,      ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::milsUnits,        ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits, ACTION_MENU::CHECK );
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->Add( ACTIONS::toggleCursorStyle,    ACTION_MENU::CHECK );
 
diff --git a/gerbview/menubar.cpp b/gerbview/menubar.cpp
index a43fa405ff..302e9e9213 100644
--- a/gerbview/menubar.cpp
+++ b/gerbview/menubar.cpp
@@ -178,7 +178,7 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::milsUnits,                    ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits,             ACTION_MENU::CHECK );
 
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->AppendSeparator();
     viewMenu->Add( GERBVIEW_ACTIONS::flashedDisplayOutlines,  ACTION_MENU::CHECK );
diff --git a/include/tool/action_menu.h b/include/tool/action_menu.h
index 8b281ebb03..3d8b94db12 100644
--- a/include/tool/action_menu.h
+++ b/include/tool/action_menu.h
@@ -105,8 +105,9 @@ public:
      * handle icons.
      *
      * @param aMenu is the submenu to be added.
+     * @param aClone is whether or not the submenu should be copied from a reference submenu
      */
-    wxMenuItem* Add( ACTION_MENU* aMenu );
+    wxMenuItem* Add( ACTION_MENU* aMenu, bool aClone = true );
 
     /**
      * Add a standard close item to the menu with the accelerator key CTRL-W.
diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp
index 227d74601b..f4b7748f49 100644
--- a/kicad/menubar.cpp
+++ b/kicad/menubar.cpp
@@ -95,21 +95,21 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
     fileMenu->AppendSeparator();
 
     //Import Sub-menu
-    ACTION_MENU* importMenu = new ACTION_MENU( false, controlTool );
-    importMenu->SetTitle( _( "Import Non-KiCad Project..." ) );
-    importMenu->SetIcon( BITMAPS::import_project );
+    ACTION_MENU* importSubMenu = new ACTION_MENU( false, controlTool );
+    importSubMenu->SetTitle( _( "Import Non-KiCad Project..." ) );
+    importSubMenu->SetIcon( BITMAPS::import_project );
 
-    importMenu->Add( _( "CADSTAR Project..." ),
+    importSubMenu->Add( _( "CADSTAR Project..." ),
                      _( "Import CADSTAR Archive Schematic and PCB (*.csa, *.cpa)" ),
                      ID_IMPORT_CADSTAR_ARCHIVE_PROJECT,
                      BITMAPS::import_project );
 
-    importMenu->Add( _( "EAGLE Project..." ),
+    importSubMenu->Add( _( "EAGLE Project..." ),
                      _( "Import EAGLE CAD XML schematic and board" ),
                      ID_IMPORT_EAGLE_PROJECT,
                      BITMAPS::import_project );
 
-    fileMenu->Add( importMenu );
+    fileMenu->Add( importSubMenu, false );
 
     fileMenu->AppendSeparator();
     fileMenu->Add( _( "&Archive Project..." ),
diff --git a/pagelayout_editor/menubar.cpp b/pagelayout_editor/menubar.cpp
index c4994daec2..1763022e87 100644
--- a/pagelayout_editor/menubar.cpp
+++ b/pagelayout_editor/menubar.cpp
@@ -118,7 +118,7 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::inchesUnits,      ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::milsUnits,        ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits, ACTION_MENU::CHECK );
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->Add( ACTIONS::toggleCursorStyle,   ACTION_MENU::CHECK );
 
diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp
index 37a088f83f..6eadd7fdfd 100644
--- a/pcbnew/menubar_footprint_editor.cpp
+++ b/pcbnew/menubar_footprint_editor.cpp
@@ -68,7 +68,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
     submenuImport->Add( PCB_ACTIONS::importFootprint,        ACTION_MENU::NORMAL, _( "Footprint..." ) );
     submenuImport->Add( PCB_ACTIONS::placeImportedGraphics,  ACTION_MENU::NORMAL, _( "Graphics..." ) );
 
-    fileMenu->Add( submenuImport );
+    fileMenu->Add( submenuImport, false );
 
     ACTION_MENU* submenuExport = new ACTION_MENU( false, selTool );
     submenuExport->SetTitle( _( "Export" ) );
@@ -80,7 +80,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
                         ID_FPEDIT_SAVE_PNG,
                         BITMAPS::export_png );
 
-    fileMenu->Add( submenuExport );
+    fileMenu->Add( submenuExport, false );
 
     fileMenu->AppendSeparator();
     fileMenu->Add( PCB_ACTIONS::footprintProperties );
@@ -140,7 +140,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::inchesUnits,                ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::milsUnits,                  ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits,           ACTION_MENU::CHECK );
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->Add( ACTIONS::toggleCursorStyle,              ACTION_MENU::CHECK );
 
@@ -153,7 +153,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
     drawingModeSubMenu->Add( PCB_ACTIONS::padDisplayMode,   ACTION_MENU::CHECK );
     drawingModeSubMenu->Add( PCB_ACTIONS::graphicsOutlines, ACTION_MENU::CHECK );
     drawingModeSubMenu->Add( PCB_ACTIONS::textOutlines,     ACTION_MENU::CHECK );
-    viewMenu->Add( drawingModeSubMenu );
+    viewMenu->Add( drawingModeSubMenu, false );
 
     // Contrast Mode Submenu
     ACTION_MENU* contrastModeSubMenu = new ACTION_MENU( false, selTool );
@@ -163,7 +163,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
     contrastModeSubMenu->Add( ACTIONS::highContrastMode,    ACTION_MENU::CHECK );
     contrastModeSubMenu->Add( PCB_ACTIONS::layerAlphaDec );
     contrastModeSubMenu->Add( PCB_ACTIONS::layerAlphaInc );
-    viewMenu->Add( contrastModeSubMenu );
+    viewMenu->Add( contrastModeSubMenu, false );
 
     viewMenu->Add( PCB_ACTIONS::flipBoard,                  ACTION_MENU::CHECK );
 
diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp
index 5901e37e34..a35756d6de 100644
--- a/pcbnew/menubar_pcb_editor.cpp
+++ b/pcbnew/menubar_pcb_editor.cpp
@@ -119,7 +119,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     }
 
     fileMenu->AppendSeparator();
-    fileMenu->Add( submenuImport );
+    fileMenu->Add( submenuImport, false );
 
     // Export submenu
     ACTION_MENU* submenuExport = new ACTION_MENU( false, selTool );
@@ -157,7 +157,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
                            "(if the library already exists it will be replaced)" ),
                         ID_MENU_EXPORT_FOOTPRINTS_TO_NEW_LIBRARY, BITMAPS::library_archive_as );
 
-    fileMenu->Add( submenuExport );
+    fileMenu->Add( submenuExport, false );
 
     // Fabrication Outputs submenu
     ACTION_MENU* submenuFabOutputs = new ACTION_MENU( false, selTool );
@@ -170,7 +170,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     submenuFabOutputs->Add( PCB_ACTIONS::generateReportFile );
     submenuFabOutputs->Add( PCB_ACTIONS::generateD356File );
     submenuFabOutputs->Add( PCB_ACTIONS::generateBOM );
-    fileMenu->Add( submenuFabOutputs );
+    fileMenu->Add( submenuFabOutputs, false );
 
     fileMenu->AppendSeparator();
     fileMenu->Add( PCB_ACTIONS::boardSetup );
@@ -246,7 +246,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     unitsSubMenu->Add( ACTIONS::inchesUnits,          ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::milsUnits,            ACTION_MENU::CHECK );
     unitsSubMenu->Add( ACTIONS::millimetersUnits,     ACTION_MENU::CHECK );
-    viewMenu->Add( unitsSubMenu );
+    viewMenu->Add( unitsSubMenu, false );
 
     viewMenu->Add( ACTIONS::toggleCursorStyle,        ACTION_MENU::CHECK );
 
@@ -278,7 +278,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     drawingModeSubMenu->Add( PCB_ACTIONS::graphicsOutlines,    ACTION_MENU::CHECK );
     drawingModeSubMenu->Add( PCB_ACTIONS::textOutlines,        ACTION_MENU::CHECK );
 
-    viewMenu->Add( drawingModeSubMenu );
+    viewMenu->Add( drawingModeSubMenu, false );
 
     // Contrast Mode Submenu
     ACTION_MENU* contrastModeSubMenu = new ACTION_MENU( false, selTool );
@@ -288,7 +288,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     contrastModeSubMenu->Add( ACTIONS::highContrastMode,    ACTION_MENU::CHECK );
     contrastModeSubMenu->Add( PCB_ACTIONS::layerAlphaDec );
     contrastModeSubMenu->Add( PCB_ACTIONS::layerAlphaInc );
-    viewMenu->Add( contrastModeSubMenu );
+    viewMenu->Add( contrastModeSubMenu, false );
 
     viewMenu->Add( PCB_ACTIONS::flipBoard,                  ACTION_MENU::CHECK );
 
@@ -313,7 +313,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     muwaveSubmenu->Add( PCB_ACTIONS::microwaveCreateStub );
     muwaveSubmenu->Add( PCB_ACTIONS::microwaveCreateStubArc );
     muwaveSubmenu->Add( PCB_ACTIONS::microwaveCreateFunctionShape );
-    placeMenu->Add( muwaveSubmenu );
+    placeMenu->Add( muwaveSubmenu, false );
 
     placeMenu->AppendSeparator();
     placeMenu->Add( PCB_ACTIONS::drawLine );
@@ -349,7 +349,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     autoplaceSubmenu->Add( PCB_ACTIONS::autoplaceOffboardComponents );
     autoplaceSubmenu->Add( PCB_ACTIONS::autoplaceSelectedComponents );
 
-    placeMenu->Add( autoplaceSubmenu );
+    placeMenu->Add( autoplaceSubmenu, false );
 
 
     //-- Route Menu ----------------------------------------------------------
@@ -444,7 +444,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     buildActionPluginMenus( submenuActionPlugins );
 
     toolsMenu->AppendSeparator();
-    toolsMenu->Add( submenuActionPlugins );
+    toolsMenu->Add( submenuActionPlugins, false );
 
     //-- Preferences menu ----------------------------------------------------
     //