1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: controllerframe.cxx,v $
10 * $Revision: 1.3.2.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "controllerframe.hxx"
32 #include "IController.hxx"
34 /** === begin UNO includes === **/
35 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
36 #include <com/sun/star/awt/XTopWindow.hpp>
37 #include <com/sun/star/awt/XWindow2.hpp>
38 #include <com/sun/star/lang/DisposedException.hpp>
39 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
40 #include <com/sun/star/frame/XController2.hpp>
41 /** === end UNO includes === **/
43 #include <cppuhelper/implbase1.hxx>
44 #include <rtl/ref.hxx>
45 #include <sfx2/objsh.hxx>
46 #include <tools/diagnose_ex.h>
48 //........................................................................
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 /** === end UNO using === **/
82 //====================================================================
83 //= FrameWindowActivationListener
84 //====================================================================
85 typedef ::cppu::WeakImplHelper1
< XTopWindowListener
86 > FrameWindowActivationListener_Base
;
87 class FrameWindowActivationListener
: public FrameWindowActivationListener_Base
90 FrameWindowActivationListener( ControllerFrame_Data
& _rData
);
95 ~FrameWindowActivationListener();
98 virtual void SAL_CALL
windowOpened( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
99 virtual void SAL_CALL
windowClosing( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
100 virtual void SAL_CALL
windowClosed( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
101 virtual void SAL_CALL
windowMinimized( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
102 virtual void SAL_CALL
windowNormalized( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
103 virtual void SAL_CALL
windowActivated( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
104 virtual void SAL_CALL
windowDeactivated( const ::com::sun::star::lang::EventObject
& e
) throw (::com::sun::star::uno::RuntimeException
);
107 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
110 void impl_checkDisposed_throw() const;
111 void impl_registerOnFrameContainerWindow_nothrow( bool _bRegister
);
114 ControllerFrame_Data
* m_pData
;
117 //====================================================================
118 //= ControllerFrame_Data
119 //====================================================================
120 struct ControllerFrame_Data
122 ControllerFrame_Data( IController
& _rController
)
123 :m_rController( _rController
)
125 ,m_xDocEventBroadcaster()
128 ,m_bLivesInTopWindow( false )
132 IController
& m_rController
;
133 Reference
< XFrame
> m_xFrame
;
134 Reference
< XDocumentEventBroadcaster
> m_xDocEventBroadcaster
;
135 ::rtl::Reference
< FrameWindowActivationListener
> m_pListener
;
137 bool m_bLivesInTopWindow
;
140 //====================================================================
142 //====================================================================
143 //--------------------------------------------------------------------
144 static void lcl_setFrame_nothrow( ControllerFrame_Data
& _rData
, const Reference
< XFrame
>& _rxFrame
)
146 // release old listener
147 if ( _rData
.m_pListener
.get() )
149 _rData
.m_pListener
->dispose();
150 _rData
.m_pListener
= NULL
;
153 // remember new frame
154 _rData
.m_xFrame
= _rxFrame
;
156 // create new listener
157 if ( _rData
.m_xFrame
.is() )
158 _rData
.m_pListener
= new FrameWindowActivationListener( _rData
);
160 // at this point in time, we can assume the controller also has a model set, if it supports models
163 Reference
< XController
> xController( _rData
.m_rController
.getXController(), UNO_SET_THROW
);
164 Reference
< XModel
> xModel( xController
->getModel() );
166 _rData
.m_xDocEventBroadcaster
.set( xModel
, UNO_QUERY
);
168 catch( const Exception
& )
170 DBG_UNHANDLED_EXCEPTION();
174 //--------------------------------------------------------------------
175 static bool lcl_isActive_nothrow( const Reference
< XFrame
>& _rxFrame
)
177 bool bIsActive
= false;
182 Reference
< XWindow2
> xWindow( _rxFrame
->getContainerWindow(), UNO_QUERY_THROW
);
183 bIsActive
= xWindow
->isActive();
187 catch( const Exception
& )
189 DBG_UNHANDLED_EXCEPTION();
194 //--------------------------------------------------------------------
195 /** updates various global and local states with a new active component
197 In particular, the following are updated
198 * the global working document (aka Basic's ThisComponent in the application
199 Basic), with our controller's model, or the controller itself if there is no such
202 static void lcl_updateActiveComponents_nothrow( const ControllerFrame_Data
& _rData
)
206 Reference
< XController
> xCompController( _rData
.m_rController
.getXController() );
207 OSL_ENSURE( xCompController
.is(), "lcl_updateActiveComponents_nothrow: can't do anything without a controller!" );
208 if ( !xCompController
.is() )
211 if ( _rData
.m_bActive
&& _rData
.m_bLivesInTopWindow
)
213 // set the "current component" at the SfxObjectShell
214 Reference
< XModel
> xModel( xCompController
->getModel() );
215 Reference
< XInterface
> xCurrentComponent
;
217 xCurrentComponent
= xModel
;
219 xCurrentComponent
= xCompController
;
220 SfxObjectShell::SetCurrentComponent( xCurrentComponent
);
223 catch( const Exception
& )
225 DBG_UNHANDLED_EXCEPTION();
229 //--------------------------------------------------------------------
230 /** broadcasts the OnFocus resp. OnUnfocus event
232 static void lcl_notifyFocusChange_nothrow( ControllerFrame_Data
& _rData
, bool _bActive
)
236 if ( _rData
.m_xDocEventBroadcaster
.is() )
238 ::rtl::OUString
sEventName( ::rtl::OUString::createFromAscii( _bActive
? "OnFocus" : "OnUnfocus" ) );
239 Reference
< XController2
> xController( _rData
.m_rController
.getXController(), UNO_QUERY_THROW
);
240 _rData
.m_xDocEventBroadcaster
->notifyDocumentEvent( sEventName
, xController
, Any() );
243 catch( const Exception
& )
245 DBG_UNHANDLED_EXCEPTION();
249 //--------------------------------------------------------------------
250 static void lcl_updateActive_nothrow( ControllerFrame_Data
& _rData
, bool _bActive
)
252 if ( _rData
.m_bActive
== _bActive
)
254 _rData
.m_bActive
= _bActive
;
256 lcl_updateActiveComponents_nothrow( _rData
);
257 lcl_notifyFocusChange_nothrow( _rData
, _bActive
);
260 //--------------------------------------------------------------------
261 FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data
& _rData
)
264 impl_registerOnFrameContainerWindow_nothrow( true );
267 //--------------------------------------------------------------------
268 FrameWindowActivationListener::~FrameWindowActivationListener()
272 //--------------------------------------------------------------------
273 void FrameWindowActivationListener::dispose()
275 impl_registerOnFrameContainerWindow_nothrow( false );
279 //--------------------------------------------------------------------
280 void FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow( bool _bRegister
)
282 OSL_ENSURE( m_pData
&& m_pData
->m_xFrame
.is(), "FrameWindowActivationListener::impl_registerOnFrameContainerWindow_nothrow: no frame!" );
283 if ( !m_pData
|| !m_pData
->m_xFrame
.is() )
288 void ( SAL_CALL
XTopWindow::*pListenerAction
)( const Reference
< XTopWindowListener
>& ) =
289 _bRegister
? &XTopWindow::addTopWindowListener
: &XTopWindow::removeTopWindowListener
;
291 Reference
< XTopWindow
> xFrameContainer( m_pData
->m_xFrame
->getContainerWindow(), UNO_QUERY
);
293 m_pData
->m_bLivesInTopWindow
= xFrameContainer
.is();
294 if ( xFrameContainer
.is() )
295 (xFrameContainer
.get()->*pListenerAction
)( this );
297 catch( const Exception
& )
299 DBG_UNHANDLED_EXCEPTION();
303 //--------------------------------------------------------------------
304 void FrameWindowActivationListener::impl_checkDisposed_throw() const
307 throw DisposedException( ::rtl::OUString(), *const_cast< FrameWindowActivationListener
* >( this ) );
310 //--------------------------------------------------------------------
311 void SAL_CALL
FrameWindowActivationListener::windowOpened( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
316 //--------------------------------------------------------------------
317 void SAL_CALL
FrameWindowActivationListener::windowClosing( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
322 //--------------------------------------------------------------------
323 void SAL_CALL
FrameWindowActivationListener::windowClosed( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
328 //--------------------------------------------------------------------
329 void SAL_CALL
FrameWindowActivationListener::windowMinimized( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
334 //--------------------------------------------------------------------
335 void SAL_CALL
FrameWindowActivationListener::windowNormalized( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
340 //--------------------------------------------------------------------
341 void SAL_CALL
FrameWindowActivationListener::windowActivated( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
343 impl_checkDisposed_throw();
344 lcl_updateActive_nothrow( *m_pData
, true );
347 //--------------------------------------------------------------------
348 void SAL_CALL
FrameWindowActivationListener::windowDeactivated( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
350 impl_checkDisposed_throw();
351 lcl_updateActive_nothrow( *m_pData
, false );
354 //--------------------------------------------------------------------
355 void SAL_CALL
FrameWindowActivationListener::disposing( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
360 //====================================================================
362 //====================================================================
363 //--------------------------------------------------------------------
364 ControllerFrame::ControllerFrame( IController
& _rController
)
365 :m_pData( new ControllerFrame_Data( _rController
) )
369 //--------------------------------------------------------------------
370 ControllerFrame::~ControllerFrame()
374 //--------------------------------------------------------------------
375 const Reference
< XFrame
>& ControllerFrame::attachFrame( const Reference
< XFrame
>& _rxFrame
)
377 // set new frame, including listener handling
378 lcl_setFrame_nothrow( *m_pData
, _rxFrame
);
380 // determine whether we're active
381 m_pData
->m_bActive
= lcl_isActive_nothrow( m_pData
->m_xFrame
);
383 // update active component
384 if ( m_pData
->m_bActive
)
386 lcl_updateActiveComponents_nothrow( *m_pData
);
387 lcl_notifyFocusChange_nothrow( *m_pData
, true );
390 return m_pData
->m_xFrame
;
393 //--------------------------------------------------------------------
394 const Reference
< XFrame
>& ControllerFrame::getFrame() const
396 return m_pData
->m_xFrame
;
399 //--------------------------------------------------------------------
400 bool ControllerFrame::isActive() const
402 return m_pData
->m_bActive
;
405 //--------------------------------------------------------------------
406 void ControllerFrame::frameAction( FrameAction _eAction
)
408 bool bActive
= m_pData
->m_bActive
;
412 case FrameAction_FRAME_ACTIVATED
:
413 case FrameAction_FRAME_UI_ACTIVATED
:
417 case FrameAction_FRAME_DEACTIVATING
:
418 case FrameAction_FRAME_UI_DEACTIVATING
:
426 lcl_updateActive_nothrow( *m_pData
, bActive
);
429 //........................................................................
431 //........................................................................