diff options
Diffstat (limited to 'forms/source/xforms/binding.cxx')
-rw-r--r-- | forms/source/xforms/binding.cxx | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/forms/source/xforms/binding.cxx b/forms/source/xforms/binding.cxx index 5d986bbd26cb..c739126642c4 100644 --- a/forms/source/xforms/binding.cxx +++ b/forms/source/xforms/binding.cxx @@ -31,9 +31,10 @@ #include <strings.hrc> #include <rtl/ustrbuf.hxx> +#include <o3tl/safeint.hxx> #include <osl/diagnose.h> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <algorithm> #include <functional> @@ -70,7 +71,6 @@ using com::sun::star::form::binding::InvalidBindingStateException; using com::sun::star::form::binding::XValueBinding; using com::sun::star::lang::EventObject; using com::sun::star::lang::IndexOutOfBoundsException; -using com::sun::star::lang::XUnoTunnel; using com::sun::star::uno::Any; using com::sun::star::uno::Reference; using com::sun::star::uno::RuntimeException; @@ -79,7 +79,6 @@ using com::sun::star::uno::UNO_QUERY; using com::sun::star::uno::UNO_QUERY_THROW; using com::sun::star::uno::XInterface; using com::sun::star::uno::Exception; -using com::sun::star::uno::makeAny; using com::sun::star::util::XModifyListener; using com::sun::star::xforms::XDataTypeRepository; using com::sun::star::xml::dom::NodeType_ATTRIBUTE_NODE; @@ -122,7 +121,7 @@ Binding::~Binding() _setModel(nullptr); } -void Binding::_setModel( const css::uno::Reference<css::xforms::XModel>& xModel ) +void Binding::_setModel( const rtl::Reference<Model>& xModel ) { PropertyChangeNotifier aNotifyModelChange( *this, HANDLE_Model ); PropertyChangeNotifier aNotifyModelIDChange( *this, HANDLE_ModelID ); @@ -143,8 +142,7 @@ void Binding::_setModel( const css::uno::Reference<css::xforms::XModel>& xModel OUString Binding::getModelID() const { - Model* pModel = getModelImpl(); - return ( pModel == nullptr ) ? OUString() : pModel->getID(); + return ( mxModel == nullptr ) ? OUString() : mxModel->getID(); } @@ -208,7 +206,14 @@ bool Binding::isValid() const { // TODO: determine whether node is suitable, not just whether it exists return maBindingExpression.getNode().is() && - isValid_DataType() && + ( + // tdf#155121, validity rules should be apply when field is required or + // when the field is not required but not empty + // so if the field is not required and empty, do not check validity + (! maMIP.isRequired() && maBindingExpression.hasValue() + && maBindingExpression.getString().isEmpty() ) || + isValid_DataType() + ) && maMIP.isConstraint() && ( ! maMIP.isRequired() || ( maBindingExpression.hasValue() && @@ -225,7 +230,7 @@ bool Binding::isUseful() const // 3) we are bound to some control // (this can be assumed if some listeners are set) bool bUseful = - getModelImpl() == nullptr + mxModel == nullptr // || msBindingID.getLength() > 0 || ! msTypeName.isEmpty() || ! maReadonly.isEmptyExpression() @@ -279,15 +284,15 @@ OUString Binding::explainInvalid() EvaluationContext Binding::getEvaluationContext() const { - OSL_ENSURE( getModelImpl() != nullptr, "need model impl" ); - EvaluationContext aContext = getModelImpl()->getEvaluationContext(); + OSL_ENSURE( mxModel != nullptr, "need model impl" ); + EvaluationContext aContext = mxModel->getEvaluationContext(); aContext.mxNamespaces = getBindingNamespaces(); return aContext; } ::std::vector<EvaluationContext> Binding::getMIPEvaluationContexts() { - OSL_ENSURE( getModelImpl() != nullptr, "need model impl" ); + OSL_ENSURE( mxModel != nullptr, "need model impl" ); // bind (in case we were not bound before) bind(); @@ -419,9 +424,8 @@ bool Binding::getExternalData() const try { - Reference< XPropertySet > xModelProps( mxModel, UNO_QUERY_THROW ); OSL_VERIFY( - xModelProps->getPropertyValue( "ExternalData" ) >>= bExternalData ); + mxModel->getPropertyValue( "ExternalData" ) >>= bExternalData ); } catch( const Exception& ) { @@ -439,14 +443,9 @@ void Binding::checkLive() bool Binding::isLive() const { - const Model* pModel = getModelImpl(); - return pModel && pModel->isInitialized(); + return mxModel && mxModel->isInitialized(); } -Model* Binding::getModelImpl() const -{ - return comphelper::getFromUnoTunnel<Model>( mxModel ); -} static void lcl_addListenerToNode( const Reference<XNode>& xNode, const Reference<XEventListener>& xListener ) @@ -463,8 +462,6 @@ static void lcl_addListenerToNode( const Reference<XNode>& xNode, xListener, false ); xTarget->addEventListener( "DOMAttrModified", xListener, true ); - xTarget->addEventListener( "DOMAttrModified", - xListener, true ); xTarget->addEventListener( "xforms-generic", xListener, true ); } @@ -490,7 +487,7 @@ static void lcl_removeListenerFromNode( const Reference<XNode>& xNode, ::std::vector<EvaluationContext> Binding::_getMIPEvaluationContexts() const { - OSL_ENSURE( getModelImpl() != nullptr, "need model impl" ); + OSL_ENSURE( mxModel != nullptr, "need model impl" ); // iterate over nodes of bind expression and create // EvaluationContext for each @@ -501,7 +498,7 @@ static void lcl_removeListenerFromNode( const Reference<XNode>& xNode, OSL_ENSURE( node.is(), "no node?" ); // create proper evaluation context for this MIP - aVector.emplace_back( node, getModel(), getBindingNamespaces() ); + aVector.emplace_back( node, mxModel, getBindingNamespaces() ); } return aVector; } @@ -558,9 +555,8 @@ void Binding::bind( bool bForceRebind ) } // 3) remove old MIPs defined by this binding - Model* pModel = getModelImpl(); - OSL_ENSURE( pModel != nullptr, "need model" ); - pModel->removeMIPs( this ); + OSL_ENSURE( mxModel != nullptr, "need model" ); + mxModel->removeMIPs( this ); // 4) calculate all MIPs ::std::vector<EvaluationContext> aMIPContexts = _getMIPEvaluationContexts(); @@ -576,7 +572,7 @@ void Binding::bind( bool bForceRebind ) { mbInCalculate = true; maCalculate.evaluate( rContext ); - pModel->setSimpleContent( rContext.mxContextNode, + mxModel->setSimpleContent( rContext.mxContextNode, maCalculate.getString() ); mbInCalculate = false; } @@ -590,7 +586,7 @@ void Binding::bind( bool bForceRebind ) // type is static; does not need updating // evaluate the locally defined MIPs, and push them to the model - pModel->addMIP( this, rContext.mxContextNode, getLocalMIP() ); + mxModel->addMIP( this, rContext.mxContextNode, getLocalMIP() ); } } @@ -633,7 +629,7 @@ void Binding::valueModified() // query MIP used by our first node (also note validity) Reference<XNode> xNode = maBindingExpression.getNode(); - maMIP = getModelImpl()->queryMIP( xNode ); + maMIP = mxModel->queryMIP( xNode ); // distribute MIPs _used_ by this binding if( xNode.is() ) @@ -734,11 +730,11 @@ MIP Binding::getLocalMIP() const css::uno::Reference<css::xsd::XDataType> Binding::getDataType() const { - OSL_ENSURE( getModel().is(), "need model" ); - OSL_ENSURE( getModel()->getDataTypeRepository().is(), "need types" ); + OSL_ENSURE( mxModel.is(), "need model" ); + OSL_ENSURE( mxModel->getDataTypeRepository().is(), "need types" ); Reference<XDataTypeRepository> xRepository = - getModel()->getDataTypeRepository(); + mxModel->getDataTypeRepository(); OUString sTypeName = maMIP.getTypeName(); return ( xRepository.is() && xRepository->hasByName( sTypeName ) ) @@ -764,9 +760,8 @@ OUString Binding::explainInvalid_DataType() void Binding::clear() { // remove MIPs contributed by this binding - Model* pModel = getModelImpl(); - if( pModel != nullptr ) - pModel->removeMIPs( this ); + if( mxModel != nullptr ) + mxModel->removeMIPs( this ); // remove all references for (auto const& eventNode : maEventNodes) @@ -855,9 +850,8 @@ css::uno::Reference<css::container::XNameContainer> Binding::_getNamespaces() co lcl_copyNamespaces( mxNamespaces, xNamespaces, true ); // merge model's with binding's own namespaces - Model* pModel = getModelImpl(); - if( pModel != nullptr ) - lcl_copyNamespaces( pModel->getNamespaces(), xNamespaces, false ); + if( mxModel != nullptr ) + lcl_copyNamespaces( mxModel->getNamespaces(), xNamespaces, false ); return xNamespaces; } @@ -867,11 +861,10 @@ css::uno::Reference<css::container::XNameContainer> Binding::_getNamespaces() co void Binding::_setNamespaces( const css::uno::Reference<css::container::XNameContainer>& rNamespaces, bool bBinding ) { - Model* pModel = getModelImpl(); - css::uno::Reference<css::container::XNameContainer> xModelNamespaces = ( pModel != nullptr ) - ? pModel->getNamespaces() + css::uno::Reference<css::container::XNameContainer> xModelNamespaces = ( mxModel != nullptr ) + ? mxModel->getNamespaces() : nullptr; - OSL_ENSURE( ( pModel != nullptr ) == xModelNamespaces.is(), "no model nmsp?"); + OSL_ENSURE( ( mxModel != nullptr ) == xModelNamespaces.is(), "no model nmsp?"); // remove deleted namespaces lcl_removeOtherNamespaces( rNamespaces, mxNamespaces ); @@ -920,10 +913,10 @@ void Binding::_setNamespaces( const css::uno::Reference<css::container::XNameCon void Binding::_checkBindingID() { - if( !getModel().is() ) + if( !mxModel.is() ) return; - Reference<XNameAccess> xBindings( getModel()->getBindings(), UNO_QUERY_THROW ); + Reference<XNameAccess> xBindings( mxModel->getBindings(), UNO_QUERY_THROW ); if( !msBindingID.isEmpty() ) return; @@ -991,7 +984,7 @@ void Binding::setValue( const css::uno::Any& aValue ) throw InvalidBindingStateException("no suitable node found", static_cast<XValueBinding*>(this)); OUString sValue = Convert::get().toXSD( aValue ); - bool bSuccess = getModelImpl()->setSimpleContent( xNode, sValue ); + bool bSuccess = mxModel->setSimpleContent( xNode, sValue ); if( ! bSuccess ) throw InvalidBindingStateException("can't set value", static_cast<XValueBinding*>(this)); @@ -1043,7 +1036,7 @@ OUString Binding::getListEntry( sal_Int32 nPosition ) // check bounds and return proper item PathExpression::NodeVector_t aNodes = maBindingExpression.getNodeList(); - if( nPosition < 0 || nPosition >= static_cast<sal_Int32>( aNodes.size() ) ) + if( nPosition < 0 || o3tl::make_unsigned(nPosition) >= aNodes.size() ) throw IndexOutOfBoundsException("", static_cast<XValueBinding*>(this)); return lcl_getString( aNodes[ nPosition ] ); } @@ -1174,9 +1167,8 @@ css::uno::Reference<css::util::XCloneable> SAL_CALL Binding::createClone() { Reference< XPropertySet > xClone; - Model* pModel = getModelImpl(); - if ( pModel ) - xClone = pModel->cloneBinding( this ); + if ( mxModel ) + xClone = mxModel->cloneBinding( this ); else { xClone = new Binding; @@ -1185,6 +1177,10 @@ css::uno::Reference<css::util::XCloneable> SAL_CALL Binding::createClone() return css::uno::Reference<css::util::XCloneable>( xClone, UNO_QUERY ); } +css::uno::Reference<css::xforms::XModel> Binding::getModel() const +{ + return mxModel; +} // property set implementations @@ -1273,7 +1269,7 @@ void SAL_CALL Binding::setName( const OUString& rName ) { // use the XPropertySet methods, so the change in the name is notified to the // property listeners - setFastPropertyValue( HANDLE_BindingID, makeAny( rName ) ); + setFastPropertyValue( HANDLE_BindingID, Any( rName ) ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |