update dev300-m58
[ooovba.git] / sfx2 / source / dialog / dockwin.cxx
blobb10283c8494a1148739605ca8f808d90e78e55a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dockwin.cxx,v $
10 * $Revision: 1.48 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <svtools/eitem.hxx>
35 #include <vcl/decoview.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/timer.hxx>
39 #include <rtl/instance.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <comphelper/processfactory.hxx>
43 #include <sfx2/dockwin.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include <sfx2/dispatch.hxx>
47 #include "workwin.hxx"
48 #include "splitwin.hxx"
49 #include <sfx2/viewsh.hxx>
50 #include "sfxhelp.hxx"
51 #include <sfx2/objsh.hxx>
53 #include <com/sun/star/frame/XController.hpp>
54 #include <com/sun/star/lang/XUnoTunnel.hpp>
55 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
56 #include <com/sun/star/awt/XWindow.hpp>
57 #include <com/sun/star/uno/XComponentContext.hpp>
58 #include <com/sun/star/frame/XModuleManager.hpp>
59 #include <com/sun/star/container/XNameAccess.hpp>
61 #define MAX_TOGGLEAREA_WIDTH 20
62 #define MAX_TOGGLEAREA_HEIGHT 20
64 using namespace ::com::sun::star;
66 // implemented in 'sfx2/source/appl/childwin.cxx'
67 extern sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize );
68 extern sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize );
70 // If you want to change the number you also have to:
71 // - Add new slot ids to sfxsids.hrc
72 // - Add new slots to frmslots.sdi
73 // - Add new slot definitions to sfx.sdi
74 static const int NUM_OF_DOCKINGWINDOWS = 10;
76 class SfxTitleDockingWindow;
77 class SfxTitleDockingWindow : public SfxDockingWindow
79 Window* m_pWrappedWindow;
80 USHORT m_nID;
82 public:
83 SfxTitleDockingWindow(
84 SfxBindings* pBindings ,
85 SfxChildWindow* pChildWin ,
86 Window* pParent ,
87 WinBits nBits,
88 USHORT nID);
89 virtual ~SfxTitleDockingWindow();
91 Window* GetWrappedWindow() const { return m_pWrappedWindow; }
92 void SetWrappedWindow(Window* const pWindow);
94 virtual void StateChanged( StateChangedType nType );
95 virtual long Notify( NotifyEvent& rNEvt );
96 virtual void Resize();
97 virtual void Resizing( Size& rSize );
98 virtual BOOL Close();
101 namespace
103 struct WindowState
105 ::rtl::OUString sTitle;
109 static uno::WeakReference< container::XNameAccess > m_xWindowStateConfiguration;
110 static uno::WeakReference< frame::XModuleManager > m_xModuleManager;
112 static bool lcl_getWindowState( const uno::Reference< container::XNameAccess >& xWindowStateMgr, const ::rtl::OUString& rResourceURL, WindowState& rWindowState )
114 bool bResult = false;
118 uno::Any a;
119 uno::Sequence< beans::PropertyValue > aWindowState;
120 a = xWindowStateMgr->getByName( rResourceURL );
121 if ( a >>= aWindowState )
123 for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
125 if ( aWindowState[n].Name.equalsAscii( "UIName" ))
127 aWindowState[n].Value >>= rWindowState.sTitle;
132 bResult = true;
134 catch ( container::NoSuchElementException& )
136 bResult = false;
139 return bResult;
142 SfxDockingWrapper::SfxDockingWrapper( Window* pParentWnd ,
143 USHORT nId ,
144 SfxBindings* pBindings ,
145 SfxChildWinInfo* pInfo )
146 : SfxChildWindow( pParentWnd , nId )
148 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
149 const rtl::OUString aDockWindowResourceURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/dockingwindow/" ));
151 SfxTitleDockingWindow* pTitleDockWindow = new SfxTitleDockingWindow( pBindings, this, pParentWnd,
152 WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE, nId);
153 pWindow = pTitleDockWindow;
154 eChildAlignment = SFX_ALIGN_NOALIGNMENT;
156 // Use factory manager to retrieve XWindow factory. That can be used to instanciate
157 // the real window factory.
158 uno::Reference< lang::XSingleComponentFactory > xFactoryMgr(
159 xServiceManager->createInstance(
160 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
161 "com.sun.star.ui.WindowContentFactoryManager"))),
162 uno::UNO_QUERY );
164 if (xFactoryMgr.is())
166 SfxDispatcher* pDispatcher = pBindings->GetDispatcher();
167 uno::Reference< frame::XFrame > xFrame( pDispatcher->GetFrame()->GetFrame()->GetFrameInterface(), uno::UNO_QUERY );
168 uno::Sequence< uno::Any > aArgs(2);
169 beans::PropertyValue aPropValue;
170 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
171 aPropValue.Value = uno::makeAny( xFrame );
172 aArgs[0] <<= aPropValue;
173 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
175 // create a resource URL from the nId provided by the sfx2
176 ::rtl::OUString aResourceURL( aDockWindowResourceURL );
177 aResourceURL += ::rtl::OUString::valueOf(sal_Int32(nId));
178 aPropValue.Value = uno::makeAny( aResourceURL );
179 aArgs[1] <<= aPropValue;
181 uno::Reference< awt::XWindow > xWindow;
184 uno::Reference< beans::XPropertySet > xProps( xServiceManager, uno::UNO_QUERY );
185 uno::Reference< uno::XComponentContext > xContext;
187 if ( xProps.is() )
188 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
189 if ( xContext.is() )
191 xWindow = uno::Reference< awt::XWindow>(
192 xFactoryMgr->createInstanceWithArgumentsAndContext( aArgs, xContext ),
193 uno::UNO_QUERY );
196 uno::Reference< frame::XModuleManager > xModuleManager( m_xModuleManager );
197 if ( !xModuleManager.is() )
199 xModuleManager = uno::Reference< frame::XModuleManager >(
200 xServiceManager->createInstance(
201 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))),
202 uno::UNO_QUERY );
203 m_xModuleManager = xModuleManager;
206 uno::Reference< container::XNameAccess > xWindowStateConfiguration( m_xWindowStateConfiguration );
207 if ( !xWindowStateConfiguration.is() )
209 xWindowStateConfiguration = uno::Reference< container::XNameAccess >(
210 xServiceManager->createInstance(
211 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.WindowStateConfiguration" ))),
212 uno::UNO_QUERY );
213 m_xWindowStateConfiguration = xWindowStateConfiguration;
216 ::rtl::OUString sModuleIdentifier = xModuleManager->identify( xFrame );
218 uno::Reference< container::XNameAccess > xModuleWindowState(
219 xWindowStateConfiguration->getByName( sModuleIdentifier ),
220 uno::UNO_QUERY );
221 if ( xModuleWindowState.is() )
223 WindowState aDockWinState;
224 if ( lcl_getWindowState( xModuleWindowState, aResourceURL, aDockWinState ))
225 pTitleDockWindow->SetText( aDockWinState.sTitle );
228 catch ( beans::UnknownPropertyException& )
231 catch ( uno::RuntimeException& )
234 catch ( uno::Exception& )
238 Window* pContentWindow = VCLUnoHelper::GetWindow(xWindow);
239 pContentWindow->SetStyle( pContentWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
240 pTitleDockWindow->SetWrappedWindow(pContentWindow);
243 pWindow->SetOutputSizePixel( Size( 270, 240 ) );
245 ( ( SfxDockingWindow* ) pWindow )->Initialize( pInfo );
246 SetHideNotDelete( TRUE );
249 SfxChildWindow* SfxDockingWrapper::CreateImpl(
250 Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo* pInfo )
252 SfxChildWindow *pWin = new SfxDockingWrapper(pParent, nId, pBindings, pInfo); return pWin;
255 sal_uInt16 SfxDockingWrapper::GetChildWindowId ()
257 DBG_ASSERT( false, "This method shouldn't be called!" );
258 return 0;
261 void SfxDockingWrapper::RegisterChildWindow (sal_Bool bVis, SfxModule *pMod, sal_uInt16 nFlags)
263 // pre-register a couple of docking windows
264 for (int i=0; i < NUM_OF_DOCKINGWINDOWS; i++ )
266 USHORT nID = USHORT(SID_DOCKWIN_START+i);
267 SfxChildWinFactory *pFact = new SfxChildWinFactory( SfxDockingWrapper::CreateImpl, nID, 0xffff );
268 pFact->aInfo.nFlags |= nFlags;
269 pFact->aInfo.bVisible = bVis;
270 SfxChildWindow::RegisterChildWindow(pMod, pFact);
274 SfxChildWinInfo SfxDockingWrapper::GetInfo() const
276 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
277 ((SfxDockingWindow*)GetWindow())->FillInfo( aInfo );
278 return aInfo;
281 SfxTitleDockingWindow::SfxTitleDockingWindow( SfxBindings* pBind ,
282 SfxChildWindow* pChildWin ,
283 Window* pParent ,
284 WinBits nBits,
285 USHORT nID ) :
286 SfxDockingWindow( pBind ,
287 pChildWin ,
288 pParent ,
289 nBits ),
290 m_pWrappedWindow(0),
291 m_nID(nID)
295 SfxTitleDockingWindow::~SfxTitleDockingWindow()
297 delete m_pWrappedWindow;
300 void SfxTitleDockingWindow::SetWrappedWindow( Window* const pWindow )
302 m_pWrappedWindow = pWindow;
303 if (m_pWrappedWindow)
305 m_pWrappedWindow->SetParent(this);
306 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
307 m_pWrappedWindow->Show();
311 long SfxTitleDockingWindow::Notify( NotifyEvent& rNEvt )
313 return SfxDockingWindow::Notify( rNEvt );
316 void SfxTitleDockingWindow::StateChanged( StateChangedType nType )
318 if ( nType == STATE_CHANGE_INITSHOW )
320 Window* pWindow = GetWrappedWindow();
321 if ( pWindow )
323 pWindow->SetSizePixel( GetOutputSizePixel() );
324 pWindow->Show();
328 SfxDockingWindow::StateChanged(nType);
331 void SfxTitleDockingWindow::Resize()
333 SfxDockingWindow::Resize();
334 if (m_pWrappedWindow)
335 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
338 void SfxTitleDockingWindow::Resizing( Size &rSize )
340 SfxDockingWindow::Resizing( rSize );
341 if (m_pWrappedWindow)
342 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
345 BOOL SfxTitleDockingWindow::Close()
347 return SfxDockingWindow::Close();
350 namespace
352 struct ChildrenRegisteredMap : public rtl::Static< bool, ChildrenRegisteredMap > {};
355 static bool lcl_checkDockingWindowID( USHORT nID )
357 if (nID < SID_DOCKWIN_START || nID >= USHORT(SID_DOCKWIN_START+NUM_OF_DOCKINGWINDOWS))
358 return false;
359 else
360 return true;
363 static SfxWorkWindow* lcl_getWorkWindowFromXFrame( const uno::Reference< frame::XFrame >& rFrame )
365 // We need to find the corresponding SfxFrame of our XFrame
366 SfxFrame* pFrame = SfxFrame::GetFirst();
367 SfxFrame* pXFrame = 0;
368 while ( pFrame )
370 uno::Reference< frame::XFrame > xViewShellFrame( pFrame->GetFrameInterface() );
371 if ( xViewShellFrame == rFrame )
373 pXFrame = pFrame;
374 break;
376 else
377 pFrame = SfxFrame::GetNext( *pFrame );
380 // If we have a SfxFrame we can retrieve the work window (Sfx layout manager for docking windows)
381 if ( pXFrame )
382 return pXFrame->GetWorkWindow_Impl();
383 else
384 return NULL;
388 Factory function used by the framework layout manager to "create" a docking window with a special name.
389 The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot range located
390 in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
392 void SAL_CALL SfxDockingWindowFactory( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName )
394 ::vos::OGuard aGuard( Application::GetSolarMutex() );
395 USHORT nID = USHORT(rDockingWindowName.toInt32());
397 // Check the range of the provided ID otherwise nothing will happen
398 if ( lcl_checkDockingWindowID( nID ))
400 SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
401 if ( pWorkWindow )
403 SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
404 if ( !pChildWindow )
406 // Register window at the workwindow child window list
407 pWorkWindow->SetChildWindow_Impl( nID, true, false );
414 Function used by the framework layout manager to determine the visibility state of a docking window with
415 a special name. The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot
416 range located in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
418 bool SAL_CALL IsDockingWindowVisible( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName )
420 ::vos::OGuard aGuard( Application::GetSolarMutex() );
422 USHORT nID = USHORT(rDockingWindowName.toInt32());
424 // Check the range of the provided ID otherwise nothing will happen
425 if ( lcl_checkDockingWindowID( nID ))
427 SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
428 if ( pWorkWindow )
430 SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
431 if ( pChildWindow )
432 return true;
436 return false;
439 class SfxDockingWindow_Impl
441 friend class SfxDockingWindow;
443 SfxChildAlignment eLastAlignment;
444 SfxChildAlignment eDockAlignment;
445 BOOL bConstructed;
446 Size aMinSize;
447 SfxSplitWindow* pSplitWin;
448 BOOL bSplitable;
449 // BOOL bAutoHide;
450 Timer aMoveTimer;
452 // Folgende members sind nur in der Zeit von StartDocking bis EndDocking
453 // g"ultig:
454 BOOL bEndDocked;
455 Size aSplitSize;
456 long nHorizontalSize;
457 long nVerticalSize;
458 USHORT nLine;
459 USHORT nPos;
460 USHORT nDockLine;
461 USHORT nDockPos;
462 BOOL bNewLine;
463 BOOL bDockingPrevented;
464 ByteString aWinState;
466 SfxChildAlignment GetLastAlignment() const
467 { return eLastAlignment; }
468 void SetLastAlignment(SfxChildAlignment eAlign)
469 { eLastAlignment = eAlign; }
470 SfxChildAlignment GetDockAlignment() const
471 { return eDockAlignment; }
472 void SetDockAlignment(SfxChildAlignment eAlign)
473 { eDockAlignment = eAlign; }
476 //-------------------------------------------------------------------------
478 void SfxDockingWindow::Resize()
480 /* [Beschreibung]
482 Diese virtuelle Methode der Klasse DockingWindow merkt sich ggf. eine
483 ver"anderte FloatingSize.
484 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
485 auch SfxDockingWindow::Resize() gerufen werden.
488 DockingWindow::Resize();
489 Invalidate();
490 if ( pImp->bConstructed && pMgr )
492 if ( IsFloatingMode() )
494 // start timer for saving window status information
495 pImp->aMoveTimer.Start();
497 else
499 Size aSize( GetSizePixel() );
500 switch ( pImp->GetDockAlignment() )
502 case SFX_ALIGN_LEFT:
503 case SFX_ALIGN_FIRSTLEFT:
504 case SFX_ALIGN_LASTLEFT:
505 case SFX_ALIGN_RIGHT:
506 case SFX_ALIGN_FIRSTRIGHT:
507 case SFX_ALIGN_LASTRIGHT:
508 pImp->nHorizontalSize = aSize.Width();
509 pImp->aSplitSize = aSize;
510 break;
511 case SFX_ALIGN_TOP:
512 case SFX_ALIGN_LOWESTTOP:
513 case SFX_ALIGN_HIGHESTTOP:
514 case SFX_ALIGN_BOTTOM:
515 case SFX_ALIGN_HIGHESTBOTTOM:
516 case SFX_ALIGN_LOWESTBOTTOM:
517 pImp->nVerticalSize = aSize.Height();
518 pImp->aSplitSize = aSize;
519 break;
520 default:
521 break;
527 //-------------------------------------------------------------------------
529 BOOL SfxDockingWindow::PrepareToggleFloatingMode()
531 /* [Beschreibung]
533 Diese virtuelle Methode der Klasse DockingWindow erm"oglicht ein Eingreifen
534 in das Umschalten des floating mode.
535 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
536 danach SfxDockingWindow::PrepareToggleFloatingMode() gerufen werden,
537 wenn nicht FALSE zur"uckgegeben wird.
541 if (!pImp->bConstructed)
542 return TRUE;
544 if ( (Application::IsInModalMode() && IsFloatingMode()) || !pMgr )
545 return FALSE;
547 if ( pImp->bDockingPrevented )
548 return FALSE;
550 if (!IsFloatingMode())
552 // Testen, ob FloatingMode erlaubt ist
553 if ( CheckAlignment(GetAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT )
554 return FALSE;
556 if ( pImp->pSplitWin )
558 // Das DockingWindow sitzt in einem SplitWindow und wird abgerissen
559 pImp->pSplitWin->RemoveWindow(this/*, FALSE*/);
560 pImp->pSplitWin = 0;
563 else if ( pMgr )
565 pImp->aWinState = GetFloatingWindow()->GetWindowState();
567 // Testen, ob es erlaubt ist, anzudocken
568 if (CheckAlignment(GetAlignment(),pImp->GetLastAlignment()) == SFX_ALIGN_NOALIGNMENT)
569 return FALSE;
571 // Testen, ob das Workwindow gerade ein Andocken erlaubt
572 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
573 if ( !pWorkWin->IsDockingAllowed() || !pWorkWin->IsInternalDockingAllowed() )
574 return FALSE;
577 return TRUE;
580 //-------------------------------------------------------------------------
582 void SfxDockingWindow::ToggleFloatingMode()
584 /* [Beschreibung]
586 Diese virtuelle Methode der Klasse DockingWindow setzt die internen
587 Daten des SfxDockingWindow und sorgt f"ur korrektes Alignment am
588 parent window.
589 Durch PrepareToggleFloatMode und Initialize ist sichergestellt, da\s
590 pImp->GetLastAlignment() immer eine erlaubtes Alignment liefert.
591 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
592 zuerst SfxDockingWindow::ToggleFloatingMode() gerufen werden.
595 if ( !pImp->bConstructed || !pMgr )
596 return; // Kein Handler-Aufruf
598 // Altes Alignment merken und dann umschalten.
599 // Sv hat jetzt schon umgeschaltet, aber Alignment am SfxDockingWindow
600 // ist noch das alte!
601 // Was war ich bisher ?
602 SfxChildAlignment eLastAlign = GetAlignment();
604 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
605 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
606 if ( pImp->bSplitable )
607 eIdent = SFX_CHILDWIN_SPLITWINDOW;
609 if (IsFloatingMode())
611 SetAlignment(SFX_ALIGN_NOALIGNMENT);
612 if ( pImp->aWinState.Len() )
613 GetFloatingWindow()->SetWindowState( pImp->aWinState );
614 else
615 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
617 if ( pImp->bSplitable && !pImp->bEndDocked )
618 // Wenn das Fenster vorher in einem SplitWindow lag, kommt von
619 // Sv kein Show
620 Show();
623 else
625 if (pImp->GetDockAlignment() == eLastAlign)
627 // Wenn ToggleFloatingMode aufgerufen wurde, das DockAlignment
628 // aber noch unver"andert ist, mu\s das ein Toggeln durch DClick
629 // gewesen sein, also LastAlignment verwenden
630 SetAlignment (pImp->GetLastAlignment());
631 if ( !pImp->bSplitable )
632 SetSizePixel( CalcDockingSize(GetAlignment()) );
634 else
636 // Toggeln wurde durch Draggen ausgel"ost
637 pImp->nLine = pImp->nDockLine;
638 pImp->nPos = pImp->nDockPos;
639 SetAlignment (pImp->GetDockAlignment());
642 if ( pImp->bSplitable )
644 // Das DockingWindow kommt jetzt in ein SplitWindow
645 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
647 // Das LastAlignment ist jetzt immer noch das zuletzt angedockte
648 SfxSplitWindow *pSplit = pWorkWin->GetSplitWindow_Impl(pImp->GetLastAlignment());
650 DBG_ASSERT( pSplit, "LastAlignment kann nicht stimmen!" );
651 if ( pSplit && pSplit != pImp->pSplitWin )
652 pSplit->ReleaseWindow_Impl(this);
653 if ( pImp->GetDockAlignment() == eLastAlign )
654 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
655 else
656 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nLine, pImp->nPos, pImp->bNewLine );
657 if ( !pImp->pSplitWin->IsFadeIn() )
658 pImp->pSplitWin->FadeIn();
662 // altes Alignment festhalten f"ur n"achstes Togglen; erst jetzt setzen
663 // wg. Abmelden beim SplitWindow!
664 pImp->SetLastAlignment(eLastAlign);
666 // DockAlignment zur"ucksetzen, falls noch EndDocking gerufen wird
667 pImp->SetDockAlignment(GetAlignment());
669 // SfxChildWindow korrekt andocken bzw. entdocken
670 if ( pMgr )
671 pWorkWin->ConfigChild_Impl( eIdent, SFX_TOGGLEFLOATMODE, pMgr->GetType() );
674 //-------------------------------------------------------------------------
676 void SfxDockingWindow::StartDocking()
678 /* [Beschreibung]
680 Diese virtuelle Methode der Klasse DockingWindow holt vom parent window
681 das innere und "au\sere docking rectangle.
682 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
683 am Ende SfxDockingWindow::StartDocking() gerufen werden.
686 if ( !pImp->bConstructed || !pMgr )
687 return;
688 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
689 if ( pImp->bSplitable )
690 eIdent = SFX_CHILDWIN_SPLITWINDOW;
691 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
692 pWorkWin->ConfigChild_Impl( eIdent, SFX_SETDOCKINGRECTS, pMgr->GetType() );
693 pImp->SetDockAlignment(GetAlignment());
695 if ( pImp->pSplitWin )
697 // Die aktuellen Docking-Daten besorgen
698 pImp->pSplitWin->GetWindowPos(this, pImp->nLine, pImp->nPos);
699 pImp->nDockLine = pImp->nLine;
700 pImp->nDockPos = pImp->nPos;
701 pImp->bNewLine = FALSE;
705 //-------------------------------------------------------------------------
707 BOOL SfxDockingWindow::Docking( const Point& rPos, Rectangle& rRect )
709 /* [Beschreibung]
711 Diese virtuelle Methode der Klasse DockingWindow berechnet das aktuelle
712 tracking rectangle. Dazu benutzt sie die Methode CalcAlignment(rPos,rRect),
713 deren Verhalten von abgeleiteten Klassen beeinflu\st werden kann (s.u.).
714 Diese Methode sollte nach M"oglichkeit nicht "uberschrieben werden.
717 if ( Application::IsInModalMode() )
718 return TRUE;
720 if ( !pImp->bConstructed || !pMgr )
722 rRect.SetSize( Size() );
723 return IsFloatingMode();
726 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
727 if ( pImp->bDockingPrevented || !pWorkWin->IsInternalDockingAllowed() )
728 return FALSE;
730 BOOL bFloatMode = FALSE;
732 if ( GetOuterRect().IsInside( rPos ) && !IsDockingPrevented() )
734 // Maus innerhalb OuterRect : Alignment und Rectangle berechnen
735 SfxChildAlignment eAlign = CalcAlignment(rPos, rRect);
736 if (eAlign == SFX_ALIGN_NOALIGNMENT)
737 bFloatMode = TRUE;
738 pImp->SetDockAlignment(eAlign);
740 else
742 // Maus nicht innerhalb OuterRect : muss FloatingWindow sein
743 // Ist das erlaubt ?
744 if (CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT)
745 return FALSE;
746 bFloatMode = TRUE;
747 if ( SFX_ALIGN_NOALIGNMENT != pImp->GetDockAlignment() )
749 // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das
750 // Alignment "andert !
751 pImp->SetDockAlignment(SFX_ALIGN_NOALIGNMENT);
752 rRect.SetSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT));
756 if ( !pImp->bSplitable )
758 // Bei individuell angedocktem Window wird die Position durch das
759 // Alignment und die docking rects festgelegt.
760 Size aSize = rRect.GetSize();
761 Point aPos;
763 switch ( pImp->GetDockAlignment() )
765 case SFX_ALIGN_LEFT:
766 case SFX_ALIGN_FIRSTLEFT:
767 case SFX_ALIGN_LASTLEFT:
768 aPos = aInnerRect.TopLeft();
769 if ( pImp->GetDockAlignment() == GetAlignment() )
770 aPos.X() -= aSize.Width();
771 break;
773 case SFX_ALIGN_TOP:
774 case SFX_ALIGN_LOWESTTOP:
775 case SFX_ALIGN_HIGHESTTOP:
776 aPos = Point(aOuterRect.Left(), aInnerRect.Top());
777 if ( pImp->GetDockAlignment() == GetAlignment() )
778 aPos.Y() -= aSize.Height();
779 break;
781 case SFX_ALIGN_RIGHT:
782 case SFX_ALIGN_FIRSTRIGHT:
783 case SFX_ALIGN_LASTRIGHT:
784 aPos = Point(aInnerRect.Right() - rRect.GetSize().Width(),
785 aInnerRect.Top());
786 if ( pImp->GetDockAlignment() == GetAlignment() )
787 aPos.X() += aSize.Width();
788 break;
790 case SFX_ALIGN_BOTTOM:
791 case SFX_ALIGN_HIGHESTBOTTOM:
792 case SFX_ALIGN_LOWESTBOTTOM:
793 aPos = Point(aOuterRect.Left(),
794 aInnerRect.Bottom() - rRect.GetSize().Height());
795 if ( pImp->GetDockAlignment() == GetAlignment() )
796 aPos.Y() += aSize.Height();
797 break;
798 default:
799 break;
802 rRect.SetPos(aPos);
805 return bFloatMode;
808 //-------------------------------------------------------------------------
810 void SfxDockingWindow::EndDocking( const Rectangle& rRect, BOOL bFloatMode )
812 /* [Beschreibung]
814 Diese virtuelle Methode der Klasse DockingWindow sorgt f"ur das korrekte
815 Alignment am parent window.
816 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
817 zuerst SfxDockingWindow::EndDocking() gerufen werden.
820 if ( !pImp->bConstructed || IsDockingCanceled() || !pMgr )
821 return;
823 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
824 BOOL bReArrange = FALSE;
825 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
826 if ( pImp->bSplitable )
828 eIdent = SFX_CHILDWIN_SPLITWINDOW;
830 // Wenn sich das Alignment "andert und das Fenster befindet sich
831 // im angedockten Zustand in einem SplitWindow, mu\s umgemeldet werden
832 // Wenn neu angedockt wird, machen PrepareToggleFloatingMode()
833 // und ToggleFloatingMode() das Ummelden.
834 if ( !bFloatMode )
835 bReArrange = TRUE;
838 if ( bReArrange )
840 if ( GetAlignment() != pImp->GetDockAlignment() )
842 // Vor dem Show() mu\s das Ummelden passiert sein, daher kann nicht
843 // die Basisklasse gerufen werden
844 if ( IsFloatingMode() || !pImp->bSplitable )
845 Show( FALSE, SHOW_NOFOCUSCHANGE );
847 // Die Gr"o\se f"urs Toggeln setzen
848 pImp->aSplitSize = rRect.GetSize();
849 if ( IsFloatingMode() )
851 SetFloatingMode( bFloatMode );
852 if ( IsFloatingMode() || !pImp->bSplitable )
853 Show( TRUE, SHOW_NOFOCUSCHANGE );
855 else
857 pImp->pSplitWin->RemoveWindow(this,FALSE);
858 pImp->nLine = pImp->nDockLine;
859 pImp->nPos = pImp->nDockPos;
860 pImp->pSplitWin->ReleaseWindow_Impl(this);
861 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(pImp->GetDockAlignment());
862 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine );
863 if ( !pImp->pSplitWin->IsFadeIn() )
864 pImp->pSplitWin->FadeIn();
867 else if ( pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || pImp->bNewLine )
869 // Ich wurde innerhalb meines Splitwindows verschoben.
870 if ( pImp->nLine != pImp->nDockLine )
871 pImp->aSplitSize = rRect.GetSize();
872 pImp->pSplitWin->MoveWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine );
875 else
877 pImp->bEndDocked = TRUE;
878 DockingWindow::EndDocking(rRect, bFloatMode);
879 pImp->bEndDocked = FALSE;
882 SetAlignment( IsFloatingMode() ? SFX_ALIGN_NOALIGNMENT : pImp->GetDockAlignment() );
885 //-------------------------------------------------------------------------
887 void SfxDockingWindow::Resizing( Size& /*rSize*/ )
889 /* [Beschreibung]
891 Virtuelle Methode der Klasse DockingWindow.
892 Hier kann das interaktive Umgr"o\sern im FloatingMode beeinflu\t werden,
893 z.B. indem nur diskrete Werte f"ur Breite und/oder H"ohe zugelassen werden.
894 Die Basisimplementation verhindert, da\s die OutputSize kleiner wird als
895 eine mit SetMinOutputSizePixel() gesetzte Gr"o\se.
900 if(rSize.Width() < pImp->aMinSize.Width())
901 rSize.Width() = pImp->aMinSize.Width();
902 if(rSize.Height() < pImp->aMinSize.Height())
903 rSize.Height() = pImp->aMinSize.Height();
907 //-------------------------------------------------------------------------
909 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
910 Window* pParent, WinBits nWinBits) :
911 DockingWindow (pParent, nWinBits),
912 pBindings(pBindinx),
913 pMgr(pCW),
914 pImp(NULL)
916 /* [Beschreibung]
918 ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt,
919 da das Andocken im Sfx "uber SfxChildWindows realisiert wird.
923 ULONG nId = GetHelpId();
924 if ( !nId && pCW )
925 nId = pCW->GetType();
926 SetHelpId( 0 );
927 SetUniqueId( nId );
929 pImp = new SfxDockingWindow_Impl;
930 pImp->bConstructed = FALSE;
931 pImp->pSplitWin = 0;
932 pImp->bEndDocked = FALSE;
933 pImp->bDockingPrevented = FALSE;
935 pImp->bSplitable = TRUE;
936 // pImp->bAutoHide = FALSE;
938 // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt
939 pImp->nLine = pImp->nDockLine = 0;
940 pImp->nPos = pImp->nDockPos = 0;
941 pImp->bNewLine = FALSE;
942 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
943 pImp->aMoveTimer.SetTimeout(50);
944 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl));
946 // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!");
949 //-------------------------------------------------------------------------
951 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
952 Window* pParent, const ResId& rResId) :
953 DockingWindow(pParent, rResId),
954 pBindings(pBindinx),
955 pMgr(pCW),
956 pImp(NULL)
958 /* [Beschreibung]
960 ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt,
961 da das Andocken im Sfx "uber SfxChildWindows realisiert wird.
965 ULONG nId = GetHelpId();
966 SetHelpId(0);
967 SetUniqueId( nId );
969 pImp = new SfxDockingWindow_Impl;
970 pImp->bConstructed = FALSE;
971 pImp->pSplitWin = 0;
972 pImp->bEndDocked = FALSE;
973 pImp->bDockingPrevented = FALSE;
975 pImp->bSplitable = TRUE;
976 // pImp->bAutoHide = FALSE;
978 // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt
979 pImp->nLine = pImp->nDockLine = 0;
980 pImp->nPos = pImp->nDockPos = 0;
981 pImp->bNewLine = FALSE;
982 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
983 pImp->aMoveTimer.SetTimeout(50);
984 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl));
986 // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!");
989 //-------------------------------------------------------------------------
991 void SfxDockingWindow::Initialize(SfxChildWinInfo *pInfo)
992 /* [Beschreibung]
994 Initialisierung der Klasse SfxDockingWindow "uber ein SfxChildWinInfo.
995 Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte
996 vom ctor der abgeleiteten Klasse oder vom ctor des SfxChildWindows
997 aufgerufen werden.
1000 if ( !pMgr )
1002 // Bugfix #39771
1003 pImp->SetDockAlignment( SFX_ALIGN_NOALIGNMENT );
1004 pImp->bConstructed = TRUE;
1005 return;
1008 if ( pInfo->nFlags & SFX_CHILDWIN_FORCEDOCK )
1009 pImp->bDockingPrevented = TRUE;
1011 pImp->aSplitSize = GetOutputSizePixel();
1012 if ( !GetFloatingSize().Width() )
1014 Size aMinSize( GetMinOutputSizePixel() );
1015 SetFloatingSize( pImp->aSplitSize );
1016 if ( pImp->aSplitSize.Width() < aMinSize.Width() )
1017 pImp->aSplitSize.Width() = aMinSize.Width();
1018 if ( pImp->aSplitSize.Height() < aMinSize.Height() )
1019 pImp->aSplitSize.Height() = aMinSize.Height();
1022 sal_Bool bVertHorzRead( sal_False );
1023 if ( pInfo->aExtraString.Len() )
1025 // get information about alignment, split size and position in SplitWindow
1026 String aStr;
1027 USHORT nPos = pInfo->aExtraString.SearchAscii("AL:");
1028 if ( nPos != STRING_NOTFOUND )
1030 // alignment information
1031 USHORT n1 = pInfo->aExtraString.Search('(', nPos);
1032 if ( n1 != STRING_NOTFOUND )
1034 USHORT n2 = pInfo->aExtraString.Search(')', n1);
1035 if ( n2 != STRING_NOTFOUND )
1037 // extract alignment information from extrastring
1038 aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1);
1039 pInfo->aExtraString.Erase(nPos, n2 - nPos + 1);
1040 aStr.Erase(nPos, n1-nPos+1);
1045 if ( aStr.Len() )
1047 // accept window state only if alignment is also set
1048 pImp->aWinState = pInfo->aWinState;
1050 // check for valid alignment
1051 SfxChildAlignment eLocalAlignment = (SfxChildAlignment) (USHORT) aStr.ToInt32();
1052 if ( pImp->bDockingPrevented )
1053 // docking prevented, ignore old configuration and take alignment from default
1054 aStr.Erase();
1055 else
1056 SetAlignment( eLocalAlignment );
1058 SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment());
1059 if ( eAlign != GetAlignment() )
1061 DBG_ERROR("Invalid Alignment!");
1062 SetAlignment( eAlign );
1063 aStr.Erase();
1066 // get last alignment (for toggeling)
1067 nPos = aStr.Search(',');
1068 if ( nPos != STRING_NOTFOUND )
1070 aStr.Erase(0, nPos+1);
1071 pImp->SetLastAlignment( (SfxChildAlignment) (USHORT) aStr.ToInt32() );
1074 nPos = aStr.Search(',');
1075 if ( nPos != STRING_NOTFOUND )
1077 // get split size and position in SplitWindow
1078 Point aPos;
1079 aStr.Erase(0, nPos+1);
1080 if ( GetPosSizeFromString( aStr, aPos, pImp->aSplitSize ) )
1082 pImp->nLine = pImp->nDockLine = (USHORT) aPos.X();
1083 pImp->nPos = pImp->nDockPos = (USHORT) aPos.Y();
1084 pImp->nVerticalSize = pImp->aSplitSize.Height();
1085 pImp->nHorizontalSize = pImp->aSplitSize.Width();
1086 if ( GetSplitSizeFromString( aStr, pImp->aSplitSize ))
1087 bVertHorzRead = sal_True;
1091 else {
1092 DBG_ERROR( "Information is missing!" );
1096 if ( !bVertHorzRead )
1098 pImp->nVerticalSize = pImp->aSplitSize.Height();
1099 pImp->nHorizontalSize = pImp->aSplitSize.Width();
1102 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1103 if ( GetAlignment() != SFX_ALIGN_NOALIGNMENT )
1105 // check if SfxWorkWindow is able to allow docking at its border
1106 if (
1107 !pWorkWin->IsDockingAllowed() ||
1108 !pWorkWin->IsInternalDockingAllowed() ||
1109 ( (GetFloatStyle() & WB_STANDALONE) && Application::IsInModalMode()) )
1111 SetAlignment( SFX_ALIGN_NOALIGNMENT );
1115 // detect floating mode
1116 // toggeling mode will not execute code in handlers, because pImp->bConstructed is not set yet
1117 BOOL bFloatMode = IsFloatingMode();
1118 if ( bFloatMode != ((GetAlignment() == SFX_ALIGN_NOALIGNMENT)) )
1120 bFloatMode = !bFloatMode;
1121 SetFloatingMode( bFloatMode );
1122 if ( bFloatMode )
1124 if ( pImp->aWinState.Len() )
1125 GetFloatingWindow()->SetWindowState( pImp->aWinState );
1126 else
1127 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
1131 if ( IsFloatingMode() )
1133 // validate last alignment
1134 SfxChildAlignment eLastAlign = pImp->GetLastAlignment();
1135 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1136 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_LEFT);
1137 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1138 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_RIGHT);
1139 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1140 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_TOP);
1141 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1142 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_BOTTOM);
1143 pImp->SetLastAlignment(eLastAlign);
1145 else
1147 // docked window must have NOALIGNMENT as last alignment
1148 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
1150 if ( pImp->bSplitable )
1152 // pImp->bAutoHide = ( pInfo->nFlags & SFX_CHILDWIN_AUTOHIDE) != 0;
1153 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
1154 pImp->pSplitWin->InsertWindow(this, pImp->aSplitSize);
1156 else
1158 //?????? Currently not supported
1159 // Fenster ist individuell angedockt; Gr"o\se berechnen.
1160 // Dazu mu\s sie mit der FloatingSize initialisiert werden, falls
1161 // irgendwer sich darauf verl"a\st, da\s eine vern"unftige Gr"o\se
1162 // gesetzt ist
1163 SetSizePixel(GetFloatingSize());
1164 SetSizePixel(CalcDockingSize(GetAlignment()));
1168 // save alignment
1169 pImp->SetDockAlignment( GetAlignment() );
1172 void SfxDockingWindow::Initialize_Impl()
1174 if ( !pMgr )
1176 // Bugfix #39771
1177 pImp->bConstructed = TRUE;
1178 return;
1181 FloatingWindow* pFloatWin = GetFloatingWindow();
1182 BOOL bSet = FALSE;
1183 if ( pFloatWin )
1185 bSet = !pFloatWin->IsDefaultPos();
1187 else
1189 Point aPos = GetFloatingPos();
1190 if ( aPos != Point() )
1191 bSet = TRUE;
1194 if ( !bSet)
1196 SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame();
1197 Window* pEditWin = pFrame->GetViewShell()->GetWindow();
1198 Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() );
1199 aPos = GetParent()->ScreenToOutputPixel( aPos );
1200 SetFloatingPos( aPos );
1203 if ( pFloatWin )
1205 // initialize floating window
1206 if ( !pImp->aWinState.Len() )
1207 // window state never set before, get if from defaults
1208 pImp->aWinState = pFloatWin->GetWindowState();
1210 // trick: use VCL method SetWindowState to adjust position and size
1211 pFloatWin->SetWindowState( pImp->aWinState );
1213 // remember floating size for calculating alignment and tracking rectangle
1214 SetFloatingSize( pFloatWin->GetSizePixel() );
1216 // some versions of VCL didn't call resize in the current situation
1217 //Resize();
1220 // allow calling of docking handlers
1221 pImp->bConstructed = TRUE;
1224 //-------------------------------------------------------------------------
1226 void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const
1228 /* [Beschreibung]
1230 F"ullt ein SfxChildWinInfo mit f"ur SfxDockingWindow spezifischen Daten,
1231 damit sie in die INI-Datei geschrieben werden koennen.
1232 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
1233 der ChildWindow-Klasse erh"alt.
1234 Eingetragen werden hier gemerkten Gr"o\sen, das ZoomIn-Flag und die
1235 f"ur das Docking relevanten Informationen.
1236 Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung
1237 gerufen werden.
1241 if ( !pMgr )
1242 return;
1244 if ( GetFloatingWindow() && pImp->bConstructed )
1245 pImp->aWinState = GetFloatingWindow()->GetWindowState();
1247 rInfo.aWinState = pImp->aWinState;
1248 rInfo.aExtraString = DEFINE_CONST_UNICODE("AL:(");
1249 rInfo.aExtraString += String::CreateFromInt32((USHORT) GetAlignment());
1250 rInfo.aExtraString += ',';
1251 rInfo.aExtraString += String::CreateFromInt32 ((USHORT) pImp->GetLastAlignment());
1252 if ( pImp->bSplitable )
1254 Point aPos(pImp->nLine, pImp->nPos);
1255 rInfo.aExtraString += ',';
1256 rInfo.aExtraString += String::CreateFromInt32( aPos.X() );
1257 rInfo.aExtraString += '/';
1258 rInfo.aExtraString += String::CreateFromInt32( aPos.Y() );
1259 rInfo.aExtraString += '/';
1260 rInfo.aExtraString += String::CreateFromInt32( pImp->nHorizontalSize );
1261 rInfo.aExtraString += '/';
1262 rInfo.aExtraString += String::CreateFromInt32( pImp->nVerticalSize );
1263 rInfo.aExtraString += ',';
1264 rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Width() );
1265 rInfo.aExtraString += ';';
1266 rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Height() );
1269 rInfo.aExtraString += ')';
1272 //-------------------------------------------------------------------------
1274 SfxDockingWindow::~SfxDockingWindow()
1276 ReleaseChildWindow_Impl();
1277 delete pImp;
1280 void SfxDockingWindow::ReleaseChildWindow_Impl()
1282 if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() )
1283 pBindings->SetActiveFrame( NULL );
1285 if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) )
1286 pImp->pSplitWin->RemoveWindow(this);
1288 pMgr=NULL;
1291 //-------------------------------------------------------------------------
1293 SfxChildAlignment SfxDockingWindow::CalcAlignment(const Point& rPos, Rectangle& rRect)
1295 /* [Beschreibung]
1297 Diese Methode berechnet f"ur gegebene Mausposition und tracking rectangle,
1298 welches Alignment sich daraus ergeben w"urde. Beim Wechsel des Alignments
1299 kann sich auch das tracking rectangle "andern, so dass ein ver"andertes
1300 rectangle zur"uckgegeben wird.
1302 Der Klassenbenutzer kann das Verhalten dieser Methode und damit das Verhalten
1303 seiner DockinWindow-Klasse beim Docken beeinflussen, indem er die hier
1304 aufgerufene virtuelle Methode
1306 SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
1308 "uberschreibt (s.u.).
1312 // calculate hypothetical sizes for different modes
1313 Size aFloatingSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT));
1314 Size aVerticalSize(CalcDockingSize(SFX_ALIGN_LEFT));
1315 Size aHorizontalSize(CalcDockingSize(SFX_ALIGN_TOP));
1317 // check if docking is permitted
1318 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1319 if ( !pWorkWin->IsDockingAllowed() )
1321 rRect.SetSize( aFloatingSize );
1322 return pImp->GetDockAlignment();
1325 // calculate borders to shrink inner area before checking for intersection with tracking rectangle
1326 long nLRBorder, nTBBorder;
1327 if ( pImp->bSplitable )
1329 // take the smaller size of docked and floating mode
1330 Size aSize = pImp->aSplitSize;
1331 if ( GetFloatingSize().Height() < aSize.Height() )
1332 aSize.Height() = GetFloatingSize().Height();
1333 if ( GetFloatingSize().Width() < aSize.Width() )
1334 aSize.Width() = GetFloatingSize().Width();
1336 nLRBorder = aSize.Width();
1337 nTBBorder = aSize.Height();
1339 else
1341 nLRBorder = aVerticalSize.Width();
1342 nTBBorder = aHorizontalSize.Height();
1345 // limit border to predefined constant values
1346 if ( nLRBorder > MAX_TOGGLEAREA_WIDTH )
1347 nLRBorder = MAX_TOGGLEAREA_WIDTH;
1348 if ( nTBBorder > MAX_TOGGLEAREA_WIDTH )
1349 nTBBorder = MAX_TOGGLEAREA_WIDTH;
1351 // shrink area for floating mode if possible
1352 Rectangle aInRect = GetInnerRect();
1353 if ( aInRect.GetWidth() > nLRBorder )
1354 aInRect.Left() += nLRBorder/2;
1355 if ( aInRect.GetWidth() > nLRBorder )
1356 aInRect.Right() -= nLRBorder/2;
1357 if ( aInRect.GetHeight() > nTBBorder )
1358 aInRect.Top() += nTBBorder/2;
1359 if ( aInRect.GetHeight() > nTBBorder )
1360 aInRect.Bottom() -= nTBBorder/2;
1362 // calculate alignment resulting from docking rectangle
1363 BOOL bBecomesFloating = FALSE;
1364 SfxChildAlignment eDockAlign = pImp->GetDockAlignment();
1365 Rectangle aDockingRect( rRect );
1366 if ( !IsFloatingMode() )
1368 // don't use tracking rectangle for alignment check, because it will be too large
1369 // to get a floating mode as result - switch to floating size
1370 // so the calculation only depends on the position of the rectangle, not the current
1371 // docking state of the window
1372 aDockingRect.SetSize( GetFloatingSize() );
1374 // in this mode docking is never done by keyboard, so it's OK to use the mouse position
1375 aDockingRect.SetPos( pWorkWin->GetWindow()->OutputToScreenPixel( pWorkWin->GetWindow()->GetPointerPosPixel() ) );
1378 Point aPos = aDockingRect.TopLeft();
1379 Rectangle aIntersect = GetOuterRect().GetIntersection( aDockingRect );
1380 if ( aIntersect.IsEmpty() )
1381 // docking rectangle completely outside docking area -> floating mode
1382 bBecomesFloating = TRUE;
1383 else
1385 // create a small test rect around the mouse position and use this one
1386 // instead of the passed rRect to not dock too easily or by accident
1387 Rectangle aSmallDockingRect;
1388 aSmallDockingRect.SetSize( Size( MAX_TOGGLEAREA_WIDTH, MAX_TOGGLEAREA_HEIGHT ) );
1389 Point aNewPos(rPos);
1390 aNewPos.X() -= aSmallDockingRect.GetWidth()/2;
1391 aNewPos.Y() -= aSmallDockingRect.GetHeight()/2;
1392 aSmallDockingRect.SetPos(rPos);
1393 Rectangle aIntersectRect = aInRect.GetIntersection( aSmallDockingRect );
1394 if ( aIntersectRect == aSmallDockingRect )
1395 // docking rectangle completely inside (shrinked) inner area -> floating mode
1396 bBecomesFloating = TRUE;
1399 if ( bBecomesFloating )
1401 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT);
1403 else
1405 // docking rectangle is in the "sensible area"
1406 Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() );
1407 Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() );
1408 Size aInSize = aInRect.GetSize();
1409 BOOL bNoChange = FALSE;
1411 // check if alignment is still unchanged
1412 switch ( GetAlignment() )
1414 case SFX_ALIGN_LEFT:
1415 case SFX_ALIGN_FIRSTLEFT:
1416 case SFX_ALIGN_LASTLEFT:
1417 if (aInPosTL.X() <= 0)
1419 eDockAlign = GetAlignment();
1420 bNoChange = TRUE;
1422 break;
1423 case SFX_ALIGN_TOP:
1424 case SFX_ALIGN_LOWESTTOP:
1425 case SFX_ALIGN_HIGHESTTOP:
1426 if ( aInPosTL.Y() <= 0)
1428 eDockAlign = GetAlignment();
1429 bNoChange = TRUE;
1431 break;
1432 case SFX_ALIGN_RIGHT:
1433 case SFX_ALIGN_FIRSTRIGHT:
1434 case SFX_ALIGN_LASTRIGHT:
1435 if ( aInPosBR.X() >= aInSize.Width())
1437 eDockAlign = GetAlignment();
1438 bNoChange = TRUE;
1440 break;
1441 case SFX_ALIGN_BOTTOM:
1442 case SFX_ALIGN_LOWESTBOTTOM:
1443 case SFX_ALIGN_HIGHESTBOTTOM:
1444 if ( aInPosBR.Y() >= aInSize.Height())
1446 eDockAlign = GetAlignment();
1447 bNoChange = TRUE;
1449 break;
1450 default:
1451 break;
1454 if ( !bNoChange )
1456 // alignment will change, test alignment according to distance of the docking rectangles edges
1457 BOOL bForbidden = TRUE;
1458 if ( aInPosTL.X() <= 0)
1460 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_LEFT);
1461 bForbidden = ( eDockAlign != SFX_ALIGN_LEFT &&
1462 eDockAlign != SFX_ALIGN_FIRSTLEFT &&
1463 eDockAlign != SFX_ALIGN_LASTLEFT );
1466 if ( bForbidden && aInPosTL.Y() <= 0)
1468 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_TOP);
1469 bForbidden = ( eDockAlign != SFX_ALIGN_TOP &&
1470 eDockAlign != SFX_ALIGN_HIGHESTTOP &&
1471 eDockAlign != SFX_ALIGN_LOWESTTOP );
1474 if ( bForbidden && aInPosBR.X() >= aInSize.Width())
1476 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_RIGHT);
1477 bForbidden = ( eDockAlign != SFX_ALIGN_RIGHT &&
1478 eDockAlign != SFX_ALIGN_FIRSTRIGHT &&
1479 eDockAlign != SFX_ALIGN_LASTRIGHT );
1482 if ( bForbidden && aInPosBR.Y() >= aInSize.Height())
1484 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_BOTTOM);
1485 bForbidden = ( eDockAlign != SFX_ALIGN_BOTTOM &&
1486 eDockAlign != SFX_ALIGN_HIGHESTBOTTOM &&
1487 eDockAlign != SFX_ALIGN_LOWESTBOTTOM );
1490 // the calculated alignment was rejected by the window -> take floating mode
1491 if ( bForbidden )
1492 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT);
1496 if ( eDockAlign == SFX_ALIGN_NOALIGNMENT )
1498 //Im FloatingMode erh"alt das tracking rectangle die floating size
1499 // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das
1500 // Alignment "andert !
1501 if ( eDockAlign != pImp->GetDockAlignment() )
1502 aDockingRect.SetSize( aFloatingSize );
1504 else if ( pImp->bSplitable )
1506 USHORT nLine, nPos;
1507 SfxSplitWindow *pSplitWin = pWorkWin->GetSplitWindow_Impl(eDockAlign);
1508 aPos = pSplitWin->ScreenToOutputPixel( aPos );
1509 if ( pSplitWin->GetWindowPos( aPos, nLine, nPos ) )
1511 // mouse over splitwindow, get line and position
1512 pImp->nDockLine = nLine;
1513 pImp->nDockPos = nPos;
1514 pImp->bNewLine = FALSE;
1516 else
1518 if ( 0 )
1520 // mouse touches outer border -> treated as floating mode
1521 eDockAlign = SFX_ALIGN_NOALIGNMENT;
1522 aDockingRect.SetSize( aFloatingSize );
1523 rRect = aDockingRect;
1524 return eDockAlign;
1527 // mouse touches inner border -> create new line
1528 if ( eDockAlign == GetAlignment() && pImp->pSplitWin &&
1529 pImp->nLine == pImp->pSplitWin->GetLineCount()-1 && pImp->pSplitWin->GetWindowCount(pImp->nLine) == 1 )
1531 // if this window is the only one in the last line, it can't be docked as new line in the same splitwindow
1532 pImp->nDockLine = pImp->nLine;
1533 pImp->nDockPos = pImp->nPos;
1534 pImp->bNewLine = FALSE;
1536 else
1538 // create new line
1539 pImp->nDockLine = pSplitWin->GetLineCount();
1540 pImp->nDockPos = 0;
1541 pImp->bNewLine = TRUE;
1545 BOOL bChanged = pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || eDockAlign != GetAlignment();
1546 if ( !bChanged && !IsFloatingMode() )
1548 // window only sightly moved, no change of any property
1549 rRect.SetSize( pImp->aSplitSize );
1550 rRect.SetPos( aDockingRect.TopLeft() );
1551 return eDockAlign;
1554 // calculate new size and position
1555 Size aSize;
1556 Point aPoint = aDockingRect.TopLeft();
1557 Size aInnerSize = GetInnerRect().GetSize();
1558 if ( eDockAlign == SFX_ALIGN_LEFT || eDockAlign == SFX_ALIGN_RIGHT )
1560 if ( pImp->bNewLine )
1562 // set height to height of free area
1563 aSize.Height() = aInnerSize.Height();
1564 aSize.Width() = pImp->nHorizontalSize;
1565 if ( eDockAlign == SFX_ALIGN_LEFT )
1567 aPoint = aInnerRect.TopLeft();
1569 else
1571 aPoint = aInnerRect.TopRight();
1572 aPoint.X() -= aSize.Width();
1575 else
1577 // get width from splitwindow
1578 aSize.Width() = pSplitWin->GetLineSize(nLine);
1579 aSize.Height() = pImp->aSplitSize.Height();
1582 else
1584 if ( pImp->bNewLine )
1586 // set width to width of free area
1587 aSize.Width() = aInnerSize.Width();
1588 aSize.Height() = pImp->nVerticalSize;
1589 if ( eDockAlign == SFX_ALIGN_TOP )
1591 aPoint = aInnerRect.TopLeft();
1593 else
1595 aPoint = aInnerRect.BottomLeft();
1596 aPoint.Y() -= aSize.Height();
1599 else
1601 // get height from splitwindow
1602 aSize.Height() = pSplitWin->GetLineSize(nLine);
1603 aSize.Width() = pImp->aSplitSize.Width();
1607 aDockingRect.SetSize( aSize );
1608 aDockingRect.SetPos( aPoint );
1610 else
1612 // window can be docked, but outside our splitwindows
1613 // tracking rectangle only needs to be modified if alignment was changed
1614 if ( eDockAlign != pImp->GetDockAlignment() )
1616 switch ( eDockAlign )
1618 case SFX_ALIGN_LEFT:
1619 case SFX_ALIGN_RIGHT:
1620 case SFX_ALIGN_FIRSTLEFT:
1621 aDockingRect.SetPos( aInnerRect.TopLeft() );
1622 aDockingRect.SetSize( aVerticalSize );
1623 break;
1624 case SFX_ALIGN_LASTLEFT:
1625 case SFX_ALIGN_FIRSTRIGHT:
1626 case SFX_ALIGN_LASTRIGHT:
1628 Point aPt( aInnerRect.TopRight() );
1629 aPt.X() -= aDockingRect.GetWidth();
1630 aDockingRect.SetPos( aPt );
1631 aDockingRect.SetSize( aVerticalSize );
1632 break;
1635 case SFX_ALIGN_TOP:
1636 case SFX_ALIGN_BOTTOM:
1637 case SFX_ALIGN_LOWESTTOP:
1638 aDockingRect.SetPos( aInnerRect.TopLeft() );
1639 aDockingRect.SetSize( aHorizontalSize );
1640 break;
1641 case SFX_ALIGN_HIGHESTTOP:
1642 case SFX_ALIGN_LOWESTBOTTOM:
1643 case SFX_ALIGN_HIGHESTBOTTOM:
1645 Point aPt( aInnerRect.BottomLeft() );
1646 aPt.Y() -= aDockingRect.GetHeight();
1647 aDockingRect.SetPos( aPt );
1648 aDockingRect.SetSize( aHorizontalSize );
1649 break;
1651 default:
1652 break;
1657 rRect = aDockingRect;
1658 return eDockAlign;
1661 //-------------------------------------------------------------------------
1663 Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
1665 /* [Beschreibung]
1667 Virtuelle Methode der Klasse SfxDockingWindow.
1668 Hier wird festgelegt, wie sich die Gr"o\se des DockingWindows abh"angig vom
1669 Alignment "andert.
1670 Die Basisimplementation setzt im Floating Mode die Gr"o\se auf die gemerkte
1671 Floating Size.
1672 Bei horizontalem Alignment wird die Breite auf die Breite des "au\seren
1673 DockingRects, bei vertikalem Alignment die H"ohe auf die H"ohe des inneren
1674 DockingRects (ergibt sich aus der Reihenfolge, in der im SFX ChildWindows
1675 ausgegeben werden). Die jeweils andere Gr"o\se wird auf die aktuelle
1676 Floating Size gesetzt, hier k"onnte eine abgeleitete Klasse "andernd
1677 eingreifen.
1678 Die DockingSize mu\s f"ur Left/Right und Top/Bottom jeweils gleich sein.
1682 // Achtung: falls das Resizing auch im angedockten Zustand geht, mu\s dabei
1683 // auch die Floating Size angepa\st werden !?
1685 Size aSize = GetFloatingSize();
1686 switch (eAlign)
1688 case SFX_ALIGN_TOP:
1689 case SFX_ALIGN_BOTTOM:
1690 case SFX_ALIGN_LOWESTTOP:
1691 case SFX_ALIGN_HIGHESTTOP:
1692 case SFX_ALIGN_LOWESTBOTTOM:
1693 case SFX_ALIGN_HIGHESTBOTTOM:
1694 aSize.Width() = aOuterRect.Right() - aOuterRect.Left();
1695 break;
1696 case SFX_ALIGN_LEFT:
1697 case SFX_ALIGN_RIGHT:
1698 case SFX_ALIGN_FIRSTLEFT:
1699 case SFX_ALIGN_LASTLEFT:
1700 case SFX_ALIGN_FIRSTRIGHT:
1701 case SFX_ALIGN_LASTRIGHT:
1702 aSize.Height() = aInnerRect.Bottom() - aInnerRect.Top();
1703 break;
1704 case SFX_ALIGN_NOALIGNMENT:
1705 break;
1706 default:
1707 break;
1710 return aSize;
1713 //-------------------------------------------------------------------------
1715 SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment,
1716 SfxChildAlignment eAlign)
1718 /* [Beschreibung]
1720 Virtuelle Methode der Klasse SfxDockingWindow.
1721 Hier kann eine abgeleitete Klasse bestimmte Alignments verbieten.
1722 Die Basisimplementation verbietet kein Alignment.
1726 return eAlign;
1729 //-------------------------------------------------------------------------
1731 BOOL SfxDockingWindow::Close()
1733 /* [Beschreibung]
1735 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
1736 ChildWindow-Slots zerst"ort wird.
1737 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
1738 danach SfxDockingWindow::Close() gerufen werden, wenn nicht das Close()
1739 mit "return FALSE" abgebrochen wird.
1743 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
1744 // werden kann
1745 if ( !pMgr )
1746 return TRUE;
1748 SfxBoolItem aValue( pMgr->GetType(), FALSE);
1749 pBindings->GetDispatcher_Impl()->Execute(
1750 pMgr->GetType(), SFX_CALLMODE_RECORD | SFX_CALLMODE_ASYNCHRON, &aValue, 0L );
1751 return TRUE;
1754 //-------------------------------------------------------------------------
1756 void SfxDockingWindow::Paint(const Rectangle& /*rRect*/)
1758 /* [Beschreibung]
1760 Es wird im angedockten Zustand eine Begrenzungslinie an der angedockten
1761 Kante und ein Rahmen ausgegeben. Dabei wird SVLOOK ber"ucksichtigt.
1765 if ( pImp->bSplitable || IsFloatingMode() )
1766 return;
1768 Rectangle aRect = Rectangle(Point(0, 0),
1769 GetOutputSizePixel());
1770 switch (GetAlignment())
1772 case SFX_ALIGN_TOP:
1774 DrawLine(aRect.BottomLeft(), aRect.BottomRight());
1775 aRect.Bottom()--;
1776 break;
1779 case SFX_ALIGN_BOTTOM:
1781 DrawLine(aRect.TopLeft(), aRect.TopRight());
1782 aRect.Top()++;
1783 break;
1786 case SFX_ALIGN_LEFT:
1788 DrawLine(aRect.TopRight(), aRect.BottomRight());
1789 aRect.Right()--;
1790 break;
1793 case SFX_ALIGN_RIGHT:
1795 DrawLine(aRect.TopLeft(), aRect.BottomLeft());
1796 aRect.Left()++;
1797 break;
1799 default:
1800 break;
1803 DecorationView aView( this );
1804 aView.DrawFrame( aRect, FRAME_DRAW_OUT );
1807 //-------------------------------------------------------------------------
1809 void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize )
1811 /* [Beschreibung]
1813 Mit dieser Methode kann eine minimale OutpuSize gesetzt werden, die
1814 im Resizing()-Handler abgefragt wird.
1818 pImp->aMinSize = rSize;
1819 DockingWindow::SetMinOutputSizePixel( rSize );
1822 //-------------------------------------------------------------------------
1824 Size SfxDockingWindow::GetMinOutputSizePixel() const
1826 /* [Beschreibung]
1828 Die gesetzte minimale Gr"o\se wird zur"uckgegeben.
1832 return pImp->aMinSize;
1835 //-------------------------------------------------------------------------
1837 long SfxDockingWindow::Notify( NotifyEvent& rEvt )
1839 if ( rEvt.GetType() == EVENT_GETFOCUS )
1841 pBindings->SetActiveFrame( pMgr->GetFrame() );
1843 if ( pImp->pSplitWin )
1844 pImp->pSplitWin->SetActiveWindow_Impl( this );
1845 else
1846 pMgr->Activate_Impl();
1848 Window* pWindow = rEvt.GetWindow();
1849 ULONG nHelpId = 0;
1850 while ( !nHelpId && pWindow )
1852 nHelpId = pWindow->GetHelpId();
1853 pWindow = pWindow->GetParent();
1856 if ( nHelpId )
1857 SfxHelp::OpenHelpAgent( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), nHelpId );
1859 // In VCL geht Notify zun"achst an das Fenster selbst,
1860 // also base class rufen, sonst erf"ahrt der parent nichts
1861 // if ( rEvt.GetWindow() == this ) PB: #i74693# not necessary any longer
1862 DockingWindow::Notify( rEvt );
1863 return TRUE;
1865 else if( rEvt.GetType() == EVENT_KEYINPUT )
1867 // KeyInput zuerst f"ur Dialogfunktionen zulassen
1868 if ( !DockingWindow::Notify( rEvt ) && SfxViewShell::Current() )
1869 // dann auch global g"ultige Acceleratoren verwenden
1870 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
1871 return TRUE;
1873 else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
1875 pBindings->SetActiveFrame( NULL );
1876 pMgr->Deactivate_Impl();
1879 return DockingWindow::Notify( rEvt );
1883 USHORT SfxDockingWindow::GetWinBits_Impl() const
1885 USHORT nBits = 0;
1886 // if ( pImp->bAutoHide )
1887 // nBits |= SWIB_AUTOHIDE;
1888 return nBits;
1891 //-------------------------------------------------------------------------
1893 void SfxDockingWindow::SetItemSize_Impl( const Size& rSize )
1895 pImp->aSplitSize = rSize;
1897 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1898 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
1899 if ( pImp->bSplitable )
1900 eIdent = SFX_CHILDWIN_SPLITWINDOW;
1901 pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
1904 void SfxDockingWindow::Disappear_Impl()
1906 if ( pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) )
1907 pImp->pSplitWin->RemoveWindow(this);
1910 void SfxDockingWindow::Reappear_Impl()
1912 if ( pImp->pSplitWin && !pImp->pSplitWin->IsItemValid( GetType() ) )
1914 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
1918 BOOL SfxDockingWindow::IsAutoHide_Impl() const
1920 if ( pImp->pSplitWin )
1921 return !pImp->pSplitWin->IsFadeIn();
1922 else
1923 return FALSE;
1926 BOOL SfxDockingWindow::IsPinned_Impl() const
1928 if ( pImp->pSplitWin )
1929 return pImp->pSplitWin->IsPinned();
1930 else
1931 return TRUE;
1933 void SfxDockingWindow::AutoShow( BOOL bShow )
1935 AutoShow_Impl(bShow);
1938 void SfxDockingWindow::AutoShow_Impl( BOOL bShow )
1940 if ( pImp->pSplitWin )
1942 if ( bShow )
1943 pImp->pSplitWin->FadeIn();
1944 else
1945 pImp->pSplitWin->FadeOut();
1950 void SfxDockingWindow::Pin_Impl( BOOL bPinned )
1952 if ( pImp->pSplitWin )
1953 pImp->pSplitWin->Pin_Impl( bPinned );
1957 SfxSplitWindow* SfxDockingWindow::GetSplitWindow_Impl() const
1959 return pImp->pSplitWin;
1962 void SfxDockingWindow::FadeIn( BOOL /*bFadeIn*/ )
1966 void SfxDockingWindow::StateChanged( StateChangedType nStateChange )
1968 if ( nStateChange == STATE_CHANGE_INITSHOW )
1969 Initialize_Impl();
1971 DockingWindow::StateChanged( nStateChange );
1974 void SfxDockingWindow::Move()
1976 if ( pImp )
1977 pImp->aMoveTimer.Start();
1980 IMPL_LINK( SfxDockingWindow, TimerHdl, Timer*, EMPTYARG)
1982 pImp->aMoveTimer.Stop();
1983 if ( IsReallyVisible() && IsFloatingMode() )
1985 if( !GetFloatingWindow()->IsRollUp() )
1986 SetFloatingSize( GetOutputSizePixel() );
1987 pImp->aWinState = GetFloatingWindow()->GetWindowState();
1988 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
1989 if ( pImp->bSplitable )
1990 eIdent = SFX_CHILDWIN_SPLITWINDOW;
1991 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1992 pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
1994 return 0;