| /************************************************************** |
| * |
| * 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; |
| } |
| |
| namespace |
| { |
| void insertDockingAreaSize( |
| const UIElement& rUIElement, |
| const awt::Rectangle& rUIElementPosSize, |
| std::vector< sal_Int32 >& rDockingAreaData ) |
| { |
| sal_Int32 nAreaPos = 0; |
| sal_Int32 nSize = 0; |
| if ( isHorizontalDockingArea( rUIElement.m_aDockedData.m_nDockedArea ) ) |
| { |
| nAreaPos = rUIElement.m_aDockedData.m_aPos.Y(); |
| nSize = rUIElementPosSize.Height; |
| } |
| else |
| { |
| nAreaPos = rUIElement.m_aDockedData.m_aPos.X(); |
| nSize = rUIElementPosSize.Width; |
| } |
| |
| const sal_uInt32 nIndexPos = nAreaPos >= 0 ? static_cast< sal_uInt32 >(nAreaPos) : 0; |
| if ( rDockingAreaData.size() < nIndexPos + 1 ) |
| { |
| rDockingAreaData.resize( nIndexPos + 1, 0 ); |
| } |
| |
| if ( rDockingAreaData[nIndexPos] < nSize ) |
| { |
| rDockingAreaData[nIndexPos] = nSize; |
| } |
| } |
| |
| |
| sal_Int32 calcDockingAreaSize( const std::vector< sal_Int32 >& rDockingAreaData ) |
| { |
| sal_Int32 nDockingAreaSize = 0; |
| |
| std::vector< sal_Int32 >::const_iterator iDockingAreaDataEnd = rDockingAreaData.end(); |
| for ( std::vector< sal_Int32 >::const_iterator iDockingAreaData = rDockingAreaData.begin(); |
| iDockingAreaData != iDockingAreaDataEnd; |
| ++iDockingAreaData ) |
| { |
| nDockingAreaSize += *(iDockingAreaData); |
| } |
| |
| return nDockingAreaSize; |
| } |
| } |
| |
| |
| Rectangle ToolbarLayoutManager::implts_calcDockingArea() |
| { |
| Rectangle aBorderSpace( 0, 0, 0, 0 ); |
| |
| // For each docking area one container of UIElement sizes. |
| std::vector< std::vector< sal_Int32 > >aDockingAreaSizeDatas( DOCKINGAREAS_COUNT ); |
| |
| { |
| ReadGuard aReadLock( m_aLock ); |
| vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // Iterate over the UIElements and collect corresponding docking area data |
| // for non-floating and visible ones separated for the each docking area. |
| // Note: For each docking area row resp. column only the size of largest UIElement is collected. |
| for ( UIElementVector::const_iterator pConstIter = m_aUIElements.begin(); pConstIter != m_aUIElements.end(); ++pConstIter ) |
| { |
| if ( !pConstIter->m_bVisible |
| || pConstIter->m_bMasterHide ) |
| { |
| continue; |
| } |
| |
| 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() ) |
| { |
| Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); |
| if ( pWindow != NULL |
| && !xDockWindow->isFloating() ) |
| { |
| const awt::Rectangle aPosSize = xWindow->getPosSize(); |
| insertDockingAreaSize( |
| *(pConstIter), |
| aPosSize, |
| aDockingAreaSizeDatas[pConstIter->m_aDockedData.m_nDockedArea] ); |
| } |
| } |
| } |
| } |
| |
| aReadLock.unlock(); |
| } |
| |
| aBorderSpace.Top() = calcDockingAreaSize( aDockingAreaSizeDatas[ui::DockingArea_DOCKINGAREA_TOP] ); |
| aBorderSpace.Bottom() = calcDockingAreaSize( aDockingAreaSizeDatas[ui::DockingArea_DOCKINGAREA_BOTTOM] ); |
| aBorderSpace.Left() = calcDockingAreaSize( aDockingAreaSizeDatas[ui::DockingArea_DOCKINGAREA_LEFT] ); |
| aBorderSpace.Right() = calcDockingAreaSize( aDockingAreaSizeDatas[ui::DockingArea_DOCKINGAREA_RIGHT] ); |
| |
| 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::implts_setToolbarVisibility( |
| bool bVisible, |
| UIElement aUIElement ) |
| { |
| bool bRet = false; |
| |
| vos::OGuard aGuard( Application::GetSolarMutex() ); |
| Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement ); |
| if ( pWindow ) |
| { |
| if ( bVisible ) |
| { |
| pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); |
| } |
| else |
| { |
| pWindow->Show( sal_False ); |
| } |
| if ( !aUIElement.m_bFloating ) |
| { |
| implts_setLayoutDirty(); |
| } |
| |
| bRet = true; |
| } |
| |
| return bRet; |
| } |
| |
| bool ToolbarLayoutManager::showToolbar( const ::rtl::OUString& rResourceURL ) |
| { |
| UIElement aUIElement = implts_findToolbar( rResourceURL ); |
| const bool bRet = implts_setToolbarVisibility( true, aUIElement ); |
| aUIElement.m_bVisible = true; |
| implts_writeWindowStateData( aUIElement ); |
| implts_setToolbar( aUIElement ); |
| implts_sortUIElements(); |
| return bRet; |
| } |
| |
| bool ToolbarLayoutManager::hideToolbar( const ::rtl::OUString& rResourceURL ) |
| { |
| UIElement aUIElement = implts_findToolbar( rResourceURL ); |
| const bool bRet = implts_setToolbarVisibility( false, aUIElement ); |
| aUIElement.m_bVisible = false; |
| implts_writeWindowStateData( aUIElement ); |
| implts_setToolbar( aUIElement ); |
| implts_sortUIElements(); |
| return bRet; |
| } |
| |
| void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars ) |
| { |
| if ( !bAutomaticToolbars ) |
| return; |
| |
| ReadGuard aReadLock( m_aLock ); |
| if ( !m_bVisible ) |
| return; |
| aReadLock.unlock(); |
| |
| UIElementVector aUIElementVector; |
| 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++ ) |
| { |
| implts_setToolbarVisibility( bVisible, *pIter ); |
| pIter->m_bMasterHide = !bVisible; |
| implts_setToolbar( *pIter ); |
| } |
| |
| implts_sortUIElements(); |
| |
| 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; |
| |
| 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 |
| && !pIter->m_bMasterHide ) |
| { |
| 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 retrieve 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 according 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 ); |
| const 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_bMasterHide |
| && !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 |
| && pIter->m_bVisible |
| && !pIter->m_bMasterHide |
| && !pIter->m_bFloating ) |
| { |
| 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 != NULL |
| && xDockWindow.is() ) |
| { |
| 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 |