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