framework/inc/menuconfiguration.hxx                             |    2 
 framework/inc/uielement/menubarmanager.hxx                      |    1 
 framework/source/uielement/menubarmanager.cxx                   |  227 
++--------
 framework/source/uielement/resourcemenucontroller.cxx           |  161 +++++++
 framework/util/fwk.component                                    |    4 
 officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu |   11 
 6 files changed, 230 insertions(+), 176 deletions(-)

New commits:
commit 3a46e402adfd8e0ac1f162de382e03ba92842bcb
Author:     Maxim Monastirsky <momonas...@gmail.com>
AuthorDate: Wed Aug 26 14:00:50 2020 +0300
Commit:     Maxim Monastirsky <momonas...@gmail.com>
CommitDate: Fri Aug 28 00:17:07 2020 +0200

    MenuBarManager: Extract the window list to own controller
    
    Change-Id: Iad3df8cfe0814f510effaac2b7ba6dd926baab7d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101476
    Tested-by: Jenkins
    Reviewed-by: Maxim Monastirsky <momonas...@gmail.com>

diff --git a/framework/inc/menuconfiguration.hxx 
b/framework/inc/menuconfiguration.hxx
index 0c8ae43545bd..84943f5326a6 100644
--- a/framework/inc/menuconfiguration.hxx
+++ b/framework/inc/menuconfiguration.hxx
@@ -29,8 +29,6 @@ namespace com::sun::star::io { class XInputStream; }
 namespace com::sun::star::io { class XOutputStream; }
 namespace com::sun::star::uno { class XComponentContext; }
 
-const sal_uInt16 START_ITEMID_WINDOWLIST    = 4600;
-const sal_uInt16 END_ITEMID_WINDOWLIST      = 4699;
 const sal_uInt16 ITEMID_ADDONLIST           = 6678; // used to be a SID in 
sfx2, now just a unique id...
 
 namespace framework
diff --git a/framework/inc/uielement/menubarmanager.hxx 
b/framework/inc/uielement/menubarmanager.hxx
index 4fa42c8e8fd1..698b46341579 100644
--- a/framework/inc/uielement/menubarmanager.hxx
+++ b/framework/inc/uielement/menubarmanager.hxx
@@ -162,7 +162,6 @@ class MenuBarManager final :
         };
 
         void             RetrieveShortcuts( std::vector< 
std::unique_ptr<MenuItemHandler> >& aMenuShortCuts );
-        static void      UpdateSpecialWindowMenu( Menu* pMenu, const 
css::uno::Reference< css::uno::XComponentContext >& xContext );
         static void      FillMenuImages( css::uno::Reference< 
css::frame::XFrame > const & xFrame, Menu* _pMenu, bool bShowMenuImages );
         static void      impl_RetrieveShortcutsFromConfiguration( const 
css::uno::Reference< css::ui::XAcceleratorConfiguration >& rAccelCfg,
                                                                   const 
css::uno::Sequence< OUString >& rCommands,
diff --git a/framework/source/uielement/menubarmanager.cxx 
b/framework/source/uielement/menubarmanager.cxx
index 5359bc712f53..eb3fe530acce 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -28,7 +28,6 @@
 #include <com/sun/star/frame/XDispatch.hpp>
 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
-#include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/uno/XCurrentContext.hpp>
 #include <com/sun/star/frame/XPopupMenuController.hpp>
@@ -51,10 +50,8 @@
 #include <uno/current_context.hxx>
 #include <unotools/cmdoptions.hxx>
 #include <toolkit/awt/vclxmenu.hxx>
-#include <toolkit/helper/vclunohelper.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/sysdata.hxx>
-#include <vcl/window.hxx>
 #include <vcl/menu.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/commandinfoprovider.hxx>
@@ -615,9 +612,6 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
 
         m_bActive = true;
 
-        if ( m_aMenuItemCommand == aSpecialWindowCommand )
-            UpdateSpecialWindowMenu( pMenu, m_xContext );
-
         // Check if some modes have changed so we have to update our menu 
images
         OUString sIconTheme = SvtMiscOptions().GetIconTheme();
 
@@ -687,64 +681,57 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu, bool )
                     if ( !menuItemHandler->xMenuItemDispatch.is() &&
                          !menuItemHandler->xSubMenuManager.is()      )
                     {
-                        // There is no dispatch mechanism for the special 
window list menu items,
-                        // because they are handled directly through 
XFrame->activate!!!
-                        // Don't update dispatches for special file menu items.
-                        if ( menuItemHandler->nItemId < 
START_ITEMID_WINDOWLIST ||
-                             menuItemHandler->nItemId >= END_ITEMID_WINDOWLIST 
)
-                        {
-                            Reference< XDispatch > xMenuItemDispatch;
+                        Reference< XDispatch > xMenuItemDispatch;
 
-                            aTargetURL.Complete = 
menuItemHandler->aMenuItemURL;
+                        aTargetURL.Complete = menuItemHandler->aMenuItemURL;
 
-                            m_xURLTransformer->parseStrict( aTargetURL );
+                        m_xURLTransformer->parseStrict( aTargetURL );
 
-                            if ( bHasDisabledEntries )
-                            {
-                                if ( aCmdOptions.Lookup( 
SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
-                                    pMenu->HideItem( menuItemHandler->nItemId 
);
-                            }
+                        if ( bHasDisabledEntries )
+                        {
+                            if ( aCmdOptions.Lookup( 
SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
+                                pMenu->HideItem( menuItemHandler->nItemId );
+                        }
 
-                            if ( aTargetURL.Complete.startsWith( 
".uno:StyleApply?" ) )
-                                xMenuItemDispatch = new StyleDispatcher( 
m_xFrame, m_xURLTransformer, aTargetURL );
-                            else if ( m_bIsBookmarkMenu )
-                                xMenuItemDispatch = 
xDispatchProvider->queryDispatch( aTargetURL, menuItemHandler->aTargetFrame, 0 
);
-                            else
-                                xMenuItemDispatch = 
xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+                        if ( aTargetURL.Complete.startsWith( 
".uno:StyleApply?" ) )
+                            xMenuItemDispatch = new StyleDispatcher( m_xFrame, 
m_xURLTransformer, aTargetURL );
+                        else if ( m_bIsBookmarkMenu )
+                            xMenuItemDispatch = 
xDispatchProvider->queryDispatch( aTargetURL, menuItemHandler->aTargetFrame, 0 
);
+                        else
+                            xMenuItemDispatch = 
xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
 
-                            bool bPopupMenu( false );
-                            if ( !menuItemHandler->xPopupMenuController.is() &&
-                                 m_xPopupMenuControllerFactory->hasController( 
menuItemHandler->aMenuItemURL, m_aModuleIdentifier ) )
-                            {
-                                if( xMenuItemDispatch.is() || 
menuItemHandler->aMenuItemURL != ".uno:RecentFileList" )
-                                    bPopupMenu = 
CreatePopupMenuController(menuItemHandler.get());
-                            }
-                            else if ( 
menuItemHandler->xPopupMenuController.is() )
-                            {
-                                // Force update of popup menu
-                                
menuItemHandler->xPopupMenuController->updatePopupMenu();
-                                bPopupMenu = true;
-                                if (PopupMenu*  pThisPopup = 
pMenu->GetPopupMenu( menuItemHandler->nItemId ))
-                                    pMenu->EnableItem( 
menuItemHandler->nItemId, pThisPopup->GetItemCount() != 0 );
-                            }
-                            lcl_CheckForChildren(pMenu, 
menuItemHandler->nItemId);
+                        bool bPopupMenu( false );
+                        if ( !menuItemHandler->xPopupMenuController.is() &&
+                             m_xPopupMenuControllerFactory->hasController( 
menuItemHandler->aMenuItemURL, m_aModuleIdentifier ) )
+                        {
+                            if( xMenuItemDispatch.is() || 
menuItemHandler->aMenuItemURL != ".uno:RecentFileList" )
+                                bPopupMenu = 
CreatePopupMenuController(menuItemHandler.get());
+                        }
+                        else if ( menuItemHandler->xPopupMenuController.is() )
+                        {
+                            // Force update of popup menu
+                            
menuItemHandler->xPopupMenuController->updatePopupMenu();
+                            bPopupMenu = true;
+                            if (PopupMenu*  pThisPopup = pMenu->GetPopupMenu( 
menuItemHandler->nItemId ))
+                                pMenu->EnableItem( menuItemHandler->nItemId, 
pThisPopup->GetItemCount() != 0 );
+                        }
+                        lcl_CheckForChildren(pMenu, menuItemHandler->nItemId);
+
+                        if ( xMenuItemDispatch.is() )
+                        {
+                            menuItemHandler->xMenuItemDispatch = 
xMenuItemDispatch;
+                            menuItemHandler->aParsedItemURL    = 
aTargetURL.Complete;
 
-                            if ( xMenuItemDispatch.is() )
+                            if ( !bPopupMenu )
                             {
-                                menuItemHandler->xMenuItemDispatch = 
xMenuItemDispatch;
-                                menuItemHandler->aParsedItemURL    = 
aTargetURL.Complete;
-
-                                if ( !bPopupMenu )
-                                {
-                                    xMenuItemDispatch->addStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
-                                    // For the menubar, we have to keep status 
listening to support Ubuntu's HUD.
-                                    if ( !m_bHasMenuBar )
-                                        
xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this 
), aTargetURL );
-                                }
+                                xMenuItemDispatch->addStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
+                                // For the menubar, we have to keep status 
listening to support Ubuntu's HUD.
+                                if ( !m_bHasMenuBar )
+                                    xMenuItemDispatch->removeStatusListener( 
static_cast< XStatusListener* >( this ), aTargetURL );
                             }
-                            else if ( !bPopupMenu )
-                                pMenu->EnableItem( menuItemHandler->nItemId, 
false );
                         }
+                        else if ( !bPopupMenu )
+                            pMenu->EnableItem( menuItemHandler->nItemId, false 
);
                     }
                     else if ( menuItemHandler->xPopupMenuController.is() )
                     {
@@ -826,49 +813,21 @@ IMPL_LINK( MenuBarManager, Select, Menu *, pMenu, bool )
         if ( pMenu == m_pVCLMenu &&
              pMenu->GetItemType( nCurPos ) != MenuItemType::SEPARATOR )
         {
-            if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
-                 nCurItemId <= END_ITEMID_WINDOWLIST )
+            MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId 
);
+            if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
             {
-                // window list menu item selected
-
-                Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( 
m_xContext );
+                aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+                m_xURLTransformer->parseStrict( aTargetURL );
 
-                sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
-                Reference< XIndexAccess > xList = xDesktop->getFrames();
-                sal_Int32 nCount = xList->getCount();
-                for ( sal_Int32 i=0; i<nCount; ++i )
+                if ( m_bIsBookmarkMenu )
                 {
-                    Reference< XFrame > xFrame;
-                    xList->getByIndex(i) >>= xFrame;
-                    if ( xFrame.is() && nTaskId == nCurItemId )
-                    {
-                        VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( 
xFrame->getContainerWindow() );
-                        pWin->GrabFocus();
-                        pWin->ToTop( ToTopFlags::RestoreWhenMin );
-                        break;
-                    }
-
-                    nTaskId++;
+                    // bookmark menu item selected
+                    aArgs.realloc( 1 );
+                    aArgs[0].Name = "Referer";
+                    aArgs[0].Value <<= OUString( "private:user" );
                 }
-            }
-            else
-            {
-                MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( 
nCurItemId );
-                if ( pMenuItemHandler && 
pMenuItemHandler->xMenuItemDispatch.is() )
-                {
-                    aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
-                    m_xURLTransformer->parseStrict( aTargetURL );
 
-                    if ( m_bIsBookmarkMenu )
-                    {
-                        // bookmark menu item selected
-                        aArgs.realloc( 1 );
-                        aArgs[0].Name = "Referer";
-                        aArgs[0].Value <<= OUString( "private:user" );
-                    }
-
-                    xDispatch = pMenuItemHandler->xMenuItemDispatch;
-                }
+                xDispatch = pMenuItemHandler->xMenuItemDispatch;
             }
         }
     }
@@ -1058,23 +1017,19 @@ void MenuBarManager::FillMenuManager( Menu* pMenu, 
const Reference< XFrame >& rF
             }
 
             if ( m_xPopupMenuControllerFactory.is() &&
-                 pPopup->GetItemCount() == 0 &&
                  m_xPopupMenuControllerFactory->hasController( aItemCommand, 
m_aModuleIdentifier )
                   )
             {
                 // Check if we have to create a popup menu for a uno based 
popup menu controller.
                 // We have to set an empty popup menu into our menu structure 
so the controller also
-                // works with inplace OLE. Remove old dummy popup menu!
+                // works with inplace OLE.
                 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, 
xStatusListener, xDispatch );
-                VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
-                PopupMenu* pNewPopupMenu = static_cast<PopupMenu 
*>(pVCLXPopupMenu->GetMenu());
-                pMenu->SetPopupMenu( nItemId, pNewPopupMenu );
+                VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu(pPopup);
                 pItemHandler->xPopupMenu = pVCLXPopupMenu;
                 pItemHandler->aMenuItemURL = aItemCommand;
                 m_aMenuItemHandlerVector.push_back( 
std::unique_ptr<MenuItemHandler>(pItemHandler) );
-                pPopup.disposeAndClear();
 
-                if ( bAccessibilityEnabled )
+                if ( bAccessibilityEnabled || pMenu->IsMenuBar())
                 {
                     if ( CreatePopupMenuController( pItemHandler ))
                         pItemHandler->xPopupMenuController->updatePopupMenu();
@@ -1761,78 +1716,6 @@ void MenuBarManager::SetHdl()
         m_xURLTransformer.set( URLTransformer::create( m_xContext) );
 }
 
-void MenuBarManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< 
XComponentContext >& xContext )
-{
-    // update window list
-    ::std::vector< OUString > aNewWindowListVector;
-
-    Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
-
-    sal_uInt16  nActiveItemId = 0;
-    sal_uInt16  nItemId = START_ITEMID_WINDOWLIST;
-
-    Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
-    Reference< XIndexAccess > xList = xDesktop->getFrames();
-    sal_Int32 nFrameCount = xList->getCount();
-    aNewWindowListVector.reserve(nFrameCount);
-    for (sal_Int32 i=0; i<nFrameCount; ++i )
-    {
-        Reference< XFrame > xFrame;
-        xList->getByIndex(i) >>= xFrame;
-
-        if (xFrame.is())
-        {
-            if ( xFrame == xCurrentFrame )
-                nActiveItemId = nItemId;
-
-            VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( 
xFrame->getContainerWindow() );
-            OUString sWindowTitle;
-            if ( pWin && pWin->IsVisible() )
-                sWindowTitle = pWin->GetText();
-
-            // tdf#101658 In case the frame is embedded somewhere, LO has no 
control over it.
-            // So we just skip it.
-            if ( sWindowTitle.isEmpty() )
-                continue;
-
-            aNewWindowListVector.push_back( sWindowTitle );
-            ++nItemId;
-        }
-    }
-
-    {
-        SolarMutexGuard g;
-
-        int nItemCount = pMenu->GetItemCount();
-
-        if ( nItemCount > 0 )
-        {
-            // remove all old window list entries from menu
-            sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
-            for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
-                pMenu->RemoveItem( n );
-
-            if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == 
MenuItemType::SEPARATOR )
-                pMenu->RemoveItem( pMenu->GetItemCount()-1 );
-        }
-
-        if ( !aNewWindowListVector.empty() )
-        {
-            // append new window list entries to menu
-            pMenu->InsertSeparator();
-            nItemId = START_ITEMID_WINDOWLIST;
-            const sal_uInt32 nCount = aNewWindowListVector.size();
-            for ( sal_uInt32 i = 0; i < nCount; i++ )
-            {
-                pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), 
MenuItemBits::RADIOCHECK );
-                if ( nItemId == nActiveItemId )
-                    pMenu->CheckItem( nItemId );
-                ++nItemId;
-            }
-        }
-    }
-}
-
 void MenuBarManager::FillMenuImages(Reference< XFrame > const & _xFrame, Menu* 
_pMenu,bool bShowMenuImages)
 {
     AddonsOptions aAddonOptions;
diff --git a/framework/source/uielement/resourcemenucontroller.cxx 
b/framework/source/uielement/resourcemenucontroller.cxx
index ea2ff5b6dbf0..6b10e152909b 100644
--- a/framework/source/uielement/resourcemenucontroller.cxx
+++ b/framework/source/uielement/resourcemenucontroller.cxx
@@ -5,6 +5,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
 #include <uielement/menubarmanager.hxx>
@@ -12,11 +22,14 @@
 #include <cppuhelper/implbase.hxx>
 #include <svtools/popupmenucontrollerbase.hxx>
 #include <toolkit/awt/vclxmenu.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
 #include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
 #include <sal/log.hxx>
 
 #include <com/sun/star/embed/VerbAttributes.hpp>
 #include <com/sun/star/embed/VerbDescriptor.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/frame/ModuleManager.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
@@ -61,10 +74,12 @@ private:
     sal_uInt16 m_nNewMenuId;
     rtl::Reference< framework::MenuBarManager > m_xMenuBarManager;
     css::uno::Reference< css::container::XIndexAccess > m_xMenuContainer;
-    css::uno::Reference< css::uno::XComponentContext > m_xContext;
     css::uno::Reference< css::ui::XUIConfigurationManager > m_xConfigManager, 
m_xModuleConfigManager;
     void addVerbs( const css::uno::Sequence< css::embed::VerbDescriptor >& 
rVerbs );
     virtual void SAL_CALL disposing() override;
+
+protected:
+    css::uno::Reference< css::uno::XComponentContext > m_xContext;
 };
 
 ResourceMenuController::ResourceMenuController( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext,
@@ -386,6 +401,142 @@ OUString SaveAsMenuController::getImplementationName()
     return "com.sun.star.comp.framework.SaveAsMenuController";
 }
 
+class WindowListMenuController : public ResourceMenuController
+{
+public:
+    using ResourceMenuController::ResourceMenuController;
+
+    // XMenuListener
+    void SAL_CALL itemActivated( const css::awt::MenuEvent& rEvent ) override;
+    void SAL_CALL itemSelected( const css::awt::MenuEvent& rEvent ) override;
+
+    // XServiceInfo
+    OUString SAL_CALL getImplementationName() override;
+
+private:
+    void impl_setPopupMenu() override;
+};
+
+constexpr sal_uInt16 START_ITEMID_WINDOWLIST    = 4600;
+constexpr sal_uInt16 END_ITEMID_WINDOWLIST      = 4699;
+
+void WindowListMenuController::itemActivated( const css::awt::MenuEvent& 
rEvent )
+{
+    ResourceMenuController::itemActivated( rEvent );
+
+    // update window list
+    ::std::vector< OUString > aNewWindowListVector;
+
+    css::uno::Reference< css::frame::XDesktop2 > xDesktop = 
css::frame::Desktop::create( m_xContext );
+
+    sal_uInt16  nActiveItemId = 0;
+    sal_uInt16  nItemId = START_ITEMID_WINDOWLIST;
+
+    css::uno::Reference< css::frame::XFrame > xCurrentFrame = 
xDesktop->getCurrentFrame();
+    css::uno::Reference< css::container::XIndexAccess > xList = 
xDesktop->getFrames();
+    sal_Int32 nFrameCount = xList->getCount();
+    aNewWindowListVector.reserve(nFrameCount);
+    for (sal_Int32 i=0; i<nFrameCount; ++i )
+    {
+        css::uno::Reference< css::frame::XFrame > xFrame;
+        xList->getByIndex(i) >>= xFrame;
+
+        if (xFrame.is())
+        {
+            if ( xFrame == xCurrentFrame )
+                nActiveItemId = nItemId;
+
+            VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( 
xFrame->getContainerWindow() );
+            OUString sWindowTitle;
+            if ( pWin && pWin->IsVisible() )
+                sWindowTitle = pWin->GetText();
+
+            // tdf#101658 In case the frame is embedded somewhere, LO has no 
control over it.
+            // So we just skip it.
+            if ( sWindowTitle.isEmpty() )
+                continue;
+
+            aNewWindowListVector.push_back( sWindowTitle );
+            ++nItemId;
+        }
+    }
+
+    {
+        SolarMutexGuard g;
+
+        VCLXMenu* pAwtMenu = comphelper::getUnoTunnelImplementation<VCLXMenu>( 
m_xPopupMenu );
+        Menu* pVCLMenu = pAwtMenu->GetMenu();
+        int nItemCount = pVCLMenu->GetItemCount();
+
+        if ( nItemCount > 0 )
+        {
+            // remove all old window list entries from menu
+            sal_uInt16 nPos = pVCLMenu->GetItemPos( START_ITEMID_WINDOWLIST );
+            for ( sal_uInt16 n = nPos; n < pVCLMenu->GetItemCount(); )
+                pVCLMenu->RemoveItem( n );
+
+            if ( pVCLMenu->GetItemType( pVCLMenu->GetItemCount()-1 ) == 
MenuItemType::SEPARATOR )
+                pVCLMenu->RemoveItem( pVCLMenu->GetItemCount()-1 );
+        }
+
+        if ( !aNewWindowListVector.empty() )
+        {
+            // append new window list entries to menu
+            pVCLMenu->InsertSeparator();
+            nItemId = START_ITEMID_WINDOWLIST;
+            const sal_uInt32 nCount = aNewWindowListVector.size();
+            for ( sal_uInt32 i = 0; i < nCount; i++ )
+            {
+                pVCLMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), 
MenuItemBits::RADIOCHECK );
+                if ( nItemId == nActiveItemId )
+                    pVCLMenu->CheckItem( nItemId );
+                ++nItemId;
+            }
+        }
+    }
+}
+
+void WindowListMenuController::itemSelected( const css::awt::MenuEvent& rEvent 
)
+{
+    if ( rEvent.MenuId >= START_ITEMID_WINDOWLIST &&
+         rEvent.MenuId <= END_ITEMID_WINDOWLIST )
+    {
+        // window list menu item selected
+        css::uno::Reference< css::frame::XDesktop2 > xDesktop = 
css::frame::Desktop::create( m_xContext );
+
+        sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
+        css::uno::Reference< css::container::XIndexAccess > xList = 
xDesktop->getFrames();
+        sal_Int32 nCount = xList->getCount();
+        for ( sal_Int32 i=0; i<nCount; ++i )
+        {
+            css::uno::Reference< css::frame::XFrame > xFrame;
+            xList->getByIndex(i) >>= xFrame;
+            if ( xFrame.is() && nTaskId == rEvent.MenuId )
+            {
+                VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( 
xFrame->getContainerWindow() );
+                pWin->GrabFocus();
+                pWin->ToTop( ToTopFlags::RestoreWhenMin );
+                break;
+            }
+
+            nTaskId++;
+        }
+    }
+}
+
+void WindowListMenuController::impl_setPopupMenu()
+{
+    // Make this controller work also with initially empty
+    // menu, which PopupMenu::ImplExecute doesn't allow.
+    if (m_xPopupMenu.is() && !m_xPopupMenu->getItemCount())
+        m_xPopupMenu->insertSeparator(0);
+}
+
+OUString WindowListMenuController::getImplementationName()
+{
+    return "com.sun.star.comp.framework.WindowListMenuController";
+}
+
 }
 
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
@@ -404,6 +555,14 @@ 
com_sun_star_comp_framework_ToolbarAsMenuController_get_implementation(
     return cppu::acquire( new ResourceMenuController( context, args, true ) );
 }
 
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_WindowListMenuController_get_implementation(
+    css::uno::XComponentContext* context,
+    css::uno::Sequence< css::uno::Any > const & args )
+{
+    return cppu::acquire( new WindowListMenuController( context, args, false ) 
);
+}
+
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
 com_sun_star_comp_framework_SaveAsMenuController_get_implementation(
     css::uno::XComponentContext* context,
diff --git a/framework/util/fwk.component b/framework/util/fwk.component
index 79538a58e8e4..e056e8a9aeb6 100644
--- a/framework/util/fwk.component
+++ b/framework/util/fwk.component
@@ -121,6 +121,10 @@
       
constructor="com_sun_star_comp_framework_SaveAsMenuController_get_implementation">
     <service name="com.sun.star.frame.PopupMenuController"/>
   </implementation>
+  <implementation name="com.sun.star.comp.framework.WindowListMenuController"
+      
constructor="com_sun_star_comp_framework_WindowListMenuController_get_implementation">
+    <service name="com.sun.star.frame.PopupMenuController"/>
+  </implementation>
   <implementation name="com.sun.star.comp.framework.StatusBarControllerFactory"
       
constructor="com_sun_star_comp_framework_StatusBarControllerFactory_get_implementation">
     <service name="com.sun.star.frame.StatusbarControllerFactory"/>
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index c18e2d1fb44a..01e6172a80c6 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -509,6 +509,17 @@
           <value>3dobjectsbar</value>
         </prop>
       </node>
+      <node oor:name="WindowListMenu" oor:op="replace">
+        <prop oor:name="Command">
+          <value>.uno:WindowList</value>
+        </prop>
+        <prop oor:name="Module">
+          <value/>
+        </prop>
+        <prop oor:name="Controller">
+          <value>com.sun.star.comp.framework.WindowListMenuController</value>
+        </prop>
+      </node>
     </node>
     <node oor:name="ToolBar">
       <node oor:name="lo.writer.ScrollToPrevious" oor:op="replace">
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to