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/componentcontext.hxx>
44 #include <comphelper/namedvaluecollection.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <svl/eitem.hxx>
47 #include <svl/intitem.hxx>
48 #include <svl/itemset.hxx>
49 #include <svl/rectitem.hxx>
50 #include <svl/stritem.hxx>
51 #include <toolkit/helper/vclunohelper.hxx>
52 #include <tools/diagnose_ex.h>
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
;
64 //------------------------------------------------------------------------
66 class SfxFrameWindow_Impl
: public Window
71 SfxFrameWindow_Impl( SfxFrame
* pF
, Window
& i_rContainerWindow
);
72 ~SfxFrameWindow_Impl( );
74 virtual void DataChanged( const DataChangedEvent
& rDCEvt
);
75 virtual void StateChanged( StateChangedType nStateChange
);
76 virtual long PreNotify( NotifyEvent
& rNEvt
);
77 virtual long Notify( NotifyEvent
& rEvt
);
78 virtual void Resize();
79 virtual void GetFocus();
83 SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame
* pF
, Window
& i_rContainerWindow
)
84 : Window( &i_rContainerWindow
, WB_BORDER
| WB_CLIPCHILDREN
| WB_NODIALOGCONTROL
| WB_3DLOOK
)
89 SfxFrameWindow_Impl::~SfxFrameWindow_Impl( )
93 void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent
& rDCEvt
)
95 Window::DataChanged( rDCEvt
);
96 SfxWorkWindow
*pWorkWin
= pFrame
->GetWorkWindow_Impl();
98 pWorkWin
->DataChanged_Impl( rDCEvt
);
101 long SfxFrameWindow_Impl::Notify( NotifyEvent
& rNEvt
)
103 if ( pFrame
->IsClosing_Impl() || !pFrame
->GetFrameInterface().is() )
106 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
107 if ( !pView
|| !pView
->GetObjectShell() )
108 return Window::Notify( rNEvt
);
110 if ( rNEvt
.GetType() == EVENT_GETFOCUS
)
112 if ( pView
->GetViewShell() && !pView
->GetViewShell()->GetUIActiveIPClient_Impl() && !pFrame
->IsInPlace() )
114 OSL_TRACE("SfxFrame: GotFocus");
115 pView
->MakeActive_Impl( sal_False
);
118 // if focus was on an external window, the clipboard content might have been changed
119 pView
->GetBindings().Invalidate( SID_PASTE
);
120 pView
->GetBindings().Invalidate( SID_PASTE_SPECIAL
);
123 else if( rNEvt
.GetType() == EVENT_KEYINPUT
)
125 if ( pView
->GetViewShell()->KeyInput( *rNEvt
.GetKeyEvent() ) )
128 else if ( rNEvt
.GetType() == EVENT_EXECUTEDIALOG
/*|| rNEvt.GetType() == EVENT_INPUTDISABLE*/ )
130 pView
->SetModalMode( sal_True
);
133 else if ( rNEvt
.GetType() == EVENT_ENDEXECUTEDIALOG
/*|| rNEvt.GetType() == EVENT_INPUTENABLE*/ )
135 pView
->SetModalMode( sal_False
);
139 return Window::Notify( rNEvt
);
142 long SfxFrameWindow_Impl::PreNotify( NotifyEvent
& rNEvt
)
144 sal_uInt16 nType
= rNEvt
.GetType();
145 if ( nType
== EVENT_KEYINPUT
|| nType
== EVENT_KEYUP
)
147 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
148 SfxViewShell
* pShell
= pView
? pView
->GetViewShell() : NULL
;
149 if ( pShell
&& pShell
->HasKeyListeners_Impl() && pShell
->HandleNotifyEvent_Impl( rNEvt
) )
152 else if ( nType
== EVENT_MOUSEBUTTONUP
|| nType
== EVENT_MOUSEBUTTONDOWN
)
154 Window
* pWindow
= rNEvt
.GetWindow();
155 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
156 SfxViewShell
* pShell
= pView
? pView
->GetViewShell() : NULL
;
158 if ( pWindow
== pShell
->GetWindow() || pShell
->GetWindow()->IsChild( pWindow
) )
159 if ( pShell
->HasMouseClickListeners_Impl() && pShell
->HandleNotifyEvent_Impl( rNEvt
) )
163 if ( nType
== EVENT_MOUSEBUTTONDOWN
)
165 Window
* pWindow
= rNEvt
.GetWindow();
166 const MouseEvent
* pMEvent
= rNEvt
.GetMouseEvent();
167 Point aPos
= pWindow
->OutputToScreenPixel( pMEvent
->GetPosPixel() );
168 SfxWorkWindow
*pWorkWin
= pFrame
->GetWorkWindow_Impl();
170 pWorkWin
->EndAutoShow_Impl( aPos
);
173 return Window::PreNotify( rNEvt
);
176 void SfxFrameWindow_Impl::GetFocus()
178 if ( pFrame
&& !pFrame
->IsClosing_Impl() && pFrame
->GetCurrentViewFrame() && pFrame
->GetFrameInterface().is() )
179 pFrame
->GetCurrentViewFrame()->MakeActive_Impl( sal_True
);
182 void SfxFrameWindow_Impl::Resize()
184 if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
188 void SfxFrameWindow_Impl::StateChanged( StateChangedType nStateChange
)
190 if ( nStateChange
== STATE_CHANGE_INITSHOW
)
192 pFrame
->pImp
->bHidden
= sal_False
;
193 if ( pFrame
->IsInPlace() )
194 // TODO/MBA: workaround for bug in LayoutManager: the final resize does not get through because the
195 // LayoutManager works asynchronously and between resize and time execution the DockingAcceptor was exchanged so that
196 // the resize event never is sent to the component
197 SetSizePixel( GetParent()->GetOutputSizePixel() );
200 SfxViewFrame
* pView
= pFrame
->GetCurrentViewFrame();
202 pView
->GetBindings().GetWorkWindow_Impl()->ShowChildren_Impl();
205 Window::StateChanged( nStateChange
);
208 void SfxFrameWindow_Impl::DoResize()
210 if ( !pFrame
->pImp
->bLockResize
)
214 Reference
< XFrame
> SfxFrame::CreateBlankFrame()
216 Reference
< XFrame
> xFrame
;
219 Reference
< XDesktop2
> xDesktop
= Desktop::create( ::comphelper::getProcessComponentContext() );
220 xFrame
.set( xDesktop
->findFrame( "_blank", 0 ), UNO_SET_THROW
);
222 catch( const Exception
& )
224 DBG_UNHANDLED_EXCEPTION();
229 SfxFrame
* SfxFrame::Create( SfxObjectShell
& rDoc
, Window
& rWindow
, sal_uInt16 nViewId
, bool bHidden
)
231 SfxFrame
* pFrame
= NULL
;
234 // create and initialize new top level frame for this window
235 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
236 Reference
< XDesktop2
> xDesktop
= Desktop::create( xContext
);
237 Reference
< XFrame2
> xFrame
= Frame::create( xContext
);
239 Reference
< awt::XWindow2
> xWin( VCLUnoHelper::GetInterface ( &rWindow
), uno::UNO_QUERY_THROW
);
240 xFrame
->initialize( xWin
.get() );
241 xDesktop
->getFrames()->append( Reference
<XFrame
>(xFrame
, uno::UNO_QUERY_THROW
) );
243 if ( xWin
->isActive() )
246 // create load arguments
247 Sequence
< PropertyValue
> aLoadArgs
;
248 TransformItems( SID_OPENDOC
, *rDoc
.GetMedium()->GetItemSet(), aLoadArgs
);
250 ::comphelper::NamedValueCollection
aArgs( aLoadArgs
);
251 aArgs
.put( "Model", rDoc
.GetModel() );
252 aArgs
.put( "Hidden", bHidden
);
254 aArgs
.put( "ViewId", nViewId
);
256 aLoadArgs
= aArgs
.getPropertyValues();
258 // load the doc into that frame
259 OUString
sLoaderURL( "private:object" );
260 Reference
< XComponentLoader
> xLoader( xFrame
, UNO_QUERY_THROW
);
261 xLoader
->loadComponentFromURL(
268 for ( pFrame
= SfxFrame::GetFirst();
270 pFrame
= SfxFrame::GetNext( *pFrame
)
273 if ( pFrame
->GetFrameInterface() == xFrame
)
277 OSL_ENSURE( pFrame
, "SfxFrame::Create: load succeeded, but no SfxFrame was created during this!" );
279 catch( const Exception
& )
281 DBG_UNHANDLED_EXCEPTION();
287 SfxFrame
* SfxFrame::Create( const Reference
< XFrame
>& i_rFrame
)
289 // create a new TopFrame to an external XFrame object ( wrap controller )
290 ENSURE_OR_THROW( i_rFrame
.is(), "NULL frame not allowed" );
291 Window
* pWindow
= VCLUnoHelper::GetWindow( i_rFrame
->getContainerWindow() );
292 ENSURE_OR_THROW( pWindow
, "frame without container window not allowed" );
294 SfxFrame
* pFrame
= new SfxFrame( *pWindow
, false );
295 pFrame
->SetFrameInterface_Impl( i_rFrame
);
299 SfxFrame::SfxFrame( Window
& i_rContainerWindow
, bool i_bHidden
)
300 :pParentFrame( NULL
)
307 pImp
->bHidden
= i_bHidden
;
308 InsertTopFrame_Impl( this );
309 pImp
->pExternalContainerWindow
= &i_rContainerWindow
;
311 pWindow
= new SfxFrameWindow_Impl( this, i_rContainerWindow
);
313 // always show pWindow, which is the ComponentWindow of the XFrame we live in
314 // nowadays, since SfxFrames can be created with an XFrame only, hiding or showing the complete XFrame
315 // is not done at level of the container window, not at SFX level. Thus, the component window can
316 // always be visible.
320 void SfxFrame::SetPresentationMode( sal_Bool bSet
)
322 if ( GetCurrentViewFrame() )
323 GetCurrentViewFrame()->GetWindow().SetBorderStyle( bSet
? WINDOW_BORDER_NOBORDER
: WINDOW_BORDER_NORMAL
);
325 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
326 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
330 Any aValue
= xPropSet
->getPropertyValue( OUString( "LayoutManager" ));
331 aValue
>>= xLayoutManager
;
334 if ( xLayoutManager
.is() )
335 xLayoutManager
->setVisible( !bSet
); // we don't want to have ui in presentation mode
337 SetMenuBarOn_Impl( !bSet
);
338 if ( GetWorkWindow_Impl() )
339 GetWorkWindow_Impl()->SetDockingAllowed( !bSet
);
340 if ( GetCurrentViewFrame() )
341 GetCurrentViewFrame()->GetDispatcher()->Update_Impl( sal_True
);
344 SystemWindow
* SfxFrame::GetSystemWindow() const
346 return GetTopWindow_Impl();
349 SystemWindow
* SfxFrame::GetTopWindow_Impl() const
351 if ( pImp
->pExternalContainerWindow
->IsSystemWindow() )
352 return (SystemWindow
*) pImp
->pExternalContainerWindow
;
357 Window
& SfxFrame::GetWindow() const
362 sal_Bool
SfxFrame::Close()
368 void SfxFrame::LockResize_Impl( sal_Bool bLock
)
370 pImp
->bLockResize
= bLock
;
373 void SfxFrame::SetMenuBarOn_Impl( sal_Bool bOn
)
375 pImp
->bMenuBarOn
= bOn
;
377 Reference
< com::sun::star::beans::XPropertySet
> xPropSet( GetFrameInterface(), UNO_QUERY
);
378 Reference
< ::com::sun::star::frame::XLayoutManager
> xLayoutManager
;
382 Any aValue
= xPropSet
->getPropertyValue( OUString( "LayoutManager" ));
383 aValue
>>= xLayoutManager
;
386 if ( xLayoutManager
.is() )
388 OUString
aMenuBarURL( "private:resource/menubar/menubar" );
391 xLayoutManager
->showElement( aMenuBarURL
);
393 xLayoutManager
->hideElement( aMenuBarURL
);
397 sal_Bool
SfxFrame::IsMenuBarOn_Impl() const
399 return pImp
->bMenuBarOn
;
402 void SfxFrame::PrepareForDoc_Impl( SfxObjectShell
& i_rDoc
)
404 const ::comphelper::NamedValueCollection
aDocumentArgs( i_rDoc
.GetModel()->getArgs() );
407 OSL_ENSURE( !pImp
->bHidden
, "when does this happen?" );
408 pImp
->bHidden
= aDocumentArgs
.getOrDefault( "Hidden", pImp
->bHidden
);
410 // update our descriptor
411 UpdateDescriptor( &i_rDoc
);
414 sal_Int16 nPluginMode
= aDocumentArgs
.getOrDefault( "PluginMode", sal_Int16( 0 ) );
415 if ( nPluginMode
&& ( nPluginMode
!= 2 ) )
416 SetInPlace_Impl( sal_True
);
419 bool SfxFrame::IsMarkedHidden_Impl() const
421 return pImp
->bHidden
;
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */