Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  toolbarmanager.cxx   Sprache: C

 
/*
 * This file is part of the LibreOffice project.
 *
 * 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 <sal/config.h>
#include <sal/log.hxx>

#include <cassert>

#include <uielement/toolbarmanager.hxx>

#include <framework/generictoolbarcontroller.hxx>
#include <officecfg/Office/Common.hxx>
#include <uielement/styletoolbarcontroller.hxx>
#include <properties.h>
#include <framework/sfxhelperfunctions.hxx>
#include <classes/fwkresid.hxx>
#include <classes/resource.hxx>
#include <strings.hrc>
#include <uielement/toolbarmerger.hxx>

#include <com/sun/star/ui/ItemType.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/XDockableWindow.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/ui/DockingArea.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <com/sun/star/frame/theToolbarControllerFactory.hpp>
#include <com/sun/star/ui/ItemStyle.hpp>
#include <com/sun/star/ui/XUIElementSettings.hpp>
#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/ImageType.hpp>
#include <com/sun/star/ui/UIElementType.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/util/URLTransformer.hpp>

#include <svtools/toolboxcontroller.hxx>
#include <unotools/cmdoptions.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <unotools/mediadescriptor.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/propertysequence.hxx>
#include <svtools/miscopt.hxx>
#include <svtools/imgdef.hxx>
#include <utility>
#include <vcl/event.hxx>
#include <vcl/graph.hxx>
#include <vcl/svapp.hxx>
#include <vcl/menu.hxx>
#include <vcl/syswin.hxx>
#include <vcl/taskpanelist.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/settings.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/weldutils.hxx>
#include <tools/debug.hxx>

//  namespaces

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::graphic;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::ui;
using namespace ::com::sun::star;

namespace framework
{

const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
const char ITEM_DESCRIPTOR_VISIBLE[]    = "IsVisible";

const sal_uInt16 STARTID_CUSTOMIZE_POPUPMENU = 1000;

static css::uno::Reference< css::frame::XLayoutManager > getLayoutManagerFromFrame(
    css::uno::Reference< css::frame::XFrame > const & rFrame )
{
    css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;

    Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
    if ( xPropSet.is() )
    {
        try
        {
            xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xLayoutManager;
        }
        catch (const RuntimeException&)
        {
            throw;
        }
        catch (const Exception&)
        {
        }
    }

    return xLayoutManager;
}
namespace
{

sal_Int16 getCurrentImageType()
{
    sal_Int16 nImageType = css::ui::ImageType::SIZE_DEFAULT;
    sal_Int16 nCurrentSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();
    if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
        nImageType |= css::ui::ImageType::SIZE_LARGE;
    else if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_32)
        nImageType |= css::ui::ImageType::SIZE_32;
    return nImageType;
}

class VclToolBarManager : public ToolBarManagerImpl
{
    DECL_LINK(Click, ToolBox*, void);

public:
    VclToolBarManager(VclPtr<ToolBox> pToolbar)
    : m_pToolBar(std::move(pToolbar))
    , m_bAddedToTaskPaneList(true)
    , m_pManager(nullptr)
    {}

    ~VclToolBarManager()
    {
        OSL_ASSERT( !m_bAddedToTaskPaneList );
    }

    virtual void Init() override
    {
        vcl::Window* pWindow = m_pToolBar;
        while ( pWindow && !pWindow->IsSystemWindow() )
            pWindow = pWindow->GetParent();

        if ( pWindow )
            static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
    }

    virtual void Destroy() override
    {
        OSL_ASSERT( m_pToolBar != nullptr );
        SolarMutexGuard g;
        if ( m_bAddedToTaskPaneList )
        {
            vcl::Window* pWindow = m_pToolBar;
            while ( pWindow && !pWindow->IsSystemWindow() )
                pWindow = pWindow->GetParent();

            if ( pWindow )
                static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
            m_bAddedToTaskPaneList = false;
        }

        // Delete the additional add-ons data
        for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
        {
            ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
            if ( nItemId > ToolBoxItemId(0) )
                delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
        }

        // #i93173# note we can still be in one of the toolbar's handlers
        m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetClickHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetDropdownClickHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetDoubleClickHdl( Link<ToolBox *, void>() );
        m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
        m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );

        m_pToolBar.disposeAndClear();
    }

    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
    {
        return VCLUnoHelper::GetInterface(m_pToolBar);
    }

    virtual void ConnectCallbacks(ToolBarManager* pManager) override
    {
        m_pManager = pManager;
        m_pToolBar->SetSelectHdl( LINK( pManager, ToolBarManager, Select) );
        m_pToolBar->SetClickHdl( LINK( this, VclToolBarManager, Click ) );
        m_pToolBar->SetDropdownClickHdl( LINK( pManager, ToolBarManager, DropdownClick ) );
        m_pToolBar->SetDoubleClickHdl( LINK( pManager, ToolBarManager, DoubleClick ) );
        m_pToolBar->SetStateChangedHdl( LINK( pManager, ToolBarManager, StateChanged ) );
        m_pToolBar->SetDataChangedHdl( LINK( pManager, ToolBarManager, DataChanged ) );

        m_pToolBar->SetMenuButtonHdl( LINK( pManager, ToolBarManager, MenuButton ) );
        m_pToolBar->SetMenuExecuteHdl( LINK( pManager, ToolBarManager, MenuPreExecute ) );
        m_pToolBar->GetMenu()->SetSelectHdl( LINK( pManager, ToolBarManager, MenuSelect ) );
    }

    virtual void InsertItem(ToolBoxItemId nId,
                            const OUString& rCommandURL,
                            const OUString& rTooltip,
                            const OUString& rLabel,
                            ToolBoxItemBits nItemBits) override
    {
        m_pToolBar->InsertItem( nId, rLabel, rCommandURL, nItemBits );
        m_pToolBar->SetQuickHelpText(nId, rTooltip);
        m_pToolBar->EnableItem( nId );
        m_pToolBar->SetItemState( nId, TRISTATE_FALSE );
    }

    virtual void InsertSeparator() override
    {
        m_pToolBar->InsertSeparator();
    }

    virtual void InsertSpace() override
    {
        m_pToolBar->InsertSpace();
    }

    virtual void InsertBreak() override
    {
        m_pToolBar->InsertBreak();
    }

    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
    {
        return m_pToolBar->GetItemId(nPos);
    }

    virtual ToolBoxItemId GetCurItemId() override
    {
        return m_pToolBar->GetCurItemId();
    }

    virtual OUString GetItemCommand(ToolBoxItemId nId) override
    {
        return m_pToolBar->GetItemCommand(nId);
    }

    virtual sal_uInt16 GetItemCount() override
    {
        return m_pToolBar->GetItemCount();
    }

    virtual void SetItemCheckable(ToolBoxItemId nId) override
    {
        m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
    }

    virtual void HideItem(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
    {
        m_pToolBar->HideItem( nId );
    }

    virtual bool IsItemVisible(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
    {
        return m_pToolBar->IsItemVisible(nId);
    }

    virtual void Clear() override
    {
        m_pToolBar->Clear();
    }

    virtual void SetName(const OUString& rName) override
    {
        m_pToolBar->SetText( rName );
    }

    virtual void SetHelpId(const OUString& rHelpId) override
    {
        m_pToolBar->SetHelpId( rHelpId );
    }

    virtual bool WillUsePopupMode() override
    {
        return m_pToolBar->WillUsePopupMode();
    }

    virtual bool IsReallyVisible() override
    {
        return m_pToolBar->IsReallyVisible();
    }

    virtual void SetIconSize(ToolBoxButtonSize eSize) override
    {
        m_pToolBar->SetToolboxButtonSize(eSize);
    }

    virtual vcl::ImageType GetImageSize() override
    {
        return m_pToolBar->GetImageSize();
    }

    virtual void SetMenuType(ToolBoxMenuType eType) override
    {
        m_pToolBar->SetMenuType( eType );
    }

    virtual void MergeToolbar(ToolBoxItemId & rItemId, sal_uInt16 nFirstItem,
                              const OUString& rModuleIdentifier,
                              CommandToInfoMap& rCommandMap,
                              MergeToolbarInstruction& rInstruction) override
    {
        ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, nFirstItem, rInstruction.aMergePoint );

        // convert the sequence< sequence< propertyvalue > > structure to
        // something we can better handle. A vector with item data
        AddonToolbarItemContainer aItems;
        ToolBarMerger::ConvertSeqSeqToVector( rInstruction.aMergeToolbarItems, aItems );

        if ( aRefPoint.bResult )
        {
            ToolBarMerger::ProcessMergeOperation( m_pToolBar,
                                                    aRefPoint.nPos,
                                                    rItemId,
                                                    rCommandMap,
                                                    rModuleIdentifier,
                                                    rInstruction.aMergeCommand,
                                                    rInstruction.aMergeCommandParameter,
                                                    aItems );
        }
        else
        {
            ToolBarMerger::ProcessMergeFallback( m_pToolBar,
                                                    rItemId,
                                                    rCommandMap,
                                                    rModuleIdentifier,
                                                    rInstruction.aMergeCommand,
                                                    rInstruction.aMergeFallback,
                                                    aItems );
        }
    }

    virtual void SetItemImage(ToolBoxItemId nId,
                              const OUString& /*rCommandURL*/,
                              const Image& rImage) override
    {
        m_pToolBar->SetItemImage(nId, rImage);
    }

    virtual void UpdateSize() override
    {
        ::Size aSize = m_pToolBar->CalcWindowSizePixel();
        m_pToolBar->SetOutputSizePixel( aSize );
    }

    virtual void SetItemWindow(ToolBoxItemId nItemId, vcl::Window* pNewWindow) override
    {
        m_pToolBar->SetItemWindow( nItemId, pNewWindow );
    }

private:
    VclPtr<ToolBox> m_pToolBar;
    bool m_bAddedToTaskPaneList;
    ToolBarManager* m_pManager;
};

IMPL_LINK_NOARG(VclToolBarManager, Click, ToolBox*, void)
{
    m_pManager->OnClick();
}

class WeldToolBarManager : public ToolBarManagerImpl
{
    DECL_LINK(Click, const OUString&, void);
    DECL_LINK(ToggleMenuHdl, const OUString&, void);

public:
    WeldToolBarManager(weld::Toolbar* pToolbar,
                       weld::Builder* pBuilder)
    : m_pWeldedToolBar(pToolbar)
    , m_pBuilder(pBuilder)
    , m_pManager(nullptr)
    , m_nCurrentId(0)
    {}

    virtual void Init() override {}

    virtual void Destroy() override {}

    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
    {
        return new weld::TransportAsXWindow(m_pWeldedToolBar, m_pBuilder);
    }

    virtual void ConnectCallbacks(ToolBarManager* pManager) override
    {
        m_pManager = pManager;
        m_pWeldedToolBar->connect_clicked(LINK(this, WeldToolBarManager, Click));
        m_pWeldedToolBar->connect_menu_toggled(LINK(this, WeldToolBarManager, ToggleMenuHdl));
    }

    virtual void InsertItem(ToolBoxItemId nId,
                            const OUString& rCommandURL,
                            const OUString& rTooltip,
                            const OUString& rLabel,
                            ToolBoxItemBits /*nItemBits*/) override
    {
        m_aCommandToId[rCommandURL] = nId;
        m_aIdToCommand[nId] = rCommandURL;
        m_aCommandOrder.push_back(rCommandURL);

        m_pWeldedToolBar->insert_item(m_aCommandOrder.size(), rCommandURL);
        m_pWeldedToolBar->set_item_tooltip_text(rCommandURL, rTooltip);
        m_pWeldedToolBar->set_item_label(rCommandURL, rLabel);
        m_pWeldedToolBar->set_item_sensitive(rCommandURL, true);
        m_pWeldedToolBar->set_item_active(rCommandURL, false);
    }

    virtual void InsertSeparator() override
    {
        m_pWeldedToolBar->append_separator(u""_ustr);
    }

    virtual void InsertSpace() override {}

    virtual void InsertBreak() override {}

    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
    {
        return m_aCommandToId[m_aCommandOrder[nPos]];
    }

    virtual ToolBoxItemId GetCurItemId() override
    {
        return m_nCurrentId;
    }

    virtual OUString GetItemCommand(ToolBoxItemId nId) override
    {
        return m_aIdToCommand[nId];
    }

    virtual sal_uInt16 GetItemCount() override
    {
        return m_aCommandOrder.size();
    }

    virtual void SetItemCheckable(ToolBoxItemId /*nId*/) override {}

    virtual void HideItem(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
    {
        m_pWeldedToolBar->set_item_visible(rCommandURL, false);
    }

    virtual bool IsItemVisible(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
    {
        return m_pWeldedToolBar->get_item_visible(rCommandURL);
    }

    virtual void Clear() override {}

    virtual void SetName(const OUString& /*rName*/) override {}

    virtual void SetHelpId(const OUString& /*rHelpId*/) override {}

    virtual bool WillUsePopupMode() override { return true; }

    virtual bool IsReallyVisible() override { return true; }

    virtual void SetIconSize(ToolBoxButtonSize /*eSize*/) override {}

    virtual vcl::ImageType GetImageSize() override
    {
        return vcl::ImageType::Size32;
    }

    virtual void SetMenuType(ToolBoxMenuType /*eType*/) override {}

    virtual void MergeToolbar(ToolBoxItemId & /*rItemId*/,
                              sal_uInt16 /*nFirstItem*/,
                              const OUString& /*rModuleIdentifier*/,
                              CommandToInfoMap& /*rCommandMap*/,
                              MergeToolbarInstruction& /*rInstruction*/) override {}

    virtual void SetItemImage(ToolBoxItemId /*nId*/,
                              const OUString& rCommandURL,
                              const Image& rImage) override
    {
        m_pWeldedToolBar->set_item_image(rCommandURL, Graphic(rImage).GetXGraphic());
    }

    virtual void UpdateSize() override {}

    virtual void SetItemWindow(ToolBoxItemId /*nItemId*/, vcl::Window* /*pNewWindow*/) override {}

private:
    weld::Toolbar* m_pWeldedToolBar;
    weld::Builder* m_pBuilder;
    ToolBarManager* m_pManager;
    ToolBoxItemId m_nCurrentId;
    std::map<const OUString, ToolBoxItemId> m_aCommandToId;
    std::map<ToolBoxItemId, OUString> m_aIdToCommand;
    std::vector<OUString> m_aCommandOrder;
};

IMPL_LINK(WeldToolBarManager, Click, const OUString&, rCommand, void)
{
    m_nCurrentId = m_aCommandToId[rCommand];
    m_pManager->OnClick(true);
}

IMPL_LINK(WeldToolBarManager, ToggleMenuHdl, const OUString&, rCommand, void)
{
    m_nCurrentId = m_aCommandToId[rCommand];
    m_pManager->OnDropdownClick(false);
}

// end anonymous namespace

//  XInterface, XTypeProvider, XServiceInfo

ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
                                const Reference< XFrame >& rFrame,
                                OUString aResourceName,
                                ToolBox* pToolBar ) :
    m_bDisposed( false ),
    m_bFrameActionRegistered( false ),
    m_bUpdateControllers( false ),
    m_eSymbolSize(SvtMiscOptions::GetCurrentSymbolsSize()),
    m_nContextMinPos(0),
    m_pImpl( new VclToolBarManager( pToolBar ) ),
    m_pToolBar( pToolBar ),
    m_pWeldedToolBar( nullptr ),
    m_aResourceName(std::move( aResourceName )),
    m_xFrame( rFrame ),
    m_xContext( rxContext ),
    m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
    m_sIconTheme( SvtMiscOptions::GetIconTheme() )
{
    Init();
}

ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
                                const Reference< XFrame >& rFrame,
                                OUString aResourceName,
                                weld::Toolbar* pToolBar,
                                weld::Builder* pBuilder ) :
    m_bDisposed( false ),
    m_bFrameActionRegistered( false ),
    m_bUpdateControllers( false ),
    m_eSymbolSize( SvtMiscOptions::GetCurrentSymbolsSize() ),
    m_nContextMinPos(0),
    m_pImpl( new WeldToolBarManager( pToolBar, pBuilder ) ),
    m_pWeldedToolBar( pToolBar ),
    m_aResourceName(std::move( aResourceName )),
    m_xFrame( rFrame ),
    m_xContext( rxContext ),
    m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
    m_sIconTheme( SvtMiscOptions::GetIconTheme() )
{
    Init();
}

void ToolBarManager::Init()
{
    OSL_ASSERT( m_xContext.is() );

    m_pImpl->Init();

    m_xToolbarControllerFactory = frame::theToolbarControllerFactory::get( m_xContext );
    m_xURLTransformer = URLTransformer::create( m_xContext );

    m_pImpl->ConnectCallbacks(this);

    if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
    else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
    else
        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);

    // enables a menu for clipped items and customization
    SvtCommandOptions aCmdOptions;
    ToolBoxMenuType nMenuType = ToolBoxMenuType::ClippedItems;
    if ( !aCmdOptions.LookupDisabled( u"CreateDialog"_ustr))
         nMenuType |= ToolBoxMenuType::Customize;

    m_pImpl->SetMenuType( nMenuType );

    // set name for testtool, the useful part is after the last '/'
    sal_Int32 idx = m_aResourceName.lastIndexOf('/');
    idx++; // will become 0 if '/' not found: use full string
    std::u16string_view aToolbarName = m_aResourceName.subView( idx );
    OUString aHelpIdAsString = ".HelpId:" + OUString::Concat(aToolbarName);
    m_pImpl->SetHelpId( aHelpIdAsString );

    m_aAsyncUpdateControllersTimer.SetTimeout( 50 );
    m_aAsyncUpdateControllersTimer.SetInvokeHandler( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) );

    SvtMiscOptions().AddListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
}

ToolBarManager::~ToolBarManager()
{
    assert(!m_aAsyncUpdateControllersTimer.IsActive());
    assert(!m_pToolBar); // must be disposed by ToolbarLayoutManager
}

void ToolBarManager::Destroy()
{
    m_pImpl->Destroy();

    SvtMiscOptions().RemoveListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
}

ToolBox* ToolBarManager::GetToolBar() const
{
    SolarMutexGuard g;
    return m_pToolBar;
}

void ToolBarManager::CheckAndUpdateImages()
{
    SolarMutexGuard g;
    bool bRefreshImages = false;

    sal_Int16 eNewSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();

    if (m_eSymbolSize != eNewSymbolSize )
    {
        bRefreshImages = true;
        m_eSymbolSize = eNewSymbolSize;
    }

    const OUString sCurrentIconTheme = SvtMiscOptions::GetIconTheme();
    if ( m_sIconTheme != sCurrentIconTheme )
    {
        bRefreshImages = true;
        m_sIconTheme = sCurrentIconTheme;
    }

    // Refresh images if requested
    if ( bRefreshImages )
        RefreshImages();
}

void ToolBarManager::RefreshImages()
{
    SolarMutexGuard g;

    if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
    else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
    else
        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);

    for ( auto const& it : m_aControllerMap )
    {
        Reference< XSubToolbarController > xController( it.second, UNO_QUERY );
        if ( xController.is() && xController->opensSubToolbar() )
        {
            // The button should show the last function that was selected from the
            // dropdown. The controller should know better than us what it was.
            xController->updateImage();
        }
        else
        {
            OUString aCommandURL = m_pImpl->GetItemCommand( it.first );
            vcl::ImageType eImageType = m_pImpl->GetImageSize();
            Image aImage = vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame, eImageType);
            // Try also to query for add-on images before giving up and use an
            // empty image.
            bool bBigImages = eImageType != vcl::ImageType::Size16;
            if ( !aImage )
                aImage = Image(framework::AddonsOptions().GetImageFromURL(aCommandURL, bBigImages));
            m_pImpl->SetItemImage( it.first, aCommandURL, aImage );
        }
    }

    m_pImpl->UpdateSize();
}

void ToolBarManager::UpdateControllers()
{

    if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
    {
        Any a;
        Reference< XLayoutManager > xLayoutManager;
        Reference< XPropertySet > xFramePropSet( m_xFrame, UNO_QUERY );
        if ( xFramePropSet.is() )
            a = xFramePropSet->getPropertyValue(u"LayoutManager"_ustr);
        a >>= xLayoutManager;
        Reference< XDockableWindow > xDockable( m_pImpl->GetInterface(), UNO_QUERY );
        if ( xLayoutManager.is() && xDockable.is() )
        {
            css::awt::Point aPoint;
            aPoint.X = aPoint.Y = SAL_MAX_INT32;
            xLayoutManager->dockWindow( m_aResourceName, DockingArea_DOCKINGAREA_DEFAULT, aPoint );
            xLayoutManager->lockWindow( m_aResourceName );
        }
    }

    if ( !m_bUpdateControllers )
    {
        m_bUpdateControllers = true;
        for (auto const& controller : m_aControllerMap)
        {
            try
            {
                Reference< XUpdatable > xUpdatable( controller.second, UNO_QUERY );
                if ( xUpdatable.is() )
                    xUpdatable->update();
            }
            catch (const Exception&)
            {
            }
        }
    }
    m_bUpdateControllers = false;
}

//for update toolbar controller via Support Visible
void ToolBarManager::UpdateController( const css::uno::Reference< css::frame::XToolbarController >& xController)
{

    if ( !m_bUpdateControllers )
    {
        m_bUpdateControllers = true;
        try
        {   if(xController.is())
            {
                Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
                if ( xUpdatable.is() )
                    xUpdatable->update();
            }
         }
         catch (const Exception&)
         {
         }

    }
    m_bUpdateControllers = false;
}

void ToolBarManager::frameAction( const FrameActionEvent& Action )
{
    SolarMutexGuard g;
    if ( Action.Action == FrameAction_CONTEXT_CHANGED && !m_bDisposed )
    {
        if (m_aImageController)
            m_aImageController->update();
        m_aAsyncUpdateControllersTimer.Start();
    }
}

void SAL_CALL ToolBarManager::disposing( const EventObject& Source )
{
    SolarMutexGuard g;

    if ( m_bDisposed )
        return;

    RemoveControllers();

    if ( m_xDocImageManager.is() )
    {
        try
        {
            m_xDocImageManager->removeConfigurationListener(
                Reference< XUIConfigurationListener >(this) );
        }
        catch (const Exception&)
        {
        }
    }

    if ( m_xModuleImageManager.is() )
    {
        try
        {
            m_xModuleImageManager->removeConfigurationListener(
                Reference< XUIConfigurationListener >(this) );
        }
        catch (const Exception&)
        {
        }
    }

    m_xDocImageManager.clear();
    m_xModuleImageManager.clear();

    if ( Source.Source == Reference< XInterface >( m_xFrame, UNO_QUERY ))
        m_xFrame.clear();

    m_xContext.clear();
}

// XComponent
void SAL_CALL ToolBarManager::dispose()
{
    Reference< XComponent > xThis(this);

    {
        EventObject aEvent( xThis );
        std::unique_lock aGuard(m_mutex);
        m_aListenerContainer.disposeAndClear( aGuard, aEvent );
    }
    {
        SolarMutexGuard g;

        if (m_bDisposed)
        {
            return;
        }

        RemoveControllers();

        if ( m_xDocImageManager.is() )
        {
            try
            {
                m_xDocImageManager->removeConfigurationListener(
                    Reference< XUIConfigurationListener >(this) );
            }
            catch (const Exception&)
            {
            }
        }
        m_xDocImageManager.clear();
        if ( m_xModuleImageManager.is() )
        {
            try
            {
                m_xModuleImageManager->removeConfigurationListener(
                    Reference< XUIConfigurationListener >(this) );
            }
            catch (const Exception&)
            {
            }
        }
        m_xModuleImageManager.clear();

        if ( m_aOverflowManager.is() )
        {
            m_aOverflowManager->dispose();
            m_aOverflowManager.clear();
        }

        // We have to destroy our toolbar instance now.
        Destroy();
        m_pToolBar.reset();

        if ( m_bFrameActionRegistered && m_xFrame.is() )
        {
            try
            {
                m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(this) );
            }
            catch (const Exception&)
            {
            }
        }

        m_xFrame.clear();
        m_xContext.clear();

        // stop timer to prevent timer events after dispose
        // do it last because other calls could restart timer in StateChanged()
        m_aAsyncUpdateControllersTimer.Stop();

        m_bDisposed = true;
    }
}

void SAL_CALL ToolBarManager::addEventListener( const Reference< XEventListener >& xListener )
{
    SolarMutexGuard g;

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    if ( m_bDisposed )
        throw DisposedException();

    std::unique_lock aGuard(m_mutex);
    m_aListenerContainer.addInterface( aGuard, xListener );
}

void SAL_CALL ToolBarManager::removeEventListener( const Reference< XEventListener >& ;xListener )
{
    std::unique_lock aGuard(m_mutex);
    m_aListenerContainer.removeInterface( aGuard, xListener );
}

// XUIConfigurationListener
void SAL_CALL ToolBarManager::elementInserted( const css::ui::ConfigurationEvent& ;Event )
{
    impl_elementChanged(false,Event);
}

void SAL_CALL ToolBarManager::elementRemoved( const css::ui::ConfigurationEvent& Event )
{
    impl_elementChanged(true,Event);
}
void ToolBarManager::impl_elementChanged(bool const isRemove,
        const css::ui::ConfigurationEvent& Event)
{
    SolarMutexGuard g;

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    if ( m_bDisposed )
        return;

    Reference< XNameAccess > xNameAccess;
    sal_Int16                nImageType = sal_Int16();
    sal_Int16                nCurrentImageType = getCurrentImageType();

    if (!(( Event.aInfo >>= nImageType ) &&
        ( nImageType == nCurrentImageType ) &&
        ( Event.Element >>= xNameAccess )))
        return;

    sal_Int16 nImageInfo( 1 );
    Reference< XInterface > xIfacDocImgMgr( m_xDocImageManager, UNO_QUERY );
    if ( xIfacDocImgMgr == Event.Source )
        nImageInfo = 0;

    const Sequence< OUString > aSeq = xNameAccess->getElementNames();
    for ( OUString const & commandName : aSeq )
    {
        CommandToInfoMap::iterator pIter = m_aCommandMap.find( commandName );
        if ( pIter != m_aCommandMap.end() && ( pIter->second.nImageInfo >= nImageInfo ))
        {
            if (isRemove)
            {
                Image aImage;
                if (( pIter->second.nImageInfo == 0 ) && ( pIter->second.nImageInfo == nImageInfo ))
                {
                    // Special case: An image from the document image manager has been removed.
                    // It is possible that we have an image at our module image manager. Before
                    // we can remove our image we have to ask our module image manager.
                    Sequence< OUString > aCmdURLSeq{ pIter->first };
                    Sequence< Reference< XGraphic > > aGraphicSeq;
                    aGraphicSeq = m_xModuleImageManager->getImages( nImageType, aCmdURLSeq );
                    aImage = Image( aGraphicSeq[0] );
                }

                setToolBarImage(aImage,pIter);
            } // if (isRemove)
            else
            {
                Reference< XGraphic > xGraphic;
                if ( xNameAccess->getByName( commandName ) >>= xGraphic )
                {
                    Image aImage( xGraphic );
                    setToolBarImage(aImage,pIter);
                }
                pIter->second.nImageInfo = nImageInfo;
            }
        }
    }
}
void ToolBarManager::setToolBarImage(const Image& rImage,
        const CommandToInfoMap::const_iterator& rIter)
{
    const ::std::vector<ToolBoxItemId>& rIDs = rIter->second.aIds;
    m_pImpl->SetItemImage( rIter->second.nId, rIter->first, rImage );
    for (auto const& it : rIDs)
    {
        m_pImpl->SetItemImage(it, rIter->first, rImage);
    }
}

void SAL_CALL ToolBarManager::elementReplaced( const css::ui::ConfigurationEvent& ;Event )
{
    impl_elementChanged(false,Event);
}

void ToolBarManager::RemoveControllers()
{
    DBG_TESTSOLARMUTEX();
    assert(!m_bDisposed);

    m_aSubToolBarControllerMap.clear();

    if (m_aImageController)
        m_aImageController->dispose();
    m_aImageController.clear();

    // i90033
    // Remove item window pointers from the toolbar. They were
    // destroyed by the dispose() at the XComponent. This is needed
    // as VCL code later tries to access the item window data in certain
    // dtors where the item window is already invalid!
    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
    {
        ToolBoxItemId nItemId = m_pImpl->GetItemId( i );
        if ( nItemId > ToolBoxItemId(0) )
        {
            Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY );
            if ( xComponent.is() )
            {
                try
                {
                    xComponent->dispose();
                }
                catch (const Exception&)
                {
                }
            }
            m_pImpl->SetItemWindow(nItemId, nullptr);
        }
    }
    m_aControllerMap.clear();
}

void ToolBarManager::CreateControllers()
{
    Reference< XWindow > xToolbarWindow = m_pImpl->GetInterface();

    css::util::URL      aURL;
    bool                bHasDisabledEntries = SvtCommandOptions().HasEntriesDisabled();
    SvtCommandOptions   aCmdOptions;

    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
    {
        ToolBoxItemId nId = m_pImpl->GetItemId( i );
        if ( nId == ToolBoxItemId(0) )
            continue;

        bool                     bInit( true );
        bool                     bCreate( true );
        Reference< XStatusListener > xController;

        OUString aCommandURL( m_pImpl->GetItemCommand( nId ) );
        // Command can be just an alias to another command.
        auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
        OUString aRealCommandURL( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
        if ( !aRealCommandURL.isEmpty() )
            aCommandURL = aRealCommandURL;

        if ( bHasDisabledEntries )
        {
            aURL.Complete = aCommandURL;
            m_xURLTransformer->parseStrict( aURL );
            if ( aCmdOptions.LookupDisabled( aURL.Path ))
            {
                m_aControllerMap[ nId ] = xController;
                m_pImpl->HideItem( nId, aCommandURL );
                continue;
            }
        }

        if ( m_xToolbarControllerFactory.is() &&
             m_xToolbarControllerFactory->hasController( aCommandURL, m_aModuleIdentifier ))
        {
            Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
            Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
                { "ModuleIdentifier", Any(m_aModuleIdentifier) },
                { "Frame", Any(m_xFrame) },
                { "ServiceManager", Any(xMSF) },
                { "ParentWindow", Any(xToolbarWindow) },
                { "Identifier", Any(sal_uInt16(nId)) },
            } ));
            xController.set( m_xToolbarControllerFactory->createInstanceWithArgumentsAndContext( aCommandURL, aArgs, m_xContext ),
                             UNO_QUERY );
            bInit = false// Initialization is done through the factory service
        }

        if (( aCommandURL == ".uno:OpenUrl" ) && ( !m_pImpl->IsItemVisible(nId, aCommandURL)))
            bCreate = false;

        if ( !xController.is() && bCreate )
        {
            if ( m_pToolBar )
                xController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL );
            if ( !xController )
            {
                if ( aCommandURL.startsWith( ".uno:StyleApply?" ) )
                {
                    xController.set( new StyleToolbarController( m_xContext, m_xFrame, aCommandURL ));
                    m_pImpl->SetItemCheckable( nId );
                }
                else if ( aCommandURL.startsWith( "private:resource/" ) )
                {
                    xController.set( m_xContext->getServiceManager()->createInstanceWithContext(
                        u"com.sun.star.comp.framework.GenericPopupToolbarController"_ustr, m_xContext ), UNO_QUERY );
                }
                else if ( m_pToolBar && m_pToolBar->GetItemData( nId ) != nullptr )
                {
                    // retrieve additional parameters
                    OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType;
                    sal_uInt16 nWidth = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->nWidth;

                    xController.set(
                        ToolBarMerger::CreateController( m_xContext,
                                                         m_xFrame,
                                                         m_pToolBar,
                                                         aCommandURL,
                                                         nId,
                                                         nWidth,
                                                         aControlType ).get(), UNO_QUERY );

                }
                else
                {
                    if ( m_pToolBar )
                        xController.set( new GenericToolbarController( m_xContext, m_xFrame, m_pToolBar, nId, aCommandURL ));
                    else
                        xController.set( new GenericToolbarController( m_xContext, m_xFrame, *m_pWeldedToolBar, aCommandURL ));
                }
            }
        }

        // Accessibility support: Set toggle button role for specific commands
        const sal_Int32 nProps = vcl::CommandInfoProvider::GetPropertiesForCommand(aCommandURL, m_aModuleIdentifier);
        if (nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON)
            m_pImpl->SetItemCheckable(nId);

        // Associate ID and controller to be able to retrieve
        // the controller from the ID later.
        m_aControllerMap[ nId ] = xController;

        // Fill sub-toolbars into our hash-map
        Reference< XSubToolbarController > xSubToolBar( xController, UNO_QUERY );
        if ( xSubToolBar.is() && xSubToolBar->opensSubToolbar() )
        {
            OUString aSubToolBarName = xSubToolBar->getSubToolbarName();
            if ( !aSubToolBarName.isEmpty() )
            {
                SubToolBarToSubToolBarControllerMap::iterator pIter =
                    m_aSubToolBarControllerMap.find( aSubToolBarName );
                if ( pIter == m_aSubToolBarControllerMap.end() )
                {
                    SubToolBarControllerVector aSubToolBarVector;
                    aSubToolBarVector.push_back( xSubToolBar );
                    m_aSubToolBarControllerMap.emplace(
                            aSubToolBarName, aSubToolBarVector );
                }
                else
                    pIter->second.push_back( xSubToolBar );
            }
        }

        Reference< XInitialization > xInit( xController, UNO_QUERY );
        if ( xInit.is() )
        {
            if ( bInit )
            {
                Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
                Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
                    { "Frame", Any(m_xFrame) },
                    { "CommandURL", Any(aCommandURL) },
                    { "ServiceManager", Any(xMSF) },
                    { "ParentWindow", Any(xToolbarWindow) },
                    { "ModuleIdentifier", Any(m_aModuleIdentifier) },
                    { "Identifier", Any(sal_uInt16(nId)) },
                } ));

                xInit->initialize( aArgs );
            }

            // Request an item window from the toolbar controller and set it at the VCL toolbar
            Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
            if ( xTbxController.is() && xToolbarWindow.is() )
            {
                Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
                if ( xWindow.is() )
                {
                    VclPtr<vcl::Window> pItemWin = VCLUnoHelper::GetWindow( xWindow );
                    if ( pItemWin )
                    {
                        WindowType eType = pItemWin->GetType();
                        if ( m_pToolBar && (eType == WindowType::LISTBOX || eType == WindowType::MULTILISTBOX || eType == WindowType::COMBOBOX) )
                            pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
                        m_pImpl->SetItemWindow( nId, pItemWin );
                    }
                }
            }
        }

        //for update Controller via support visible state
        Reference< XPropertySet > xPropSet( xController, UNO_QUERY );
        if ( xPropSet.is() )
        {
            try
            {
                bool bSupportVisible = true;
                Any a( xPropSet->getPropertyValue(u"SupportsVisible"_ustr) );
                a >>= bSupportVisible;
                if (bSupportVisible)
                {
                    Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
                    UpdateController(xTbxController);
                }
            }
            catch (const RuntimeException&)
            {
                throw;
            }
            catch (const Exception&)
            {
            }
        }
    }

    AddFrameActionListener();
}

void ToolBarManager::AddFrameActionListener()
{
    if ( !m_bFrameActionRegistered && m_xFrame.is() )
    {
        m_bFrameActionRegistered = true;
        m_xFrame->addFrameActionListener( Reference< XFrameActionListener >(this) );
    }
}

// static
ToolBoxItemBits ToolBarManager::ConvertStyleToToolboxItemBits( sal_Int32 nStyle )
{
    ToolBoxItemBits nItemBits( ToolBoxItemBits::NONE );
    if ( nStyle & css::ui::ItemStyle::RADIO_CHECK )
        nItemBits |= ToolBoxItemBits::RADIOCHECK;
    if ( nStyle & css::ui::ItemStyle::ALIGN_LEFT )
        nItemBits |= ToolBoxItemBits::LEFT;
    if ( nStyle & css::ui::ItemStyle::AUTO_SIZE )
        nItemBits |= ToolBoxItemBits::AUTOSIZE;
    if ( nStyle & css::ui::ItemStyle::DROP_DOWN )
        nItemBits |= ToolBoxItemBits::DROPDOWN;
    if ( nStyle & css::ui::ItemStyle::REPEAT )
        nItemBits |= ToolBoxItemBits::REPEAT;
    if ( nStyle & css::ui::ItemStyle::DROPDOWN_ONLY )
        nItemBits |= ToolBoxItemBits::DROPDOWNONLY;
    if ( nStyle & css::ui::ItemStyle::TEXT )
        nItemBits |= ToolBoxItemBits::TEXT_ONLY;
    if ( nStyle & css::ui::ItemStyle::ICON )
        nItemBits |= ToolBoxItemBits::ICON_ONLY;

    return nItemBits;
}

void ToolBarManager::InitImageManager()
{
    Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
    if ( !m_xDocImageManager.is() )
    {
        Reference< XModel > xModel( GetModelFromFrame() );
        if ( xModel.is() )
        {
            Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
            if ( xSupplier.is() )
            {
                Reference< XUIConfigurationManager > xDocUICfgMgr = xSupplier->getUIConfigurationManager();
                m_xDocImageManager.set( xDocUICfgMgr->getImageManager(), UNO_QUERY );
                m_xDocImageManager->addConfigurationListener(
                                        Reference< XUIConfigurationListener >(this) );
            }
        }
    }

    try
    {
        m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
    }
    catch (const Exception&)
    {
    }

    if ( !m_xModuleImageManager.is() )
    {
        Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier =
            theModuleUIConfigurationManagerSupplier::get( m_xContext );
        Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
        m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
        m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
    }
}

void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer,
                                  const Reference< XIndexAccess >& rContextData,
                                  const OUString& rContextToolbarName )
{
    OString aTbxName = OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US );
    SAL_INFO( "fwk.uielement""framework (cd100003) ::ToolBarManager::FillToolbar " << aTbxName );

    SolarMutexGuard g;

    if ( m_bDisposed )
        return;

    InitImageManager();

    RemoveControllers();

    // reset and fill command map
    m_pImpl->Clear();
    m_aControllerMap.clear();
    m_aCommandMap.clear();

    ToolBoxItemId nId(1), nAddonId(1000);
    FillToolbarFromContainer( rItemContainer, m_aResourceName, nId, nAddonId );
    m_aContextResourceName = rContextToolbarName;
    if ( rContextData.is() )
    {
        m_pImpl->InsertSeparator();
        FillToolbarFromContainer( rContextData, m_aContextResourceName, nId, nAddonId );
    }

    // Request images for all toolbar items. Must be done before CreateControllers as
    // some controllers need access to the image.
    RequestImages();

    // Create controllers after we set the images. There are controllers which needs
    // an image at the toolbar at creation time!
    CreateControllers();

    // Notify controllers that they are now correctly initialized and can start listening
    // toolbars that will open in popup mode will be updated immediately to avoid flickering
    if( m_pImpl->WillUsePopupMode() )
        UpdateControllers();
    else if ( m_pImpl->IsReallyVisible() )
    {
        m_aAsyncUpdateControllersTimer.Start();
    }

    // Try to retrieve UIName from the container property set and set it as the title
    // if it is not empty.
    Reference< XPropertySet > xPropSet( rItemContainer, UNO_QUERY );
    if ( !xPropSet.is() )
        return;

    try
    {
        OUString aUIName;
        xPropSet->getPropertyValue(u"UIName"_ustr) >>= aUIName;
        if ( !aUIName.isEmpty() )
            m_pImpl->SetName( aUIName );
    }
    catch (const Exception&)
    {
    }
}

void ToolBarManager::FillToolbarFromContainer( const Reference< XIndexAccess >& rItemContainer,
                                               const OUString& rResourceName, ToolBoxItemId& nId, ToolBoxItemId& nAddonId )
{
    m_nContextMinPos = m_pImpl->GetItemCount();
    CommandInfo aCmdInfo;
    for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
    {
        Sequence< PropertyValue >   aProps;
        OUString                    aCommandURL;
        OUString                    aLabel;
        OUString                    aTooltip;
        sal_uInt16                  nType( css::ui::ItemType::DEFAULT );
        sal_uInt32                  nStyle( 0 );

        try
        {
            if ( rItemContainer->getByIndex( n ) >>= aProps )
            {
                bool bIsVisible( true );
                for (PropertyValue const& prop : aProps)
                {
                    if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
                        prop.Value >>= aCommandURL;
                    else if ( prop.Name == "Label" )
                        prop.Value >>= aLabel;
                    else if ( prop.Name == "Tooltip" )
                        prop.Value >>= aTooltip;
                    else if ( prop.Name == "Type" )
                        prop.Value >>= nType;
                    else if ( prop.Name == ITEM_DESCRIPTOR_VISIBLE )
                        prop.Value >>= bIsVisible;
                    else if ( prop.Name == "Style" )
                        prop.Value >>= nStyle;
                }

                if (!aCommandURL.isEmpty() && vcl::CommandInfoProvider::IsExperimental(aCommandURL, m_aModuleIdentifier) &&
                    !officecfg::Office::Common::Misc::ExperimentalMode::get())
                {
                    continue;
                }

                if (( nType == css::ui::ItemType::DEFAULT ) && !aCommandURL.isEmpty() )
                {
                    auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
                    if (!aProperties.hasElements()) // E.g., user-provided macro command?
                        aProperties = std::move(aProps); // Use existing info, including user-provided Label

                    ToolBoxItemBits nItemBits = ConvertStyleToToolboxItemBits( nStyle );

                    if ( aTooltip.isEmpty() )
                        aTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(aCommandURL, aProperties, m_xFrame);

                    if ( aLabel.isEmpty() )
                        aLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);

                    m_pImpl->InsertItem(nId, aCommandURL, aTooltip, aLabel, nItemBits);

                    // Fill command map. It stores all our commands and from what
                    // image manager we got our image. So we can decide if we have to use an
                    // image from a notification message.
                    auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
                    if ( pIter.second )
                    {
                        aCmdInfo.nId = nId;
                        pIter.first->second.nId = nId;
                    }
                    else
                    {
                        pIter.first->second.aIds.push_back( nId );
                    }

                    if ( !bIsVisible )
                        m_pImpl->HideItem( nId, aCommandURL );

                    ++nId;
                }
                else if ( nType == css::ui::ItemType::SEPARATOR_LINE )
                {
                    m_pImpl->InsertSeparator();
                }
                else if ( nType == css::ui::ItemType::SEPARATOR_SPACE )
                {
                    m_pImpl->InsertSpace();
                }
                else if ( nType == css::ui::ItemType::SEPARATOR_LINEBREAK )
                {
                    m_pImpl->InsertBreak();
                }
            }
        }
        catch (const css::lang::IndexOutOfBoundsException&)
        {
            break;
        }
    }

    // Support add-on toolbar merging here. Working directly on the toolbar object is much
    // simpler and faster.
    MergeToolbarInstructionContainer aMergeInstructionContainer;

    // Retrieve the toolbar name from the resource name
    OUString aToolbarName( rResourceName );
    sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' );
    if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() ))
        aToolbarName = aToolbarName.copy( nIndex+1 );

    AddonsOptions().GetMergeToolbarInstructions( aToolbarName, aMergeInstructionContainer );

    if ( !aMergeInstructionContainer.empty() )
    {
        const sal_uInt32 nCount = aMergeInstructionContainer.size();
        for ( sal_uInt32 i=0; i < nCount; i++ )
        {
            MergeToolbarInstruction& rInstruction = aMergeInstructionContainer[i];
            if ( ToolBarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier ))
            {
                m_pImpl->MergeToolbar(nAddonId, m_nContextMinPos, m_aModuleIdentifier, m_aCommandMap, rInstruction);
            }
        }
    }
}

void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
{
    if (!m_pToolBar)
        return;

    SolarMutexGuard g;

    if ( m_bDisposed )
        return;

    InitImageManager();

    RemoveControllers();

    // reset and fill command map
    m_pToolBar->Clear();
    m_aControllerMap.clear();
    m_aCommandMap.clear();

    ToolBoxItemId nId( 1 );
    CommandInfo aCmdInfo;
    for ( const Sequence< PropertyValue >& rSeq : rAddonToolbar )
    {
        OUString   aURL;
        OUString   aTitle;
        OUString   aContext;
        OUString   aTarget;
        OUString   aControlType;
        sal_uInt16 nWidth( 0 );

        ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aTarget, aContext, aControlType, nWidth );

        if ( ToolBarMerger::IsCorrectContext( aContext, m_aModuleIdentifier ) )
        {
            if ( aURL == "private:separator" )
            {
                ToolBox::ImplToolItems::size_type nCount = m_pToolBar->GetItemCount();
                if ( nCount > 0 && m_pToolBar->GetItemType( nCount-1 ) != ToolBoxItemType::SEPARATOR )
                    m_pToolBar->InsertSeparator();
            }
            else
            {
                m_pToolBar->InsertItem( nId, aTitle, aURL );

                OUString aShortcut(vcl::CommandInfoProvider::GetCommandShortcut(aURL, m_xFrame));
                if (!aShortcut.isEmpty())
                    m_pToolBar->SetQuickHelpText(nId, aTitle + " (" + aShortcut + ")");

                // Create AddonsParams to hold additional information we will need in the future
                AddonsParams* pRuntimeItemData = new AddonsParams;
                pRuntimeItemData->aControlType = aControlType;
                pRuntimeItemData->nWidth = nWidth;
                m_pToolBar->SetItemData( nId, pRuntimeItemData );

                // Fill command map. It stores all our commands and from what
                // image manager we got our image. So we can decide if we have to use an
                // image from a notification message.
                auto pIter = m_aCommandMap.emplace( aURL, aCmdInfo );
                if ( pIter.second )
                {
                    aCmdInfo.nId = nId;
                    pIter.first->second.nId = nId;
                }
                else
                {
                    pIter.first->second.aIds.push_back( nId );
                }
                ++nId;
            }
        }
    }

    // Don't setup images yet, AddonsToolbarWrapper::populateImages does that.
    // (But some controllers might need an image at the toolbar at creation time!)
    CreateControllers();

    // Notify controllers that they are now correctly initialized and can start listening.
    UpdateControllers();
}

void ToolBarManager::FillOverflowToolbar( ToolBox const * pParent )
{
    if (!m_pToolBar)
        return;

    CommandInfo aCmdInfo;
    bool bInsertSeparator = false;
    for ( ToolBox::ImplToolItems::size_type i = 0; i < pParent->GetItemCount(); ++i )
    {
        ToolBoxItemId nId = pParent->GetItemId( i );
        if ( pParent->IsItemClipped( nId ) )
        {
            if ( bInsertSeparator )
            {
                m_pToolBar->InsertSeparator();
                bInsertSeparator = false;
            }

            const OUString aCommandURL( pParent->GetItemCommand( nId ) );
            m_pToolBar->InsertItem( nId, pParent->GetItemText( nId ), aCommandURL );
            m_pToolBar->SetQuickHelpText( nId, pParent->GetQuickHelpText( nId ) );

            // Handle possible add-on controls.
            AddonsParams* pAddonParams = static_cast< AddonsParams* >( pParent->GetItemData( nId ) );
            if ( pAddonParams )
                m_pToolBar->SetItemData( nId, new AddonsParams( *pAddonParams ) );

            // Fill command map. It stores all our commands and from what
            // image manager we got our image. So we can decide if we have to use an
            // image from a notification message.
            auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
            if ( pIter.second )
            {
                aCmdInfo.nId = nId;
                pIter.first->second.nId = nId;
            }
            else
            {
                pIter.first->second.aIds.push_back( nId );
            }
        }
        else
        {
            ToolBoxItemType eType = pParent->GetItemType( i );
            if ( m_pToolBar->GetItemCount() &&
                ( eType == ToolBoxItemType::SEPARATOR || eType == ToolBoxItemType::BREAK ) )
                bInsertSeparator = true;
        }
    }

    InitImageManager();

    // Request images for all toolbar items. Must be done before CreateControllers as
    // some controllers need access to the image.
    RequestImages();

    // Create controllers after we set the images. There are controllers which needs
    // an image at the toolbar at creation time!
    CreateControllers();

    // Notify controllers that they are now correctly initialized and can start listening
    // toolbars that will open in popup mode will be updated immediately to avoid flickering
    UpdateControllers();
}

void ToolBarManager::RequestImages()
{

    // Request images from image manager
    Sequence< OUString > aCmdURLSeq( comphelper::mapKeysToSequence(m_aCommandMap) );
    Sequence< Reference< XGraphic > > aDocGraphicSeq;
    Sequence< Reference< XGraphic > > aModGraphicSeq;

    sal_Int16 nImageType = getCurrentImageType();

    if ( m_xDocImageManager.is() )
        aDocGraphicSeq = m_xDocImageManager->getImages(nImageType, aCmdURLSeq);
    aModGraphicSeq = m_xModuleImageManager->getImages(nImageType, aCmdURLSeq);

    sal_uInt32 i = 0;
    CommandToInfoMap::iterator pIter = m_aCommandMap.begin();
    CommandToInfoMap::iterator pEnd = m_aCommandMap.end();
    while ( pIter != pEnd )
    {
        Image aImage;
        if ( aDocGraphicSeq.hasElements() )
            aImage = Image( aDocGraphicSeq[i] );
        if ( !aImage )
        {
            aImage = Image( aModGraphicSeq[i] );
            // Try also to query for add-on images before giving up and use an
            // empty image.
            if ( !aImage )
                aImage = Image(framework::AddonsOptions().GetImageFromURL(aCmdURLSeq[i], SvtMiscOptions::AreCurrentSymbolsLarge()));

            pIter->second.nImageInfo = 1; // mark image as module based
        }
        else
        {
            pIter->second.nImageInfo = 0; // mark image as document based
        }
        setToolBarImage(aImage,pIter);
        ++pIter;
        ++i;
    }

    assert(!m_aImageController); // an existing one isn't disposed here
    m_aImageController = new ImageOrientationController(m_xContext, m_xFrame, m_pImpl->GetInterface(), m_aModuleIdentifier);
    m_aImageController->update();
}

