xref: /aoo41x/main/sfx2/source/dialog/dockwin.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 
31 #include <svl/eitem.hxx>
32 #include <vcl/decoview.hxx>
33 
34 #include <vcl/svapp.hxx>
35 #include <vcl/timer.hxx>
36 #include <rtl/instance.hxx>
37 #include <toolkit/helper/vclunohelper.hxx>
38 #include <comphelper/processfactory.hxx>
39 
40 #include <sfx2/dockwin.hxx>
41 #include <sfx2/bindings.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <sfx2/dispatch.hxx>
44 #include "workwin.hxx"
45 #include "splitwin.hxx"
46 #include <sfx2/viewsh.hxx>
47 #include "sfx2/sfxhelp.hxx"
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/msgpool.hxx>
50 
51 #include <com/sun/star/frame/XController.hpp>
52 #include <com/sun/star/lang/XUnoTunnel.hpp>
53 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
54 #include <com/sun/star/awt/XWindow.hpp>
55 #include <com/sun/star/uno/XComponentContext.hpp>
56 #include <com/sun/star/frame/XModuleManager.hpp>
57 #include <com/sun/star/container/XNameAccess.hpp>
58 
59 #define MAX_TOGGLEAREA_WIDTH 		20
60 #define MAX_TOGGLEAREA_HEIGHT		20
61 
62 using namespace ::com::sun::star;
63 
64 // implemented in 'sfx2/source/appl/childwin.cxx'
65 extern sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize );
66 extern sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize );
67 
68 // If you want to change the number you also have to:
69 // - Add new slot ids to sfxsids.hrc
70 // - Add new slots to frmslots.sdi
71 // - Add new slot definitions to sfx.sdi
72 static const int NUM_OF_DOCKINGWINDOWS = 10;
73 
74 class SfxTitleDockingWindow;
75 class SfxTitleDockingWindow : public SfxDockingWindow
76 {
77 	Window*				m_pWrappedWindow;
78 	sal_uInt16              m_nID;
79 
80 public:
81 						SfxTitleDockingWindow(
82 							SfxBindings* pBindings ,
83 							SfxChildWindow* pChildWin ,
84 							Window* pParent ,
85 							WinBits nBits,
86 							sal_uInt16  nID);
87 	virtual             ~SfxTitleDockingWindow();
88 
89 	Window*				GetWrappedWindow() const { return m_pWrappedWindow; }
90 	void				SetWrappedWindow(Window* const pWindow);
91 
92     virtual void        StateChanged( StateChangedType nType );
93     virtual long        Notify( NotifyEvent& rNEvt );
94 	virtual void 		Resize();
95 	virtual void        Resizing( Size& rSize );
96 	virtual sal_Bool        Close();
97 };
98 
99 namespace
100 {
101     struct WindowState
102     {
103         ::rtl::OUString sTitle;
104     };
105 }
106 
107 static uno::WeakReference< container::XNameAccess > m_xWindowStateConfiguration;
108 static uno::WeakReference< frame::XModuleManager >  m_xModuleManager;
109 
110 static bool lcl_getWindowState( const uno::Reference< container::XNameAccess >& xWindowStateMgr, const ::rtl::OUString& rResourceURL, WindowState& rWindowState )
111 {
112     bool bResult = false;
113 
114     try
115     {
116         uno::Any a;
117         uno::Sequence< beans::PropertyValue > aWindowState;
118         a = xWindowStateMgr->getByName( rResourceURL );
119         if ( a >>= aWindowState )
120         {
121             for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
122             {
123                 if ( aWindowState[n].Name.equalsAscii( "UIName" ))
124                 {
125                     aWindowState[n].Value >>= rWindowState.sTitle;
126                 }
127             }
128         }
129 
130         bResult = true;
131     }
132     catch ( container::NoSuchElementException& )
133     {
134         bResult = false;
135     }
136 
137     return bResult;
138 }
139 
140 SfxDockingWrapper::SfxDockingWrapper( Window* pParentWnd ,
141 								      sal_uInt16 nId ,
142 									  SfxBindings* pBindings ,
143 									  SfxChildWinInfo* pInfo )
144 					: SfxChildWindow( pParentWnd , nId )
145 {
146     uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
147     const rtl::OUString aDockWindowResourceURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/dockingwindow/" ));
148 
149     SfxTitleDockingWindow* pTitleDockWindow = new SfxTitleDockingWindow( pBindings, this, pParentWnd,
150         WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE, nId);
151     pWindow = pTitleDockWindow;
152 	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
153 
154     // Use factory manager to retrieve XWindow factory. That can be used to instanciate
155     // the real window factory.
156     uno::Reference< lang::XSingleComponentFactory > xFactoryMgr(
157             xServiceManager->createInstance(
158                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
159                     "com.sun.star.ui.WindowContentFactoryManager"))),
160                 uno::UNO_QUERY );
161 
162     if (xFactoryMgr.is())
163     {
164         SfxDispatcher* pDispatcher = pBindings->GetDispatcher();
165         uno::Reference< frame::XFrame > xFrame( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY );
166         uno::Sequence< uno::Any > aArgs(2);
167         beans::PropertyValue      aPropValue;
168         aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
169         aPropValue.Value = uno::makeAny( xFrame );
170         aArgs[0] <<= aPropValue;
171         aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
172 
173         // create a resource URL from the nId provided by the sfx2
174         ::rtl::OUString aResourceURL( aDockWindowResourceURL );
175         aResourceURL += ::rtl::OUString::valueOf(sal_Int32(nId));
176         aPropValue.Value = uno::makeAny( aResourceURL );
177         aArgs[1] <<= aPropValue;
178 
179         uno::Reference< awt::XWindow > xWindow;
180         try
181         {
182             uno::Reference< beans::XPropertySet >    xProps( xServiceManager, uno::UNO_QUERY );
183             uno::Reference< uno::XComponentContext > xContext;
184 
185             if ( xProps.is() )
186                 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
187             if ( xContext.is() )
188             {
189                 xWindow = uno::Reference< awt::XWindow>(
190                             xFactoryMgr->createInstanceWithArgumentsAndContext( aArgs, xContext ),
191                           uno::UNO_QUERY );
192             }
193 
194             uno::Reference< frame::XModuleManager > xModuleManager( m_xModuleManager );
195             if ( !xModuleManager.is() )
196             {
197                 xModuleManager = uno::Reference< frame::XModuleManager >(
198                                     xServiceManager->createInstance(
199                                         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))),
200                                     uno::UNO_QUERY );
201                 m_xModuleManager = xModuleManager;
202             }
203 
204             uno::Reference< container::XNameAccess > xWindowStateConfiguration( m_xWindowStateConfiguration );
205             if ( !xWindowStateConfiguration.is() )
206             {
207                 xWindowStateConfiguration = uno::Reference< container::XNameAccess >(
208                                                 xServiceManager->createInstance(
209                                                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.WindowStateConfiguration" ))),
210                                                 uno::UNO_QUERY );
211                 m_xWindowStateConfiguration = xWindowStateConfiguration;
212             }
213 
214             ::rtl::OUString sModuleIdentifier = xModuleManager->identify( xFrame );
215 
216             uno::Reference< container::XNameAccess > xModuleWindowState(
217                                                         xWindowStateConfiguration->getByName( sModuleIdentifier ),
218                                                         uno::UNO_QUERY );
219             if ( xModuleWindowState.is() )
220             {
221                 WindowState aDockWinState;
222                 if ( lcl_getWindowState( xModuleWindowState, aResourceURL, aDockWinState ))
223                     pTitleDockWindow->SetText( aDockWinState.sTitle );
224             }
225         }
226         catch ( beans::UnknownPropertyException& )
227         {
228         }
229         catch ( uno::RuntimeException& )
230         {
231         }
232         catch ( uno::Exception& )
233         {
234         }
235 
236         Window* pContentWindow = VCLUnoHelper::GetWindow(xWindow);
237         if ( pContentWindow )
238             pContentWindow->SetStyle( pContentWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
239 		pTitleDockWindow->SetWrappedWindow(pContentWindow);
240     }
241 
242     pWindow->SetOutputSizePixel( Size( 270, 240 ) );
243 
244 	( ( SfxDockingWindow* ) pWindow )->Initialize( pInfo );
245 	SetHideNotDelete( sal_True );
246 }
247 
248 SfxChildWindow*  SfxDockingWrapper::CreateImpl(
249 Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo* pInfo )
250 {
251     SfxChildWindow *pWin = new SfxDockingWrapper(pParent, nId, pBindings, pInfo); return pWin;
252 }
253 
254 sal_uInt16 SfxDockingWrapper::GetChildWindowId ()
255 {
256 	DBG_ASSERT( false, "This method shouldn't be called!" );
257 	return 0;
258 }
259 
260 void SfxDockingWrapper::RegisterChildWindow (sal_Bool bVis, SfxModule *pMod, sal_uInt16 nFlags)
261 {
262 	// pre-register a couple of docking windows
263 	for (int i=0; i < NUM_OF_DOCKINGWINDOWS; i++ )
264 	{
265 		sal_uInt16 nID = sal_uInt16(SID_DOCKWIN_START+i);
266 		SfxChildWinFactory *pFact = new SfxChildWinFactory( SfxDockingWrapper::CreateImpl, nID, 0xffff );
267 		pFact->aInfo.nFlags |= nFlags;
268 		pFact->aInfo.bVisible = bVis;
269 		SfxChildWindow::RegisterChildWindow(pMod, pFact);
270 	}
271 }
272 
273 SfxChildWinInfo  SfxDockingWrapper::GetInfo() const
274 {
275     SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
276 	((SfxDockingWindow*)GetWindow())->FillInfo( aInfo );
277 	return aInfo;
278 };
279 
280 SfxTitleDockingWindow::SfxTitleDockingWindow( SfxBindings* pBind ,
281 											  SfxChildWindow* pChildWin ,
282 										      Window* pParent ,
283 										      WinBits nBits,
284 											  sal_uInt16  nID ) :
285 						  SfxDockingWindow( pBind ,
286 										    pChildWin ,
287 										    pParent ,
288 										    nBits ),
289                           m_pWrappedWindow(0),
290 					      m_nID(nID)
291 {
292 }
293 
294 SfxTitleDockingWindow::~SfxTitleDockingWindow()
295 {
296 	delete m_pWrappedWindow;
297 }
298 
299 void SfxTitleDockingWindow::SetWrappedWindow( Window* const pWindow )
300 {
301 	m_pWrappedWindow = pWindow;
302 	if (m_pWrappedWindow)
303 	{
304 		m_pWrappedWindow->SetParent(this);
305 		m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
306 		m_pWrappedWindow->Show();
307 	}
308 }
309 
310 long SfxTitleDockingWindow::Notify( NotifyEvent& rNEvt )
311 {
312     return SfxDockingWindow::Notify( rNEvt );
313 }
314 
315 void SfxTitleDockingWindow::StateChanged( StateChangedType nType )
316 {
317     if ( nType == STATE_CHANGE_INITSHOW )
318     {
319         Window* pWindow = GetWrappedWindow();
320         if ( pWindow )
321         {
322 		    pWindow->SetSizePixel( GetOutputSizePixel() );
323             pWindow->Show();
324         }
325     }
326 
327     SfxDockingWindow::StateChanged(nType);
328 }
329 
330 void SfxTitleDockingWindow::Resize()
331 {
332 	SfxDockingWindow::Resize();
333 	if (m_pWrappedWindow)
334         m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
335 }
336 
337 void SfxTitleDockingWindow::Resizing( Size &rSize )
338 {
339 	SfxDockingWindow::Resizing( rSize );
340 	if (m_pWrappedWindow)
341         m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() );
342 }
343 
344 sal_Bool SfxTitleDockingWindow::Close()
345 {
346 	return SfxDockingWindow::Close();
347 }
348 
349 namespace
350 {
351     struct ChildrenRegisteredMap : public rtl::Static< bool, ChildrenRegisteredMap > {};
352 }
353 
354 static bool lcl_checkDockingWindowID( sal_uInt16 nID )
355 {
356     if (nID < SID_DOCKWIN_START || nID >= sal_uInt16(SID_DOCKWIN_START+NUM_OF_DOCKINGWINDOWS))
357 		return false;
358     else
359         return true;
360 }
361 
362 static SfxWorkWindow* lcl_getWorkWindowFromXFrame( const uno::Reference< frame::XFrame >& rFrame )
363 {
364 	// We need to find the corresponding SfxFrame of our XFrame
365 	SfxFrame* pFrame  = SfxFrame::GetFirst();
366 	SfxFrame* pXFrame = 0;
367 	while ( pFrame )
368 	{
369 		uno::Reference< frame::XFrame > xViewShellFrame( pFrame->GetFrameInterface() );
370 		if ( xViewShellFrame == rFrame )
371 		{
372 			pXFrame = pFrame;
373 			break;
374 		}
375 		else
376 			pFrame = SfxFrame::GetNext( *pFrame );
377 	}
378 
379 	// If we have a SfxFrame we can retrieve the work window (Sfx layout manager for docking windows)
380 	if ( pXFrame )
381 		return pXFrame->GetWorkWindow_Impl();
382     else
383         return NULL;
384 }
385 
386 /*
387     Factory function used by the framework layout manager to "create" a docking window with a special name.
388     The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot range located
389     in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
390 */
391 void SAL_CALL SfxDockingWindowFactory( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName )
392 {
393 	::vos::OGuard aGuard( Application::GetSolarMutex() );
394 	sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32());
395 
396 	// Check the range of the provided ID otherwise nothing will happen
397     if ( lcl_checkDockingWindowID( nID ))
398     {
399         SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
400         if ( pWorkWindow )
401         {
402 		    SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
403 		    if ( !pChildWindow )
404 		    {
405                 // Register window at the workwindow child window list
406                 pWorkWindow->SetChildWindow_Impl( nID, true, false );
407 		    }
408 	    }
409     }
410 }
411 
412 /*
413     Function used by the framework layout manager to determine the visibility state of a docking window with
414     a special name. The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot
415     range located in sfxsids.hrc (currently SID_DOCKWIN_START = 9800).
416 */
417 bool SAL_CALL IsDockingWindowVisible( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName )
418 {
419 	::vos::OGuard aGuard( Application::GetSolarMutex() );
420 
421     sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32());
422 
423 	// Check the range of the provided ID otherwise nothing will happen
424     if ( lcl_checkDockingWindowID( nID ))
425     {
426         SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame );
427         if ( pWorkWindow )
428         {
429 		    SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID);
430             if ( pChildWindow )
431                 return true;
432         }
433     }
434 
435     return false;
436 }
437 
438 class SfxDockingWindow_Impl
439 {
440 friend class SfxDockingWindow;
441 
442 	SfxChildAlignment	eLastAlignment;
443 	SfxChildAlignment	eDockAlignment;
444 	sal_Bool				bConstructed;
445 	Size				aMinSize;
446 	SfxSplitWindow*		pSplitWin;
447 	sal_Bool				bSplitable;
448 //	sal_Bool				bAutoHide;
449     Timer               aMoveTimer;
450 
451 	// Folgende members sind nur in der Zeit von StartDocking bis EndDocking
452 	// g"ultig:
453 	sal_Bool				bEndDocked;
454 	Size				aSplitSize;
455     long                nHorizontalSize;
456     long                nVerticalSize;
457 	sal_uInt16				nLine;
458 	sal_uInt16 				nPos;
459 	sal_uInt16 				nDockLine;
460 	sal_uInt16				nDockPos;
461 	sal_Bool				bNewLine;
462 	sal_Bool 				bDockingPrevented;
463     ByteString          aWinState;
464 
465 	SfxChildAlignment	GetLastAlignment() const
466 						{ return eLastAlignment; }
467 	void				SetLastAlignment(SfxChildAlignment eAlign)
468 						{ eLastAlignment = eAlign; }
469 	SfxChildAlignment	GetDockAlignment() const
470 						{ return eDockAlignment; }
471 	void				SetDockAlignment(SfxChildAlignment eAlign)
472 						{ eDockAlignment = eAlign; }
473 };
474 
475 //-------------------------------------------------------------------------
476 
477 void SfxDockingWindow::Resize()
478 
479 /*  [Beschreibung]
480 
481 	Diese virtuelle Methode der Klasse DockingWindow merkt sich ggf. eine
482 	ver"anderte FloatingSize.
483 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
484 	auch SfxDockingWindow::Resize() gerufen werden.
485 */
486 {
487 	DockingWindow::Resize();
488     Invalidate();
489     if ( pImp->bConstructed && pMgr )
490     {
491         if ( IsFloatingMode() )
492         {
493             // start timer for saving window status information
494             pImp->aMoveTimer.Start();
495         }
496 		else
497 		{
498             Size aSize( GetSizePixel() );
499             switch ( pImp->GetDockAlignment() )
500             {
501                 case SFX_ALIGN_LEFT:
502                 case SFX_ALIGN_FIRSTLEFT:
503                 case SFX_ALIGN_LASTLEFT:
504                 case SFX_ALIGN_RIGHT:
505                 case SFX_ALIGN_FIRSTRIGHT:
506                 case SFX_ALIGN_LASTRIGHT:
507                     pImp->nHorizontalSize = aSize.Width();
508                     pImp->aSplitSize = aSize;
509                     break;
510                 case SFX_ALIGN_TOP:
511                 case SFX_ALIGN_LOWESTTOP:
512                 case SFX_ALIGN_HIGHESTTOP:
513                 case SFX_ALIGN_BOTTOM:
514                 case SFX_ALIGN_HIGHESTBOTTOM:
515                 case SFX_ALIGN_LOWESTBOTTOM:
516                     pImp->nVerticalSize = aSize.Height();
517                     pImp->aSplitSize = aSize;
518                     break;
519                 default:
520                     break;
521             }
522 		}
523     }
524 }
525 
526 //-------------------------------------------------------------------------
527 
528 sal_Bool SfxDockingWindow::PrepareToggleFloatingMode()
529 
530 /*  [Beschreibung]
531 
532 	Diese virtuelle Methode der Klasse DockingWindow erm"oglicht ein Eingreifen
533 	in das Umschalten des floating mode.
534 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
535 	danach SfxDockingWindow::PrepareToggleFloatingMode() gerufen werden,
536 	wenn nicht FALSE zur"uckgegeben wird.
537 */
538 
539 {
540 	if (!pImp->bConstructed)
541 		return sal_True;
542 
543 	if ( (Application::IsInModalMode() && IsFloatingMode()) || !pMgr )
544 		return sal_False;
545 
546     if ( pImp->bDockingPrevented )
547 		return sal_False;
548 
549     if (!IsFloatingMode())
550 	{
551 		// Testen, ob FloatingMode erlaubt ist
552         if ( CheckAlignment(GetAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT )
553 			return sal_False;
554 
555 		if ( pImp->pSplitWin )
556 		{
557 			// Das DockingWindow sitzt in einem SplitWindow und wird abgerissen
558 			pImp->pSplitWin->RemoveWindow(this/*, sal_False*/);
559 			pImp->pSplitWin = 0;
560 		}
561 	}
562 	else if ( pMgr )
563 	{
564 		pImp->aWinState = GetFloatingWindow()->GetWindowState();
565 
566 		// Testen, ob es erlaubt ist, anzudocken
567         if (CheckAlignment(GetAlignment(),pImp->GetLastAlignment()) == SFX_ALIGN_NOALIGNMENT)
568 			return sal_False;
569 
570 		// Testen, ob das Workwindow gerade ein Andocken erlaubt
571 		SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
572 		if ( !pWorkWin->IsDockingAllowed() || !pWorkWin->IsInternalDockingAllowed() )
573 			return sal_False;
574 	}
575 
576 	return sal_True;
577 }
578 
579 //-------------------------------------------------------------------------
580 
581 void SfxDockingWindow::ToggleFloatingMode()
582 
583 /*  [Beschreibung]
584 
585 	Diese virtuelle Methode der Klasse DockingWindow setzt die internen
586 	Daten des SfxDockingWindow und sorgt f"ur korrektes Alignment am
587 	parent window.
588 	Durch PrepareToggleFloatMode und Initialize ist sichergestellt, da\s
589 	pImp->GetLastAlignment() immer eine erlaubtes Alignment liefert.
590 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
591 	zuerst SfxDockingWindow::ToggleFloatingMode() gerufen werden.
592 */
593 {
594 	if ( !pImp->bConstructed || !pMgr )
595 		return;					// Kein Handler-Aufruf
596 
597 	// Altes Alignment merken und dann umschalten.
598 	// Sv hat jetzt schon umgeschaltet, aber Alignment am SfxDockingWindow
599 	// ist noch das alte!
600 	// Was war ich bisher ?
601 	SfxChildAlignment eLastAlign = GetAlignment();
602 
603 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
604 	SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
605 	if ( pImp->bSplitable )
606 		eIdent = SFX_CHILDWIN_SPLITWINDOW;
607 
608 	if (IsFloatingMode())
609 	{
610 		SetAlignment(SFX_ALIGN_NOALIGNMENT);
611         if ( pImp->aWinState.Len() )
612             GetFloatingWindow()->SetWindowState( pImp->aWinState );
613         else
614             GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
615 /*
616 		if ( pImp->bSplitable && !pImp->bEndDocked )
617 			// Wenn das Fenster vorher in einem SplitWindow lag, kommt von
618 			// Sv kein Show
619 			Show();
620 */
621 	}
622 	else
623 	{
624 		if (pImp->GetDockAlignment() == eLastAlign)
625 		{
626 			// Wenn ToggleFloatingMode aufgerufen wurde, das DockAlignment
627 			// aber noch unver"andert ist, mu\s das ein Toggeln durch DClick
628 			// gewesen sein, also LastAlignment verwenden
629 			SetAlignment (pImp->GetLastAlignment());
630             if ( !pImp->bSplitable )
631 				SetSizePixel( CalcDockingSize(GetAlignment()) );
632 		}
633 		else
634 		{
635 			// Toggeln wurde durch Draggen ausgel"ost
636 			pImp->nLine = pImp->nDockLine;
637 			pImp->nPos = pImp->nDockPos;
638 			SetAlignment (pImp->GetDockAlignment());
639 		}
640 
641 		if ( pImp->bSplitable )
642 		{
643 			// Das DockingWindow kommt jetzt in ein SplitWindow
644 			pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
645 
646 			// Das LastAlignment ist jetzt immer noch das zuletzt angedockte
647             SfxSplitWindow *pSplit = pWorkWin->GetSplitWindow_Impl(pImp->GetLastAlignment());
648 
649             DBG_ASSERT( pSplit, "LastAlignment kann nicht stimmen!" );
650 			if ( pSplit && pSplit != pImp->pSplitWin )
651 				pSplit->ReleaseWindow_Impl(this);
652 			if ( pImp->GetDockAlignment() == eLastAlign )
653                 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
654 			else
655                 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nLine, pImp->nPos, pImp->bNewLine );
656 			if ( !pImp->pSplitWin->IsFadeIn() )
657 				pImp->pSplitWin->FadeIn();
658 		}
659 	}
660 
661 	// altes Alignment festhalten f"ur n"achstes Togglen; erst jetzt setzen
662 	// wg. Abmelden beim SplitWindow!
663 	pImp->SetLastAlignment(eLastAlign);
664 
665 	// DockAlignment zur"ucksetzen, falls noch EndDocking gerufen wird
666 	pImp->SetDockAlignment(GetAlignment());
667 
668 	// SfxChildWindow korrekt andocken bzw. entdocken
669 	if ( pMgr )
670 		pWorkWin->ConfigChild_Impl( eIdent, SFX_TOGGLEFLOATMODE, pMgr->GetType() );
671 }
672 
673 //-------------------------------------------------------------------------
674 
675 void SfxDockingWindow::StartDocking()
676 
677 /*  [Beschreibung]
678 
679 	Diese virtuelle Methode der Klasse DockingWindow holt vom parent window
680 	das innere und "au\sere docking rectangle.
681 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
682 	am Ende SfxDockingWindow::StartDocking() gerufen werden.
683 */
684 {
685 	if ( !pImp->bConstructed || !pMgr )
686 		return;
687 	SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
688 	if ( pImp->bSplitable )
689 		eIdent = SFX_CHILDWIN_SPLITWINDOW;
690 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
691 	pWorkWin->ConfigChild_Impl( eIdent, SFX_SETDOCKINGRECTS, pMgr->GetType() );
692 	pImp->SetDockAlignment(GetAlignment());
693 
694 	if ( pImp->pSplitWin )
695 	{
696 		// Die aktuellen Docking-Daten besorgen
697 		pImp->pSplitWin->GetWindowPos(this, pImp->nLine, pImp->nPos);
698 		pImp->nDockLine = pImp->nLine;
699 		pImp->nDockPos = pImp->nPos;
700 		pImp->bNewLine = sal_False;
701 	}
702 }
703 
704 //-------------------------------------------------------------------------
705 
706 sal_Bool SfxDockingWindow::Docking( const Point& rPos, Rectangle& rRect )
707 
708 /*  [Beschreibung]
709 
710 	Diese virtuelle Methode der Klasse DockingWindow berechnet das aktuelle
711 	tracking rectangle. Dazu benutzt sie die Methode CalcAlignment(rPos,rRect),
712 	deren Verhalten von abgeleiteten Klassen beeinflu\st werden kann (s.u.).
713 	Diese Methode sollte nach M"oglichkeit nicht "uberschrieben werden.
714 */
715 {
716 	if ( Application::IsInModalMode() )
717 		return sal_True;
718 
719 	if ( !pImp->bConstructed || !pMgr )
720 	{
721 		rRect.SetSize( Size() );
722 		return IsFloatingMode();
723 	}
724 
725 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
726     if ( pImp->bDockingPrevented || !pWorkWin->IsInternalDockingAllowed() )
727 		return sal_False;
728 
729 	sal_Bool bFloatMode = sal_False;
730 
731 	if ( GetOuterRect().IsInside( rPos ) && !IsDockingPrevented() )
732 	{
733 		// Maus innerhalb OuterRect : Alignment und Rectangle berechnen
734 		SfxChildAlignment eAlign = CalcAlignment(rPos, rRect);
735 		if (eAlign == SFX_ALIGN_NOALIGNMENT)
736 			bFloatMode = sal_True;
737 		pImp->SetDockAlignment(eAlign);
738 	}
739 	else
740 	{
741 		// Maus nicht innerhalb OuterRect : muss FloatingWindow sein
742 		// Ist das erlaubt ?
743         if (CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT)
744 			return sal_False;
745 		bFloatMode = sal_True;
746 		if ( SFX_ALIGN_NOALIGNMENT != pImp->GetDockAlignment() )
747 		{
748 			// wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das
749 			// Alignment "andert !
750 			pImp->SetDockAlignment(SFX_ALIGN_NOALIGNMENT);
751 			rRect.SetSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT));
752 		}
753 	}
754 
755     if ( !pImp->bSplitable )
756 	{
757 		// Bei individuell angedocktem Window wird die Position durch das
758 		// Alignment und die docking rects festgelegt.
759 		Size aSize = rRect.GetSize();
760 		Point aPos;
761 
762 		switch ( pImp->GetDockAlignment() )
763 		{
764 			case SFX_ALIGN_LEFT:
765 			case SFX_ALIGN_FIRSTLEFT:
766 			case SFX_ALIGN_LASTLEFT:
767 				aPos = aInnerRect.TopLeft();
768 				if ( pImp->GetDockAlignment() == GetAlignment() )
769 					aPos.X() -= aSize.Width();
770 				break;
771 
772 			case SFX_ALIGN_TOP:
773 			case SFX_ALIGN_LOWESTTOP:
774 			case SFX_ALIGN_HIGHESTTOP:
775 				aPos = Point(aOuterRect.Left(), aInnerRect.Top());
776 				if ( pImp->GetDockAlignment() == GetAlignment() )
777 					aPos.Y() -= aSize.Height();
778 				break;
779 
780 			case SFX_ALIGN_RIGHT:
781 			case SFX_ALIGN_FIRSTRIGHT:
782 			case SFX_ALIGN_LASTRIGHT:
783 				aPos = Point(aInnerRect.Right() - rRect.GetSize().Width(),
784 							aInnerRect.Top());
785 				if ( pImp->GetDockAlignment() == GetAlignment() )
786 					aPos.X() += aSize.Width();
787 				break;
788 
789 			case SFX_ALIGN_BOTTOM:
790 			case SFX_ALIGN_HIGHESTBOTTOM:
791 			case SFX_ALIGN_LOWESTBOTTOM:
792 				aPos = Point(aOuterRect.Left(),
793 						aInnerRect.Bottom() - rRect.GetSize().Height());
794 				if ( pImp->GetDockAlignment() == GetAlignment() )
795 					aPos.Y() += aSize.Height();
796 				break;
797                      default:
798                          break;
799 		}
800 
801 		rRect.SetPos(aPos);
802 	}
803 
804 	return bFloatMode;
805 }
806 
807 //-------------------------------------------------------------------------
808 
809 void SfxDockingWindow::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode )
810 
811 /*  [Beschreibung]
812 
813 	Diese virtuelle Methode der Klasse DockingWindow sorgt f"ur das korrekte
814 	Alignment am parent window.
815 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
816 	zuerst SfxDockingWindow::EndDocking() gerufen werden.
817 */
818 {
819 	if ( !pImp->bConstructed || IsDockingCanceled() || !pMgr )
820 		return;
821 
822 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
823 	sal_Bool bReArrange = sal_False;
824 	SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
825 	if ( pImp->bSplitable )
826 	{
827 		eIdent = SFX_CHILDWIN_SPLITWINDOW;
828 
829 		// Wenn sich das Alignment "andert und das Fenster befindet sich
830 		// im angedockten Zustand in einem SplitWindow, mu\s umgemeldet werden
831 		// Wenn neu angedockt wird, machen PrepareToggleFloatingMode()
832 		// und ToggleFloatingMode() das Ummelden.
833 		if ( !bFloatMode )
834 			bReArrange = sal_True;
835 	}
836 
837 	if ( bReArrange )
838 	{
839 		if ( GetAlignment() != pImp->GetDockAlignment() )
840 		{
841 			// Vor dem Show() mu\s das Ummelden passiert sein, daher kann nicht
842 			// die Basisklasse gerufen werden
843 			if ( IsFloatingMode() || !pImp->bSplitable )
844 				Show( sal_False, SHOW_NOFOCUSCHANGE );
845 
846 			// Die Gr"o\se f"urs Toggeln setzen
847             pImp->aSplitSize = rRect.GetSize();
848 			if ( IsFloatingMode() )
849 			{
850 				SetFloatingMode( bFloatMode );
851 				if ( IsFloatingMode() || !pImp->bSplitable )
852                     Show( sal_True, SHOW_NOFOCUSCHANGE );
853 			}
854 			else
855 			{
856 				pImp->pSplitWin->RemoveWindow(this,sal_False);
857 				pImp->nLine = pImp->nDockLine;
858 				pImp->nPos = pImp->nDockPos;
859 				pImp->pSplitWin->ReleaseWindow_Impl(this);
860 				pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(pImp->GetDockAlignment());
861                 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine );
862 				if ( !pImp->pSplitWin->IsFadeIn() )
863 					pImp->pSplitWin->FadeIn();
864 			}
865 		}
866         else if ( pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || pImp->bNewLine )
867 		{
868 			// Ich wurde innerhalb meines Splitwindows verschoben.
869 			if ( pImp->nLine != pImp->nDockLine )
870 				pImp->aSplitSize = rRect.GetSize();
871             pImp->pSplitWin->MoveWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine );
872 		}
873 	}
874 	else
875 	{
876 		pImp->bEndDocked = sal_True;
877 		DockingWindow::EndDocking(rRect, bFloatMode);
878 		pImp->bEndDocked = sal_False;
879 	}
880 
881 	SetAlignment( IsFloatingMode() ? SFX_ALIGN_NOALIGNMENT : pImp->GetDockAlignment() );
882 }
883 
884 //-------------------------------------------------------------------------
885 
886 void SfxDockingWindow::Resizing( Size& /*rSize*/ )
887 
888 /*	[Beschreibung]
889 
890 	Virtuelle Methode der Klasse DockingWindow.
891 	Hier kann das interaktive Umgr"o\sern im FloatingMode beeinflu\t werden,
892 	z.B. indem nur diskrete Werte f"ur Breite und/oder H"ohe zugelassen werden.
893 	Die Basisimplementation verhindert, da\s die OutputSize kleiner wird als
894 	eine mit SetMinOutputSizePixel() gesetzte Gr"o\se.
895 */
896 
897 {
898 /*
899 	if(rSize.Width()   < pImp->aMinSize.Width())
900 		rSize.Width()  = pImp->aMinSize.Width();
901 	if(rSize.Height()  < pImp->aMinSize.Height())
902 		rSize.Height() = pImp->aMinSize.Height();
903 */
904 }
905 
906 //-------------------------------------------------------------------------
907 
908 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
909 	Window* pParent, WinBits nWinBits) :
910 	DockingWindow (pParent, nWinBits),
911 	pBindings(pBindinx),
912     pMgr(pCW),
913     pImp(NULL)
914 
915 /*  [Beschreibung]
916 
917 	ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt,
918 	da das Andocken im Sfx "uber SfxChildWindows realisiert wird.
919 */
920 
921 {
922     if ( GetHelpId().getLength() )
923     {
924 	    SetUniqueId( GetHelpId() );
925     	SetHelpId("");
926     }
927     else
928     {
929         SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame();
930         SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool();
931         const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() );
932         if ( pSlot )
933         {
934             rtl::OString aCmd("SFXDOCKINGWINDOW_");
935             aCmd += pSlot->GetUnoName();
936             SetUniqueId( aCmd );
937         }
938     }
939 
940 	pImp = new SfxDockingWindow_Impl;
941 	pImp->bConstructed = sal_False;
942 	pImp->pSplitWin = 0;
943 	pImp->bEndDocked = sal_False;
944 	pImp->bDockingPrevented = sal_False;
945 
946 	pImp->bSplitable = sal_True;
947 //	pImp->bAutoHide = sal_False;
948 
949 	// Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt
950 	pImp->nLine = pImp->nDockLine = 0;
951 	pImp->nPos  = pImp->nDockPos = 0;
952 	pImp->bNewLine = sal_False;
953 	pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
954     pImp->aMoveTimer.SetTimeout(50);
955     pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl));
956 
957 //	DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!");
958 }
959 
960 //-------------------------------------------------------------------------
961 
962 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW,
963 	Window* pParent, const ResId& rResId) :
964 	DockingWindow(pParent, rResId),
965 	pBindings(pBindinx),
966     pMgr(pCW),
967     pImp(NULL)
968 
969 /*  [Beschreibung]
970 
971 	ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt,
972 	da das Andocken im Sfx "uber SfxChildWindows realisiert wird.
973 */
974 
975 {
976     if ( GetHelpId().getLength() )
977     {
978 	    SetUniqueId( GetHelpId() );
979     	SetHelpId("");
980     }
981     else
982     {
983         SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame();
984         SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool();
985         const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() );
986         if ( pSlot )
987         {
988             rtl::OString aCmd("SFXDOCKINGWINDOW_");
989             aCmd += pSlot->GetUnoName();
990             SetUniqueId( aCmd );
991         }
992     }
993 
994 	pImp = new SfxDockingWindow_Impl;
995 	pImp->bConstructed = sal_False;
996 	pImp->pSplitWin = 0;
997 	pImp->bEndDocked = sal_False;
998 	pImp->bDockingPrevented = sal_False;
999 
1000 	pImp->bSplitable = sal_True;
1001 //	pImp->bAutoHide = sal_False;
1002 
1003 	// Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt
1004 	pImp->nLine = pImp->nDockLine = 0;
1005 	pImp->nPos  = pImp->nDockPos = 0;
1006 	pImp->bNewLine = sal_False;
1007 	pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
1008     pImp->aMoveTimer.SetTimeout(50);
1009     pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl));
1010 
1011 //	DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!");
1012 }
1013 
1014 //-------------------------------------------------------------------------
1015 
1016 void SfxDockingWindow::Initialize(SfxChildWinInfo *pInfo)
1017 /*  [Beschreibung]
1018 
1019 	Initialisierung der Klasse SfxDockingWindow "uber ein SfxChildWinInfo.
1020 	Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte
1021 	vom ctor der abgeleiteten Klasse oder vom ctor des SfxChildWindows
1022 	aufgerufen werden.
1023 */
1024 {
1025 	if ( !pMgr )
1026 	{
1027 		// Bugfix #39771
1028 		pImp->SetDockAlignment( SFX_ALIGN_NOALIGNMENT );
1029 		pImp->bConstructed = sal_True;
1030 		return;
1031 	}
1032 
1033 	if ( pInfo->nFlags & SFX_CHILDWIN_FORCEDOCK )
1034 		pImp->bDockingPrevented = sal_True;
1035 
1036     pImp->aSplitSize = GetOutputSizePixel();
1037     if ( !GetFloatingSize().Width() )
1038     {
1039         Size aMinSize( GetMinOutputSizePixel() );
1040         SetFloatingSize( pImp->aSplitSize );
1041         if ( pImp->aSplitSize.Width() < aMinSize.Width() )
1042             pImp->aSplitSize.Width() = aMinSize.Width();
1043         if ( pImp->aSplitSize.Height() < aMinSize.Height() )
1044             pImp->aSplitSize.Height() = aMinSize.Height();
1045     }
1046 
1047     sal_Bool bVertHorzRead( sal_False );
1048     if ( pInfo->aExtraString.Len() )
1049     {
1050         // get information about alignment, split size and position in SplitWindow
1051         String aStr;
1052         sal_uInt16 nPos = pInfo->aExtraString.SearchAscii("AL:");
1053         if ( nPos != STRING_NOTFOUND )
1054         {
1055             // alignment information
1056             sal_uInt16 n1 = pInfo->aExtraString.Search('(', nPos);
1057             if ( n1 != STRING_NOTFOUND )
1058             {
1059                 sal_uInt16 n2 = pInfo->aExtraString.Search(')', n1);
1060                 if ( n2 != STRING_NOTFOUND )
1061                 {
1062                     // extract alignment information from extrastring
1063                     aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1);
1064                     pInfo->aExtraString.Erase(nPos, n2 - nPos + 1);
1065                     aStr.Erase(nPos, n1-nPos+1);
1066                 }
1067             }
1068         }
1069 
1070         if ( aStr.Len() )
1071         {
1072             // accept window state only if alignment is also set
1073             pImp->aWinState = pInfo->aWinState;
1074 
1075             // check for valid alignment
1076 			SfxChildAlignment eLocalAlignment = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32();
1077 			if ( pImp->bDockingPrevented )
1078 				// docking prevented, ignore old configuration and take alignment from default
1079 				aStr.Erase();
1080 			else
1081             	SetAlignment( eLocalAlignment );
1082 
1083             SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment());
1084             if ( eAlign != GetAlignment() )
1085             {
1086                 DBG_ERROR("Invalid Alignment!");
1087                 SetAlignment( eAlign );
1088                 aStr.Erase();
1089             }
1090 
1091             // get last alignment (for toggeling)
1092             nPos = aStr.Search(',');
1093             if ( nPos != STRING_NOTFOUND )
1094             {
1095                 aStr.Erase(0, nPos+1);
1096                 pImp->SetLastAlignment( (SfxChildAlignment) (sal_uInt16) aStr.ToInt32() );
1097             }
1098 
1099             nPos = aStr.Search(',');
1100             if ( nPos != STRING_NOTFOUND )
1101             {
1102                 // get split size and position in SplitWindow
1103                 Point aPos;
1104                 aStr.Erase(0, nPos+1);
1105                 if ( GetPosSizeFromString( aStr, aPos, pImp->aSplitSize ) )
1106                 {
1107                     pImp->nLine = pImp->nDockLine = (sal_uInt16) aPos.X();
1108                     pImp->nPos  = pImp->nDockPos  = (sal_uInt16) aPos.Y();
1109                     pImp->nVerticalSize = pImp->aSplitSize.Height();
1110                     pImp->nHorizontalSize = pImp->aSplitSize.Width();
1111                     if ( GetSplitSizeFromString( aStr, pImp->aSplitSize ))
1112                         bVertHorzRead = sal_True;
1113                 }
1114             }
1115         }
1116         else {
1117             DBG_ERROR( "Information is missing!" );
1118         }
1119     }
1120 
1121     if ( !bVertHorzRead )
1122     {
1123         pImp->nVerticalSize = pImp->aSplitSize.Height();
1124         pImp->nHorizontalSize = pImp->aSplitSize.Width();
1125     }
1126 
1127 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1128 	if ( GetAlignment() != SFX_ALIGN_NOALIGNMENT )
1129 	{
1130         // check if SfxWorkWindow is able to allow docking at its border
1131 		if (
1132             !pWorkWin->IsDockingAllowed() ||
1133             !pWorkWin->IsInternalDockingAllowed() ||
1134             ( (GetFloatStyle() & WB_STANDALONE) && Application::IsInModalMode()) )
1135         {
1136 			SetAlignment( SFX_ALIGN_NOALIGNMENT );
1137         }
1138 	}
1139 
1140     // detect floating mode
1141     // toggeling mode will not execute code in handlers, because pImp->bConstructed is not set yet
1142 	sal_Bool bFloatMode = IsFloatingMode();
1143     if ( bFloatMode != ((GetAlignment() == SFX_ALIGN_NOALIGNMENT)) )
1144     {
1145         bFloatMode = !bFloatMode;
1146         SetFloatingMode( bFloatMode );
1147         if ( bFloatMode )
1148         {
1149             if ( pImp->aWinState.Len() )
1150                 GetFloatingWindow()->SetWindowState( pImp->aWinState );
1151             else
1152                 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() );
1153         }
1154     }
1155 
1156     if ( IsFloatingMode() )
1157 	{
1158         // validate last alignment
1159         SfxChildAlignment eLastAlign = pImp->GetLastAlignment();
1160 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1161 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_LEFT);
1162 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1163 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_RIGHT);
1164 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1165 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_TOP);
1166 		if ( eLastAlign == SFX_ALIGN_NOALIGNMENT)
1167 			eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_BOTTOM);
1168 		pImp->SetLastAlignment(eLastAlign);
1169 	}
1170 	else
1171 	{
1172         // docked window must have NOALIGNMENT as last alignment
1173 		pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT);
1174 
1175         if ( pImp->bSplitable )
1176 		{
1177 //			pImp->bAutoHide = ( pInfo->nFlags & SFX_CHILDWIN_AUTOHIDE) != 0;
1178 			pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment());
1179 			pImp->pSplitWin->InsertWindow(this, pImp->aSplitSize);
1180 		}
1181 		else
1182 		{
1183             //?????? Currently not supported
1184 			// Fenster ist individuell angedockt; Gr"o\se berechnen.
1185 			// Dazu mu\s sie mit der FloatingSize initialisiert werden, falls
1186 			// irgendwer sich darauf verl"a\st, da\s eine vern"unftige Gr"o\se
1187             // gesetzt ist
1188 			SetSizePixel(GetFloatingSize());
1189 			SetSizePixel(CalcDockingSize(GetAlignment()));
1190 		}
1191 	}
1192 
1193     // save alignment
1194     pImp->SetDockAlignment( GetAlignment() );
1195 }
1196 
1197 void SfxDockingWindow::Initialize_Impl()
1198 {
1199 	if ( !pMgr )
1200     {
1201 		// Bugfix #39771
1202         pImp->bConstructed = sal_True;
1203 		return;
1204     }
1205 
1206     FloatingWindow* pFloatWin = GetFloatingWindow();
1207     sal_Bool bSet = sal_False;
1208     if ( pFloatWin )
1209     {
1210         bSet = !pFloatWin->IsDefaultPos();
1211     }
1212     else
1213     {
1214         Point aPos = GetFloatingPos();
1215         if ( aPos != Point() )
1216             bSet = sal_True;
1217     }
1218 
1219     if ( !bSet)
1220 	{
1221 		SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame();
1222 		Window* pEditWin = pFrame->GetViewShell()->GetWindow();
1223         Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() );
1224 		aPos = GetParent()->ScreenToOutputPixel( aPos );
1225 		SetFloatingPos( aPos );
1226 	}
1227 
1228     if ( pFloatWin )
1229     {
1230         // initialize floating window
1231         if ( !pImp->aWinState.Len() )
1232             // window state never set before, get if from defaults
1233             pImp->aWinState = pFloatWin->GetWindowState();
1234 
1235         // trick: use VCL method SetWindowState to adjust position and size
1236         pFloatWin->SetWindowState( pImp->aWinState );
1237 
1238         // remember floating size for calculating alignment and tracking rectangle
1239         SetFloatingSize( pFloatWin->GetSizePixel() );
1240 
1241         // some versions of VCL didn't call resize in the current situation
1242 		//Resize();
1243     }
1244 
1245     // allow calling of docking handlers
1246 	pImp->bConstructed = sal_True;
1247 }
1248 
1249 //-------------------------------------------------------------------------
1250 
1251 void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const
1252 
1253 /*  [Beschreibung]
1254 
1255 	F"ullt ein SfxChildWinInfo mit f"ur SfxDockingWindow spezifischen Daten,
1256 	damit sie in die INI-Datei geschrieben werden koennen.
1257 	Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in
1258 	der ChildWindow-Klasse erh"alt.
1259 	Eingetragen werden hier gemerkten Gr"o\sen, das ZoomIn-Flag und die
1260 	f"ur das Docking relevanten Informationen.
1261 	Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung
1262 	gerufen werden.
1263 */
1264 
1265 {
1266 	if ( !pMgr )
1267 		return;
1268 
1269     if ( GetFloatingWindow() && pImp->bConstructed )
1270         pImp->aWinState = GetFloatingWindow()->GetWindowState();
1271 
1272     rInfo.aWinState = pImp->aWinState;
1273 	rInfo.aExtraString = DEFINE_CONST_UNICODE("AL:(");
1274     rInfo.aExtraString += String::CreateFromInt32((sal_uInt16) GetAlignment());
1275 	rInfo.aExtraString += ',';
1276     rInfo.aExtraString += String::CreateFromInt32 ((sal_uInt16) pImp->GetLastAlignment());
1277 	if ( pImp->bSplitable )
1278 	{
1279 		Point aPos(pImp->nLine, pImp->nPos);
1280 		rInfo.aExtraString += ',';
1281     	rInfo.aExtraString += String::CreateFromInt32( aPos.X() );
1282 		rInfo.aExtraString += '/';
1283     	rInfo.aExtraString += String::CreateFromInt32( aPos.Y() );
1284 		rInfo.aExtraString += '/';
1285         rInfo.aExtraString += String::CreateFromInt32( pImp->nHorizontalSize );
1286         rInfo.aExtraString += '/';
1287         rInfo.aExtraString += String::CreateFromInt32( pImp->nVerticalSize );
1288         rInfo.aExtraString += ',';
1289         rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Width() );
1290 		rInfo.aExtraString += ';';
1291         rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Height() );
1292 	}
1293 
1294 	rInfo.aExtraString += ')';
1295 }
1296 
1297 //-------------------------------------------------------------------------
1298 
1299 SfxDockingWindow::~SfxDockingWindow()
1300 {
1301     ReleaseChildWindow_Impl();
1302 	delete pImp;
1303 }
1304 
1305 void SfxDockingWindow::ReleaseChildWindow_Impl()
1306 {
1307     if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() )
1308         pBindings->SetActiveFrame( NULL );
1309 
1310 	if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) )
1311 		pImp->pSplitWin->RemoveWindow(this);
1312 
1313     pMgr=NULL;
1314 }
1315 
1316 //-------------------------------------------------------------------------
1317 
1318 SfxChildAlignment SfxDockingWindow::CalcAlignment(const Point& rPos, Rectangle& rRect)
1319 
1320 /*  [Beschreibung]
1321 
1322 	Diese Methode berechnet f"ur gegebene Mausposition und tracking rectangle,
1323 	welches Alignment sich daraus ergeben w"urde. Beim Wechsel des Alignments
1324 	kann sich auch das tracking rectangle "andern, so dass ein ver"andertes
1325 	rectangle zur"uckgegeben wird.
1326 
1327 	Der Klassenbenutzer kann das Verhalten dieser Methode und damit das Verhalten
1328 	seiner DockinWindow-Klasse beim Docken beeinflussen, indem er die hier
1329 	aufgerufene virtuelle Methode
1330 
1331 		SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
1332 
1333 	"uberschreibt (s.u.).
1334 */
1335 
1336 {
1337 	// calculate hypothetical sizes for different modes
1338 	Size aFloatingSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT));
1339 	Size aVerticalSize(CalcDockingSize(SFX_ALIGN_LEFT));
1340 	Size aHorizontalSize(CalcDockingSize(SFX_ALIGN_TOP));
1341 
1342 	// check if docking is permitted
1343 	SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1344 	if ( !pWorkWin->IsDockingAllowed() )
1345 	{
1346 		rRect.SetSize( aFloatingSize );
1347 		return pImp->GetDockAlignment();
1348 	}
1349 
1350 	// calculate borders to shrink inner area before checking for intersection with tracking rectangle
1351 	long nLRBorder, nTBBorder;
1352 	if ( pImp->bSplitable )
1353 	{
1354 		// take the smaller size of docked and floating mode
1355         Size aSize = pImp->aSplitSize;
1356 		if ( GetFloatingSize().Height() < aSize.Height() )
1357 			aSize.Height() = GetFloatingSize().Height();
1358 		if ( GetFloatingSize().Width() < aSize.Width() )
1359 			aSize.Width() = GetFloatingSize().Width();
1360 
1361 		nLRBorder = aSize.Width();
1362 		nTBBorder = aSize.Height();
1363 	}
1364 	else
1365 	{
1366 		nLRBorder = aVerticalSize.Width();
1367 		nTBBorder = aHorizontalSize.Height();
1368 	}
1369 
1370 	// limit border to predefined constant values
1371 	if ( nLRBorder > MAX_TOGGLEAREA_WIDTH )
1372 		nLRBorder = MAX_TOGGLEAREA_WIDTH;
1373 	if ( nTBBorder > MAX_TOGGLEAREA_WIDTH )
1374 		nTBBorder = MAX_TOGGLEAREA_WIDTH;
1375 
1376 	// shrink area for floating mode if possible
1377 	Rectangle aInRect = GetInnerRect();
1378 	if ( aInRect.GetWidth() > nLRBorder )
1379 		aInRect.Left()	 += nLRBorder/2;
1380 	if ( aInRect.GetWidth() > nLRBorder )
1381 		aInRect.Right()  -= nLRBorder/2;
1382 	if ( aInRect.GetHeight() > nTBBorder )
1383 		aInRect.Top()	 += nTBBorder/2;
1384 	if ( aInRect.GetHeight() > nTBBorder )
1385 		aInRect.Bottom() -= nTBBorder/2;
1386 
1387 	// calculate alignment resulting from docking rectangle
1388 	sal_Bool bBecomesFloating = sal_False;
1389 	SfxChildAlignment eDockAlign = pImp->GetDockAlignment();
1390 	Rectangle aDockingRect( rRect );
1391 	if ( !IsFloatingMode() )
1392 	{
1393 		// don't use tracking rectangle for alignment check, because it will be too large
1394 		// to get a floating mode as result - switch to floating size
1395 		// so the calculation only depends on the position of the rectangle, not the current
1396 		// docking state of the window
1397 		aDockingRect.SetSize( GetFloatingSize() );
1398 
1399 		// in this mode docking is never done by keyboard, so it's OK to use the mouse position
1400 		aDockingRect.SetPos( pWorkWin->GetWindow()->OutputToScreenPixel( pWorkWin->GetWindow()->GetPointerPosPixel() ) );
1401 	}
1402 
1403 	Point aPos = aDockingRect.TopLeft();
1404 	Rectangle aIntersect = GetOuterRect().GetIntersection( aDockingRect );
1405     if ( aIntersect.IsEmpty() )
1406 		// docking rectangle completely outside docking area -> floating mode
1407 		bBecomesFloating = sal_True;
1408 	else
1409     {
1410         // create a small test rect around the mouse position and use this one
1411         // instead of the passed rRect to not dock too easily or by accident
1412         Rectangle aSmallDockingRect;
1413         aSmallDockingRect.SetSize( Size( MAX_TOGGLEAREA_WIDTH, MAX_TOGGLEAREA_HEIGHT ) );
1414         Point aNewPos(rPos);
1415         aNewPos.X() -= aSmallDockingRect.GetWidth()/2;
1416         aNewPos.Y() -= aSmallDockingRect.GetHeight()/2;
1417         aSmallDockingRect.SetPos(rPos);
1418         Rectangle aIntersectRect = aInRect.GetIntersection( aSmallDockingRect );
1419         if ( aIntersectRect == aSmallDockingRect )
1420 			// docking rectangle completely inside (shrinked) inner area -> floating mode
1421             bBecomesFloating = sal_True;
1422 	}
1423 
1424 	if ( bBecomesFloating )
1425 	{
1426 		eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT);
1427 	}
1428 	else
1429 	{
1430 		// docking rectangle is in the "sensible area"
1431         Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() );
1432         Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() );
1433 		Size  aInSize = aInRect.GetSize();
1434 		sal_Bool  bNoChange = sal_False;
1435 
1436 		// check if alignment is still unchanged
1437 		switch ( GetAlignment() )
1438 		{
1439 			case SFX_ALIGN_LEFT:
1440 			case SFX_ALIGN_FIRSTLEFT:
1441 			case SFX_ALIGN_LASTLEFT:
1442                 if (aInPosTL.X() <= 0)
1443 				{
1444 					eDockAlign = GetAlignment();
1445 					bNoChange = sal_True;
1446 				}
1447 				break;
1448 			case SFX_ALIGN_TOP:
1449 			case SFX_ALIGN_LOWESTTOP:
1450 			case SFX_ALIGN_HIGHESTTOP:
1451                 if ( aInPosTL.Y() <= 0)
1452 				{
1453 					eDockAlign = GetAlignment();
1454 					bNoChange = sal_True;
1455 				}
1456 				break;
1457 			case SFX_ALIGN_RIGHT:
1458 			case SFX_ALIGN_FIRSTRIGHT:
1459 			case SFX_ALIGN_LASTRIGHT:
1460                 if ( aInPosBR.X() >= aInSize.Width())
1461 				{
1462 					eDockAlign = GetAlignment();
1463 					bNoChange = sal_True;
1464 				}
1465 				break;
1466 			case SFX_ALIGN_BOTTOM:
1467 			case SFX_ALIGN_LOWESTBOTTOM:
1468 			case SFX_ALIGN_HIGHESTBOTTOM:
1469                 if ( aInPosBR.Y() >= aInSize.Height())
1470 				{
1471 					eDockAlign = GetAlignment();
1472 					bNoChange = sal_True;
1473 				}
1474 				break;
1475 			default:
1476 				break;
1477 		}
1478 
1479 		if ( !bNoChange )
1480 		{
1481 			// alignment will change, test alignment according to distance of the docking rectangles edges
1482 			sal_Bool bForbidden = sal_True;
1483             if ( aInPosTL.X() <= 0)
1484 			{
1485 				eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_LEFT);
1486 				bForbidden = ( eDockAlign != SFX_ALIGN_LEFT &&
1487 							   eDockAlign != SFX_ALIGN_FIRSTLEFT &&
1488 							   eDockAlign != SFX_ALIGN_LASTLEFT );
1489 			}
1490 
1491             if ( bForbidden && aInPosTL.Y() <= 0)
1492 			{
1493 				eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_TOP);
1494 				bForbidden = ( eDockAlign != SFX_ALIGN_TOP &&
1495 							   eDockAlign != SFX_ALIGN_HIGHESTTOP &&
1496 							   eDockAlign != SFX_ALIGN_LOWESTTOP );
1497 			}
1498 
1499             if ( bForbidden && aInPosBR.X() >= aInSize.Width())
1500 			{
1501 				eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_RIGHT);
1502 				bForbidden = ( eDockAlign != SFX_ALIGN_RIGHT &&
1503 							   eDockAlign != SFX_ALIGN_FIRSTRIGHT &&
1504 							   eDockAlign != SFX_ALIGN_LASTRIGHT );
1505 			}
1506 
1507             if ( bForbidden && aInPosBR.Y() >= aInSize.Height())
1508 			{
1509 				eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_BOTTOM);
1510 				bForbidden = ( eDockAlign != SFX_ALIGN_BOTTOM &&
1511 							   eDockAlign != SFX_ALIGN_HIGHESTBOTTOM &&
1512 							   eDockAlign != SFX_ALIGN_LOWESTBOTTOM );
1513 			}
1514 
1515 			// the calculated alignment was rejected by the window -> take floating mode
1516 			if ( bForbidden )
1517 				eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT);
1518 		}
1519 	}
1520 
1521 	if ( eDockAlign == SFX_ALIGN_NOALIGNMENT )
1522 	{
1523 		//Im FloatingMode erh"alt das tracking rectangle die floating size
1524 		// wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das
1525 		// Alignment "andert !
1526 		if ( eDockAlign != pImp->GetDockAlignment() )
1527 			aDockingRect.SetSize( aFloatingSize );
1528 	}
1529 	else if ( pImp->bSplitable )
1530 	{
1531 		sal_uInt16 nLine, nPos;
1532 		SfxSplitWindow *pSplitWin = pWorkWin->GetSplitWindow_Impl(eDockAlign);
1533 		aPos = pSplitWin->ScreenToOutputPixel( aPos );
1534 		if ( pSplitWin->GetWindowPos( aPos, nLine, nPos ) )
1535 		{
1536 			// mouse over splitwindow, get line and position
1537 			pImp->nDockLine = nLine;
1538 			pImp->nDockPos = nPos;
1539 			pImp->bNewLine = sal_False;
1540 		}
1541 		else
1542 		{
1543 			if ( 0 )
1544 			{
1545 				// mouse touches outer border -> treated as floating mode
1546 				eDockAlign = SFX_ALIGN_NOALIGNMENT;
1547 				aDockingRect.SetSize( aFloatingSize );
1548 				rRect = aDockingRect;
1549 				return eDockAlign;
1550 			}
1551 
1552 			// mouse touches inner border -> create new line
1553 			if ( eDockAlign == GetAlignment() && pImp->pSplitWin &&
1554  				pImp->nLine == pImp->pSplitWin->GetLineCount()-1 && pImp->pSplitWin->GetWindowCount(pImp->nLine) == 1 )
1555 			{
1556 				// if this window is the only one in the last line, it can't be docked as new line in the same splitwindow
1557 				pImp->nDockLine = pImp->nLine;
1558 				pImp->nDockPos = pImp->nPos;
1559 				pImp->bNewLine = sal_False;
1560 			}
1561 			else
1562 			{
1563 				// create new line
1564 				pImp->nDockLine = pSplitWin->GetLineCount();
1565 				pImp->nDockPos = 0;
1566 				pImp->bNewLine = sal_True;
1567 			}
1568 		}
1569 
1570 		sal_Bool bChanged = pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || eDockAlign != GetAlignment();
1571 		if ( !bChanged && !IsFloatingMode() )
1572 		{
1573 			// window only sightly moved, no change of any property
1574             rRect.SetSize( pImp->aSplitSize );
1575         	rRect.SetPos( aDockingRect.TopLeft() );
1576 			return eDockAlign;
1577 		}
1578 
1579 		// calculate new size and position
1580         Size aSize;
1581 		Point aPoint = aDockingRect.TopLeft();
1582 		Size aInnerSize = GetInnerRect().GetSize();
1583 		if ( eDockAlign == SFX_ALIGN_LEFT || eDockAlign == SFX_ALIGN_RIGHT )
1584 		{
1585 			if ( pImp->bNewLine )
1586 			{
1587 				// set height to height of free area
1588 				aSize.Height() = aInnerSize.Height();
1589                 aSize.Width() = pImp->nHorizontalSize;
1590 				if ( eDockAlign == SFX_ALIGN_LEFT )
1591 				{
1592             		aPoint = aInnerRect.TopLeft();
1593 				}
1594 				else
1595 				{
1596             		aPoint = aInnerRect.TopRight();
1597             		aPoint.X() -= aSize.Width();
1598 				}
1599 			}
1600 			else
1601 			{
1602 				// get width from splitwindow
1603 				aSize.Width() = pSplitWin->GetLineSize(nLine);
1604                 aSize.Height() = pImp->aSplitSize.Height();
1605 			}
1606 		}
1607 		else
1608 		{
1609 			if ( pImp->bNewLine )
1610 			{
1611 				// set width to width of free area
1612 				aSize.Width() = aInnerSize.Width();
1613                 aSize.Height() = pImp->nVerticalSize;
1614 				if ( eDockAlign == SFX_ALIGN_TOP )
1615 				{
1616             		aPoint = aInnerRect.TopLeft();
1617 				}
1618 				else
1619         		{
1620             		aPoint = aInnerRect.BottomLeft();
1621             		aPoint.Y() -= aSize.Height();
1622         		}
1623 			}
1624 			else
1625 			{
1626 				// get height from splitwindow
1627 				aSize.Height() = pSplitWin->GetLineSize(nLine);
1628                 aSize.Width() = pImp->aSplitSize.Width();
1629 			}
1630     	}
1631 
1632 		aDockingRect.SetSize( aSize );
1633 		aDockingRect.SetPos( aPoint );
1634 	}
1635 	else
1636 	{
1637 		// window can be docked, but outside our splitwindows
1638 		// tracking rectangle only needs to be modified if alignment was changed
1639 		if ( eDockAlign != pImp->GetDockAlignment() )
1640 		{
1641 			switch ( eDockAlign )
1642 			{
1643 				case SFX_ALIGN_LEFT:
1644 				case SFX_ALIGN_RIGHT:
1645 				case SFX_ALIGN_FIRSTLEFT:
1646         		    aDockingRect.SetPos( aInnerRect.TopLeft() );
1647 					aDockingRect.SetSize( aVerticalSize );
1648 					break;
1649 				case SFX_ALIGN_LASTLEFT:
1650 				case SFX_ALIGN_FIRSTRIGHT:
1651 				case SFX_ALIGN_LASTRIGHT:
1652         		{
1653             		Point aPt( aInnerRect.TopRight() );
1654             		aPt.X() -= aDockingRect.GetWidth();
1655             		aDockingRect.SetPos( aPt );
1656 					aDockingRect.SetSize( aVerticalSize );
1657             		break;
1658         		}
1659 
1660 				case SFX_ALIGN_TOP:
1661 				case SFX_ALIGN_BOTTOM:
1662 				case SFX_ALIGN_LOWESTTOP:
1663             		aDockingRect.SetPos( aInnerRect.TopLeft() );
1664 					aDockingRect.SetSize( aHorizontalSize );
1665 					break;
1666 				case SFX_ALIGN_HIGHESTTOP:
1667 				case SFX_ALIGN_LOWESTBOTTOM:
1668 				case SFX_ALIGN_HIGHESTBOTTOM:
1669         		{
1670             		Point aPt( aInnerRect.BottomLeft() );
1671             		aPt.Y() -= aDockingRect.GetHeight();
1672             		aDockingRect.SetPos( aPt );
1673 					aDockingRect.SetSize( aHorizontalSize );
1674             		break;
1675         		}
1676                         default:
1677                             break;
1678 			}
1679 		}
1680 	}
1681 
1682 	rRect = aDockingRect;
1683     return eDockAlign;
1684 }
1685 
1686 //-------------------------------------------------------------------------
1687 
1688 Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign)
1689 
1690 /*	[Beschreibung]
1691 
1692 	Virtuelle Methode der Klasse SfxDockingWindow.
1693 	Hier wird festgelegt, wie sich die Gr"o\se des DockingWindows abh"angig vom
1694 	Alignment "andert.
1695 	Die Basisimplementation setzt im Floating Mode die Gr"o\se auf die gemerkte
1696 	Floating Size.
1697 	Bei horizontalem Alignment wird die Breite auf die Breite des "au\seren
1698 	DockingRects, bei vertikalem Alignment die H"ohe auf die H"ohe des inneren
1699 	DockingRects (ergibt sich aus der Reihenfolge, in der im SFX ChildWindows
1700 	ausgegeben werden). Die jeweils andere Gr"o\se wird auf die aktuelle
1701 	Floating Size gesetzt, hier k"onnte eine abgeleitete Klasse "andernd
1702 	eingreifen.
1703 	Die DockingSize mu\s f"ur Left/Right und Top/Bottom jeweils gleich sein.
1704 */
1705 
1706 {
1707 	// Achtung: falls das Resizing auch im angedockten Zustand geht, mu\s dabei
1708 	// auch die Floating Size angepa\st werden !?
1709 
1710 	Size aSize = GetFloatingSize();
1711 	switch (eAlign)
1712 	{
1713 		case SFX_ALIGN_TOP:
1714 		case SFX_ALIGN_BOTTOM:
1715 		case SFX_ALIGN_LOWESTTOP:
1716 		case SFX_ALIGN_HIGHESTTOP:
1717 		case SFX_ALIGN_LOWESTBOTTOM:
1718 		case SFX_ALIGN_HIGHESTBOTTOM:
1719 			aSize.Width() = aOuterRect.Right() - aOuterRect.Left();
1720 			break;
1721 		case SFX_ALIGN_LEFT:
1722 		case SFX_ALIGN_RIGHT:
1723 		case SFX_ALIGN_FIRSTLEFT:
1724 		case SFX_ALIGN_LASTLEFT:
1725 		case SFX_ALIGN_FIRSTRIGHT:
1726 		case SFX_ALIGN_LASTRIGHT:
1727 			aSize.Height() = aInnerRect.Bottom() - aInnerRect.Top();
1728 			break;
1729 		case SFX_ALIGN_NOALIGNMENT:
1730 			break;
1731               default:
1732                   break;
1733 	}
1734 
1735 	return aSize;
1736 }
1737 
1738 //-------------------------------------------------------------------------
1739 
1740 SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment,
1741 	SfxChildAlignment eAlign)
1742 
1743 /*	[Beschreibung]
1744 
1745 	Virtuelle Methode der Klasse SfxDockingWindow.
1746 	Hier kann eine abgeleitete Klasse bestimmte Alignments verbieten.
1747 	Die Basisimplementation verbietet kein Alignment.
1748 */
1749 
1750 {
1751 	return eAlign;
1752 }
1753 
1754 //-------------------------------------------------------------------------
1755 
1756 sal_Bool SfxDockingWindow::Close()
1757 
1758 /*	[Beschreibung]
1759 
1760 	Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des
1761 	ChildWindow-Slots zerst"ort wird.
1762 	Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s
1763 	danach SfxDockingWindow::Close() gerufen werden, wenn nicht das Close()
1764 	mit "return FALSE" abgebrochen wird.
1765 
1766 */
1767 {
1768 	// Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert
1769 	// werden kann
1770 	if ( !pMgr )
1771 		return sal_True;
1772 
1773 	SfxBoolItem aValue( pMgr->GetType(), sal_False);
1774 	pBindings->GetDispatcher_Impl()->Execute(
1775 		pMgr->GetType(), SFX_CALLMODE_RECORD | SFX_CALLMODE_ASYNCHRON, &aValue, 0L );
1776 	return sal_True;
1777 }
1778 
1779 //-------------------------------------------------------------------------
1780 
1781 void SfxDockingWindow::Paint(const Rectangle& /*rRect*/)
1782 
1783 /*	[Beschreibung]
1784 
1785 	Es wird im angedockten Zustand eine Begrenzungslinie an der angedockten
1786 	Kante und ein Rahmen ausgegeben. Dabei wird SVLOOK ber"ucksichtigt.
1787 */
1788 
1789 {
1790 	if ( pImp->bSplitable || IsFloatingMode() )
1791 		return;
1792 
1793 	Rectangle aRect = Rectangle(Point(0, 0),
1794 								GetOutputSizePixel());
1795 	switch (GetAlignment())
1796 	{
1797 		case SFX_ALIGN_TOP:
1798 		{
1799 			DrawLine(aRect.BottomLeft(), aRect.BottomRight());
1800 			aRect.Bottom()--;
1801 			break;
1802 		}
1803 
1804 		case SFX_ALIGN_BOTTOM:
1805 		{
1806 			DrawLine(aRect.TopLeft(), aRect.TopRight());
1807 			aRect.Top()++;
1808 			break;
1809 		}
1810 
1811 		case SFX_ALIGN_LEFT:
1812 		{
1813 			DrawLine(aRect.TopRight(), aRect.BottomRight());
1814 			aRect.Right()--;
1815 			break;
1816 		}
1817 
1818 		case SFX_ALIGN_RIGHT:
1819 		{
1820 			DrawLine(aRect.TopLeft(), aRect.BottomLeft());
1821 			aRect.Left()++;
1822 			break;
1823 		}
1824               default:
1825                   break;
1826 	}
1827 
1828 	DecorationView aView( this );
1829 	aView.DrawFrame( aRect, FRAME_DRAW_OUT );
1830 }
1831 
1832 //-------------------------------------------------------------------------
1833 
1834 void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize )
1835 
1836 /*	[Beschreibung]
1837 
1838 	Mit dieser Methode kann eine minimale OutpuSize gesetzt werden, die
1839 	im Resizing()-Handler abgefragt wird.
1840 */
1841 
1842 {
1843 	pImp->aMinSize = rSize;
1844     DockingWindow::SetMinOutputSizePixel( rSize );
1845 }
1846 
1847 //-------------------------------------------------------------------------
1848 
1849 Size SfxDockingWindow::GetMinOutputSizePixel() const
1850 
1851 /*	[Beschreibung]
1852 
1853 	Die gesetzte minimale Gr"o\se wird zur"uckgegeben.
1854 */
1855 
1856 {
1857 	return pImp->aMinSize;
1858 }
1859 
1860 //-------------------------------------------------------------------------
1861 
1862 long SfxDockingWindow::Notify( NotifyEvent& rEvt )
1863 {
1864     if ( rEvt.GetType() == EVENT_GETFOCUS )
1865 	{
1866 		pBindings->SetActiveFrame( pMgr->GetFrame() );
1867 
1868 		if ( pImp->pSplitWin )
1869 			pImp->pSplitWin->SetActiveWindow_Impl( this );
1870 		else
1871 			pMgr->Activate_Impl();
1872 
1873         Window* pWindow = rEvt.GetWindow();
1874         rtl::OString sHelpId;
1875         while ( !sHelpId.getLength() && pWindow )
1876         {
1877             sHelpId = pWindow->GetHelpId();
1878             pWindow = pWindow->GetParent();
1879         }
1880 
1881         if ( sHelpId.getLength() )
1882             SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId );
1883 
1884         // In VCL geht Notify zun"achst an das Fenster selbst,
1885 		// also base class rufen, sonst erf"ahrt der parent nichts
1886         // if ( rEvt.GetWindow() == this )  PB: #i74693# not necessary any longer
1887         DockingWindow::Notify( rEvt );
1888 		return sal_True;
1889 	}
1890 	else if( rEvt.GetType() == EVENT_KEYINPUT )
1891 	{
1892 		// KeyInput zuerst f"ur Dialogfunktionen zulassen
1893         if ( !DockingWindow::Notify( rEvt ) && SfxViewShell::Current() )
1894 			// dann auch global g"ultige Acceleratoren verwenden
1895 			return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() );
1896 		return sal_True;
1897 	}
1898     else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() )
1899 	{
1900         pBindings->SetActiveFrame( NULL );
1901         pMgr->Deactivate_Impl();
1902 	}
1903 
1904 	return DockingWindow::Notify( rEvt );
1905 }
1906 
1907 
1908 sal_uInt16 SfxDockingWindow::GetWinBits_Impl() const
1909 {
1910 	sal_uInt16 nBits = 0;
1911 //	if ( pImp->bAutoHide )
1912 //		nBits |= SWIB_AUTOHIDE;
1913 	return nBits;
1914 }
1915 
1916 //-------------------------------------------------------------------------
1917 
1918 void SfxDockingWindow::SetItemSize_Impl( const Size& rSize )
1919 {
1920 	pImp->aSplitSize = rSize;
1921 
1922     SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
1923     SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
1924     if ( pImp->bSplitable )
1925         eIdent = SFX_CHILDWIN_SPLITWINDOW;
1926     pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
1927 }
1928 
1929 void SfxDockingWindow::Disappear_Impl()
1930 {
1931 	if ( pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) )
1932 		pImp->pSplitWin->RemoveWindow(this);
1933 }
1934 
1935 void SfxDockingWindow::Reappear_Impl()
1936 {
1937 	if ( pImp->pSplitWin && !pImp->pSplitWin->IsItemValid( GetType() ) )
1938 	{
1939 		pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize );
1940 	}
1941 }
1942 
1943 sal_Bool SfxDockingWindow::IsAutoHide_Impl() const
1944 {
1945 	if ( pImp->pSplitWin )
1946 		return !pImp->pSplitWin->IsFadeIn();
1947 	else
1948 		return sal_False;
1949 }
1950 
1951 sal_Bool SfxDockingWindow::IsPinned_Impl() const
1952 {
1953 	if ( pImp->pSplitWin )
1954 		return pImp->pSplitWin->IsPinned();
1955 	else
1956 		return sal_True;
1957 }
1958 void SfxDockingWindow::AutoShow( sal_Bool bShow )
1959 {
1960     AutoShow_Impl(bShow);
1961 }
1962 
1963 void SfxDockingWindow::AutoShow_Impl( sal_Bool bShow )
1964 {
1965 	if ( pImp->pSplitWin )
1966 	{
1967 		if ( bShow )
1968 			pImp->pSplitWin->FadeIn();
1969 		else
1970 			pImp->pSplitWin->FadeOut();
1971 	}
1972 }
1973 
1974 /*
1975 void SfxDockingWindow::Pin_Impl( sal_Bool bPinned )
1976 {
1977 	if ( pImp->pSplitWin )
1978 		pImp->pSplitWin->Pin_Impl( bPinned );
1979 }
1980 */
1981 
1982 SfxSplitWindow* SfxDockingWindow::GetSplitWindow_Impl() const
1983 {
1984 	return pImp->pSplitWin;
1985 }
1986 
1987 void SfxDockingWindow::FadeIn( sal_Bool /*bFadeIn*/ )
1988 {
1989 }
1990 
1991 void SfxDockingWindow::StateChanged( StateChangedType nStateChange )
1992 {
1993 	if ( nStateChange == STATE_CHANGE_INITSHOW )
1994 		Initialize_Impl();
1995 
1996 	DockingWindow::StateChanged( nStateChange );
1997 }
1998 
1999 void SfxDockingWindow::Move()
2000 {
2001     if ( pImp )
2002         pImp->aMoveTimer.Start();
2003 }
2004 
2005 IMPL_LINK( SfxDockingWindow, TimerHdl, Timer*, EMPTYARG)
2006 {
2007     pImp->aMoveTimer.Stop();
2008 	if ( IsReallyVisible() && IsFloatingMode() )
2009 	{
2010         if( !GetFloatingWindow()->IsRollUp() )
2011             SetFloatingSize( GetOutputSizePixel() );
2012         pImp->aWinState = GetFloatingWindow()->GetWindowState();
2013 		SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW;
2014 		if ( pImp->bSplitable )
2015 			eIdent = SFX_CHILDWIN_SPLITWINDOW;
2016 		SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl();
2017 		pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() );
2018 	}
2019 	return 0;
2020 }
2021 
2022