/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

// my own includes
#include <toolbarlayoutmanager.hxx>
#include <helpers.hxx>
#include <services.h>
#include <classes/resource.hrc>
#include <classes/fwkresid.hxx>
#include <uiconfiguration/windowstateconfiguration.hxx>

// interface includes
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/ui/UIElementType.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/ui/XUIElementSettings.hpp>
#include <com/sun/star/ui/XUIFunctionListener.hpp>

// other includes
#include <unotools/cmdoptions.hxx>
#include <toolkit/unohlp.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <vcl/i18nhelp.hxx>
#include <vcl/dockingarea.hxx>
#include <boost/bind.hpp>

using namespace ::com::sun::star;

namespace framework
{

ToolbarLayoutManager::ToolbarLayoutManager( 
    const uno::Reference< lang::XMultiServiceFactory >& xSMGR, 
    const uno::Reference< ui::XUIElementFactory >& xUIElementFactory,
    ILayoutNotifications* pParentLayouter )
    : ThreadHelpBase( &Application::GetSolarMutex() ),
    m_xSMGR( xSMGR ),
    m_xUIElementFactoryManager( xUIElementFactory ),
    m_pParentLayouter( pParentLayouter ),
    m_eDockOperation( DOCKOP_ON_COLROW ),
    m_pAddonOptions( 0 ),
    m_pGlobalSettings( 0 ),
    m_bComponentAttached( false ),
    m_bMustLayout( false ),
    m_bLayoutDirty( false ),
    m_bStoreWindowState( false ),
    m_bGlobalSettings( false ),
    m_bDockingInProgress( false ),
    m_bVisible( true ),
    m_bLayoutInProgress( false ),
    m_bToolbarCreation( false ),
    m_aFullAddonTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )),
    m_aCustomTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "custom_" )),
    m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" )),
    m_aToolbarTypeString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCETYPE_TOOLBAR ))
{
    // initialize rectangles to zero values
    setZeroRectangle( m_aDockingAreaOffsets );
    setZeroRectangle( m_aDockingArea );
    
    // create toolkit object
    m_xToolkit = uno::Reference< awt::XToolkit >( m_xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), uno::UNO_QUERY );
}

ToolbarLayoutManager::~ToolbarLayoutManager()
{
}

//---------------------------------------------------------------------------------------------------------
//  XInterface
//---------------------------------------------------------------------------------------------------------
void SAL_CALL ToolbarLayoutManager::acquire() throw()
{
    OWeakObject::acquire();
}

void SAL_CALL ToolbarLayoutManager::release() throw()
{
    OWeakObject::release();
}

uno::Any SAL_CALL ToolbarLayoutManager::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException )
{
    uno::Any a = ::cppu::queryInterface( rType,
        SAL_STATIC_CAST( awt::XDockableWindowListener*, this ),
        SAL_STATIC_CAST( ui::XUIConfigurationListener*, this ),
        SAL_STATIC_CAST( awt::XWindowListener*,         this ));

    if ( a.hasValue() )
        return a;

    return OWeakObject::queryInterface( rType );
}

void SAL_CALL ToolbarLayoutManager::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
{
    if ( aEvent.Source == m_xFrame )
    {
        // Reset all internal references
        reset();
        implts_destroyDockingAreaWindows();
    }
}

awt::Rectangle ToolbarLayoutManager::getDockingArea()
{
    WriteGuard aWriteLock( m_aLock );
    Rectangle aNewDockingArea( m_aDockingArea );
    aWriteLock.unlock();

    if ( isLayoutDirty() )
        aNewDockingArea = implts_calcDockingArea();
    
    aWriteLock.lock();
    m_aDockingArea = aNewDockingArea;
    aWriteLock.unlock();
    
    return putRectangleValueToAWT(aNewDockingArea);
}

void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea )
{
    WriteGuard aWriteLock( m_aLock );
    m_aDockingArea = putAWTToRectangle( rDockingArea );
    m_bLayoutDirty = true;
    aWriteLock.unlock();
}

void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& rBorderSpace )
{
    ReadGuard aReadLock( m_aLock );
    Rectangle aDockOffsets = m_aDockingAreaOffsets;
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
    uno::Reference< awt::XWindow > xTopDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    uno::Reference< awt::XWindow > xBottomDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
    uno::Reference< awt::XWindow > xLeftDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    uno::Reference< awt::XWindow > xRightDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
    aReadLock.unlock();

    uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
    
    // Convert relativ size to output size.
    awt::Rectangle  aRectangle           = xContainerWindow->getPosSize();
    awt::DeviceInfo aInfo                = xDevice->getInfo();
    awt::Size       aContainerClientSize = awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset  ,
                                                      aRectangle.Height - aInfo.TopInset  - aInfo.BottomInset );
    long aStatusBarHeight                = aDockOffsets.GetHeight();

    sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height );
    if ( rBorderSpace.Y >= 0 )
    {
        // Top docking area window
        xTopDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, awt::PosSize::POSSIZE );
        xTopDockAreaWindow->setVisible( sal_True );
        nLeftRightDockingAreaHeight -= rBorderSpace.Y;
    }

    if ( rBorderSpace.Height >= 0 )
    {
        // Bottom docking area window
        sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarHeight ), sal_Int32( 0 ));
        sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height;

        xBottomDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, awt::PosSize::POSSIZE );
        xBottomDockAreaWindow->setVisible( sal_True );
        nLeftRightDockingAreaHeight -= nHeight;
    }

    nLeftRightDockingAreaHeight -= aStatusBarHeight;
    if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 )
    {
        // Left docking area window
        // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
        sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));

        xLeftDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, awt::PosSize::POSSIZE );
        xLeftDockAreaWindow->setVisible( sal_True );
    }
    if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 )
    {
        // Right docking area window
        // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
        sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width ));
        sal_Int32 nHeight  = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));
        sal_Int32 nWidth   = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width;

        xRightDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, awt::PosSize::POSSIZE );
        xRightDockAreaWindow->setVisible( sal_True );
    }
}

bool ToolbarLayoutManager::isLayoutDirty()
{
    return m_bLayoutDirty;
}

void ToolbarLayoutManager::doLayout(const ::Size& aContainerSize)
{
    WriteGuard aWriteLock( m_aLock );
    bool bLayoutInProgress( m_bLayoutInProgress );
    m_bLayoutInProgress = true;
    awt::Rectangle aDockingArea = putRectangleValueToAWT( m_aDockingArea );
    aWriteLock.unlock();

    if ( bLayoutInProgress )
        return;

    // Retrieve row/column dependent data from all docked user-interface elements
    for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ )
    {
        bool bReverse( isReverseOrderDockingArea( i ));
        std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;

        implts_getDockingAreaElementInfos( (ui::DockingArea)i, aRowColumnsWindowData );

        sal_Int32 nOffset( 0 );
        const sal_uInt32 nCount = aRowColumnsWindowData.size();
        for ( sal_uInt32 j = 0; j < nCount; ++j )
        {
            sal_uInt32 nIndex = bReverse ? nCount-j-1 : j;
            implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[nIndex], aContainerSize );
            nOffset += aRowColumnsWindowData[j].nStaticSize;
        }
    }

    implts_setDockingAreaWindowSizes( aDockingArea );
    
    aWriteLock.lock();
    m_bLayoutDirty      = false;
    m_bLayoutInProgress = false;
    aWriteLock.unlock();
}

bool ToolbarLayoutManager::implts_isParentWindowVisible() const
{
    ReadGuard aReadLock( m_aLock );
    bool bVisible( false );    
    if ( m_xContainerWindow.is() )
        bVisible = m_xContainerWindow->isVisible();

    return bVisible;
}

Rectangle ToolbarLayoutManager::implts_calcDockingArea()
{
    ReadGuard aReadLock( m_aLock );
    UIElementVector aWindowVector( m_aUIElements );
    aReadLock.unlock();

    Rectangle                aBorderSpace;
    sal_Int32                nCurrRowColumn( 0 );
    sal_Int32                nCurrPos( 0 );
    sal_Int32                nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP );
    std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT];
    UIElementVector::const_iterator pConstIter;

    // initialize rectangle with zero values!
    aBorderSpace.setWidth(0);
    aBorderSpace.setHeight(0);

    aRowColumnSizes[nCurrDockingArea].clear();
    aRowColumnSizes[nCurrDockingArea].push_back( 0 );

    for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); pConstIter++ )
    {
        uno::Reference< ui::XUIElement > xUIElement( pConstIter->m_xUIElement, uno::UNO_QUERY );
        if ( xUIElement.is() )
        {
            uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
            uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
            if ( xWindow.is() && xDockWindow.is() )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );

                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow && !xDockWindow->isFloating() && pConstIter->m_bVisible )
                {
                    awt::Rectangle aPosSize = xWindow->getPosSize();
                    if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea )
                    {
                        nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea;
                        nCurrRowColumn   = 0;
                        nCurrPos         = 0;
                        aRowColumnSizes[nCurrDockingArea].clear();
                        aRowColumnSizes[nCurrDockingArea].push_back( 0 );
                    }

                    if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea )
                    {
                        if ( isHorizontalDockingArea( pConstIter->m_aDockedData.m_nDockedArea ))
                        {
                            if ( pConstIter->m_aDockedData.m_aPos.Y() > nCurrPos )
                            {
                                ++nCurrRowColumn;
                                nCurrPos = pConstIter->m_aDockedData.m_aPos.Y();
                                aRowColumnSizes[nCurrDockingArea].push_back( 0 );
                            }

                            if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
                                aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height;
                        }
                        else
                        {
                            if ( pConstIter->m_aDockedData.m_aPos.X() > nCurrPos )
                            {
                                ++nCurrRowColumn;
                                nCurrPos = pConstIter->m_aDockedData.m_aPos.X();
                                aRowColumnSizes[nCurrDockingArea].push_back( 0 );
                            }

                            if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
                                aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width;
                        }
                    }
                }
            }
        }
    }

    // Sum up max heights from every row/column
    if ( !aWindowVector.empty() )
    {
        for ( sal_Int32 i = 0; i <= ui::DockingArea_DOCKINGAREA_RIGHT; i++ )
        {
            sal_Int32 nSize( 0 );
            const sal_uInt32 nCount = aRowColumnSizes[i].size();
            for ( sal_uInt32 j = 0; j < nCount; j++ )
                nSize += aRowColumnSizes[i][j];

            if ( i == ui::DockingArea_DOCKINGAREA_TOP )
                aBorderSpace.Top() = nSize;
            else if ( i == ui::DockingArea_DOCKINGAREA_BOTTOM )
                aBorderSpace.Bottom() = nSize;
            else if ( i == ui::DockingArea_DOCKINGAREA_LEFT )
                aBorderSpace.Left() = nSize;
            else
                aBorderSpace.Right() = nSize;
        }
    }

    return aBorderSpace;
}

void ToolbarLayoutManager::reset()
{    
    WriteGuard aWriteLock( m_aLock );
    uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
    uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
    m_xModuleCfgMgr.clear();
    m_xDocCfgMgr.clear();
    m_bComponentAttached = false;
    aWriteLock.unlock();

    destroyToolbars();
    resetDockingArea();
}

void ToolbarLayoutManager::attach( 
    const uno::Reference< frame::XFrame >& xFrame,
    const uno::Reference< ui::XUIConfigurationManager >& xModuleCfgMgr,
    const uno::Reference< ui::XUIConfigurationManager >& xDocCfgMgr,
    const uno::Reference< container::XNameAccess >& xPersistentWindowState )
{
    // reset toolbar manager if we lose our current frame
    if ( m_xFrame.is() && m_xFrame != xFrame )
        reset();
    
    WriteGuard aWriteLock( m_aLock );
    m_xFrame                 = xFrame;
    m_xModuleCfgMgr          = xModuleCfgMgr;
    m_xDocCfgMgr             = xDocCfgMgr;
    m_xPersistentWindowState = xPersistentWindowState;
    m_bComponentAttached     = true;
}

void ToolbarLayoutManager::createStaticToolbars()
{
    resetDockingArea();
    implts_createCustomToolBars();
    implts_createAddonsToolBars();
    implts_createNonContextSensitiveToolBars();
    implts_sortUIElements();
}

bool ToolbarLayoutManager::requestToolbar( const ::rtl::OUString& rResourceURL )
{
    bool bNotify( false );
    bool bMustCallCreate( false );
    uno::Reference< ui::XUIElement > xUIElement;

    ReadGuard aReadLock( m_aLock );
    uno::Reference< frame::XFrame > xFrame( m_xFrame );
    aReadLock.unlock();
    
    uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame ));
    if ( implts_isPreviewModel( xModel ))
        return false; // no toolbars for preview frame!
    
	UIElement aRequestedToolbar = impl_findToolbar( rResourceURL );
    if ( aRequestedToolbar.m_aName != rResourceURL  )
    {
        bMustCallCreate = true;
        aRequestedToolbar.m_aName      = rResourceURL;
        aRequestedToolbar.m_aType      = m_aToolbarTypeString;
        aRequestedToolbar.m_xUIElement = xUIElement;
        implts_readWindowStateData( rResourceURL, aRequestedToolbar );
    }
    
    xUIElement = aRequestedToolbar.m_xUIElement;
    if ( !xUIElement.is() )
        bMustCallCreate = true;
    
    bool bCreateOrShowToolbar( aRequestedToolbar.m_bVisible & !aRequestedToolbar.m_bMasterHide );
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
    if ( xContainerWindow.is() && aRequestedToolbar.m_bFloating )
        bCreateOrShowToolbar &= bool( xContainerWindow->isActive());
    
    if ( bCreateOrShowToolbar )
        bNotify = ( bMustCallCreate ) ? createToolbar( rResourceURL ) : showToolbar( rResourceURL );
    
    return bNotify;
}

bool ToolbarLayoutManager::createToolbar( const ::rtl::OUString& rResourceURL )
{
    bool bNotify( false );
    uno::Reference< ui::XUIElement > xUITempElement;
    
    implts_createToolBar( rResourceURL, bNotify, xUITempElement );
    return bNotify;
}

bool ToolbarLayoutManager::destroyToolbar( const ::rtl::OUString& rResourceURL )
{
    const rtl::OUString aAddonTbResourceName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ));
    
    UIElementVector::iterator pIter;
    uno::Reference< lang::XComponent > xComponent;

    bool bNotify( false );
    bool bMustBeSorted( false );
    bool bMustLayouted( false );
    bool bMustBeDestroyed( rResourceURL.indexOf( aAddonTbResourceName ) != 0 );
    
    WriteGuard aWriteLock( m_aLock );
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_aName == rResourceURL )
        {
            xComponent.set( pIter->m_xUIElement, uno::UNO_QUERY );
            if ( bMustBeDestroyed )
                pIter->m_xUIElement.clear();
            else
                pIter->m_bVisible = false;
            break;
        }
    }
    aWriteLock.unlock();

    uno::Reference< ui::XUIElement > xUIElement( xComponent, uno::UNO_QUERY );
    if ( xUIElement.is() )
    {
        uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
        uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );

        if ( bMustBeDestroyed )
        {
            try
            {
                if ( xWindow.is() )
                    xWindow->removeWindowListener( uno::Reference< awt::XWindowListener >(
                        static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
            }
            catch( uno::Exception& ) {}

            try
            {
                if ( xDockWindow.is() )
                    xDockWindow->removeDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
                        static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
            }
            catch ( uno::Exception& ) {}
        }
        else
        {
            if ( xWindow.is() )
                xWindow->setVisible( sal_False );
            bNotify = true;
        }

        if ( !xDockWindow->isFloating() )
            bMustLayouted = true;
        bMustBeSorted = true;
    }
    
    if ( bMustBeDestroyed )
    {
        if ( xComponent.is() )
            xComponent->dispose();
        bNotify = true;
    }

    if ( bMustLayouted )
         implts_setLayoutDirty();
    
    if ( bMustBeSorted )
        implts_sortUIElements();

    return bNotify;
}

void ToolbarLayoutManager::destroyToolbars()
{
    UIElementVector aUIElementVector;
    implts_getUIElementVectorCopy( aUIElementVector );

    WriteGuard aWriteLock( m_aLock );
    m_aUIElements.clear();
    m_bLayoutDirty = true;
    aWriteLock.unlock();

    UIElementVector::iterator pIter;
    for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
    {
        uno::Reference< lang::XComponent > xComponent( pIter->m_xUIElement, uno::UNO_QUERY );
        if ( xComponent.is() )
            xComponent->dispose();
    }
}

bool ToolbarLayoutManager::showToolbar( const ::rtl::OUString& rResourceURL )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    
    vos::OGuard aGuard( Application::GetSolarMutex() );
    Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
    if ( pWindow )
    {
        if ( !aUIElement.m_bFloating )
            implts_setLayoutDirty();
        else
            pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
        
        aUIElement.m_bVisible = true;
        implts_writeWindowStateData( aUIElement );
        implts_setToolbar( aUIElement );
        return true;
    }
    
    return false;
}

bool ToolbarLayoutManager::hideToolbar( const ::rtl::OUString& rResourceURL )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );

    vos::OGuard aGuard( Application::GetSolarMutex() );
    Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
    if ( pWindow )
    {
        pWindow->Show( sal_False );
        if ( !aUIElement.m_bFloating )
            implts_setLayoutDirty();
        
        aUIElement.m_bVisible = false;
        implts_writeWindowStateData( aUIElement );
        implts_setToolbar( aUIElement );
        return true;
    }

    return false;
}

void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars )
{
    UIElementVector aUIElementVector;

    ReadGuard aReadLock( m_aLock );
    bool bVisible( m_bVisible );
    aReadLock.unlock();

    if ( !bVisible || !bAutomaticToolbars )
        return;

    implts_getUIElementVectorCopy( aUIElementVector );
    
    UIElement aUIElement;
    vos::OGuard aGuard( Application::GetSolarMutex() );
    UIElementVector::iterator pIter;
    for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
    {
        if ( implts_readWindowStateData( pIter->m_aName, aUIElement ) &&
             ( pIter->m_bVisible != aUIElement.m_bVisible ) && !pIter->m_bMasterHide )
        {
            WriteGuard aWriteLock( m_aLock );
            UIElement& rUIElement = impl_findToolbar( pIter->m_aName );
            if ( rUIElement.m_aName == pIter->m_aName )
            {
                rUIElement.m_bVisible = aUIElement.m_bVisible;
                implts_setLayoutDirty();
            }
        }
    }
}

void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible )
{
    UIElementVector aUIElementVector;
    implts_getUIElementVectorCopy( aUIElementVector );

    vos::OGuard aGuard( Application::GetSolarMutex() );
    UIElementVector::iterator pIter;
    for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
    {
        Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
        if ( pWindow && pIter->m_bFloating )
        {
            if ( bVisible )
            {    
                if ( pIter->m_bVisible && !pIter->m_bMasterHide )
                    pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
            }
            else
                pWindow->Show( sal_False );
        }            
    }
}

void ToolbarLayoutManager::setVisible( bool bVisible )
{
    UIElementVector aUIElementVector;
    implts_getUIElementVectorCopy( aUIElementVector );
    
    vos::OGuard aGuard( Application::GetSolarMutex() );
    UIElementVector::iterator pIter;
    for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
    {
        pIter->m_bMasterHide = !bVisible;
        Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
        if ( pWindow )
        {
            bool bSetVisible( pIter->m_bVisible & bVisible );
            if ( !bSetVisible )
                pWindow->Hide();
            else
            {
                if ( pIter->m_bFloating )
                    pWindow->Show(true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
                else
                    implts_setLayoutDirty();
            }
        }
    }
        
    if ( !bVisible )
        resetDockingArea();
}

bool ToolbarLayoutManager::dockToolbar( const ::rtl::OUString& rResourceURL, ui::DockingArea eDockingArea, const awt::Point& aPos )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );

    if ( aUIElement.m_xUIElement.is() )
    {
        try
        {
            uno::Reference< awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
            if ( xDockWindow.is() )
            {
                if ( eDockingArea != ui::DockingArea_DOCKINGAREA_DEFAULT )
                    aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );

                if ( !isDefaultPos( aPos ))
                    aUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y );

                if ( !xDockWindow->isFloating() )
                {
                    Window*  pWindow( 0 );
                    ToolBox* pToolBox( 0 );

                    {
                        vos::OGuard aGuard( Application::GetSolarMutex() );
                        pWindow = VCLUnoHelper::GetWindow( xWindow );
                        if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
                        {
                            pToolBox = (ToolBox *)pWindow;

                            // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a
                            // horizontal to a vertical docking area!
                            pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ));
                        }
                    }

                    if ( hasDefaultPosValue( aUIElement.m_aDockedData.m_aPos ))
                    {
                        // Docking on its default position without a preset position -
                        // we have to find a good place for it.
                        ::Size aSize;

                        vos::OGuard aGuard( Application::GetSolarMutex() );
                        {
                            if ( pToolBox )
                                aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) );
                            else
                                aSize = pWindow->GetSizePixel();
                        }

                        ::Point aPixelPos;
                        ::Point aDockPos;
                        implts_findNextDockingPos((ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
                        aUIElement.m_aDockedData.m_aPos = aDockPos;
                    }
                }

                implts_setToolbar( aUIElement );

                if ( xDockWindow->isFloating() )
                {
                    // ATTENTION: This will call toggleFloatingMode() via notifications which 
                    // sets the floating member of the UIElement correctly!
                    xDockWindow->setFloatingMode( sal_False );
                }
                else
                {
                    implts_writeWindowStateData( aUIElement );
                    implts_sortUIElements();

                    if ( aUIElement.m_bVisible )
                        implts_setLayoutDirty();
                }
                return true;
            }
        }
        catch ( lang::DisposedException& ) {}
    }

    return false;
}

bool ToolbarLayoutManager::dockAllToolbars()
{
    std::vector< ::rtl::OUString > aToolBarNameVector;

    ::rtl::OUString aElementType;
    ::rtl::OUString aElementName;

    ReadGuard aReadLock( m_aLock );
    UIElementVector::iterator pIter;
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_aType.equalsAscii( "toolbar" ) && pIter->m_xUIElement.is() &&
             pIter->m_bFloating && pIter->m_bVisible )
            aToolBarNameVector.push_back( pIter->m_aName );
    }
    aReadLock.unlock();

    bool bResult(true);
    const sal_uInt32 nCount = aToolBarNameVector.size();
    for ( sal_uInt32 i = 0; i < nCount; ++i )
    {
        awt::Point aPoint;
        aPoint.X = aPoint.Y = SAL_MAX_INT32;
        bResult &= dockToolbar( aToolBarNameVector[i], ui::DockingArea_DOCKINGAREA_DEFAULT, aPoint );
    }

    return bResult;
}

long ToolbarLayoutManager::childWindowEvent( VclSimpleEvent* pEvent )
{
    // To enable toolbar controllers to change their image when a sub-toolbar function
    // is activated, we need this mechanism. We have NO connection between these toolbars
    // anymore!
    if ( pEvent && pEvent->ISA( VclWindowEvent ))
    {
        if ( pEvent->GetId() == VCLEVENT_TOOLBOX_SELECT )
        {
            ::rtl::OUString aToolbarName;
            ::rtl::OUString aCommand;
            ToolBox*        pToolBox = getToolboxPtr( ((VclWindowEvent*)pEvent)->GetWindow() );
            
            if ( pToolBox )
            {
                aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
                sal_uInt16 nId = pToolBox->GetCurItemId();
                if ( nId > 0 )
                    aCommand = pToolBox->GetItemCommand( nId );
            }

            if (( aToolbarName.getLength() > 0 ) && ( aCommand.getLength() > 0 ))
            {
                ReadGuard aReadLock( m_aLock );
                ::std::vector< uno::Reference< ui::XUIFunctionListener > > aListenerArray;
                UIElementVector::iterator pIter;

                for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
                {
                    if ( pIter->m_xUIElement.is() )
                    {
                        uno::Reference< ui::XUIFunctionListener > xListener( pIter->m_xUIElement, uno::UNO_QUERY );
                        if ( xListener.is() )
                            aListenerArray.push_back( xListener );
                    }
                }
                aReadLock.unlock();

                const sal_uInt32 nCount = aListenerArray.size();
                for ( sal_uInt32 i = 0; i < nCount; ++i )
                {
                    try { aListenerArray[i]->functionExecute( aToolbarName, aCommand ); }
                    catch ( uno::RuntimeException& ) { throw; }
                    catch ( uno::Exception& ) {}
                }
            }
        }
        else if ( pEvent->GetId() == VCLEVENT_TOOLBOX_FORMATCHANGED )
        {
            if ( !implts_isToolbarCreationActive() )
            {    
                ToolBox* pToolBox = getToolboxPtr( ((VclWindowEvent*)pEvent)->GetWindow() );
                if ( pToolBox )
                {
                    ::rtl::OUString aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
                    if ( aToolbarName.getLength() > 0 )
                    {
                        ::rtl::OUStringBuffer aBuf(100);
                        aBuf.appendAscii( "private:resource/toolbar/" );
                        aBuf.append( aToolbarName );

                        UIElement aToolbar = implts_findToolbar( aBuf.makeStringAndClear() );
                        if ( aToolbar.m_xUIElement.is() && !aToolbar.m_bFloating )
                        {
                            implts_setLayoutDirty();                    
                            m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
                        }
                    }
                }
            }
        }
    }

    return 1;
}

void ToolbarLayoutManager::resetDockingArea()
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
    uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
    aReadLock.unlock();
    
    if ( xTopDockingWindow.is() )
        xTopDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
    if ( xLeftDockingWindow.is() )
        xLeftDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
    if ( xRightDockingWindow.is() )
        xRightDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
    if ( xBottomDockingWindow.is() )
        xBottomDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
}

void ToolbarLayoutManager::setParentWindow( 
    const uno::Reference< awt::XWindowPeer >& xParentWindow )
{
    static const char DOCKINGAREASTRING[] = "dockingarea";

    uno::Reference< awt::XWindow > xTopDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
    uno::Reference< awt::XWindow > xLeftDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
    uno::Reference< awt::XWindow > xRightDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
    uno::Reference< awt::XWindow > xBottomDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
    
    WriteGuard aWriteLock( m_aLock );
    m_xContainerWindow = uno::Reference< awt::XWindow2 >( xParentWindow, uno::UNO_QUERY );    
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]    = xTopDockWindow;
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]   = xLeftDockWindow;
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT]  = xRightDockWindow;
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockWindow;
    aWriteLock.unlock();

    if ( xParentWindow.is() )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        ::DockingAreaWindow* pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ) );
        if( pWindow ) pWindow->SetAlign( WINDOWALIGN_TOP );
        pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ) );
            if( pWindow ) pWindow->SetAlign( WINDOWALIGN_BOTTOM );
        pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ) );
            if( pWindow ) pWindow->SetAlign( WINDOWALIGN_LEFT );
        pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ) );
            if( pWindow ) pWindow->SetAlign( WINDOWALIGN_RIGHT );
        implts_reparentToolbars();
    }
    else
    {
        destroyToolbars();
        resetDockingArea();
    }
}

void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle aOffsets )
{
    WriteGuard aWriteLock( m_aLock );
    m_aDockingAreaOffsets = aOffsets;
    m_bLayoutDirty        = true;
}

rtl::OUString ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const
{
    String aAddonGenericTitle;

    aAddonGenericTitle = String( FwkResId( STR_TOOLBAR_TITLE_ADDON ));
    const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();

    String aNumStr = rI18nHelper.GetNum( nNumber, 0, sal_False, sal_False );
    aAddonGenericTitle.SearchAndReplaceAscii( "%num%", aNumStr );

    return rtl::OUString( aAddonGenericTitle );
}

void ToolbarLayoutManager::implts_createAddonsToolBars()
{
    WriteGuard aWriteLock( m_aLock );
    if ( !m_pAddonOptions )
        m_pAddonOptions = new AddonsOptions;

    uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
    uno::Reference< frame::XFrame > xFrame( m_xFrame );
    aWriteLock.unlock();

    uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame ));
    if ( implts_isPreviewModel( xModel ))
        return; // no addon toolbars for preview frame!

    UIElementVector aUIElementVector;
    uno::Sequence< uno::Sequence< beans::PropertyValue > > aAddonToolBarData;
    uno::Reference< ui::XUIElement >                       xUIElement;

    sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount();
    ::rtl::OUString aAddonsToolBarStaticName( m_aFullAddonTbxPrefix );
    ::rtl::OUString aElementType( RTL_CONSTASCII_USTRINGPARAM( "toolbar" ));

    uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
    aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
    aPropSeq[0].Value <<= xFrame;
    aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
    for ( sal_uInt32 i = 0; i < nCount; i++ )
    {
        ::rtl::OUString aAddonToolBarName( aAddonsToolBarStaticName + m_pAddonOptions->GetAddonsToolbarResourceName(i) );
        aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i );
        aPropSeq[1].Value <<= aAddonToolBarData;

        UIElement aElement = implts_findToolbar( aAddonToolBarName );

        // #i79828
        // It's now possible that we are called more than once. Be sure to not create
        // add-on toolbars more than once!
        if ( aElement.m_xUIElement.is() )
            continue;

        try
        {
            xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq );
            if ( xUIElement.is() )
            {
                uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
                if ( xDockWindow.is() )
                {
                    try
                    {
                        xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
                        xDockWindow->enableDocking( sal_True );
                        uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
                        if ( xWindow.is() )
                            xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
                    }
                    catch ( uno::Exception& ) {}
                }

                ::rtl::OUString aAddonUIName = m_pAddonOptions->GetAddonsToolbarUIName( i );
                const bool bAddonUIName = aAddonUIName.getLength();
                ::rtl::OUString aAddonTitle = bAddonUIName ?
                    aAddonUIName : implts_generateGenericAddonToolbarTitle( i+1 );

                if ( aElement.m_aName.getLength() > 0 )
                {
                    // Reuse a local entry so we are able to use the latest
                    // UI changes for this document.
                    implts_setElementData( aElement, xDockWindow );
                    aElement.m_xUIElement = xUIElement;
                    if ( aElement.m_aUIName.getLength() == 0 && !bAddonUIName)
                    {
                        aElement.m_aUIName = aAddonTitle;
                        implts_writeWindowStateData( aElement );
                    }
                }
                else
                {
                    // Create new UI element and try to read its state data
                    UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement );
                    aNewToolbar.m_bFloating = true;
                    implts_readWindowStateData( aAddonToolBarName, aNewToolbar );
                    implts_setElementData( aNewToolbar, xDockWindow );
                    if ( aNewToolbar.m_aUIName.getLength() == 0 && !bAddonUIName)
                    {
                        aNewToolbar.m_aUIName = aAddonTitle;
                        implts_writeWindowStateData( aNewToolbar );
                    }
                    implts_insertToolbar( aNewToolbar );
                }

                uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
                if ( xWindow.is() )
                {
                    // Set generic title for add-on toolbar
                    vos::OGuard aGuard( Application::GetSolarMutex() );
                    Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                    if ( pWindow->GetText().Len() == 0 )
                        pWindow->SetText( aAddonTitle );
                    if ( pWindow->GetType() == WINDOW_TOOLBOX )
                    {
                        ToolBox* pToolbar = (ToolBox *)pWindow;
                        pToolbar->SetMenuType();
                    }
                }
            }
        }
        catch ( container::NoSuchElementException& ) {}
        catch ( lang::IllegalArgumentException& ) {}
    }
}

