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 //........................................................................
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
91 FrameWindowActivationListener( ControllerFrame_Data
& _rData
);
96 ~FrameWindowActivationListener();
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
);
108 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
111 void impl_checkDisposed_throw() const;
112 void impl_registerOnFrameContainerWindow_nothrow( bool _bRegister
);
115 ControllerFrame_Data
* m_pData
;
118 //====================================================================
119 //= ControllerFrame_Data
120 //====================================================================
121 struct ControllerFrame_Data
123 ControllerFrame_Data( IController
& _rController
)
124 :m_rController( _rController
)
126 ,m_xDocEventBroadcaster()
129 ,m_bIsTopLevelDocumentWindow( false )
133 IController
& m_rController
;
134 Reference
< XFrame
> m_xFrame
;
135 Reference
< XDocumentEventBroadcaster
> m_xDocEventBroadcaster
;
136 ::rtl::Reference
< FrameWindowActivationListener
> m_pListener
;
138 bool m_bIsTopLevelDocumentWindow
;
141 //====================================================================
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() );
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;
183 Reference
< XWindow2
> xWindow( _rxFrame
->getContainerWindow(), UNO_QUERY_THROW
);
184 bIsActive
= xWindow
->isActive();
188 catch( const Exception
& )
190 DBG_UNHANDLED_EXCEPTION();
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
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() )
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
;
218 xCurrentComponent
= xModel
;
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
)
255 _rData
.m_bActive
= _bActive
;
257 lcl_updateActiveComponents_nothrow( _rData
);
258 lcl_notifyFocusChange_nothrow( _rData
, _bActive
);
261 //--------------------------------------------------------------------
262 FrameWindowActivationListener::FrameWindowActivationListener( ControllerFrame_Data
& _rData
)
265 impl_registerOnFrameContainerWindow_nothrow( true );
268 //--------------------------------------------------------------------
269 FrameWindowActivationListener::~FrameWindowActivationListener()
273 //--------------------------------------------------------------------
274 void FrameWindowActivationListener::dispose()
276 impl_registerOnFrameContainerWindow_nothrow( false );
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() )
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
);
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
315 throw DisposedException( ::rtl::OUString(), *const_cast< FrameWindowActivationListener
* >( this ) );
318 //--------------------------------------------------------------------
319 void SAL_CALL
FrameWindowActivationListener::windowOpened( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
324 //--------------------------------------------------------------------
325 void SAL_CALL
FrameWindowActivationListener::windowClosing( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
330 //--------------------------------------------------------------------
331 void SAL_CALL
FrameWindowActivationListener::windowClosed( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
336 //--------------------------------------------------------------------
337 void SAL_CALL
FrameWindowActivationListener::windowMinimized( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
342 //--------------------------------------------------------------------
343 void SAL_CALL
FrameWindowActivationListener::windowNormalized( const EventObject
& /*_rEvent*/ ) throw (RuntimeException
)
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
)
368 //====================================================================
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
;
420 case FrameAction_FRAME_ACTIVATED
:
421 case FrameAction_FRAME_UI_ACTIVATED
:
425 case FrameAction_FRAME_DEACTIVATING
:
426 case FrameAction_FRAME_UI_DEACTIVATING
:
434 lcl_updateActive_nothrow( *m_pData
, bActive
);
437 //........................................................................
439 //........................................................................
441 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */