summaryrefslogtreecommitdiffstats
path: root/forms/source/xforms/binding.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'forms/source/xforms/binding.cxx')
-rw-r--r--forms/source/xforms/binding.cxx96
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: */