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 <com/sun/star/uno/Reference.hxx>
23 #include <cppuhelper/implbase.hxx>
24 #include "propertysetbase.hxx"
25 #include <com/sun/star/form/binding/XValueBinding.hpp>
26 #include <com/sun/star/form/binding/XListEntrySource.hpp>
27 #include <com/sun/star/form/validation/XValidator.hpp>
28 #include <com/sun/star/util/XModifyBroadcaster.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/xml/dom/events/XEventListener.hpp>
31 #include <com/sun/star/lang/XUnoTunnel.hpp>
32 #include <com/sun/star/util/XCloneable.hpp>
34 #include "pathexpression.hxx"
35 #include "boolexpression.hxx"
37 #include <rtl/ustring.hxx>
40 // forward declaractions
44 class EvaluationContext
;
46 namespace com::sun::star
{
48 namespace xpath
{ class XXPathAPI
; }
55 namespace container
{ class XNameContainer
; }
56 namespace xforms
{ class XModel
; }
57 namespace xsd
{ class XDataType
; }
64 /** An XForms Binding. Contains:
65 * # a connection to its model
67 * # a binding expression
68 * # model item properties
69 * # (NOT YET IMPLEMENTED) child bindings (sequence of)
71 * See http://www.w3.org/TR/xforms/ for more information.
74 typedef cppu::ImplInheritanceHelper
<
76 css::form::binding::XValueBinding
,
77 css::form::binding::XListEntrySource
,
78 css::form::validation::XValidator
,
79 css::util::XModifyBroadcaster
,
80 css::container::XNamed
,
81 css::xml::dom::events::XEventListener
,
82 css::lang::XUnoTunnel
,
86 class Binding
: public Binding_t
89 typedef std::vector
<css::uno::Reference
<css::util::XModifyListener
> > ModifyListeners_t
;
90 typedef std::vector
<css::uno::Reference
<css::form::validation::XValidityConstraintListener
> > XValidityConstraintListeners_t
;
91 typedef std::vector
<css::uno::Reference
<css::form::binding::XListEntryListener
> > XListEntryListeners_t
;
96 /// the Model to which this Binding belongs; may be NULL
97 css::uno::Reference
<css::xforms::XModel
> mxModel
;
99 /// binding-ID. A document-wide unique ID for this binding element.
100 OUString msBindingID
;
102 /// an XPath-expression to be instantiated on the data instance
103 PathExpression maBindingExpression
;
105 /// an XPath-expression to determine read-only status
106 BoolExpression maReadonly
;
108 /// an XPath-expression to determine relevance
109 BoolExpression maRelevant
;
111 /// an XPath-expression to determine if item is required
112 BoolExpression maRequired
;
114 /// an XPath-expression to determine if item is valid
115 BoolExpression maConstraint
;
117 /// user-readable explanation of the constraint
118 OUString msExplainConstraint
;
120 /// an XPath-expression to calculate values
121 ComputedExpression maCalculate
;
123 /// the XML namespaces used for XML names/XPath-expressions in this binding
124 css::uno::Reference
<css::container::XNameContainer
> mxNamespaces
;
130 ModifyListeners_t maModifyListeners
;
132 /// list entry listener
133 XListEntryListeners_t maListEntryListeners
;
135 /// validity listeners;
136 XValidityConstraintListeners_t maValidityListeners
;
138 /// nodes on which we are listening for events
139 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > maEventNodes
;
141 /// the current MIP object for the first node we are bound to
144 /// flag to detect recursions in calculate
147 // flags to manage deferred notifications:
148 /// if >0, valueModified() and bindingModified() will only set flags
149 sal_Int32 mnDeferModifyNotifications
;
150 bool mbValueModified
; /// if true, valueModified needs to be called
151 bool mbBindingModified
; /// if true, bindingModified needs to be called
154 void initializePropertySet();
159 virtual ~Binding() override
;
162 // property methods: get/set value
165 css::uno::Reference
<css::xforms::XModel
> getModel() const { return mxModel
;} /// get XForms model
166 void _setModel( const css::uno::Reference
<css::xforms::XModel
>& ); /// set XForms model (only called by Model)
169 OUString
getModelID() const; /// get ID of XForms model
171 OUString
getBindingID() const { return msBindingID
;} /// get ID for this binding
172 void setBindingID( const OUString
& ); /// set ID for this binding
174 OUString
getBindingExpression() const; /// get binding expression
175 void setBindingExpression( const OUString
& ); /// set binding exp.
177 // MIPs (model item properties)
179 OUString
getReadonlyExpression() const; /// get read-only MIP
180 void setReadonlyExpression( const OUString
& ); /// set read-only MIP
182 OUString
getRelevantExpression() const; /// get relevant MIP
183 void setRelevantExpression( const OUString
& ); /// set relevant MIP
185 OUString
getRequiredExpression() const; /// get required MIP
186 void setRequiredExpression( const OUString
& ); /// set required MIP
188 OUString
getConstraintExpression() const; /// get constraint MIP
189 void setConstraintExpression( const OUString
& );/// set constraint MIP
191 OUString
getCalculateExpression() const; /// get calculate MIP
192 void setCalculateExpression( const OUString
& ); /// set calculate MIP
194 OUString
getType() const { return msTypeName
;} /// get type name MIP (static)
195 void setType( const OUString
& ); /// set type name MIP (static)
197 // a binding expression can only be interpreted with respect to
198 // suitable namespace declarations. We collect those in the model and in a binding.
200 // access to a binding's namespace
201 // (set-method only changes local namespaces (but may add to model))
202 css::uno::Reference
<css::container::XNameContainer
> getBindingNamespaces() const { return mxNamespaces
; }
203 void setBindingNamespaces( const css::uno::Reference
<css::container::XNameContainer
>& ); /// get binding nmsp.
205 // access to the model's namespaces
206 // (set-method changes model's namespaces (unless a local one is present))
207 css::uno::Reference
<css::container::XNameContainer
> getModelNamespaces() const; /// set model namespaces
208 void setModelNamespaces( const css::uno::Reference
<css::container::XNameContainer
>& ); /// get model nmsp.
211 // read-only properties that map MIPs to control data source properties
212 bool getReadOnly() const; // MIP readonly
213 bool getRelevant() const; // MIP relevant
214 bool getExternalData() const; // mapped from model's ExternalData property
217 // missing binding properties:
218 // - type (static; default: xsd:string)
219 // - minOccurs/maxOccurs (computed XPath; default: 0/inf)
220 // - p3ptype (static; no default)
223 /// get this binding's context node
224 xforms::EvaluationContext
getEvaluationContext() const;
226 /// get evaluation contexts for this binding's MIPs
227 std::vector
<xforms::EvaluationContext
> getMIPEvaluationContexts();
229 /// get nodeset the bind is bound to
230 css::uno::Reference
<css::xml::dom::XNodeList
> getXNodeList();
232 /// heuristically determine whether this binding is simple binding
233 /// (here: simple binding == does not depend on other parts of the
234 /// instance, it's not a 'dynamic' binding)
235 bool isSimpleBinding() const;
237 /// heuristically determine whether this binding's binding
238 /// expression is simple
239 bool isSimpleBindingExpression() const;
241 /// update this binding (e.g. called by model for refresh )
244 /// prevent change notifications being sent to controls
245 void deferNotifications( bool );
247 /// is this binding valid? (are constraint, type and required MIPs ok?)
248 bool isValid() const;
250 /// determine whether this binding currently performs a useful
251 /// function, r whether is may be discarded
252 bool isUseful() const;
254 /// explain why binding is invalid
255 OUString
explainInvalid();
258 // the ID for XUnoTunnel calls
259 static css::uno::Sequence
<sal_Int8
> getUnoTunnelId();
263 /// check whether object is live, and throw suitable exception if not
264 /// (to be used be API methods before acting on the object)
266 /// @throws css::uno::RuntimeException
269 /// determine whether object is live
270 /// live: has model, and model has been initialized
273 /// get the model implementation
274 xforms::Model
* getModelImpl() const;
276 /// get MIP evaluation contexts
277 /// (only valid if control has already been bound)
278 std::vector
<xforms::EvaluationContext
> _getMIPEvaluationContexts() const;
280 /// bind this binding, and pre-compute the affected nodes
281 void bind( bool bForceRebind
= false );
283 /// the binding value has been changed:
284 /// trigger a modified event on all modified listeners
285 void valueModified();
287 /// the binding itself has changed:
288 /// force rebind, then call valueModified()
289 void bindingModified();
292 /// set MIPs defined by this binding on MIP item
293 MIP
getLocalMIP() const;
295 /// get the data type that applies to this binding
296 css::uno::Reference
<css::xsd::XDataType
> getDataType() const;
298 /// determine whether binding is valid according to the given data type
299 bool isValid_DataType() const;
301 /// explain validity of binding with respect to the given data type
302 OUString
explainInvalid_DataType();
304 /// 'clear' this binding - remove all listeners, etc.
307 /// distribute MIPs from current node recursively to children
308 void distributeMIP( const css::uno::Reference
<css::xml::dom::XNode
> &rxNode
);
310 /// implement get*Namespaces()
311 css::uno::Reference
<css::container::XNameContainer
> _getNamespaces() const;
313 /// implement set*Namespaces()
314 void _setNamespaces( const css::uno::Reference
<css::container::XNameContainer
>&, bool bBinding
);
316 /// set a useful default binding ID (if none is set)
317 void _checkBindingID();
321 virtual css::uno::Sequence
<css::uno::Type
> SAL_CALL
getSupportedValueTypes() override
;
323 virtual sal_Bool SAL_CALL
supportsType( const css::uno::Type
& aType
) override
;
325 virtual css::uno::Any SAL_CALL
getValue( const css::uno::Type
& aType
) override
;
327 virtual void SAL_CALL
setValue( const css::uno::Any
& aValue
) override
;
333 virtual sal_Int32 SAL_CALL
getListEntryCount() override
;
335 virtual OUString SAL_CALL
getListEntry( sal_Int32 nPosition
) override
;
337 virtual css::uno::Sequence
<OUString
> SAL_CALL
getAllListEntries() override
;
339 virtual void SAL_CALL
addListEntryListener( const css::uno::Reference
<css::form::binding::XListEntryListener
>& ) override
;
341 virtual void SAL_CALL
removeListEntryListener( const css::uno::Reference
<css::form::binding::XListEntryListener
>&) override
;
347 virtual sal_Bool SAL_CALL
isValid(
348 const css::uno::Any
& ) override
;
350 virtual OUString SAL_CALL
explainInvalid(
351 const css::uno::Any
& ) override
;
353 virtual void SAL_CALL
addValidityConstraintListener(
354 const css::uno::Reference
<css::form::validation::XValidityConstraintListener
>& xListener
) override
;
356 virtual void SAL_CALL
removeValidityConstraintListener(
357 const css::uno::Reference
<css::form::validation::XValidityConstraintListener
>& xListener
) override
;
360 // XModifyBroadcaster & friends:
361 // inform listeners about changes in our values
366 virtual void SAL_CALL
addModifyListener(
367 const css::uno::Reference
<css::util::XModifyListener
>& xListener
) override
;
369 virtual void SAL_CALL
removeModifyListener(
370 const css::uno::Reference
<css::util::XModifyListener
>& xListener
) override
;
379 virtual OUString SAL_CALL
getName() override
;
381 virtual void SAL_CALL
setName( const OUString
& ) override
;
384 // xml::dom::event::XEventListener
385 // receive an event if our node changed
388 virtual void SAL_CALL
handleEvent(
389 const css::uno::Reference
<css::xml::dom::events::XEvent
>& xEvent
) override
;
395 virtual sal_Int64 SAL_CALL
getSomething( const css::uno::Sequence
<sal_Int8
>& ) override
;
401 virtual css::uno::Reference
<css::util::XCloneable
> SAL_CALL
createClone() override
;
405 } // namespace xforms
407 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */