/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "precompiled_sfx2.hxx"

#include "sfx2/taskpane.hxx"
#include "imagemgr.hxx"
#include "sfx2/sfxsids.hrc"
#include "sfx2/bindings.hxx"
#include "sfx2/dispatch.hxx"
#include "sfxresid.hxx"
#include "sfxlocal.hrc"
#include "helpid.hrc"

/** === begin UNO includes === **/
#include <com/sun/star/frame/XModuleManager.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/ui/XToolPanel.hpp>
#include <com/sun/star/ui/XUIElementFactory.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/awt/XControl.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/types.hxx>
#include <comphelper/processfactory.hxx>
#include <tools/diagnose_ex.h>
#include <svtools/toolpanel/toolpaneldeck.hxx>
#include <svtools/toolpanel/tablayouter.hxx>
#include <svtools/toolpanel/drawerlayouter.hxx>
#include <unotools/confignode.hxx>
#include <vcl/menu.hxx>
#include <vcl/svapp.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/urlobj.hxx>
#include <boost/noncopyable.hpp>

//......................................................................................................................
namespace sfx2
{
//......................................................................................................................

    /** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
	using ::com::sun::star::uno::Sequence;
	using ::com::sun::star::uno::Type;
    using ::com::sun::star::frame::XModuleManager;
    using ::com::sun::star::container::XNameAccess;
    using ::com::sun::star::ui::XToolPanel;
    using ::com::sun::star::ui::XUIElementFactory;
    using ::com::sun::star::ui::XUIElement;
    using ::com::sun::star::awt::XWindow;
    using ::com::sun::star::frame::XModuleManager;
    using ::com::sun::star::frame::XFrame;
    using ::com::sun::star::lang::XComponent;
    using ::com::sun::star::graphic::XGraphicProvider;
    using ::com::sun::star::graphic::XGraphic;
    using ::com::sun::star::accessibility::XAccessible;
    using ::com::sun::star::awt::XControl;
    /** === end UNO using === **/
    namespace PosSize = ::com::sun::star::awt::PosSize;

	//==================================================================================================================
	//= helpers
	//==================================================================================================================
    namespace
    {
	    //--------------------------------------------------------------------------------------------------------------
        ::utl::OConfigurationTreeRoot lcl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier,
            const ::rtl::OUString& i_rResourceURL = ::rtl::OUString() )
        {
            const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            ::rtl::OUStringBuffer aPathComposer;
            try
            {
                const Reference< XNameAccess > xModuleAccess( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW );
                const ::comphelper::NamedValueCollection aModuleProps( xModuleAccess->getByName( i_rModuleIdentifier ) );

                const ::rtl::OUString sWindowStateRef( aModuleProps.getOrDefault( "ooSetupFactoryWindowStateConfigRef", ::rtl::OUString() ) );

                aPathComposer.appendAscii( "org.openoffice.Office.UI." );
                aPathComposer.append( sWindowStateRef );
                aPathComposer.appendAscii( "/UIElements/States" );
                if ( i_rResourceURL.getLength() )
                {
                    aPathComposer.appendAscii( "/" );
                    aPathComposer.append( i_rResourceURL );
                }
            }
            catch( const Exception& )
            {
        	    DBG_UNHANDLED_EXCEPTION();
            }
            return ::utl::OConfigurationTreeRoot( aContext, aPathComposer.makeStringAndClear(), false );
        }

	    //--------------------------------------------------------------------------------------------------------------
        ::rtl::OUString lcl_identifyModule( const Reference< XFrame >& i_rDocumentFrame )
        {
            ::rtl::OUString sModuleName;
            try
            {
                const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
                const Reference< XModuleManager > xModuleManager( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW );
                sModuleName = xModuleManager->identify( i_rDocumentFrame );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
            return sModuleName;
        }

	    //--------------------------------------------------------------------------------------------------------------
        Reference< XFrame > lcl_getFrame( const SfxBindings* i_pBindings )
        {
            const SfxViewFrame* pViewFrame = i_pBindings->GetDispatcher()->GetFrame();
            const SfxFrame& rFrame = pViewFrame->GetFrame();
            const Reference< XFrame > xFrame( rFrame.GetFrameInterface() );
            return xFrame;
        }

	    //--------------------------------------------------------------------------------------------------------------
        ::rtl::OUString lcl_getPanelHelpURL( const ::utl::OConfigurationNode& i_rPanelConfigNode )
        {
            const ::rtl::OUString sHelpURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "HelpURL" ) ) );
            return sHelpURL;
        }

	    //--------------------------------------------------------------------------------------------------------------
        Image lcl_getPanelImage( const Reference< XFrame >& i_rDocFrame, const ::utl::OConfigurationNode& i_rPanelConfigNode )
        {
            const ::rtl::OUString sImageURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "ImageURL" ) ) );
            if ( sImageURL.getLength() )
            {
                try
                {
                    ::comphelper::NamedValueCollection aMediaProperties;
                    aMediaProperties.put( "URL", sImageURL );

                    // special handling: if the ImageURL denotes a CommandName, then retrieve the image for that command
                    const sal_Char* pCommandImagePrefix = "private:commandimage/";
                    const sal_Int32 nCommandImagePrefixLen = strlen( pCommandImagePrefix );
                    if ( sImageURL.compareToAscii( pCommandImagePrefix, nCommandImagePrefixLen ) == 0 )
                    {
                        ::rtl::OUStringBuffer aCommandName;
                        aCommandName.appendAscii( ".uno:" );
                        aCommandName.append( sImageURL.copy( nCommandImagePrefixLen ) );
                        const ::rtl::OUString sCommandName( aCommandName.makeStringAndClear() );

                        const sal_Bool bHiContrast( Application::GetSettings().GetStyleSettings().GetHighContrastMode() );
                        const Image aPanelImage( GetImage( i_rDocFrame, sCommandName, sal_False, bHiContrast ) );
                        return aPanelImage.GetXGraphic();
                    }

                    // otherwise, delegate to the GraphicProvider
                    const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
                    const Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW );

                    const Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_SET_THROW );
                    return Image( xGraphic );
                }
                catch( const Exception& )
                {
            	    DBG_UNHANDLED_EXCEPTION();
                }
            }
            return Image();
        }
    }

	//==================================================================================================================
	//= TaskPaneDockingWindow
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    TaskPaneDockingWindow::TaskPaneDockingWindow( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits )
        :TitledDockingWindow( i_pBindings, &i_rWrapper, i_pParent, i_nBits )
        ,m_aTaskPane( GetContentWindow(), lcl_getFrame( i_pBindings ) )
        ,m_aPaneController( m_aTaskPane, *this )
    {
        m_aTaskPane.Show();
        SetText( String( SfxResId( SID_TASKPANE ) ) );
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneDockingWindow::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
    {
        m_aPaneController.ActivateToolPanel( i_rPanelURL );
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneDockingWindow::GetFocus()
    {
        TitledDockingWindow::GetFocus();
        m_aTaskPane.GrabFocus();
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneDockingWindow::onLayoutDone()
    {
        m_aTaskPane.SetPosSizePixel( Point(), GetContentWindow().GetOutputSizePixel() );
    }

	//==================================================================================================================
	//= TaskPaneWrapper
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    SFX_IMPL_DOCKINGWINDOW( TaskPaneWrapper, SID_TASKPANE );

	//------------------------------------------------------------------------------------------------------------------
    TaskPaneWrapper::TaskPaneWrapper( Window* i_pParent, sal_uInt16 i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pInfo )
        :SfxChildWindow( i_pParent, i_nId )
    {
        pWindow = new TaskPaneDockingWindow( i_pBindings, *this, i_pParent,
            WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE);
	    eChildAlignment = SFX_ALIGN_RIGHT;

	    pWindow->SetHelpId( HID_TASKPANE_WINDOW );
        pWindow->SetOutputSizePixel( Size( 300, 450 ) );

        dynamic_cast< SfxDockingWindow* >( pWindow )->Initialize( i_pInfo );
	    SetHideNotDelete( sal_True );

        pWindow->Show();
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneWrapper::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
    {
        TaskPaneDockingWindow* pDockingWindow = dynamic_cast< TaskPaneDockingWindow* >( GetWindow() );
        ENSURE_OR_RETURN_VOID( pDockingWindow, "TaskPaneWrapper::ActivateToolPanel: invalid docking window implementation!" );
        pDockingWindow->ActivateToolPanel( i_rPanelURL );
    }

	//==================================================================================================================
	//= CustomPanelUIElement
	//==================================================================================================================
    class CustomPanelUIElement
    {
    public:
        CustomPanelUIElement()
            :m_xUIElement()
            ,m_xToolPanel()
            ,m_xPanelWindow()
        {
        }

        CustomPanelUIElement( const Reference< XUIElement >& i_rUIElement )
            :m_xUIElement( i_rUIElement, UNO_SET_THROW )
            ,m_xToolPanel( i_rUIElement->getRealInterface(), UNO_QUERY_THROW )
            ,m_xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW )
        {
        }

        bool is() const { return m_xPanelWindow.is(); }

        const Reference< XUIElement >&  getUIElement() const { return m_xUIElement; }
        const Reference< XToolPanel >&  getToolPanel() const { return m_xToolPanel; }
        const Reference< XWindow >&     getPanelWindow() const { return m_xPanelWindow; }

    private:
        Reference< XUIElement > m_xUIElement;
        Reference< XToolPanel > m_xToolPanel;
        Reference< XWindow >    m_xPanelWindow;
    };

	//==================================================================================================================
	//= CustomToolPanel
	//==================================================================================================================
    class CustomToolPanel : public ::svt::ToolPanelBase
    {
    public:
        CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame );

        virtual ::rtl::OUString GetDisplayName() const;
        virtual Image GetImage() const;
        virtual rtl::OString GetHelpID() const;
        virtual void Activate( Window& i_rParentWindow );
        virtual void Deactivate();
        virtual void SetSizePixel( const Size& i_rPanelWindowSize );
        virtual void GrabFocus();
        virtual void Dispose();
        virtual Reference< XAccessible >
                    CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible );

        const ::rtl::OUString&
                    GetResourceURL() const { return m_sResourceURL; }

    protected:
        ~CustomToolPanel();

    private:
        bool    impl_ensureToolPanelWindow( Window& i_rPanelParentWindow );
        void    impl_updatePanelConfig( const bool i_bVisible ) const;

    private:
        const ::rtl::OUString   m_sUIName;
        const Image             m_aPanelImage;
        const ::rtl::OUString   m_aPanelHelpURL;
        const ::rtl::OUString   m_sResourceURL;
        const ::rtl::OUString   m_sPanelConfigPath;
        Reference< XFrame >     m_xFrame;
        CustomPanelUIElement    m_aCustomPanel;
        bool                    m_bAttemptedCreation;
    };

    //------------------------------------------------------------------------------------------------------------------
    CustomToolPanel::CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame )
        :m_sUIName( ::comphelper::getString( i_rPanelWindowState.getNodeValue( "UIName" ) ) )
        ,m_aPanelImage( lcl_getPanelImage( i_rFrame, i_rPanelWindowState ) )
        ,m_aPanelHelpURL( lcl_getPanelHelpURL( i_rPanelWindowState ) )
        ,m_sResourceURL( i_rPanelWindowState.getLocalName() )
        ,m_sPanelConfigPath( i_rPanelWindowState.getNodePath() )
        ,m_xFrame( i_rFrame )
        ,m_aCustomPanel()
        ,m_bAttemptedCreation( false )
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    CustomToolPanel::~CustomToolPanel()
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    bool CustomToolPanel::impl_ensureToolPanelWindow( Window& i_rPanelParentWindow )
    {
        if ( m_bAttemptedCreation )
            return m_aCustomPanel.is();

        m_bAttemptedCreation = true;
        try
        {
            const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            const Reference< XUIElementFactory > xFactory( aContext.createComponent( "com.sun.star.ui.UIElementFactoryManager" ), UNO_QUERY_THROW );

            ::comphelper::NamedValueCollection aCreationArgs;
            aCreationArgs.put( "Frame", makeAny( m_xFrame ) );
            aCreationArgs.put( "ParentWindow", makeAny( i_rPanelParentWindow.GetComponentInterface() ) );

            const Reference< XUIElement > xElement(
                xFactory->createUIElement( m_sResourceURL, aCreationArgs.getPropertyValues() ),
                UNO_SET_THROW );

            m_aCustomPanel = CustomPanelUIElement( xElement );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return m_aCustomPanel.is();
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::impl_updatePanelConfig( const bool i_bVisible ) const
    {
        ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
        ::utl::OConfigurationTreeRoot aConfig( aContext, m_sPanelConfigPath, true );

        aConfig.setNodeValue( "Visible", makeAny( i_bVisible ) );
        aConfig.commit();
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString CustomToolPanel::GetDisplayName() const
    {
        return m_sUIName;
    }

    //------------------------------------------------------------------------------------------------------------------
    Image CustomToolPanel::GetImage() const
    {
        return m_aPanelImage;
    }

	static rtl::OString lcl_getHelpId( const ::rtl::OUString& _rHelpURL )
    {
        INetURLObject aHID( _rHelpURL );
        if ( aHID.GetProtocol() == INET_PROT_HID )
            return rtl::OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 );
        else
            return rtl::OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 );
    }

    //------------------------------------------------------------------------------------------------------------------
    rtl::OString CustomToolPanel::GetHelpID() const
    {
        return lcl_getHelpId( m_aPanelHelpURL );
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::Activate( Window& i_rParentWindow )
    {
        ENSURE_OR_RETURN_VOID( impl_ensureToolPanelWindow( i_rParentWindow ), "no panel to activate!" );

        // TODO: we might need a mechanism to decide whether the panel should be destroyed/re-created, or (as it is
        // done now) hidden/shown
        m_aCustomPanel.getPanelWindow()->setVisible( sal_True );

        // update the panel's configuration
        impl_updatePanelConfig( true );
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::Deactivate()
    {
        ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to deactivate!" );

        m_aCustomPanel.getPanelWindow()->setVisible( sal_False );

        // update the panel's configuration
        impl_updatePanelConfig( false );
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::SetSizePixel( const Size& i_rPanelWindowSize )
    {
        ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to position!" );

        try
        {
            m_aCustomPanel.getPanelWindow()->setPosSize( 0, 0, i_rPanelWindowSize.Width(), i_rPanelWindowSize.Height(),
                PosSize::POSSIZE );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::GrabFocus()
    {
        ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to focus!" );

        m_aCustomPanel.getPanelWindow()->setFocus();
    }

    //------------------------------------------------------------------------------------------------------------------
    void CustomToolPanel::Dispose()
    {
        if ( !m_bAttemptedCreation )
            // nothing to dispose
            return;

        ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to destroy!" );
        try
        {
            Reference< XComponent > xUIElementComponent( m_aCustomPanel.getUIElement(), UNO_QUERY_THROW );
            xUIElementComponent->dispose();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //------------------------------------------------------------------------------------------------------------------
    Reference< XAccessible > CustomToolPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible )
    {
        ENSURE_OR_RETURN( m_aCustomPanel.is(), "no panel to ask!", NULL );

        Reference< XAccessible > xPanelAccessible;
        try
        {
            xPanelAccessible.set( m_aCustomPanel.getToolPanel()->createAccessible( i_rParentAccessible ), UNO_SET_THROW );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return xPanelAccessible;
    }

	//==================================================================================================================
	//= ModuleTaskPane_Impl
	//==================================================================================================================
    class ModuleTaskPane_Impl : public ::boost::noncopyable
    {
    public:
        ModuleTaskPane_Impl( ModuleTaskPane& i_rAntiImpl, const Reference< XFrame >& i_rDocumentFrame,
                const IToolPanelCompare* i_pPanelCompare )
            :m_rAntiImpl( i_rAntiImpl )
            ,m_sModuleIdentifier( lcl_identifyModule( i_rDocumentFrame ) )
            ,m_xFrame( i_rDocumentFrame )
            ,m_aPanelDeck( i_rAntiImpl )
        {
            m_aPanelDeck.Show();
            OnResize();
            impl_initFromConfiguration( i_pPanelCompare );
        }

        ~ModuleTaskPane_Impl()
        {
        }

        void    OnResize();
        void    OnGetFocus();

        static bool ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier );

              ::svt::ToolPanelDeck& GetPanelDeck()          { return m_aPanelDeck; }
        const ::svt::ToolPanelDeck& GetPanelDeck() const    { return m_aPanelDeck; }

        ::boost::optional< size_t >
                    GetPanelPos( const ::rtl::OUString& i_rResourceURL );
        ::rtl::OUString
                    GetPanelResourceURL( const size_t i_nPanelPos ) const;

        void        SetDrawersLayout();
        void        SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent );

    private:
        void    impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare );

        static bool
                impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL );

        DECL_LINK( OnActivatePanel, void* );

    private:
        ModuleTaskPane&             m_rAntiImpl;
        const ::rtl::OUString       m_sModuleIdentifier;
        const Reference< XFrame >   m_xFrame;
        ::svt::ToolPanelDeck        m_aPanelDeck;
    };

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane_Impl::OnResize()
    {
        m_aPanelDeck.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() );
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane_Impl::OnGetFocus()
    {
        m_aPanelDeck.GrabFocus();
    }

	//------------------------------------------------------------------------------------------------------------------
    IMPL_LINK( ModuleTaskPane_Impl, OnActivatePanel, void*, i_pArg )
    {
        m_aPanelDeck.ActivatePanel( reinterpret_cast< size_t >( i_pArg ) );
        return 1L;
    }

	//------------------------------------------------------------------------------------------------------------------
    bool ModuleTaskPane_Impl::impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL )
    {
        return i_rResourceURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/" ) );
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane_Impl::impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare )
    {
        const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( m_sModuleIdentifier ) );
        if ( !aWindowStateConfig.isValid() )
            return;

        ::rtl::OUString sFirstVisiblePanelResource;
        ::rtl::OUString sFirstPanelResource;

        const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() );
        for (   const ::rtl::OUString* resource = aUIElements.getConstArray();
                resource != aUIElements.getConstArray() + aUIElements.getLength();
                ++resource
            )
        {
            if ( !impl_isToolPanelResource( *resource ) )
                continue;

            sFirstPanelResource = *resource;

            ::utl::OConfigurationNode aResourceNode( aWindowStateConfig.openNode( *resource ) );
            ::svt::PToolPanel pCustomPanel( new CustomToolPanel( aResourceNode, m_xFrame ) );

            size_t nPanelPos = m_aPanelDeck.GetPanelCount();
            if ( i_pPanelCompare )
            {
                // assuming that nobody will insert hundreths of panels, a simple O(n) search should suffice here ...
                while ( nPanelPos > 0 )
                {
                    const short nCompare = i_pPanelCompare->compareToolPanelsURLs( 
                        *resource,
                        GetPanelResourceURL( --nPanelPos )
                    );
                    if ( nCompare >= 0 )
                    {
                        ++nPanelPos;
                        break;
                    }
                }
            }
            nPanelPos = m_aPanelDeck.InsertPanel( pCustomPanel, nPanelPos );

            if ( ::comphelper::getBOOL( aResourceNode.getNodeValue( "Visible" ) ) )
                sFirstVisiblePanelResource = *resource;
        }

        if ( sFirstVisiblePanelResource.getLength() == 0 )
            sFirstVisiblePanelResource = sFirstPanelResource;

        if ( sFirstVisiblePanelResource.getLength() )
        {
            ::boost::optional< size_t > aPanelPos( GetPanelPos( sFirstVisiblePanelResource ) );
            OSL_ENSURE( !!aPanelPos, "ModuleTaskPane_Impl::impl_isToolPanelResource: just inserted it, and it's not there?!" );
            if ( !!aPanelPos )
                m_rAntiImpl.PostUserEvent( LINK( this, ModuleTaskPane_Impl, OnActivatePanel ), reinterpret_cast< void* >( *aPanelPos ) );
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    bool ModuleTaskPane_Impl::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier )
    {
        const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( i_rModuleIdentifier ) );
        if ( !aWindowStateConfig.isValid() )
            return false;

        const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() );
        for (   const ::rtl::OUString* resource = aUIElements.getConstArray();
                resource != aUIElements.getConstArray() + aUIElements.getLength();
                ++resource
            )
        {
            if ( impl_isToolPanelResource( *resource ) )
                return true;
        }
        return false;
    }

	//------------------------------------------------------------------------------------------------------------------
    ::boost::optional< size_t > ModuleTaskPane_Impl::GetPanelPos( const ::rtl::OUString& i_rResourceURL )
    {
        ::boost::optional< size_t > aPanelPos;
        for ( size_t i = 0; i < m_aPanelDeck.GetPanelCount(); ++i )
        {
            const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i ) );
            const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() );
            ENSURE_OR_CONTINUE( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!" );
            if ( pCustomPanel->GetResourceURL() == i_rResourceURL )
            {
                aPanelPos = i;
                break;
            }
        }
        return aPanelPos;
    }

	//------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString ModuleTaskPane_Impl::GetPanelResourceURL( const size_t i_nPanelPos ) const
    {
        ENSURE_OR_RETURN( i_nPanelPos < m_aPanelDeck.GetPanelCount(), "ModuleTaskPane_Impl::GetPanelResourceURL: illegal panel position!", ::rtl::OUString() );
        const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i_nPanelPos ) );
        const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() );
        ENSURE_OR_RETURN( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!", ::rtl::OUString() );
        return pCustomPanel->GetResourceURL();
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane_Impl::SetDrawersLayout()
    {
        const ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() );
        const ::svt::DrawerDeckLayouter* pDrawerLayouter = dynamic_cast< const ::svt::DrawerDeckLayouter* >( pLayouter.get() );
        if ( pDrawerLayouter != NULL )
            // already have the proper layout
            return;
        m_aPanelDeck.SetLayouter( new ::svt::DrawerDeckLayouter( m_aPanelDeck, m_aPanelDeck ) );
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane_Impl::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent )
    {
        ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() );
        ::svt::TabDeckLayouter* pTabLayouter = dynamic_cast< ::svt::TabDeckLayouter* >( pLayouter.get() );
        if  (   ( pTabLayouter != NULL )
            &&  ( pTabLayouter->GetTabAlignment() == i_eTabAlignment )
            &&  ( pTabLayouter->GetTabItemContent() == i_eTabContent )
            )
            // already have the requested layout
            return;

        if ( pTabLayouter && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) )
        {
            // changing only the item content does not require a new layouter instance
            pTabLayouter->SetTabItemContent( i_eTabContent );
            return;
        }

        m_aPanelDeck.SetLayouter( new ::svt::TabDeckLayouter( m_aPanelDeck, m_aPanelDeck, i_eTabAlignment, i_eTabContent ) );
    }

	//==================================================================================================================
	//= ModuleTaskPane
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame )
        :Window( &i_rParentWindow, WB_DIALOGCONTROL )
        ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, NULL ) )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame,
            const IToolPanelCompare& i_rCompare )
        :Window( &i_rParentWindow, WB_DIALOGCONTROL )
        ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, &i_rCompare ) )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    ModuleTaskPane::~ModuleTaskPane()
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    bool ModuleTaskPane::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier )
    {
        return ModuleTaskPane_Impl::ModuleHasToolPanels( i_rModuleIdentifier );
    }

	//------------------------------------------------------------------------------------------------------------------
    bool ModuleTaskPane::ModuleHasToolPanels( const Reference< XFrame >& i_rDocumentFrame )
    {
        return ModuleTaskPane_Impl::ModuleHasToolPanels( lcl_identifyModule( i_rDocumentFrame ) );
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane::Resize()
    {
        Window::Resize();
        m_pImpl->OnResize();
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane::GetFocus()
    {
        Window::GetFocus();
        m_pImpl->OnGetFocus();
    }

	//------------------------------------------------------------------------------------------------------------------
    ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck()
    {
        return m_pImpl->GetPanelDeck();
    }

	//------------------------------------------------------------------------------------------------------------------
    const ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() const
    {
        return m_pImpl->GetPanelDeck();
    }

	//------------------------------------------------------------------------------------------------------------------
    ::boost::optional< size_t > ModuleTaskPane::GetPanelPos( const ::rtl::OUString& i_rResourceURL )
    {
        return m_pImpl->GetPanelPos( i_rResourceURL );
    }

	//------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString ModuleTaskPane::GetPanelResourceURL( const size_t i_nPanelPos ) const
    {
        return m_pImpl->GetPanelResourceURL( i_nPanelPos );
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane::SetDrawersLayout()
    {
        m_pImpl->SetDrawersLayout();
    }

	//------------------------------------------------------------------------------------------------------------------
    void ModuleTaskPane::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent )
    {
        m_pImpl->SetTabsLayout( i_eTabAlignment, i_eTabContent );
    }

    // =====================================================================================================================
    // = PanelSelectorLayout
    // =====================================================================================================================
    enum PanelSelectorLayout
    {
        LAYOUT_DRAWERS,
        LAYOUT_TABS_RIGHT,
        LAYOUT_TABS_LEFT,
        LAYOUT_TABS_TOP,
        LAYOUT_TABS_BOTTOM
    };

	//==================================================================================================================
	//= helper
	//==================================================================================================================
    namespace
    {
        PanelSelectorLayout lcl_getTabLayoutFromAlignment( const SfxChildAlignment i_eAlignment )
        {
            switch ( i_eAlignment )
            {
            case SFX_ALIGN_LEFT:
                return LAYOUT_TABS_LEFT;
            case SFX_ALIGN_TOP:
                return LAYOUT_TABS_TOP;
            case SFX_ALIGN_BOTTOM:
                return LAYOUT_TABS_BOTTOM;
            default:
                return LAYOUT_TABS_RIGHT;
            }
        }
    }

    // =====================================================================================================================
    // = PanelDescriptor
    // =====================================================================================================================
    /** is a helper class for TaskPaneController_Impl, holding the details about a single panel which is not
        contained in the IToolPanel implementation itself.
    */
    struct PanelDescriptor
    {
        ::svt::PToolPanel   pPanel;
        bool                bHidden;

        PanelDescriptor()
            :pPanel()
            ,bHidden( false )
        {
        }

        PanelDescriptor( const ::svt::PToolPanel& i_rPanel )
            :pPanel( i_rPanel )
            ,bHidden( false )
        {
        }
    };

	//==================================================================================================================
	//= TaskPaneController_Impl
	//==================================================================================================================
    class TaskPaneController_Impl   :public ::boost::noncopyable
                                    ,public ::svt::IToolPanelDeckListener
    {
    public:
        TaskPaneController_Impl(
            ModuleTaskPane& i_rTaskPane,
            TitledDockingWindow& i_rDockingWindow
        );
        ~TaskPaneController_Impl();

        void    SetDefaultTitle( const String& i_rTitle );
        void    ActivateToolPanel( const ::rtl::OUString& i_rPanelURL );

    protected:
        // IToolPanelDeckListener overridables
        virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition );
        virtual void PanelRemoved( const size_t i_nPosition );
        virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive );
        virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter );
        virtual void Dying();

    private:
        DECL_LINK( OnToolboxClicked, ToolBox* );
        DECL_LINK( OnMenuItemSelected, Menu* );
        DECL_LINK( DockingChanged, TitledDockingWindow* );
        ::std::auto_ptr< PopupMenu > impl_createPopupMenu() const;

        /// sets the given layout for the panel selector
        void    impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce = false );

        /// returns the current layout of the panel selector
        PanelSelectorLayout
                impl_getLayout() const { return m_eCurrentLayout; }

        void    impl_updateDockingWindowTitle();
        void    impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex );
        size_t  impl_getLogicalPanelIndex( const size_t i_nVisibleIndex );

    private:
        enum MenuId
        {
            MID_UNLOCK_TASK_PANEL = 1,
            MID_LOCK_TASK_PANEL = 2,
            MID_LAYOUT_TABS = 3,
            MID_LAYOUT_DRAWERS = 4,
            MID_FIRST_PANEL = 5
        };

    private:
        typedef ::std::vector< PanelDescriptor >    PanelDescriptors;

        ModuleTaskPane&         m_rTaskPane;
        TitledDockingWindow&    m_rDockingWindow;
        sal_uInt16                  m_nViewMenuID;
        PanelSelectorLayout     m_eCurrentLayout;
        PanelDescriptors        m_aPanelRepository;
        bool                    m_bTogglingPanelVisibility;
        ::rtl::OUString         m_sDefaultTitle;
    };

	//------------------------------------------------------------------------------------------------------------------
    TaskPaneController_Impl::TaskPaneController_Impl( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow )
        :m_rTaskPane( i_rTaskPane )
        ,m_rDockingWindow( i_rDockingWindow )
        ,m_nViewMenuID( 0 )
        ,m_eCurrentLayout( LAYOUT_DRAWERS )
        ,m_aPanelRepository()
        ,m_bTogglingPanelVisibility( false )
        ,m_sDefaultTitle()
    {
        m_rDockingWindow.ResetToolBox();
        m_nViewMenuID = m_rDockingWindow.AddDropDownToolBoxItem(
            String( SfxResId( STR_SFX_TASK_PANE_VIEW ) ),
			HID_TASKPANE_VIEW_MENU,
            LINK( this, TaskPaneController_Impl, OnToolboxClicked )
        );
        m_rDockingWindow.SetEndDockingHdl( LINK( this, TaskPaneController_Impl, DockingChanged ) );
        impl_setLayout(LAYOUT_TABS_RIGHT, true);

        m_rTaskPane.GetPanelDeck().AddListener( *this );

        // initialize the panel repository
        for ( size_t i = 0; i < m_rTaskPane.GetPanelDeck().GetPanelCount(); ++i )
        {
            ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( i ) );
            m_aPanelRepository.push_back( PanelDescriptor( pPanel ) );
        }

        SetDefaultTitle( String( SfxResId( STR_SFX_TASKS ) ) );
    }

	//------------------------------------------------------------------------------------------------------------------
    TaskPaneController_Impl::~TaskPaneController_Impl()
    {
        m_rTaskPane.GetPanelDeck().RemoveListener( *this );

        // remove the panels which are not under the control of the panel deck currently
        for (   PanelDescriptors::iterator panelPos = m_aPanelRepository.begin();
                panelPos != m_aPanelRepository.end();
                ++panelPos
            )
        {
            if ( panelPos->bHidden )
                panelPos->pPanel->Dispose();
        }
        m_aPanelRepository.clear();
    }

    // -----------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::SetDefaultTitle( const String& i_rTitle )
    {
        m_sDefaultTitle = i_rTitle;
        impl_updateDockingWindowTitle();
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
    {
        ::boost::optional< size_t > aPanelPos( m_rTaskPane.GetPanelPos( i_rPanelURL ) );
        ENSURE_OR_RETURN_VOID( !!aPanelPos, "TaskPaneController_Impl::ActivateToolPanel: no such panel!" );

        if ( aPanelPos == m_rTaskPane.GetPanelDeck().GetActivePanel() )
        {
            ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( *aPanelPos ) );
            pPanel->GrabFocus();
        }
        else
        {
            m_rTaskPane.GetPanelDeck().ActivatePanel( aPanelPos );
        }
    }

    // -----------------------------------------------------------------------------------------------------------------
    IMPL_LINK( TaskPaneController_Impl, DockingChanged, TitledDockingWindow*, i_pDockingWindow )
    {
        ENSURE_OR_RETURN( i_pDockingWindow && &m_rDockingWindow, "TaskPaneController_Impl::DockingChanged: where does this come from?", 0L );

        if ( impl_getLayout() == LAYOUT_DRAWERS )
            return 0L;

        impl_setLayout( lcl_getTabLayoutFromAlignment( i_pDockingWindow->GetAlignment() ) );
        return 1L;
    }

    // -----------------------------------------------------------------------------------------------------------------
    IMPL_LINK( TaskPaneController_Impl, OnToolboxClicked, ToolBox*, i_pToolBox )
    {
	    if ( i_pToolBox->GetCurItemId() == m_nViewMenuID )
        {
            i_pToolBox->EndSelection();
            
            ::std::auto_ptr< PopupMenu > pMenu = impl_createPopupMenu();
            pMenu->SetSelectHdl( LINK( this, TaskPaneController_Impl, OnMenuItemSelected ) );

            // pass toolbox button rect so the menu can stay open on button up
            Rectangle aMenuRect( i_pToolBox->GetItemRect( m_nViewMenuID ) );
            aMenuRect.SetPos( i_pToolBox->GetPosPixel() );
            pMenu->Execute( &m_rDockingWindow, aMenuRect, POPUPMENU_EXECUTE_DOWN );
        }

	    return 0;
    }

    // ---------------------------------------------------------------------------------------------------------------------
    IMPL_LINK( TaskPaneController_Impl, OnMenuItemSelected, Menu*, i_pMenu )
    {
        ENSURE_OR_RETURN( i_pMenu, "TaskPaneController_Impl::OnMenuItemSelected: illegal menu!", 0L );

        i_pMenu->Deactivate();
        switch ( i_pMenu->GetCurItemId() )
        {
            case MID_UNLOCK_TASK_PANEL:
                m_rDockingWindow.SetFloatingMode( sal_True );
                break;

            case MID_LOCK_TASK_PANEL:
                m_rDockingWindow.SetFloatingMode( sal_False );
                break;

            case MID_LAYOUT_DRAWERS:
                impl_setLayout( LAYOUT_DRAWERS );
                break;

            case MID_LAYOUT_TABS:
                impl_setLayout( lcl_getTabLayoutFromAlignment( m_rDockingWindow.GetAlignment() ) );
                break;

            default:
            {
                size_t nPanelIndex = size_t( i_pMenu->GetCurItemId() - MID_FIRST_PANEL );
                impl_togglePanelVisibility( nPanelIndex );
            }
            break;
        }

        return 1L;
    }

    // ---------------------------------------------------------------------------------------------------------------------
    size_t TaskPaneController_Impl::impl_getLogicalPanelIndex( const size_t i_nVisibleIndex )
    {
        size_t nLogicalIndex = 0;
        size_t nVisibleIndex( i_nVisibleIndex );
        for ( size_t i=0; i < m_aPanelRepository.size(); ++i )
        {
            if ( !m_aPanelRepository[i].bHidden )
            {
                if ( !nVisibleIndex )
                    break;
                --nVisibleIndex;
            }
            ++nLogicalIndex;
        }
        return nLogicalIndex;
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition )
    {
        if ( m_bTogglingPanelVisibility )
            return;

        const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) );
        m_aPanelRepository.insert( m_aPanelRepository.begin() + nLogicalIndex, PanelDescriptor( i_pPanel ) );
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::PanelRemoved( const size_t i_nPosition )
    {
        if ( m_bTogglingPanelVisibility )
            return;

        const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) );
        m_aPanelRepository.erase( m_aPanelRepository.begin() + nLogicalIndex );
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
    {
        if ( impl_getLayout() == LAYOUT_DRAWERS )
            // no adjustment of the title when we use the classical "drawers" layout
            return;

        impl_updateDockingWindowTitle( );
        (void)i_rOldActive;
        (void)i_rNewActive;
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter )
    {
        // not interested in
        (void)i_rNewLayouter;
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::Dying()
    {
        OSL_ENSURE( false, "TaskPaneController_Impl::Dying: unexpected call!" );
        // We are expected to live longer than the ToolPanelDeck we work with. Since we remove ourself, in our dtor,
        // as listener from the panel deck, this method here should never be called.
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex )
    {
        ENSURE_OR_RETURN_VOID( i_nLogicalPanelIndex < m_aPanelRepository.size(), "illegal index" );

        // get the actual panel index, within the deck
        size_t nActualPanelIndex(0);
        for ( size_t i=0; i < i_nLogicalPanelIndex; ++i )
        {
            if ( !m_aPanelRepository[i].bHidden )
                ++nActualPanelIndex;
        }

        ::boost::optional< size_t > aActivatePanel;

        m_bTogglingPanelVisibility = true;
        if ( m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden )
        {
            OSL_VERIFY( m_rTaskPane.GetPanelDeck().InsertPanel( m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel, nActualPanelIndex ) == nActualPanelIndex );
            // if there has not been an active panel before, activate the newly inserted one
            ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() );
            if ( !aActivePanel )
                aActivatePanel = nActualPanelIndex;
        }
        else
        {
            OSL_VERIFY( m_rTaskPane.GetPanelDeck().RemovePanel( nActualPanelIndex ).get() == m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel.get() );
        }
        m_bTogglingPanelVisibility = false;
        m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden = !m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden;

        if ( !!aActivatePanel )
            m_rTaskPane.GetPanelDeck().ActivatePanel( *aActivatePanel );
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce )
    {
        if ( !i_bForce && ( m_eCurrentLayout == i_eLayout ) )
            return;

        switch ( i_eLayout )
        {
        case LAYOUT_DRAWERS:
            m_rTaskPane.SetDrawersLayout();
            break;
        case LAYOUT_TABS_TOP:
            m_rTaskPane.SetTabsLayout( ::svt::TABS_TOP, ::svt::TABITEM_IMAGE_ONLY );
            break;
        case LAYOUT_TABS_BOTTOM:
            m_rTaskPane.SetTabsLayout( ::svt::TABS_BOTTOM, ::svt::TABITEM_IMAGE_ONLY );
            break;
        case LAYOUT_TABS_LEFT:
            m_rTaskPane.SetTabsLayout( ::svt::TABS_LEFT, ::svt::TABITEM_IMAGE_ONLY );
            break;
        case LAYOUT_TABS_RIGHT:
            m_rTaskPane.SetTabsLayout( ::svt::TABS_RIGHT, ::svt::TABITEM_IMAGE_ONLY );
            break;
        }
        m_eCurrentLayout = i_eLayout;

        impl_updateDockingWindowTitle();
    }

    // ---------------------------------------------------------------------------------------------------------------------
    void TaskPaneController_Impl::impl_updateDockingWindowTitle()
    {
        ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() );
        if ( !aActivePanel || ( impl_getLayout() == LAYOUT_DRAWERS ) )
            m_rDockingWindow.SetTitle( m_sDefaultTitle );
        else
        {
            size_t nNewActive( *aActivePanel );
            for ( size_t i=0; i < m_aPanelRepository.size(); ++i )
            {
                if ( m_aPanelRepository[i].bHidden )
                    continue;

                if ( !nNewActive )
                {
                    m_rDockingWindow.SetTitle( m_aPanelRepository[i].pPanel->GetDisplayName() );
                    break;
                }
                --nNewActive;
            }
        }
    }

    // ---------------------------------------------------------------------------------------------------------------------
    ::std::auto_ptr< PopupMenu > TaskPaneController_Impl::impl_createPopupMenu() const
    {
        ::std::auto_ptr<PopupMenu> pMenu( new PopupMenu );
        FloatingWindow* pMenuWindow = static_cast< FloatingWindow* >( pMenu->GetWindow() );
        if ( pMenuWindow != NULL )
        {
            pMenuWindow->SetPopupModeFlags ( pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE );
        }

        // Add one entry for every tool panel element to individually make
        // them visible or hide them.
        sal_uInt16 nIndex = MID_FIRST_PANEL;
        for ( size_t i=0; i<m_aPanelRepository.size(); ++i, ++nIndex )
        {
            const PanelDescriptor& rPanelDesc( m_aPanelRepository[i] );
            pMenu->InsertItem( nIndex, rPanelDesc.pPanel->GetDisplayName(), MIB_CHECKABLE );
            pMenu->CheckItem( nIndex, !rPanelDesc.bHidden );
        }
        pMenu->InsertSeparator();

    #if OSL_DEBUG_LEVEL > 0
        pMenu->InsertItem( MID_LAYOUT_TABS, String::CreateFromAscii( "Tab-Layout (exp.)" ), MIB_CHECKABLE );
        pMenu->CheckItem( MID_LAYOUT_TABS, impl_getLayout() != LAYOUT_DRAWERS );
        pMenu->InsertItem( MID_LAYOUT_DRAWERS, String::CreateFromAscii( "Drawer-Layout" ), MIB_CHECKABLE );
        pMenu->CheckItem( MID_LAYOUT_DRAWERS, impl_getLayout() == LAYOUT_DRAWERS );

        pMenu->InsertSeparator();
    #endif

        // Add entry for docking or un-docking the tool panel.
        if ( m_rDockingWindow.IsFloatingMode() )
            pMenu->InsertItem(
                MID_LOCK_TASK_PANEL,
                String( SfxResId( STR_SFX_DOCK ) )
            );
        else
            pMenu->InsertItem(
                MID_UNLOCK_TASK_PANEL,
                String( SfxResId( STR_SFX_UNDOCK ) )
            );

        pMenu->RemoveDisabledEntries( sal_False, sal_False );
                
        return pMenu;
    }

	//==================================================================================================================
	//= TaskPaneController
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    TaskPaneController::TaskPaneController( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow )
        :m_pImpl( new TaskPaneController_Impl( i_rTaskPane, i_rDockingWindow ) )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    TaskPaneController::~TaskPaneController()
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneController::SetDefaultTitle( const String& i_rTitle )
    {
        m_pImpl->SetDefaultTitle( i_rTitle );
    }

	//------------------------------------------------------------------------------------------------------------------
    void TaskPaneController::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL )
    {
        m_pImpl->ActivateToolPanel( i_rPanelURL );
    }

//......................................................................................................................
} // namespace sfx2
//......................................................................................................................
