33#include <rtl/ustrbuf.hxx>
35#include <osl/diagnose.h>
42#include <com/sun/star/form/binding/IncompatibleTypesException.hpp>
43#include <com/sun/star/form/binding/InvalidBindingStateException.hpp>
44#include <com/sun/star/uno/Any.hxx>
45#include <com/sun/star/xml/dom/XNodeList.hpp>
46#include <com/sun/star/xml/dom/XNode.hpp>
47#include <com/sun/star/xml/dom/XDocument.hpp>
48#include <com/sun/star/xml/dom/XElement.hpp>
49#include <com/sun/star/xml/dom/NodeType.hpp>
50#include <com/sun/star/xml/dom/events/XEventTarget.hpp>
51#include <com/sun/star/xml/dom/events/XEventListener.hpp>
52#include <com/sun/star/lang/XUnoTunnel.hpp>
53#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
54#include <com/sun/star/container/XNameContainer.hpp>
68using com::sun::star::container::XNameAccess;
69using com::sun::star::form::binding::IncompatibleTypesException;
70using com::sun::star::form::binding::InvalidBindingStateException;
71using com::sun::star::form::binding::XValueBinding;
72using com::sun::star::lang::EventObject;
73using com::sun::star::lang::IndexOutOfBoundsException;
74using com::sun::star::uno::Any;
76using com::sun::star::uno::RuntimeException;
78using com::sun::star::uno::UNO_QUERY;
79using com::sun::star::uno::UNO_QUERY_THROW;
80using com::sun::star::uno::XInterface;
81using com::sun::star::uno::Exception;
82using com::sun::star::util::XModifyListener;
83using com::sun::star::xforms::XDataTypeRepository;
84using com::sun::star::xml::dom::NodeType_ATTRIBUTE_NODE;
85using com::sun::star::xml::dom::NodeType_TEXT_NODE;
86using com::sun::star::xml::dom::XNode;
87using com::sun::star::xml::dom::XNodeList;
88using com::sun::star::xml::dom::events::XEventListener;
89using com::sun::star::xml::dom::events::XEventTarget;
90using com::sun::star::xsd::XDataType;
92#define HANDLE_BindingID 0
93#define HANDLE_BindingExpression 1
95#define HANDLE_ModelID 3
96#define HANDLE_BindingNamespaces 4
97#define HANDLE_ReadonlyExpression 5
98#define HANDLE_RelevantExpression 6
99#define HANDLE_RequiredExpression 7
100#define HANDLE_ConstraintExpression 8
101#define HANDLE_CalculateExpression 9
102#define HANDLE_Type 10
103#define HANDLE_ReadOnly 11
104#define HANDLE_Relevant 12
105#define HANDLE_ModelNamespaces 13
106#define HANDLE_ExternalData 14
111 mbInCalculate( false ),
112 mnDeferModifyNotifications( 0 ),
113 mbValueModified( false ),
114 mbBindingModified( false )
131 css::uno::Reference<css::container::XNameContainer> xNamespaces =
getModelNamespaces();
146 return ( pModel ==
nullptr ) ? OUString() : pModel->
getID();
203 "deferred modifications not delivered?" );
255 ?
getResource( RID_STR_XFORMS_NO_BINDING_EXPRESSION )
256 :
getResource( RID_STR_XFORMS_INVALID_BINDING_EXPRESSION );
261 if( sReason.isEmpty() )
264 sReason =
getResource( RID_STR_XFORMS_INVALID_VALUE,
279 OSL_ENSURE( sReason.isEmpty() ==
isValid(),
280 "invalid data should have an explanation!" );
288 OSL_ENSURE(
getModelImpl() !=
nullptr,
"need model impl" );
296 OSL_ENSURE(
getModelImpl() !=
nullptr,
"need model impl" );
307 return aImplementationId.
getSeq();
422 bool bExternalData =
true;
424 return bExternalData;
430 xModelProps->getPropertyValue(
"ExternalData" ) >>= bExternalData );
436 return bExternalData;
443 throw RuntimeException(
"Binding not initialized",
static_cast<XValueBinding*
>(
this));
464 xTarget->addEventListener(
"DOMCharacterDataModified",
466 xTarget->addEventListener(
"DOMCharacterDataModified",
468 xTarget->addEventListener(
"DOMAttrModified",
470 xTarget->addEventListener(
"DOMAttrModified",
472 xTarget->addEventListener(
"xforms-generic",
483 xTarget->removeEventListener(
"DOMCharacterDataModified",
485 xTarget->removeEventListener(
"DOMCharacterDataModified",
487 xTarget->removeEventListener(
"DOMAttrModified",
489 xTarget->removeEventListener(
"DOMAttrModified",
491 xTarget->removeEventListener(
"xforms-generic",
497 OSL_ENSURE(
getModelImpl() !=
nullptr,
"need model impl" );
502 ::std::vector<EvaluationContext> aVector;
503 for (
auto const& node : aNodes)
505 OSL_ENSURE( node.is(),
"no node?" );
516 throw RuntimeException(
"Binding has no Model",
static_cast<XValueBinding*
>(
this));
544 "we should bind to the newly inserted node!" );
566 OSL_ENSURE( pModel !=
nullptr,
"need model" );
571 for (
auto & context : aMIPContexts)
603static void lcl_modified(
const css::uno::Reference<css::util::XModifyListener>& xListener,
606 OSL_ENSURE( xListener.is(),
"no listener?" );
607 xListener->modified( EventObject( xSource ) );
611static void lcl_listentry(
const css::uno::Reference<css::form::binding::XListEntryListener>& xListener,
614 OSL_ENSURE( xListener.is(),
"no listener?" );
616 xListener->allEntriesChanged( EventObject( xSource ) );
620static void lcl_validate(
const css::uno::Reference<css::form::validation::XValidityConstraintListener>& xListener,
623 OSL_ENSURE( xListener.is(),
"no listener?" );
624 xListener->validityConstraintChanged( EventObject( xSource ) );
655 ::std::bind(
lcl_modified, std::placeholders::_1, xSource ) );
658 ::std::bind(
lcl_listentry, std::placeholders::_1, xSource ) );
661 ::std::bind(
lcl_validate, std::placeholders::_1, xSource ) );
671 pEvent->initXFormsEvent(
"xforms-generic",
true,
false);
674 css::uno::Reference<css::xml::dom::XNode> xNode( rxNode );
679 css::uno::Reference<css::xml::dom::XNode> child(xNode->getFirstChild());
688 target->dispatchEvent(pEvent);
690 xNode = xNode->getNextSibling();
741 OSL_ENSURE(
getModel().is(),
"need model" );
742 OSL_ENSURE(
getModel()->getDataTypeRepository().is(),
"need types" );
745 getModel()->getDataTypeRepository();
748 return ( xRepository.is() && xRepository->hasByName( sTypeName ) )
756 return !xDataType.is()
763 return xDataType.is()
772 if( pModel !=
nullptr )
793 css::uno::Reference<css::container::XNameContainer>
const & xTo )
795 OSL_ENSURE( xFrom.is(),
"no source" );
796 OSL_ENSURE( xTo.is(),
"no target" );
800 sal_Int32 nNames = aNames.getLength();
801 const OUString* pNames = aNames.getConstArray();
802 for( sal_Int32
i = 0;
i < nNames;
i++ )
804 const OUString& rName = pNames[
i];
806 if( ! xFrom->hasByName( rName ) )
807 xTo->removeByName( rName );
820 css::uno::Reference<css::container::XNameContainer>
const & xTo,
823 OSL_ENSURE( xFrom.is(),
"no source" );
824 OSL_ENSURE( xTo.is(),
"no target" );
828 sal_Int32 nNames = aNames.getLength();
829 const OUString* pNames = aNames.getConstArray();
830 for( sal_Int32
i = 0;
i < nNames;
i++ )
832 const OUString& rName = pNames[
i];
837 bool bInTarget = xTo->hasByName( rName );
841 bool bCopy = bOverwrite || ! bInTarget;
847 xTo->replaceByName( rName, xFrom->getByName( rName ) );
849 xTo->insertByName( rName, xFrom->getByName( rName ) );
863 if( pModel !=
nullptr )
875 css::uno::Reference<css::container::XNameContainer> xModelNamespaces = ( pModel != nullptr )
878 OSL_ENSURE( ( pModel !=
nullptr ) == xModelNamespaces.is(),
"no model nmsp?");
882 if( !bBinding && xModelNamespaces.is() )
887 sal_Int32 nNames = aNames.getLength();
888 const OUString* pNames = aNames.getConstArray();
889 for( sal_Int32
i = 0;
i < nNames;
i++ )
891 const OUString& rName = pNames[
i];
892 Any aValue = rNamespaces->getByName( rName );
897 ! xModelNamespaces.is()
900 && xModelNamespaces.is()
901 && xModelNamespaces->hasByName( rName ) );
904 css::uno::Reference<css::container::XNameContainer>& rWhich = bLocal ?
mxNamespaces : xModelNamespaces;
905 OSL_ENSURE( rWhich.is(),
"whoops" );
906 if( rWhich->hasByName( rName ) )
907 rWhich->replaceByName( rName, aValue );
909 rWhich->insertByName( rName, aValue );
912 if( xModelNamespaces.is()
913 && xModelNamespaces->hasByName( rName )
915 && xModelNamespaces->getByName( rName ) ==
mxNamespaces->getByName( rName ) )
935 OUString sIDPrefix =
getResource( RID_STR_XFORMS_BINDING_UI_NAME ) +
" ";
936 sal_Int32 nNumber = 0;
941 sName = sIDPrefix + OUString::number( nNumber );
943 while( xBindings->hasByName(
sName ) );
968 throw IncompatibleTypesException(
"type unsupported",
static_cast<XValueBinding*
>(
this));
988 throw IncompatibleTypesException(
"type unsupported",
static_cast<XValueBinding*
>(
this));
991 throw InvalidBindingStateException(
"no suitable node found",
static_cast<XValueBinding*
>(
this));
995 throw InvalidBindingStateException(
"no suitable node found",
static_cast<XValueBinding*
>(
this));
1000 throw InvalidBindingStateException(
"can't set value",
static_cast<XValueBinding*
>(
this));
1020 if( xNode->getNodeType() == NodeType_TEXT_NODE
1021 || xNode->getNodeType() == NodeType_ATTRIBUTE_NODE )
1023 rBuffer.append( xNode->getNodeValue() );
1029 xChild = xChild->getNextSibling() )
1040 return aBuffer.makeStringAndClear();
1051 throw IndexOutOfBoundsException(
"",
static_cast<XValueBinding*
>(
this));
1063 OUString* pSequence = aSequence.getArray();
1064 for( sal_Int32
n = 0;
n < aSequence.getLength();
n++ )
1074 OSL_ENSURE( xListener.is(),
"need listener!" );
1084 XListEntryListeners_t::iterator aIter =
1105 const css::uno::Any& )
1115 const css::uno::Reference<css::form::validation::XValidityConstraintListener>& xListener )
1117 OSL_ENSURE( xListener.is(),
"need listener!" );
1124 const css::uno::Reference<css::form::validation::XValidityConstraintListener>& xListener )
1126 XValidityConstraintListeners_t::iterator aIter =
1139 OUString
sType(xEvent->getType());
1142 if(
sType ==
"xforms-generic") {
1187 copy(
this, xClone );
1189 return css::uno::Reference<css::util::XCloneable>( xClone, UNO_QUERY );
1203 registerProperty( css::beans::Property(
"Model",
HANDLE_Model,
cppu::UnoType<css::uno::Reference<css::xforms::XModel>>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::READONLY ),
1206 registerProperty( css::beans::Property(
"BindingNamespaces",
HANDLE_BindingNamespaces,
cppu::UnoType<css::uno::Reference<css::container::XNameContainer>>::get(), css::beans::PropertyAttribute::BOUND ),
1209 registerProperty( css::beans::Property(
"ModelNamespaces",
HANDLE_ModelNamespaces,
cppu::UnoType<css::uno::Reference<css::container::XNameContainer>>::get(), css::beans::PropertyAttribute::BOUND ),
1248 const css::uno::Reference<css::util::XModifyListener>& xListener )
1250 OSL_ENSURE( xListener.is(),
"need listener!" );
1262 const css::uno::Reference<css::util::XModifyListener>& xListener )
1264 ModifyListeners_t::iterator aIter =
static void lcl_addListenerToNode(const Reference< XNode > &xNode, const Reference< XEventListener > &xListener)
static void lcl_getString(const Reference< XNode > &xNode, OUStringBuffer &rBuffer)
#define HANDLE_ExternalData
#define HANDLE_BindingExpression
static void lcl_copyNamespaces(const css::uno::Reference< css::container::XNameContainer > &xFrom, css::uno::Reference< css::container::XNameContainer > const &xTo, bool bOverwrite)
copy namespaces from one namespace container into another
static void lcl_validate(const css::uno::Reference< css::form::validation::XValidityConstraintListener > &xListener, const Reference< XInterface > &xSource)
static void lcl_modified(const css::uno::Reference< css::util::XModifyListener > &xListener, const Reference< XInterface > &xSource)
#define HANDLE_CalculateExpression
#define HANDLE_ConstraintExpression
static void lcl_removeOtherNamespaces(const css::uno::Reference< css::container::XNameContainer > &xFrom, css::uno::Reference< css::container::XNameContainer > const &xTo)
#define HANDLE_ModelNamespaces
static void lcl_removeListenerFromNode(const Reference< XNode > &xNode, const Reference< XEventListener > &xListener)
#define HANDLE_BindingNamespaces
#define HANDLE_RequiredExpression
static void lcl_listentry(const css::uno::Reference< css::form::binding::XListEntryListener > &xListener, const Reference< XInterface > &xSource)
#define HANDLE_ReadonlyExpression
#define HANDLE_RelevantExpression
helper class for implementing non-UNO accessors to a boolean property
helper class for implementing property accessors via non-UNO methods
const css::uno::Sequence< sal_Int8 > & getSeq() const
define the context for the evaluation of an XPath expression
css::uno::Reference< css::xml::dom::XNode > mxContextNode
css::uno::Reference< css::container::XNameContainer > mxNamespaces
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XInterface > xTarget
class SAL_NO_VTABLE XPropertySet
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
a helper class for notifying property changes in a <type>PropertySetBase</type> instance.
Reference< XModel > xModel
std::unique_ptr< char[]> aBuffer
bool isValidQName(const OUString &sName, const Reference< XNameContainer > &)