void ToolBarManager::notifyRegisteredControllers( const OUString& aUIElementNameconst OUString& aCommand )
{
    SolarMutexClearableGuard aGuard;
    if ( m_aSubToolBarControllerMap.empty() )
        return;

    SubToolBarToSubToolBarControllerMap::const_iterator pIter =
        m_aSubToolBarControllerMap.find( aUIElementName );

    if ( pIter == m_aSubToolBarControllerMap.end() )
        return;

    const SubToolBarControllerVector& rSubToolBarVector = pIter->second;
    if ( rSubToolBarVector.empty() )
        return;

    SubToolBarControllerVector aNotifyVector = rSubToolBarVector;
    aGuard.clear();

    const sal_uInt32 nCount = aNotifyVector.size();
    for ( sal_uInt32 i=0; i < nCount; i++ )
    {
        try
        {
            const Reference< XSubToolbarController >& xController = aNotifyVector[i];
            if ( xController.is() )
                xController->functionSelected( aCommand );
        }
        catch (const RuntimeException&)
        {
            throw;
        }
        catch (const Exception&)
        {
        }
    }
}

void ToolBarManager::HandleClick(ClickAction eClickAction)
{
    SolarMutexGuard g;

    if ( m_bDisposed )
        return;

    ToolBoxItemId nId( m_pImpl->GetCurItemId() );
    ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
    if ( pIter == m_aControllerMap.end() )
        return;

    Reference< XToolbarController > xController( pIter->second, UNO_QUERY );

    if ( xController.is() )
    {
        switch (eClickAction)
        {
            case ClickAction::Click:
                xController->click();
                break;

            case ClickAction::DblClick:
                xController->doubleClick();
                break;

            case ClickAction::Execute:
                xController->execute(0);
                break;
        }
    }
}

void ToolBarManager::OnClick(bool bUseExecute)
{
    if (bUseExecute)
        HandleClick(ClickAction::Execute);
    else
        HandleClick(ClickAction::Click);
}

IMPL_LINK_NOARG(ToolBarManager, DropdownClick, ToolBox *, void)
{
    OnDropdownClick(true);
}

void ToolBarManager::OnDropdownClick(bool bCreatePopupWindow)
{
    SolarMutexGuard g;

    if ( m_bDisposed )
        return;

    ToolBoxItemId nId( m_pImpl->GetCurItemId() );
    ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
    if ( pIter == m_aControllerMap.end() )
        return;

    Reference< XToolbarController > xController( pIter->second, UNO_QUERY );

    if ( xController.is() )
    {
        if (bCreatePopupWindow)
        {
            Reference< XWindow > xWin = xController->createPopupWindow();
            if ( xWin.is() )
                xWin->setFocus();
        }
        else
        {
            xController->click();
        }
    }
}

IMPL_LINK_NOARG(ToolBarManager, DoubleClick, ToolBox *, void)
{
    HandleClick(ClickAction::DblClick);
}

Reference< XModel > ToolBarManager::GetModelFromFrame() const
{
    Reference< XController > xController = m_xFrame->getController();
    Reference< XModel > xModel;
    if ( xController.is() )
        xModel = xController->getModel();

    return xModel;
}

bool ToolBarManager::IsPluginMode() const
{
    bool bPluginMode( false );

    if ( m_xFrame.is() )
    {
        Reference< XModel > xModel = GetModelFromFrame();
        if ( xModel.is() )
        {
            Sequence< PropertyValue > aSeq = xModel->getArgs();
            utl::MediaDescriptor aMediaDescriptor( aSeq );
            bPluginMode = aMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_VIEWONLY, false );
        }
    }

    return bPluginMode;
}

void ToolBarManager::AddCustomizeMenuItems(ToolBox const * pToolBar)
{
    if (!m_pToolBar)
        return;

    // No config menu entries if command ".uno:ConfigureDialog" is not enabled
    Reference< XDispatch > xDisp;
    css::util::URL aURL;
    if ( m_xFrame.is() )
    {
        Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
        aURL.Complete = ".uno:ConfigureDialog";
        m_xURLTransformer->parseStrict( aURL );
        if ( xProv.is() )
            xDisp = xProv->queryDispatch( aURL, OUString(), 0 );

        if ( !xDisp.is() || IsPluginMode() )
            return;
    }

    // popup menu for quick customization
    bool bHideDisabledEntries = !officecfg::Office::Common::View::Menu::DontHideDisabledEntry::get();

    ::PopupMenu *pMenu = pToolBar->GetMenu();

    // copy all menu items 'Visible buttons, Customize toolbar, Dock toolbar,
    // Dock all Toolbars) from the loaded resource into the toolbar menu
    sal_uInt16 nGroupLen = pMenu->GetItemCount();
    if (nGroupLen)
        pMenu->InsertSeparator();

    VclPtr<PopupMenu> xVisibleItemsPopupMenu;

    if (!m_aResourceName.startsWith("private:resource/toolbar/addon_"))
    {
        pMenu->InsertItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, FwkResId(STR_TOOLBAR_VISIBLE_BUTTONS));
        xVisibleItemsPopupMenu = VclPtr<PopupMenu>::Create();
        pMenu->SetPopupMenu(MENUITEM_TOOLBAR_VISIBLEBUTTON, xVisibleItemsPopupMenu);

        if (m_pToolBar->IsCustomize())
        {
            pMenu->InsertItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, FwkResId(STR_TOOLBAR_CUSTOMIZE_TOOLBAR));
            pMenu->SetItemCommand(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, u".uno:ConfigureToolboxVisible"_ustr);
        }
        pMenu->InsertSeparator();
    }

    if (pToolBar->IsFloatingMode())
    {
        pMenu->InsertItem(MENUITEM_TOOLBAR_DOCKTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_TOOLBAR));
        pMenu->SetAccelKey(MENUITEM_TOOLBAR_DOCKTOOLBAR, vcl::KeyCode(KEY_F10, truetruefalsefalse));
    }
    else
    {
        pMenu->InsertItem(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, FwkResId(STR_TOOLBAR_UNDOCK_TOOLBAR));
        pMenu->SetAccelKey(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, vcl::KeyCode(KEY_F10, truetruefalsefalse));
    }

    pMenu->InsertItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_ALL_TOOLBARS));
    pMenu->InsertSeparator();
    pMenu->InsertItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, FwkResId(STR_TOOLBAR_LOCK_TOOLBAR), MenuItemBits::CHECKABLE);
    pMenu->InsertItem(MENUITEM_TOOLBAR_CLOSE, FwkResId(STR_TOOLBAR_CLOSE_TOOLBAR));

    if (m_pToolBar->IsCustomize())
    {
        bool    bIsFloating( false );

        DockingManager* pDockMgr = vcl::Window::GetDockingManager();
        if ( pDockMgr )
            bIsFloating = pDockMgr->IsFloating( m_pToolBar );

        if ( !bIsFloating )
        {
            pMenu->EnableItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, false);
            Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
            if( xDockable.is() )
                pMenu->CheckItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, xDockable->isLocked());
        }
        else
            pMenu->EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);

        if (officecfg::Office::Common::Misc::DisableUICustomization::get())
        {
            pMenu->EnableItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, false);
            pMenu->EnableItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, false);
            pMenu->EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=96 H=98 G=96

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge