Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / dbaccess / source / ui / misc / controllerframe.cxx
bloba69e3abace30bf0c65a51cec62ea5fc97c94d216
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 .
20 #include <dbaccess/controllerframe.hxx>
21 #include <dbaccess/IController.hxx>
23 #include <com/sun/star/awt/XTopWindow.hpp>
24 #include <com/sun/star/awt/XWindow2.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
27 #include <com/sun/star/frame/XController2.hpp>
29 #include <cppuhelper/implbase.hxx>
30 #include <rtl/ref.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <toolkit/helper/vclunohelper.hxx>
34 #include <vcl/window.hxx>
36 namespace dbaui
39 using ::com::sun::star::uno::Reference;
40 using ::com::sun::star::uno::XInterface;
41 using ::com::sun::star::uno::UNO_QUERY;
42 using ::com::sun::star::uno::UNO_QUERY_THROW;
43 using ::com::sun::star::uno::UNO_SET_THROW;
44 using ::com::sun::star::uno::Exception;
45 using ::com::sun::star::uno::RuntimeException;
46 using ::com::sun::star::uno::Any;
47 using ::com::sun::star::frame::XFrame;
48 using ::com::sun::star::frame::FrameAction;
49 using ::com::sun::star::frame::FrameAction_FRAME_ACTIVATED;
50 using ::com::sun::star::frame::FrameAction_FRAME_UI_ACTIVATED;
51 using ::com::sun::star::frame::FrameAction_FRAME_DEACTIVATING;
52 using ::com::sun::star::frame::FrameAction_FRAME_UI_DEACTIVATING;
53 using ::com::sun::star::frame::XModel;
54 using ::com::sun::star::frame::XController;
55 using ::com::sun::star::frame::XController2;
56 using ::com::sun::star::awt::XTopWindow;
57 using ::com::sun::star::awt::XTopWindowListener;
58 using ::com::sun::star::awt::XWindow2;
59 using ::com::sun::star::lang::DisposedException;
60 using ::com::sun::star::lang::EventObject;
61 using ::com::sun::star::document::XDocumentEventBroadcaster;
62 using ::com::sun::star::awt::XWindow;
64 // FrameWindowActivationListener
65 typedef ::cppu::WeakImplHelper< XTopWindowListener
66 > FrameWindowActivationListener_Base;
67 class FrameWindowActivationListener : public FrameWindowActivationListener_Base
69 public:
70 explicit FrameWindowActivationListener( ControllerFrame_Data& _rData );
72 void dispose();
74 protected:
75 virtual ~FrameWindowActivationListener();
77 // XTopWindowListener
78 virtual void SAL_CALL windowOpened( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
79 virtual void SAL_CALL windowClosing( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
80 virtual void SAL_CALL windowClosed( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
81 virtual void SAL_CALL windowMinimized( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
82 virtual void SAL_CALL windowNormalized( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
83 virtual void SAL_CALL windowActivated( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
84 virtual void SAL_CALL windowDeactivated( const css::lang::EventObject& e ) throw (css::uno::RuntimeException, std::exception) override;
86 // XEventListener
87 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) throw (css::uno::RuntimeException, std::exception) override;
89 private:
90 void impl_checkDisposed_throw() const;
91 void impl_registerOnFrameContainerWindow_nothrow( bool _bRegister );
93 private:
94 ControllerFrame_Data* m_pData;
97 // ControllerFrame_Data
98 struct ControllerFrame_Data
100 explicit ControllerFrame_Data( IController& _rController )
101 :m_rController( _rController )
102 ,m_xFrame()
103 ,m_xDocEventBroadcaster()
104 ,m_pListener()
105 ,m_bActive( false )
106 ,m_bIsTopLevelDocumentWindow( false )
110 IController& m_rController;
111 Reference< XFrame > m_xFrame;
112 Reference< XDocumentEventBroadcaster > m_xDocEventBroadcaster;
113 ::rtl::Reference< FrameWindowActivationListener > m_pListener;
114 bool m_bActive;
115 bool m_bIsTopLevelDocumentWindow;
118 // helper
119 static void lcl_setFrame_nothrow( ControllerFrame_Data& _rData, const Reference< XFrame >& _rxFrame )
121 // release old listener
122 if ( _rData.m_pListener.get() )
124 _rData.m_pListener->dispose();
125 _rData.m_pListener = nullptr;
128 // remember new frame
129 _rData.m_xFrame = _rxFrame;
131 // create new listener
132 if ( _rData.m_xFrame.is() )
133 _rData.m_pListener = new FrameWindowActivationListener( _rData );
135 // at this point in time, we can assume the controller also has a model set, if it supports models
138 Reference< XController > xController( _rData.m_rController.getXController(), UNO_SET_THROW );
139 Reference< XModel > xModel( xController->getModel() );
140 if ( xModel.is() )
141 _rData.m_xDocEventBroadcaster.set( xModel, UNO_QUERY );
143 catch( const Exception& )
145 DBG_UNHANDLED_EXCEPTION();
149 static bool lcl_isActive_nothrow( const Reference< XFrame >& _rxFrame )
151 bool bIsActive = false;
154 if ( _rxFrame.is() )
156 Reference< XWindow2 > xWindow( _rxFrame->getContainerWindow(), UNO_QUERY_THROW );
157 bIsActive = xWindow->isActive();
161 catch( const Exception& )
163 DBG_UNHANDLED_EXCEPTION();
165 return bIsActive;
168 /** updates various global and local states with a new active component
170 In particular, the following are updated
171 * the global working document (aka Basic's ThisComponent in the application
172 Basic), with our controller's model, or the controller itself if there is no such
173 model.
175 static void lcl_updateActiveComponents_nothrow( const ControllerFrame_Data& _rData )
179 Reference< XController > xCompController( _rData.m_rController.getXController() );
180 OSL_ENSURE( xCompController.is(), "lcl_updateActiveComponents_nothrow: can't do anything without a controller!" );
181 if ( !xCompController.is() )
182 return;
184 if ( _rData.m_bActive && _rData.m_bIsTopLevelDocumentWindow )
186 // set the "current component" at the SfxObjectShell
187 Reference< XModel > xModel( xCompController->getModel() );
188 Reference< XInterface > xCurrentComponent;
189 if ( xModel.is() )
190 xCurrentComponent = xModel;
191 else
192 xCurrentComponent = xCompController;
193 SfxObjectShell::SetCurrentComponent( xCurrentComponent );
196 catch( const Exception& )
198 DBG_UNHANDLED_EXCEPTION();
202 /** broadcasts the OnFocus resp. OnUnfocus event
204 static void lcl_notifyFocusChange_nothrow( ControllerFrame_Data& _rData, bool _bActive )
208 if ( _rData.m_xDocEventBroadcaster.is() )
210 OUString sEventName = _bActive ? OUString("OnFocus") : OUString("OnUnfocus");
211 Reference< XController2 > xController( _rData.m_rController.getXController(), UNO_QUERY_THROW );
212 _rData.m_xDocEventBroadcaster->notifyDocumentEvent( sEventName, xController, Any() );
215 catch( const Exception& )
217 DBG_UNHANDLED_EXCEPTION();
221 static void lcl_updateActive_nothrow( ControllerFrame_Data& _rData, bool _bActive )
223 if ( _rData.m_bActive == _bActive )
224 return;
225 _rData.m_bActive = _bActive;
227 lcl_updateActiveComponents_nothrow( _rData );
228 lcl_notifyFocusChange_nothrow( _rData, _bActive );
231 FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data& _rData )
232 :m_pData( &_rData )
234 impl_registerOnFrameContainerWindow_nothrow( true );
237 FrameWindowActivationListener::~FrameWindowActivationListener()
241 void FrameWindowActivationListener::dispose()
243 impl_registerOnFrameContainerWindow_nothrow( false );
244 m_pData = nullptr;
247 void FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow( bool _bRegister )
249 OSL_ENSURE( m_pData && m_pData->m_xFrame.is(), "FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow: no frame!" );
250 if ( !m_pData || !m_pData->m_xFrame.is() )
251 return;
255 void ( SAL_CALL XTopWindow::*pListenerAction )( const Reference< XTopWindowListener >& ) =
256 _bRegister ? &XTopWindow::addTopWindowListener : &XTopWindow::removeTopWindowListener;
258 const Reference< XWindow > xContainerWindow( m_pData->m_xFrame->getContainerWindow(), UNO_SET_THROW );
259 if ( _bRegister )
261 const vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
262 ENSURE_OR_THROW( pContainerWindow, "no Window implementation for the frame's container window!" );
264 m_pData->m_bIsTopLevelDocumentWindow = ( pContainerWindow->GetExtendedStyle() & WB_EXT_DOCUMENT ) != 0;
267 const Reference< XTopWindow > xFrameContainer( xContainerWindow, UNO_QUERY );
268 if ( xFrameContainer.is() )
269 (xFrameContainer.get()->*pListenerAction)( this );
271 catch( const Exception& )
273 DBG_UNHANDLED_EXCEPTION();
277 void FrameWindowActivationListener::impl_checkDisposed_throw() const
279 if ( !m_pData )
280 throw DisposedException( OUString(), *const_cast< FrameWindowActivationListener* >( this ) );
283 void SAL_CALL FrameWindowActivationListener::windowOpened( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
285 // not interested in
288 void SAL_CALL FrameWindowActivationListener::windowClosing( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
290 // not interested in
293 void SAL_CALL FrameWindowActivationListener::windowClosed( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
295 // not interested in
298 void SAL_CALL FrameWindowActivationListener::windowMinimized( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
300 // not interested in
303 void SAL_CALL FrameWindowActivationListener::windowNormalized( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
305 // not interested in
308 void SAL_CALL FrameWindowActivationListener::windowActivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
310 impl_checkDisposed_throw();
311 lcl_updateActive_nothrow( *m_pData, true );
314 void SAL_CALL FrameWindowActivationListener::windowDeactivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
316 impl_checkDisposed_throw();
317 lcl_updateActive_nothrow( *m_pData, false );
320 void SAL_CALL FrameWindowActivationListener::disposing( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
322 dispose();
325 // ControllerFrame
326 ControllerFrame::ControllerFrame( IController& _rController )
327 :m_pData( new ControllerFrame_Data( _rController ) )
331 ControllerFrame::~ControllerFrame()
335 const Reference< XFrame >& ControllerFrame::attachFrame( const Reference< XFrame >& _rxFrame )
337 // set new frame, including listener handling
338 lcl_setFrame_nothrow( *m_pData, _rxFrame );
340 // determine whether we're active
341 m_pData->m_bActive = lcl_isActive_nothrow( m_pData->m_xFrame );
343 // update active component
344 if ( m_pData->m_bActive )
346 lcl_updateActiveComponents_nothrow( *m_pData );
347 lcl_notifyFocusChange_nothrow( *m_pData, true );
350 return m_pData->m_xFrame;
353 const Reference< XFrame >& ControllerFrame::getFrame() const
355 return m_pData->m_xFrame;
358 bool ControllerFrame::isActive() const
360 return m_pData->m_bActive;
363 void ControllerFrame::frameAction( FrameAction _eAction )
365 bool bActive = m_pData->m_bActive;
367 switch ( _eAction )
369 case FrameAction_FRAME_ACTIVATED:
370 case FrameAction_FRAME_UI_ACTIVATED:
371 bActive = true;
372 break;
374 case FrameAction_FRAME_DEACTIVATING:
375 case FrameAction_FRAME_UI_DEACTIVATING:
376 bActive = false;
377 break;
379 default:
380 break;
383 lcl_updateActive_nothrow( *m_pData, bActive );
386 } // namespace dbaui
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */