1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _EXTENSIONS_PROPCTRLR_COMMONCONTROL_HXX_
25 #define _EXTENSIONS_PROPCTRLR_COMMONCONTROL_HXX_
26 
27 /** === begin UNO includes === **/
28 #include <com/sun/star/inspection/XPropertyControl.hpp>
29 #include <com/sun/star/lang/DisposedException.hpp>
30 /** === end UNO includes === **/
31 #include <cppuhelper/compbase1.hxx>
32 #include <comphelper/broadcasthelper.hxx>
33 #include <tools/link.hxx>
34 #include <vcl/window.hxx>
35 
36 class NotifyEvent;
37 //............................................................................
38 namespace pcr
39 {
40 //............................................................................
41 
42     class ControlHelper;
43     //========================================================================
44     //= ControlWindow
45     //========================================================================
46     template< class WINDOW >
47     class ControlWindow : public WINDOW
48     {
49     protected:
50         typedef WINDOW  WindowType;
51 
52     protected:
53         ControlHelper*  m_pHelper;
54 
55     public:
ControlWindow(Window * _pParent,WinBits _nStyle)56         ControlWindow( Window* _pParent, WinBits _nStyle )
57             :WindowType( _pParent, _nStyle )
58             ,m_pHelper( NULL )
59         {
60         }
61 
62         /// sets a ControlHelper instance which some functionality is delegated to
63         inline virtual void setControlHelper( ControlHelper& _rControlHelper );
64 
65     protected:
66         // Window overridables
67         inline virtual long PreNotify( NotifyEvent& rNEvt );
68     };
69 
70     //========================================================================
71     //= IModifyListener
72     //========================================================================
73     class SAL_NO_VTABLE IModifyListener
74     {
75     public:
76         virtual void modified() = 0;
77     };
78 
79     //========================================================================
80     //= ControlHelper
81     //========================================================================
82     /** A helper class for implementing the <type scope="com::sun::star::inspection">XPropertyControl</type>
83         or one of its derived interfaces.
84 
85         This class is intended to be held as member of another class which implements the
86         <type scope="com::sun::star::inspection">XPropertyControl</type> interface. The pointer
87         to this interface is to be passed to the ctor.
88     */
89     class ControlHelper
90     {
91     private:
92         Window*                         m_pControlWindow;
93         sal_Int16                       m_nControlType;
94         ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext >
95                                         m_xContext;
96         ::com::sun::star::inspection::XPropertyControl&
97                                         m_rAntiImpl;
98         IModifyListener*                m_pModifyListener;
99         sal_Bool                        m_bModified;
100 
101     public:
102         /** creates the instance
103             @param  _rControlWindow
104                 the window which is associated with the <type scope="com::sun::star::inspection">XPropertyControl</type>.
105                 Must not be <NULL/>.<br/>
106                 Ownership for this window is taken by the ControlHelper - it will be deleted in <member>disposing</member>.
107             @param  _nControlType
108                 the type of the control - one of the <type scope="com::sun::star::inspection">PropertyControlType</type>
109                 constants
110             @param _pAntiImpl
111                 Reference to the instance as whose "impl-class" we act. This reference is held during lifetime
112                 of the <type>ControlHelper</type> class, within acquiring it. Thus, the owner of the
113                 <type>ControlHelper</type> is responsible for assuring the lifetime of the instance
114                 pointed to by <arg>_pAntiImpl</arg>.
115             @param _pModifyListener
116                 a listener to be modfied when the user modified the control's value. the
117                 <member>IModifyListener::modified</member> of this listener is called from within our
118                 ModifiedHdl. A default implementation of <member>IModifyListener::modified</member>
119                 would just call our <member>setModified</member>.
120         */
121         ControlHelper(
122             Window* _pControlWindow,
123             sal_Int16 _nControlType,
124             ::com::sun::star::inspection::XPropertyControl& _rAntiImpl,
125             IModifyListener* _pModifyListener );
126 
127         virtual ~ControlHelper();
128 
129         /** sets our "modified" flag to <TRUE/>
130         */
setModified()131         inline void setModified() { m_bModified = sal_True; }
getVclControlWindow()132         inline       Window* getVclControlWindow()       { return m_pControlWindow; }
getVclControlWindow() const133         inline const Window* getVclControlWindow() const { return m_pControlWindow; }
134 
135     public:
136         // XPropertyControl
137         ::sal_Int16 SAL_CALL getControlType() throw (::com::sun::star::uno::RuntimeException);
138         ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext > SAL_CALL getControlContext() throw (::com::sun::star::uno::RuntimeException);
139         void SAL_CALL setControlContext( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext >& _controlcontext ) throw (::com::sun::star::uno::RuntimeException);
140         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getControlWindow() throw (::com::sun::star::uno::RuntimeException);
141         ::sal_Bool SAL_CALL isModified(  ) throw (::com::sun::star::uno::RuntimeException);
142         void SAL_CALL notifyModifiedValue(  ) throw (::com::sun::star::uno::RuntimeException);
143 
144         // XComponent
145         virtual void SAL_CALL dispose();
146 
147         /** (fail-safe) wrapper around calling our context's activateNextControl
148         */
activateNextControl() const149         inline void activateNextControl() const { impl_activateNextControl_nothrow(); }
150 
151     public:
152         /// may be used to implement the default handling in PreNotify; returns sal_True if handled
153         bool handlePreNotify(NotifyEvent& _rNEvt);
154 
155         /// automatically size the window given in the ctor
156         void    autoSizeWindow();
157 
158         /// may be used by derived classes, they forward the event to the PropCtrListener
159         DECL_LINK( ModifiedHdl, Window* );
160         DECL_LINK( GetFocusHdl, Window* );
161         DECL_LINK( LoseFocusHdl, Window* );
162 
163     private:
164         /** fail-safe wrapper around calling our context's activateNextControl
165         */
166         void    impl_activateNextControl_nothrow() const;
167     };
168 
169     //========================================================================
170     //= CommonBehaviourControl
171     //========================================================================
172     /** implements a base class for <type scope="com::sun::star::inspection">XPropertyControl</type>
173         implementations, which delegates the generic functionality of this interface to a
174         <type>ControlHelper</type> member.
175 
176         @param CONTROL_INTERFACE
177             an interface class which is derived from (or identical to) <type scope="com::sun::star::inspection">XPropertyControl</type>
178         @param CONTROL_WINDOW
179             a class which is derived from ControlWindow
180     */
181     template < class CONTROL_INTERFACE, class CONTROL_WINDOW >
182     class CommonBehaviourControl    :public ::comphelper::OBaseMutex
183                                     ,public ::cppu::WeakComponentImplHelper1< CONTROL_INTERFACE >
184                                     ,public IModifyListener
185     {
186     protected:
187         typedef CONTROL_INTERFACE   InterfaceType;
188         typedef CONTROL_WINDOW      WindowType;
189 
190         typedef ::comphelper::OBaseMutex                                MutexBaseClass;
191         typedef ::cppu::WeakComponentImplHelper1< CONTROL_INTERFACE >   ComponentBaseClass;
192 
193     protected:
194         ControlHelper   m_aImplControl;
195 
196     protected:
197         inline CommonBehaviourControl( sal_Int16 _nControlType, Window* _pParentWindow, WinBits _nWindowStyle, bool _bDoSetHandlers = true );
198 
199         // XPropertyControl - delegated to ->m_aImplControl
200         inline ::sal_Int16 SAL_CALL getControlType() throw (::com::sun::star::uno::RuntimeException);
201         inline ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext > SAL_CALL getControlContext() throw (::com::sun::star::uno::RuntimeException);
202         inline void SAL_CALL setControlContext( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext >& _controlcontext ) throw (::com::sun::star::uno::RuntimeException);
203         inline ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getControlWindow() throw (::com::sun::star::uno::RuntimeException);
204         inline ::sal_Bool SAL_CALL isModified(  ) throw (::com::sun::star::uno::RuntimeException);
205         inline void SAL_CALL notifyModifiedValue(  ) throw (::com::sun::star::uno::RuntimeException);
206 
207         // XComponent
208         inline virtual void SAL_CALL disposing();
209 
210         // IModifyListener
211         inline virtual void modified();
212 
213         /// returns a typed pointer to our control window
getTypedControlWindow()214               WindowType* getTypedControlWindow()       { return static_cast< WindowType* >      ( m_aImplControl.getVclControlWindow() ); }
getTypedControlWindow() const215         const WindowType* getTypedControlWindow() const { return static_cast< const WindowType* >( m_aImplControl.getVclControlWindow() ); }
216 
217     protected:
218         /** checks whether the instance is already disposed
219             @throws DisposedException
220                 if the instance is already disposed
221         */
222         inline void impl_checkDisposed_throw();
223     };
224 
225     //========================================================================
226     //= ControlWindow - implementation
227     //========================================================================
228     //------------------------------------------------------------------------
229     template< class WINDOW >
setControlHelper(ControlHelper & _rControlHelper)230     inline void ControlWindow< WINDOW >::setControlHelper( ControlHelper& _rControlHelper )
231     {
232         m_pHelper = &_rControlHelper;
233     }
234 
235     //------------------------------------------------------------------------
236     template< class WINDOW >
PreNotify(NotifyEvent & rNEvt)237     inline long ControlWindow< WINDOW >::PreNotify( NotifyEvent& rNEvt )
238     {
239         if ( m_pHelper && m_pHelper->handlePreNotify( rNEvt ) )
240             return 1;
241         return WindowType::PreNotify( rNEvt );
242     }
243 
244     //========================================================================
245     //= CommonBehaviourControl - implementation
246     //========================================================================
247     //------------------------------------------------------------------------
248     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
CommonBehaviourControl(sal_Int16 _nControlType,Window * _pParentWindow,WinBits _nWindowStyle,bool _bDoSetHandlers)249     inline CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::CommonBehaviourControl ( sal_Int16 _nControlType, Window* _pParentWindow, WinBits _nWindowStyle, bool _bDoSetHandlers )
250         :ComponentBaseClass( m_aMutex )
251         ,m_aImplControl( new WindowType( _pParentWindow, _nWindowStyle ), _nControlType, *this, this )
252     {
253         WindowType* pControlWindow( getTypedControlWindow() );
254         pControlWindow->setControlHelper( m_aImplControl );
255         if ( _bDoSetHandlers )
256         {
257             pControlWindow->SetModifyHdl( LINK( &m_aImplControl, ControlHelper, ModifiedHdl ) );
258 		    pControlWindow->SetGetFocusHdl( LINK( &m_aImplControl, ControlHelper, GetFocusHdl ) );
259 		    pControlWindow->SetLoseFocusHdl( LINK( &m_aImplControl, ControlHelper, LoseFocusHdl ) );
260         }
261 		m_aImplControl.autoSizeWindow();
262     }
263 
264     //--------------------------------------------------------------------
265     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
getControlType()266     inline ::sal_Int16 SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::getControlType() throw (::com::sun::star::uno::RuntimeException)
267     {
268         return m_aImplControl.getControlType();
269     }
270 
271     //--------------------------------------------------------------------
272     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
getControlContext()273     inline ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext > SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::getControlContext() throw (::com::sun::star::uno::RuntimeException)
274     {
275         return m_aImplControl.getControlContext();
276     }
277 
278     //--------------------------------------------------------------------
279     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
setControlContext(const::com::sun::star::uno::Reference<::com::sun::star::inspection::XPropertyControlContext> & _controlcontext)280     inline void SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::setControlContext( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlContext >& _controlcontext ) throw (::com::sun::star::uno::RuntimeException)
281     {
282         m_aImplControl.setControlContext( _controlcontext );
283     }
284 
285     //--------------------------------------------------------------------
286     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
getControlWindow()287     inline ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::getControlWindow() throw (::com::sun::star::uno::RuntimeException)
288     {
289         return m_aImplControl.getControlWindow();
290     }
291 
292     //--------------------------------------------------------------------
293     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
isModified()294     inline ::sal_Bool SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::isModified(  ) throw (::com::sun::star::uno::RuntimeException)
295     {
296         return m_aImplControl.isModified();
297     }
298 
299     //--------------------------------------------------------------------
300     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
notifyModifiedValue()301     inline void SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::notifyModifiedValue(  ) throw (::com::sun::star::uno::RuntimeException)
302     {
303         m_aImplControl.notifyModifiedValue();
304     }
305 
306     //--------------------------------------------------------------------
307     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
disposing()308     inline void SAL_CALL CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::disposing()
309     {
310         m_aImplControl.dispose();
311     }
312 
313     //--------------------------------------------------------------------
314     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
modified()315     inline void CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::modified()
316     {
317         m_aImplControl.setModified();
318     }
319 
320     //--------------------------------------------------------------------
321     template< class CONTROL_INTERFACE, class CONTROL_WINDOW >
impl_checkDisposed_throw()322     inline void CommonBehaviourControl< CONTROL_INTERFACE, CONTROL_WINDOW >::impl_checkDisposed_throw()
323     {
324         if ( ComponentBaseClass::rBHelper.bDisposed )
325             throw ::com::sun::star::lang::DisposedException( ::rtl::OUString(), *this );
326     }
327 
328 //............................................................................
329 } // namespace pcr
330 //............................................................................
331 
332 #endif // _EXTENSIONS_PROPCTRLR_COMMONCONTROL_HXX_
333 
334