tdf#104382 - Menus should be disabled when they have no enabled submenus

Disable menu elements if they only have disabled submenu elemets.
TODO: GTK3

Change-Id: I83cdc58846afd61719ceeba9f993df894ce6fd01
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154938
Tested-by: Jenkins
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index b445324..f86ede8e 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -515,7 +515,7 @@ void SAL_CALL MenuBarManager::disposing( const EventObject& Source )
static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId)
{
    if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId ))
        pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() != 0 );
        pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() != 0 && pThisPopup->HasValidEntries(true));
}

// vcl handler
@@ -672,6 +672,15 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
                {
                    if( xMenuItemDispatch.is() || menuItemHandler->aMenuItemURL != ".uno:RecentFileList" )
                        bPopupMenu = CreatePopupMenuController(menuItemHandler.get(), m_xDispatchProvider, m_aModuleIdentifier);

                    if (bPopupMenu && menuItemHandler->xPopupMenuController.is())
                    {
                        if (PopupMenu* pThisPopup = pMenu->GetPopupMenu(menuItemHandler->nItemId))
                        {
                            pThisPopup->Activate();
                            pThisPopup->Deactivate();
                        }
                    }
                }
                else if ( menuItemHandler->xPopupMenuController.is() )
                {
@@ -679,7 +688,10 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
                    menuItemHandler->xPopupMenuController->updatePopupMenu();
                    bPopupMenu = true;
                    if (PopupMenu*  pThisPopup = pMenu->GetPopupMenu( menuItemHandler->nItemId ))
                        pMenu->EnableItem( menuItemHandler->nItemId, pThisPopup->GetItemCount() != 0 );
                    {
                        pThisPopup->Activate();
                        pThisPopup->Deactivate();
                    }
                }
                lcl_CheckForChildren(pMenu, menuItemHandler->nItemId);

@@ -703,6 +715,11 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
            {
                // Force update of popup menu
                menuItemHandler->xPopupMenuController->updatePopupMenu();
                if (PopupMenu* pThisPopup = pMenu->GetPopupMenu(menuItemHandler->nItemId))
                {
                    pThisPopup->Activate();
                    pThisPopup->Deactivate();
                }
                lcl_CheckForChildren(pMenu, menuItemHandler->nItemId);
            }
            else if ( menuItemHandler->xMenuItemDispatch.is() )
@@ -722,8 +739,16 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
                {
                }
            }
            else if ( menuItemHandler->xSubMenuManager.is() )
            else if (menuItemHandler->xSubMenuManager.is())
            {
                MenuBarManager* pMenuBarManager = static_cast<MenuBarManager*>(menuItemHandler->xSubMenuManager.get());
                if (pMenuBarManager)
                {
                    pMenuBarManager->Activate(pMenuBarManager->GetMenuBar());
                    pMenuBarManager->Deactivate(pMenuBarManager->GetMenuBar());
                }
                lcl_CheckForChildren(pMenu, menuItemHandler->nItemId);
            }
        }
    }

diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index aeedc2c..2442eef 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -252,6 +252,7 @@ public:
    void SetMenuFlags( MenuFlags nFlags ) { nMenuFlags = nFlags; }
    MenuFlags GetMenuFlags() const { return nMenuFlags; }

    bool HasValidEntries(bool bCheckPopups) const;
    sal_uInt16 GetItemCount() const;
    sal_uInt16 GetItemId(sal_uInt16 nPos) const;
    sal_uInt16 GetItemId(std::u16string_view rIdent) const;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 284a54a..b33219c 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -579,6 +579,24 @@ sal_uInt16 Menu::GetItemCount() const
    return static_cast<sal_uInt16>(pItemList->size());
}

bool Menu::HasValidEntries(bool bCheckPopups) const
{
    bool bValidEntries = false;
    sal_uInt16 nCount = GetItemCount();
    for (sal_uInt16 n = 0; !bValidEntries && (n < nCount); n++)
    {
        MenuItemData* pItem = pItemList->GetDataFromPos(n);
        if (pItem->bEnabled && (pItem->eType != MenuItemType::SEPARATOR))
        {
            if (bCheckPopups && pItem->pSubMenu)
                bValidEntries = pItem->pSubMenu->HasValidEntries(true);
            else
                bValidEntries = true;
        }
    }
    return bValidEntries;
}

sal_uInt16 Menu::ImplGetVisibleItemCount() const
{
    sal_uInt16 nItems = 0;