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 Window
66 : {
67 : public:
68 : SfxFrame* pFrame;
69 :
70 : SfxFrameWindow_Impl( SfxFrame* pF, 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 0 : SfxFrameWindow_Impl::SfxFrameWindow_Impl( SfxFrame* pF, Window& i_rContainerWindow )
83 : : Window( &i_rContainerWindow, WB_BORDER | WB_CLIPCHILDREN | WB_NODIALOGCONTROL | WB_3DLOOK )
84 0 : , pFrame( pF )
85 : {
86 0 : }
87 :
88 0 : SfxFrameWindow_Impl::~SfxFrameWindow_Impl( )
89 : {
90 0 : }
91 :
92 0 : void SfxFrameWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
93 : {
94 0 : Window::DataChanged( rDCEvt );
95 0 : SfxWorkWindow *pWorkWin = pFrame->GetWorkWindow_Impl();
96 0 : if ( pWorkWin )
97 0 : pWorkWin->DataChanged_Impl( rDCEvt );
98 0 : }
99 :
100 0 : bool SfxFrameWindow_Impl::Notify( NotifyEvent& rNEvt )
101 : {
102 0 : if ( pFrame->IsClosing_Impl() || !pFrame->GetFrameInterface().is() )
103 0 : return false;
104 :
105 0 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
106 0 : if ( !pView || !pView->GetObjectShell() )
107 0 : return Window::Notify( rNEvt );
108 :
109 0 : if ( rNEvt.GetType() == EVENT_GETFOCUS )
110 : {
111 0 : if ( pView->GetViewShell() && !pView->GetViewShell()->GetUIActiveIPClient_Impl() && !pFrame->IsInPlace() )
112 : {
113 : OSL_TRACE("SfxFrame: GotFocus");
114 0 : pView->MakeActive_Impl( false );
115 : }
116 :
117 : // if focus was on an external window, the clipboard content might have been changed
118 0 : pView->GetBindings().Invalidate( SID_PASTE );
119 0 : pView->GetBindings().Invalidate( SID_PASTE_SPECIAL );
120 0 : return true;
121 : }
122 0 : else if( rNEvt.GetType() == EVENT_KEYINPUT )
123 : {
124 0 : if ( pView->GetViewShell()->KeyInput( *rNEvt.GetKeyEvent() ) )
125 0 : return true;
126 : }
127 0 : else if ( rNEvt.GetType() == EVENT_EXECUTEDIALOG /*|| rNEvt.GetType() == EVENT_INPUTDISABLE*/ )
128 : {
129 0 : pView->SetModalMode( true );
130 0 : return true;
131 : }
132 0 : else if ( rNEvt.GetType() == EVENT_ENDEXECUTEDIALOG /*|| rNEvt.GetType() == EVENT_INPUTENABLE*/ )
133 : {
134 0 : pView->SetModalMode( false );
135 0 : return true;
136 : }
137 :
138 0 : return Window::Notify( rNEvt );
139 : }
140 :
141 0 : bool SfxFrameWindow_Impl::PreNotify( NotifyEvent& rNEvt )
142 : {
143 0 : sal_uInt16 nType = rNEvt.GetType();
144 0 : 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 0 : else if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
152 : {
153 0 : 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 0 : if ( nType == EVENT_MOUSEBUTTONDOWN )
163 : {
164 0 : 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 0 : return Window::PreNotify( rNEvt );
173 : }
174 :
175 0 : void SfxFrameWindow_Impl::GetFocus()
176 : {
177 0 : if ( pFrame && !pFrame->IsClosing_Impl() && pFrame->GetCurrentViewFrame() && pFrame->GetFrameInterface().is() )
178 0 : pFrame->GetCurrentViewFrame()->MakeActive_Impl( true );
179 0 : }
180 :
181 0 : void SfxFrameWindow_Impl::Resize()
182 : {
183 0 : if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
184 0 : DoResize();
185 0 : }
186 :
187 0 : void SfxFrameWindow_Impl::StateChanged( StateChangedType nStateChange )
188 : {
189 0 : if ( nStateChange == STATE_CHANGE_INITSHOW )
190 : {
191 0 : pFrame->pImp->bHidden = false;
192 0 : 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 0 : DoResize();
199 0 : SfxViewFrame* pView = pFrame->GetCurrentViewFrame();
200 0 : if ( pView )
201 0 : pView->GetBindings().GetWorkWindow_Impl()->ShowChildren_Impl();
202 : }
203 :
204 0 : Window::StateChanged( nStateChange );
205 0 : }
206 :
207 0 : void SfxFrameWindow_Impl::DoResize()
208 : {
209 0 : if ( !pFrame->pImp->bLockResize )
210 0 : pFrame->Resize();
211 0 : }
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, 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 0 : SfxFrame* SfxFrame::Create( const Reference < XFrame >& i_rFrame )
287 : {
288 : // create a new TopFrame to an external XFrame object ( wrap controller )
289 0 : ENSURE_OR_THROW( i_rFrame.is(), "NULL frame not allowed" );
290 0 : Window* pWindow = VCLUnoHelper::GetWindow( i_rFrame->getContainerWindow() );
291 0 : ENSURE_OR_THROW( pWindow, "frame without container window not allowed" );
292 :
293 0 : SfxFrame* pFrame = new SfxFrame( *pWindow, false );
294 0 : pFrame->SetFrameInterface_Impl( i_rFrame );
295 0 : return pFrame;
296 : }
297 :
298 0 : SfxFrame::SfxFrame( Window& i_rContainerWindow, bool i_bHidden )
299 : :pParentFrame( NULL )
300 : ,pChildArr( NULL )
301 : ,pImp( NULL )
302 0 : ,pWindow( NULL )
303 : {
304 0 : Construct_Impl();
305 :
306 0 : pImp->bHidden = i_bHidden;
307 0 : InsertTopFrame_Impl( this );
308 0 : pImp->pExternalContainerWindow = &i_rContainerWindow;
309 :
310 0 : pWindow = new SfxFrameWindow_Impl( this, i_rContainerWindow );
311 :
312 : // always show pWindow, which is the ComponentWindow of the XFrame we live in
313 : // nowadays, since SfxFrames can be created with an XFrame only, hiding or showing the complete XFrame
314 : // is not done at level of the container window, not at SFX level. Thus, the component window can
315 : // always be visible.
316 0 : pWindow->Show();
317 0 : }
318 :
319 0 : void SfxFrame::SetPresentationMode( bool bSet )
320 : {
321 0 : if ( GetCurrentViewFrame() )
322 0 : GetCurrentViewFrame()->GetWindow().SetBorderStyle( bSet ? WINDOW_BORDER_NOBORDER : WINDOW_BORDER_NORMAL );
323 :
324 0 : Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
325 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
326 :
327 0 : if ( xPropSet.is() )
328 : {
329 0 : Any aValue = xPropSet->getPropertyValue("LayoutManager");
330 0 : aValue >>= xLayoutManager;
331 : }
332 :
333 0 : if ( xLayoutManager.is() )
334 0 : xLayoutManager->setVisible( !bSet ); // we don't want to have ui in presentation mode
335 :
336 0 : SetMenuBarOn_Impl( !bSet );
337 0 : if ( GetWorkWindow_Impl() )
338 0 : GetWorkWindow_Impl()->SetDockingAllowed( !bSet );
339 0 : if ( GetCurrentViewFrame() )
340 0 : GetCurrentViewFrame()->GetDispatcher()->Update_Impl( true );
341 0 : }
342 :
343 0 : SystemWindow* SfxFrame::GetSystemWindow() const
344 : {
345 0 : return GetTopWindow_Impl();
346 : }
347 :
348 0 : SystemWindow* SfxFrame::GetTopWindow_Impl() const
349 : {
350 0 : if ( pImp->pExternalContainerWindow->IsSystemWindow() )
351 0 : return (SystemWindow*) pImp->pExternalContainerWindow;
352 : else
353 0 : return NULL;
354 : }
355 :
356 0 : Window& SfxFrame::GetWindow() const
357 : {
358 0 : return *pWindow;
359 : }
360 :
361 0 : bool SfxFrame::Close()
362 : {
363 0 : delete this;
364 0 : return true;
365 : }
366 :
367 0 : void SfxFrame::LockResize_Impl( bool bLock )
368 : {
369 0 : pImp->bLockResize = bLock;
370 0 : }
371 :
372 0 : void SfxFrame::SetMenuBarOn_Impl( bool bOn )
373 : {
374 0 : pImp->bMenuBarOn = bOn;
375 :
376 0 : Reference< com::sun::star::beans::XPropertySet > xPropSet( GetFrameInterface(), UNO_QUERY );
377 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
378 :
379 0 : if ( xPropSet.is() )
380 : {
381 0 : Any aValue = xPropSet->getPropertyValue("LayoutManager");
382 0 : aValue >>= xLayoutManager;
383 : }
384 :
385 0 : if ( xLayoutManager.is() )
386 : {
387 0 : OUString aMenuBarURL( "private:resource/menubar/menubar" );
388 :
389 0 : if ( bOn )
390 0 : xLayoutManager->showElement( aMenuBarURL );
391 : else
392 0 : xLayoutManager->hideElement( aMenuBarURL );
393 0 : }
394 0 : }
395 :
396 0 : bool SfxFrame::IsMenuBarOn_Impl() const
397 : {
398 0 : return pImp->bMenuBarOn;
399 : }
400 :
401 0 : void SfxFrame::PrepareForDoc_Impl( SfxObjectShell& i_rDoc )
402 : {
403 0 : const ::comphelper::NamedValueCollection aDocumentArgs( i_rDoc.GetModel()->getArgs() );
404 :
405 : // hidden?
406 : OSL_ENSURE( !pImp->bHidden, "when does this happen?" );
407 0 : pImp->bHidden = aDocumentArgs.getOrDefault( "Hidden", pImp->bHidden );
408 :
409 : // update our descriptor
410 0 : UpdateDescriptor( &i_rDoc );
411 :
412 : // plugin mode
413 0 : sal_Int16 nPluginMode = aDocumentArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) );
414 0 : if ( nPluginMode && ( nPluginMode != 2 ) )
415 0 : SetInPlace_Impl( true );
416 0 : }
417 :
418 0 : bool SfxFrame::IsMarkedHidden_Impl() const
419 : {
420 0 : return pImp->bHidden;
421 : }
422 :
423 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|