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_forms.hxx"
30 #include "refvaluecomponent.hxx"
31 
32 /** === begin UNO includes === **/
33 /** === end UNO includes === **/
34 
35 #include <tools/diagnose_ex.h>
36 
37 #include <list>
38 
39 //........................................................................
40 namespace frm
41 {
42 //........................................................................
43 
44     using namespace ::com::sun::star::uno;
45     using namespace ::com::sun::star::lang;
46     using namespace ::com::sun::star::beans;
47     using namespace ::com::sun::star::form::binding;
48 
49     //====================================================================
50 	//=
51 	//====================================================================
52 	//--------------------------------------------------------------------
53 	OReferenceValueComponent::OReferenceValueComponent( const Reference< XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName, const ::rtl::OUString& _rDefault, sal_Bool _bSupportNoCheckRefValue )
54         :OBoundControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, sal_False, sal_True, sal_True )
55 	    ,m_eDefaultChecked( STATE_NOCHECK )
56         ,m_bSupportSecondRefValue( _bSupportNoCheckRefValue )
57     {
58     }
59 
60 	//--------------------------------------------------------------------
61 	OReferenceValueComponent::OReferenceValueComponent( const OReferenceValueComponent* _pOriginal, const	Reference< XMultiServiceFactory>& _rxFactory )
62         :OBoundControlModel( _pOriginal, _rxFactory )
63     {
64         m_sReferenceValue           = _pOriginal->m_sReferenceValue;
65         m_sNoCheckReferenceValue    = _pOriginal->m_sNoCheckReferenceValue;
66         m_eDefaultChecked           = _pOriginal->m_eDefaultChecked;
67         m_bSupportSecondRefValue    = _pOriginal->m_bSupportSecondRefValue;
68 
69         calculateExternalValueType();
70     }
71 
72 	//--------------------------------------------------------------------
73     OReferenceValueComponent::~OReferenceValueComponent()
74     {
75     }
76 
77     //--------------------------------------------------------------------
78     void OReferenceValueComponent::setReferenceValue( const ::rtl::OUString& _rRefValue )
79     {
80         m_sReferenceValue = _rRefValue;
81         calculateExternalValueType();
82     }
83 
84     //--------------------------------------------------------------------
85     void SAL_CALL OReferenceValueComponent::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
86     {
87 	    switch ( _nHandle )
88 	    {
89         case PROPERTY_ID_REFVALUE:          _rValue <<= m_sReferenceValue; break;
90 		case PROPERTY_ID_DEFAULT_STATE:    _rValue <<= (sal_Int16)m_eDefaultChecked; break;
91 
92         case PROPERTY_ID_UNCHECKED_REFVALUE:
93             OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::getFastPropertyValue: not supported!" );
94             _rValue <<= m_sNoCheckReferenceValue;
95             break;
96 
97         default:
98             OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
99         }
100     }
101 
102     //--------------------------------------------------------------------
103     void SAL_CALL OReferenceValueComponent::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
104     {
105         switch ( _nHandle )
106         {
107         case PROPERTY_ID_REFVALUE :
108             OSL_VERIFY( _rValue >>= m_sReferenceValue );
109             calculateExternalValueType();
110             break;
111 
112         case PROPERTY_ID_UNCHECKED_REFVALUE:
113             OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::setFastPropertyValue_NoBroadcast: not supported!" );
114             OSL_VERIFY( _rValue >>= m_sNoCheckReferenceValue );
115             break;
116 
117         case PROPERTY_ID_DEFAULT_STATE:
118         {
119             sal_Int16 nDefaultChecked( (sal_Int16)STATE_NOCHECK );
120 			OSL_VERIFY( _rValue >>= nDefaultChecked );
121             m_eDefaultChecked = (ToggleState)nDefaultChecked;
122 			resetNoBroadcast();
123         }
124 		break;
125 
126         default:
127             OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
128         }
129     }
130 
131     //--------------------------------------------------------------------
132     sal_Bool SAL_CALL OReferenceValueComponent::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
133     {
134         sal_Bool bModified = sal_False;
135 	    switch ( _nHandle )
136 	    {
137 		case PROPERTY_ID_REFVALUE:
138 			bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sReferenceValue );
139 			break;
140 
141         case PROPERTY_ID_UNCHECKED_REFVALUE:
142             OSL_ENSURE( m_bSupportSecondRefValue, "OReferenceValueComponent::convertFastPropertyValue: not supported!" );
143 			bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sNoCheckReferenceValue );
144             break;
145 
146         case PROPERTY_ID_DEFAULT_STATE:
147             bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_eDefaultChecked );
148             break;
149 
150         default:
151 			bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
152 			break;
153         }
154         return bModified;
155     }
156 
157     //------------------------------------------------------------------------------
158     Any OReferenceValueComponent::getDefaultForReset() const
159     {
160         return makeAny( (sal_Int16)m_eDefaultChecked );
161     }
162 
163     //--------------------------------------------------------------------
164     void OReferenceValueComponent::describeFixedProperties( Sequence< Property >& _rProps ) const
165     {
166         BEGIN_DESCRIBE_PROPERTIES( m_bSupportSecondRefValue ? 3 : 2, OBoundControlModel )
167             DECL_PROP1( REFVALUE,       ::rtl::OUString,    BOUND );
168             DECL_PROP1( DEFAULT_STATE, sal_Int16,          BOUND );
169             if ( m_bSupportSecondRefValue )
170             {
171                 DECL_PROP1( UNCHECKED_REFVALUE, ::rtl::OUString,    BOUND );
172             }
173         END_DESCRIBE_PROPERTIES();
174     }
175 
176     //-----------------------------------------------------------------------------
177     Sequence< Type > OReferenceValueComponent::getSupportedBindingTypes()
178     {
179         ::std::list< Type > aTypes;
180         aTypes.push_back( ::getCppuType( static_cast< sal_Bool* >( NULL ) ) );
181 
182         if ( m_sReferenceValue.getLength() )
183             aTypes.push_front( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) );
184             // push_front, because this is the preferred type
185 
186         Sequence< Type > aTypesRet( aTypes.size() );
187         ::std::copy( aTypes.begin(), aTypes.end(), aTypesRet.getArray() );
188         return aTypesRet;
189     }
190 
191     //-----------------------------------------------------------------------------
192     Any OReferenceValueComponent::translateExternalValueToControlValue( const Any& _rExternalValue ) const
193     {
194         sal_Int16 nState = STATE_DONTKNOW;
195 
196         sal_Bool bExternalState = sal_False;
197         ::rtl::OUString sExternalValue;
198         if ( _rExternalValue >>= bExternalState )
199         {
200             nState = ::sal::static_int_cast< sal_Int16 >( bExternalState ? STATE_CHECK : STATE_NOCHECK );
201         }
202         else if ( _rExternalValue >>= sExternalValue )
203         {
204             if ( sExternalValue == m_sReferenceValue )
205                 nState = STATE_CHECK;
206             else
207             {
208                 if ( !m_bSupportSecondRefValue || ( sExternalValue == m_sNoCheckReferenceValue ) )
209                     nState = STATE_NOCHECK;
210                 else
211                     nState = STATE_DONTKNOW;
212             }
213         }
214         else if ( !_rExternalValue.hasValue() )
215         {
216             nState = STATE_DONTKNOW;
217         }
218         else
219         {
220             OSL_ENSURE( false, "OReferenceValueComponent::translateExternalValueToControlValue: unexpected value type!" );
221         }
222 
223         return makeAny( nState );
224     }
225 
226     //-----------------------------------------------------------------------------
227     Any OReferenceValueComponent::translateControlValueToExternalValue( ) const
228     {
229         Any aExternalValue;
230 
231         try
232         {
233             Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
234             sal_Int16 nControlValue = STATE_DONTKNOW;
235 	        aControlValue >>= nControlValue;
236 
237             bool bBooleanExchange = getExternalValueType().getTypeClass() == TypeClass_BOOLEAN;
238             bool bStringExchange = getExternalValueType().getTypeClass() == TypeClass_STRING;
239             OSL_ENSURE( bBooleanExchange || bStringExchange,
240                 "OReferenceValueComponent::translateControlValueToExternalValue: unexpected value exchange type!" );
241 
242             switch( nControlValue )
243 	        {
244 		    case STATE_CHECK:
245                 if ( bBooleanExchange )
246                 {
247 			        aExternalValue <<= (sal_Bool)sal_True;
248                 }
249                 else if ( bStringExchange )
250                 {
251                     aExternalValue <<= m_sReferenceValue;
252                 }
253 			    break;
254 
255             case STATE_NOCHECK:
256                 if ( bBooleanExchange )
257                 {
258 			        aExternalValue <<= (sal_Bool)sal_False;
259                 }
260                 else if ( bStringExchange )
261                 {
262                     aExternalValue <<= m_bSupportSecondRefValue ? m_sNoCheckReferenceValue : ::rtl::OUString();
263                 }
264 			    break;
265 	        }
266         }
267         catch( const Exception& )
268         {
269         	OSL_ENSURE( sal_False, "OReferenceValueComponent::translateControlValueToExternalValue: caught an exception!" );
270         }
271 
272         return aExternalValue;
273     }
274 
275     //-----------------------------------------------------------------------------
276     Any OReferenceValueComponent::translateControlValueToValidatableValue( ) const
277     {
278         if ( !m_xAggregateSet.is() )
279             return Any();
280 
281         Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
282         sal_Int16 nControlValue = STATE_DONTKNOW;
283 	    aControlValue >>= nControlValue;
284 
285         Any aValidatableValue;
286         switch ( nControlValue )
287         {
288         case STATE_CHECK:
289             aValidatableValue <<= (sal_Bool)sal_True;
290             break;
291         case STATE_NOCHECK:
292             aValidatableValue <<= (sal_Bool)sal_False;
293             break;
294         }
295         return aValidatableValue;
296     }
297 
298 //........................................................................
299 } // namespace frm
300 //........................................................................
301 
302