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