bump product version to 5.0.4.1
[LibreOffice.git] / sfx2 / source / view / frame2.cxx
blob92cb344cf2cd37b9a3a159ec9c007b8cfb0bead0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
68 public:
69 SfxFrame* pFrame;
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;
79 void DoResize();
82 SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame* pF, vcl::Window& i_rContainerWindow )
83 : Window( &i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK )
84 , pFrame( pF )
88 void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
90 Window::DataChanged( rDCEvt );
91 SfxWorkWindow *pWorkWin = pFrame->GetWorkWindow_Impl();
92 if ( pWorkWin )
93 pWorkWin->DataChanged_Impl( rDCEvt );
96 bool SfxFrameWindow_Impl::Notify( NotifyEvent& rNEvt )
98 if ( pFrame->IsClosing_Impl() || !pFrame->GetFrameInterface().is() )
99 return false;
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 );
116 return true;
118 else if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
120 if ( pView->GetViewShell()->KeyInput( *rNEvt.GetKeyEvent() ) )
121 return true;
123 else if ( rNEvt.GetType() == MouseNotifyEvent::EXECUTEDIALOG /*|| rNEvt.GetType() == MouseNotifyEvent::INPUTDISABLE*/ )
125 pView->SetModalMode( true );
126 return true;
128 else if ( rNEvt.GetType() == MouseNotifyEvent::ENDEXECUTEDIALOG /*|| rNEvt.GetType() == MouseNotifyEvent::INPUTENABLE*/ )
130 pView->SetModalMode( false );
131 return true;
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 ) )
145 return true;
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;
152 if ( pShell )
153 if ( pWindow == pShell->GetWindow() || pShell->GetWindow()->IsChild( pWindow ) )
154 if ( pShell->HasMouseClickListeners_Impl() && pShell->HandleNotifyEvent_Impl( rNEvt ) )
155 return true;
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();
164 if ( pWorkWin )
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() )
180 DoResize();
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() );
194 DoResize();
195 SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
196 if ( pView )
197 pView->GetBindings().GetWorkWindow_Impl()->ShowChildren_Impl();
200 Window::StateChanged( nStateChange );
203 void SfxFrameWindow_Impl::DoResize()
205 if ( !pFrame->pImp->bLockResize )
206 pFrame->Resize();
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();
221 return xFrame;
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() )
239 xFrame->activate();
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 );
248 if ( nViewId )
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(
257 sLoaderURL,
258 OUString( "_self" ),
260 aLoadArgs
263 for ( pFrame = SfxFrame::GetFirst();
264 pFrame;
265 pFrame = SfxFrame::GetNext( *pFrame )
268 if ( pFrame->GetFrameInterface() == xFrame )
269 break;
272 OSL_ENSURE( pFrame, "SfxFrame::Create: load succeeded, but no SfxFrame was created during this!" );
274 catch( const Exception& )
276 DBG_UNHANDLED_EXCEPTION();
279 return pFrame;
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 );
291 return pFrame;
294 SfxFrame::SfxFrame( vcl::Window& i_rContainerWindow, bool i_bHidden )
295 :SvCompatWeakBase<SfxFrame>( this )
296 ,pParentFrame( NULL )
297 ,pChildArr( NULL )
298 ,pImp( NULL )
299 ,pWindow( NULL )
301 Construct_Impl();
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.
313 pWindow->Show();
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;
324 if ( xPropSet.is() )
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() );
349 else
350 return NULL;
354 bool SfxFrame::Close()
356 delete this;
357 return true;
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;
372 if ( xPropSet.is() )
374 Any aValue = xPropSet->getPropertyValue("LayoutManager");
375 aValue >>= xLayoutManager;
378 if ( xLayoutManager.is() )
380 OUString aMenuBarURL( "private:resource/menubar/menubar" );
382 if ( bOn )
383 xLayoutManager->showElement( aMenuBarURL );
384 else
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() );
398 // hidden?
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 );
405 // plugin mode
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: */