1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "refvaluecomponent.hxx"
21 #include <property.hxx>
22 
23 #include <comphelper/property.hxx>
24 #include <tools/diagnose_ex.h>
25 
26 #include <vector>
27 
28 
29 namespace frm
30 {
31 
32 
33     using namespace ::com::sun::star::uno;
34     using namespace ::com::sun::star::lang;
35     using namespace ::com::sun::star::beans;
36     using namespace ::com::sun::star::form::binding;
37 
38 
39     //=
40 
41 
OReferenceValueComponent(const Reference<XComponentContext> & _rxFactory,const OUString & _rUnoControlModelTypeName,const OUString & _rDefault)42     OReferenceValueComponent::OReferenceValueComponent( const Reference< XComponentContext >& _rxFactory, const OUString& _rUnoControlModelTypeName, const OUString& _rDefault )
43         :OBoundControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, false, true, true )
44         ,m_eDefaultChecked( TRISTATE_FALSE )
45     {
46     }
47 
48 
OReferenceValueComponent(const OReferenceValueComponent * _pOriginal,const Reference<XComponentContext> & _rxFactory)49     OReferenceValueComponent::OReferenceValueComponent( const OReferenceValueComponent* _pOriginal, const Reference< XComponentContext>& _rxFactory )
50         :OBoundControlModel( _pOriginal, _rxFactory )
51     {
52         m_sReferenceValue           = _pOriginal->m_sReferenceValue;
53         m_sNoCheckReferenceValue    = _pOriginal->m_sNoCheckReferenceValue;
54         m_eDefaultChecked           = _pOriginal->m_eDefaultChecked;
55 
56         calculateExternalValueType();
57     }
58 
59 
~OReferenceValueComponent()60     OReferenceValueComponent::~OReferenceValueComponent()
61     {
62     }
63 
64 
setReferenceValue(const OUString & _rRefValue)65     void OReferenceValueComponent::setReferenceValue( const OUString& _rRefValue )
66     {
67         m_sReferenceValue = _rRefValue;
68         calculateExternalValueType();
69     }
70 
71 
getFastPropertyValue(Any & _rValue,sal_Int32 _nHandle) const72     void SAL_CALL OReferenceValueComponent::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
73     {
74         switch ( _nHandle )
75         {
76         case PROPERTY_ID_REFVALUE:          _rValue <<= m_sReferenceValue; break;
77         case PROPERTY_ID_DEFAULT_STATE:    _rValue <<= static_cast<sal_Int16>(m_eDefaultChecked); break;
78 
79         case PROPERTY_ID_UNCHECKED_REFVALUE:
80             _rValue <<= m_sNoCheckReferenceValue;
81             break;
82 
83         default:
84             OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
85         }
86     }
87 
88 
setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle,const Any & _rValue)89     void SAL_CALL OReferenceValueComponent::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue )
90     {
91         switch ( _nHandle )
92         {
93         case PROPERTY_ID_REFVALUE :
94             OSL_VERIFY( _rValue >>= m_sReferenceValue );
95             calculateExternalValueType();
96             break;
97 
98         case PROPERTY_ID_UNCHECKED_REFVALUE:
99             OSL_VERIFY( _rValue >>= m_sNoCheckReferenceValue );
100             break;
101 
102         case PROPERTY_ID_DEFAULT_STATE:
103         {
104             sal_Int16 nDefaultChecked;
105             if (!(_rValue >>= nDefaultChecked) || nDefaultChecked < 0
106                 || nDefaultChecked > 2)
107             {
108                 throw css::lang::IllegalArgumentException(
109                     ("DefaultState property value must be a SHORT in the range"
110                      " 0--2"),
111                     css::uno::Reference<css::uno::XInterface>(), -1);
112             }
113             m_eDefaultChecked = static_cast<ToggleState>(nDefaultChecked);
114             resetNoBroadcast();
115         }
116         break;
117 
118         default:
119             OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
120         }
121     }
122 
123 
convertFastPropertyValue(Any & _rConvertedValue,Any & _rOldValue,sal_Int32 _nHandle,const Any & _rValue)124     sal_Bool SAL_CALL OReferenceValueComponent::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue )
125     {
126         bool bModified = false;
127         switch ( _nHandle )
128         {
129         case PROPERTY_ID_REFVALUE:
130             bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sReferenceValue );
131             break;
132 
133         case PROPERTY_ID_UNCHECKED_REFVALUE:
134             bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_sNoCheckReferenceValue );
135             break;
136 
137         case PROPERTY_ID_DEFAULT_STATE:
138             bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, static_cast<sal_Int16>(m_eDefaultChecked) );
139             break;
140 
141         default:
142             bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
143             break;
144         }
145         return bModified;
146     }
147 
148 
getDefaultForReset() const149     Any OReferenceValueComponent::getDefaultForReset() const
150     {
151         return makeAny( static_cast<sal_Int16>(m_eDefaultChecked) );
152     }
153 
154 
describeFixedProperties(Sequence<Property> & _rProps) const155     void OReferenceValueComponent::describeFixedProperties( Sequence< Property >& _rProps ) const
156     {
157         BEGIN_DESCRIBE_PROPERTIES( 3, OBoundControlModel )
158             DECL_PROP1( REFVALUE,       OUString,    BOUND );
159             DECL_PROP1( DEFAULT_STATE, sal_Int16,          BOUND );
160             DECL_PROP1( UNCHECKED_REFVALUE, OUString,    BOUND );
161         END_DESCRIBE_PROPERTIES();
162     }
163 
164 
getSupportedBindingTypes()165     Sequence< Type > OReferenceValueComponent::getSupportedBindingTypes()
166     {
167         ::std::vector< Type > aTypes;
168 
169         if ( !m_sReferenceValue.isEmpty() )
170             aTypes.push_back( cppu::UnoType<OUString>::get() );
171 
172         aTypes.push_back( cppu::UnoType<sal_Bool>::get() );
173 
174         return comphelper::containerToSequence(aTypes);
175     }
176 
177 
translateExternalValueToControlValue(const Any & _rExternalValue) const178     Any OReferenceValueComponent::translateExternalValueToControlValue( const Any& _rExternalValue ) const
179     {
180         sal_Int16 nState = TRISTATE_INDET;
181 
182         bool bExternalState = false;
183         OUString sExternalValue;
184         if ( _rExternalValue >>= bExternalState )
185         {
186             nState = ::sal::static_int_cast< sal_Int16 >( bExternalState ? TRISTATE_TRUE : TRISTATE_FALSE );
187         }
188         else if ( _rExternalValue >>= sExternalValue )
189         {
190             if ( sExternalValue == m_sReferenceValue )
191                 nState = TRISTATE_TRUE;
192             else
193             {
194                 if ( sExternalValue == m_sNoCheckReferenceValue )
195                     nState = TRISTATE_FALSE;
196                 else
197                     nState = TRISTATE_INDET;
198             }
199         }
200         else if ( !_rExternalValue.hasValue() )
201         {
202             nState = TRISTATE_INDET;
203         }
204         else
205         {
206             OSL_FAIL( "OReferenceValueComponent::translateExternalValueToControlValue: unexpected value type!" );
207         }
208 
209         return makeAny( nState );
210     }
211 
212 
translateControlValueToExternalValue() const213     Any OReferenceValueComponent::translateControlValueToExternalValue( ) const
214     {
215         Any aExternalValue;
216 
217         try
218         {
219             Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
220             sal_Int16 nControlValue = TRISTATE_INDET;
221             aControlValue >>= nControlValue;
222 
223             bool bBooleanExchange = getExternalValueType().getTypeClass() == TypeClass_BOOLEAN;
224             bool bStringExchange = getExternalValueType().getTypeClass() == TypeClass_STRING;
225             OSL_ENSURE( bBooleanExchange || bStringExchange,
226                 "OReferenceValueComponent::translateControlValueToExternalValue: unexpected value exchange type!" );
227 
228             switch( nControlValue )
229             {
230             case TRISTATE_TRUE:
231                 if ( bBooleanExchange )
232                 {
233                     aExternalValue <<= true;
234                 }
235                 else if ( bStringExchange )
236                 {
237                     aExternalValue <<= m_sReferenceValue;
238                 }
239                 break;
240 
241             case TRISTATE_FALSE:
242                 if ( bBooleanExchange )
243                 {
244                     aExternalValue <<= false;
245                 }
246                 else if ( bStringExchange )
247                 {
248                     aExternalValue <<= m_sNoCheckReferenceValue;
249                 }
250                 break;
251             }
252         }
253         catch( const Exception& )
254         {
255             TOOLS_WARN_EXCEPTION( "forms.component", "OReferenceValueComponent::translateControlValueToExternalValue" );
256         }
257 
258         return aExternalValue;
259     }
260 
261 
translateControlValueToValidatableValue() const262     Any OReferenceValueComponent::translateControlValueToValidatableValue( ) const
263     {
264         if ( !m_xAggregateSet.is() )
265             return Any();
266 
267         Any aControlValue( m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) );
268         sal_Int16 nControlValue = TRISTATE_INDET;
269         aControlValue >>= nControlValue;
270 
271         Any aValidatableValue;
272         switch ( nControlValue )
273         {
274         case TRISTATE_TRUE:
275             aValidatableValue <<= true;
276             break;
277         case TRISTATE_FALSE:
278             aValidatableValue <<= false;
279             break;
280         }
281         return aValidatableValue;
282     }
283 
284 
285 } // namespace frm
286 
287 
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
289