1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "impframe.hxx"
22 #include "objshimp.hxx"
23 #include <sfx2/sfxhelp.hxx>
24 #include "workwin.hxx"
26 #include <sfx2/app.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/docfac.hxx>
30 #include <sfx2/docfile.hxx>
31 #include <sfx2/event.hxx>
32 #include <sfx2/objface.hxx>
33 #include <sfx2/request.hxx>
35 #include <com/sun/star/awt/XWindow2.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/frame/Desktop.hpp>
38 #include <com/sun/star/frame/XComponentLoader.hpp>
39 #include <com/sun/star/frame/Frame.hpp>
40 #include <com/sun/star/frame/XFramesSupplier.hpp>
41 #include <com/sun/star/frame/XLayoutManager.hpp>
43 #include <comphelper/namedvaluecollection.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <svl/eitem.hxx>
46 #include <svl/intitem.hxx>
47 #include <svl/itemset.hxx>
48 #include <svl/rectitem.hxx>
49 #include <svl/stritem.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
51 #include <tools/diagnose_ex.h>
52 #include <vcl/syswin.hxx>
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::frame
;
57 using namespace ::com::sun::star::util
;
58 using namespace ::com::sun::star::container
;
59 using namespace ::com::sun::star::beans
;
60 using ::com::sun::star::lang::XMultiServiceFactory
;
61 using ::com::sun::star::lang::XComponent
;
62 using ::com::sun::star::frame::XComponentLoader
;
66 class SfxFrameWindow_Impl
: public vcl::Window
71 SfxFrameWindow_Impl( SfxFrame
* pF
, vcl::Window
& i_rContainerWindow
);
73 virtual void DataChanged( const DataChangedEvent
& rDCEvt
) SAL_OVERRIDE
;
74 virtual void StateChanged( StateChangedType nStateChange
) SAL_OVERRIDE
;
75 virtual bool PreNotify( NotifyEvent
& rNEvt
) SAL_OVERRIDE
;
76 virtual bool Notify( NotifyEvent
& rEvt
) SAL_OVERRIDE
;
77 virtual void Resize() SAL_OVERRIDE
;
78 virtual void GetFocus() SAL_OVERRIDE
;
82 SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame
* pF
, vcl::Window
& i_rContainerWindow
)
83 : Window( &i_rContainerWindow
, WB_BORDER
| WB_CLIPCHILDREN
| WB_NODIALOGCONTROL
| WB_3DLOOK
)
88 void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent
& rDCEvt
)
90 Window::DataChanged( rDCEvt
);
91 SfxWorkWindow
*pWorkWin
= pFrame
->GetWorkWindow_Impl();
93 pWorkWin
->DataChanged_Impl( rDCEvt
);
96 bool SfxFrameWindow_Impl::Notify( NotifyEvent
& rNEvt
)
98 if ( pFrame
->IsClosing_Impl() || !pFrame
->GetFrameInterface().is() )
101 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
102 if ( !pView
|| !pView
->GetObjectShell() )
103 return Window::Notify( rNEvt
);
105 if ( rNEvt
.GetType() == MouseNotifyEvent::GETFOCUS
)
107 if ( pView
->GetViewShell() && !pView
->GetViewShell()->GetUIActiveIPClient_Impl() && !pFrame
->IsInPlace() )
109 OSL_TRACE("SfxFrame: GotFocus");
110 pView
->MakeActive_Impl( false );
113 // if focus was on an external window, the clipboard content might have been changed
114 pView
->GetBindings().Invalidate( SID_PASTE
);
115 pView
->GetBindings().Invalidate( SID_PASTE_SPECIAL
);
118 else if( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
120 if ( pView
->GetViewShell()->KeyInput( *rNEvt
.GetKeyEvent() ) )
123 else if ( rNEvt
.GetType() == MouseNotifyEvent::EXECUTEDIALOG
/*|| rNEvt.GetType() == MouseNotifyEvent::INPUTDISABLE*/ )
125 pView
->SetModalMode( true );
128 else if ( rNEvt
.GetType() == MouseNotifyEvent::ENDEXECUTEDIALOG
/*|| rNEvt.GetType() == MouseNotifyEvent::INPUTENABLE*/ )
130 pView
->SetModalMode( false );
134 return Window::Notify( rNEvt
);
137 bool SfxFrameWindow_Impl::PreNotify( NotifyEvent
& rNEvt
)
139 MouseNotifyEvent nType
= rNEvt
.GetType();
140 if ( nType
== MouseNotifyEvent::KEYINPUT
|| nType
== MouseNotifyEvent::KEYUP
)
142 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
143 SfxViewShell
* pShell
= pView
? pView
->GetViewShell() : NULL
;
144 if ( pShell
&& pShell
->HasKeyListeners_Impl() && pShell
->HandleNotifyEvent_Impl( rNEvt
) )
147 else if ( nType
== MouseNotifyEvent::MOUSEBUTTONUP
|| nType
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
149 vcl::Window
* pWindow
= rNEvt
.GetWindow();
150 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
151 SfxViewShell
* pShell
= pView
? pView
->GetViewShell() : NULL
;
153 if ( pWindow
== pShell
->GetWindow() || pShell
->GetWindow()->IsChild( pWindow
) )
154 if ( pShell
->HasMouseClickListeners_Impl() && pShell
->HandleNotifyEvent_Impl( rNEvt
) )
158 if ( nType
== MouseNotifyEvent::MOUSEBUTTONDOWN
)
160 vcl::Window
* pWindow
= rNEvt
.GetWindow();
161 const MouseEvent
* pMEvent
= rNEvt
.GetMouseEvent();
162 Point aPos
= pWindow
->OutputToScreenPixel( pMEvent
->GetPosPixel() );
163 SfxWorkWindow
*pWorkWin
= pFrame
->GetWorkWindow_Impl();
165 pWorkWin
->EndAutoShow_Impl( aPos
);
168 return Window::PreNotify( rNEvt
);
171 void SfxFrameWindow_Impl::GetFocus()
173 if ( pFrame
&& !pFrame
->IsClosing_Impl() && pFrame
->GetCurrentViewFrame() && pFrame
->GetFrameInterface().is() )
174 pFrame
->GetCurrentViewFrame()->MakeActive_Impl( true );
177 void SfxFrameWindow_Impl::Resize()
179 if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
183 void SfxFrameWindow_Impl::StateChanged( StateChangedType nStateChange
)
185 if ( nStateChange
== StateChangedType::InitShow
)
187 pFrame
->pImp
->bHidden
= false;
188 if ( pFrame
->IsInPlace() )
189 // TODO/MBA: workaround for bug in LayoutManager: the final resize does not get through because the
190 // LayoutManager works asynchronously and between resize and time execution the DockingAcceptor was exchanged so that
191 // the resize event never is sent to the component
192 SetSizePixel( GetParent()->GetOutputSizePixel() );
195 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
197 pView
->GetBindings().GetWorkWindow_Impl()->ShowChildren_Impl();
200 Window::StateChanged( nStateChange
);
203 void SfxFrameWindow_Impl::DoResize()
205 if ( !pFrame
->pImp
->bLockResize
)
209 Reference
< XFrame
> SfxFrame::CreateBlankFrame()
211 Reference
< XFrame
> xFrame
;
214 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
215 xFrame
.set( xDesktop
->findFrame( "_blank", 0 ), UNO_SET_THROW
);
217 catch( const Exception
& )
219 DBG_UNHANDLED_EXCEPTION();
224 SfxFrame
* SfxFrame::Create( SfxObjectShell
& rDoc
, vcl::Window
& rWindow
, sal_uInt16 nViewId
, bool bHidden
)
226 SfxFrame
* pFrame
= NULL
;
229 // create and initialize new top level frame for this window
230 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
231 Reference
< XDesktop2
> xDesktop
= Desktop::create( xContext
);
232 Reference
< XFrame2
> xFrame
= Frame::create( xContext
);
234 Reference
< awt::XWindow2
> xWin( VCLUnoHelper::GetInterface ( &rWindow
), uno::UNO_QUERY_THROW
);
235 xFrame
->initialize( xWin
.get() );
236 xDesktop
->getFrames()->append( xFrame
);
238 if ( xWin
->isActive() )
241 // create load arguments
242 Sequence
< PropertyValue
> aLoadArgs
;
243 TransformItems( SID_OPENDOC
, *rDoc
.GetMedium()->GetItemSet(), aLoadArgs
);
245 ::comphelper::NamedValueCollection
aArgs( aLoadArgs
);
246 aArgs
.put( "Model", rDoc
.GetModel() );
247 aArgs
.put( "Hidden", bHidden
);
249 aArgs
.put( "ViewId", nViewId
);
251 aLoadArgs
= aArgs
.getPropertyValues();
253 // load the doc into that frame
254 OUString
sLoaderURL( "private:object" );
255 Reference
< XComponentLoader
> xLoader( xFrame
, UNO_QUERY_THROW
);
256 xLoader
->loadComponentFromURL(
263 for ( pFrame
= SfxFrame::GetFirst();
265 pFrame
= SfxFrame::GetNext( *pFrame
)
268 if ( pFrame
->GetFrameInterface() == xFrame
)
272 OSL_ENSURE( pFrame
, "SfxFrame::Create: load succeeded, but no SfxFrame was created during this!" );
274 catch( const Exception
& )
276 DBG_UNHANDLED_EXCEPTION();
282 SfxFrame
* SfxFrame::Create( const Reference
< XFrame
>& i_rFrame
)
284 // create a new TopFrame to an external XFrame object ( wrap controller )
285 ENSURE_OR_THROW( i_rFrame
.is(), "NULL frame not allowed" );
286 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( i_rFrame
->getContainerWindow() );
287 ENSURE_OR_THROW( pWindow
, "frame without container window not allowed" );
289 SfxFrame
* pFrame
= new SfxFrame( *pWindow
, false );
290 pFrame
->SetFrameInterface_Impl( i_rFrame
);
294 SfxFrame::SfxFrame( vcl::Window
& i_rContainerWindow
, bool i_bHidden
)
295 :SvCompatWeakBase
<SfxFrame
>( this )
296 ,pParentFrame( NULL
)
303 pImp
->bHidden
= i_bHidden
;
304 InsertTopFrame_Impl( this );
305 pImp
->pExternalContainerWindow
= &i_rContainerWindow
;
307 pWindow
= VclPtr
<SfxFrameWindow_Impl
>::Create( this, i_rContainerWindow
);
309 // always show pWindow, which is the ComponentWindow of the XFrame we live in
310 // nowadays, since SfxFrames can be created with an XFrame only, hiding or showing the complete XFrame
311 // is not done at level of the container window, not at SFX level. Thus, the component window can
312 // always be visible.
316 void SfxFrame::SetPresentationMode( bool bSet
)
318 if ( GetCurrentViewFrame() )
319 GetCurrentViewFrame()->GetWindow().SetBorderStyle( bSet
? WindowBorderStyle::NOBORDER
: WindowBorderStyle::NORMAL
);
321 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
322 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
326 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
327 aValue
>>= xLayoutManager
;
330 if ( xLayoutManager
.is() )
331 xLayoutManager
->setVisible( !bSet
); // we don't want to have ui in presentation mode
333 SetMenuBarOn_Impl( !bSet
);
334 if ( GetWorkWindow_Impl() )
335 GetWorkWindow_Impl()->SetDockingAllowed( !bSet
);
336 if ( GetCurrentViewFrame() )
337 GetCurrentViewFrame()->GetDispatcher()->Update_Impl( true );
340 SystemWindow
* SfxFrame::GetSystemWindow() const
342 return GetTopWindow_Impl();
345 SystemWindow
* SfxFrame::GetTopWindow_Impl() const
347 if ( pImp
->pExternalContainerWindow
->IsSystemWindow() )
348 return static_cast<SystemWindow
*>( pImp
->pExternalContainerWindow
.get() );
354 bool SfxFrame::Close()
360 void SfxFrame::LockResize_Impl( bool bLock
)
362 pImp
->bLockResize
= bLock
;
365 void SfxFrame::SetMenuBarOn_Impl( bool bOn
)
367 pImp
->bMenuBarOn
= bOn
;
369 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
370 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
374 Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
375 aValue
>>= xLayoutManager
;
378 if ( xLayoutManager
.is() )
380 OUString
aMenuBarURL( "private:resource/menubar/menubar" );
383 xLayoutManager
->showElement( aMenuBarURL
);
385 xLayoutManager
->hideElement( aMenuBarURL
);
389 bool SfxFrame::IsMenuBarOn_Impl() const
391 return pImp
->bMenuBarOn
;
394 void SfxFrame::PrepareForDoc_Impl( SfxObjectShell
& i_rDoc
)
396 const ::comphelper::NamedValueCollection
aDocumentArgs( i_rDoc
.GetModel()->getArgs() );
399 OSL_ENSURE( !pImp
->bHidden
, "when does this happen?" );
400 pImp
->bHidden
= aDocumentArgs
.getOrDefault( "Hidden", pImp
->bHidden
);
402 // update our descriptor
403 UpdateDescriptor( &i_rDoc
);
406 sal_Int16 nPluginMode
= aDocumentArgs
.getOrDefault( "PluginMode", sal_Int16( 0 ) );
407 if ( nPluginMode
&& ( nPluginMode
!= 2 ) )
408 SetInPlace_Impl( true );
411 bool SfxFrame::IsMarkedHidden_Impl() const
413 return pImp
->bHidden
;
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */