| /************************************************************** |
| * |
| * 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_sfx2.hxx" |
| |
| #include <svl/eitem.hxx> |
| #include <vcl/decoview.hxx> |
| |
| #include <vcl/svapp.hxx> |
| #include <vcl/timer.hxx> |
| #include <rtl/instance.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <comphelper/processfactory.hxx> |
| |
| #include <sfx2/dockwin.hxx> |
| #include <sfx2/bindings.hxx> |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/dispatch.hxx> |
| #include "workwin.hxx" |
| #include "splitwin.hxx" |
| #include <sfx2/viewsh.hxx> |
| #include "sfx2/sfxhelp.hxx" |
| #include <sfx2/objsh.hxx> |
| #include <sfx2/msgpool.hxx> |
| |
| #include <com/sun/star/frame/XController.hpp> |
| #include <com/sun/star/lang/XUnoTunnel.hpp> |
| #include <com/sun/star/lang/XSingleComponentFactory.hpp> |
| #include <com/sun/star/awt/XWindow.hpp> |
| #include <com/sun/star/uno/XComponentContext.hpp> |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| |
| #define MAX_TOGGLEAREA_WIDTH 20 |
| #define MAX_TOGGLEAREA_HEIGHT 20 |
| |
| using namespace ::com::sun::star; |
| |
| // implemented in 'sfx2/source/appl/childwin.cxx' |
| extern sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize ); |
| extern sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize ); |
| |
| // If you want to change the number you also have to: |
| // - Add new slot ids to sfxsids.hrc |
| // - Add new slots to frmslots.sdi |
| // - Add new slot definitions to sfx.sdi |
| static const int NUM_OF_DOCKINGWINDOWS = 10; |
| |
| class SfxTitleDockingWindow; |
| class SfxTitleDockingWindow : public SfxDockingWindow |
| { |
| Window* m_pWrappedWindow; |
| sal_uInt16 m_nID; |
| |
| public: |
| SfxTitleDockingWindow( |
| SfxBindings* pBindings , |
| SfxChildWindow* pChildWin , |
| Window* pParent , |
| WinBits nBits, |
| sal_uInt16 nID); |
| virtual ~SfxTitleDockingWindow(); |
| |
| Window* GetWrappedWindow() const { return m_pWrappedWindow; } |
| void SetWrappedWindow(Window* const pWindow); |
| |
| virtual void StateChanged( StateChangedType nType ); |
| virtual long Notify( NotifyEvent& rNEvt ); |
| virtual void Resize(); |
| virtual void Resizing( Size& rSize ); |
| virtual sal_Bool Close(); |
| }; |
| |
| namespace |
| { |
| struct WindowState |
| { |
| ::rtl::OUString sTitle; |
| }; |
| } |
| |
| static uno::WeakReference< container::XNameAccess > m_xWindowStateConfiguration; |
| static uno::WeakReference< frame::XModuleManager > m_xModuleManager; |
| |
| static bool lcl_getWindowState( const uno::Reference< container::XNameAccess >& xWindowStateMgr, const ::rtl::OUString& rResourceURL, WindowState& rWindowState ) |
| { |
| bool bResult = false; |
| |
| try |
| { |
| uno::Any a; |
| uno::Sequence< beans::PropertyValue > aWindowState; |
| a = xWindowStateMgr->getByName( rResourceURL ); |
| if ( a >>= aWindowState ) |
| { |
| for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ ) |
| { |
| if ( aWindowState[n].Name.equalsAscii( "UIName" )) |
| { |
| aWindowState[n].Value >>= rWindowState.sTitle; |
| } |
| } |
| } |
| |
| bResult = true; |
| } |
| catch ( container::NoSuchElementException& ) |
| { |
| bResult = false; |
| } |
| |
| return bResult; |
| } |
| |
| SfxDockingWrapper::SfxDockingWrapper( Window* pParentWnd , |
| sal_uInt16 nId , |
| SfxBindings* pBindings , |
| SfxChildWinInfo* pInfo ) |
| : SfxChildWindow( pParentWnd , nId ) |
| { |
| uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); |
| const rtl::OUString aDockWindowResourceURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/dockingwindow/" )); |
| |
| SfxTitleDockingWindow* pTitleDockWindow = new SfxTitleDockingWindow( pBindings, this, pParentWnd, |
| WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE, nId); |
| pWindow = pTitleDockWindow; |
| eChildAlignment = SFX_ALIGN_NOALIGNMENT; |
| |
| // Use factory manager to retrieve XWindow factory. That can be used to instanciate |
| // the real window factory. |
| uno::Reference< lang::XSingleComponentFactory > xFactoryMgr( |
| xServiceManager->createInstance( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.ui.WindowContentFactoryManager"))), |
| uno::UNO_QUERY ); |
| |
| if (xFactoryMgr.is()) |
| { |
| SfxDispatcher* pDispatcher = pBindings->GetDispatcher(); |
| uno::Reference< frame::XFrame > xFrame( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); |
| uno::Sequence< uno::Any > aArgs(2); |
| beans::PropertyValue aPropValue; |
| aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); |
| aPropValue.Value = uno::makeAny( xFrame ); |
| aArgs[0] <<= aPropValue; |
| aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )); |
| |
| // create a resource URL from the nId provided by the sfx2 |
| ::rtl::OUString aResourceURL( aDockWindowResourceURL ); |
| aResourceURL += ::rtl::OUString::valueOf(sal_Int32(nId)); |
| aPropValue.Value = uno::makeAny( aResourceURL ); |
| aArgs[1] <<= aPropValue; |
| |
| uno::Reference< awt::XWindow > xWindow; |
| try |
| { |
| uno::Reference< beans::XPropertySet > xProps( xServiceManager, uno::UNO_QUERY ); |
| uno::Reference< uno::XComponentContext > xContext; |
| |
| if ( xProps.is() ) |
| xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext; |
| if ( xContext.is() ) |
| { |
| xWindow = uno::Reference< awt::XWindow>( |
| xFactoryMgr->createInstanceWithArgumentsAndContext( aArgs, xContext ), |
| uno::UNO_QUERY ); |
| } |
| |
| uno::Reference< frame::XModuleManager > xModuleManager( m_xModuleManager ); |
| if ( !xModuleManager.is() ) |
| { |
| xModuleManager = uno::Reference< frame::XModuleManager >( |
| xServiceManager->createInstance( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))), |
| uno::UNO_QUERY ); |
| m_xModuleManager = xModuleManager; |
| } |
| |
| uno::Reference< container::XNameAccess > xWindowStateConfiguration( m_xWindowStateConfiguration ); |
| if ( !xWindowStateConfiguration.is() ) |
| { |
| xWindowStateConfiguration = uno::Reference< container::XNameAccess >( |
| xServiceManager->createInstance( |
| rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.WindowStateConfiguration" ))), |
| uno::UNO_QUERY ); |
| m_xWindowStateConfiguration = xWindowStateConfiguration; |
| } |
| |
| ::rtl::OUString sModuleIdentifier = xModuleManager->identify( xFrame ); |
| |
| uno::Reference< container::XNameAccess > xModuleWindowState( |
| xWindowStateConfiguration->getByName( sModuleIdentifier ), |
| uno::UNO_QUERY ); |
| if ( xModuleWindowState.is() ) |
| { |
| WindowState aDockWinState; |
| if ( lcl_getWindowState( xModuleWindowState, aResourceURL, aDockWinState )) |
| pTitleDockWindow->SetText( aDockWinState.sTitle ); |
| } |
| } |
| catch ( beans::UnknownPropertyException& ) |
| { |
| } |
| catch ( uno::RuntimeException& ) |
| { |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| Window* pContentWindow = VCLUnoHelper::GetWindow(xWindow); |
| if ( pContentWindow ) |
| pContentWindow->SetStyle( pContentWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL ); |
| pTitleDockWindow->SetWrappedWindow(pContentWindow); |
| } |
| |
| pWindow->SetOutputSizePixel( Size( 270, 240 ) ); |
| |
| ( ( SfxDockingWindow* ) pWindow )->Initialize( pInfo ); |
| SetHideNotDelete( sal_True ); |
| } |
| |
| SfxChildWindow* SfxDockingWrapper::CreateImpl( |
| Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo* pInfo ) |
| { |
| SfxChildWindow *pWin = new SfxDockingWrapper(pParent, nId, pBindings, pInfo); return pWin; |
| } |
| |
| sal_uInt16 SfxDockingWrapper::GetChildWindowId () |
| { |
| DBG_ASSERT( false, "This method shouldn't be called!" ); |
| return 0; |
| } |
| |
| void SfxDockingWrapper::RegisterChildWindow (sal_Bool bVis, SfxModule *pMod, sal_uInt16 nFlags) |
| { |
| // pre-register a couple of docking windows |
| for (int i=0; i < NUM_OF_DOCKINGWINDOWS; i++ ) |
| { |
| sal_uInt16 nID = sal_uInt16(SID_DOCKWIN_START+i); |
| SfxChildWinFactory *pFact = new SfxChildWinFactory( SfxDockingWrapper::CreateImpl, nID, 0xffff ); |
| pFact->aInfo.nFlags |= nFlags; |
| pFact->aInfo.bVisible = bVis; |
| SfxChildWindow::RegisterChildWindow(pMod, pFact); |
| } |
| } |
| |
| SfxChildWinInfo SfxDockingWrapper::GetInfo() const |
| { |
| SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); |
| ((SfxDockingWindow*)GetWindow())->FillInfo( aInfo ); |
| return aInfo; |
| }; |
| |
| SfxTitleDockingWindow::SfxTitleDockingWindow( SfxBindings* pBind , |
| SfxChildWindow* pChildWin , |
| Window* pParent , |
| WinBits nBits, |
| sal_uInt16 nID ) : |
| SfxDockingWindow( pBind , |
| pChildWin , |
| pParent , |
| nBits ), |
| m_pWrappedWindow(0), |
| m_nID(nID) |
| { |
| } |
| |
| SfxTitleDockingWindow::~SfxTitleDockingWindow() |
| { |
| delete m_pWrappedWindow; |
| } |
| |
| void SfxTitleDockingWindow::SetWrappedWindow( Window* const pWindow ) |
| { |
| m_pWrappedWindow = pWindow; |
| if (m_pWrappedWindow) |
| { |
| m_pWrappedWindow->SetParent(this); |
| m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); |
| m_pWrappedWindow->Show(); |
| } |
| } |
| |
| long SfxTitleDockingWindow::Notify( NotifyEvent& rNEvt ) |
| { |
| return SfxDockingWindow::Notify( rNEvt ); |
| } |
| |
| void SfxTitleDockingWindow::StateChanged( StateChangedType nType ) |
| { |
| if ( nType == STATE_CHANGE_INITSHOW ) |
| { |
| Window* pWindow = GetWrappedWindow(); |
| if ( pWindow ) |
| { |
| pWindow->SetSizePixel( GetOutputSizePixel() ); |
| pWindow->Show(); |
| } |
| } |
| |
| SfxDockingWindow::StateChanged(nType); |
| } |
| |
| void SfxTitleDockingWindow::Resize() |
| { |
| SfxDockingWindow::Resize(); |
| if (m_pWrappedWindow) |
| m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); |
| } |
| |
| void SfxTitleDockingWindow::Resizing( Size &rSize ) |
| { |
| SfxDockingWindow::Resizing( rSize ); |
| if (m_pWrappedWindow) |
| m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); |
| } |
| |
| sal_Bool SfxTitleDockingWindow::Close() |
| { |
| return SfxDockingWindow::Close(); |
| } |
| |
| namespace |
| { |
| struct ChildrenRegisteredMap : public rtl::Static< bool, ChildrenRegisteredMap > {}; |
| } |
| |
| static bool lcl_checkDockingWindowID( sal_uInt16 nID ) |
| { |
| if (nID < SID_DOCKWIN_START || nID >= sal_uInt16(SID_DOCKWIN_START+NUM_OF_DOCKINGWINDOWS)) |
| return false; |
| else |
| return true; |
| } |
| |
| static SfxWorkWindow* lcl_getWorkWindowFromXFrame( const uno::Reference< frame::XFrame >& rFrame ) |
| { |
| // We need to find the corresponding SfxFrame of our XFrame |
| SfxFrame* pFrame = SfxFrame::GetFirst(); |
| SfxFrame* pXFrame = 0; |
| while ( pFrame ) |
| { |
| uno::Reference< frame::XFrame > xViewShellFrame( pFrame->GetFrameInterface() ); |
| if ( xViewShellFrame == rFrame ) |
| { |
| pXFrame = pFrame; |
| break; |
| } |
| else |
| pFrame = SfxFrame::GetNext( *pFrame ); |
| } |
| |
| // If we have a SfxFrame we can retrieve the work window (Sfx layout manager for docking windows) |
| if ( pXFrame ) |
| return pXFrame->GetWorkWindow_Impl(); |
| else |
| return NULL; |
| } |
| |
| /* |
| Factory function used by the framework layout manager to "create" a docking window with a special name. |
| The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot range located |
| in sfxsids.hrc (currently SID_DOCKWIN_START = 9800). |
| */ |
| void SAL_CALL SfxDockingWindowFactory( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32()); |
| |
| // Check the range of the provided ID otherwise nothing will happen |
| if ( lcl_checkDockingWindowID( nID )) |
| { |
| SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame ); |
| if ( pWorkWindow ) |
| { |
| SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID); |
| if ( !pChildWindow ) |
| { |
| // Register window at the workwindow child window list |
| pWorkWindow->SetChildWindow_Impl( nID, true, false ); |
| } |
| } |
| } |
| } |
| |
| /* |
| Function used by the framework layout manager to determine the visibility state of a docking window with |
| a special name. The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot |
| range located in sfxsids.hrc (currently SID_DOCKWIN_START = 9800). |
| */ |
| bool SAL_CALL IsDockingWindowVisible( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32()); |
| |
| // Check the range of the provided ID otherwise nothing will happen |
| if ( lcl_checkDockingWindowID( nID )) |
| { |
| SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame ); |
| if ( pWorkWindow ) |
| { |
| SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID); |
| if ( pChildWindow ) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| class SfxDockingWindow_Impl |
| { |
| friend class SfxDockingWindow; |
| |
| SfxChildAlignment eLastAlignment; |
| SfxChildAlignment eDockAlignment; |
| sal_Bool bConstructed; |
| Size aMinSize; |
| SfxSplitWindow* pSplitWin; |
| sal_Bool bSplitable; |
| // sal_Bool bAutoHide; |
| Timer aMoveTimer; |
| |
| // Folgende members sind nur in der Zeit von StartDocking bis EndDocking |
| // g"ultig: |
| sal_Bool bEndDocked; |
| Size aSplitSize; |
| long nHorizontalSize; |
| long nVerticalSize; |
| sal_uInt16 nLine; |
| sal_uInt16 nPos; |
| sal_uInt16 nDockLine; |
| sal_uInt16 nDockPos; |
| sal_Bool bNewLine; |
| sal_Bool bDockingPrevented; |
| ByteString aWinState; |
| |
| SfxChildAlignment GetLastAlignment() const |
| { return eLastAlignment; } |
| void SetLastAlignment(SfxChildAlignment eAlign) |
| { eLastAlignment = eAlign; } |
| SfxChildAlignment GetDockAlignment() const |
| { return eDockAlignment; } |
| void SetDockAlignment(SfxChildAlignment eAlign) |
| { eDockAlignment = eAlign; } |
| }; |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::Resize() |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow merkt sich ggf. eine |
| ver"anderte FloatingSize. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| auch SfxDockingWindow::Resize() gerufen werden. |
| */ |
| { |
| DockingWindow::Resize(); |
| Invalidate(); |
| if ( pImp->bConstructed && pMgr ) |
| { |
| if ( IsFloatingMode() ) |
| { |
| // start timer for saving window status information |
| pImp->aMoveTimer.Start(); |
| } |
| else |
| { |
| Size aSize( GetSizePixel() ); |
| switch ( pImp->GetDockAlignment() ) |
| { |
| case SFX_ALIGN_LEFT: |
| case SFX_ALIGN_FIRSTLEFT: |
| case SFX_ALIGN_LASTLEFT: |
| case SFX_ALIGN_RIGHT: |
| case SFX_ALIGN_FIRSTRIGHT: |
| case SFX_ALIGN_LASTRIGHT: |
| pImp->nHorizontalSize = aSize.Width(); |
| pImp->aSplitSize = aSize; |
| break; |
| case SFX_ALIGN_TOP: |
| case SFX_ALIGN_LOWESTTOP: |
| case SFX_ALIGN_HIGHESTTOP: |
| case SFX_ALIGN_BOTTOM: |
| case SFX_ALIGN_HIGHESTBOTTOM: |
| case SFX_ALIGN_LOWESTBOTTOM: |
| pImp->nVerticalSize = aSize.Height(); |
| pImp->aSplitSize = aSize; |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| sal_Bool SfxDockingWindow::PrepareToggleFloatingMode() |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow erm"oglicht ein Eingreifen |
| in das Umschalten des floating mode. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| danach SfxDockingWindow::PrepareToggleFloatingMode() gerufen werden, |
| wenn nicht FALSE zur"uckgegeben wird. |
| */ |
| |
| { |
| if (!pImp->bConstructed) |
| return sal_True; |
| |
| if ( (Application::IsInModalMode() && IsFloatingMode()) || !pMgr ) |
| return sal_False; |
| |
| if ( pImp->bDockingPrevented ) |
| return sal_False; |
| |
| if (!IsFloatingMode()) |
| { |
| // Testen, ob FloatingMode erlaubt ist |
| if ( CheckAlignment(GetAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT ) |
| return sal_False; |
| |
| if ( pImp->pSplitWin ) |
| { |
| // Das DockingWindow sitzt in einem SplitWindow und wird abgerissen |
| pImp->pSplitWin->RemoveWindow(this/*, sal_False*/); |
| pImp->pSplitWin = 0; |
| } |
| } |
| else if ( pMgr ) |
| { |
| pImp->aWinState = GetFloatingWindow()->GetWindowState(); |
| |
| // Testen, ob es erlaubt ist, anzudocken |
| if (CheckAlignment(GetAlignment(),pImp->GetLastAlignment()) == SFX_ALIGN_NOALIGNMENT) |
| return sal_False; |
| |
| // Testen, ob das Workwindow gerade ein Andocken erlaubt |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| if ( !pWorkWin->IsDockingAllowed() || !pWorkWin->IsInternalDockingAllowed() ) |
| return sal_False; |
| } |
| |
| return sal_True; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::ToggleFloatingMode() |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow setzt die internen |
| Daten des SfxDockingWindow und sorgt f"ur korrektes Alignment am |
| parent window. |
| Durch PrepareToggleFloatMode und Initialize ist sichergestellt, da\s |
| pImp->GetLastAlignment() immer eine erlaubtes Alignment liefert. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| zuerst SfxDockingWindow::ToggleFloatingMode() gerufen werden. |
| */ |
| { |
| if ( !pImp->bConstructed || !pMgr ) |
| return; // Kein Handler-Aufruf |
| |
| // Altes Alignment merken und dann umschalten. |
| // Sv hat jetzt schon umgeschaltet, aber Alignment am SfxDockingWindow |
| // ist noch das alte! |
| // Was war ich bisher ? |
| SfxChildAlignment eLastAlign = GetAlignment(); |
| |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; |
| if ( pImp->bSplitable ) |
| eIdent = SFX_CHILDWIN_SPLITWINDOW; |
| |
| if (IsFloatingMode()) |
| { |
| SetAlignment(SFX_ALIGN_NOALIGNMENT); |
| if ( pImp->aWinState.Len() ) |
| GetFloatingWindow()->SetWindowState( pImp->aWinState ); |
| else |
| GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() ); |
| /* |
| if ( pImp->bSplitable && !pImp->bEndDocked ) |
| // Wenn das Fenster vorher in einem SplitWindow lag, kommt von |
| // Sv kein Show |
| Show(); |
| */ |
| } |
| else |
| { |
| if (pImp->GetDockAlignment() == eLastAlign) |
| { |
| // Wenn ToggleFloatingMode aufgerufen wurde, das DockAlignment |
| // aber noch unver"andert ist, mu\s das ein Toggeln durch DClick |
| // gewesen sein, also LastAlignment verwenden |
| SetAlignment (pImp->GetLastAlignment()); |
| if ( !pImp->bSplitable ) |
| SetSizePixel( CalcDockingSize(GetAlignment()) ); |
| } |
| else |
| { |
| // Toggeln wurde durch Draggen ausgel"ost |
| pImp->nLine = pImp->nDockLine; |
| pImp->nPos = pImp->nDockPos; |
| SetAlignment (pImp->GetDockAlignment()); |
| } |
| |
| if ( pImp->bSplitable ) |
| { |
| // Das DockingWindow kommt jetzt in ein SplitWindow |
| pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment()); |
| |
| // Das LastAlignment ist jetzt immer noch das zuletzt angedockte |
| SfxSplitWindow *pSplit = pWorkWin->GetSplitWindow_Impl(pImp->GetLastAlignment()); |
| |
| DBG_ASSERT( pSplit, "LastAlignment kann nicht stimmen!" ); |
| if ( pSplit && pSplit != pImp->pSplitWin ) |
| pSplit->ReleaseWindow_Impl(this); |
| if ( pImp->GetDockAlignment() == eLastAlign ) |
| pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize ); |
| else |
| pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nLine, pImp->nPos, pImp->bNewLine ); |
| if ( !pImp->pSplitWin->IsFadeIn() ) |
| pImp->pSplitWin->FadeIn(); |
| } |
| } |
| |
| // altes Alignment festhalten f"ur n"achstes Togglen; erst jetzt setzen |
| // wg. Abmelden beim SplitWindow! |
| pImp->SetLastAlignment(eLastAlign); |
| |
| // DockAlignment zur"ucksetzen, falls noch EndDocking gerufen wird |
| pImp->SetDockAlignment(GetAlignment()); |
| |
| // SfxChildWindow korrekt andocken bzw. entdocken |
| if ( pMgr ) |
| pWorkWin->ConfigChild_Impl( eIdent, SFX_TOGGLEFLOATMODE, pMgr->GetType() ); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::StartDocking() |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow holt vom parent window |
| das innere und "au\sere docking rectangle. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| am Ende SfxDockingWindow::StartDocking() gerufen werden. |
| */ |
| { |
| if ( !pImp->bConstructed || !pMgr ) |
| return; |
| SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; |
| if ( pImp->bSplitable ) |
| eIdent = SFX_CHILDWIN_SPLITWINDOW; |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| pWorkWin->ConfigChild_Impl( eIdent, SFX_SETDOCKINGRECTS, pMgr->GetType() ); |
| pImp->SetDockAlignment(GetAlignment()); |
| |
| if ( pImp->pSplitWin ) |
| { |
| // Die aktuellen Docking-Daten besorgen |
| pImp->pSplitWin->GetWindowPos(this, pImp->nLine, pImp->nPos); |
| pImp->nDockLine = pImp->nLine; |
| pImp->nDockPos = pImp->nPos; |
| pImp->bNewLine = sal_False; |
| } |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| sal_Bool SfxDockingWindow::Docking( const Point& rPos, Rectangle& rRect ) |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow berechnet das aktuelle |
| tracking rectangle. Dazu benutzt sie die Methode CalcAlignment(rPos,rRect), |
| deren Verhalten von abgeleiteten Klassen beeinflu\st werden kann (s.u.). |
| Diese Methode sollte nach M"oglichkeit nicht "uberschrieben werden. |
| */ |
| { |
| if ( Application::IsInModalMode() ) |
| return sal_True; |
| |
| if ( !pImp->bConstructed || !pMgr ) |
| { |
| rRect.SetSize( Size() ); |
| return IsFloatingMode(); |
| } |
| |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| if ( pImp->bDockingPrevented || !pWorkWin->IsInternalDockingAllowed() ) |
| return sal_False; |
| |
| sal_Bool bFloatMode = sal_False; |
| |
| if ( GetOuterRect().IsInside( rPos ) && !IsDockingPrevented() ) |
| { |
| // Maus innerhalb OuterRect : Alignment und Rectangle berechnen |
| SfxChildAlignment eAlign = CalcAlignment(rPos, rRect); |
| if (eAlign == SFX_ALIGN_NOALIGNMENT) |
| bFloatMode = sal_True; |
| pImp->SetDockAlignment(eAlign); |
| } |
| else |
| { |
| // Maus nicht innerhalb OuterRect : muss FloatingWindow sein |
| // Ist das erlaubt ? |
| if (CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT) |
| return sal_False; |
| bFloatMode = sal_True; |
| if ( SFX_ALIGN_NOALIGNMENT != pImp->GetDockAlignment() ) |
| { |
| // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das |
| // Alignment "andert ! |
| pImp->SetDockAlignment(SFX_ALIGN_NOALIGNMENT); |
| rRect.SetSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT)); |
| } |
| } |
| |
| if ( !pImp->bSplitable ) |
| { |
| // Bei individuell angedocktem Window wird die Position durch das |
| // Alignment und die docking rects festgelegt. |
| Size aSize = rRect.GetSize(); |
| Point aPos; |
| |
| switch ( pImp->GetDockAlignment() ) |
| { |
| case SFX_ALIGN_LEFT: |
| case SFX_ALIGN_FIRSTLEFT: |
| case SFX_ALIGN_LASTLEFT: |
| aPos = aInnerRect.TopLeft(); |
| if ( pImp->GetDockAlignment() == GetAlignment() ) |
| aPos.X() -= aSize.Width(); |
| break; |
| |
| case SFX_ALIGN_TOP: |
| case SFX_ALIGN_LOWESTTOP: |
| case SFX_ALIGN_HIGHESTTOP: |
| aPos = Point(aOuterRect.Left(), aInnerRect.Top()); |
| if ( pImp->GetDockAlignment() == GetAlignment() ) |
| aPos.Y() -= aSize.Height(); |
| break; |
| |
| case SFX_ALIGN_RIGHT: |
| case SFX_ALIGN_FIRSTRIGHT: |
| case SFX_ALIGN_LASTRIGHT: |
| aPos = Point(aInnerRect.Right() - rRect.GetSize().Width(), |
| aInnerRect.Top()); |
| if ( pImp->GetDockAlignment() == GetAlignment() ) |
| aPos.X() += aSize.Width(); |
| break; |
| |
| case SFX_ALIGN_BOTTOM: |
| case SFX_ALIGN_HIGHESTBOTTOM: |
| case SFX_ALIGN_LOWESTBOTTOM: |
| aPos = Point(aOuterRect.Left(), |
| aInnerRect.Bottom() - rRect.GetSize().Height()); |
| if ( pImp->GetDockAlignment() == GetAlignment() ) |
| aPos.Y() += aSize.Height(); |
| break; |
| default: |
| break; |
| } |
| |
| rRect.SetPos(aPos); |
| } |
| |
| return bFloatMode; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode ) |
| |
| /* [Beschreibung] |
| |
| Diese virtuelle Methode der Klasse DockingWindow sorgt f"ur das korrekte |
| Alignment am parent window. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| zuerst SfxDockingWindow::EndDocking() gerufen werden. |
| */ |
| { |
| if ( !pImp->bConstructed || IsDockingCanceled() || !pMgr ) |
| return; |
| |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| sal_Bool bReArrange = sal_False; |
| SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; |
| if ( pImp->bSplitable ) |
| { |
| eIdent = SFX_CHILDWIN_SPLITWINDOW; |
| |
| // Wenn sich das Alignment "andert und das Fenster befindet sich |
| // im angedockten Zustand in einem SplitWindow, mu\s umgemeldet werden |
| // Wenn neu angedockt wird, machen PrepareToggleFloatingMode() |
| // und ToggleFloatingMode() das Ummelden. |
| if ( !bFloatMode ) |
| bReArrange = sal_True; |
| } |
| |
| if ( bReArrange ) |
| { |
| if ( GetAlignment() != pImp->GetDockAlignment() ) |
| { |
| // Vor dem Show() mu\s das Ummelden passiert sein, daher kann nicht |
| // die Basisklasse gerufen werden |
| if ( IsFloatingMode() || !pImp->bSplitable ) |
| Show( sal_False, SHOW_NOFOCUSCHANGE ); |
| |
| // Die Gr"o\se f"urs Toggeln setzen |
| pImp->aSplitSize = rRect.GetSize(); |
| if ( IsFloatingMode() ) |
| { |
| SetFloatingMode( bFloatMode ); |
| if ( IsFloatingMode() || !pImp->bSplitable ) |
| Show( sal_True, SHOW_NOFOCUSCHANGE ); |
| } |
| else |
| { |
| pImp->pSplitWin->RemoveWindow(this,sal_False); |
| pImp->nLine = pImp->nDockLine; |
| pImp->nPos = pImp->nDockPos; |
| pImp->pSplitWin->ReleaseWindow_Impl(this); |
| pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(pImp->GetDockAlignment()); |
| pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine ); |
| if ( !pImp->pSplitWin->IsFadeIn() ) |
| pImp->pSplitWin->FadeIn(); |
| } |
| } |
| else if ( pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || pImp->bNewLine ) |
| { |
| // Ich wurde innerhalb meines Splitwindows verschoben. |
| if ( pImp->nLine != pImp->nDockLine ) |
| pImp->aSplitSize = rRect.GetSize(); |
| pImp->pSplitWin->MoveWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine ); |
| } |
| } |
| else |
| { |
| pImp->bEndDocked = sal_True; |
| DockingWindow::EndDocking(rRect, bFloatMode); |
| pImp->bEndDocked = sal_False; |
| } |
| |
| SetAlignment( IsFloatingMode() ? SFX_ALIGN_NOALIGNMENT : pImp->GetDockAlignment() ); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::Resizing( Size& /*rSize*/ ) |
| |
| /* [Beschreibung] |
| |
| Virtuelle Methode der Klasse DockingWindow. |
| Hier kann das interaktive Umgr"o\sern im FloatingMode beeinflu\t werden, |
| z.B. indem nur diskrete Werte f"ur Breite und/oder H"ohe zugelassen werden. |
| Die Basisimplementation verhindert, da\s die OutputSize kleiner wird als |
| eine mit SetMinOutputSizePixel() gesetzte Gr"o\se. |
| */ |
| |
| { |
| /* |
| if(rSize.Width() < pImp->aMinSize.Width()) |
| rSize.Width() = pImp->aMinSize.Width(); |
| if(rSize.Height() < pImp->aMinSize.Height()) |
| rSize.Height() = pImp->aMinSize.Height(); |
| */ |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, |
| Window* pParent, WinBits nWinBits) : |
| DockingWindow (pParent, nWinBits), |
| pBindings(pBindinx), |
| pMgr(pCW), |
| pImp(NULL) |
| |
| /* [Beschreibung] |
| |
| ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt, |
| da das Andocken im Sfx "uber SfxChildWindows realisiert wird. |
| */ |
| |
| { |
| if ( GetHelpId().getLength() ) |
| { |
| SetUniqueId( GetHelpId() ); |
| SetHelpId(""); |
| } |
| else |
| { |
| SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame(); |
| SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool(); |
| const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() ); |
| if ( pSlot ) |
| { |
| rtl::OString aCmd("SFXDOCKINGWINDOW_"); |
| aCmd += pSlot->GetUnoName(); |
| SetUniqueId( aCmd ); |
| } |
| } |
| |
| pImp = new SfxDockingWindow_Impl; |
| pImp->bConstructed = sal_False; |
| pImp->pSplitWin = 0; |
| pImp->bEndDocked = sal_False; |
| pImp->bDockingPrevented = sal_False; |
| |
| pImp->bSplitable = sal_True; |
| // pImp->bAutoHide = sal_False; |
| |
| // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt |
| pImp->nLine = pImp->nDockLine = 0; |
| pImp->nPos = pImp->nDockPos = 0; |
| pImp->bNewLine = sal_False; |
| pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); |
| pImp->aMoveTimer.SetTimeout(50); |
| pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl)); |
| |
| // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!"); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, |
| Window* pParent, const ResId& rResId) : |
| DockingWindow(pParent, rResId), |
| pBindings(pBindinx), |
| pMgr(pCW), |
| pImp(NULL) |
| |
| /* [Beschreibung] |
| |
| ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt, |
| da das Andocken im Sfx "uber SfxChildWindows realisiert wird. |
| */ |
| |
| { |
| if ( GetHelpId().getLength() ) |
| { |
| SetUniqueId( GetHelpId() ); |
| SetHelpId(""); |
| } |
| else |
| { |
| SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame(); |
| SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool(); |
| const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() ); |
| if ( pSlot ) |
| { |
| rtl::OString aCmd("SFXDOCKINGWINDOW_"); |
| aCmd += pSlot->GetUnoName(); |
| SetUniqueId( aCmd ); |
| } |
| } |
| |
| pImp = new SfxDockingWindow_Impl; |
| pImp->bConstructed = sal_False; |
| pImp->pSplitWin = 0; |
| pImp->bEndDocked = sal_False; |
| pImp->bDockingPrevented = sal_False; |
| |
| pImp->bSplitable = sal_True; |
| // pImp->bAutoHide = sal_False; |
| |
| // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt |
| pImp->nLine = pImp->nDockLine = 0; |
| pImp->nPos = pImp->nDockPos = 0; |
| pImp->bNewLine = sal_False; |
| pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); |
| pImp->aMoveTimer.SetTimeout(50); |
| pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl)); |
| |
| // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!"); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::Initialize(SfxChildWinInfo *pInfo) |
| /* [Beschreibung] |
| |
| Initialisierung der Klasse SfxDockingWindow "uber ein SfxChildWinInfo. |
| Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte |
| vom ctor der abgeleiteten Klasse oder vom ctor des SfxChildWindows |
| aufgerufen werden. |
| */ |
| { |
| if ( !pMgr ) |
| { |
| // Bugfix #39771 |
| pImp->SetDockAlignment( SFX_ALIGN_NOALIGNMENT ); |
| pImp->bConstructed = sal_True; |
| return; |
| } |
| |
| if ( pInfo->nFlags & SFX_CHILDWIN_FORCEDOCK ) |
| pImp->bDockingPrevented = sal_True; |
| |
| pImp->aSplitSize = GetOutputSizePixel(); |
| if ( !GetFloatingSize().Width() ) |
| { |
| Size aMinSize( GetMinOutputSizePixel() ); |
| SetFloatingSize( pImp->aSplitSize ); |
| if ( pImp->aSplitSize.Width() < aMinSize.Width() ) |
| pImp->aSplitSize.Width() = aMinSize.Width(); |
| if ( pImp->aSplitSize.Height() < aMinSize.Height() ) |
| pImp->aSplitSize.Height() = aMinSize.Height(); |
| } |
| |
| sal_Bool bVertHorzRead( sal_False ); |
| if ( pInfo->aExtraString.Len() ) |
| { |
| // get information about alignment, split size and position in SplitWindow |
| String aStr; |
| sal_uInt16 nPos = pInfo->aExtraString.SearchAscii("AL:"); |
| if ( nPos != STRING_NOTFOUND ) |
| { |
| // alignment information |
| sal_uInt16 n1 = pInfo->aExtraString.Search('(', nPos); |
| if ( n1 != STRING_NOTFOUND ) |
| { |
| sal_uInt16 n2 = pInfo->aExtraString.Search(')', n1); |
| if ( n2 != STRING_NOTFOUND ) |
| { |
| // extract alignment information from extrastring |
| aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1); |
| pInfo->aExtraString.Erase(nPos, n2 - nPos + 1); |
| aStr.Erase(nPos, n1-nPos+1); |
| } |
| } |
| } |
| |
| if ( aStr.Len() ) |
| { |
| // accept window state only if alignment is also set |
| pImp->aWinState = pInfo->aWinState; |
| |
| // check for valid alignment |
| SfxChildAlignment eLocalAlignment = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32(); |
| if ( pImp->bDockingPrevented ) |
| // docking prevented, ignore old configuration and take alignment from default |
| aStr.Erase(); |
| else |
| SetAlignment( eLocalAlignment ); |
| |
| SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment()); |
| if ( eAlign != GetAlignment() ) |
| { |
| DBG_ERROR("Invalid Alignment!"); |
| SetAlignment( eAlign ); |
| aStr.Erase(); |
| } |
| |
| // get last alignment (for toggeling) |
| nPos = aStr.Search(','); |
| if ( nPos != STRING_NOTFOUND ) |
| { |
| aStr.Erase(0, nPos+1); |
| pImp->SetLastAlignment( (SfxChildAlignment) (sal_uInt16) aStr.ToInt32() ); |
| } |
| |
| nPos = aStr.Search(','); |
| if ( nPos != STRING_NOTFOUND ) |
| { |
| // get split size and position in SplitWindow |
| Point aPos; |
| aStr.Erase(0, nPos+1); |
| if ( GetPosSizeFromString( aStr, aPos, pImp->aSplitSize ) ) |
| { |
| pImp->nLine = pImp->nDockLine = (sal_uInt16) aPos.X(); |
| pImp->nPos = pImp->nDockPos = (sal_uInt16) aPos.Y(); |
| pImp->nVerticalSize = pImp->aSplitSize.Height(); |
| pImp->nHorizontalSize = pImp->aSplitSize.Width(); |
| if ( GetSplitSizeFromString( aStr, pImp->aSplitSize )) |
| bVertHorzRead = sal_True; |
| } |
| } |
| } |
| else { |
| DBG_ERROR( "Information is missing!" ); |
| } |
| } |
| |
| if ( !bVertHorzRead ) |
| { |
| pImp->nVerticalSize = pImp->aSplitSize.Height(); |
| pImp->nHorizontalSize = pImp->aSplitSize.Width(); |
| } |
| |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| if ( GetAlignment() != SFX_ALIGN_NOALIGNMENT ) |
| { |
| // check if SfxWorkWindow is able to allow docking at its border |
| if ( |
| !pWorkWin->IsDockingAllowed() || |
| !pWorkWin->IsInternalDockingAllowed() || |
| ( (GetFloatStyle() & WB_STANDALONE) && Application::IsInModalMode()) ) |
| { |
| SetAlignment( SFX_ALIGN_NOALIGNMENT ); |
| } |
| } |
| |
| // detect floating mode |
| // toggeling mode will not execute code in handlers, because pImp->bConstructed is not set yet |
| sal_Bool bFloatMode = IsFloatingMode(); |
| if ( bFloatMode != ((GetAlignment() == SFX_ALIGN_NOALIGNMENT)) ) |
| { |
| bFloatMode = !bFloatMode; |
| SetFloatingMode( bFloatMode ); |
| if ( bFloatMode ) |
| { |
| if ( pImp->aWinState.Len() ) |
| GetFloatingWindow()->SetWindowState( pImp->aWinState ); |
| else |
| GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() ); |
| } |
| } |
| |
| if ( IsFloatingMode() ) |
| { |
| // validate last alignment |
| SfxChildAlignment eLastAlign = pImp->GetLastAlignment(); |
| if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) |
| eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_LEFT); |
| if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) |
| eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_RIGHT); |
| if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) |
| eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_TOP); |
| if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) |
| eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_BOTTOM); |
| pImp->SetLastAlignment(eLastAlign); |
| } |
| else |
| { |
| // docked window must have NOALIGNMENT as last alignment |
| pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); |
| |
| if ( pImp->bSplitable ) |
| { |
| // pImp->bAutoHide = ( pInfo->nFlags & SFX_CHILDWIN_AUTOHIDE) != 0; |
| pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment()); |
| pImp->pSplitWin->InsertWindow(this, pImp->aSplitSize); |
| } |
| else |
| { |
| //?????? Currently not supported |
| // Fenster ist individuell angedockt; Gr"o\se berechnen. |
| // Dazu mu\s sie mit der FloatingSize initialisiert werden, falls |
| // irgendwer sich darauf verl"a\st, da\s eine vern"unftige Gr"o\se |
| // gesetzt ist |
| SetSizePixel(GetFloatingSize()); |
| SetSizePixel(CalcDockingSize(GetAlignment())); |
| } |
| } |
| |
| // save alignment |
| pImp->SetDockAlignment( GetAlignment() ); |
| } |
| |
| void SfxDockingWindow::Initialize_Impl() |
| { |
| if ( !pMgr ) |
| { |
| // Bugfix #39771 |
| pImp->bConstructed = sal_True; |
| return; |
| } |
| |
| FloatingWindow* pFloatWin = GetFloatingWindow(); |
| sal_Bool bSet = sal_False; |
| if ( pFloatWin ) |
| { |
| bSet = !pFloatWin->IsDefaultPos(); |
| } |
| else |
| { |
| Point aPos = GetFloatingPos(); |
| if ( aPos != Point() ) |
| bSet = sal_True; |
| } |
| |
| if ( !bSet) |
| { |
| SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame(); |
| Window* pEditWin = pFrame->GetViewShell()->GetWindow(); |
| Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() ); |
| aPos = GetParent()->ScreenToOutputPixel( aPos ); |
| SetFloatingPos( aPos ); |
| } |
| |
| if ( pFloatWin ) |
| { |
| // initialize floating window |
| if ( !pImp->aWinState.Len() ) |
| // window state never set before, get if from defaults |
| pImp->aWinState = pFloatWin->GetWindowState(); |
| |
| // trick: use VCL method SetWindowState to adjust position and size |
| pFloatWin->SetWindowState( pImp->aWinState ); |
| |
| // remember floating size for calculating alignment and tracking rectangle |
| SetFloatingSize( pFloatWin->GetSizePixel() ); |
| |
| // some versions of VCL didn't call resize in the current situation |
| //Resize(); |
| } |
| |
| // allow calling of docking handlers |
| pImp->bConstructed = sal_True; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const |
| |
| /* [Beschreibung] |
| |
| F"ullt ein SfxChildWinInfo mit f"ur SfxDockingWindow spezifischen Daten, |
| damit sie in die INI-Datei geschrieben werden koennen. |
| Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in |
| der ChildWindow-Klasse erh"alt. |
| Eingetragen werden hier gemerkten Gr"o\sen, das ZoomIn-Flag und die |
| f"ur das Docking relevanten Informationen. |
| Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung |
| gerufen werden. |
| */ |
| |
| { |
| if ( !pMgr ) |
| return; |
| |
| if ( GetFloatingWindow() && pImp->bConstructed ) |
| pImp->aWinState = GetFloatingWindow()->GetWindowState(); |
| |
| rInfo.aWinState = pImp->aWinState; |
| rInfo.aExtraString = DEFINE_CONST_UNICODE("AL:("); |
| rInfo.aExtraString += String::CreateFromInt32((sal_uInt16) GetAlignment()); |
| rInfo.aExtraString += ','; |
| rInfo.aExtraString += String::CreateFromInt32 ((sal_uInt16) pImp->GetLastAlignment()); |
| if ( pImp->bSplitable ) |
| { |
| Point aPos(pImp->nLine, pImp->nPos); |
| rInfo.aExtraString += ','; |
| rInfo.aExtraString += String::CreateFromInt32( aPos.X() ); |
| rInfo.aExtraString += '/'; |
| rInfo.aExtraString += String::CreateFromInt32( aPos.Y() ); |
| rInfo.aExtraString += '/'; |
| rInfo.aExtraString += String::CreateFromInt32( pImp->nHorizontalSize ); |
| rInfo.aExtraString += '/'; |
| rInfo.aExtraString += String::CreateFromInt32( pImp->nVerticalSize ); |
| rInfo.aExtraString += ','; |
| rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Width() ); |
| rInfo.aExtraString += ';'; |
| rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Height() ); |
| } |
| |
| rInfo.aExtraString += ')'; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| SfxDockingWindow::~SfxDockingWindow() |
| { |
| ReleaseChildWindow_Impl(); |
| delete pImp; |
| } |
| |
| void SfxDockingWindow::ReleaseChildWindow_Impl() |
| { |
| if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() ) |
| pBindings->SetActiveFrame( NULL ); |
| |
| if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) ) |
| pImp->pSplitWin->RemoveWindow(this); |
| |
| pMgr=NULL; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| SfxChildAlignment SfxDockingWindow::CalcAlignment(const Point& rPos, Rectangle& rRect) |
| |
| /* [Beschreibung] |
| |
| Diese Methode berechnet f"ur gegebene Mausposition und tracking rectangle, |
| welches Alignment sich daraus ergeben w"urde. Beim Wechsel des Alignments |
| kann sich auch das tracking rectangle "andern, so dass ein ver"andertes |
| rectangle zur"uckgegeben wird. |
| |
| Der Klassenbenutzer kann das Verhalten dieser Methode und damit das Verhalten |
| seiner DockinWindow-Klasse beim Docken beeinflussen, indem er die hier |
| aufgerufene virtuelle Methode |
| |
| SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign) |
| |
| "uberschreibt (s.u.). |
| */ |
| |
| { |
| // calculate hypothetical sizes for different modes |
| Size aFloatingSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT)); |
| Size aVerticalSize(CalcDockingSize(SFX_ALIGN_LEFT)); |
| Size aHorizontalSize(CalcDockingSize(SFX_ALIGN_TOP)); |
| |
| // check if docking is permitted |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| if ( !pWorkWin->IsDockingAllowed() ) |
| { |
| rRect.SetSize( aFloatingSize ); |
| return pImp->GetDockAlignment(); |
| } |
| |
| // calculate borders to shrink inner area before checking for intersection with tracking rectangle |
| long nLRBorder, nTBBorder; |
| if ( pImp->bSplitable ) |
| { |
| // take the smaller size of docked and floating mode |
| Size aSize = pImp->aSplitSize; |
| if ( GetFloatingSize().Height() < aSize.Height() ) |
| aSize.Height() = GetFloatingSize().Height(); |
| if ( GetFloatingSize().Width() < aSize.Width() ) |
| aSize.Width() = GetFloatingSize().Width(); |
| |
| nLRBorder = aSize.Width(); |
| nTBBorder = aSize.Height(); |
| } |
| else |
| { |
| nLRBorder = aVerticalSize.Width(); |
| nTBBorder = aHorizontalSize.Height(); |
| } |
| |
| // limit border to predefined constant values |
| if ( nLRBorder > MAX_TOGGLEAREA_WIDTH ) |
| nLRBorder = MAX_TOGGLEAREA_WIDTH; |
| if ( nTBBorder > MAX_TOGGLEAREA_WIDTH ) |
| nTBBorder = MAX_TOGGLEAREA_WIDTH; |
| |
| // shrink area for floating mode if possible |
| Rectangle aInRect = GetInnerRect(); |
| if ( aInRect.GetWidth() > nLRBorder ) |
| aInRect.Left() += nLRBorder/2; |
| if ( aInRect.GetWidth() > nLRBorder ) |
| aInRect.Right() -= nLRBorder/2; |
| if ( aInRect.GetHeight() > nTBBorder ) |
| aInRect.Top() += nTBBorder/2; |
| if ( aInRect.GetHeight() > nTBBorder ) |
| aInRect.Bottom() -= nTBBorder/2; |
| |
| // calculate alignment resulting from docking rectangle |
| sal_Bool bBecomesFloating = sal_False; |
| SfxChildAlignment eDockAlign = pImp->GetDockAlignment(); |
| Rectangle aDockingRect( rRect ); |
| if ( !IsFloatingMode() ) |
| { |
| // don't use tracking rectangle for alignment check, because it will be too large |
| // to get a floating mode as result - switch to floating size |
| // so the calculation only depends on the position of the rectangle, not the current |
| // docking state of the window |
| aDockingRect.SetSize( GetFloatingSize() ); |
| |
| // in this mode docking is never done by keyboard, so it's OK to use the mouse position |
| aDockingRect.SetPos( pWorkWin->GetWindow()->OutputToScreenPixel( pWorkWin->GetWindow()->GetPointerPosPixel() ) ); |
| } |
| |
| Point aPos = aDockingRect.TopLeft(); |
| Rectangle aIntersect = GetOuterRect().GetIntersection( aDockingRect ); |
| if ( aIntersect.IsEmpty() ) |
| // docking rectangle completely outside docking area -> floating mode |
| bBecomesFloating = sal_True; |
| else |
| { |
| // create a small test rect around the mouse position and use this one |
| // instead of the passed rRect to not dock too easily or by accident |
| Rectangle aSmallDockingRect; |
| aSmallDockingRect.SetSize( Size( MAX_TOGGLEAREA_WIDTH, MAX_TOGGLEAREA_HEIGHT ) ); |
| Point aNewPos(rPos); |
| aNewPos.X() -= aSmallDockingRect.GetWidth()/2; |
| aNewPos.Y() -= aSmallDockingRect.GetHeight()/2; |
| aSmallDockingRect.SetPos(rPos); |
| Rectangle aIntersectRect = aInRect.GetIntersection( aSmallDockingRect ); |
| if ( aIntersectRect == aSmallDockingRect ) |
| // docking rectangle completely inside (shrinked) inner area -> floating mode |
| bBecomesFloating = sal_True; |
| } |
| |
| if ( bBecomesFloating ) |
| { |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT); |
| } |
| else |
| { |
| // docking rectangle is in the "sensible area" |
| Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() ); |
| Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() ); |
| Size aInSize = aInRect.GetSize(); |
| sal_Bool bNoChange = sal_False; |
| |
| // check if alignment is still unchanged |
| switch ( GetAlignment() ) |
| { |
| case SFX_ALIGN_LEFT: |
| case SFX_ALIGN_FIRSTLEFT: |
| case SFX_ALIGN_LASTLEFT: |
| if (aInPosTL.X() <= 0) |
| { |
| eDockAlign = GetAlignment(); |
| bNoChange = sal_True; |
| } |
| break; |
| case SFX_ALIGN_TOP: |
| case SFX_ALIGN_LOWESTTOP: |
| case SFX_ALIGN_HIGHESTTOP: |
| if ( aInPosTL.Y() <= 0) |
| { |
| eDockAlign = GetAlignment(); |
| bNoChange = sal_True; |
| } |
| break; |
| case SFX_ALIGN_RIGHT: |
| case SFX_ALIGN_FIRSTRIGHT: |
| case SFX_ALIGN_LASTRIGHT: |
| if ( aInPosBR.X() >= aInSize.Width()) |
| { |
| eDockAlign = GetAlignment(); |
| bNoChange = sal_True; |
| } |
| break; |
| case SFX_ALIGN_BOTTOM: |
| case SFX_ALIGN_LOWESTBOTTOM: |
| case SFX_ALIGN_HIGHESTBOTTOM: |
| if ( aInPosBR.Y() >= aInSize.Height()) |
| { |
| eDockAlign = GetAlignment(); |
| bNoChange = sal_True; |
| } |
| break; |
| default: |
| break; |
| } |
| |
| if ( !bNoChange ) |
| { |
| // alignment will change, test alignment according to distance of the docking rectangles edges |
| sal_Bool bForbidden = sal_True; |
| if ( aInPosTL.X() <= 0) |
| { |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_LEFT); |
| bForbidden = ( eDockAlign != SFX_ALIGN_LEFT && |
| eDockAlign != SFX_ALIGN_FIRSTLEFT && |
| eDockAlign != SFX_ALIGN_LASTLEFT ); |
| } |
| |
| if ( bForbidden && aInPosTL.Y() <= 0) |
| { |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_TOP); |
| bForbidden = ( eDockAlign != SFX_ALIGN_TOP && |
| eDockAlign != SFX_ALIGN_HIGHESTTOP && |
| eDockAlign != SFX_ALIGN_LOWESTTOP ); |
| } |
| |
| if ( bForbidden && aInPosBR.X() >= aInSize.Width()) |
| { |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_RIGHT); |
| bForbidden = ( eDockAlign != SFX_ALIGN_RIGHT && |
| eDockAlign != SFX_ALIGN_FIRSTRIGHT && |
| eDockAlign != SFX_ALIGN_LASTRIGHT ); |
| } |
| |
| if ( bForbidden && aInPosBR.Y() >= aInSize.Height()) |
| { |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_BOTTOM); |
| bForbidden = ( eDockAlign != SFX_ALIGN_BOTTOM && |
| eDockAlign != SFX_ALIGN_HIGHESTBOTTOM && |
| eDockAlign != SFX_ALIGN_LOWESTBOTTOM ); |
| } |
| |
| // the calculated alignment was rejected by the window -> take floating mode |
| if ( bForbidden ) |
| eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT); |
| } |
| } |
| |
| if ( eDockAlign == SFX_ALIGN_NOALIGNMENT ) |
| { |
| //Im FloatingMode erh"alt das tracking rectangle die floating size |
| // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das |
| // Alignment "andert ! |
| if ( eDockAlign != pImp->GetDockAlignment() ) |
| aDockingRect.SetSize( aFloatingSize ); |
| } |
| else if ( pImp->bSplitable ) |
| { |
| sal_uInt16 nLine, nPos; |
| SfxSplitWindow *pSplitWin = pWorkWin->GetSplitWindow_Impl(eDockAlign); |
| aPos = pSplitWin->ScreenToOutputPixel( aPos ); |
| if ( pSplitWin->GetWindowPos( aPos, nLine, nPos ) ) |
| { |
| // mouse over splitwindow, get line and position |
| pImp->nDockLine = nLine; |
| pImp->nDockPos = nPos; |
| pImp->bNewLine = sal_False; |
| } |
| else |
| { |
| if ( 0 ) |
| { |
| // mouse touches outer border -> treated as floating mode |
| eDockAlign = SFX_ALIGN_NOALIGNMENT; |
| aDockingRect.SetSize( aFloatingSize ); |
| rRect = aDockingRect; |
| return eDockAlign; |
| } |
| |
| // mouse touches inner border -> create new line |
| if ( eDockAlign == GetAlignment() && pImp->pSplitWin && |
| pImp->nLine == pImp->pSplitWin->GetLineCount()-1 && pImp->pSplitWin->GetWindowCount(pImp->nLine) == 1 ) |
| { |
| // if this window is the only one in the last line, it can't be docked as new line in the same splitwindow |
| pImp->nDockLine = pImp->nLine; |
| pImp->nDockPos = pImp->nPos; |
| pImp->bNewLine = sal_False; |
| } |
| else |
| { |
| // create new line |
| pImp->nDockLine = pSplitWin->GetLineCount(); |
| pImp->nDockPos = 0; |
| pImp->bNewLine = sal_True; |
| } |
| } |
| |
| sal_Bool bChanged = pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || eDockAlign != GetAlignment(); |
| if ( !bChanged && !IsFloatingMode() ) |
| { |
| // window only sightly moved, no change of any property |
| rRect.SetSize( pImp->aSplitSize ); |
| rRect.SetPos( aDockingRect.TopLeft() ); |
| return eDockAlign; |
| } |
| |
| // calculate new size and position |
| Size aSize; |
| Point aPoint = aDockingRect.TopLeft(); |
| Size aInnerSize = GetInnerRect().GetSize(); |
| if ( eDockAlign == SFX_ALIGN_LEFT || eDockAlign == SFX_ALIGN_RIGHT ) |
| { |
| if ( pImp->bNewLine ) |
| { |
| // set height to height of free area |
| aSize.Height() = aInnerSize.Height(); |
| aSize.Width() = pImp->nHorizontalSize; |
| if ( eDockAlign == SFX_ALIGN_LEFT ) |
| { |
| aPoint = aInnerRect.TopLeft(); |
| } |
| else |
| { |
| aPoint = aInnerRect.TopRight(); |
| aPoint.X() -= aSize.Width(); |
| } |
| } |
| else |
| { |
| // get width from splitwindow |
| aSize.Width() = pSplitWin->GetLineSize(nLine); |
| aSize.Height() = pImp->aSplitSize.Height(); |
| } |
| } |
| else |
| { |
| if ( pImp->bNewLine ) |
| { |
| // set width to width of free area |
| aSize.Width() = aInnerSize.Width(); |
| aSize.Height() = pImp->nVerticalSize; |
| if ( eDockAlign == SFX_ALIGN_TOP ) |
| { |
| aPoint = aInnerRect.TopLeft(); |
| } |
| else |
| { |
| aPoint = aInnerRect.BottomLeft(); |
| aPoint.Y() -= aSize.Height(); |
| } |
| } |
| else |
| { |
| // get height from splitwindow |
| aSize.Height() = pSplitWin->GetLineSize(nLine); |
| aSize.Width() = pImp->aSplitSize.Width(); |
| } |
| } |
| |
| aDockingRect.SetSize( aSize ); |
| aDockingRect.SetPos( aPoint ); |
| } |
| else |
| { |
| // window can be docked, but outside our splitwindows |
| // tracking rectangle only needs to be modified if alignment was changed |
| if ( eDockAlign != pImp->GetDockAlignment() ) |
| { |
| switch ( eDockAlign ) |
| { |
| case SFX_ALIGN_LEFT: |
| case SFX_ALIGN_RIGHT: |
| case SFX_ALIGN_FIRSTLEFT: |
| aDockingRect.SetPos( aInnerRect.TopLeft() ); |
| aDockingRect.SetSize( aVerticalSize ); |
| break; |
| case SFX_ALIGN_LASTLEFT: |
| case SFX_ALIGN_FIRSTRIGHT: |
| case SFX_ALIGN_LASTRIGHT: |
| { |
| Point aPt( aInnerRect.TopRight() ); |
| aPt.X() -= aDockingRect.GetWidth(); |
| aDockingRect.SetPos( aPt ); |
| aDockingRect.SetSize( aVerticalSize ); |
| break; |
| } |
| |
| case SFX_ALIGN_TOP: |
| case SFX_ALIGN_BOTTOM: |
| case SFX_ALIGN_LOWESTTOP: |
| aDockingRect.SetPos( aInnerRect.TopLeft() ); |
| aDockingRect.SetSize( aHorizontalSize ); |
| break; |
| case SFX_ALIGN_HIGHESTTOP: |
| case SFX_ALIGN_LOWESTBOTTOM: |
| case SFX_ALIGN_HIGHESTBOTTOM: |
| { |
| Point aPt( aInnerRect.BottomLeft() ); |
| aPt.Y() -= aDockingRect.GetHeight(); |
| aDockingRect.SetPos( aPt ); |
| aDockingRect.SetSize( aHorizontalSize ); |
| break; |
| } |
| default: |
| break; |
| } |
| } |
| } |
| |
| rRect = aDockingRect; |
| return eDockAlign; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign) |
| |
| /* [Beschreibung] |
| |
| Virtuelle Methode der Klasse SfxDockingWindow. |
| Hier wird festgelegt, wie sich die Gr"o\se des DockingWindows abh"angig vom |
| Alignment "andert. |
| Die Basisimplementation setzt im Floating Mode die Gr"o\se auf die gemerkte |
| Floating Size. |
| Bei horizontalem Alignment wird die Breite auf die Breite des "au\seren |
| DockingRects, bei vertikalem Alignment die H"ohe auf die H"ohe des inneren |
| DockingRects (ergibt sich aus der Reihenfolge, in der im SFX ChildWindows |
| ausgegeben werden). Die jeweils andere Gr"o\se wird auf die aktuelle |
| Floating Size gesetzt, hier k"onnte eine abgeleitete Klasse "andernd |
| eingreifen. |
| Die DockingSize mu\s f"ur Left/Right und Top/Bottom jeweils gleich sein. |
| */ |
| |
| { |
| // Achtung: falls das Resizing auch im angedockten Zustand geht, mu\s dabei |
| // auch die Floating Size angepa\st werden !? |
| |
| Size aSize = GetFloatingSize(); |
| switch (eAlign) |
| { |
| case SFX_ALIGN_TOP: |
| case SFX_ALIGN_BOTTOM: |
| case SFX_ALIGN_LOWESTTOP: |
| case SFX_ALIGN_HIGHESTTOP: |
| case SFX_ALIGN_LOWESTBOTTOM: |
| case SFX_ALIGN_HIGHESTBOTTOM: |
| aSize.Width() = aOuterRect.Right() - aOuterRect.Left(); |
| break; |
| case SFX_ALIGN_LEFT: |
| case SFX_ALIGN_RIGHT: |
| case SFX_ALIGN_FIRSTLEFT: |
| case SFX_ALIGN_LASTLEFT: |
| case SFX_ALIGN_FIRSTRIGHT: |
| case SFX_ALIGN_LASTRIGHT: |
| aSize.Height() = aInnerRect.Bottom() - aInnerRect.Top(); |
| break; |
| case SFX_ALIGN_NOALIGNMENT: |
| break; |
| default: |
| break; |
| } |
| |
| return aSize; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment, |
| SfxChildAlignment eAlign) |
| |
| /* [Beschreibung] |
| |
| Virtuelle Methode der Klasse SfxDockingWindow. |
| Hier kann eine abgeleitete Klasse bestimmte Alignments verbieten. |
| Die Basisimplementation verbietet kein Alignment. |
| */ |
| |
| { |
| return eAlign; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| sal_Bool SfxDockingWindow::Close() |
| |
| /* [Beschreibung] |
| |
| Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des |
| ChildWindow-Slots zerst"ort wird. |
| Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s |
| danach SfxDockingWindow::Close() gerufen werden, wenn nicht das Close() |
| mit "return FALSE" abgebrochen wird. |
| |
| */ |
| { |
| // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert |
| // werden kann |
| if ( !pMgr ) |
| return sal_True; |
| |
| SfxBoolItem aValue( pMgr->GetType(), sal_False); |
| pBindings->GetDispatcher_Impl()->Execute( |
| pMgr->GetType(), SFX_CALLMODE_RECORD | SFX_CALLMODE_ASYNCHRON, &aValue, 0L ); |
| return sal_True; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::Paint(const Rectangle& /*rRect*/) |
| |
| /* [Beschreibung] |
| |
| Es wird im angedockten Zustand eine Begrenzungslinie an der angedockten |
| Kante und ein Rahmen ausgegeben. Dabei wird SVLOOK ber"ucksichtigt. |
| */ |
| |
| { |
| if ( pImp->bSplitable || IsFloatingMode() ) |
| return; |
| |
| Rectangle aRect = Rectangle(Point(0, 0), |
| GetOutputSizePixel()); |
| switch (GetAlignment()) |
| { |
| case SFX_ALIGN_TOP: |
| { |
| DrawLine(aRect.BottomLeft(), aRect.BottomRight()); |
| aRect.Bottom()--; |
| break; |
| } |
| |
| case SFX_ALIGN_BOTTOM: |
| { |
| DrawLine(aRect.TopLeft(), aRect.TopRight()); |
| aRect.Top()++; |
| break; |
| } |
| |
| case SFX_ALIGN_LEFT: |
| { |
| DrawLine(aRect.TopRight(), aRect.BottomRight()); |
| aRect.Right()--; |
| break; |
| } |
| |
| case SFX_ALIGN_RIGHT: |
| { |
| DrawLine(aRect.TopLeft(), aRect.BottomLeft()); |
| aRect.Left()++; |
| break; |
| } |
| default: |
| break; |
| } |
| |
| DecorationView aView( this ); |
| aView.DrawFrame( aRect, FRAME_DRAW_OUT ); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize ) |
| |
| /* [Beschreibung] |
| |
| Mit dieser Methode kann eine minimale OutpuSize gesetzt werden, die |
| im Resizing()-Handler abgefragt wird. |
| */ |
| |
| { |
| pImp->aMinSize = rSize; |
| DockingWindow::SetMinOutputSizePixel( rSize ); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| Size SfxDockingWindow::GetMinOutputSizePixel() const |
| |
| /* [Beschreibung] |
| |
| Die gesetzte minimale Gr"o\se wird zur"uckgegeben. |
| */ |
| |
| { |
| return pImp->aMinSize; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| long SfxDockingWindow::Notify( NotifyEvent& rEvt ) |
| { |
| if ( rEvt.GetType() == EVENT_GETFOCUS ) |
| { |
| if (pMgr != NULL) |
| pBindings->SetActiveFrame( pMgr->GetFrame() ); |
| |
| if ( pImp->pSplitWin ) |
| pImp->pSplitWin->SetActiveWindow_Impl( this ); |
| else if (pMgr != NULL) |
| pMgr->Activate_Impl(); |
| |
| Window* pWindow = rEvt.GetWindow(); |
| rtl::OString sHelpId; |
| while ( !sHelpId.getLength() && pWindow ) |
| { |
| sHelpId = pWindow->GetHelpId(); |
| pWindow = pWindow->GetParent(); |
| } |
| |
| if ( sHelpId.getLength() ) |
| SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); |
| |
| // In VCL geht Notify zun"achst an das Fenster selbst, |
| // also base class rufen, sonst erf"ahrt der parent nichts |
| // if ( rEvt.GetWindow() == this ) PB: #i74693# not necessary any longer |
| DockingWindow::Notify( rEvt ); |
| return sal_True; |
| } |
| else if( rEvt.GetType() == EVENT_KEYINPUT ) |
| { |
| // KeyInput zuerst f"ur Dialogfunktionen zulassen |
| if ( !DockingWindow::Notify( rEvt ) && SfxViewShell::Current() ) |
| // dann auch global g"ultige Acceleratoren verwenden |
| return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); |
| return sal_True; |
| } |
| else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() ) |
| { |
| pBindings->SetActiveFrame( NULL ); |
| if (pMgr != NULL) |
| pMgr->Deactivate_Impl(); |
| } |
| |
| return DockingWindow::Notify( rEvt ); |
| } |
| |
| |
| sal_uInt16 SfxDockingWindow::GetWinBits_Impl() const |
| { |
| sal_uInt16 nBits = 0; |
| // if ( pImp->bAutoHide ) |
| // nBits |= SWIB_AUTOHIDE; |
| return nBits; |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| void SfxDockingWindow::SetItemSize_Impl( const Size& rSize ) |
| { |
| pImp->aSplitSize = rSize; |
| |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; |
| if ( pImp->bSplitable ) |
| eIdent = SFX_CHILDWIN_SPLITWINDOW; |
| pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() ); |
| } |
| |
| void SfxDockingWindow::Disappear_Impl() |
| { |
| if ( pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) ) |
| pImp->pSplitWin->RemoveWindow(this); |
| } |
| |
| void SfxDockingWindow::Reappear_Impl() |
| { |
| if ( pImp->pSplitWin && !pImp->pSplitWin->IsItemValid( GetType() ) ) |
| { |
| pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize ); |
| } |
| } |
| |
| sal_Bool SfxDockingWindow::IsAutoHide_Impl() const |
| { |
| if ( pImp->pSplitWin ) |
| return !pImp->pSplitWin->IsFadeIn(); |
| else |
| return sal_False; |
| } |
| |
| sal_Bool SfxDockingWindow::IsPinned_Impl() const |
| { |
| if ( pImp->pSplitWin ) |
| return pImp->pSplitWin->IsPinned(); |
| else |
| return sal_True; |
| } |
| void SfxDockingWindow::AutoShow( sal_Bool bShow ) |
| { |
| AutoShow_Impl(bShow); |
| } |
| |
| void SfxDockingWindow::AutoShow_Impl( sal_Bool bShow ) |
| { |
| if ( pImp->pSplitWin ) |
| { |
| if ( bShow ) |
| pImp->pSplitWin->FadeIn(); |
| else |
| pImp->pSplitWin->FadeOut(); |
| } |
| } |
| |
| /* |
| void SfxDockingWindow::Pin_Impl( sal_Bool bPinned ) |
| { |
| if ( pImp->pSplitWin ) |
| pImp->pSplitWin->Pin_Impl( bPinned ); |
| } |
| */ |
| |
| SfxSplitWindow* SfxDockingWindow::GetSplitWindow_Impl() const |
| { |
| return pImp->pSplitWin; |
| } |
| |
| void SfxDockingWindow::FadeIn( sal_Bool /*bFadeIn*/ ) |
| { |
| } |
| |
| void SfxDockingWindow::StateChanged( StateChangedType nStateChange ) |
| { |
| if ( nStateChange == STATE_CHANGE_INITSHOW ) |
| Initialize_Impl(); |
| |
| DockingWindow::StateChanged( nStateChange ); |
| } |
| |
| void SfxDockingWindow::Move() |
| { |
| if ( pImp ) |
| pImp->aMoveTimer.Start(); |
| } |
| |
| IMPL_LINK( SfxDockingWindow, TimerHdl, Timer*, EMPTYARG) |
| { |
| pImp->aMoveTimer.Stop(); |
| if ( IsReallyVisible() && IsFloatingMode() ) |
| { |
| if( !GetFloatingWindow()->IsRollUp() ) |
| SetFloatingSize( GetOutputSizePixel() ); |
| pImp->aWinState = GetFloatingWindow()->GetWindowState(); |
| SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; |
| if ( pImp->bSplitable ) |
| eIdent = SFX_CHILDWIN_SPLITWINDOW; |
| SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); |
| pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() ); |
| } |
| return 0; |
| } |
| |