Line data Source code
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 "objshimp.hxx"
23 : #include <sfx2/sfxhelp.hxx>
24 : #include "workwin.hxx"
25 :
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>
34 :
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>
42 :
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 :
53 : using namespace ::com::sun::star;
54 : using namespace ::com::sun::star::uno;
55 : using namespace ::com::sun::star::frame;
56 : using namespace ::com::sun::star::util;
57 : using namespace ::com::sun::star::container;
58 : using namespace ::com::sun::star::beans;
59 : using ::com::sun::star::lang::XMultiServiceFactory;
60 : using ::com::sun::star::lang::XComponent;
61 : using ::com::sun::star::frame::XComponentLoader;
62 :
63 :
64 :
65 : class SfxFrameWindow_Impl : public vcl::Window
66 : {
67 : public:
68 : SfxFrame* pFrame;
69 :
70 : SfxFrameWindow_Impl( SfxFrame* pF, vcl::Window& i_rContainerWindow );
71 : virtual ~SfxFrameWindow_Impl( );
72 :
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();
80 : };
81 :
82 5508 : SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame* pF, vcl::Window& i_rContainerWindow )
83 : : Window( &i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK )
84 5508 : , pFrame( pF )
85 : {
86 5508 : }
87 :
88 11012 : SfxFrameWindow_Impl::~SfxFrameWindow_Impl( )
89 : {
90 11012 : }
91 :
92 96 : void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
93 : {
94 96 : Window::DataChanged( rDCEvt );
95 96 : SfxWorkWindow *pWorkWin = pFrame->GetWorkWindow_Impl();
96 96 : if ( pWorkWin )
97 96 : pWorkWin->DataChanged_Impl( rDCEvt );
98 96 : }
99 :
100 265964 : bool SfxFrameWindow_Impl::Notify( NotifyEvent& rNEvt )
101 : {
102 265964 : if ( pFrame->IsClosing_Impl() || !pFrame->GetFrameInterface().is() )
103 241070 : return false;
104 :
105 24894 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
106 24894 : if ( !pView || !pView->GetObjectShell() )
107 0 : return Window::Notify( rNEvt );
108 :
109 24894 : if ( rNEvt.GetType() == EVENT_GETFOCUS )
110 : {
111 5131 : if ( pView->GetViewShell() && !pView->GetViewShell()->GetUIActiveIPClient_Impl() && !pFrame->IsInPlace() )
112 : {
113 : OSL_TRACE("SfxFrame: GotFocus");
114 5129 : pView->MakeActive_Impl( false );
115 : }
116 :
117 : // if focus was on an external window, the clipboard content might have been changed
118 5131 : pView->GetBindings().Invalidate( SID_PASTE );
119 5131 : pView->GetBindings().Invalidate( SID_PASTE_SPECIAL );
120 5131 : return true;
121 : }
122 19763 : else if( rNEvt.GetType() == EVENT_KEYINPUT )
123 : {
124 0 : if ( pView->GetViewShell()->KeyInput( *rNEvt.GetKeyEvent() ) )
125 0 : return true;
126 : }
127 19763 : else if ( rNEvt.GetType() == EVENT_EXECUTEDIALOG /*|| rNEvt.GetType() == EVENT_INPUTDISABLE*/ )
128 : {
129 0 : pView->SetModalMode( true );
130 0 : return true;
131 : }
132 19763 : else if ( rNEvt.GetType() == EVENT_ENDEXECUTEDIALOG /*|| rNEvt.GetType() == EVENT_INPUTENABLE*/ )
133 : {
134 0 : pView->SetModalMode( false );
135 0 : return true;
136 : }
137 :
138 19763 : return Window::Notify( rNEvt );
139 : }
140 :
141 35678 : bool SfxFrameWindow_Impl::PreNotify( NotifyEvent& rNEvt )
142 : {
143 35678 : sal_uInt16 nType = rNEvt.GetType();
144 35678 : if ( nType == EVENT_KEYINPUT || nType == EVENT_KEYUP )
145 : {
146 0 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
147 0 : SfxViewShell* pShell = pView ? pView->GetViewShell() : NULL;
148 0 : if ( pShell && pShell->HasKeyListeners_Impl() && pShell->HandleNotifyEvent_Impl( rNEvt ) )
149 0 : return true;
150 : }
151 35678 : else if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
152 : {
153 0 : vcl::Window* pWindow = rNEvt.GetWindow();
154 0 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
155 0 : SfxViewShell* pShell = pView ? pView->GetViewShell() : NULL;
156 0 : if ( pShell )
157 0 : if ( pWindow == pShell->GetWindow() || pShell->GetWindow()->IsChild( pWindow ) )
158 0 : if ( pShell->HasMouseClickListeners_Impl() && pShell->HandleNotifyEvent_Impl( rNEvt ) )
159 0 : return true;
160 : }
161 :
162 35678 : if ( nType == EVENT_MOUSEBUTTONDOWN )
163 : {
164 0 : vcl::Window* pWindow = rNEvt.GetWindow();
165 0 : const MouseEvent* pMEvent = rNEvt.GetMouseEvent();
166 0 : Point aPos = pWindow->OutputToScreenPixel( pMEvent->GetPosPixel() );
167 0 : SfxWorkWindow *pWorkWin = pFrame->GetWorkWindow_Impl();
168 0 : if ( pWorkWin )
169 0 : pWorkWin->EndAutoShow_Impl( aPos );
170 : }
171 :
172 35678 : return Window::PreNotify( rNEvt );
173 : }
174 :
175 9886 : void SfxFrameWindow_Impl::GetFocus()
176 : {
177 9886 : if ( pFrame && !pFrame->IsClosing_Impl() && pFrame->GetCurrentViewFrame() && pFrame->GetFrameInterface().is() )
178 4956 : pFrame->GetCurrentViewFrame()->MakeActive_Impl( true );
179 9886 : }
180 :
181 18375 : void SfxFrameWindow_Impl::Resize()
182 : {
183 18375 : if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
184 12867 : DoResize();
185 18375 : }
186 :
187 13146 : void SfxFrameWindow_Impl::StateChanged( StateChangedType nStateChange )
188 : {
189 13146 : if ( nStateChange == StateChangedType::INITSHOW )
190 : {
191 5442 : pFrame->pImp->bHidden = false;
192 5442 : if ( pFrame->IsInPlace() )
193 : // TODO/MBA: workaround for bug in LayoutManager: the final resize does not get through because the
194 : // LayoutManager works asynchronously and between resize and time execution the DockingAcceptor was exchanged so that
195 : // the resize event never is sent to the component
196 0 : SetSizePixel( GetParent()->GetOutputSizePixel() );
197 :
198 5442 : DoResize();
199 5442 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
200 5442 : if ( pView )
201 1658 : pView->GetBindings().GetWorkWindow_Impl()->ShowChildren_Impl();
202 : }
203 :
204 13146 : Window::StateChanged( nStateChange );
205 13146 : }
206 :
207 18309 : void SfxFrameWindow_Impl::DoResize()
208 : {
209 18309 : if ( !pFrame->pImp->bLockResize )
210 18309 : pFrame->Resize();
211 18309 : }
212 :
213 0 : Reference < XFrame > SfxFrame::CreateBlankFrame()
214 : {
215 0 : Reference < XFrame > xFrame;
216 : try
217 : {
218 0 : Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
219 0 : xFrame.set( xDesktop->findFrame( "_blank", 0 ), UNO_SET_THROW );
220 : }
221 0 : catch( const Exception& )
222 : {
223 : DBG_UNHANDLED_EXCEPTION();
224 : }
225 0 : return xFrame;
226 : }
227 :
228 0 : SfxFrame* SfxFrame::Create( SfxObjectShell& rDoc, vcl::Window& rWindow, sal_uInt16 nViewId, bool bHidden )
229 : {
230 0 : SfxFrame* pFrame = NULL;
231 : try
232 : {
233 : // create and initialize new top level frame for this window
234 0 : Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
235 0 : Reference < XDesktop2 > xDesktop = Desktop::create( xContext );
236 0 : Reference < XFrame2 > xFrame = Frame::create( xContext );
237 :
238 0 : Reference< awt::XWindow2 > xWin( VCLUnoHelper::GetInterface ( &rWindow ), uno::UNO_QUERY_THROW );
239 0 : xFrame->initialize( xWin.get() );
240 0 : xDesktop->getFrames()->append( xFrame );
241 :
242 0 : if ( xWin->isActive() )
243 0 : xFrame->activate();
244 :
245 : // create load arguments
246 0 : Sequence< PropertyValue > aLoadArgs;
247 0 : TransformItems( SID_OPENDOC, *rDoc.GetMedium()->GetItemSet(), aLoadArgs );
248 :
249 0 : ::comphelper::NamedValueCollection aArgs( aLoadArgs );
250 0 : aArgs.put( "Model", rDoc.GetModel() );
251 0 : aArgs.put( "Hidden", bHidden );
252 0 : if ( nViewId )
253 0 : aArgs.put( "ViewId", nViewId );
254 :
255 0 : aLoadArgs = aArgs.getPropertyValues();
256 :
257 : // load the doc into that frame
258 0 : OUString sLoaderURL( "private:object" );
259 0 : Reference< XComponentLoader > xLoader( xFrame, UNO_QUERY_THROW );
260 0 : xLoader->loadComponentFromURL(
261 : sLoaderURL,
262 : OUString( "_self" ),
263 : 0,
264 : aLoadArgs
265 0 : );
266 :
267 0 : for ( pFrame = SfxFrame::GetFirst();
268 : pFrame;
269 : pFrame = SfxFrame::GetNext( *pFrame )
270 : )
271 : {
272 0 : if ( pFrame->GetFrameInterface() == xFrame )
273 0 : break;
274 : }
275 :
276 0 : OSL_ENSURE( pFrame, "SfxFrame::Create: load succeeded, but no SfxFrame was created during this!" );
277 : }
278 0 : catch( const Exception& )
279 : {
280 : DBG_UNHANDLED_EXCEPTION();
281 : }
282 :
283 0 : return pFrame;
284 : }
285 :
286 5508 : SfxFrame* SfxFrame::Create( const Reference < XFrame >& i_rFrame )
287 : {
288 : // create a new TopFrame to an external XFrame object ( wrap controller )
289 5508 : ENSURE_OR_THROW( i_rFrame.is(), "NULL frame not allowed" );
290 5508 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( i_rFrame->getContainerWindow() );
291 5508 : ENSURE_OR_THROW( pWindow, "frame without container window not allowed" );
292 :
293 5508 : SfxFrame* pFrame = new SfxFrame( *pWindow, false );
294 5508 : pFrame->SetFrameInterface_Impl( i_rFrame );
295 5508 : return pFrame;
296 : }
297 :
298 5508 : SfxFrame::SfxFrame( vcl::Window& i_rContainerWindow, bool i_bHidden )
299 : :SvCompatWeakBase<SfxFrame>( this )
300 : ,pParentFrame( NULL )
301 : ,pChildArr( NULL )
302 : ,pImp( NULL )
303 5508 : ,pWindow( NULL )
304 : {
305 5508 : Construct_Impl();
306 :
307 5508 : pImp->bHidden = i_bHidden;
308 5508 : InsertTopFrame_Impl( this );
309 5508 : pImp->pExternalContainerWindow = &i_rContainerWindow;
310 :
311 5508 : pWindow = new SfxFrameWindow_Impl( this, i_rContainerWindow );
312 :
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.
317 5508 : pWindow->Show();
318 5508 : }
319 :
320 0 : void SfxFrame::SetPresentationMode( bool bSet )
321 : {
322 0 : if ( GetCurrentViewFrame() )
323 0 : GetCurrentViewFrame()->GetWindow().SetBorderStyle( bSet ? WindowBorderStyle::NOBORDER : WindowBorderStyle::NORMAL );
324 :
325 0 : Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
326 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
327 :
328 0 : if ( xPropSet.is() )
329 : {
330 0 : Any aValue = xPropSet->getPropertyValue("LayoutManager");
331 0 : aValue >>= xLayoutManager;
332 : }
333 :
334 0 : if ( xLayoutManager.is() )
335 0 : xLayoutManager->setVisible( !bSet ); // we don't want to have ui in presentation mode
336 :
337 0 : SetMenuBarOn_Impl( !bSet );
338 0 : if ( GetWorkWindow_Impl() )
339 0 : GetWorkWindow_Impl()->SetDockingAllowed( !bSet );
340 0 : if ( GetCurrentViewFrame() )
341 0 : GetCurrentViewFrame()->GetDispatcher()->Update_Impl( true );
342 0 : }
343 :
344 0 : SystemWindow* SfxFrame::GetSystemWindow() const
345 : {
346 0 : return GetTopWindow_Impl();
347 : }
348 :
349 36 : SystemWindow* SfxFrame::GetTopWindow_Impl() const
350 : {
351 36 : if ( pImp->pExternalContainerWindow->IsSystemWindow() )
352 36 : return static_cast<SystemWindow*>( pImp->pExternalContainerWindow );
353 : else
354 0 : return NULL;
355 : }
356 :
357 :
358 5506 : bool SfxFrame::Close()
359 : {
360 5506 : delete this;
361 5506 : return true;
362 : }
363 :
364 0 : void SfxFrame::LockResize_Impl( bool bLock )
365 : {
366 0 : pImp->bLockResize = bLock;
367 0 : }
368 :
369 0 : void SfxFrame::SetMenuBarOn_Impl( bool bOn )
370 : {
371 0 : pImp->bMenuBarOn = bOn;
372 :
373 0 : Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
374 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
375 :
376 0 : if ( xPropSet.is() )
377 : {
378 0 : Any aValue = xPropSet->getPropertyValue("LayoutManager");
379 0 : aValue >>= xLayoutManager;
380 : }
381 :
382 0 : if ( xLayoutManager.is() )
383 : {
384 0 : OUString aMenuBarURL( "private:resource/menubar/menubar" );
385 :
386 0 : if ( bOn )
387 0 : xLayoutManager->showElement( aMenuBarURL );
388 : else
389 0 : xLayoutManager->hideElement( aMenuBarURL );
390 0 : }
391 0 : }
392 :
393 17371 : bool SfxFrame::IsMenuBarOn_Impl() const
394 : {
395 17371 : return pImp->bMenuBarOn;
396 : }
397 :
398 5508 : void SfxFrame::PrepareForDoc_Impl( SfxObjectShell& i_rDoc )
399 : {
400 5508 : const ::comphelper::NamedValueCollection aDocumentArgs( i_rDoc.GetModel()->getArgs() );
401 :
402 : // hidden?
403 : OSL_ENSURE( !pImp->bHidden, "when does this happen?" );
404 5508 : pImp->bHidden = aDocumentArgs.getOrDefault( "Hidden", pImp->bHidden );
405 :
406 : // update our descriptor
407 5508 : UpdateDescriptor( &i_rDoc );
408 :
409 : // plugin mode
410 5508 : sal_Int16 nPluginMode = aDocumentArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
411 5508 : if ( nPluginMode && ( nPluginMode != 2 ) )
412 0 : SetInPlace_Impl( true );
413 5508 : }
414 :
415 5524 : bool SfxFrame::IsMarkedHidden_Impl() const
416 : {
417 5524 : return pImp->bHidden;
418 951 : }
419 :
420 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|