LibreOffice Module forms (master) 1
RadioButton.cxx
Go to the documentation of this file.
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 "RadioButton.hxx"
21#include "GroupManager.hxx"
22#include <property.hxx>
23#include <services.hxx>
26#include <tools/debug.hxx>
27#include <com/sun/star/beans/PropertyAttribute.hpp>
28#include <com/sun/star/container/XIndexAccess.hpp>
29#include <com/sun/star/form/FormComponentType.hpp>
30
31namespace frm
32{
33using namespace ::com::sun::star::uno;
34using namespace ::com::sun::star::sdb;
35using namespace ::com::sun::star::sdbc;
36using namespace ::com::sun::star::beans;
37using namespace ::com::sun::star::container;
38using namespace ::com::sun::star::form;
39using namespace ::com::sun::star::awt;
40using namespace ::com::sun::star::io;
41using namespace ::com::sun::star::lang;
42using namespace ::com::sun::star::util;
43using namespace ::com::sun::star::form::binding;
44
45
46css::uno::Sequence<OUString> SAL_CALL ORadioButtonControl::getSupportedServiceNames()
47{
48 css::uno::Sequence<OUString> aSupported = OBoundControl::getSupportedServiceNames();
49 aSupported.realloc(aSupported.getLength() + 2);
50
51 OUString* pArray = aSupported.getArray();
52 pArray[aSupported.getLength()-2] = FRM_SUN_CONTROL_RADIOBUTTON;
53 pArray[aSupported.getLength()-1] = STARDIV_ONE_FORM_CONTROL_RADIOBUTTON;
54 return aSupported;
55}
56
57
58ORadioButtonControl::ORadioButtonControl(const Reference<XComponentContext>& _rxFactory)
60{
61}
62
63
64ORadioButtonModel::ORadioButtonModel(const Reference<XComponentContext>& _rxFactory)
66 // use the old control name for compytibility reasons
67{
68
69 m_nClassId = FormComponentType::RADIOBUTTON;
70 m_aLabelServiceName = FRM_SUN_COMPONENT_GROUPBOX;
71 initValueProperty( PROPERTY_STATE, PROPERTY_ID_STATE );
72 startAggregatePropertyListening( PROPERTY_GROUP_NAME );
73}
74
75
76ORadioButtonModel::ORadioButtonModel( const ORadioButtonModel* _pOriginal, const Reference<XComponentContext>& _rxFactory )
77 :OReferenceValueComponent( _pOriginal, _rxFactory )
78{
79}
80
81
83{
84}
85
86// XCloneable
87
88css::uno::Reference< css::util::XCloneable > SAL_CALL ORadioButtonModel::createClone()
89{
91 pClone->clonedFrom(this);
92 return pClone;
93}
94
95// XServiceInfo
96
97css::uno::Sequence<OUString> SAL_CALL ORadioButtonModel::getSupportedServiceNames()
98{
99 css::uno::Sequence<OUString> aSupported = OReferenceValueComponent::getSupportedServiceNames();
100
101 sal_Int32 nOldLen = aSupported.getLength();
102 aSupported.realloc( nOldLen + 9 );
103 OUString* pStoreTo = aSupported.getArray() + nOldLen;
104
105 *pStoreTo++ = BINDABLE_CONTROL_MODEL;
106 *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
107 *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
108
111
112 *pStoreTo++ = FRM_SUN_COMPONENT_RADIOBUTTON;
114 *pStoreTo++ = BINDABLE_DATABASE_RADIO_BUTTON;
115
116 *pStoreTo++ = FRM_COMPONENT_RADIOBUTTON;
117
118 return aSupported;
119}
120
121
122void ORadioButtonModel::SetSiblingPropsTo(const OUString& rPropName, const Any& rValue)
123{
124 // my name
125 OUString sMyGroup;
128 if (sMyGroup.isEmpty())
129 sMyGroup = m_aName;
130
131 // Iterate over my siblings
132 Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
133 if (!xIndexAccess.is())
134 return;
135
136 Reference<XPropertySet> xMyProps = this;
137 OUString sCurrentGroup;
138 sal_Int32 nNumSiblings = xIndexAccess->getCount();
139 for (sal_Int32 i=0; i<nNumSiblings; ++i)
140 {
141 Reference<XPropertySet> xSiblingProperties(xIndexAccess->getByIndex(i), UNO_QUERY);
142 if (!xSiblingProperties.is())
143 continue;
144 if (xMyProps == xSiblingProperties)
145 continue; // do not set myself
146
147 // Only if it's a RadioButton
148 if (!hasProperty(PROPERTY_CLASSID, xSiblingProperties))
149 continue;
150 sal_Int16 nType = 0;
151 xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
152 if (nType != FormComponentType::RADIOBUTTON)
153 continue;
154
155 // The group association is attached to the name
156 sCurrentGroup = OGroupManager::GetGroupName( xSiblingProperties );
157 if (sCurrentGroup == sMyGroup)
158 xSiblingProperties->setPropertyValue(rPropName, rValue);
159 }
160}
161
162
163void ORadioButtonModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue)
164{
166
167 // if the label control changed ...
169 { // ... forward this to our siblings
171 }
172
173 // If the ControlSource property has changed ...
175 { // ... I have to pass the new ControlSource to my siblings, which are in the same RadioButton group as I am
177 }
178
179 // The other way: if my name changes ...
181 {
183 }
184
186 return;
187
188 sal_Int16 nValue;
189 rValue >>= nValue;
190 if (1 == nValue)
191 { // Reset the 'default checked' for all Radios of the same group.
192 // Because (as the Highlander already knew): "There can be only one"
193 Any aZero;
194 nValue = 0;
195 aZero <<= nValue;
197 }
198}
199
201{
202 Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
203 if (!xIndexAccess.is())
204 return;
205
206 OUString sName, sGroupName;
207
211
212 Reference<XPropertySet> xMyProps = this;
213 for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
214 {
215 Reference<XPropertySet> xSiblingProperties(xIndexAccess->getByIndex(i), UNO_QUERY);
216 if (!xSiblingProperties.is())
217 continue;
218
219 if (xMyProps == xSiblingProperties)
220 // Only if I didn't find myself
221 continue;
222
223 sal_Int16 nType = 0;
224 xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
225 if (nType != FormComponentType::RADIOBUTTON)
226 // Only RadioButtons
227 continue;
228
229 OUString sSiblingName, sSiblingGroupName;
230 if (hasProperty(PROPERTY_GROUP_NAME, xSiblingProperties))
231 xSiblingProperties->getPropertyValue(PROPERTY_GROUP_NAME) >>= sSiblingGroupName;
232 xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sSiblingName;
233
234 if ((sGroupName.isEmpty() && sSiblingGroupName.isEmpty() && // (no group name
235 sName == sSiblingName) || // names match) or
236 (!sGroupName.isEmpty() && !sSiblingGroupName.isEmpty() && // (have group name
237 sGroupName == sSiblingGroupName)) // they match)
238 {
239 setPropertyValue(PROPERTY_CONTROLSOURCE, xSiblingProperties->getPropertyValue(PROPERTY_CONTROLSOURCE));
240 break;
241 }
242 }
243}
244
245
246void ORadioButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
247{
249 sal_Int32 nOldCount = _rProps.getLength();
250 _rProps.realloc( nOldCount + 1);
251 css::beans::Property* pProperties = _rProps.getArray() + nOldCount;
252 *pProperties++ = css::beans::Property(PROPERTY_TABINDEX, PROPERTY_ID_TABINDEX, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND);
253 DBG_ASSERT( pProperties == _rProps.getArray() + _rProps.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?");
254}
255
256
258{
259 return FRM_COMPONENT_RADIOBUTTON; // old (non-sun) name for compatibility !
260}
261
262
263void SAL_CALL ORadioButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
264{
266
267 // Version
268 _rxOutStream->writeShort(0x0003);
269
270 // Properties
271 _rxOutStream << getReferenceValue();
272 _rxOutStream << static_cast<sal_Int16>(getDefaultChecked());
273 writeHelpTextCompatibly(_rxOutStream);
274
275 // from version 0x0003 : common properties
276 writeCommonProperties(_rxOutStream);
277}
278
279
280void SAL_CALL ORadioButtonModel::read(const Reference<XObjectInputStream>& _rxInStream)
281{
283 ::osl::MutexGuard aGuard(m_aMutex);
284
285 // Version
286 sal_uInt16 nVersion = _rxInStream->readShort();
287
288 OUString sReferenceValue;
289 sal_Int16 nDefaultChecked( 0 );
290 switch (nVersion)
291 {
292 case 0x0001 :
293 _rxInStream >> sReferenceValue;
294 _rxInStream >> nDefaultChecked;
295 break;
296 case 0x0002 :
297 _rxInStream >> sReferenceValue;
298 _rxInStream >> nDefaultChecked;
299 readHelpTextCompatibly(_rxInStream);
300 break;
301 case 0x0003 :
302 _rxInStream >> sReferenceValue;
303 _rxInStream >> nDefaultChecked;
304 readHelpTextCompatibly(_rxInStream);
305 readCommonProperties(_rxInStream);
306 break;
307 default :
308 OSL_FAIL("ORadioButtonModel::read : unknown version !");
310 break;
311 }
312
313 setReferenceValue( sReferenceValue );
314 setDefaultChecked( static_cast<ToggleState>(nDefaultChecked) );
315
316 // Display default values after read
317 if ( !getControlSource().isEmpty() )
318 // (not if we don't have a control source - the "State" property acts like it is persistent, then
320}
321
322
323void ORadioButtonModel::_propertyChanged(const PropertyChangeEvent& _rEvent)
324{
325 if ( _rEvent.PropertyName == PROPERTY_STATE )
326 {
327 if ( _rEvent.NewValue == sal_Int16(1) )
328 {
329 // If my status has changed to 'checked', I have to reset all my siblings, which are in the same group as I am
330 Any aZero;
331 aZero <<= sal_Int16(0);
333 }
334 }
335 else if ( _rEvent.PropertyName == PROPERTY_GROUP_NAME )
336 {
338 // Can't call OReferenceValueComponent::_propertyChanged(), as it
339 // doesn't know what to do with the GroupName property.
340 return;
341 }
342
344}
345
346
348{
349 return Any( static_cast<sal_Int16>( ( m_xColumn->getString() == getReferenceValue() ) ? TRISTATE_TRUE : TRISTATE_FALSE )
350 );
351}
352
353
355{
357 sal_Int16 nState = TRISTATE_FALSE;
358 if ( ( aControlValue >>= nState ) && ( nState == TRISTATE_INDET ) )
359 // radio buttons do not have the DONTKNOW state
360 aControlValue <<= sal_Int16(TRISTATE_FALSE);
361 return aControlValue;
362}
363
364
366{
367 Reference< XPropertySet > xField( getField() );
368 OSL_PRECOND( xField.is(), "ORadioButtonModel::commitControlValueToDbColumn: not bound!" );
369 if ( xField.is() )
370 {
371 try
372 {
373 sal_Int16 nValue = 0;
374 m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) >>= nValue;
375 if ( nValue == 1 )
376 xField->setPropertyValue( PROPERTY_VALUE, Any( getReferenceValue() ) );
377 }
378 catch(const Exception&)
379 {
380 OSL_FAIL("ORadioButtonModel::commitControlValueToDbColumn: could not commit !");
381 }
382 }
383 return true;
384}
385
386}
387
388extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
389com_sun_star_form_ORadioButtonModel_get_implementation(css::uno::XComponentContext* component,
390 css::uno::Sequence<css::uno::Any> const &)
391{
392 return cppu::acquire(new frm::ORadioButtonModel(component));
393}
394
395extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
396com_sun_star_form_ORadioButtonControl_get_implementation(css::uno::XComponentContext* component,
397 css::uno::Sequence<css::uno::Any> const &)
398{
399 return cppu::acquire(new frm::ORadioButtonControl(component));
400}
401
402/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_form_ORadioButtonControl_get_implementation(css::uno::XComponentContext *component, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_form_ORadioButtonModel_get_implementation(css::uno::XComponentContext *component, css::uno::Sequence< css::uno::Any > const &)
void writeCommonProperties(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream)
We can't write (new) common properties in this base class, as the file format doesn't allow this (unf...
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::sdb::XColumn > m_xColumn
virtual void resetNoBroadcast()
called to reset the control to some kind of default.
const OUString & getControlSource() const
virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream > &OutStream) override
virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream > &InStream) override
void readCommonProperties(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream)
const css::uno::Reference< css::beans::XPropertySet > & getField() const
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &_rEvt) override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
::osl::Mutex m_aMutex
const css::uno::Reference< css::uno::XComponentContext > & getContext() const
void writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream)
void readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
static OUString GetGroupName(const css::uno::Reference< css::beans::XPropertySet > &xComponent)
ORadioButtonControl(const css::uno::Reference< css::uno::XComponentContext > &_rxFactory)
Definition: RadioButton.cxx:58
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: RadioButton.cxx:46
virtual ~ORadioButtonModel() override
Definition: RadioButton.cxx:82
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual css::uno::Any translateExternalValueToControlValue(const css::uno::Any &_rExternalValue) const override
translates the given value, which was obtained from the current external value binding,...
virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream) override
virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream) override
virtual css::uno::Any translateDbColumnToControlValue() override
translates a db column value into a control value.
virtual bool commitControlValueToDbColumn(bool _bPostReset) override
commits the current control value to the database column we're bound to @precond we're properly bound...
void SetSiblingPropsTo(const OUString &rPropName, const css::uno::Any &rValue)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: RadioButton.cxx:97
virtual OUString SAL_CALL getServiceName() override
virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override
Definition: RadioButton.cxx:88
virtual void describeFixedProperties(css::uno::Sequence< css::beans::Property > &_rProps) const override
describes the properties provided by this class, or its respective derived class
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &evt) override
ORadioButtonModel(const css::uno::Reference< css::uno::XComponentContext > &_rxFactory)
an OBoundControlModel which features the exchange of a reference value
void setDefaultChecked(ToggleState _eChecked)
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
const OUString & getReferenceValue() const
ToggleState getDefaultChecked() const
virtual void describeFixedProperties(css::uno::Sequence< css::beans::Property > &_rProps) const override
describes the properties provided by this class, or its respective derived class
virtual css::uno::Any translateExternalValueToControlValue(const css::uno::Any &_rExternalValue) const override
translates the given value, which was obtained from the current external value binding,...
void setReferenceValue(const OUString &_rRefValue)
#define DBG_ASSERT(sCon, aError)
sal_Int32 nState
sal_Int16 nVersion
sal_Int16 nValue
OUString sName
constexpr OUStringLiteral PROPERTY_TABINDEX
Definition: frm_strings.hxx:26
constexpr OUStringLiteral PROPERTY_NAME
Definition: frm_strings.hxx:28
constexpr OUStringLiteral PROPERTY_GROUP_NAME
Definition: frm_strings.hxx:29
constexpr OUStringLiteral PROPERTY_CONTROLSOURCE
Definition: frm_strings.hxx:38
constexpr OUStringLiteral PROPERTY_CONTROLLABEL
constexpr OUStringLiteral PROPERTY_STATE
Definition: frm_strings.hxx:58
constexpr OUStringLiteral PROPERTY_DEFAULT_STATE
Definition: frm_strings.hxx:65
constexpr OUStringLiteral PROPERTY_CLASSID
Definition: frm_strings.hxx:30
constexpr OUStringLiteral PROPERTY_VALUE
Definition: frm_strings.hxx:32
@ Exception
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
ListBox is a bit confusing / different from other form components, so here are a few notes:
Definition: BaseListBox.hxx:25
ToggleState
Definition: togglestate.hxx:27
@ TRISTATE_INDET
Definition: togglestate.hxx:27
@ TRISTATE_FALSE
Definition: togglestate.hxx:27
@ TRISTATE_TRUE
Definition: togglestate.hxx:27
int i
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
#define PROPERTY_ID_NAME
Definition: property.hxx:40
#define PROPERTY_ID_DEFAULT_STATE
Definition: property.hxx:112
#define PROPERTY_ID_CONTROLLABEL
Definition: property.hxx:205
#define PROPERTY_ID_STATE
Definition: property.hxx:87
#define PROPERTY_ID_CONTROLSOURCE
Definition: property.hxx:42
#define PROPERTY_ID_TABINDEX
Definition: property.hxx:41
QPRO_FUNC_TYPE nType
sal_Int32 nHandle
constexpr OUStringLiteral VCL_CONTROL_RADIOBUTTON
Definition: services.hxx:26
constexpr OUStringLiteral FRM_SUN_COMPONENT_DATABASE_RADIOBUTTON
Definition: services.hxx:138
constexpr OUStringLiteral FRM_SUN_COMPONENT_RADIOBUTTON
Definition: services.hxx:116
constexpr OUStringLiteral BINDABLE_DATABASE_RADIO_BUTTON
Definition: services.hxx:174
constexpr OUStringLiteral VALIDATABLE_BINDABLE_CONTROL_MODEL
Definition: services.hxx:184
constexpr OUStringLiteral BINDABLE_DATA_AWARE_CONTROL_MODEL
Definition: services.hxx:181
constexpr OUStringLiteral DATA_AWARE_CONTROL_MODEL
Definition: services.hxx:182
constexpr OUStringLiteral FRM_SUN_COMPONENT_GROUPBOX
Definition: services.hxx:117
constexpr OUStringLiteral VALIDATABLE_CONTROL_MODEL
Definition: services.hxx:183
constexpr OUStringLiteral FRM_SUN_CONTROL_RADIOBUTTON
Definition: services.hxx:153
constexpr OUStringLiteral FRM_COMPONENT_RADIOBUTTON
Definition: services.hxx:69
constexpr OUStringLiteral STARDIV_ONE_FORM_CONTROL_RADIOBUTTON
Definition: services.hxx:90
constexpr OUStringLiteral BINDABLE_CONTROL_MODEL
Definition: services.hxx:179
constexpr OUStringLiteral VCL_CONTROLMODEL_RADIOBUTTON
Definition: services.hxx:42