void ToolbarLayoutManager::implts_createCustomToolBars()
{
    ReadGuard aReadLock( m_aLock );
    if ( !m_bComponentAttached )
        return;

    uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
    uno::Reference< frame::XFrame > xFrame( m_xFrame );
    uno::Reference< frame::XModel > xModel;
    uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, uno::UNO_QUERY );
    uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, uno::UNO_QUERY );
    aReadLock.unlock();

    if ( xFrame.is() )
    {
        xModel = impl_getModelFromFrame( xFrame );
        if ( implts_isPreviewModel( xModel ))
            return; // no custom toolbars for preview frame!

        uno::Sequence< uno::Sequence< beans::PropertyValue > > aTbxSeq;
        if ( xDocCfgMgr.is() )
        {
            aTbxSeq = xDocCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
            implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars
        }
        if ( xModuleCfgMgr.is() )
        {
            aTbxSeq = xModuleCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
            implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars
        }
    }
}

void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars()
{
    ReadGuard aReadLock( m_aLock );

    if ( !m_xPersistentWindowState.is() || !m_xFrame.is() || !m_bComponentAttached )
        return;

    uno::Reference< frame::XFrame >          xFrame( m_xFrame );
    uno::Reference< ui::XUIElementFactory >  xUIElementFactory( m_xUIElementFactoryManager );
    uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
    aReadLock.unlock();

    if ( implts_isPreviewModel( impl_getModelFromFrame( xFrame )))
        return;

    std::vector< rtl::OUString > aMakeVisibleToolbars;

    try
    {
        uno::Sequence< ::rtl::OUString > aToolbarNames = xPersistentWindowState->getElementNames();

        if ( aToolbarNames.getLength() > 0 )
        {
            ::rtl::OUString aElementType;
            ::rtl::OUString aElementName;
            ::rtl::OUString aName;

            uno::Reference< ui::XUIElement > xUIElement;
            aMakeVisibleToolbars.reserve(aToolbarNames.getLength());

            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
            WriteGuard aWriteLock( m_aLock );

            const rtl::OUString* pTbNames = aToolbarNames.getConstArray();
            for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ )
            {
                aName = pTbNames[i];
                parseResourceURL( aName, aElementType, aElementName );
                
                // Check that we only create:
                // - Toolbars (the statusbar is also member of the persistent window state)
                // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars)
                if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && aElementName.indexOf( m_aCustomTbxPrefix ) == -1 )
                {
                    UIElement aNewToolbar = implts_findToolbar( aName );
                    bool bFound = ( aNewToolbar.m_aName == aName );
                    if ( !bFound )
                        implts_readWindowStateData( aName, aNewToolbar );

                    if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive )
                    {
                        if ( !bFound )
                            implts_insertToolbar( aNewToolbar );
                        aMakeVisibleToolbars.push_back( aName );
                    }
                }
            }
            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
        }
    }
    catch ( uno::RuntimeException& ) { throw; }
    catch ( uno::Exception& ) {}

    if ( !aMakeVisibleToolbars.empty() )
        ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),::boost::bind( &ToolbarLayoutManager::requestToolbar, this,_1 ));
}

void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence< uno::Sequence< beans::PropertyValue > >& aTbxSeqSeq )
{
    const uno::Sequence< beans::PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray();
    for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ )
    {
        const uno::Sequence< beans::PropertyValue >& rTbxSeq = pTbxSeq[i];
        ::rtl::OUString aTbxResName;
        ::rtl::OUString aTbxTitle;
        for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ )
        {
            if ( rTbxSeq[j].Name.equalsAscii( "ResourceURL" ))
                rTbxSeq[j].Value >>= aTbxResName;
            else if ( rTbxSeq[j].Name.equalsAscii( "UIName" ))
                rTbxSeq[j].Value >>= aTbxTitle;
        }

        // Only create custom toolbars. Their name have to start with "custom_"!
        if ( aTbxResName.getLength() > 0 && aTbxResName.indexOf( m_aCustomTbxPrefix ) != -1 )
            implts_createCustomToolBar( aTbxResName, aTbxTitle );
    }
}

void ToolbarLayoutManager::implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle )
{
    if ( aTbxResName.getLength() > 0 )
    {
        bool bNotify( false );
        uno::Reference< ui::XUIElement > xUIElement;
        implts_createToolBar( aTbxResName, bNotify, xUIElement );
        
        if ( !aTitle.isEmpty() && xUIElement.is() )
        {
            vos::OGuard aGuard( Application::GetSolarMutex() );

            Window* pWindow = getWindowFromXUIElement( xUIElement );
            if ( pWindow  )
                pWindow->SetText( aTitle );
        }
    }
}

void ToolbarLayoutManager::implts_reparentToolbars()
{
    WriteGuard aWriteLock( m_aLock );
    UIElementVector aUIElementVector = m_aUIElements;
    Window* pContainerWindow  = VCLUnoHelper::GetWindow( m_xContainerWindow );
    Window* pTopDockWindow    = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    Window* pBottomDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
    Window* pLeftDockWindow   = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    Window* pRightDockWindow  = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
    aWriteLock.unlock();

    vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( pContainerWindow )
    {
        UIElementVector::iterator pIter;
        for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
        {
            uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
            if ( xUIElement.is() )
            {
                uno::Reference< awt::XWindow > xWindow;
                try
                {
                    // We have to retreive the window reference with try/catch as it is
                    // possible that all elements have been disposed!
                    xWindow = uno::Reference< awt::XWindow >( xUIElement->getRealInterface(), uno::UNO_QUERY );
                }
                catch ( uno::RuntimeException& ) { throw; }
                catch ( uno::Exception& ) {}

                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow )
                {
                    // Reparent our child windows acording to their current state.
                    if ( pIter->m_bFloating )
                        pWindow->SetParent( pContainerWindow );
                    else
                    {
                        if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
                            pWindow->SetParent( pTopDockWindow );
                        else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
                            pWindow->SetParent( pBottomDockWindow );
                        else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
                            pWindow->SetParent( pLeftDockWindow );
                        else
                            pWindow->SetParent( pRightDockWindow );
                    }
                }
            }
        }
    }
}

void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart )
{
    WriteGuard aWriteLock( m_aLock );
    m_bToolbarCreation = bStart;
}

bool ToolbarLayoutManager::implts_isToolbarCreationActive()
{
    ReadGuard aReadLock( m_aLock );
    return m_bToolbarCreation;
}

void ToolbarLayoutManager::implts_createToolBar( const ::rtl::OUString& aName, bool& bNotify, uno::Reference< ui::XUIElement >& rUIElement )
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< frame::XFrame > xFrame( m_xFrame );
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
    aReadLock.unlock();

    bNotify = false;
    
    if ( !xFrame.is() || !xContainerWindow.is() )
        return;

    UIElement aToolbarElement = implts_findToolbar( aName );
    if ( !aToolbarElement.m_xUIElement.is()  )
    {
        uno::Reference< ui::XUIElement > xUIElement = implts_createElement( aName );

        bool bVisible( false );
        bool bFloating( false );
        if ( xUIElement.is() )
        {
            rUIElement = xUIElement;
            
            uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
            uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
            if ( xDockWindow.is() && xWindow.is() )
            {
                try
                {
                    xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
                        static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
                    xWindow->addWindowListener( uno::Reference< awt::XWindowListener >(
                        static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
                    xDockWindow->enableDocking( sal_True );
                }
                catch ( uno::Exception& ) {}
            }

            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
            WriteGuard aWriteLock( m_aLock );

            UIElement& rElement = impl_findToolbar( aName );
            if ( rElement.m_aName.getLength() > 0 )
            {
                // Reuse a local entry so we are able to use the latest
                // UI changes for this document.
                implts_setElementData( rElement, xDockWindow );
                rElement.m_xUIElement = xUIElement;
                bVisible = rElement.m_bVisible;
                bFloating = rElement.m_bFloating;
            }
            else
            {
                // Create new UI element and try to read its state data
                UIElement aNewToolbar( aName, m_aToolbarTypeString, xUIElement );
                implts_readWindowStateData( aName, aNewToolbar );
                implts_setElementData( aNewToolbar, xDockWindow );
                implts_insertToolbar( aNewToolbar );
                bVisible = aNewToolbar.m_bVisible;
                bFloating = rElement.m_bFloating;
            }
            aWriteLock.unlock();
            /* SAFE AREA ----------------------------------------------------------------------------------------------- */

            // set toolbar menu style according to customize command state
            SvtCommandOptions aCmdOptions;

            vos::OGuard aGuard( Application::GetSolarMutex() );
            Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
            if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
            {
                ToolBox* pToolbar = (ToolBox *)pWindow;
                sal_uInt16 nMenuType = pToolbar->GetMenuType();
                if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, m_aCustomizeCmd ))
                    pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE );
                else
                    pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE );
            }
            bNotify = true;
            
            implts_sortUIElements();

            if ( bVisible && !bFloating )
                implts_setLayoutDirty();
        }
    }
}

uno::Reference< ui::XUIElement > ToolbarLayoutManager::implts_createElement( const ::rtl::OUString& aName )
{
    uno::Reference< ui::XUIElement > xUIElement;

    ReadGuard aReadLock( m_aLock );
    uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
    aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
    aPropSeq[0].Value <<= m_xFrame;
    aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ));
    aPropSeq[1].Value <<= true;
    uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
    aReadLock.unlock();

    implts_setToolbarCreation( true );
    try
    {
        if ( xUIElementFactory.is() )
            xUIElement = xUIElementFactory->createUIElement( aName, aPropSeq );
    }
    catch ( container::NoSuchElementException& ) {}
    catch ( lang::IllegalArgumentException& ) {}
    implts_setToolbarCreation( false );

    return xUIElement;
}

void ToolbarLayoutManager::implts_setElementData( UIElement& rElement, const uno::Reference< awt::XDockableWindow >& rDockWindow )
{
    ReadGuard aReadLock( m_aLock );
    bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && implts_isParentWindowVisible() );
    aReadLock.unlock();

    uno::Reference< awt::XDockableWindow > xDockWindow( rDockWindow );
    uno::Reference< awt::XWindow2 >        xWindow( xDockWindow, uno::UNO_QUERY );

    Window*  pWindow( 0 );
    ToolBox* pToolBox( 0 );

    if ( xDockWindow.is() && xWindow.is() )
    {
        {
            vos::OGuard aGuard( Application::GetSolarMutex() );
            pWindow = VCLUnoHelper::GetWindow( xWindow );
            if ( pWindow )
            {
                String aText = pWindow->GetText();
                if ( aText.Len() == 0 )
                    pWindow->SetText( rElement.m_aUIName );
                if ( rElement.m_bNoClose )
                    pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE );
                if ( pWindow->GetType() == WINDOW_TOOLBOX )
                    pToolBox = (ToolBox *)pWindow;
            }
            if ( pToolBox )
            {
                if (( rElement.m_nStyle < 0 ) || ( rElement.m_nStyle > BUTTON_SYMBOLTEXT ))
                    rElement.m_nStyle = BUTTON_SYMBOL;
                pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle );
                if ( rElement.m_bNoClose )
                    pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
            }
        }

        if ( rElement.m_bFloating )
        {
            if ( pWindow )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                String aText = pWindow->GetText();
                if ( aText.Len() == 0 )
                    pWindow->SetText( rElement.m_aUIName );
            }

            ::Point  aPos( rElement.m_aFloatingData.m_aPos.X(),
                           rElement.m_aFloatingData.m_aPos.Y() );
            bool bWriteData( false );
            bool bUndefPos = hasDefaultPosValue( rElement.m_aFloatingData.m_aPos );
            bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width() != 0 &&
                              rElement.m_aFloatingData.m_aSize.Height() != 0 );
            xDockWindow->setFloatingMode( sal_True );
            if ( bUndefPos )
            {
                aPos = implts_findNextCascadeFloatingPos();
                rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position
                bWriteData = true;
            }

            if( bSetSize )
                xWindow->setOutputSize( AWTSize( rElement.m_aFloatingData.m_aSize ) );
            else
            {
                if( pToolBox )
                {
                    // set an optimal initial floating size
                    vos::OGuard aGuard( Application::GetSolarMutex() );
                    ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() );
                    pToolBox->SetOutputSizePixel( aSize );
                }
            }

            // #i60882# IMPORTANT: Set position after size as it is
            // possible that we position some part of the toolbar
            // outside of the desktop. A default constructed toolbar
            // always has one line. Now VCL automatically
            // position the toolbar back into the desktop. Therefore
            // we resize the toolbar with the new (wrong) position.
            // To fix this problem we have to set the size BEFORE the
            // position.
            xWindow->setPosSize( aPos.X(), aPos.Y(), 0, 0, awt::PosSize::POS );

            if ( bWriteData )
                implts_writeWindowStateData( rElement );
            if ( bShowElement && pWindow )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
            }
        }
        else
        {
            bool    bSetSize( false );
            ::Point aDockPos;
            ::Point aPixelPos;
            ::Size  aSize;

            if ( pToolBox )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea )  );
                pToolBox->SetLineCount( 1 );
                xDockWindow->setFloatingMode( sal_False );
                if ( rElement.m_aDockedData.m_bLocked )
                    xDockWindow->lock();
                aSize = pToolBox->CalcWindowSizePixel();
                bSetSize = true;

                if ( isDefaultPos( rElement.m_aDockedData.m_aPos ))
                {
                    implts_findNextDockingPos( (ui::DockingArea)rElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
                    rElement.m_aDockedData.m_aPos = aDockPos;
                }
            }

            xWindow->setPosSize( aPixelPos.X(), aPixelPos.Y(), 0, 0, awt::PosSize::POS );
            if( bSetSize )
                xWindow->setOutputSize( AWTSize( aSize) );

            if ( pWindow )
            {            
                vos::OGuard aGuard( Application::GetSolarMutex() );
                if ( !bShowElement )
                    pWindow->Hide();
            }
        }
    }
}

void ToolbarLayoutManager::implts_destroyDockingAreaWindows()
{
    WriteGuard aWriteLock( m_aLock );
    uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
    uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP].clear();
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT].clear();
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT].clear();
    m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM].clear();
    aWriteLock.unlock();

    // destroy windows
    xTopDockingWindow->dispose();
    xLeftDockingWindow->dispose();
    xRightDockingWindow->dispose();
    xBottomDockingWindow->dispose();
}

//---------------------------------------------------------------------------------------------------------
// persistence methods
//---------------------------------------------------------------------------------------------------------

sal_Bool ToolbarLayoutManager::implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData )
{
    WriteGuard aWriteLock( m_aLock );
    uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
    bool bGetSettingsState( false );
    aWriteLock.unlock();

    if ( xPersistentWindowState.is() )
    {
        aWriteLock.lock();
        bool bGlobalSettings( m_bGlobalSettings );
        GlobalSettings* pGlobalSettings( 0 );
        if ( m_pGlobalSettings == 0 )
        {
            m_pGlobalSettings = new GlobalSettings( m_xSMGR );
            bGetSettingsState = true;
        }
        pGlobalSettings = m_pGlobalSettings;
        aWriteLock.unlock();

        try
        {
            uno::Sequence< beans::PropertyValue > aWindowState;
            if ( xPersistentWindowState->getByName( aName ) >>= aWindowState )
            {
                sal_Bool bValue( sal_False );
                for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
                {
                    if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKED ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bFloating = !bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bVisible = bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA ))
                    {
                        ui::DockingArea eDockingArea;
                        if ( aWindowState[n].Value >>= eDockingArea )
                            rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS ))
                    {
                        awt::Point aPoint;
                        if ( aWindowState[n].Value >>= aPoint )
                        {
                            rElementData.m_aDockedData.m_aPos.X() = aPoint.X;
                            rElementData.m_aDockedData.m_aPos.Y() = aPoint.Y;
                        }
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_POS ))
                    {
                        awt::Point aPoint;
                        if ( aWindowState[n].Value >>= aPoint )
                        {
                            rElementData.m_aFloatingData.m_aPos.X() = aPoint.X;
                            rElementData.m_aFloatingData.m_aPos.Y() = aPoint.Y;
                        }
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SIZE ))
                    {
                        awt::Size aSize;
                        if ( aWindowState[n].Value >>= aSize )
                        {
                            rElementData.m_aFloatingData.m_aSize.Width() = aSize.Width;
                            rElementData.m_aFloatingData.m_aSize.Height() = aSize.Height;
                        }
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME ))
                        aWindowState[n].Value >>= rElementData.m_aUIName;
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_STYLE ))
                    {
                        sal_Int32 nStyle = 0;
                        if ( aWindowState[n].Value >>= nStyle )
                            rElementData.m_nStyle = sal_Int16( nStyle );
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_LOCKED ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_aDockedData.m_bLocked = bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bContextSensitive = bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_NOCLOSE ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bNoClose = bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXTACTIVE ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bContextActive = bValue;
                    }
                    else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SOFTCLOSE ))
                    {
                        if ( aWindowState[n].Value >>= bValue )
                            rElementData.m_bSoftClose = bValue;
                    }
                }
            }

            // oversteer values with global settings
            if ( pGlobalSettings && ( bGetSettingsState || bGlobalSettings ))
            {
                if ( pGlobalSettings->HasStatesInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR ))
                {
                    WriteGuard aWriteLock2( m_aLock );
                    m_bGlobalSettings = true;
                    aWriteLock2.unlock();

                    uno::Any aValue;
                    sal_Bool bValue = sal_Bool();
                    if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
                                                        GlobalSettings::STATEINFO_LOCKED,
                                                        aValue ))
                        aValue >>= rElementData.m_aDockedData.m_bLocked;
                    if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
                                                        GlobalSettings::STATEINFO_DOCKED,
                                                        aValue ))
                    {
                        if ( aValue >>= bValue )
                            rElementData.m_bFloating = !bValue;
                    }
                }
            }

            return sal_True;
        }
        catch ( container::NoSuchElementException& ) {}
    }

    return sal_False;
}

void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement& rElementData )
{
    WriteGuard aWriteLock( m_aLock );
    uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
    m_bStoreWindowState = true; // set flag to determine that we triggered the notification
    aWriteLock.unlock();

    bool bPersistent( sal_False );
    uno::Reference< beans::XPropertySet > xPropSet( rElementData.m_xUIElement, uno::UNO_QUERY );
    if ( xPropSet.is() )
    {
        try
        {
            // Check persistent flag of the user interface element
            xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ))) >>= bPersistent;
        }
        catch ( beans::UnknownPropertyException )
        {
            bPersistent = true; // Non-configurable elements should at least store their dimension/position
        }
        catch ( lang::WrappedTargetException ) {}
    }

    if ( bPersistent && xPersistentWindowState.is() )
    {
        try
        {
            uno::Sequence< beans::PropertyValue > aWindowState( 9 );

            aWindowState[0].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKED );
            aWindowState[0].Value = ::uno::makeAny( sal_Bool( !rElementData.m_bFloating ));
            aWindowState[1].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_VISIBLE );
            aWindowState[1].Value = uno::makeAny( sal_Bool( rElementData.m_bVisible ));
            aWindowState[2].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA );
            aWindowState[2].Value = uno::makeAny( static_cast< ui::DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) );

            awt::Point aPos;
            aPos.X = rElementData.m_aDockedData.m_aPos.X();
            aPos.Y = rElementData.m_aDockedData.m_aPos.Y();
            aWindowState[3].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKPOS );
            aWindowState[3].Value <<= aPos;

            aPos.X = rElementData.m_aFloatingData.m_aPos.X();
            aPos.Y = rElementData.m_aFloatingData.m_aPos.Y();
            aWindowState[4].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_POS );
            aWindowState[4].Value <<= aPos;

            awt::Size aSize;
            aSize.Width  = rElementData.m_aFloatingData.m_aSize.Width();
            aSize.Height = rElementData.m_aFloatingData.m_aSize.Height();
            aWindowState[5].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_SIZE );
            aWindowState[5].Value <<= aSize;
            aWindowState[6].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_UINAME );
            aWindowState[6].Value = uno::makeAny( rElementData.m_aUIName );
            aWindowState[7].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_LOCKED );
            aWindowState[7].Value = uno::makeAny( rElementData.m_aDockedData.m_bLocked );
            aWindowState[8].Name  = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_STYLE );
            aWindowState[8].Value = uno::makeAny( rElementData.m_nStyle );

            ::rtl::OUString aName = rElementData.m_aName;
            if ( xPersistentWindowState->hasByName( aName ))
            {
                uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
                xReplace->replaceByName( aName, uno::makeAny( aWindowState ));
            }
            else
            {
                uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
                xInsert->insertByName( aName, uno::makeAny( aWindowState ));
            }
        }
        catch ( uno::Exception& ) {}
    }

    // Reset flag
    aWriteLock.lock();
    m_bStoreWindowState = false;
    aWriteLock.unlock();
}

void ToolbarLayoutManager::implts_writeNewWindowStateData( const rtl::OUString aName, const uno::Reference< awt::XWindow >& xWindow )
{
    bool bVisible( false );
    bool bFloating( true );
    awt::Rectangle aPos;
    awt::Size      aSize;

    if ( xWindow.is() )
    {
        uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
        if ( xDockWindow.is() )
            bFloating = xDockWindow->isFloating();

        uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY );
        if( xWindow2.is() )
        {
            aPos     = xWindow2->getPosSize();
            aSize    = xWindow2->getOutputSize();   // always use output size for consistency
            bVisible = xWindow2->isVisible();
        }

        WriteGuard aWriteLock( m_aLock );
        UIElement& rUIElement = impl_findToolbar( aName );
        if ( rUIElement.m_xUIElement.is() )
        {
            rUIElement.m_bVisible   = bVisible;
            rUIElement.m_bFloating  = bFloating;
            if ( bFloating )
            {
                rUIElement.m_aFloatingData.m_aPos  = ::Point( aPos.X, aPos.Y );
                rUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
            }
        }
        implts_writeWindowStateData( rUIElement );
        aWriteLock.unlock();
    }
}

/******************************************************************************
                        LOOKUP PART FOR TOOLBARS
******************************************************************************/

UIElement& ToolbarLayoutManager::impl_findToolbar( const rtl::OUString& aName )
{
    static UIElement aEmptyElement;
    UIElementVector::iterator pIter;
    
    ReadGuard aReadLock( m_aLock );
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_aName == aName )
            return *pIter;
    }

    return aEmptyElement;
}

UIElement ToolbarLayoutManager::implts_findToolbar( const rtl::OUString& aName )
{
    ReadGuard aReadLock( m_aLock );
    UIElement aElement = impl_findToolbar( aName );
    aReadLock.unlock();

    return aElement;
}

UIElement ToolbarLayoutManager::implts_findToolbar( const uno::Reference< uno::XInterface >& xToolbar )
{
    UIElement                       aToolbar;
    UIElementVector::const_iterator pIter;

    ReadGuard aReadLock( m_aLock );
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_xUIElement.is() )
        {
            uno::Reference< uno::XInterface > xIfac( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            if ( xIfac == xToolbar )
            {
                aToolbar = *pIter;
                break;
            }
        }
    }

    return aToolbar;
}

uno::Reference< awt::XWindow > ToolbarLayoutManager::implts_getXWindow( const ::rtl::OUString& aName )
{
    UIElementVector::iterator pIter;
    uno::Reference< awt::XWindow > xWindow;

    ReadGuard aReadLock( m_aLock );
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_aName == aName && pIter->m_xUIElement.is() )
        {
             xWindow = uno::Reference< awt::XWindow >( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
             break;
        }
    }

    return xWindow;
}

Window* ToolbarLayoutManager::implts_getWindow( const ::rtl::OUString& aName )
{
    uno::Reference< awt::XWindow > xWindow = implts_getXWindow( aName );
    Window* pWindow = VCLUnoHelper::GetWindow( xWindow );

    return pWindow;
}

bool ToolbarLayoutManager::implts_insertToolbar( const UIElement& rUIElement )
{
    UIElement aTempData;
    bool      bFound( false );
    bool      bResult( false );
    
    aTempData = implts_findToolbar( rUIElement.m_aName );
    if ( aTempData.m_aName == rUIElement.m_aName )
        bFound = true;
    
    if ( !bFound )
    {
        WriteGuard aWriteLock( m_aLock );
        m_aUIElements.push_back( rUIElement );
        bResult = true;
    }
    
    return bResult;
}

void ToolbarLayoutManager::implts_setToolbar( const UIElement& rUIElement )
{
    WriteGuard aWriteLock( m_aLock );
    UIElement& rData = impl_findToolbar( rUIElement.m_aName );
    if ( rData.m_aName == rUIElement.m_aName )
        rData = rUIElement;
    else
        m_aUIElements.push_back( rUIElement );
}

/******************************************************************************
                        LAYOUT CODE PART FOR TOOLBARS
******************************************************************************/

::Point ToolbarLayoutManager::implts_findNextCascadeFloatingPos()
{
    const sal_Int32 nHotZoneX       = 50;
    const sal_Int32 nHotZoneY       = 50;
    const sal_Int32 nCascadeIndentX = 15;
    const sal_Int32 nCascadeIndentY = 15;

    ReadGuard aReadLock( m_aLock );
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
    uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    aReadLock.unlock();

    ::Point aStartPos( nCascadeIndentX, nCascadeIndentY );
    ::Point aCurrPos( aStartPos );
    awt::Rectangle aRect;

    Window* pContainerWindow( 0 );
    if ( xContainerWindow.is() )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
        if ( pContainerWindow )
            aStartPos = pContainerWindow->OutputToScreenPixel( aStartPos );
    }

    // Determine size of top and left docking area
    awt::Rectangle aTopRect( xTopDockingWindow->getPosSize() );
    awt::Rectangle aLeftRect( xLeftDockingWindow->getPosSize() );

    aStartPos.X() += aLeftRect.Width + nCascadeIndentX;
    aStartPos.Y() += aTopRect.Height + nCascadeIndentY;
    aCurrPos = aStartPos;

    // Try to find a cascaded position for the new floating window
    UIElementVector::const_iterator pIter;
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_xUIElement.is() )
        {
            uno::Reference< awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
            if ( xDockWindow.is() && xDockWindow->isFloating() )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow && pWindow->IsVisible() )
                {
                    awt::Rectangle aFloatRect = xWindow->getPosSize();
                    if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X() ) &&
                        ( aFloatRect.X >= aCurrPos.X() ) &&
                        (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y() ) &&
                        ( aFloatRect.Y >= aCurrPos.Y() ))
                    {
                        aCurrPos.X() = aFloatRect.X + nCascadeIndentX;
                        aCurrPos.Y() = aFloatRect.Y + nCascadeIndentY;
                    }
                }
            }
        }
    }

    return aCurrPos;
}

void ToolbarLayoutManager::implts_sortUIElements()
{
    WriteGuard aWriteLock( m_aLock );
    UIElementVector::iterator pIterStart = m_aUIElements.begin();
    UIElementVector::iterator pIterEnd   = m_aUIElements.end();

    std::stable_sort( pIterStart, pIterEnd ); // first created element should first

    // We have to reset our temporary flags.
    UIElementVector::iterator pIter;
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
        pIter->m_bUserActive = sal_False;
    aWriteLock.unlock();
}

void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector& rCopy )
{
    ReadGuard aReadLock( m_aLock );
    rCopy = m_aUIElements;
}

::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
{
    ::Size                         aSize;
    uno::Reference< awt::XWindow > xTopDockingAreaWindow;
    uno::Reference< awt::XWindow > xBottomDockingAreaWindow;

    ReadGuard aReadLock( m_aLock );
    xTopDockingAreaWindow    = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP];
    xBottomDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM];
    aReadLock.unlock();

    if ( xTopDockingAreaWindow.is() )
        aSize.Width() = xTopDockingAreaWindow->getPosSize().Height;
    if ( xBottomDockingAreaWindow.is() )
        aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height;

    return aSize;
}

void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData )
{
    std::vector< UIElement > aWindowVector;

    if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
        eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;

    uno::Reference< awt::XWindow > xDockAreaWindow;

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ReadGuard aReadLock( m_aLock );
    aWindowVector.reserve(m_aUIElements.size());
    xDockAreaWindow = m_xDockAreaWindows[eDockingArea];
    UIElementVector::iterator   pIter;
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating )
        {
            uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
            if ( xUIElement.is() )
            {
                uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
                uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
                if ( xDockWindow.is() )
                {
                    // docked windows
                    aWindowVector.push_back( *pIter );
                }
            }
        }
    }
    aReadLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    rRowColumnsWindowData.clear();

    // Collect data from windows that are on the same row/column
    sal_Int32 j;
    sal_Int32 nIndex( 0 );
    sal_Int32 nLastPos( 0 );
    sal_Int32 nCurrPos( -1 );
    sal_Int32 nLastRowColPixelPos( 0 );
    awt::Rectangle aDockAreaRect;

    if ( xDockAreaWindow.is() )
        aDockAreaRect = xDockAreaWindow->getPosSize();

    if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
        nLastRowColPixelPos = 0;
    else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
        nLastRowColPixelPos = aDockAreaRect.Height;
    else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
        nLastRowColPixelPos = 0;
    else
        nLastRowColPixelPos = aDockAreaRect.Width;

    const sal_uInt32 nCount = aWindowVector.size();
    for ( j = 0; j < sal_Int32( nCount); j++ )
    {
        const UIElement& rElement = aWindowVector[j];
        uno::Reference< awt::XWindow > xWindow;
        uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
        awt::Rectangle aPosSize;
        
        if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
            continue;
        if ( isHorizontalDockingArea( eDockingArea ))
        {
            if ( nCurrPos == -1 )
            {
                nCurrPos = rElement.m_aDockedData.m_aPos.Y();
                nLastPos = 0;

                SingleRowColumnWindowData aRowColumnWindowData;
                aRowColumnWindowData.nRowColumn = nCurrPos;
                rRowColumnsWindowData.push_back( aRowColumnWindowData );
            }

            sal_Int32 nSpace( 0 );
            if ( rElement.m_aDockedData.m_aPos.Y() != nCurrPos )
            {
                if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
                    nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
                else
                    nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
                ++nIndex;
                nLastPos = 0;
                nCurrPos = rElement.m_aDockedData.m_aPos.Y();
                SingleRowColumnWindowData aRowColumnWindowData;
                aRowColumnWindowData.nRowColumn = nCurrPos;
                rRowColumnsWindowData.push_back( aRowColumnWindowData );
            }

            // Calc space before an element and store it
            nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos );
            if ( rElement.m_aDockedData.m_aPos.X() >= nLastPos )
            {
                rRowColumnsWindowData[nIndex].nSpace += nSpace;
                nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width;
            }
            else
            {
                nSpace = 0;
                nLastPos += aPosSize.Width;
            }
            rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );

            rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
            rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
            rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back(
                awt::Rectangle( rElement.m_aDockedData.m_aPos.X(),
                                rElement.m_aDockedData.m_aPos.Y(),
                                aPosSize.Width,
                                aPosSize.Height ));
            if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height )
                rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height;
            if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
                rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, nLastRowColPixelPos,
                                                                               aDockAreaRect.Width, aPosSize.Height );
            else
                rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ),
                                                                               aDockAreaRect.Width, aPosSize.Height );
            rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace;
        }
        else
        {
            if ( nCurrPos == -1 )
            {
                nCurrPos = rElement.m_aDockedData.m_aPos.X();
                nLastPos = 0;

                SingleRowColumnWindowData aRowColumnWindowData;
                aRowColumnWindowData.nRowColumn = nCurrPos;
                rRowColumnsWindowData.push_back( aRowColumnWindowData );
            }

            sal_Int32 nSpace( 0 );
            if ( rElement.m_aDockedData.m_aPos.X() != nCurrPos )
            {
                if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
                    nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
                else
                    nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
                ++nIndex;
                nLastPos = 0;
                nCurrPos = rElement.m_aDockedData.m_aPos.X();
                SingleRowColumnWindowData aRowColumnWindowData;
                aRowColumnWindowData.nRowColumn = nCurrPos;
                rRowColumnsWindowData.push_back( aRowColumnWindowData );
            }

            // Calc space before an element and store it
            nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos );
            if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos )
            {
                rRowColumnsWindowData[nIndex].nSpace += nSpace;
                nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height;
            }
            else
            {
                nSpace = 0;
                nLastPos += aPosSize.Height;
            }
            rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );

            rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
            rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
            rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back(
                awt::Rectangle( rElement.m_aDockedData.m_aPos.X(),
                                rElement.m_aDockedData.m_aPos.Y(),
                                aPosSize.Width,
                                aPosSize.Height ));
            if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width )
                rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width;
            if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
                rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( nLastRowColPixelPos, 0,
                                                                               aPosSize.Width, aDockAreaRect.Height );
            else
                rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0,
                                                                                 aPosSize.Width, aDockAreaRect.Height );
            rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace;
        }
    }
}

void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData )
{
    std::vector< UIElement > aWindowVector;

    if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
        eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;

    bool bHorzDockArea = isHorizontalDockingArea( eDockingArea );

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ReadGuard aReadLock( m_aLock );
    UIElementVector::iterator   pIter;
    UIElementVector::iterator   pEnd = m_aUIElements.end();
    for ( pIter = m_aUIElements.begin(); pIter != pEnd; pIter++ )
    {
        if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea )
        {
            bool bSameRowCol = bHorzDockArea ? ( pIter->m_aDockedData.m_aPos.Y() == nRowCol ) : ( pIter->m_aDockedData.m_aPos.X() == nRowCol );
            uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );

            if ( bSameRowCol && xUIElement.is() )
            {
                uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
                if ( xWindow.is() )
                {
                    vos::OGuard aGuard( Application::GetSolarMutex() );
                    Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                    uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
                    if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating )
                        aWindowVector.push_back( *pIter ); // docked windows
                }
            }
        }
    }
    aReadLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    // Initialize structure
    rRowColumnWindowData.aUIElementNames.clear();
    rRowColumnWindowData.aRowColumnWindows.clear();
    rRowColumnWindowData.aRowColumnWindowSizes.clear();
    rRowColumnWindowData.aRowColumnSpace.clear();
    rRowColumnWindowData.nVarSize = 0;
    rRowColumnWindowData.nStaticSize = 0;
    rRowColumnWindowData.nSpace = 0;
    rRowColumnWindowData.nRowColumn = nRowCol;

    // Collect data from windows that are on the same row/column
    sal_Int32 j;
    sal_Int32 nLastPos( 0 );

    const sal_uInt32 nCount = aWindowVector.size();
    for ( j = 0; j < sal_Int32( nCount); j++ )
    {
        const UIElement& rElement = aWindowVector[j];
        uno::Reference< awt::XWindow > xWindow;
        uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
        awt::Rectangle aPosSize;
        if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
            continue;

        sal_Int32 nSpace;
        if ( isHorizontalDockingArea( eDockingArea ))
        {
            nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos );

            // Calc space before an element and store it
            if ( rElement.m_aDockedData.m_aPos.X() > nLastPos )
                rRowColumnWindowData.nSpace += nSpace;
            else
                nSpace = 0;

            nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width;


            rRowColumnWindowData.aRowColumnWindowSizes.push_back(
                awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), rElement.m_aDockedData.m_aPos.Y(),
                                aPosSize.Width, aPosSize.Height ));
            if ( rRowColumnWindowData.nStaticSize < aPosSize.Height )
                rRowColumnWindowData.nStaticSize = aPosSize.Height;
            rRowColumnWindowData.nVarSize += aPosSize.Width;
        }
        else
        {
            // Calc space before an element and store it
            nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos );
            if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos )
                rRowColumnWindowData.nSpace += nSpace;
            else
                nSpace = 0;

            nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height;

            rRowColumnWindowData.aRowColumnWindowSizes.push_back(
                awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), rElement.m_aDockedData.m_aPos.Y(),
                                aPosSize.Width, aPosSize.Height ));
            if ( rRowColumnWindowData.nStaticSize < aPosSize.Width )
                rRowColumnWindowData.nStaticSize = aPosSize.Width;
            rRowColumnWindowData.nVarSize += aPosSize.Height;
        }

        rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName );
        rRowColumnWindowData.aRowColumnWindows.push_back( xWindow );
        rRowColumnWindowData.aRowColumnSpace.push_back( nSpace );
        rRowColumnWindowData.nVarSize += nSpace;
    }
}

::Rectangle ToolbarLayoutManager::implts_getWindowRectFromRowColumn(
    ui::DockingArea DockingArea,
    const SingleRowColumnWindowData& rRowColumnWindowData,
    const ::Point& rMousePos,
    const rtl::OUString& rExcludeElementName )
{
    ::Rectangle aWinRect;

    if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
        DockingArea = ui::DockingArea_DOCKINGAREA_TOP;

    if ( rRowColumnWindowData.aRowColumnWindows.empty() )
        return aWinRect;
    else
    {
        ReadGuard aReadLock( m_aLock );
        Window* pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow ));
        Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows[DockingArea] ));
        aReadLock.unlock();

        // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
        vos::OGuard aGuard( Application::GetSolarMutex() );

        // Retrieve output size from container Window
        if ( pDockingAreaWindow && pContainerWindow )
        {
            const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size();
            for ( sal_uInt32 i = 0; i < nCount; i++ )
            {
                awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize();
                ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height );
                aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
                if ( aRect.IsInside( rMousePos ))
                {
                    // Check if we have found the excluded element. If yes, we have to provide an empty rectangle.
                    // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle!
                    if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] )
                        return aRect;
                    else
                        break;
                }
            }
        }
    }

    return aWinRect;
}

::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect(
    ui::DockingArea        eDockingArea,
    sal_Int32              nRowCol,
    const ::Rectangle&     rDockedElementRect,
    const ::rtl::OUString& rMovedElementName,
    const ::Rectangle&     rMovedElementRect )
{
    SingleRowColumnWindowData aRowColumnWindowData;

    sal_Bool bHorzDockArea( isHorizontalDockingArea( eDockingArea ));
    implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData );
    if ( aRowColumnWindowData.aRowColumnWindows.empty() )
        return rMovedElementRect;
    else
    {
        sal_Int32 nSpace( 0 );
        ::Rectangle aFrontDockingRect( rMovedElementRect );
        const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size();
        for ( sal_uInt32 i = 0; i < nCount; i++ )
        {
            if ( bHorzDockArea )
            {
                if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() )
                {
                    nSpace += aRowColumnWindowData.aRowColumnSpace[i];
                    break;
                }
                else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
                    nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width +
                              aRowColumnWindowData.aRowColumnSpace[i];
                else
                    nSpace = 0;
            }
            else
            {
                if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() )
                {
                    nSpace += aRowColumnWindowData.aRowColumnSpace[i];
                    break;
                }
                else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
                    nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height +
                              aRowColumnWindowData.aRowColumnSpace[i];
                else
                    nSpace = 0;
            }
        }

        if ( nSpace > 0 )
        {
            sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) );
            if ( bHorzDockArea )
                aFrontDockingRect.Move( -nMove, 0 );
            else
                aFrontDockingRect.Move( 0, -nMove );
        }

        return aFrontDockingRect;
    }
}

void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos )
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< awt::XWindow > xDockingWindow( m_xDockAreaWindows[DockingArea] );
    ::Size                         aDockingWinSize;
    Window*                        pDockingWindow( 0 );
    aReadLock.unlock();

    if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
        DockingArea = ui::DockingArea_DOCKINGAREA_TOP;

    {
        // Retrieve output size from container Window
        vos::OGuard aGuard( Application::GetSolarMutex() );
        pDockingWindow  = VCLUnoHelper::GetWindow( xDockingWindow );
        if ( pDockingWindow )
            aDockingWinSize = pDockingWindow->GetOutputSizePixel();
    }

    sal_Int32 nFreeRowColPixelPos( 0 );
    sal_Int32 nMaxSpace( 0 );
    sal_Int32 nNeededSpace( 0 );
    sal_Int32 nTopDockingAreaSize( 0 );

    if ( isHorizontalDockingArea( DockingArea ))
    {
        nMaxSpace    = aDockingWinSize.Width();
        nNeededSpace = aUIElementSize.Width();
    }
    else
    {
        nMaxSpace           = aDockingWinSize.Height();
        nNeededSpace        = aUIElementSize.Height();
        nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width();
    }

    std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;

    implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData );
    sal_Int32 nPixelPos( 0 );
    const sal_uInt32 nCount = aRowColumnsWindowData.size();
    for ( sal_uInt32 i = 0; i < nCount; i++ )
    {
        SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i];

        if (( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) ||
            ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT  ))
            nPixelPos += rRowColumnWindowData.nStaticSize;

        if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) ||
            ( rRowColumnWindowData.nSpace >= nNeededSpace ))
        {
            // Check current row where we can find the needed space
            sal_Int32 nCurrPos( 0 );
            const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
            for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ )
            {
                awt::Rectangle rRect  = rRowColumnWindowData.aRowColumnWindowSizes[j];
                sal_Int32&     rSpace = rRowColumnWindowData.aRowColumnSpace[j];
                if ( isHorizontalDockingArea( DockingArea ))
                {
                    if ( rSpace >= nNeededSpace )
                    {
                        rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
                        if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
                            rPixelPos   = ::Point( nCurrPos, nPixelPos );
                        else
                            rPixelPos   = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
                        return;
                    }
                    nCurrPos = rRect.X + rRect.Width;
                }
                else
                {
                    if ( rSpace >= nNeededSpace )
                    {
                        rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
                        if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
                            rPixelPos   = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
                        else
                            rPixelPos   = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
                        return;
                    }
                    nCurrPos = rRect.Y + rRect.Height;
                }
            }

            if (( nCurrPos + nNeededSpace ) <= nMaxSpace )
            {
                if ( isHorizontalDockingArea( DockingArea ))
                {
                    rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
                    if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
                        rPixelPos   = ::Point( nCurrPos, nPixelPos );
                    else
                        rPixelPos   = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
                    return;
                }
                else
                {
                    rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
                    if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
                        rPixelPos   = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
                    else
                        rPixelPos   = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
                    return;
                }
            }
        }

        if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT  ))
            nPixelPos += rRowColumnWindowData.nStaticSize;
    }

    sal_Int32 nNextFreeRowCol( 0 );
    sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size();
    if ( nRowColumnsCount > 0 )
        nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1;
    else
        nNextFreeRowCol = 0;

    if ( nNextFreeRowCol == 0 )
    {
        if ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
            nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height();
        else if ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT  )
            nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width();
    }

    if ( isHorizontalDockingArea( DockingArea ))
    {
        rVirtualPos = ::Point( 0, nNextFreeRowCol );
        if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
            rPixelPos = ::Point( 0, nFreeRowColPixelPos );
        else
            rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos );
    }
    else
    {
        rVirtualPos = ::Point( nNextFreeRowCol, 0 );
        rPixelPos   = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 );
    }
}

void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn( 
    sal_Int32 nDockingArea,
    sal_Int32 nOffset,
    SingleRowColumnWindowData& rRowColumnWindowData,
    const ::Size& rContainerSize )
{
    sal_Int32 nDiff(0);
    sal_Int32 nRCSpace( rRowColumnWindowData.nSpace );
    sal_Int32 nTopDockingAreaSize(0);
    sal_Int32 nBottomDockingAreaSize(0);
    sal_Int32 nContainerClientSize(0);

    if ( rRowColumnWindowData.aRowColumnWindows.empty() )
        return;

    if ( isHorizontalDockingArea( nDockingArea ))
    {
        nContainerClientSize = rContainerSize.Width();
        nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
    }
    else
    {
        nTopDockingAreaSize    = implts_getTopBottomDockingAreaSizes().Width();
        nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height();
        nContainerClientSize   = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize );
        nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
    }

    const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
    if (( nDiff < 0 ) && ( nRCSpace > 0 ))
    {
        // First we try to reduce the size of blank space before/behind docked windows
        sal_Int32 i = nCount - 1;
        while ( i >= 0 )
        {
            sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i];
            if ( nSpace >= -nDiff )
            {
                if ( isHorizontalDockingArea( nDockingArea ))
                {
                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount ; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
                }
                else
                {
                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount ; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
                }
                nDiff = 0;

                break;
            }
            else if ( nSpace > 0 )
            {
                if ( isHorizontalDockingArea( nDockingArea ))
                {
                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace;
                }
                else
                {
                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace;
                }
                nDiff += nSpace;
            }
            --i;
        }
    }

    // Check if we have to reduce further
    if ( nDiff < 0 )
    {
        // Now we have to reduce the size of certain docked windows
        sal_Int32 i = sal_Int32( nCount - 1 );
        while ( i >= 0 )
        {
            awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
            ::Size          aMinSize;

            vos::OGuard aGuard( Application::GetSolarMutex() );
            {
                uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
                    aMinSize = ((ToolBox *)pWindow)->CalcMinimumWindowSizePixel();
            }

            if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 ))
            {
                if ( isHorizontalDockingArea( nDockingArea ))
                {
                    sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() );
                    if ( nMaxReducation >= -nDiff )
                    {
                        rWinRect.Width = rWinRect.Width + nDiff;
                        nDiff = 0;
                    }
                    else
                    {
                        rWinRect.Width = aMinSize.Width();
                        nDiff += nMaxReducation;
                    }

                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
                }
                else
                {
                    sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() );
                    if ( nMaxReducation >= -nDiff )
                    {
                        rWinRect.Height = rWinRect.Height + nDiff;
                        nDiff = 0;
                    }
                    else
                    {
                        rWinRect.Height = aMinSize.Height();
                        nDiff += nMaxReducation;
                    }

                    // Try to move this and all user elements behind with the calculated difference
                    for ( sal_uInt32 j = i; j < nCount; j++ )
                        rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
                }
            }

            if ( nDiff >= 0 )
                break;

            --i;
        }
    }

    ReadGuard aReadLock( m_aLock );
    Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] );
    aReadLock.unlock();

    sal_Int32 nCurrPos( 0 );

    vos::OGuard aGuard( Application::GetSolarMutex() );
    for ( sal_uInt32 i = 0; i < nCount; i++ )
    {
        uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        Window* pOldParentWindow = pWindow->GetParent();

        if ( pDockAreaWindow != pOldParentWindow )
            pWindow->SetParent( pDockAreaWindow );

        awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
        if ( isHorizontalDockingArea( nDockingArea ))
        {
            if ( aWinRect.X < nCurrPos )
                aWinRect.X = nCurrPos;
            pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize ));
            pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
            nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width;
        }
        else
        {
            if ( aWinRect.Y < nCurrPos )
                aWinRect.Y = nCurrPos;
            pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height ));
            pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
            nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height;
        }
    }
}

void ToolbarLayoutManager::implts_setLayoutDirty()
{
    WriteGuard aWriteLock( m_aLock );
    m_bLayoutDirty = true;
}

void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress )
{
    WriteGuard aWriteLock( m_aLock );
    m_bLayoutInProgress = bInProgress;
}

::Rectangle ToolbarLayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset )
{
    ::Rectangle aRect( rRect );

    aRect.Left() -= nHotZoneOffset;
    aRect.Top() -= nHotZoneOffset;
    aRect.Right() += nHotZoneOffset;
    aRect.Bottom() += nHotZoneOffset;
    
    return aRect;
}

void ToolbarLayoutManager::implts_calcDockingPosSize(
    UIElement&          rUIElement,
    DockingOperation&   rDockingOperation,
    ::Rectangle&        rTrackingRect,
    const Point&        rMousePos )
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
    ::Size                          aContainerWinSize;
    Window*                         pContainerWindow( 0 );
    ::Rectangle                     aDockingAreaOffsets( m_aDockingAreaOffsets );
    aReadLock.unlock();

    if ( !rUIElement.m_xUIElement.is() )
    {
        rTrackingRect = ::Rectangle();
        return;
    }

    {
        // Retrieve output size from container Window
        vos::OGuard aGuard( Application::GetSolarMutex() );
        pContainerWindow  = VCLUnoHelper::GetWindow( xContainerWindow );
        aContainerWinSize = pContainerWindow->GetOutputSizePixel();
    }

    Window*                        pDockWindow( 0 );
    Window*                        pDockingAreaWindow( 0 );
    ToolBox*                       pToolBox( 0 );
    uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
    uno::Reference< awt::XWindow > xDockingAreaWindow;
    ::Rectangle                    aTrackingRect( rTrackingRect );
    ui::DockingArea                eDockedArea( (ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea );
    sal_Int32                      nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
    sal_Int32                      nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
    bool                           bHorizontalDockArea(( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) ||
                                                       ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ));
    sal_Int32                      nMaxLeftRightDockAreaSize = aContainerWinSize.Height() -
                                                               nTopDockingAreaSize -
                                                               nBottomDockingAreaSize -
                                                               aDockingAreaOffsets.Top() -
                                                               aDockingAreaOffsets.Bottom();
    ::Rectangle                    aDockingAreaRect;

    aReadLock.lock();
    xDockingAreaWindow = m_xDockAreaWindows[eDockedArea];
    aReadLock.unlock();

    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
        pDockWindow        = VCLUnoHelper::GetWindow( xWindow );
        if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX )
            pToolBox = (ToolBox *)pDockWindow;

        aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() );
        if ( pToolBox )
        {
            // docked toolbars always have one line
            ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) );
            aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() ));
        }
    }

    // default docking operation, dock on the given row/column
    bool                                     bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos ));
    std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;

    rDockingOperation = DOCKOP_ON_COLROW;
    implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData );

    // determine current first row/column and last row/column
    sal_Int32 nMaxRowCol( -1 );
    sal_Int32 nMinRowCol( SAL_MAX_INT32 );
    const sal_uInt32 nCount = aRowColumnsWindowData.size();
    for ( sal_uInt32 i = 0; i < nCount; i++ )
    {
        if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol )
            nMaxRowCol = aRowColumnsWindowData[i].nRowColumn;
        if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol )
            nMinRowCol = aRowColumnsWindowData[i].nRowColumn;
    }

    if ( !bOpOutsideOfDockingArea )
    {
        // docking inside our docking area
        sal_Int32   nIndex( -1 );
        sal_Int32   nRowCol( -1 );
        ::Rectangle aWindowRect;
        ::Rectangle aRowColumnRect;

        const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size();
        for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ )
        {
            ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X,
                               aRowColumnsWindowData[i].aRowColumnRect.Y,
                               aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width,
                               aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height );

            {
                // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
                vos::OGuard aGuard( Application::GetSolarMutex() );
                aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
            }

            bool bIsInsideRowCol( aRect.IsInside( rMousePos ) );
            if ( bIsInsideRowCol )
            {
                nIndex            = i;
                nRowCol           = aRowColumnsWindowData[i].nRowColumn;
                rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos );
                aWindowRect       = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName );
                aRowColumnRect    = aRect;
                break;
            }
        }

        OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" );
        if (( nIndex >= 0 ) && ( nRowCol >= 0 ))
        {
            if ( rDockingOperation == DOCKOP_ON_COLROW )
            {
                if ( !aWindowRect.IsEmpty())
                {
                    // Tracking rect is on a row/column and mouse is over a docked toolbar.
                    // Determine if the tracking rect must be located before/after the docked toolbar.

                    ::Rectangle aUIElementRect( aWindowRect );
                    sal_Int32   nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) :
                                                               ( aWindowRect.Top() + aWindowRect.getHeight() / 2 ));
                    sal_Bool    bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle ));
                    if ( bInsertBefore )
                    {
                        if ( bHorizontalDockArea )
                        {
                            sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() -  aWindowRect.Left() ),
                                                                                    sal_Int32( aTrackingRect.getWidth() )));
                            if ( nSize == 0 )
                                nSize = aWindowRect.getWidth();

                            aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
                            aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect );

                            // Set virtual position
                            rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Left();
                            rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
                        }
                        else
                        {
                            sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(
                                                    nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ),
                                                    sal_Int32( aTrackingRect.getHeight() )));
                            if ( nSize == 0 )
                                nSize = aWindowRect.getHeight();

                            aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));
                            aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect );

                            // Set virtual position
                            sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel(
                                                pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y();
                            rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
                            rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
                        }

                        rTrackingRect = aWindowRect;
                        return;
                    }
                    else
                    {
                        if ( bHorizontalDockArea )
                        {
                            sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ),
                                                                                    sal_Int32( aTrackingRect.getWidth() )));
                            if ( nSize == 0 )
                            {
                                aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() ));
                                aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() ));
                                rUIElement.m_aDockedData.m_aPos.X() = aUIElementRect.Left();
                            }
                            else
                            {
                                aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() ));
                                aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
                                rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Right();
                            }

                            // Set virtual position
                            rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
                        }
                        else
                        {
                            sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ),
                                                                                    sal_Int32( aTrackingRect.getHeight() )));
                            aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() ));
                            aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));

                            // Set virtual position
                            sal_Int32 nPosY( 0 );
                            {
                                vos::OGuard aGuard( Application::GetSolarMutex() );
                                nPosY = pDockingAreaWindow->ScreenToOutputPixel(
                                                    pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y();
                            }
                            rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
                            rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
                        }

                        rTrackingRect = aUIElementRect;
                        return;
                    }
                }
                else
                {
                    implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
                    rTrackingRect = implts_calcTrackingAndElementRect(
                                        eDockedArea, nRowCol, rUIElement,
                                        aTrackingRect, aRowColumnRect, aContainerWinSize );
                    return;
                }
            }
            else
            {
                if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) ||
                    (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW  )))
                    bOpOutsideOfDockingArea = true;
                else
                {
                    // handle docking before/after a row
                    implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
                    rTrackingRect = implts_calcTrackingAndElementRect(
                                        eDockedArea, nRowCol, rUIElement,
                                        aTrackingRect, aRowColumnRect, aContainerWinSize );

                    sal_Int32 nOffsetX( 0 );
                    sal_Int32 nOffsetY( 0 );
                    if ( bHorizontalDockArea )
                        nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2 + 0.5 ));
                    else
                        nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2 + 0.5 ));

                    if ( rDockingOperation == DOCKOP_BEFORE_COLROW )
                    {
                        if (( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ))
                        {
                            // Docking before/after means move track rectangle half column/row.
                            // As left and top are ordered 0...n instead of right and bottom
                            // which uses n...0, we have to use negative values for top/left.
                            nOffsetX *= -1;
                            nOffsetY *= -1;
                        }
                    }
                    else
                    {
                        if (( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT ))
                        {
                            // Docking before/after means move track rectangle half column/row.
                            // As left and top are ordered 0...n instead of right and bottom
                            // which uses n...0, we have to use negative values for top/left.
                            nOffsetX *= -1;
                            nOffsetY *= -1;
                        }
                        nRowCol++;
                    }

                    if ( bHorizontalDockArea )
                        rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
                    else
                        rUIElement.m_aDockedData.m_aPos.X() = nRowCol;

                    rTrackingRect.Move( nOffsetX, nOffsetY );
                    rTrackingRect.SetSize( aTrackingRect.GetSize() );
                }
            }
        }
    }

    // Docking outside of our docking window area =>
    // Users want to dock before/after first/last docked element or to an empty docking area
    if ( bOpOutsideOfDockingArea )
    {
        // set correct size for docking
        implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
        rTrackingRect = aTrackingRect;

        if ( bHorizontalDockArea )
        {
            sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
            if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() )
                nPosX = std::min( nPosX,
                                std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ),
                                          sal_Int32( 0 )));

            sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() );
            sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 ));
            if ( nDockHeight == 0 )
            {
                sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
                    nPosY -= rTrackingRect.getHeight();
                rTrackingRect.SetPos( Point( nPosX, nPosY ));
                rUIElement.m_aDockedData.m_aPos.Y() = 0;
            }
            else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 )))
            {
                rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
                    rUIElement.m_aDockedData.m_aPos.Y() = 0;
                else
                    rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
                rDockingOperation = DOCKOP_BEFORE_COLROW;
            }
            else
            {
                rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
                    rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
                else
                    rUIElement.m_aDockedData.m_aPos.Y() = 0;
                rDockingOperation = DOCKOP_AFTER_COLROW;
            }
            rTrackingRect.setWidth( nSize );

            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                nPosX = pDockingAreaWindow->ScreenToOutputPixel(
                                    pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X();
            }
            rUIElement.m_aDockedData.m_aPos.X() = nPosX;
        }
        else
        {
            sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), sal_Int32( nMaxLeftRightDockAreaSize ));
            sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
            if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
                nPosY = std::min( nPosY,
                                std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
                                        sal_Int32( nTopDockingAreaSize )));

            sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );
            sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 ));
            if ( nDockWidth == 0 )
            {
                sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT )
                    nPosX -= rTrackingRect.getWidth();
                rTrackingRect.SetPos( Point( nPosX, nPosY ));
                rUIElement.m_aDockedData.m_aPos.X() = 0;
            }
            else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 )))
            {
                rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
                    rUIElement.m_aDockedData.m_aPos.X() = 0;
                else
                    rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
                rDockingOperation = DOCKOP_BEFORE_COLROW;
            }
            else
            {
                rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY ));
                if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
                    rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
                else
                    rUIElement.m_aDockedData.m_aPos.X() = 0;
                rDockingOperation = DOCKOP_AFTER_COLROW;
            }
            rTrackingRect.setHeight( nSize );

            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                nPosY = pDockingAreaWindow->ScreenToOutputPixel(
                                    pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y();
            }
            rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
        }
    }
}

framework::ToolbarLayoutManager::DockingOperation ToolbarLayoutManager::implts_determineDockingOperation(
    ui::DockingArea    DockingArea,
    const ::Rectangle& rRowColRect,
    const Point&       rMousePos )
{
    const sal_Int32 nHorzVerticalRegionSize        = 6;
    const sal_Int32 nHorzVerticalMoveRegion        = 4;

    if ( rRowColRect.IsInside( rMousePos ))
    {
        if ( isHorizontalDockingArea( DockingArea ))
        {
            sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize;
            sal_Int32 nPosY   = rRowColRect.Top() + nRegion;

            if ( rMousePos.Y() < nPosY )
                return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
            else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion ))
                return DOCKOP_ON_COLROW;
            else
                return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
        }
        else
        {
            sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize;
            sal_Int32 nPosX   = rRowColRect.Left() + nRegion;

            if ( rMousePos.X() < nPosX )
                return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
            else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion ))
                return DOCKOP_ON_COLROW;
            else
                return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
        }
    }
    else
        return DOCKOP_ON_COLROW;
}

::Rectangle ToolbarLayoutManager::implts_calcTrackingAndElementRect(
    ui::DockingArea eDockingArea,
    sal_Int32 nRowCol,
    UIElement& rUIElement,
    const ::Rectangle& rTrackingRect,
    const ::Rectangle& rRowColumnRect,
    const ::Size& rContainerWinSize )
{
    ReadGuard aReadGuard( m_aLock );
    ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
    aReadGuard.unlock();

    bool      bHorizontalDockArea( isHorizontalDockingArea( eDockingArea ));
    sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
    sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );

    sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() -
                                          nTopDockingAreaSize -
                                          nBottomDockingAreaSize -
                                          aDockingAreaOffsets.Top() -
                                          aDockingAreaOffsets.Bottom();

    ::Rectangle aTrackingRect( rTrackingRect );
    if ( bHorizontalDockArea )
    {
        sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
        if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() )
            nPosX = std::min( nPosX,
                                std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ),
                                          sal_Int32( 0 )));

        sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() );

        aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() ));
        aTrackingRect.setWidth( nSize );
        aTrackingRect.setHeight( rRowColumnRect.getHeight() );

        // Set virtual position
        rUIElement.m_aDockedData.m_aPos.X() = nPosX;
        rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
    }
    else
    {
        sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ),
                                                    sal_Int32( nMaxLeftRightDockAreaSize ));

        sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
        if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
            nPosY = std::min( nPosY,
                                std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
                                        sal_Int32( nTopDockingAreaSize )));

        sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );

        aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY ));
        aTrackingRect.setWidth( rRowColumnRect.getWidth() );
        aTrackingRect.setHeight( nSize );

        aReadGuard.lock();
        uno::Reference< awt::XWindow  > xDockingAreaWindow( m_xDockAreaWindows[eDockingArea] );
        uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
        aReadGuard.unlock();

        sal_Int32 nDockPosY( 0 );
        Window* pDockingAreaWindow( 0 );
        Window* pContainerWindow( 0 );
        {
            vos::OGuard aGuard( Application::GetSolarMutex() );
            pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
            pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
            nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y();
        }

        // Set virtual position
        rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
        rUIElement.m_aDockedData.m_aPos.Y() = nDockPosY;
    }

    return aTrackingRect;
}

void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect )
{
    ::Point aPoint( rTrackingRect.TopLeft());
    if ( isHorizontalDockingArea( eDockingArea ))
        aPoint.X() = rMousePos.X();
    else
        aPoint.Y() = rMousePos.Y();
    rTrackingRect.SetPos( aPoint );
}

void ToolbarLayoutManager::implts_renumberRowColumnData(
    ui::DockingArea eDockingArea,
    DockingOperation /*eDockingOperation*/,
    const UIElement& rUIElement )
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
    aReadLock.unlock();

    bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea ));
    sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y() : rUIElement.m_aDockedData.m_aPos.X() );

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    WriteGuard aWriteLock( m_aLock );
    UIElementVector::iterator pIter;
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && ( pIter->m_aName != rUIElement.m_aName ))
        {
            // Don't change toolbars without a valid docking position!
            if ( isDefaultPos( pIter->m_aDockedData.m_aPos ))
                continue;

            sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? pIter->m_aDockedData.m_aPos.Y() : pIter->m_aDockedData.m_aPos.X();
            if ( nWindowRowCol >= nRowCol )
            {
                if ( bHorzDockingArea )
                    pIter->m_aDockedData.m_aPos.Y() += 1;
                else
                    pIter->m_aDockedData.m_aPos.X() += 1;
            }
        }
    }
    aWriteLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    // We have to change the persistent window state part
    if ( xPersistentWindowState.is() )
    {
        try
        {
            uno::Sequence< ::rtl::OUString > aWindowElements = xPersistentWindowState->getElementNames();
            for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ )
            {
                if ( rUIElement.m_aName != aWindowElements[i] )
                {
                    try
                    {
                        uno::Sequence< beans::PropertyValue > aPropValueSeq;
                        awt::Point                            aDockedPos;
                        ui::DockingArea                       nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT );

                        xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq;
                        for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ )
                        {
                            if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA ))
                                aPropValueSeq[j].Value >>= nDockedArea;
                            else if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS ))
                                aPropValueSeq[j].Value >>= aDockedPos;
                        }

                        // Don't change toolbars without a valid docking position!
                        if ( isDefaultPos( aDockedPos ))
                            continue;

                        sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X;
                        if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol ))
                        {
                            if ( bHorzDockingArea )
                                aDockedPos.Y += 1;
                            else
                                aDockedPos.X += 1;

                            uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
                            xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq ));
                        }
                    }
                    catch ( uno::Exception& ) {}
                }
            }
        }
        catch ( uno::Exception& ) {}
    }
}

//---------------------------------------------------------------------------------------------------------
//  XWindowListener
//---------------------------------------------------------------------------------------------------------
void SAL_CALL ToolbarLayoutManager::windowResized( const awt::WindowEvent& aEvent ) 
throw( uno::RuntimeException )
{
    WriteGuard aWriteLock( m_aLock );
    bool bLocked( m_bDockingInProgress );
    bool bLayoutInProgress( m_bLayoutInProgress );
    aWriteLock.unlock();

    // Do not do anything if we are in the middle of a docking process. This would interfere all other
    // operations. We will store the new position and size in the docking handlers.
    // Do not do anything if we are in the middle of our layouting process. We will adapt the position
    // and size of the user interface elements.
    if ( !bLocked && !bLayoutInProgress )
    {
        bool                           bNotify( false );
        uno::Reference< awt::XWindow > xWindow( aEvent.Source, uno::UNO_QUERY );

        UIElement aUIElement = implts_findToolbar( aEvent.Source );
        if ( aUIElement.m_xUIElement.is() )
        {
            if ( aUIElement.m_bFloating )
            {
                uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY );
                
                if( xWindow2.is() )
                {
                    awt::Rectangle aPos     = xWindow2->getPosSize();
                    awt::Size      aSize    = xWindow2->getOutputSize();   // always use output size for consistency
                    bool           bVisible = xWindow2->isVisible();
                    
                    // update element data
                    aUIElement.m_aFloatingData.m_aPos  = ::Point( aPos.X, aPos.Y );
                    aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
                    aUIElement.m_bVisible              = bVisible;
                }
                
                implts_writeWindowStateData( aUIElement );
            }
            else
            {
                implts_setLayoutDirty();
                bNotify = true;
            }
        }

        if ( bNotify )
            m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
    }
}

void SAL_CALL ToolbarLayoutManager::windowMoved( const awt::WindowEvent& /*aEvent*/ ) 
throw( uno::RuntimeException )
{
}

void SAL_CALL ToolbarLayoutManager::windowShown( const lang::EventObject& /*aEvent*/ ) 
throw( uno::RuntimeException )
{
}

void SAL_CALL ToolbarLayoutManager::windowHidden( const lang::EventObject& /*aEvent*/ ) 
throw( uno::RuntimeException )
{
}

//---------------------------------------------------------------------------------------------------------
//  XDockableWindowListener
//---------------------------------------------------------------------------------------------------------
void SAL_CALL ToolbarLayoutManager::startDocking( const awt::DockingEvent& e ) 
throw (uno::RuntimeException)
{
    bool bWinFound( false );

    ReadGuard aReadGuard( m_aLock );
    uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
    uno::Reference< awt::XWindow2 > xWindow( e.Source, uno::UNO_QUERY );
    aReadGuard.unlock();

    Window* pContainerWindow( 0 );
    Window* pWindow( 0 );
    ::Point aMousePos;
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
        aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ));
    }

    UIElement aUIElement = implts_findToolbar( e.Source );

    if ( aUIElement.m_xUIElement.is() && xWindow.is() )
    {
        awt::Rectangle aRect;
        
        bWinFound = true;
        uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
        if ( xDockWindow->isFloating() )
        {
            awt::Rectangle aPos  = xWindow->getPosSize();
            awt::Size      aSize = xWindow->getOutputSize();

            aUIElement.m_aFloatingData.m_aPos  = ::Point( aPos.X, aPos.Y );
            aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );

            vos::OGuard aGuard( Application::GetSolarMutex() );
            pWindow = VCLUnoHelper::GetWindow( xWindow );
            if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
            {
                ToolBox* pToolBox = (ToolBox *)pWindow;
                aUIElement.m_aFloatingData.m_nLines        = pToolBox->GetFloatingLines();
                aUIElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
            }
        }
    }

    WriteGuard aWriteLock( m_aLock );
    m_bDockingInProgress = bWinFound;
    m_aDockUIElement = aUIElement;
    m_aDockUIElement.m_bUserActive = true;
    m_aStartDockMousePos = aMousePos;
    aWriteLock.unlock();
}

awt::DockingData SAL_CALL ToolbarLayoutManager::docking( const awt::DockingEvent& e ) 
throw (uno::RuntimeException)
{
    const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25;
    const sal_Int32 MAGNETIC_DISTANCE_DOCK   = 20;

    ReadGuard aReadLock( m_aLock );
    awt::DockingData                       aDockingData;
    uno::Reference< awt::XDockableWindow > xDockWindow( e.Source, uno::UNO_QUERY );
    uno::Reference< awt::XWindow >         xWindow( e.Source, uno::UNO_QUERY );
    uno::Reference< awt::XWindow >         xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
    uno::Reference< awt::XWindow >         xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
    uno::Reference< awt::XWindow >         xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
    uno::Reference< awt::XWindow >         xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
    uno::Reference< awt::XWindow2 >        xContainerWindow( m_xContainerWindow );
    UIElement                              aUIDockingElement( m_aDockUIElement );
    DockingOperation                       eDockingOperation( DOCKOP_ON_COLROW );
    bool                                   bDockingInProgress( m_bDockingInProgress );
    aReadLock.unlock();

    if ( bDockingInProgress )
        aDockingData.TrackingRectangle = e.TrackingRectangle;

    if ( bDockingInProgress && xDockWindow.is() && xWindow.is() )
    {
        try
        {
            vos::OGuard aGuard( Application::GetSolarMutex() );

            sal_Int16 eDockingArea( -1 ); // none
            sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK );
            awt::Rectangle aNewTrackingRect;
            ::Rectangle aTrackingRect( e.TrackingRectangle.X, e.TrackingRectangle.Y,
                                       ( e.TrackingRectangle.X + e.TrackingRectangle.Width ),
                                       ( e.TrackingRectangle.Y + e.TrackingRectangle.Height ));

            awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize();
            ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height );
            ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone ));

            aTmpRect = xBottomDockingWindow->getPosSize();
            ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height ));
            ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone ));

            aTmpRect = xLeftDockingWindow->getPosSize();
            ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
            ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone ));

            aTmpRect = xRightDockingWindow->getPosSize();
            ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
            ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone ));

            Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) );
            Window* pDockingAreaWindow( 0 );
            ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )));

            if ( aHotZoneTopDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
            else if ( aHotZoneBottomDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
            else if ( aHotZoneLeftDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
            else if ( aHotZoneRightDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;

            // Higher priority for movements inside the real docking area
            if ( aTopDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
            else if ( aBottomDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
            else if ( aLeftDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
            else if ( aRightDockRect.IsInside( aMousePos ))
                eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;

            // Determine if we have a toolbar and set alignment according to the docking area!
            Window*  pWindow = VCLUnoHelper::GetWindow( xWindow );
            ToolBox* pToolBox = 0;
            if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
                pToolBox = (ToolBox *)pWindow;

            if ( eDockingArea != -1 )
            {
                if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
                {
                    aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_TOP;
                    aUIDockingElement.m_bFloating = false;
                    pDockingAreaWindow = VCLUnoHelper::GetWindow( xTopDockingWindow );
                }
                else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
                {
                    aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
                    aUIDockingElement.m_bFloating = false;
                    pDockingAreaWindow = VCLUnoHelper::GetWindow( xBottomDockingWindow );
                }
                else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
                {
                    aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_LEFT;
                    aUIDockingElement.m_bFloating = false;
                    pDockingAreaWindow = VCLUnoHelper::GetWindow( xLeftDockingWindow );
                }
                else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )
                {
                    aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_RIGHT;
                    aUIDockingElement.m_bFloating = false;
                    pDockingAreaWindow = VCLUnoHelper::GetWindow( xRightDockingWindow );
                }

                ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() );
                aTrackingRect.SetPos( aOutputPos );

                ::Rectangle aNewDockingRect( aTrackingRect );
                implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos );

                ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() );
                aNewTrackingRect = awt::Rectangle( aScreenPos.X(), aScreenPos.Y(),
                                                   aNewDockingRect.getWidth(), aNewDockingRect.getHeight() );
                aDockingData.TrackingRectangle = aNewTrackingRect;
            }
            else if ( pToolBox && bDockingInProgress )
            {
                bool bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
                ::Size aFloatSize  = aUIDockingElement.m_aFloatingData.m_aSize;
                if ( aFloatSize.Width() > 0 && aFloatSize.Height() > 0 )
                {
                    aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel(
                                                                ::Point( e.MousePos.X, e.MousePos.Y ));
                    aDockingData.TrackingRectangle.Height = aFloatSize.Height();
                    aDockingData.TrackingRectangle.Width  = aFloatSize.Width();
                }
                else
                {
                    aFloatSize = pToolBox->CalcWindowSizePixel();
                    if ( !bIsHorizontal )
                    {
                        // Floating toolbars are always horizontal aligned! We have to swap
                        // width/height if we have a vertical aligned toolbar.
                        sal_Int32 nTemp = aFloatSize.Height();
                        aFloatSize.Height() = aFloatSize.Width();
                        aFloatSize.Width()  = nTemp;
                    }

                    aDockingData.TrackingRectangle.Height = aFloatSize.Height();
                    aDockingData.TrackingRectangle.Width  = aFloatSize.Width();

                    // For the first time we don't have any data about the floating size of a toolbar.
                    // We calculate it and store it for later use.
                    aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel(::Point( e.MousePos.X, e.MousePos.Y ));
                    aUIDockingElement.m_aFloatingData.m_aSize         = aFloatSize;
                    aUIDockingElement.m_aFloatingData.m_nLines        = pToolBox->GetFloatingLines();
                    aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
                }
                aDockingData.TrackingRectangle.X = e.MousePos.X;
                aDockingData.TrackingRectangle.Y = e.MousePos.Y;
            }

            aDockingData.bFloating = ( eDockingArea == -1 );

            // Write current data to the member docking progress data
            WriteGuard aWriteLock( m_aLock );
            m_aDockUIElement.m_bFloating = aDockingData.bFloating;
            if ( !aDockingData.bFloating )
            {
                m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
                m_eDockOperation               = eDockingOperation;
            }
            else
                m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
            aWriteLock.unlock();
        }
        catch ( uno::Exception& ) {}
    }

    return aDockingData;
}

void SAL_CALL ToolbarLayoutManager::endDocking( const awt::EndDockingEvent& e ) 
throw (uno::RuntimeException)
{
    bool bDockingInProgress( false );
    bool bStartDockFloated( false );
    bool bFloating( false );
    UIElement aUIDockingElement;

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    WriteGuard aWriteLock( m_aLock );
    bDockingInProgress = m_bDockingInProgress;
    aUIDockingElement  = m_aDockUIElement;
    bFloating          = aUIDockingElement.m_bFloating;

    UIElement& rUIElement = impl_findToolbar( aUIDockingElement.m_aName );
    if ( rUIElement.m_aName == aUIDockingElement.m_aName )
    {
        if ( aUIDockingElement.m_bFloating )
        {
            // Write last position into position data
            uno::Reference< awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
            awt::Rectangle aTmpRect = xWindow->getPosSize();
            rUIElement.m_aFloatingData.m_aPos = ::Point( aTmpRect.X, aTmpRect.Y );
            // make changes also for our local data as we use it to make data persistent
            aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData;
        }
        else
        {
            rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
            rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize;

            if ( m_eDockOperation != DOCKOP_ON_COLROW )
            {
                // we have to renumber our row/column data to insert a new row/column
                implts_renumberRowColumnData((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, m_eDockOperation, aUIDockingElement );
            }
        }

        bStartDockFloated        = rUIElement.m_bFloating;
        rUIElement.m_bFloating   = m_aDockUIElement.m_bFloating;
        rUIElement.m_bUserActive = true;
    }

    // reset member for next docking operation
    m_aDockUIElement.m_xUIElement.clear();
    m_eDockOperation = DOCKOP_ON_COLROW;
    aWriteLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    implts_writeWindowStateData( aUIDockingElement );

    if ( bDockingInProgress )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        Window*  pWindow = VCLUnoHelper::GetWindow( uno::Reference< awt::XWindow >( e.Source, uno::UNO_QUERY ));
        ToolBox* pToolBox = 0;
        if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
            pToolBox = (ToolBox *)pWindow;

        if ( pToolBox )
        {
            if( e.bFloating )
            {
                if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
                    pToolBox->SetAlign( WINDOWALIGN_TOP );
                else
                    pToolBox->SetAlign( WINDOWALIGN_LEFT );
            }
            else
            {
                ::Size aSize;

                pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );

                // Docked toolbars have always one line
                aSize = pToolBox->CalcWindowSizePixel( 1 );

                // Lock layouting updates as our listener would be called due to SetSizePixel
                pToolBox->SetOutputSizePixel( aSize );
            }
        }
    }

    implts_sortUIElements();
    
    aWriteLock.lock();
    m_bDockingInProgress = sal_False;
    m_bLayoutDirty       = !bStartDockFloated || !bFloating;
    bool bNotify         = m_bLayoutDirty;
    aWriteLock.unlock();

    if ( bNotify )
        m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
}

sal_Bool SAL_CALL ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject& e ) 
throw (uno::RuntimeException)
{
    ReadGuard aReadLock( m_aLock );
    bool bDockingInProgress = m_bDockingInProgress;
    aReadLock.unlock();

    UIElement aUIDockingElement = implts_findToolbar( e.Source );
    bool      bWinFound( aUIDockingElement.m_aName.getLength() > 0 );
    uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY );

    if ( bWinFound && xWindow.is() )
    {
        if ( !bDockingInProgress )
        {
            awt::Rectangle aRect;
            uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
            if ( xDockWindow->isFloating() )
            {
                {
                    vos::OGuard aGuard( Application::GetSolarMutex() );
                    Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                    if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
                    {
                        ToolBox* pToolBox = static_cast< ToolBox *>( pWindow );
                        aUIDockingElement.m_aFloatingData.m_aPos          = pToolBox->GetPosPixel();
                        aUIDockingElement.m_aFloatingData.m_aSize         = pToolBox->GetOutputSizePixel();
                        aUIDockingElement.m_aFloatingData.m_nLines        = pToolBox->GetFloatingLines();
                        aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
                    }
                }

                UIElement aUIElement = implts_findToolbar( aUIDockingElement.m_aName );
                if ( aUIElement.m_aName == aUIDockingElement.m_aName )
                    implts_setToolbar( aUIDockingElement );
            }
        }
    }

    return sal_True;
}

void SAL_CALL ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject& e ) 
throw (uno::RuntimeException)
{
    UIElement aUIDockingElement;

    ReadGuard aReadLock( m_aLock );
    bool bDockingInProgress( m_bDockingInProgress );
    if ( bDockingInProgress )
        aUIDockingElement = m_aDockUIElement;
    aReadLock.unlock();

    Window*  pWindow( 0 );
    ToolBox* pToolBox( 0 );
    uno::Reference< awt::XWindow2 > xWindow;

    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        xWindow = uno::Reference< awt::XWindow2 >( e.Source, uno::UNO_QUERY );
        pWindow = VCLUnoHelper::GetWindow( xWindow );

        if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
            pToolBox = (ToolBox *)pWindow;
    }

    if ( !bDockingInProgress )
    {
        aUIDockingElement = implts_findToolbar( e.Source );
        bool bWinFound = ( aUIDockingElement.m_aName.getLength() > 0 );
        
        if ( bWinFound && xWindow.is() )
        {
            aUIDockingElement.m_bFloating   = !aUIDockingElement.m_bFloating;
            aUIDockingElement.m_bUserActive = true;

            implts_setLayoutInProgress( true );
            if ( aUIDockingElement.m_bFloating )
            {
                vos::OGuard aGuard( Application::GetSolarMutex() );
                if ( pToolBox )
                {
                    pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines );
                    if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
                        pToolBox->SetAlign( WINDOWALIGN_TOP );
                    else
                        pToolBox->SetAlign( WINDOWALIGN_LEFT );
                }

                bool bUndefPos = hasDefaultPosValue( aUIDockingElement.m_aFloatingData.m_aPos );
                bool bSetSize = !hasEmptySize( aUIDockingElement.m_aFloatingData.m_aSize );

                if ( bUndefPos )
                    aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos();

                if ( !bSetSize )
                {
                    if ( pToolBox )
                        aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->CalcFloatingWindowSizePixel();
                    else
                        aUIDockingElement.m_aFloatingData.m_aSize = pWindow->GetOutputSizePixel();
                }

                xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X(),
                                     aUIDockingElement.m_aFloatingData.m_aPos.Y(),
                                     0, 0, awt::PosSize::POS );
                xWindow->setOutputSize( AWTSize( aUIDockingElement.m_aFloatingData.m_aSize ) );
            }
            else
            {
                if ( isDefaultPos( aUIDockingElement.m_aDockedData.m_aPos ))
                {
                    // Docking on its default position without a preset position -
                    // we have to find a good place for it.
                    ::Point aPixelPos;
                    ::Point aDockPos;
                    ::Size  aSize;

                    {
                        vos::OGuard aGuard( Application::GetSolarMutex() );
                        if ( pToolBox )
                            aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) );
                        else
                            aSize = pWindow->GetSizePixel();
                    }

                    implts_findNextDockingPos((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
                    aUIDockingElement.m_aDockedData.m_aPos = aDockPos;
                }

                vos::OGuard aGuard( Application::GetSolarMutex() );
                if ( pToolBox )
                {
                    pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
                    ::Size aSize = pToolBox->CalcWindowSizePixel( 1 );
                    awt::Rectangle aRect = xWindow->getPosSize();
                    xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, awt::PosSize::POS );
                    xWindow->setOutputSize( AWTSize( aSize ) );
                }
            }

            implts_setLayoutInProgress( false );
            implts_setToolbar( aUIDockingElement );
            implts_writeWindowStateData( aUIDockingElement );
            implts_sortUIElements();
            implts_setLayoutDirty();
            
            aReadLock.lock();
            ILayoutNotifications* pParentLayouter( m_pParentLayouter );
            aReadLock.unlock();

            if ( pParentLayouter )
                pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
        }
    }
    else
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        if ( pToolBox )
        {
            if ( aUIDockingElement.m_bFloating )
            {
                if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
                    pToolBox->SetAlign( WINDOWALIGN_TOP );
                else
                    pToolBox->SetAlign( WINDOWALIGN_LEFT );
            }
            else
                pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
        }
    }
}

void SAL_CALL ToolbarLayoutManager::closed( const lang::EventObject& e ) 
throw (uno::RuntimeException)
{
    rtl::OUString aName;
    UIElement     aUIElement;
    UIElementVector::iterator pIter;

    WriteGuard aWriteLock( m_aLock );
    for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
    {
        uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
        if ( xUIElement.is() )
        {
            uno::Reference< uno::XInterface > xIfac( xUIElement->getRealInterface(), uno::UNO_QUERY );
            if ( xIfac == e.Source )
            {
                aName = pIter->m_aName;

                // user closes a toolbar =>
                // context sensitive toolbar: only destroy toolbar and store state.
                // context sensitive toolbar: make it invisible, store state and destroy it.
                if ( !pIter->m_bContextSensitive )
                    pIter->m_bVisible = sal_False;

                aUIElement = *pIter;
                break;
            }
        }
    }
    aWriteLock.unlock();

    // destroy element
    if ( aName.getLength() > 0 )
    {
        implts_writeWindowStateData( aUIElement );
        destroyToolbar( aName );
    }
}

void SAL_CALL ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent& /*e*/ ) 
throw (uno::RuntimeException)
{
}

//---------------------------------------------------------------------------------------------------------
//  XUIConfigurationListener
//---------------------------------------------------------------------------------------------------------
void SAL_CALL ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent& rEvent ) 
throw (uno::RuntimeException)
{
    UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );

    uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
    if ( xElementSettings.is() )
    {
        ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
        uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
        if ( xPropSet.is() )
        {
            if ( rEvent.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
                xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr ));
        }
        xElementSettings->updateSettings();
    }
    else
    {
        ::rtl::OUString aElementType;
        ::rtl::OUString aElementName;
        parseResourceURL( rEvent.ResourceURL, aElementType, aElementName );
        if ( aElementName.indexOf( m_aCustomTbxPrefix ) != -1 )
        {
            // custom toolbar must be directly created, shown and layouted!
            createToolbar( rEvent.ResourceURL );
            uno::Reference< ui::XUIElement > xUIElement = getToolbar( rEvent.ResourceURL );
            if ( xUIElement.is() )
            {
                ::rtl::OUString                               aUIName;
                uno::Reference< ui::XUIConfigurationManager > xCfgMgr;
                uno::Reference< beans::XPropertySet >         xPropSet;

                try
                {
                    xCfgMgr  = uno::Reference< ui::XUIConfigurationManager >( rEvent.Source, uno::UNO_QUERY );
                    xPropSet = uno::Reference< beans::XPropertySet >( xCfgMgr->getSettings( rEvent.ResourceURL, sal_False ), uno::UNO_QUERY );

                    if ( xPropSet.is() )
                        xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
                }
                catch ( container::NoSuchElementException& ) {}
                catch ( beans::UnknownPropertyException& ) {}
                catch ( lang::WrappedTargetException& ) {}

                {
                    vos::OGuard aGuard( Application::GetSolarMutex() );
                    Window* pWindow = getWindowFromXUIElement( xUIElement );
                    if ( pWindow  )
                        pWindow->SetText( aUIName );
                }

                showToolbar( rEvent.ResourceURL );
            }
        }
    }
}

void SAL_CALL ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent& rEvent ) 
throw (uno::RuntimeException)
{
    ReadGuard aReadLock( m_aLock );
    uno::Reference< awt::XWindow > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
    uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
    uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
    aReadLock.unlock();
    
    UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
    uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
    if ( xElementSettings.is() )
    {
        bool                                  bNoSettings( false );
        ::rtl::OUString                       aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
        uno::Reference< uno::XInterface >     xElementCfgMgr;
        uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );

        if ( xPropSet.is() )
            xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;

        if ( !xElementCfgMgr.is() )
            return;

        // Check if the same UI configuration manager has changed => check further
        if ( rEvent.Source == xElementCfgMgr )
        {
            // Same UI configuration manager where our element has its settings
            if ( rEvent.Source == uno::Reference< uno::XInterface >( xDocCfgMgr, uno::UNO_QUERY ))
            {
                // document settings removed
                if ( xModuleCfgMgr->hasSettings( rEvent.ResourceURL ))
                {
                    xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( xModuleCfgMgr ));
                    xElementSettings->updateSettings();
                    return;
                }
            }

            bNoSettings = true;
        }

        // No settings anymore, element must be destroyed
        if ( xContainerWindow.is() && bNoSettings )
            destroyToolbar( rEvent.ResourceURL );
    }
}

void SAL_CALL ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent& rEvent ) 
throw (uno::RuntimeException)
{
    UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );

    uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
    if ( xElementSettings.is() )
    {
        ::rtl::OUString                       aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
        uno::Reference< uno::XInterface >     xElementCfgMgr;
        uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );

        if ( xPropSet.is() )
            xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;

        if ( !xElementCfgMgr.is() )
            return;

        // Check if the same UI configuration manager has changed => update settings
        if ( rEvent.Source == xElementCfgMgr )
        {
            xElementSettings->updateSettings();
            
            WriteGuard aWriteLock( m_aLock );
            bool bNotify = !aUIElement.m_bFloating;
            m_bLayoutDirty = bNotify;
            ILayoutNotifications* pParentLayouter( m_pParentLayouter );
            aWriteLock.unlock();

            if ( bNotify && pParentLayouter )
                pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
        }
    }
}

uno::Reference< ui::XUIElement > ToolbarLayoutManager::getToolbar( const ::rtl::OUString& aName )
{
    return implts_findToolbar( aName ).m_xUIElement;
}

uno::Sequence< uno::Reference< ui::XUIElement > > ToolbarLayoutManager::getToolbars()
{
    uno::Sequence< uno::Reference< ui::XUIElement > > aSeq;
    
    ReadGuard aReadLock( m_aLock );
    if ( m_aUIElements.size() > 0 )
    {
        sal_uInt32 nCount(0);
        UIElementVector::iterator pIter;
        for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
        {
            if ( pIter->m_xUIElement.is() )
            {
                ++nCount;
                aSeq.realloc( nCount );
                aSeq[nCount-1] = pIter->m_xUIElement;
            }
        }
    }

    return aSeq;
}

bool ToolbarLayoutManager::floatToolbar( const ::rtl::OUString& rResourceURL )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    if ( aUIElement.m_xUIElement.is() )
    {
        try
        {
            uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            if ( xDockWindow.is() && !xDockWindow->isFloating() )
            {
                aUIElement.m_bFloating = true;
                implts_writeWindowStateData( aUIElement );
                xDockWindow->setFloatingMode( true );

                implts_setLayoutDirty();
                implts_setToolbar( aUIElement );                
                return true;
            }
        }
        catch ( lang::DisposedException& ) {}
    }

    return false;
}

bool ToolbarLayoutManager::lockToolbar( const ::rtl::OUString& rResourceURL )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    if ( aUIElement.m_xUIElement.is() )
    {
        try
        {
            uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            if ( xDockWindow.is() && !xDockWindow->isFloating() && !xDockWindow->isLocked() )
            {
                aUIElement.m_aDockedData.m_bLocked = true;
                implts_writeWindowStateData( aUIElement );
                xDockWindow->lock();

                implts_setLayoutDirty();
                implts_setToolbar( aUIElement );                
                return true;
            }
        }
        catch ( lang::DisposedException& ) {}
    }

    return false;
}

bool ToolbarLayoutManager::unlockToolbar( const ::rtl::OUString& rResourceURL )
{
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    if ( aUIElement.m_xUIElement.is() )
    {
        try
        {
            uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
            if ( xDockWindow.is() && !xDockWindow->isFloating() && xDockWindow->isLocked() )
            {
                aUIElement.m_aDockedData.m_bLocked = false;
                implts_writeWindowStateData( aUIElement );
                xDockWindow->unlock();

                implts_setLayoutDirty();
                implts_setToolbar( aUIElement );                
                return true;
            }
        }
        catch ( lang::DisposedException& ) {}
    }

    return false;
}

bool ToolbarLayoutManager::isToolbarVisible( const ::rtl::OUString& rResourceURL )
{
    uno::Reference< awt::XWindow2 > xWindow2( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
    return ( xWindow2.is() && xWindow2->isVisible() );
}

bool ToolbarLayoutManager::isToolbarFloating( const ::rtl::OUString& rResourceURL )
{
    uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
    return ( xDockWindow.is() && xDockWindow->isFloating() );
}

bool ToolbarLayoutManager::isToolbarDocked( const ::rtl::OUString& rResourceURL )
{
    return !isToolbarFloating( rResourceURL );
}    

bool ToolbarLayoutManager::isToolbarLocked( const ::rtl::OUString& rResourceURL )
{
    uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
    return ( xDockWindow.is() && xDockWindow->isLocked() );
}

awt::Size ToolbarLayoutManager::getToolbarSize( const ::rtl::OUString& rResourceURL )
{
    Window* pWindow = implts_getWindow( rResourceURL );
    
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if ( pWindow )
    {
        ::Size    aSize = pWindow->GetSizePixel();
        awt::Size aWinSize;
        aWinSize.Width  = aSize.Width();
        aWinSize.Height = aSize.Height();
        return aWinSize;
    }

    return awt::Size();
}

awt::Point ToolbarLayoutManager::getToolbarPos( const ::rtl::OUString& rResourceURL )
{
    awt::Point aPos;
    UIElement  aUIElement = implts_findToolbar( rResourceURL );
    
    uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
    if ( xWindow.is() )
    {
        if ( aUIElement.m_bFloating )
        {
            awt::Rectangle aRect = xWindow->getPosSize();
            aPos.X = aRect.X;
            aPos.Y = aRect.Y;
        }
        else
        {
            ::Point aVirtualPos = aUIElement.m_aDockedData.m_aPos;
            aPos.X = aVirtualPos.X();
            aPos.Y = aVirtualPos.Y();
        }
    }
    
    return aPos;
}

void ToolbarLayoutManager::setToolbarSize( const ::rtl::OUString& rResourceURL, const awt::Size& aSize )
{
  uno::Reference< awt::XWindow2 > xWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
    uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    
    if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
    {
        xWindow->setOutputSize( aSize );
        aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
        implts_setToolbar( aUIElement );
        implts_writeWindowStateData( aUIElement );
        implts_sortUIElements();
    }
}

void ToolbarLayoutManager::setToolbarPos( const ::rtl::OUString& rResourceURL, const awt::Point& aPos )
{
    uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
    uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
    UIElement aUIElement = implts_findToolbar( rResourceURL );
    
    if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
    {
        xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS );
        aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y );
        implts_setToolbar( aUIElement );
        implts_writeWindowStateData( aUIElement );
        implts_sortUIElements();
    }
}

void ToolbarLayoutManager::setToolbarPosSize( const ::rtl::OUString& rResourceURL, const awt::Point& aPos, const awt::Size& aSize )
{
    setToolbarPos( rResourceURL, aPos );
    setToolbarSize( rResourceURL, aSize );
}

} // namespace framework
