From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- forms/source/component/Edit.cxx | 717 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 717 insertions(+) create mode 100644 forms/source/component/Edit.cxx (limited to 'forms/source/component/Edit.cxx') diff --git a/forms/source/component/Edit.cxx b/forms/source/component/Edit.cxx new file mode 100644 index 000000000..6c7d83f20 --- /dev/null +++ b/forms/source/component/Edit.cxx @@ -0,0 +1,717 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "Edit.hxx" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +using namespace dbtools; + +namespace frm +{ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::form::binding; + + +Sequence OEditControl::_getTypes() +{ + // my two base classes + static Sequence const aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes()); + return aTypes; +} + + +Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) +{ + Any aReturn = OBoundControl::queryAggregation(_rType); + if (!aReturn.hasValue()) + aReturn = OEditControl_BASE::queryInterface(_rType); + + return aReturn; +} + + +OEditControl::OEditControl(const Reference& _rxFactory) + :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL ) + ,m_aChangeListeners(m_aMutex) + ,m_nKeyEvent( nullptr ) +{ + + osl_atomic_increment(&m_refCount); + { + Reference xComp; + if (query_aggregation(m_xAggregate, xComp)) + { + xComp->addFocusListener(this); + xComp->addKeyListener(this); + } + } + osl_atomic_decrement(&m_refCount); +} + + +OEditControl::~OEditControl() +{ + if( m_nKeyEvent ) + Application::RemoveUserEvent( m_nKeyEvent ); + + if (!OComponentHelper::rBHelper.bDisposed) + { + acquire(); + dispose(); + } + +} + +// XChangeBroadcaster + +void OEditControl::addChangeListener(const Reference& l) +{ + m_aChangeListeners.addInterface( l ); +} + + +void OEditControl::removeChangeListener(const Reference& l) +{ + m_aChangeListeners.removeInterface( l ); +} + +// OComponentHelper + +void OEditControl::disposing() +{ + OBoundControl::disposing(); + + EventObject aEvt(static_cast(this)); + m_aChangeListeners.disposeAndClear(aEvt); +} + +// XServiceInfo + +css::uno::Sequence OEditControl::getSupportedServiceNames() +{ + css::uno::Sequence aSupported = OBoundControl::getSupportedServiceNames(); + aSupported.realloc(aSupported.getLength() + 3); + + OUString*pArray = aSupported.getArray(); + pArray[aSupported.getLength()-3] = FRM_SUN_CONTROL_TEXTFIELD; + pArray[aSupported.getLength()-2] = STARDIV_ONE_FORM_CONTROL_EDIT; + pArray[aSupported.getLength()-1] = STARDIV_ONE_FORM_CONTROL_TEXTFIELD; + return aSupported; +} + +// XEventListener + +void OEditControl::disposing(const EventObject& Source) +{ + OBoundControl::disposing(Source); +} + +// XFocusListener + +void OEditControl::focusGained( const FocusEvent& /*e*/ ) +{ + Reference xSet(getModel(), UNO_QUERY); + if (xSet.is()) + xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue; +} + + +void OEditControl::focusLost( const FocusEvent& /*e*/ ) +{ + Reference xSet(getModel(), UNO_QUERY); + if (xSet.is()) + { + OUString sNewHtmlChangeValue; + xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue; + if( sNewHtmlChangeValue != m_aHtmlChangeValue ) + { + EventObject aEvt( *this ); + m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt ); + } + } +} + +// XKeyListener + +void OEditControl::keyPressed(const css::awt::KeyEvent& e) +{ + if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 ) + return; + + // Is the Control in a form with a submit URL? + Reference xSet(getModel(), UNO_QUERY); + if( !xSet.is() ) + return; + + // Not for multiline edits + Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE)); + if ((aTmp.getValueType().equals(cppu::UnoType::get())) && getBOOL(aTmp)) + return; + + Reference xFComp(xSet, UNO_QUERY); + css::uno::Reference xParent = xFComp->getParent(); + if( !xParent.is() ) + return; + + Reference xFormSet(xParent, UNO_QUERY); + if( !xFormSet.is() ) + return; + + aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL ); + if (!aTmp.getValueType().equals(cppu::UnoType::get()) || + getString(aTmp).isEmpty() ) + return; + + Reference xElements(xParent, UNO_QUERY); + sal_Int32 nCount = xElements->getCount(); + if( nCount > 1 ) + { + Reference xFCSet; + for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ ) + { + // Any aElement(xElements->getByIndex(nIndex)); + xElements->getByIndex(nIndex) >>= xFCSet; + OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!"); + + if (hasProperty(PROPERTY_CLASSID, xFCSet) && + getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD) + { + // Found another Edit -> then do not submit! + if (xFCSet != xSet) + return; + } + } + } + + // Because we're still in the header, trigger submit asynchronously + if( m_nKeyEvent ) + Application::RemoveUserEvent( m_nKeyEvent ); + m_nKeyEvent = Application::PostUserEvent( LINK(this, OEditControl, OnKeyPressed) ); +} + + +void OEditControl::keyReleased(const css::awt::KeyEvent& /*e*/) +{ +} + + +IMPL_LINK_NOARG(OEditControl, OnKeyPressed, void*, void) +{ + m_nKeyEvent = nullptr; + + Reference xFComp(getModel(), UNO_QUERY); + css::uno::Reference xParent = xFComp->getParent(); + Reference xSubmit(xParent, UNO_QUERY); + if (xSubmit.is()) + xSubmit->submit( Reference(), css::awt::MouseEvent() ); +} + + + +OEditModel::OEditModel(const Reference& _rxFactory) + :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, true, true ) + ,m_bMaxTextLenModified(false) + ,m_bWritingFormattedFake(false) +{ + + m_nClassId = FormComponentType::TEXTFIELD; + initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT ); +} + + +OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference& _rxFactory ) + :OEditBaseModel( _pOriginal, _rxFactory ) + ,m_bMaxTextLenModified(false) + ,m_bWritingFormattedFake(false) +{ + + // Note that most of the properties are not clone from the original object: + // Things as the format key, it's type, and such, depend on the field being part of a loaded form + // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself + // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded, + // they will be set to new values, anyway... +} + + +OEditModel::~OEditModel() +{ + if (!OComponentHelper::rBHelper.bDisposed) + { + acquire(); + dispose(); + } + +} + + +css::uno::Reference< css::util::XCloneable > SAL_CALL OEditModel::createClone() +{ + rtl::Reference pClone = new OEditModel(this, getContext()); + pClone->clonedFrom(this); + return pClone; +} + + +void OEditModel::disposing() +{ + OEditBaseModel::disposing(); + m_pValueFormatter.reset(); +} + +// XPersistObject + +OUString SAL_CALL OEditModel::getServiceName() +{ + return FRM_COMPONENT_EDIT; // old (non-sun) name for compatibility ! +} + +// XServiceInfo + +css::uno::Sequence SAL_CALL OEditModel::getSupportedServiceNames() +{ + css::uno::Sequence aSupported = OBoundControlModel::getSupportedServiceNames(); + + sal_Int32 nOldLen = aSupported.getLength(); + aSupported.realloc( nOldLen + 9 ); + OUString* pStoreTo = aSupported.getArray() + nOldLen; + + *pStoreTo++ = BINDABLE_CONTROL_MODEL; + *pStoreTo++ = DATA_AWARE_CONTROL_MODEL; + *pStoreTo++ = VALIDATABLE_CONTROL_MODEL; + + *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL; + *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL; + + *pStoreTo++ = FRM_SUN_COMPONENT_TEXTFIELD; + *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD; + *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD; + + *pStoreTo++ = FRM_COMPONENT_TEXTFIELD; + + return aSupported; +} + +// XPropertySet +void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const +{ + if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle ) + { + if ( m_bMaxTextLenModified ) + rValue <<= sal_Int16(0); + else if ( m_xAggregateSet.is() ) + rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN); + } + else + { + OEditBaseModel::getFastPropertyValue(rValue, nHandle ); + } +} + + +void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const +{ + OEditBaseModel::describeFixedProperties( _rProps ); + sal_Int32 nOldCount = _rProps.getLength(); + _rProps.realloc( nOldCount + 5); + css::beans::Property* pProperties = _rProps.getArray() + nOldCount; + *pProperties++ = css::beans::Property(PROPERTY_PERSISTENCE_MAXTEXTLENGTH, PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH, cppu::UnoType::get(), css::beans::PropertyAttribute::READONLY | css::beans::PropertyAttribute::TRANSIENT); + *pProperties++ = css::beans::Property(PROPERTY_DEFAULT_TEXT, PROPERTY_ID_DEFAULT_TEXT, cppu::UnoType::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_EMPTY_IS_NULL, PROPERTY_ID_EMPTY_IS_NULL, cppu::UnoType::get(), + css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_TABINDEX, PROPERTY_ID_TABINDEX, cppu::UnoType::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_FILTERPROPOSAL, PROPERTY_ID_FILTERPROPOSAL, cppu::UnoType::get(), + css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + DBG_ASSERT( pProperties == _rProps.getArray() + _rProps.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?"); +} + + +void OEditModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const +{ + OEditBaseModel::describeAggregateProperties( _rAggregateProps ); + + // our aggregate is a rich text model, which also derives from OControlModel, as + // do we, so we need to remove some duplicate properties + RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX ); + RemoveProperty( _rAggregateProps, PROPERTY_CLASSID ); + RemoveProperty( _rAggregateProps, PROPERTY_NAME ); + RemoveProperty( _rAggregateProps, PROPERTY_TAG ); + RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK ); + +} + + +bool OEditModel::implActsAsRichText( ) const +{ + bool bActAsRichText = false; + if ( m_xAggregateSet.is() ) + { + OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText ); + } + return bActAsRichText; +} + + +void SAL_CALL OEditModel::reset( ) +{ + // no reset if we currently act as rich text control + if ( implActsAsRichText() ) + return; + + OEditBaseModel::reset(); +} + + +namespace +{ + void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest ) + { + try + { + Reference< XPropertySetInfo > xSourceInfo; + if ( _rxSource.is() ) + xSourceInfo = _rxSource->getPropertySetInfo(); + + Reference< XPropertySetInfo > xDestInfo; + if ( _rxDest.is() ) + xDestInfo = _rxDest->getPropertySetInfo(); + + if ( !xSourceInfo.is() || !xDestInfo.is() ) + { + OSL_FAIL( "lcl_transferProperties: invalid property set(s)!" ); + return; + } + + const Sequence< Property > aSourceProps( xSourceInfo->getProperties() ); + for ( auto const & sourceprop : aSourceProps ) + { + if ( !xDestInfo->hasPropertyByName( sourceprop.Name ) ) + { + continue; + } + + Property aDestProp( xDestInfo->getPropertyByName( sourceprop.Name ) ); + if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) ) + { + continue; + } + + try + { + _rxDest->setPropertyValue( sourceprop.Name, _rxSource->getPropertyValue( sourceprop.Name ) ); + } + catch(const IllegalArgumentException&) + { + TOOLS_WARN_EXCEPTION( "forms.component", "could not transfer the property named '" + << sourceprop.Name + << "'" ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("forms.component"); + } + } +} + + +void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const +{ + // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate, + // but for compatibility, we need to use an "old" aggregate for writing and reading + + Reference< XPropertySet > xFakedAggregate( + getContext()->getServiceManager()->createInstanceWithContext( VCL_CONTROLMODEL_EDIT, getContext() ), + UNO_QUERY + ); + OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" ); + if ( !xFakedAggregate.is() ) + return; + + lcl_transferProperties( m_xAggregateSet, xFakedAggregate ); + + Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY ); + OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" ); + if ( xFakedPersist.is() ) + xFakedPersist->write( _rxOutStream ); +} + + +void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream ) +{ + // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate, + // but for compatibility, we need to use an "old" aggregate for writing and reading + + Reference< XPropertySet > xFakedAggregate( + getContext()->getServiceManager()->createInstanceWithContext( VCL_CONTROLMODEL_EDIT, getContext() ), + UNO_QUERY + ); + Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY ); + OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" ); + if ( xFakedPersist.is() ) + { + xFakedPersist->read( _rxInStream ); + lcl_transferProperties( xFakedAggregate, m_xAggregateSet ); + } +} + + +void OEditModel::write(const Reference& _rxOutStream) +{ + Any aCurrentText; + sal_Int16 nOldTextLen = 0; + // Am I loaded at the moment and did I switch MaxTextLen temporarily? + if ( m_bMaxTextLenModified ) + { // -> for the duration of saving, make my aggregated model believe the old TextLen + + // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len + aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT); + + m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen; + m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, Any(sal_Int16(0))); + } + + OEditBaseModel::write(_rxOutStream); + + if ( m_bMaxTextLenModified ) + { // Reset again + m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, Any(nOldTextLen)); + // and reset the text + // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks + // we aren't changing the prop (it didn't notify the - implicit - change of the text prop while setting the max text len) + // This seems to be a bug with in toolkit's EditControl-implementation. + m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, Any(OUString())); + m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText); + } +} + + +void OEditModel::read(const Reference& _rxInStream) +{ + OEditBaseModel::read(_rxInStream); + + // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown + // to older versions (5.0). + // correct this ... + if (m_xAggregateSet.is()) + { + Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL); + if ( (aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING) + && (getString(aDefaultControl) == STARDIV_ONE_FORM_CONTROL_TEXTFIELD ) + ) + { + m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, Any( OUString(STARDIV_ONE_FORM_CONTROL_EDIT) ) ); + // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT, + // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD. + } + } +} + + +sal_uInt16 OEditModel::getPersistenceFlags() const +{ + sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags(); + + if (m_bWritingFormattedFake) + nFlags |= PF_FAKE_FORMATTED_FIELD; + + return nFlags; +} + + +void OEditModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) +{ + Reference< XPropertySet > xField = getField(); + if ( !xField.is() ) + return; + + m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) ); + + if ( m_pValueFormatter->getKeyType() == NumberFormat::SCIENTIFIC ) + return; + + m_bMaxTextLenModified = getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0; + if ( !m_bMaxTextLenModified ) + { + sal_Int32 nFieldLen = 0; + xField->getPropertyValue("Precision") >>= nFieldLen; + + if (nFieldLen > 0 && nFieldLen <= SAL_MAX_INT16) + { + Any aVal; + aVal <<= static_cast(nFieldLen); + m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal); + + m_bMaxTextLenModified = true; + } + } + else + m_bMaxTextLenModified = false; // to get sure that the text len won't be set in unloaded +} + + +void OEditModel::onDisconnectedDbColumn() +{ + OEditBaseModel::onDisconnectedDbColumn(); + + m_pValueFormatter.reset(); + + if ( hasField() && m_bMaxTextLenModified ) + { + Any aVal; + aVal <<= sal_Int16(0); // Only if it was 0, I switched it in onConnectedDbColumn + m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal); + m_bMaxTextLenModified = false; + } +} + + +bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType ) +{ + // if we act as rich text currently, we do not allow binding to a database column + if ( implActsAsRichText() ) + return false; + + return OEditBaseModel::approveDbColumnType( _nColumnType ); +} + + +bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ ) +{ + Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) ); + + OUString sNewValue; + aNewValue >>= sNewValue; + + if ( !aNewValue.hasValue() + || ( sNewValue.isEmpty() // an empty string + && m_bEmptyIsNull // which should be interpreted as NULL + ) + ) + { + m_xColumnUpdate->updateNull(); + } + else + { + OSL_PRECOND(m_pValueFormatter, + "OEditModel::commitControlValueToDbColumn: no value formatter!"); + try + { + if (m_pValueFormatter) + { + if ( !m_pValueFormatter->setFormattedValue( sNewValue ) ) + return false; + } + else + m_xColumnUpdate->updateString( sNewValue ); + } + catch ( const Exception& ) + { + return false; + } + } + + return true; +} + + +Any OEditModel::translateDbColumnToControlValue() +{ + OSL_PRECOND(m_pValueFormatter, + "OEditModel::translateDbColumnToControlValue: no value formatter!"); + Any aRet; + if (m_pValueFormatter) + { + OUString sValue( m_pValueFormatter->getFormattedValue() ); + if ( sValue.isEmpty() + && m_pValueFormatter->getColumn().is() + && m_pValueFormatter->getColumn()->wasNull() + ) + { + } + else + { + // #i2817# OJ + sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) ); + if ( nMaxTextLen && sValue.getLength() > nMaxTextLen ) + { + sal_Int32 nDiff = sValue.getLength() - nMaxTextLen; + sValue = sValue.replaceAt( nMaxTextLen, nDiff, u"" ); + } + + aRet <<= sValue; + } + } + + return aRet.hasValue() ? aRet : Any( OUString() ); +} + + +Any OEditModel::getDefaultForReset() const +{ + return Any( m_aDefaultText ); +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_form_OEditModel_get_implementation(css::uno::XComponentContext* component, + css::uno::Sequence const &) +{ + return cppu::acquire(new frm::OEditModel(component)); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_form_OEditControl_get_implementation(css::uno::XComponentContext* component, + css::uno::Sequence const &) +{ + return cppu::acquire(new frm::OEditControl(component)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3