Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / dbaccess / source / ui / misc / controllerframe.cxx
blob54d612329400fcd71ce00c1e6805bef615d279ff
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "controllerframe.hxx"
30 #include "IController.hxx"
32 /** === begin UNO includes === **/
33 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
34 #include <com/sun/star/awt/XTopWindow.hpp>
35 #include <com/sun/star/awt/XWindow2.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
38 #include <com/sun/star/frame/XController2.hpp>
39 /** === end UNO includes === **/
41 #include <cppuhelper/implbase1.hxx>
42 #include <rtl/ref.hxx>
43 #include <sfx2/objsh.hxx>
44 #include <tools/diagnose_ex.h>
45 #include <toolkit/helper/vclunohelper.hxx>
46 #include <vcl/window.hxx>
48 //........................................................................
49 namespace dbaui
51 //........................................................................
53 /** === begin UNO using === **/
54 using ::com::sun::star::uno::Reference;
55 using ::com::sun::star::uno::XInterface;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::uno::UNO_QUERY_THROW;
58 using ::com::sun::star::uno::UNO_SET_THROW;
59 using ::com::sun::star::uno::Exception;
60 using ::com::sun::star::uno::RuntimeException;
61 using ::com::sun::star::uno::Any;
62 using ::com::sun::star::uno::makeAny;
63 using ::com::sun::star::frame::XFrame;
64 using ::com::sun::star::frame::FrameAction;
65 using ::com::sun::star::frame::FrameAction_FRAME_ACTIVATED;
66 using ::com::sun::star::frame::FrameAction_FRAME_UI_ACTIVATED;
67 using ::com::sun::star::frame::FrameAction_FRAME_DEACTIVATING;
68 using ::com::sun::star::frame::FrameAction_FRAME_UI_DEACTIVATING;
69 using ::com::sun::star::frame::XModel;
70 using ::com::sun::star::frame::XController;
71 using ::com::sun::star::frame::XController2;
72 using ::com::sun::star::frame::XFramesSupplier;
73 using ::com::sun::star::sdb::XOfficeDatabaseDocument;
74 using ::com::sun::star::awt::XTopWindow;
75 using ::com::sun::star::awt::XTopWindowListener;
76 using ::com::sun::star::awt::XWindow2;
77 using ::com::sun::star::lang::DisposedException;
78 using ::com::sun::star::lang::EventObject;
79 using ::com::sun::star::document::XDocumentEventBroadcaster;
80 using ::com::sun::star::awt::XWindow;
81 /** === end UNO using === **/
83 //====================================================================
84 //= FrameWindowActivationListener
85 //====================================================================
86 typedef ::cppu::WeakImplHelper1 < XTopWindowListener
87 > FrameWindowActivationListener_Base;
88 class FrameWindowActivationListener : public FrameWindowActivationListener_Base
90 public:
91 FrameWindowActivationListener( ControllerFrame_Data& _rData );
93 void dispose();
95 protected:
96 ~FrameWindowActivationListener();
98 // XTopWindowListener
99 virtual void SAL_CALL windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
100 virtual void SAL_CALL windowClosing( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
101 virtual void SAL_CALL windowClosed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
102 virtual void SAL_CALL windowMinimized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
103 virtual void SAL_CALL windowNormalized( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
104 virtual void SAL_CALL windowActivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
105 virtual void SAL_CALL windowDeactivated( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
107 // XEventListener
108 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
110 private:
111 void impl_checkDisposed_throw() const;
112 void impl_registerOnFrameContainerWindow_nothrow( bool _bRegister );
114 private:
115 ControllerFrame_Data* m_pData;
118 //====================================================================
119 //= ControllerFrame_Data
120 //====================================================================
121 struct ControllerFrame_Data
123 ControllerFrame_Data( IController& _rController )
124 :m_rController( _rController )
125 ,m_xFrame()
126 ,m_xDocEventBroadcaster()
127 ,m_pListener()
128 ,m_bActive( false )
129 ,m_bIsTopLevelDocumentWindow( false )
133 IController& m_rController;
134 Reference< XFrame > m_xFrame;
135 Reference< XDocumentEventBroadcaster > m_xDocEventBroadcaster;
136 ::rtl::Reference< FrameWindowActivationListener > m_pListener;
137 bool m_bActive;
138 bool m_bIsTopLevelDocumentWindow;
141 //====================================================================
142 //= helper
143 //====================================================================
144 //--------------------------------------------------------------------
145 static void lcl_setFrame_nothrow( ControllerFrame_Data& _rData, const Reference< XFrame >& _rxFrame )
147 // release old listener
148 if ( _rData.m_pListener.get() )
150 _rData.m_pListener->dispose();
151 _rData.m_pListener = NULL;
154 // remember new frame
155 _rData.m_xFrame = _rxFrame;
157 // create new listener
158 if ( _rData.m_xFrame.is() )
159 _rData.m_pListener = new FrameWindowActivationListener( _rData );
161 // at this point in time, we can assume the controller also has a model set, if it supports models
164 Reference< XController > xController( _rData.m_rController.getXController(), UNO_SET_THROW );
165 Reference< XModel > xModel( xController->getModel() );
166 if ( xModel.is() )
167 _rData.m_xDocEventBroadcaster.set( xModel, UNO_QUERY );
169 catch( const Exception& )
171 DBG_UNHANDLED_EXCEPTION();
175 //--------------------------------------------------------------------
176 static bool lcl_isActive_nothrow( const Reference< XFrame >& _rxFrame )
178 bool bIsActive = false;
181 if ( _rxFrame.is() )
183 Reference< XWindow2 > xWindow( _rxFrame->getContainerWindow(), UNO_QUERY_THROW );
184 bIsActive = xWindow->isActive();
188 catch( const Exception& )
190 DBG_UNHANDLED_EXCEPTION();
192 return bIsActive;
195 //--------------------------------------------------------------------
196 /** updates various global and local states with a new active component
198 In particular, the following are updated
199 * the global working document (aka Basic's ThisComponent in the application
200 Basic), with our controller's model, or the controller itself if there is no such
201 model.
203 static void lcl_updateActiveComponents_nothrow( const ControllerFrame_Data& _rData )
207 Reference< XController > xCompController( _rData.m_rController.getXController() );
208 OSL_ENSURE( xCompController.is(), "lcl_updateActiveComponents_nothrow: can't do anything without a controller!" );
209 if ( !xCompController.is() )
210 return;
212 if ( _rData.m_bActive && _rData.m_bIsTopLevelDocumentWindow )
214 // set the "current component" at the SfxObjectShell
215 Reference< XModel > xModel( xCompController->getModel() );
216 Reference< XInterface > xCurrentComponent;
217 if ( xModel.is() )
218 xCurrentComponent = xModel;
219 else
220 xCurrentComponent = xCompController;
221 SfxObjectShell::SetCurrentComponent( xCurrentComponent );
224 catch( const Exception& )
226 DBG_UNHANDLED_EXCEPTION();
230 //--------------------------------------------------------------------
231 /** broadcasts the OnFocus resp. OnUnfocus event
233 static void lcl_notifyFocusChange_nothrow( ControllerFrame_Data& _rData, bool _bActive )
237 if ( _rData.m_xDocEventBroadcaster.is() )
239 ::rtl::OUString sEventName = _bActive ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnFocus")) : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnUnfocus"));
240 Reference< XController2 > xController( _rData.m_rController.getXController(), UNO_QUERY_THROW );
241 _rData.m_xDocEventBroadcaster->notifyDocumentEvent( sEventName, xController, Any() );
244 catch( const Exception& )
246 DBG_UNHANDLED_EXCEPTION();
250 //--------------------------------------------------------------------
251 static void lcl_updateActive_nothrow( ControllerFrame_Data& _rData, bool _bActive )
253 if ( _rData.m_bActive == _bActive )
254 return;
255 _rData.m_bActive = _bActive;
257 lcl_updateActiveComponents_nothrow( _rData );
258 lcl_notifyFocusChange_nothrow( _rData, _bActive );
261 //--------------------------------------------------------------------
262 FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data& _rData )
263 :m_pData( &_rData )
265 impl_registerOnFrameContainerWindow_nothrow( true );
268 //--------------------------------------------------------------------
269 FrameWindowActivationListener::~FrameWindowActivationListener()
273 //--------------------------------------------------------------------
274 void FrameWindowActivationListener::dispose()
276 impl_registerOnFrameContainerWindow_nothrow( false );
277 m_pData = NULL;
280 //--------------------------------------------------------------------
281 void FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow( bool _bRegister )
283 OSL_ENSURE( m_pData && m_pData->m_xFrame.is(), "FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow: no frame!" );
284 if ( !m_pData || !m_pData->m_xFrame.is() )
285 return;
289 void ( SAL_CALL XTopWindow::*pListenerAction )( const Reference< XTopWindowListener >& ) =
290 _bRegister ? &XTopWindow::addTopWindowListener : &XTopWindow::removeTopWindowListener;
292 const Reference< XWindow > xContainerWindow( m_pData->m_xFrame->getContainerWindow(), UNO_SET_THROW );
293 if ( _bRegister )
295 const Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
296 ENSURE_OR_THROW( pContainerWindow, "no Window implementation for the frame's container window!" );
298 m_pData->m_bIsTopLevelDocumentWindow = ( pContainerWindow->GetExtendedStyle() & WB_EXT_DOCUMENT ) != 0;
301 const Reference< XTopWindow > xFrameContainer( xContainerWindow, UNO_QUERY );
302 if ( xFrameContainer.is() )
303 (xFrameContainer.get()->*pListenerAction)( this );
305 catch( const Exception& )
307 DBG_UNHANDLED_EXCEPTION();
311 //--------------------------------------------------------------------
312 void FrameWindowActivationListener::impl_checkDisposed_throw() const
314 if ( !m_pData )
315 throw DisposedException( ::rtl::OUString(), *const_cast< FrameWindowActivationListener* >( this ) );
318 //--------------------------------------------------------------------
319 void SAL_CALL FrameWindowActivationListener::windowOpened( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
321 // not interested in
324 //--------------------------------------------------------------------
325 void SAL_CALL FrameWindowActivationListener::windowClosing( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
327 // not interested in
330 //--------------------------------------------------------------------
331 void SAL_CALL FrameWindowActivationListener::windowClosed( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
333 // not interested in
336 //--------------------------------------------------------------------
337 void SAL_CALL FrameWindowActivationListener::windowMinimized( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
339 // not interested in
342 //--------------------------------------------------------------------
343 void SAL_CALL FrameWindowActivationListener::windowNormalized( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
345 // not interested in
348 //--------------------------------------------------------------------
349 void SAL_CALL FrameWindowActivationListener::windowActivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
351 impl_checkDisposed_throw();
352 lcl_updateActive_nothrow( *m_pData, true );
355 //--------------------------------------------------------------------
356 void SAL_CALL FrameWindowActivationListener::windowDeactivated( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
358 impl_checkDisposed_throw();
359 lcl_updateActive_nothrow( *m_pData, false );
362 //--------------------------------------------------------------------
363 void SAL_CALL FrameWindowActivationListener::disposing( const EventObject& /*_rEvent*/ ) throw (RuntimeException)
365 dispose();
368 //====================================================================
369 //= ControllerFrame
370 //====================================================================
371 //--------------------------------------------------------------------
372 ControllerFrame::ControllerFrame( IController& _rController )
373 :m_pData( new ControllerFrame_Data( _rController ) )
377 //--------------------------------------------------------------------
378 ControllerFrame::~ControllerFrame()
382 //--------------------------------------------------------------------
383 const Reference< XFrame >& ControllerFrame::attachFrame( const Reference< XFrame >& _rxFrame )
385 // set new frame, including listener handling
386 lcl_setFrame_nothrow( *m_pData, _rxFrame );
388 // determine whether we're active
389 m_pData->m_bActive = lcl_isActive_nothrow( m_pData->m_xFrame );
391 // update active component
392 if ( m_pData->m_bActive )
394 lcl_updateActiveComponents_nothrow( *m_pData );
395 lcl_notifyFocusChange_nothrow( *m_pData, true );
398 return m_pData->m_xFrame;
401 //--------------------------------------------------------------------
402 const Reference< XFrame >& ControllerFrame::getFrame() const
404 return m_pData->m_xFrame;
407 //--------------------------------------------------------------------
408 bool ControllerFrame::isActive() const
410 return m_pData->m_bActive;
413 //--------------------------------------------------------------------
414 void ControllerFrame::frameAction( FrameAction _eAction )
416 bool bActive = m_pData->m_bActive;
418 switch ( _eAction )
420 case FrameAction_FRAME_ACTIVATED:
421 case FrameAction_FRAME_UI_ACTIVATED:
422 bActive = true;
423 break;
425 case FrameAction_FRAME_DEACTIVATING:
426 case FrameAction_FRAME_UI_DEACTIVATING:
427 bActive = false;
428 break;
430 default:
431 break;
434 lcl_updateActive_nothrow( *m_pData, bActive );
437 //........................................................................
438 } // namespace dbaui
439 //........................................................................
441 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */