1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_toolkit.hxx"
30 #include "toolkit/awt/vclxspinbutton.hxx"
31 #include "toolkit/helper/property.hxx"
32 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
33 
34 
35 #include <tools/debug.hxx>
36 #include <vcl/spin.hxx>
37 
38 namespace toolkit
39 {
40     void                        setButtonLikeFaceColor( Window* _pWindow, const ::com::sun::star::uno::Any& _rColorValue );
41     ::com::sun::star::uno::Any  getButtonLikeFaceColor( const Window* _pWindow );
42 }
43 
44 //........................................................................
45 namespace toolkit
46 {
47 //........................................................................
48 
49     using namespace ::com::sun::star::uno;
50     using namespace ::com::sun::star::awt;
51     using namespace ::com::sun::star::lang;
52     using namespace ::com::sun::star::beans;
53 
54     //--------------------------------------------------------------------
55     namespace
56     {
57         void lcl_modifyStyle( Window* _pWindow, WinBits _nStyleBits, sal_Bool _bShouldBePresent )
58         {
59             WinBits nStyle = _pWindow->GetStyle();
60             if ( _bShouldBePresent )
61                 nStyle |= _nStyleBits;
62             else
63                 nStyle &= ~_nStyleBits;
64             _pWindow->SetStyle( nStyle );
65         }
66     }
67 
68     //====================================================================
69 	//= VCLXSpinButton
70 	//====================================================================
71     DBG_NAME( VCLXSpinButton )
72     //--------------------------------------------------------------------
73     VCLXSpinButton::VCLXSpinButton()
74         :maAdjustmentListeners( *this )
75     {
76         DBG_CTOR( VCLXSpinButton, NULL );
77     }
78 
79     //--------------------------------------------------------------------
80     VCLXSpinButton::~VCLXSpinButton()
81     {
82         DBG_DTOR( VCLXSpinButton, NULL );
83     }
84 
85     //--------------------------------------------------------------------
86     IMPLEMENT_FORWARD_XINTERFACE2( VCLXSpinButton, VCLXWindow, VCLXSpinButton_Base )
87 
88     //--------------------------------------------------------------------
89     IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXSpinButton, VCLXWindow, VCLXSpinButton_Base )
90 
91     //--------------------------------------------------------------------
92     void SAL_CALL VCLXSpinButton::dispose( ) throw(RuntimeException)
93     {
94         {
95 	        ::vos::OGuard aGuard( GetMutex() );
96 
97 	        EventObject aDisposeEvent;
98 	        aDisposeEvent.Source = *this;
99 	        maAdjustmentListeners.disposeAndClear( aDisposeEvent );
100         }
101 
102         VCLXWindow::dispose();
103     }
104 
105     //--------------------------------------------------------------------
106     void SAL_CALL VCLXSpinButton::addAdjustmentListener( const Reference< XAdjustmentListener >& listener ) throw (RuntimeException)
107     {
108         if ( listener.is() )
109             maAdjustmentListeners.addInterface( listener );
110     }
111 
112     //--------------------------------------------------------------------
113     void SAL_CALL VCLXSpinButton::removeAdjustmentListener( const Reference< XAdjustmentListener >& listener ) throw (RuntimeException)
114     {
115         if ( listener.is() )
116             maAdjustmentListeners.removeInterface( listener );
117     }
118 
119     namespace
120     {
121         typedef void (SpinButton::*SetSpinButtonValue) (long);
122         typedef long (SpinButton::*GetSpinButtonValue) (void) const;
123 
124         //................................................................
125         void lcl_setSpinButtonValue( ::vos::IMutex& _rMutex, Window* _pWindow, SetSpinButtonValue _pSetter, sal_Int32 _nValue )
126         {
127 	        ::vos::OGuard aGuard( _rMutex );
128 
129 	        SpinButton* pSpinButton = static_cast< SpinButton* >( _pWindow );
130 	        if ( pSpinButton )
131 		        (pSpinButton->*_pSetter)( _nValue );
132         }
133 
134         //................................................................
135         sal_Int32 lcl_getSpinButtonValue( ::vos::IMutex& _rMutex, const Window* _pWindow, GetSpinButtonValue _pGetter )
136         {
137 	        ::vos::OGuard aGuard( _rMutex );
138 
139             sal_Int32 nValue = 0;
140 
141             const SpinButton* pSpinButton = static_cast< const SpinButton* >( _pWindow );
142 	        if ( pSpinButton )
143 		        nValue = (pSpinButton->*_pGetter)( );
144             return nValue;
145         }
146     }
147 
148     //--------------------------------------------------------------------
149     void SAL_CALL VCLXSpinButton::setValue( sal_Int32 n ) throw (RuntimeException)
150     {
151         lcl_setSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::SetValue, n );
152     }
153 
154     //--------------------------------------------------------------------
155     void SAL_CALL VCLXSpinButton::setValues( sal_Int32 minValue, sal_Int32 maxValue, sal_Int32 currentValue ) throw (RuntimeException)
156     {
157         ::vos::OGuard aGuard( GetMutex() );
158 
159         setMinimum( minValue );
160         setMaximum( maxValue );
161         setValue( currentValue );
162     }
163 
164     //--------------------------------------------------------------------
165     sal_Int32 SAL_CALL VCLXSpinButton::getValue(  ) throw (RuntimeException)
166     {
167         return lcl_getSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::GetValue );
168     }
169 
170     //--------------------------------------------------------------------
171     void SAL_CALL VCLXSpinButton::setMinimum( sal_Int32 minValue ) throw (RuntimeException)
172     {
173         lcl_setSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::SetRangeMin, minValue );
174     }
175 
176     //--------------------------------------------------------------------
177     void SAL_CALL VCLXSpinButton::setMaximum( sal_Int32 maxValue ) throw (RuntimeException)
178     {
179         lcl_setSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::SetRangeMax, maxValue );
180     }
181 
182     //--------------------------------------------------------------------
183     sal_Int32 SAL_CALL VCLXSpinButton::getMinimum(  ) throw (RuntimeException)
184     {
185         return lcl_getSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::GetRangeMin );
186     }
187 
188     //--------------------------------------------------------------------
189     sal_Int32 SAL_CALL VCLXSpinButton::getMaximum(  ) throw (RuntimeException)
190     {
191         return lcl_getSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::GetRangeMax );
192     }
193 
194     //--------------------------------------------------------------------
195     void SAL_CALL VCLXSpinButton::setSpinIncrement( sal_Int32 spinIncrement ) throw (RuntimeException)
196     {
197         lcl_setSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::SetValueStep, spinIncrement );
198     }
199 
200     //--------------------------------------------------------------------
201     sal_Int32 SAL_CALL VCLXSpinButton::getSpinIncrement(  ) throw (RuntimeException)
202     {
203         return lcl_getSpinButtonValue( GetMutex(), GetWindow(), &SpinButton::GetValueStep );
204     }
205 
206     //--------------------------------------------------------------------
207     void SAL_CALL VCLXSpinButton::setOrientation( sal_Int32 orientation ) throw (NoSupportException, RuntimeException)
208     {
209         ::vos::OGuard aGuard( GetMutex() );
210 
211         lcl_modifyStyle( GetWindow(), WB_HSCROLL, orientation == ScrollBarOrientation::HORIZONTAL );
212     }
213 
214     //--------------------------------------------------------------------
215     sal_Int32 SAL_CALL VCLXSpinButton::getOrientation(  ) throw (RuntimeException)
216     {
217         return  ( 0 != ( GetWindow()->GetStyle() & WB_HSCROLL ) )
218             ?   ScrollBarOrientation::HORIZONTAL
219             :   ScrollBarOrientation::VERTICAL;
220     }
221 
222     //--------------------------------------------------------------------
223     void VCLXSpinButton::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
224     {
225         ::vos::OClearableGuard aGuard( GetMutex() );
226         Reference< XSpinValue > xKeepAlive( this );
227         SpinButton* pSpinButton = static_cast< SpinButton* >( GetWindow() );
228         if ( !pSpinButton )
229             return;
230 
231 	    switch ( _rVclWindowEvent.GetId() )
232 	    {
233 		    case VCLEVENT_SPINBUTTON_UP:
234             case VCLEVENT_SPINBUTTON_DOWN:
235 			    if ( maAdjustmentListeners.getLength() )
236 			    {
237 				    AdjustmentEvent aEvent;
238 				    aEvent.Source = *this;
239 				    aEvent.Value = pSpinButton->GetValue();
240 
241                     aGuard.clear();
242 				    maAdjustmentListeners.adjustmentValueChanged( aEvent );
243                 }
244 			    break;
245 
246 		    default:
247                 xKeepAlive.clear();
248                 aGuard.clear();
249 			    VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
250 			    break;
251 	    }
252     }
253 
254     //--------------------------------------------------------------------
255     void SAL_CALL VCLXSpinButton::setProperty( const ::rtl::OUString& PropertyName, const Any& Value ) throw(RuntimeException)
256     {
257 	    ::vos::OGuard aGuard( GetMutex() );
258 
259         sal_Int32 nValue = 0;
260         sal_Bool  bIsLongValue = ( Value >>= nValue );
261 
262 	    if ( GetWindow() )
263 	    {
264 		    sal_uInt16 nPropertyId = GetPropertyId( PropertyName );
265             switch ( nPropertyId )
266             {
267             case BASEPROPERTY_BACKGROUNDCOLOR:
268                 // the default implementation of the base class doesn't work here, since our
269                 // interpretation for this property is slightly different
270                 setButtonLikeFaceColor( GetWindow(), Value);
271                 break;
272 
273             case BASEPROPERTY_SPINVALUE:
274                 if ( bIsLongValue )
275                     setValue( nValue );
276                 break;
277 
278             case BASEPROPERTY_SPINVALUE_MIN:
279                 if ( bIsLongValue )
280                     setMinimum( nValue );
281                 break;
282 
283             case BASEPROPERTY_SPINVALUE_MAX:
284                 if ( bIsLongValue )
285                     setMaximum( nValue );
286                 break;
287 
288             case BASEPROPERTY_SPININCREMENT:
289                 if ( bIsLongValue )
290                     setSpinIncrement( nValue );
291                 break;
292 
293             case BASEPROPERTY_ORIENTATION:
294                 if ( bIsLongValue )
295                     lcl_modifyStyle( GetWindow(), WB_HSCROLL, nValue == ScrollBarOrientation::HORIZONTAL );
296                 break;
297 
298             default:
299                 VCLXWindow::setProperty( PropertyName, Value );
300             }
301         }
302     }
303 
304     //--------------------------------------------------------------------
305     Any SAL_CALL VCLXSpinButton::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
306     {
307 	    ::vos::OGuard aGuard( GetMutex() );
308 
309         Any aReturn;
310 
311 	    if ( GetWindow() )
312 	    {
313 		    sal_uInt16 nPropertyId = GetPropertyId( PropertyName );
314             switch ( nPropertyId )
315             {
316             case BASEPROPERTY_BACKGROUNDCOLOR:
317                 // the default implementation of the base class doesn't work here, since our
318                 // interpretation for this property is slightly different
319                 aReturn = getButtonLikeFaceColor( GetWindow() );
320                 break;
321 
322             case BASEPROPERTY_SPINVALUE:
323                 aReturn <<= (sal_Int32)getValue( );
324                 break;
325 
326             case BASEPROPERTY_SPINVALUE_MIN:
327                 aReturn <<= (sal_Int32)getMinimum( );
328                 break;
329 
330             case BASEPROPERTY_SPINVALUE_MAX:
331                 aReturn <<= (sal_Int32)getMaximum( );
332                 break;
333 
334             case BASEPROPERTY_SPININCREMENT:
335                 aReturn <<= (sal_Int32)getSpinIncrement( );
336                 break;
337 
338             case BASEPROPERTY_ORIENTATION:
339                 aReturn <<= (sal_Int32)
340                     (   ( 0 != ( GetWindow()->GetStyle() & WB_HSCROLL ) )
341                     ?   ScrollBarOrientation::HORIZONTAL
342                     :   ScrollBarOrientation::VERTICAL
343                     );
344                 break;
345 
346             default:
347                 aReturn = VCLXWindow::getProperty( PropertyName );
348             }
349         }
350         return aReturn;
351     }
352 
353 //........................................................................
354 }   // namespace toolkit
355 //........................................................................
356