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/beans/PropertyAttribute.hpp>
26 #include <com/sun/star/form/FormComponentType.hpp>
27 #include <com/sun/star/uno/Type.hxx>
28 #include <com/sun/star/awt/XWindow.hpp>
29 #include <com/sun/star/container/XIndexAccess.hpp>
30 #include <com/sun/star/form/XSubmit.hpp>
31 #include <com/sun/star/util/NumberFormat.hpp>
33 #include <vcl/svapp.hxx>
34 #include <vcl/keycodes.hxx>
36 #include <connectivity/formattedcolumnvalue.hxx>
38 #include <comphelper/property.hxx>
39 #include <comphelper/types.hxx>
40 #include <tools/debug.hxx>
41 #include <comphelper/diagnose_ex.hxx>
42 #include <sal/log.hxx>
44 using namespace dbtools
;
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::sdb
;
50 using namespace ::com::sun::star::sdbc
;
51 using namespace ::com::sun::star::beans
;
52 using namespace ::com::sun::star::container
;
53 using namespace ::com::sun::star::form
;
54 using namespace ::com::sun::star::awt
;
55 using namespace ::com::sun::star::io
;
56 using namespace ::com::sun::star::lang
;
57 using namespace ::com::sun::star::util
;
60 Sequence
<Type
> OEditControl::_getTypes()
62 // my two base classes
63 static Sequence
<Type
> const aTypes
= concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes());
68 Any SAL_CALL
OEditControl::queryAggregation(const Type
& _rType
)
70 Any aReturn
= OBoundControl::queryAggregation(_rType
);
71 if (!aReturn
.hasValue())
72 aReturn
= OEditControl_BASE::queryInterface(_rType
);
78 OEditControl::OEditControl(const Reference
<XComponentContext
>& _rxFactory
)
79 :OBoundControl( _rxFactory
, FRM_SUN_CONTROL_RICHTEXTCONTROL
)
80 ,m_aChangeListeners(m_aMutex
)
81 ,m_nKeyEvent( nullptr )
84 osl_atomic_increment(&m_refCount
);
86 if (auto xComp
= query_aggregation
<XWindow
>(m_xAggregate
))
88 xComp
->addFocusListener(this);
89 xComp
->addKeyListener(this);
92 osl_atomic_decrement(&m_refCount
);
96 OEditControl::~OEditControl()
99 Application::RemoveUserEvent( m_nKeyEvent
);
101 if (!OComponentHelper::rBHelper
.bDisposed
)
109 // XChangeBroadcaster
111 void OEditControl::addChangeListener(const Reference
<XChangeListener
>& l
)
113 m_aChangeListeners
.addInterface( l
);
117 void OEditControl::removeChangeListener(const Reference
<XChangeListener
>& l
)
119 m_aChangeListeners
.removeInterface( l
);
124 void OEditControl::disposing()
126 OBoundControl::disposing();
128 EventObject
aEvt(static_cast<XWeak
*>(this));
129 m_aChangeListeners
.disposeAndClear(aEvt
);
134 css::uno::Sequence
<OUString
> OEditControl::getSupportedServiceNames()
136 css::uno::Sequence
<OUString
> aSupported
= OBoundControl::getSupportedServiceNames();
137 aSupported
.realloc(aSupported
.getLength() + 3);
139 OUString
*pArray
= aSupported
.getArray();
140 pArray
[aSupported
.getLength()-3] = FRM_SUN_CONTROL_TEXTFIELD
;
141 pArray
[aSupported
.getLength()-2] = STARDIV_ONE_FORM_CONTROL_EDIT
;
142 pArray
[aSupported
.getLength()-1] = STARDIV_ONE_FORM_CONTROL_TEXTFIELD
;
148 void OEditControl::disposing(const EventObject
& Source
)
150 OBoundControl::disposing(Source
);
155 void OEditControl::focusGained( const FocusEvent
& /*e*/ )
157 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
159 xSet
->getPropertyValue( PROPERTY_TEXT
) >>= m_aHtmlChangeValue
;
163 void OEditControl::focusLost( const FocusEvent
& /*e*/ )
165 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
168 OUString sNewHtmlChangeValue
;
169 xSet
->getPropertyValue( PROPERTY_TEXT
) >>= sNewHtmlChangeValue
;
170 if( sNewHtmlChangeValue
!= m_aHtmlChangeValue
)
172 EventObject
aEvt( *this );
173 m_aChangeListeners
.notifyEach( &XChangeListener::changed
, aEvt
);
180 void OEditControl::keyPressed(const css::awt::KeyEvent
& e
)
182 if( e
.KeyCode
!= KEY_RETURN
|| e
.Modifiers
!= 0 )
185 // Is the Control in a form with a submit URL?
186 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
190 // Not for multiline edits
191 Any
aTmp( xSet
->getPropertyValue(PROPERTY_MULTILINE
));
192 if ((aTmp
.getValueType().equals(cppu::UnoType
<bool>::get())) && getBOOL(aTmp
))
195 Reference
<XFormComponent
> xFComp(xSet
, UNO_QUERY
);
196 css::uno::Reference
<css::uno::XInterface
> xParent
= xFComp
->getParent();
200 Reference
<XPropertySet
> xFormSet(xParent
, UNO_QUERY
);
204 aTmp
= xFormSet
->getPropertyValue( PROPERTY_TARGET_URL
);
205 if (!aTmp
.getValueType().equals(cppu::UnoType
<OUString
>::get()) ||
206 getString(aTmp
).isEmpty() )
209 Reference
<XIndexAccess
> xElements(xParent
, UNO_QUERY
);
210 sal_Int32 nCount
= xElements
->getCount();
213 Reference
<XPropertySet
> xFCSet
;
214 for( sal_Int32 nIndex
=0; nIndex
< nCount
; nIndex
++ )
216 // Any aElement(xElements->getByIndex(nIndex));
217 xElements
->getByIndex(nIndex
) >>= xFCSet
;
218 OSL_ENSURE(xFCSet
.is(),"OEditControl::keyPressed: No XPropertySet!");
220 if (hasProperty(PROPERTY_CLASSID
, xFCSet
) &&
221 getINT16(xFCSet
->getPropertyValue(PROPERTY_CLASSID
)) == FormComponentType::TEXTFIELD
)
223 // Found another Edit -> then do not submit!
230 // Because we're still in the header, trigger submit asynchronously
232 Application::RemoveUserEvent( m_nKeyEvent
);
233 m_nKeyEvent
= Application::PostUserEvent( LINK(this, OEditControl
, OnKeyPressed
) );
237 void OEditControl::keyReleased(const css::awt::KeyEvent
& /*e*/)
242 IMPL_LINK_NOARG(OEditControl
, OnKeyPressed
, void*, void)
244 m_nKeyEvent
= nullptr;
246 Reference
<XFormComponent
> xFComp(getModel(), UNO_QUERY
);
247 css::uno::Reference
<css::uno::XInterface
> xParent
= xFComp
->getParent();
248 Reference
<XSubmit
> xSubmit(xParent
, UNO_QUERY
);
250 xSubmit
->submit( Reference
<XControl
>(), css::awt::MouseEvent() );
255 OEditModel::OEditModel(const Reference
<XComponentContext
>& _rxFactory
)
256 :OEditBaseModel( _rxFactory
, FRM_SUN_COMPONENT_RICHTEXTCONTROL
, FRM_SUN_CONTROL_TEXTFIELD
, true, true )
257 ,m_bMaxTextLenModified(false)
258 ,m_bWritingFormattedFake(false)
261 m_nClassId
= FormComponentType::TEXTFIELD
;
262 initValueProperty( PROPERTY_TEXT
, PROPERTY_ID_TEXT
);
266 OEditModel::OEditModel( const OEditModel
* _pOriginal
, const Reference
<XComponentContext
>& _rxFactory
)
267 :OEditBaseModel( _pOriginal
, _rxFactory
)
268 ,m_bMaxTextLenModified(false)
269 ,m_bWritingFormattedFake(false)
272 // Note that most of the properties are not clone from the original object:
273 // Things as the format key, it's type, and such, depend on the field being part of a loaded form
274 // (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself
275 // certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded,
276 // they will be set to new values, anyway...
280 OEditModel::~OEditModel()
282 if (!OComponentHelper::rBHelper
.bDisposed
)
291 css::uno::Reference
< css::util::XCloneable
> SAL_CALL
OEditModel::createClone()
293 rtl::Reference
<OEditModel
> pClone
= new OEditModel(this, getContext());
294 pClone
->clonedFrom(this);
299 void OEditModel::disposing()
301 OEditBaseModel::disposing();
302 m_pValueFormatter
.reset();
307 OUString SAL_CALL
OEditModel::getServiceName()
309 return FRM_COMPONENT_EDIT
; // old (non-sun) name for compatibility !
314 css::uno::Sequence
<OUString
> SAL_CALL
OEditModel::getSupportedServiceNames()
316 css::uno::Sequence
<OUString
> aSupported
= OBoundControlModel::getSupportedServiceNames();
318 sal_Int32 nOldLen
= aSupported
.getLength();
319 aSupported
.realloc( nOldLen
+ 9 );
320 OUString
* pStoreTo
= aSupported
.getArray() + nOldLen
;
322 *pStoreTo
++ = BINDABLE_CONTROL_MODEL
;
323 *pStoreTo
++ = DATA_AWARE_CONTROL_MODEL
;
324 *pStoreTo
++ = VALIDATABLE_CONTROL_MODEL
;
326 *pStoreTo
++ = BINDABLE_DATA_AWARE_CONTROL_MODEL
;
327 *pStoreTo
++ = VALIDATABLE_BINDABLE_CONTROL_MODEL
;
329 *pStoreTo
++ = FRM_SUN_COMPONENT_TEXTFIELD
;
330 *pStoreTo
++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD
;
331 *pStoreTo
++ = BINDABLE_DATABASE_TEXT_FIELD
;
333 *pStoreTo
++ = FRM_COMPONENT_TEXTFIELD
;
339 void SAL_CALL
OEditModel::getFastPropertyValue(Any
& rValue
, sal_Int32 nHandle
) const
341 if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH
== nHandle
)
343 if ( m_bMaxTextLenModified
)
344 rValue
<<= sal_Int16(0);
345 else if ( m_xAggregateSet
.is() )
346 rValue
= m_xAggregateSet
->getPropertyValue(PROPERTY_MAXTEXTLEN
);
350 OEditBaseModel::getFastPropertyValue(rValue
, nHandle
);
355 void OEditModel::describeFixedProperties( Sequence
< Property
>& _rProps
) const
357 OEditBaseModel::describeFixedProperties( _rProps
);
358 sal_Int32 nOldCount
= _rProps
.getLength();
359 _rProps
.realloc( nOldCount
+ 5);
360 css::beans::Property
* pProperties
= _rProps
.getArray() + nOldCount
;
361 *pProperties
++ = css::beans::Property(PROPERTY_PERSISTENCE_MAXTEXTLENGTH
, PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH
, cppu::UnoType
<sal_Int16
>::get(), css::beans::PropertyAttribute::READONLY
| css::beans::PropertyAttribute::TRANSIENT
);
362 *pProperties
++ = css::beans::Property(PROPERTY_DEFAULT_TEXT
, PROPERTY_ID_DEFAULT_TEXT
, cppu::UnoType
<OUString
>::get(), css::beans::PropertyAttribute::BOUND
| css::beans::PropertyAttribute::MAYBEDEFAULT
);
363 *pProperties
++ = css::beans::Property(PROPERTY_EMPTY_IS_NULL
, PROPERTY_ID_EMPTY_IS_NULL
, cppu::UnoType
<bool>::get(),
364 css::beans::PropertyAttribute::BOUND
);
365 *pProperties
++ = css::beans::Property(PROPERTY_TABINDEX
, PROPERTY_ID_TABINDEX
, cppu::UnoType
<sal_Int16
>::get(), css::beans::PropertyAttribute::BOUND
);
366 *pProperties
++ = css::beans::Property(PROPERTY_FILTERPROPOSAL
, PROPERTY_ID_FILTERPROPOSAL
, cppu::UnoType
<bool>::get(),
367 css::beans::PropertyAttribute::BOUND
| css::beans::PropertyAttribute::MAYBEDEFAULT
);
368 DBG_ASSERT( pProperties
== _rProps
.getArray() + _rProps
.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?");
372 void OEditModel::describeAggregateProperties( Sequence
< Property
>& _rAggregateProps
) const
374 OEditBaseModel::describeAggregateProperties( _rAggregateProps
);
376 // our aggregate is a rich text model, which also derives from OControlModel, as
377 // do we, so we need to remove some duplicate properties
378 RemoveProperty( _rAggregateProps
, PROPERTY_TABINDEX
);
379 RemoveProperty( _rAggregateProps
, PROPERTY_CLASSID
);
380 RemoveProperty( _rAggregateProps
, PROPERTY_NAME
);
381 RemoveProperty( _rAggregateProps
, PROPERTY_TAG
);
382 RemoveProperty( _rAggregateProps
, PROPERTY_NATIVE_LOOK
);
383 RemoveProperty( _rAggregateProps
, PROPERTY_STANDARD_THEME
);
388 bool OEditModel::implActsAsRichText( ) const
390 bool bActAsRichText
= false;
391 if ( m_xAggregateSet
.is() )
393 OSL_VERIFY( m_xAggregateSet
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bActAsRichText
);
395 return bActAsRichText
;
399 void SAL_CALL
OEditModel::reset( )
401 // no reset if we currently act as rich text control
402 if ( implActsAsRichText() )
405 OEditBaseModel::reset();
411 void lcl_transferProperties( const Reference
< XPropertySet
>& _rxSource
, const Reference
< XPropertySet
>& _rxDest
)
415 Reference
< XPropertySetInfo
> xSourceInfo
;
416 if ( _rxSource
.is() )
417 xSourceInfo
= _rxSource
->getPropertySetInfo();
419 Reference
< XPropertySetInfo
> xDestInfo
;
421 xDestInfo
= _rxDest
->getPropertySetInfo();
423 if ( !xSourceInfo
.is() || !xDestInfo
.is() )
425 OSL_FAIL( "lcl_transferProperties: invalid property set(s)!" );
429 const Sequence
< Property
> aSourceProps( xSourceInfo
->getProperties() );
430 for ( auto const & sourceprop
: aSourceProps
)
432 if ( !xDestInfo
->hasPropertyByName( sourceprop
.Name
) )
437 Property
aDestProp( xDestInfo
->getPropertyByName( sourceprop
.Name
) );
438 if ( 0 != ( aDestProp
.Attributes
& PropertyAttribute::READONLY
) )
445 _rxDest
->setPropertyValue( sourceprop
.Name
, _rxSource
->getPropertyValue( sourceprop
.Name
) );
447 catch(const IllegalArgumentException
&)
449 TOOLS_WARN_EXCEPTION( "forms.component", "could not transfer the property named '"
455 catch( const Exception
& )
457 DBG_UNHANDLED_EXCEPTION("forms.component");
463 void OEditModel::writeAggregate( const Reference
< XObjectOutputStream
>& _rxOutStream
) const
465 // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate,
466 // but for compatibility, we need to use an "old" aggregate for writing and reading
468 Reference
< XPropertySet
> xFakedAggregate(
469 getContext()->getServiceManager()->createInstanceWithContext( VCL_CONTROLMODEL_EDIT
, getContext() ),
472 OSL_ENSURE( xFakedAggregate
.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" );
473 if ( !xFakedAggregate
.is() )
476 lcl_transferProperties( m_xAggregateSet
, xFakedAggregate
);
478 Reference
< XPersistObject
> xFakedPersist( xFakedAggregate
, UNO_QUERY
);
479 OSL_ENSURE( xFakedPersist
.is(), "OEditModel::writeAggregate: no XPersistObject!" );
480 if ( xFakedPersist
.is() )
481 xFakedPersist
->write( _rxOutStream
);
485 void OEditModel::readAggregate( const Reference
< XObjectInputStream
>& _rxInStream
)
487 // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate,
488 // but for compatibility, we need to use an "old" aggregate for writing and reading
490 Reference
< XPropertySet
> xFakedAggregate(
491 getContext()->getServiceManager()->createInstanceWithContext( VCL_CONTROLMODEL_EDIT
, getContext() ),
494 Reference
< XPersistObject
> xFakedPersist( xFakedAggregate
, UNO_QUERY
);
495 OSL_ENSURE( xFakedPersist
.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" );
496 if ( xFakedPersist
.is() )
498 xFakedPersist
->read( _rxInStream
);
499 lcl_transferProperties( xFakedAggregate
, m_xAggregateSet
);
504 void OEditModel::write(const Reference
<XObjectOutputStream
>& _rxOutStream
)
507 sal_Int16 nOldTextLen
= 0;
508 // Am I loaded at the moment and did I switch MaxTextLen temporarily?
509 if ( m_bMaxTextLenModified
)
510 { // -> for the duration of saving, make my aggregated model believe the old TextLen
512 // before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len
513 aCurrentText
= m_xAggregateSet
->getPropertyValue(PROPERTY_TEXT
);
515 m_xAggregateSet
->getPropertyValue(PROPERTY_MAXTEXTLEN
) >>= nOldTextLen
;
516 m_xAggregateSet
->setPropertyValue(PROPERTY_MAXTEXTLEN
, Any(sal_Int16(0)));
519 OEditBaseModel::write(_rxOutStream
);
521 if ( m_bMaxTextLenModified
)
523 m_xAggregateSet
->setPropertyValue(PROPERTY_MAXTEXTLEN
, Any(nOldTextLen
));
524 // and reset the text
525 // First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks
526 // we aren't changing the prop (it didn't notify the - implicit - change of the text prop while setting the max text len)
527 // This seems to be a bug with in toolkit's EditControl-implementation.
528 m_xAggregateSet
->setPropertyValue(PROPERTY_TEXT
, Any(OUString()));
529 m_xAggregateSet
->setPropertyValue(PROPERTY_TEXT
, aCurrentText
);
534 void OEditModel::read(const Reference
<XObjectInputStream
>& _rxInStream
)
536 OEditBaseModel::read(_rxInStream
);
538 // Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown
539 // to older versions (5.0).
541 if (m_xAggregateSet
.is())
543 Any aDefaultControl
= m_xAggregateSet
->getPropertyValue(PROPERTY_DEFAULTCONTROL
);
544 if ( (aDefaultControl
.getValueTypeClass() == TypeClass_STRING
)
545 && (getString(aDefaultControl
) == STARDIV_ONE_FORM_CONTROL_TEXTFIELD
)
548 m_xAggregateSet
->setPropertyValue( PROPERTY_DEFAULTCONTROL
, Any( STARDIV_ONE_FORM_CONTROL_EDIT
) );
549 // Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT,
550 // the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD.
556 sal_uInt16
OEditModel::getPersistenceFlags() const
558 sal_uInt16 nFlags
= OEditBaseModel::getPersistenceFlags();
560 if (m_bWritingFormattedFake
)
561 nFlags
|= PF_FAKE_FORMATTED_FIELD
;
567 void OEditModel::onConnectedDbColumn( const Reference
< XInterface
>& _rxForm
)
569 Reference
< XPropertySet
> xField
= getField();
573 m_pValueFormatter
.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference
< XRowSet
>( _rxForm
, UNO_QUERY
), xField
) );
575 if ( m_pValueFormatter
->getKeyType() == NumberFormat::SCIENTIFIC
)
578 m_bMaxTextLenModified
= getINT16(m_xAggregateSet
->getPropertyValue(PROPERTY_MAXTEXTLEN
)) != 0;
579 if ( !m_bMaxTextLenModified
)
581 sal_Int32 nFieldLen
= 0;
582 xField
->getPropertyValue(u
"Precision"_ustr
) >>= nFieldLen
;
584 if (nFieldLen
> 0 && nFieldLen
<= SAL_MAX_INT16
)
587 aVal
<<= static_cast<sal_Int16
>(nFieldLen
);
588 m_xAggregateSet
->setPropertyValue(PROPERTY_MAXTEXTLEN
, aVal
);
590 m_bMaxTextLenModified
= true;
594 m_bMaxTextLenModified
= false; // to get sure that the text len won't be set in unloaded
598 void OEditModel::onDisconnectedDbColumn()
600 OEditBaseModel::onDisconnectedDbColumn();
602 m_pValueFormatter
.reset();
604 if ( hasField() && m_bMaxTextLenModified
)
607 aVal
<<= sal_Int16(0); // Only if it was 0, I switched it in onConnectedDbColumn
608 m_xAggregateSet
->setPropertyValue(PROPERTY_MAXTEXTLEN
, aVal
);
609 m_bMaxTextLenModified
= false;
614 bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType
)
616 // if we act as rich text currently, we do not allow binding to a database column
617 if ( implActsAsRichText() )
620 return OEditBaseModel::approveDbColumnType( _nColumnType
);
624 bool OEditModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
626 Any
aNewValue( m_xAggregateFastSet
->getFastPropertyValue( getValuePropertyAggHandle() ) );
629 aNewValue
>>= sNewValue
;
631 if ( !aNewValue
.hasValue()
632 || ( sNewValue
.isEmpty() // an empty string
633 && m_bEmptyIsNull
// which should be interpreted as NULL
637 m_xColumnUpdate
->updateNull();
641 OSL_PRECOND(m_pValueFormatter
,
642 "OEditModel::commitControlValueToDbColumn: no value formatter!");
645 if (m_pValueFormatter
)
647 if ( !m_pValueFormatter
->setFormattedValue( sNewValue
) )
651 m_xColumnUpdate
->updateString( sNewValue
);
653 catch ( const Exception
& )
663 Any
OEditModel::translateDbColumnToControlValue()
665 OSL_PRECOND(m_pValueFormatter
,
666 "OEditModel::translateDbColumnToControlValue: no value formatter!");
668 if (m_pValueFormatter
)
670 OUString
sValue( m_pValueFormatter
->getFormattedValue() );
671 if ( sValue
.isEmpty()
672 && m_pValueFormatter
->getColumn().is()
673 && m_pValueFormatter
->getColumn()->wasNull()
680 sal_uInt16 nMaxTextLen
= getINT16( m_xAggregateSet
->getPropertyValue( PROPERTY_MAXTEXTLEN
) );
681 if ( nMaxTextLen
&& sValue
.getLength() > nMaxTextLen
)
683 sal_Int32 nDiff
= sValue
.getLength() - nMaxTextLen
;
684 sValue
= sValue
.replaceAt( nMaxTextLen
, nDiff
, u
"" );
691 return aRet
.hasValue() ? aRet
: Any( OUString() );
695 Any
OEditModel::getDefaultForReset() const
697 return Any( m_aDefaultText
);
702 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
703 com_sun_star_form_OEditModel_get_implementation(css::uno::XComponentContext
* component
,
704 css::uno::Sequence
<css::uno::Any
> const &)
706 return cppu::acquire(new frm::OEditModel(component
));
709 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
710 com_sun_star_form_OEditControl_get_implementation(css::uno::XComponentContext
* component
,
711 css::uno::Sequence
<css::uno::Any
> const &)
713 return cppu::acquire(new frm::OEditControl(component
));
716 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */