Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / misc / controllerframe.cxx
blobfae7d7555961b352d44c540bd542928c03b18de2
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/sdb/XOfficeDatabaseDocument.hpp>
24 #include <com/sun/star/awt/XTopWindow.hpp>
25 #include <com/sun/star/awt/XWindow2.hpp>
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
28 #include <com/sun/star/frame/XController2.hpp>
30 #include <cppuhelper/implbase1.hxx>
31 #include <rtl/ref.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include <vcl/window.hxx>
37 namespace dbaui
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::XInterface;
42 using ::com::sun::star::uno::UNO_QUERY;
43 using ::com::sun::star::uno::UNO_QUERY_THROW;
44 using ::com::sun::star::uno::UNO_SET_THROW;
45 using ::com::sun::star::uno::Exception;
46 using ::com::sun::star::uno::RuntimeException;
47 using ::com::sun::star::uno::Any;
48 using ::com::sun::star::uno::makeAny;
49 using ::com::sun::star::frame::XFrame;
50 using ::com::sun::star::frame::FrameAction;
51 using ::com::sun::star::frame::FrameAction_FRAME_ACTIVATED;
52 using ::com::sun::star::frame::FrameAction_FRAME_UI_ACTIVATED;
53 using ::com::sun::star::frame::FrameAction_FRAME_DEACTIVATING;
54 using ::com::sun::star::frame::FrameAction_FRAME_UI_DEACTIVATING;
55 using ::com::sun::star::frame::XModel;
56 using ::com::sun::star::frame::XController;
57 using ::com::sun::star::frame::XController2;
58 using ::com::sun::star::frame::XFramesSupplier;
59 using ::com::sun::star::sdb::XOfficeDatabaseDocument;
60 using ::com::sun::star::awt::XTopWindow;
61 using ::com::sun::star::awt::XTopWindowListener;
62 using ::com::sun::star::awt::XWindow2;
63 using ::com::sun::star::lang::DisposedException;
64 using ::com::sun::star::lang::EventObject;
65 using ::com::sun::star::document::XDocumentEventBroadcaster;
66 using ::com::sun::star::awt::XWindow;
68 // FrameWindowActivationListener
69 typedef ::cppu::WeakImplHelper1 < XTopWindowListener
70 > FrameWindowActivationListener_Base;
71 class FrameWindowActivationListener : public FrameWindowActivationListener_Base
73 public:
74 FrameWindowActivationListener( ControllerFrame_Data& _rData );
76 void dispose();
78 protected:
79 virtual ~FrameWindowActivationListener();
81 // XTopWindowListener
82 virtual void SAL_CALL windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
83 virtual void SAL_CALL windowClosing( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
84 virtual void SAL_CALL windowClosed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
85 virtual void SAL_CALL windowMinimized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
86 virtual void SAL_CALL windowNormalized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
87 virtual void SAL_CALL windowActivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
88 virtual void SAL_CALL windowDeactivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
90 // XEventListener
91 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
93 private:
94 void impl_checkDisposed_throw() const;
95 void impl_registerOnFrameContainerWindow_nothrow( bool _bRegister );
97 private:
98 ControllerFrame_Data* m_pData;
101 // ControllerFrame_Data
102 struct ControllerFrame_Data
104 ControllerFrame_Data( IController& _rController )
105 :m_rController( _rController )
106 ,m_xFrame()
107 ,m_xDocEventBroadcaster()
108 ,m_pListener()
109 ,m_bActive( false )
110 ,m_bIsTopLevelDocumentWindow( false )
114 IController& m_rController;
115 Reference< XFrame > m_xFrame;
116 Reference< XDocumentEventBroadcaster > m_xDocEventBroadcaster;
117 ::rtl::Reference< FrameWindowActivationListener > m_pListener;
118 bool m_bActive;
119 bool m_bIsTopLevelDocumentWindow;
122 // helper
123 static void lcl_setFrame_nothrow( ControllerFrame_Data& _rData, const Reference< XFrame >& _rxFrame )
125 // release old listener
126 if ( _rData.m_pListener.get() )
128 _rData.m_pListener->dispose();
129 _rData.m_pListener = NULL;
132 // remember new frame
133 _rData.m_xFrame = _rxFrame;
135 // create new listener
136 if ( _rData.m_xFrame.is() )
137 _rData.m_pListener = new FrameWindowActivationListener( _rData );
139 // at this point in time, we can assume the controller also has a model set, if it supports models
142 Reference< XController > xController( _rData.m_rController.getXController(), UNO_SET_THROW );
143 Reference< XModel > xModel( xController->getModel() );
144 if ( xModel.is() )
145 _rData.m_xDocEventBroadcaster.set( xModel, UNO_QUERY );
147 catch( const Exception& )
149 DBG_UNHANDLED_EXCEPTION();
153 static bool lcl_isActive_nothrow( const Reference< XFrame >& _rxFrame )
155 bool bIsActive = false;
158 if ( _rxFrame.is() )
160 Reference< XWindow2 > xWindow( _rxFrame->getContainerWindow(), UNO_QUERY_THROW );
161 bIsActive = xWindow->isActive();
165 catch( const Exception& )
167 DBG_UNHANDLED_EXCEPTION();
169 return bIsActive;
172 /** updates various global and local states with a new active component
174 In particular, the following are updated
175 * the global working document (aka Basic's ThisComponent in the application
176 Basic), with our controller's model, or the controller itself if there is no such
177 model.
179 static void lcl_updateActiveComponents_nothrow( const ControllerFrame_Data& _rData )
183 Reference< XController > xCompController( _rData.m_rController.getXController() );
184 OSL_ENSURE( xCompController.is(), "lcl_updateActiveComponents_nothrow: can't do anything without a controller!" );
185 if ( !xCompController.is() )
186 return;
188 if ( _rData.m_bActive && _rData.m_bIsTopLevelDocumentWindow )
190 // set the "current component" at the SfxObjectShell
191 Reference< XModel > xModel( xCompController->getModel() );
192 Reference< XInterface > xCurrentComponent;
193 if ( xModel.is() )
194 xCurrentComponent = xModel;
195 else
196 xCurrentComponent = xCompController;
197 SfxObjectShell::SetCurrentComponent( xCurrentComponent );
200 catch( const Exception& )
202 DBG_UNHANDLED_EXCEPTION();
206 /** broadcasts the OnFocus resp. OnUnfocus event
208 static void lcl_notifyFocusChange_nothrow( ControllerFrame_Data& _rData, bool _bActive )
212 if ( _rData.m_xDocEventBroadcaster.is() )
214 OUString sEventName = _bActive ? OUString("OnFocus") : OUString("OnUnfocus");
215 Reference< XController2 > xController( _rData.m_rController.getXController(), UNO_QUERY_THROW );
216 _rData.m_xDocEventBroadcaster->notifyDocumentEvent( sEventName, xController, Any() );
219 catch( const Exception& )
221 DBG_UNHANDLED_EXCEPTION();
225 static void lcl_updateActive_nothrow( ControllerFrame_Data& _rData, bool _bActive )
227 if ( _rData.m_bActive == _bActive )
228 return;
229 _rData.m_bActive = _bActive;
231 lcl_updateActiveComponents_nothrow( _rData );
232 lcl_notifyFocusChange_nothrow( _rData, _bActive );
235 FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data& _rData )
236 :m_pData( &_rData )
238 impl_registerOnFrameContainerWindow_nothrow( true );
241 FrameWindowActivationListener::~FrameWindowActivationListener()
245 void FrameWindowActivationListener::dispose()
247 impl_registerOnFrameContainerWindow_nothrow( false );
248 m_pData = NULL;
251 void FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow( bool _bRegister )
253 OSL_ENSURE( m_pData && m_pData->m_xFrame.is(), "FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow: no frame!" );
254 if ( !m_pData || !m_pData->m_xFrame.is() )
255 return;
259 void ( SAL_CALL XTopWindow::*pListenerAction )( const Reference< XTopWindowListener >& ) =
260 _bRegister ? &XTopWindow::addTopWindowListener : &XTopWindow::removeTopWindowListener;
262 const Reference< XWindow > xContainerWindow( m_pData->m_xFrame->getContainerWindow(), UNO_SET_THROW );
263 if ( _bRegister )
265 const vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
266 ENSURE_OR_THROW( pContainerWindow, "no Window implementation for the frame's container window!" );
268 m_pData->m_bIsTopLevelDocumentWindow = ( pContainerWindow->GetExtendedStyle() & WB_EXT_DOCUMENT ) != 0;
271 const Reference< XTopWindow > xFrameContainer( xContainerWindow, UNO_QUERY );
272 if ( xFrameContainer.is() )
273 (xFrameContainer.get()->*pListenerAction)( this );
275 catch( const Exception& )
277 DBG_UNHANDLED_EXCEPTION();
281 void FrameWindowActivationListener::impl_checkDisposed_throw() const
283 if ( !m_pData )
284 throw DisposedException( OUString(), *const_cast< FrameWindowActivationListener* >( this ) );
287 void SAL_CALL FrameWindowActivationListener::windowOpened( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
289 // not interested in
292 void SAL_CALL FrameWindowActivationListener::windowClosing( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
294 // not interested in
297 void SAL_CALL FrameWindowActivationListener::windowClosed( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
299 // not interested in
302 void SAL_CALL FrameWindowActivationListener::windowMinimized( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
304 // not interested in
307 void SAL_CALL FrameWindowActivationListener::windowNormalized( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
309 // not interested in
312 void SAL_CALL FrameWindowActivationListener::windowActivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
314 impl_checkDisposed_throw();
315 lcl_updateActive_nothrow( *m_pData, true );
318 void SAL_CALL FrameWindowActivationListener::windowDeactivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
320 impl_checkDisposed_throw();
321 lcl_updateActive_nothrow( *m_pData, false );
324 void SAL_CALL FrameWindowActivationListener::disposing( const EventObject& /*_rEvent*/ ) throw (RuntimeException, std::exception)
326 dispose();
329 // ControllerFrame
330 ControllerFrame::ControllerFrame( IController& _rController )
331 :m_pData( new ControllerFrame_Data( _rController ) )
335 ControllerFrame::~ControllerFrame()
339 const Reference< XFrame >& ControllerFrame::attachFrame( const Reference< XFrame >& _rxFrame )
341 // set new frame, including listener handling
342 lcl_setFrame_nothrow( *m_pData, _rxFrame );
344 // determine whether we're active
345 m_pData->m_bActive = lcl_isActive_nothrow( m_pData->m_xFrame );
347 // update active component
348 if ( m_pData->m_bActive )
350 lcl_updateActiveComponents_nothrow( *m_pData );
351 lcl_notifyFocusChange_nothrow( *m_pData, true );
354 return m_pData->m_xFrame;
357 const Reference< XFrame >& ControllerFrame::getFrame() const
359 return m_pData->m_xFrame;
362 bool ControllerFrame::isActive() const
364 return m_pData->m_bActive;
367 void ControllerFrame::frameAction( FrameAction _eAction )
369 bool bActive = m_pData->m_bActive;
371 switch ( _eAction )
373 case FrameAction_FRAME_ACTIVATED:
374 case FrameAction_FRAME_UI_ACTIVATED:
375 bActive = true;
376 break;
378 case FrameAction_FRAME_DEACTIVATING:
379 case FrameAction_FRAME_UI_DEACTIVATING:
380 bActive = false;
381 break;
383 default:
384 break;
387 lcl_updateActive_nothrow( *m_pData, bActive );
390 } // namespace dbaui
392 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */