LibreOffice Module sfx2 (master) 1
frame2.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include "impframe.hxx"
22#include <workwin.hxx>
23
24#include <sfx2/bindings.hxx>
25#include <sfx2/dispatch.hxx>
26#include <sfx2/docfile.hxx>
27#include <sfx2/sfxsids.hrc>
28#include <sfx2/sfxuno.hxx>
29#include <sfx2/viewsh.hxx>
30
31#include <com/sun/star/awt/XWindow2.hpp>
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/frame/Desktop.hpp>
34#include <com/sun/star/frame/XComponentLoader.hpp>
35#include <com/sun/star/frame/Frame.hpp>
36#include <com/sun/star/frame/XLayoutManager.hpp>
37
42#include <vcl/event.hxx>
43#include <vcl/syswin.hxx>
44#include <sal/log.hxx>
45
46using namespace ::com::sun::star;
47using namespace ::com::sun::star::uno;
48using namespace ::com::sun::star::frame;
49using namespace ::com::sun::star::util;
50using namespace ::com::sun::star::container;
51using namespace ::com::sun::star::beans;
52using ::com::sun::star::frame::XComponentLoader;
53
55{
56 DECL_LINK(ModalHierarchyHdl, bool, void);
57public:
59
60 SfxFrameWindow_Impl( SfxFrame* pF, vcl::Window& i_rContainerWindow );
61
62 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
63 virtual void StateChanged( StateChangedType nStateChange ) override;
64 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
65 virtual bool EventNotify( NotifyEvent& rEvt ) override;
66 virtual void Resize() override;
67 virtual void GetFocus() override;
68 virtual void dispose() override;
69 void DoResize();
70};
71
73 : Window(&i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK)
74 , m_pFrame(pF)
75{
76 i_rContainerWindow.SetModalHierarchyHdl(LINK(this, SfxFrameWindow_Impl, ModalHierarchyHdl));
77}
78
80{
83}
84
86{
87 Window::DataChanged( rDCEvt );
88 // tdf#131613 the printers changing has no effect on window layout
89 if (rDCEvt.GetType() == DataChangedEventType::PRINTER)
90 return;
92 if ( pWorkWin )
93 pWorkWin->DataChanged_Impl();
94}
95
97{
99 return false;
100
102 if ( !pView || !pView->GetObjectShell() )
103 return Window::EventNotify( rNEvt );
104
105 if ( rNEvt.GetType() == NotifyEventType::GETFOCUS )
106 {
107 if ( pView->GetViewShell() && !pView->GetViewShell()->GetUIActiveIPClient_Impl() && !m_pFrame->IsInPlace() )
108 {
109 SAL_INFO("sfx", "SfxFrame: GotFocus");
110 pView->MakeActive_Impl( false );
111 }
112
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;
117 }
118 else if( rNEvt.GetType() == NotifyEventType::KEYINPUT )
119 {
120 if ( pView->GetViewShell()->KeyInput( *rNEvt.GetKeyEvent() ) )
121 return true;
122 }
123
124 return Window::EventNotify( rNEvt );
125}
126
127IMPL_LINK(SfxFrameWindow_Impl, ModalHierarchyHdl, bool, bSetModal, void)
128{
129 SfxViewFrame* pView = m_pFrame->GetCurrentViewFrame();
130 if (!pView || !pView->GetObjectShell())
131 return;
132 pView->SetModalMode(bSetModal);
133}
134
136{
137 NotifyEventType nType = rNEvt.GetType();
138 if ( nType == NotifyEventType::KEYINPUT || nType == NotifyEventType::KEYUP )
139 {
141 SfxViewShell* pShell = pView ? pView->GetViewShell() : nullptr;
142 if ( pShell && pShell->HasKeyListeners_Impl() && pShell->HandleNotifyEvent_Impl( rNEvt ) )
143 return true;
144 }
145 else if ( nType == NotifyEventType::MOUSEBUTTONUP || nType == NotifyEventType::MOUSEBUTTONDOWN )
146 {
147 vcl::Window* pWindow = rNEvt.GetWindow();
149 SfxViewShell* pShell = pView ? pView->GetViewShell() : nullptr;
150 if ( pShell )
151 if ( pWindow == pShell->GetWindow() || pShell->GetWindow()->IsChild( pWindow ) )
152 if ( pShell->HasMouseClickListeners_Impl() && pShell->HandleNotifyEvent_Impl( rNEvt ) )
153 return true;
154 }
155
156 if ( nType == NotifyEventType::MOUSEBUTTONDOWN )
157 {
158 vcl::Window* pWindow = rNEvt.GetWindow();
159 const MouseEvent* pMEvent = rNEvt.GetMouseEvent();
160 Point aPos = pWindow->OutputToScreenPixel( pMEvent->GetPosPixel() );
162 if ( pWorkWin )
163 pWorkWin->EndAutoShow_Impl( aPos );
164 }
165
166 return Window::PreNotify( rNEvt );
167}
168
170{
171 if ( m_pFrame && !m_pFrame->IsClosing_Impl() &&
175}
176
178{
180 DoResize();
181}
182
184{
185 if ( nStateChange == StateChangedType::InitShow )
186 {
187 m_pFrame->m_pImpl->bHidden = false;
188 if ( m_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
193
194 DoResize();
196 if ( pView )
198 }
199
200 Window::StateChanged( nStateChange );
201}
202
204{
205 if ( !m_pFrame->m_pImpl->bLockResize )
206 m_pFrame->Resize();
207}
208
209Reference < XFrame > SfxFrame::CreateBlankFrame()
210{
211 Reference < XFrame > xFrame;
212 try
213 {
214 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
215 xFrame.set( xDesktop->findFrame( "_blank", 0 ), UNO_SET_THROW );
216 }
217 catch( const Exception& )
218 {
219 DBG_UNHANDLED_EXCEPTION("sfx.view");
220 }
221 return xFrame;
222}
223
225{
226 SfxFrame* pFrame = nullptr;
227 try
228 {
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 );
233
234 Reference< awt::XWindow2 > xWin( VCLUnoHelper::GetInterface ( &rWindow ), uno::UNO_QUERY_THROW );
235 xFrame->initialize( xWin );
236 xDesktop->getFrames()->append( xFrame );
237
238 if ( xWin->isActive() )
239 xFrame->activate();
240
241 // create load arguments
242 Sequence< PropertyValue > aLoadArgs;
243 TransformItems( SID_OPENDOC, rDoc.GetMedium()->GetItemSet(), aLoadArgs );
244
245 ::comphelper::NamedValueCollection aArgs( aLoadArgs );
246 aArgs.put( "Model", rDoc.GetModel() );
247 aArgs.put( "Hidden", true );
248 if ( nViewId != SFX_INTERFACE_NONE )
249 aArgs.put( "ViewId", static_cast<sal_uInt16>(nViewId) );
250
251 aLoadArgs = aArgs.getPropertyValues();
252
253 // load the doc into that frame
254 Reference< XComponentLoader > xLoader( xFrame, UNO_QUERY_THROW );
255 xLoader->loadComponentFromURL(
256 "private:object",
257 "_self",
258 0,
259 aLoadArgs
260 );
261
262 for ( pFrame = SfxFrame::GetFirst();
263 pFrame;
264 pFrame = SfxFrame::GetNext( *pFrame )
265 )
266 {
267 if ( pFrame->GetFrameInterface() == xFrame )
268 break;
269 }
270
271 OSL_ENSURE( pFrame, "SfxFrame::Create: load succeeded, but no SfxFrame was created during this!" );
272 }
273 catch( const Exception& )
274 {
275 DBG_UNHANDLED_EXCEPTION("sfx.view");
276 }
277
278 return pFrame;
279}
280
281SfxFrame* SfxFrame::Create( const Reference < XFrame >& i_rFrame )
282{
283 // create a new TopFrame to an external XFrame object ( wrap controller )
284 ENSURE_OR_THROW( i_rFrame.is(), "NULL frame not allowed" );
285 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( i_rFrame->getContainerWindow() );
286 ENSURE_OR_THROW( pWindow, "frame without container window not allowed" );
287
288 SfxFrame* pFrame = new SfxFrame( *pWindow );
289 pFrame->SetFrameInterface_Impl( i_rFrame );
290 return pFrame;
291}
292
293SfxFrame::SfxFrame( vcl::Window& i_rContainerWindow )
294 :SvCompatWeakBase<SfxFrame>( this )
295 ,m_pWindow( nullptr )
296{
298
299 m_pImpl->bHidden = false;
300 InsertTopFrame_Impl( this );
301 m_pImpl->pExternalContainerWindow = &i_rContainerWindow;
302
303 m_pWindow = VclPtr<SfxFrameWindow_Impl>::Create( this, i_rContainerWindow );
304
305 // always show pWindow, which is the ComponentWindow of the XFrame we live in
306 // nowadays, since SfxFrames can be created with an XFrame only, hiding or showing the complete XFrame
307 // is not done at level of the container window, not at SFX level. Thus, the component window can
308 // always be visible.
309 m_pWindow->Show();
310}
311
313{
314 if ( GetCurrentViewFrame() )
315 GetCurrentViewFrame()->GetWindow().SetBorderStyle( bSet ? WindowBorderStyle::NOBORDER : WindowBorderStyle::NORMAL );
316
317 Reference< css::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
318 Reference< css::frame::XLayoutManager > xLayoutManager;
319
320 if ( xPropSet.is() )
321 {
322 Any aValue = xPropSet->getPropertyValue("LayoutManager");
323 aValue >>= xLayoutManager;
324 }
325
326 if ( xLayoutManager.is() )
327 xLayoutManager->setVisible( !bSet ); // we don't want to have ui in presentation mode
328
329 SetMenuBarOn_Impl( !bSet );
330 if ( GetWorkWindow_Impl() )
332 if ( GetCurrentViewFrame() )
334}
335
337{
338 return GetTopWindow_Impl();
339}
340
342{
343 if ( m_pImpl->pExternalContainerWindow->IsSystemWindow() )
344 return static_cast<SystemWindow*>( m_pImpl->pExternalContainerWindow.get() );
345 else
346 return nullptr;
347}
348
349
351{
352 m_pImpl->bLockResize = bLock;
353}
354
356{
357 m_pImpl->bMenuBarOn = bOn;
358
359 Reference< css::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
360 Reference< css::frame::XLayoutManager > xLayoutManager;
361
362 if ( xPropSet.is() )
363 {
364 Any aValue = xPropSet->getPropertyValue("LayoutManager");
365 aValue >>= xLayoutManager;
366 }
367
368 if ( xLayoutManager.is() )
369 {
370 OUString aMenuBarURL( "private:resource/menubar/menubar" );
371
372 if ( bOn )
373 xLayoutManager->showElement( aMenuBarURL );
374 else
375 xLayoutManager->hideElement( aMenuBarURL );
376 }
377}
378
380{
381 return m_pImpl->bMenuBarOn;
382}
383
385{
386 const ::comphelper::NamedValueCollection aDocumentArgs( i_rDoc.GetModel()->getArgs2( { "Hidden", "PluginMode" } ) );
387
388 // hidden?
389 OSL_ENSURE( !m_pImpl->bHidden, "when does this happen?" );
390 m_pImpl->bHidden = aDocumentArgs.getOrDefault( "Hidden", m_pImpl->bHidden );
391
392 // update our descriptor
393 UpdateDescriptor( &i_rDoc );
394
395 // plugin mode
396 sal_Int16 nPluginMode = aDocumentArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
397 if ( nPluginMode && ( nPluginMode != 2 ) )
398 m_pImpl->bInPlace = true;
399}
400
402{
403 return m_pImpl->bHidden;
404}
405
406/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void TransformItems(sal_uInt16 nSlotId, const SfxItemSet &rSet, uno::Sequence< beans::PropertyValue > &rArgs, const SfxSlot *pSlot)
Definition: appuno.cxx:908
DataChangedEventType GetType() const
const Point & GetPosPixel() const
const KeyEvent * GetKeyEvent() const
vcl::Window * GetWindow() const
const MouseEvent * GetMouseEvent() const
NotifyEventType GetType() const
SAL_DLLPRIVATE SfxWorkWindow * GetWorkWindow_Impl() const
Definition: bindings.cxx:1683
void Invalidate(sal_uInt16 nId)
Definition: bindings.cxx:639
SAL_DLLPRIVATE void Update_Impl(bool bForce=false)
Definition: dispatch.cxx:1034
DECL_LINK(ModalHierarchyHdl, bool, void)
virtual void GetFocus() override
Definition: frame2.cxx:169
virtual void Resize() override
Definition: frame2.cxx:177
SfxFrame * m_pFrame
Definition: frame2.cxx:58
virtual bool EventNotify(NotifyEvent &rEvt) override
Definition: frame2.cxx:96
SfxFrameWindow_Impl(SfxFrame *pF, vcl::Window &i_rContainerWindow)
Definition: frame2.cxx:72
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: frame2.cxx:135
virtual void dispose() override
Definition: frame2.cxx:79
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: frame2.cxx:85
virtual void StateChanged(StateChangedType nStateChange) override
Definition: frame2.cxx:183
static SfxFrame * Create(const css::uno::Reference< css::frame::XFrame > &xFrame)
Definition: frame2.cxx:281
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
SAL_DLLPRIVATE void PrepareForDoc_Impl(const SfxObjectShell &i_rDoc)
Definition: frame2.cxx:384
SystemWindow * GetSystemWindow() const
Definition: frame2.cxx:336
VclPtr< vcl::Window > m_pWindow
Definition: frame.hxx:73
SAL_DLLPRIVATE SystemWindow * GetTopWindow_Impl() const
Definition: frame2.cxx:341
void Resize()
Definition: frame.cxx:662
bool IsClosing_Impl() const
Definition: frame.cxx:197
SAL_DLLPRIVATE void SetMenuBarOn_Impl(bool bOn)
Definition: frame2.cxx:355
SAL_DLLPRIVATE void SetFrameInterface_Impl(const css::uno::Reference< css::frame::XFrame > &rFrame)
Definition: frame.cxx:520
void UpdateDescriptor(SfxObjectShell const *pDoc)
Definition: frame.cxx:293
SAL_DLLPRIVATE SfxFrame(vcl::Window &i_rContainerWindow)
Definition: frame2.cxx:293
void SetPresentationMode(bool bSet)
Definition: frame2.cxx:312
SAL_DLLPRIVATE bool IsMenuBarOn_Impl() const
Definition: frame2.cxx:379
static css::uno::Reference< css::frame::XFrame > CreateBlankFrame()
Definition: frame2.cxx:209
SAL_DLLPRIVATE SfxWorkWindow * GetWorkWindow_Impl() const
Definition: frame.cxx:588
SAL_DLLPRIVATE bool IsMarkedHidden_Impl() const
Definition: frame2.cxx:401
SAL_DLLPRIVATE void Construct_Impl()
Definition: frame.cxx:70
static SAL_DLLPRIVATE void InsertTopFrame_Impl(SfxFrame *pFrame)
Definition: frame.cxx:366
std::unique_ptr< SfxFrame_Impl > m_pImpl
Definition: frame.hxx:72
static SfxFrame * CreateHidden(SfxObjectShell const &rDoc, vcl::Window &rWindow, SfxInterfaceId nViewId)
Definition: frame2.cxx:224
static SAL_WARN_UNUSED_RESULT SfxFrame * GetNext(SfxFrame &)
Definition: frame.cxx:711
bool IsInPlace() const
Definition: frame.cxx:657
static SAL_WARN_UNUSED_RESULT SfxFrame * GetFirst()
Definition: frame.cxx:706
SAL_WARN_UNUSED_RESULT SfxViewFrame * GetCurrentViewFrame() const
Definition: frame.cxx:234
SAL_DLLPRIVATE void LockResize_Impl(bool bLock)
Definition: frame2.cxx:350
SfxItemSet & GetItemSet() const
Definition: docfile.cxx:3647
SfxMedium * GetMedium() const
Definition: objsh.hxx:261
css::uno::Reference< css::frame::XModel3 > GetModel() const
Definition: objxtor.cxx:838
SfxViewShell * GetViewShell() const
Returns the SfxViewShell in which they are located in the subshells.
Definition: shell.cxx:129
void SetModalMode(bool)
Definition: viewfrm.cxx:2814
vcl::Window & GetWindow() const
Definition: viewfrm.cxx:2792
SfxBindings & GetBindings()
Definition: viewfrm.hxx:110
SfxDispatcher * GetDispatcher()
Definition: viewfrm.hxx:109
virtual SfxObjectShell * GetObjectShell() override
Definition: viewfrm.cxx:2218
SAL_DLLPRIVATE void MakeActive_Impl(bool bActivate)
Definition: viewfrm.cxx:2178
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
SAL_DLLPRIVATE bool HasMouseClickListeners_Impl() const
Definition: viewsh.cxx:2833
SAL_DLLPRIVATE bool HasKeyListeners_Impl() const
Definition: viewsh.cxx:2827
SAL_DLLPRIVATE bool HandleNotifyEvent_Impl(NotifyEvent const &rEvent)
Definition: viewsh.cxx:2820
virtual bool KeyInput(const KeyEvent &rKeyEvent)
Definition: viewsh.cxx:2469
vcl::Window * GetWindow() const
Definition: viewsh.hxx:272
SAL_DLLPRIVATE SfxInPlaceClient * GetUIActiveIPClient_Impl() const
Definition: viewsh.cxx:1500
void DataChanged_Impl()
Definition: workwin.cxx:2429
void EndAutoShow_Impl(Point aPos)
Definition: workwin.cxx:2251
void ShowChildren_Impl()
Definition: workwin.cxx:961
void SetDockingAllowed(bool bSet)
Definition: workwin.hxx:235
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
static VclPtr< reference_type > Create(Arg &&... arg)
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
Point OutputToScreenPixel(const Point &rPos) const
virtual void dispose() override
bool IsReallyVisible() const
vcl::Window * GetParent() const
bool IsChild(const vcl::Window *pWindow) const
virtual void SetSizePixel(const Size &rNewSize)
bool IsReallyShown() const
Size GetOutputSizePixel() const
void SetBorderStyle(WindowBorderStyle nBorderStyle)
void SetModalHierarchyHdl(const Link< bool, void > &rLink)
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
NotifyEventType
IMPL_LINK(SfxFrameWindow_Impl, ModalHierarchyHdl, bool, bSetModal, void)
Definition: frame2.cxx:127
#define SAL_INFO(area, stream)
@ Exception
QPRO_FUNC_TYPE nType
constexpr auto SFX_INTERFACE_NONE
Definition: shell.hxx:60
Reference< XFrame > xFrame
StateChangedType
WinBits const WB_3DLOOK
WinBits const WB_BORDER
WinBits const WB_NODIALOGCONTROL
WinBits const WB_CLIPCHILDREN