1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <property.hxx>
23 #include <services.hxx>
25 #include <com/sun/star/awt/XVclWindowPeer.hpp>
26 #include <com/sun/star/form/FormComponentType.hpp>
28 #include <comphelper/streamsection.hxx>
29 #include <comphelper/basicio.hxx>
30 #include <comphelper/property.hxx>
31 #include <o3tl/any.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <tools/debug.hxx>
34 #include <tools/urlobj.hxx>
35 #include <vcl/svapp.hxx>
36 #include <osl/mutex.hxx>
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::sdb
;
44 using namespace ::com::sun::star::sdbc
;
45 using namespace ::com::sun::star::beans
;
46 using namespace ::com::sun::star::container
;
47 using namespace ::com::sun::star::form
;
48 using namespace ::com::sun::star::awt
;
49 using namespace ::com::sun::star::io
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star::util
;
52 using ::com::sun::star::frame::XDispatchProviderInterceptor
;
58 OButtonModel::OButtonModel(const Reference
<XComponentContext
>& _rxFactory
)
59 :OClickableImageBaseModel( _rxFactory
, VCL_CONTROLMODEL_COMMANDBUTTON
, FRM_SUN_CONTROL_COMMANDBUTTON
)
60 // use the old control name for compatibility reasons
61 ,m_aResetHelper( *this, m_aMutex
)
62 ,m_eDefaultState( TRISTATE_FALSE
)
64 m_nClassId
= FormComponentType::COMMANDBUTTON
;
68 Any SAL_CALL
OButtonModel::queryAggregation( const Type
& _type
)
70 Any aReturn
= OClickableImageBaseModel::queryAggregation( _type
);
71 if ( !aReturn
.hasValue() )
72 aReturn
= OButtonModel_Base::queryInterface( _type
);
77 Sequence
< Type
> OButtonModel::_getTypes()
79 return ::comphelper::concatSequences(
80 OClickableImageBaseModel::_getTypes(),
81 OButtonModel_Base::getTypes()
86 OButtonModel::OButtonModel( const OButtonModel
* _pOriginal
, const Reference
<XComponentContext
>& _rxFactory
)
87 :OClickableImageBaseModel( _pOriginal
, _rxFactory
)
88 ,m_aResetHelper( *this, m_aMutex
)
89 ,m_eDefaultState( _pOriginal
->m_eDefaultState
)
91 m_nClassId
= FormComponentType::COMMANDBUTTON
;
93 implInitializeImageURL();
97 OButtonModel::~OButtonModel()
102 void OButtonModel::describeFixedProperties( Sequence
< Property
>& _rProps
) const
104 OClickableImageBaseModel::describeFixedProperties( _rProps
);
105 sal_Int32 nOldCount
= _rProps
.getLength();
106 _rProps
.realloc( nOldCount
+ 6);
107 css::beans::Property
* pProperties
= _rProps
.getArray() + nOldCount
;
108 *pProperties
++ = css::beans::Property(PROPERTY_BUTTONTYPE
, PROPERTY_ID_BUTTONTYPE
, cppu::UnoType
<FormButtonType
>::get(), css::beans::PropertyAttribute::BOUND
);
109 *pProperties
++ = css::beans::Property(PROPERTY_DEFAULT_STATE
, PROPERTY_ID_DEFAULT_STATE
, cppu::UnoType
<sal_Int16
>::get(), css::beans::PropertyAttribute::BOUND
);
110 *pProperties
++ = css::beans::Property(PROPERTY_DISPATCHURLINTERNAL
, PROPERTY_ID_DISPATCHURLINTERNAL
, cppu::UnoType
<sal_Bool
>::get(), css::beans::PropertyAttribute::BOUND
);
111 *pProperties
++ = css::beans::Property(PROPERTY_TARGET_URL
, PROPERTY_ID_TARGET_URL
, cppu::UnoType
<OUString
>::get(), css::beans::PropertyAttribute::BOUND
);
112 *pProperties
++ = css::beans::Property(PROPERTY_TARGET_FRAME
, PROPERTY_ID_TARGET_FRAME
, cppu::UnoType
<OUString
>::get(), css::beans::PropertyAttribute::BOUND
);
113 *pProperties
++ = css::beans::Property(PROPERTY_TABINDEX
, PROPERTY_ID_TABINDEX
, cppu::UnoType
<sal_Int16
>::get(), css::beans::PropertyAttribute::BOUND
);
114 DBG_ASSERT( pProperties
== _rProps
.getArray() + _rProps
.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?");
118 css::uno::Reference
< css::util::XCloneable
> SAL_CALL
OButtonModel::createClone()
120 rtl::Reference
<OButtonModel
> pClone
= new OButtonModel(this, getContext());
121 pClone
->clonedFrom(this);
128 css::uno::Sequence
<OUString
> OButtonModel::getSupportedServiceNames()
130 css::uno::Sequence
<OUString
> aSupported
= OClickableImageBaseModel::getSupportedServiceNames();
131 aSupported
.realloc( aSupported
.getLength() + 2 );
133 OUString
* pArray
= aSupported
.getArray();
134 pArray
[ aSupported
.getLength() - 2 ] = FRM_SUN_COMPONENT_COMMANDBUTTON
;
135 pArray
[ aSupported
.getLength() - 1 ] = FRM_COMPONENT_COMMANDBUTTON
;
141 OUString
OButtonModel::getServiceName()
143 return FRM_COMPONENT_COMMANDBUTTON
; // old (non-sun) name for compatibility !
147 void OButtonModel::write(const Reference
<XObjectOutputStream
>& _rxOutStream
)
149 OClickableImageBaseModel::write(_rxOutStream
);
151 _rxOutStream
->writeShort(0x0003); // Version
154 OStreamSection
aSection( _rxOutStream
);
155 // this will allow readers to skip unknown bytes in their dtor
157 _rxOutStream
->writeShort( static_cast<sal_uInt16
>(m_eButtonType
) );
159 OUString sTmp
= INetURLObject::decode( m_sTargetURL
, INetURLObject::DecodeMechanism::Unambiguous
);
160 _rxOutStream
<< sTmp
;
161 _rxOutStream
<< m_sTargetFrame
;
162 writeHelpTextCompatibly(_rxOutStream
);
163 _rxOutStream
<< isDispatchUrlInternal();
168 void OButtonModel::read(const Reference
<XObjectInputStream
>& _rxInStream
)
170 OClickableImageBaseModel::read(_rxInStream
);
172 sal_uInt16 nVersion
= _rxInStream
->readShort(); // Version
177 m_eButtonType
= static_cast<FormButtonType
>(_rxInStream
->readShort());
179 _rxInStream
>> m_sTargetURL
;
180 _rxInStream
>> m_sTargetFrame
;
186 m_eButtonType
= static_cast<FormButtonType
>(_rxInStream
->readShort());
188 _rxInStream
>> m_sTargetURL
;
189 _rxInStream
>> m_sTargetFrame
;
190 readHelpTextCompatibly(_rxInStream
);
196 OStreamSection
aSection( _rxInStream
);
197 // this will skip any unknown bytes in its dtor
200 m_eButtonType
= static_cast<FormButtonType
>(_rxInStream
->readShort());
203 _rxInStream
>> m_sTargetURL
;
206 _rxInStream
>> m_sTargetFrame
;
209 readHelpTextCompatibly(_rxInStream
);
213 _rxInStream
>> bDispatch
;
214 setDispatchUrlInternal(bDispatch
);
219 OSL_FAIL("OButtonModel::read : unknown version !");
220 m_eButtonType
= FormButtonType_PUSH
;
221 m_sTargetURL
.clear();
222 m_sTargetFrame
.clear();
228 void SAL_CALL
OButtonModel::disposing()
230 m_aResetHelper
.disposing();
231 OClickableImageBaseModel::disposing();
235 void SAL_CALL
OButtonModel::reset()
237 if ( !m_aResetHelper
.approveReset() )
240 impl_resetNoBroadcast_nothrow();
242 m_aResetHelper
.notifyResetted();
246 void SAL_CALL
OButtonModel::addResetListener( const Reference
< XResetListener
>& _listener
)
248 m_aResetHelper
.addResetListener( _listener
);
252 void SAL_CALL
OButtonModel::removeResetListener( const Reference
< XResetListener
>& _listener
)
254 m_aResetHelper
.removeResetListener( _listener
);
258 void SAL_CALL
OButtonModel::getFastPropertyValue( Any
& _rValue
, sal_Int32 _nHandle
) const
262 case PROPERTY_ID_DEFAULT_STATE
:
263 _rValue
<<= static_cast<sal_Int16
>(m_eDefaultState
);
267 OClickableImageBaseModel::getFastPropertyValue( _rValue
, _nHandle
);
273 void SAL_CALL
OButtonModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle
, const Any
& _rValue
)
277 case PROPERTY_ID_DEFAULT_STATE
:
279 sal_Int16 nDefaultState
= sal_Int16(TRISTATE_FALSE
);
280 OSL_VERIFY( _rValue
>>= nDefaultState
);
281 m_eDefaultState
= static_cast<ToggleState
>(nDefaultState
);
282 impl_resetNoBroadcast_nothrow();
287 OClickableImageBaseModel::setFastPropertyValue_NoBroadcast( _nHandle
, _rValue
);
293 sal_Bool SAL_CALL
OButtonModel::convertFastPropertyValue( Any
& _rConvertedValue
, Any
& _rOldValue
, sal_Int32 _nHandle
, const Any
& _rValue
)
295 bool bModified
= false;
298 case PROPERTY_ID_DEFAULT_STATE
:
299 bModified
= tryPropertyValue( _rConvertedValue
, _rOldValue
, _rValue
, static_cast<sal_Int16
>(m_eDefaultState
) );
303 bModified
= OClickableImageBaseModel::convertFastPropertyValue( _rConvertedValue
, _rOldValue
, _nHandle
, _rValue
);
310 Any
OButtonModel::getPropertyDefaultByHandle( sal_Int32 _nHandle
) const
315 case PROPERTY_ID_DEFAULT_STATE
:
316 aDefault
<<= sal_Int16(TRISTATE_FALSE
);
320 aDefault
= OClickableImageBaseModel::getPropertyDefaultByHandle( _nHandle
);
327 void OButtonModel::impl_resetNoBroadcast_nothrow()
331 setPropertyValue( PROPERTY_STATE
, getPropertyValue( PROPERTY_DEFAULT_STATE
) );
333 catch( const Exception
& )
335 DBG_UNHANDLED_EXCEPTION("forms.component");
343 Sequence
<Type
> OButtonControl::_getTypes()
345 return ::comphelper::concatSequences(
346 OButtonControl_BASE::getTypes(),
347 OClickableImageBaseControl::_getTypes(),
348 OFormNavigationHelper::getTypes()
353 css::uno::Sequence
<OUString
> OButtonControl::getSupportedServiceNames()
355 css::uno::Sequence
<OUString
> aSupported
= OClickableImageBaseControl::getSupportedServiceNames();
356 aSupported
.realloc(aSupported
.getLength() + 2);
358 OUString
*pArray
= aSupported
.getArray();
359 pArray
[aSupported
.getLength()-2] = FRM_SUN_CONTROL_COMMANDBUTTON
;
360 pArray
[aSupported
.getLength()-1] = STARDIV_ONE_FORM_CONTROL_COMMANDBUTTON
;
365 OButtonControl::OButtonControl(const Reference
<XComponentContext
>& _rxFactory
)
366 :OClickableImageBaseControl(_rxFactory
, VCL_CONTROL_COMMANDBUTTON
)
367 ,OFormNavigationHelper( _rxFactory
)
368 ,m_nClickEvent( nullptr )
369 ,m_nTargetUrlFeatureId( -1 )
370 ,m_bEnabledByPropertyValue( false )
372 osl_atomic_increment(&m_refCount
);
374 // Register as ActionListener
375 Reference
<XButton
> xButton
;
376 query_aggregation( m_xAggregate
, xButton
);
378 xButton
->addActionListener(this);
380 // For Listener: refcount at one
381 osl_atomic_decrement(&m_refCount
);
385 OButtonControl::~OButtonControl()
388 Application::RemoveUserEvent(m_nClickEvent
);
393 Any SAL_CALL
OButtonControl::queryAggregation(const Type
& _rType
)
395 // if asked for the XTypeProvider, don't let OButtonControl_BASE do this
397 if ( !_rType
.equals( cppu::UnoType
<XTypeProvider
>::get() ) )
398 aReturn
= OButtonControl_BASE::queryInterface( _rType
);
400 if ( !aReturn
.hasValue() )
401 aReturn
= OClickableImageBaseControl::queryAggregation( _rType
);
403 if ( !aReturn
.hasValue() )
404 aReturn
= OFormNavigationHelper::queryInterface( _rType
);
410 void SAL_CALL
OButtonControl::disposing()
412 startOrStopModelPropertyListening( false );
414 OClickableImageBaseControl::disposing();
415 OFormNavigationHelper::dispose();
419 void SAL_CALL
OButtonControl::disposing( const EventObject
& _rSource
)
421 OControl::disposing( _rSource
);
422 OFormNavigationHelper::disposing( _rSource
);
427 void OButtonControl::actionPerformed(const ActionEvent
& /*rEvent*/)
429 // Asynchronous for css::util::URL-Button
430 ImplSVEvent
* n
= Application::PostUserEvent( LINK(this, OButtonControl
, OnClick
) );
432 ::osl::MutexGuard
aGuard( m_aMutex
);
438 IMPL_LINK_NOARG(OButtonControl
, OnClick
, void*, void)
440 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
441 m_nClickEvent
= nullptr;
443 if (m_aApproveActionListeners
.getLength())
445 // if there are listeners, start the action in an own thread, to not allow
446 // them to block us here (we're in the application's main thread)
447 getImageProducerThread()->addEvent();
451 // Else, don't. We then must not notify the Listeners in any case,
452 // not even if added later on.
455 // recognize the button type
456 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
460 if (FormButtonType_PUSH
== *o3tl::doAccess
<FormButtonType
>(xSet
->getPropertyValue(PROPERTY_BUTTONTYPE
)))
462 // notify the action listeners for a push button
463 ::comphelper::OInterfaceIteratorHelper2
aIter(m_aActionListeners
);
464 ActionEvent
aEvt(static_cast<XWeak
*>(this), m_aActionCommand
);
465 while(aIter
.hasMoreElements() )
468 // and catch them on a per-listener basis - if one listener fails, the others still need
472 static_cast< XActionListener
* >( aIter
.next() )->actionPerformed(aEvt
);
475 catch( const RuntimeException
& )
480 catch( const Exception
& )
482 TOOLS_WARN_EXCEPTION( "forms.component", "OButtonControl::OnClick: caught an exception other than RuntimeException!" );
487 actionPerformed_Impl( false, css::awt::MouseEvent() );
492 void OButtonControl::actionPerformed_Impl( bool _bNotifyListener
, const css::awt::MouseEvent
& _rEvt
)
495 sal_Int16 nFeatureId
= -1;
497 ::osl::MutexGuard
aGuard( m_aMutex
);
498 nFeatureId
= m_nTargetUrlFeatureId
;
501 if ( nFeatureId
!= -1 )
503 if ( !approveAction() )
506 SolarMutexGuard aGuard
;
507 dispatch( nFeatureId
);
512 OClickableImageBaseControl::actionPerformed_Impl( _bNotifyListener
, _rEvt
);
517 void OButtonControl::setLabel(const OUString
& Label
)
519 Reference
<XButton
> xButton
;
520 query_aggregation( m_xAggregate
, xButton
);
522 xButton
->setLabel(Label
);
526 void SAL_CALL
OButtonControl::setActionCommand(const OUString
& _rCommand
)
529 ::osl::MutexGuard
aGuard( m_aMutex
);
530 m_aActionCommand
= _rCommand
;
533 Reference
<XButton
> xButton
;
534 query_aggregation( m_xAggregate
, xButton
);
536 xButton
->setActionCommand(_rCommand
);
540 void SAL_CALL
OButtonControl::addActionListener(const Reference
<XActionListener
>& _rxListener
)
542 m_aActionListeners
.addInterface(_rxListener
);
546 void SAL_CALL
OButtonControl::removeActionListener(const Reference
<XActionListener
>& _rxListener
)
548 m_aActionListeners
.removeInterface(_rxListener
);
553 class DoPropertyListening
556 Reference
< XPropertySet
> m_xProps
;
557 Reference
< XPropertyChangeListener
> m_xListener
;
558 bool m_bStartListening
;
562 const Reference
< XInterface
>& _rxComponent
,
563 const Reference
< XPropertyChangeListener
>& _rxListener
,
567 void handleListening( const OUString
& _rPropertyName
);
572 DoPropertyListening::DoPropertyListening(
573 const Reference
< XInterface
>& _rxComponent
, const Reference
< XPropertyChangeListener
>& _rxListener
,
575 :m_xProps( _rxComponent
, UNO_QUERY
)
576 ,m_xListener( _rxListener
)
577 ,m_bStartListening( _bStart
)
579 DBG_ASSERT( m_xProps
.is() || !_rxComponent
.is(), "DoPropertyListening::DoPropertyListening: valid component, but no property set!" );
580 DBG_ASSERT( m_xListener
.is(), "DoPropertyListening::DoPropertyListening: invalid listener!" );
584 void DoPropertyListening::handleListening( const OUString
& _rPropertyName
)
588 if ( m_bStartListening
)
589 m_xProps
->addPropertyChangeListener( _rPropertyName
, m_xListener
);
591 m_xProps
->removePropertyChangeListener( _rPropertyName
, m_xListener
);
596 void OButtonControl::startOrStopModelPropertyListening( bool _bStart
)
598 DoPropertyListening
aListeningHandler( getModel(), this, _bStart
);
599 aListeningHandler
.handleListening( PROPERTY_TARGET_URL
);
600 aListeningHandler
.handleListening( PROPERTY_BUTTONTYPE
);
601 aListeningHandler
.handleListening( PROPERTY_ENABLED
);
605 sal_Bool SAL_CALL
OButtonControl::setModel( const Reference
< XControlModel
>& _rxModel
)
607 startOrStopModelPropertyListening( false );
608 bool bResult
= OClickableImageBaseControl::setModel( _rxModel
);
609 startOrStopModelPropertyListening( true );
611 m_bEnabledByPropertyValue
= true;
612 Reference
< XPropertySet
> xModelProps( _rxModel
, UNO_QUERY
);
613 if ( xModelProps
.is() )
614 xModelProps
->getPropertyValue( PROPERTY_ENABLED
) >>= m_bEnabledByPropertyValue
;
616 modelFeatureUrlPotentiallyChanged( );
622 void OButtonControl::modelFeatureUrlPotentiallyChanged( )
624 sal_Int16 nOldUrlFeatureId
= m_nTargetUrlFeatureId
;
626 // Do we have another TargetURL now? If so, we need to update our dispatches
627 m_nTargetUrlFeatureId
= getModelUrlFeatureId( );
628 if ( nOldUrlFeatureId
!= m_nTargetUrlFeatureId
)
630 invalidateSupportedFeaturesSet();
631 if ( !isDesignMode() )
637 void SAL_CALL
OButtonControl::propertyChange( const PropertyChangeEvent
& _rEvent
)
639 if ( _rEvent
.PropertyName
== PROPERTY_TARGET_URL
640 || _rEvent
.PropertyName
== PROPERTY_BUTTONTYPE
643 modelFeatureUrlPotentiallyChanged( );
645 else if ( _rEvent
.PropertyName
== PROPERTY_ENABLED
)
647 _rEvent
.NewValue
>>= m_bEnabledByPropertyValue
;
654 bool isFormControllerURL( const OUString
& _rURL
)
656 return ( _rURL
.getLength() > RTL_CONSTASCII_LENGTH( ".uno:FormController/" ) )
657 && ( _rURL
.startsWith( ".uno:FormController/" ) );
662 sal_Int16
OButtonControl::getModelUrlFeatureId( ) const
664 sal_Int16 nFeatureId
= -1;
666 // some URL related properties of the model
668 FormButtonType eButtonType
= FormButtonType_PUSH
;
670 Reference
< XPropertySet
> xModelProps( const_cast< OButtonControl
* >( this )->getModel(), UNO_QUERY
);
671 if ( xModelProps
.is() )
673 xModelProps
->getPropertyValue( PROPERTY_TARGET_URL
) >>= sUrl
;
674 xModelProps
->getPropertyValue( PROPERTY_BUTTONTYPE
) >>= eButtonType
;
677 // are we a URL button?
678 if ( eButtonType
== FormButtonType_URL
)
680 // is it a feature URL?
681 if ( isFormControllerURL( sUrl
) )
683 nFeatureId
= OFormNavigationMapper::getFeatureId( sUrl
);
691 void SAL_CALL
OButtonControl::setDesignMode( sal_Bool _bOn
)
693 OClickableImageBaseControl::setDesignMode( _bOn
);
696 disconnectDispatchers();
698 connectDispatchers();
699 // this will connect if not already connected and just update else
703 void OButtonControl::getSupportedFeatures( ::std::vector
< sal_Int16
>& /* [out] */ _rFeatureIds
)
705 if ( -1 != m_nTargetUrlFeatureId
)
706 _rFeatureIds
.push_back( m_nTargetUrlFeatureId
);
710 void OButtonControl::featureStateChanged( sal_Int16 _nFeatureId
, bool _bEnabled
)
712 if ( _nFeatureId
== m_nTargetUrlFeatureId
)
714 // enable or disable our peer, according to the new state
715 Reference
< XVclWindowPeer
> xPeer( getPeer(), UNO_QUERY
);
717 xPeer
->setProperty( PROPERTY_ENABLED
, makeAny( m_bEnabledByPropertyValue
&& _bEnabled
) );
718 // if we're disabled according to our model's property, then
719 // we don't care for the feature state, but *are* disabled.
720 // If the model's property states that we're enabled, then we *do*
721 // care for the feature state
725 OFormNavigationHelper::featureStateChanged( _nFeatureId
, _bEnabled
);
729 void OButtonControl::allFeatureStatesChanged( )
731 if ( -1 != m_nTargetUrlFeatureId
)
732 // we have only one supported feature, so simulate it has changed ...
733 featureStateChanged( m_nTargetUrlFeatureId
, isEnabled( m_nTargetUrlFeatureId
) );
736 OFormNavigationHelper::allFeatureStatesChanged( );
740 bool OButtonControl::isEnabled( sal_Int16 _nFeatureId
) const
742 if ( const_cast< OButtonControl
* >( this )->isDesignMode() )
743 // TODO: the model property?
746 return OFormNavigationHelper::isEnabled( _nFeatureId
);
750 void SAL_CALL
OButtonControl::registerDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
)
752 OClickableImageBaseControl::registerDispatchProviderInterceptor( _rxInterceptor
);
753 OFormNavigationHelper::registerDispatchProviderInterceptor( _rxInterceptor
);
757 void SAL_CALL
OButtonControl::releaseDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
)
759 OClickableImageBaseControl::releaseDispatchProviderInterceptor( _rxInterceptor
);
760 OFormNavigationHelper::releaseDispatchProviderInterceptor( _rxInterceptor
);
765 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
766 com_sun_star_form_OButtonModel_get_implementation(css::uno::XComponentContext
* component
,
767 css::uno::Sequence
<css::uno::Any
> const &)
769 return cppu::acquire(new frm::OButtonModel(component
));
772 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
773 com_sun_star_form_OButtonControl_get_implementation(css::uno::XComponentContext
* component
,
774 css::uno::Sequence
<css::uno::Any
> const &)
776 return cppu::acquire(new frm::OButtonControl(component
));
779 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */