From 196c9bab6aaf91e30a6e275b84d21d0c9869306c Mon Sep 17 00:00:00 2001 From: Lionel Elie Mamane Date: Thu, 3 Aug 2017 16:42:01 +0200 Subject: form controls: validate *before* propagating value, but only on commit *Before* propagating, because after it is propagated it is too late! Only on commit (unless the control is not commitable), because validating each time the control value changes leads to a validator being called each time the user enters a character of the value. So each validator necessarily has to accept any prefix of a valid value, which often defeats the purpose. E.g. one cannot do a valiator that enforces a minimum length, or minimum password complexity. So validating on commit makes much more sense. That's when the user is trying to actually set the value as a complete value. Change-Id: Id3142367bacd81e07d093c8bee97d518df28cafe --- forms/source/component/FormComponent.cxx | 35 +++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/forms/source/component/FormComponent.cxx b/forms/source/component/FormComponent.cxx index 51a54bac573d..faeca82fa0cd 100644 --- a/forms/source/component/FormComponent.cxx +++ b/forms/source/component/FormComponent.cxx @@ -1378,25 +1378,31 @@ void OBoundControlModel::onValuePropertyChange( ControlModelLock& i_rControLock { if ( hasExternalValueBinding() ) { + // validate the value + if ( m_bSupportsValidation ) + recheckValidity( true ); + // the control value changed, while we have an external value binding // -> forward the value to it if ( m_eControlValueChangeInstigator != eExternalBinding ) transferControlValueToExternal( i_rControLock ); } - - else if ( !m_bCommitable && m_xColumnUpdate.is() ) + else if ( !m_bCommitable ) { - // the control value changed, while we are bound to a database column, - // but not committable (which means changes in the control have to be reflected to - // the underlying database column immediately) - // -> forward the value to the database column - if ( m_eControlValueChangeInstigator != eDbColumnBinding ) - commitControlValueToDbColumn( false ); - } + // validate the value + if ( m_bSupportsValidation ) + recheckValidity( true ); - // validate the new value - if ( m_bSupportsValidation ) - recheckValidity( true ); + if( && m_xColumnUpdate.is() ) + { + // the control value changed, while we are bound to a database column, + // but not committable (which means changes in the control have to be reflected to + // the underlying database column immediately) + // -> forward the value to the database column + if ( m_eControlValueChangeInstigator != eDbColumnBinding ) + commitControlValueToDbColumn( false ); + } + } } void OBoundControlModel::_propertyChanged( const PropertyChangeEvent& _rEvt ) @@ -1846,6 +1852,11 @@ sal_Bool SAL_CALL OBoundControlModel::commit() { ControlModelLock aLock( *this ); OSL_PRECOND( m_bCommitable, "OBoundControlModel::commit: invalid call (I'm not commitable !) " ); + + // validate the value + if ( m_bSupportsValidation ) + recheckValidity( true ); + if ( hasExternalValueBinding() ) { // in most cases, no action is required: For most derivees, we know the value property of -- cgit