LCOV - code coverage report
Current view: top level - forms/source/xforms - binding.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 591 0.0 %
Date: 2012-08-25 Functions: 0 89 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 1218 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "binding.hxx"
      31                 :            : 
      32                 :            : #include "model.hxx"
      33                 :            : #include "unohelper.hxx"
      34                 :            : #include "NameContainer.hxx"
      35                 :            : #include "evaluationcontext.hxx"
      36                 :            : #include "convert.hxx"
      37                 :            : #include "resourcehelper.hxx"
      38                 :            : #include "xmlhelper.hxx"
      39                 :            : #include "xformsevent.hxx"
      40                 :            : 
      41                 :            : #include <rtl/ustrbuf.hxx>
      42                 :            : #include <osl/diagnose.h>
      43                 :            : 
      44                 :            : #include <tools/diagnose_ex.h>
      45                 :            : 
      46                 :            : #include <algorithm>
      47                 :            : #include <functional>
      48                 :            : 
      49                 :            : #include <com/sun/star/uno/Any.hxx>
      50                 :            : #include <com/sun/star/xml/dom/XNodeList.hpp>
      51                 :            : #include <com/sun/star/xml/dom/XNode.hpp>
      52                 :            : #include <com/sun/star/xml/dom/XDocument.hpp>
      53                 :            : #include <com/sun/star/xml/dom/XElement.hpp>
      54                 :            : #include <com/sun/star/xml/dom/NodeType.hpp>
      55                 :            : #include <com/sun/star/xml/dom/events/XEventTarget.hpp>
      56                 :            : #include <com/sun/star/xml/dom/events/XEventListener.hpp>
      57                 :            : #include <com/sun/star/xml/dom/events/XDocumentEvent.hpp>
      58                 :            : #include <com/sun/star/lang/XUnoTunnel.hpp>
      59                 :            : #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
      60                 :            : #include <com/sun/star/container/XSet.hpp>
      61                 :            : #include <com/sun/star/container/XNameContainer.hpp>
      62                 :            : 
      63                 :            : #include <comphelper/propertysetinfo.hxx>
      64                 :            : #include <unotools/textsearch.hxx>
      65                 :            : #include <cppuhelper/typeprovider.hxx>
      66                 :            : 
      67                 :            : using namespace com::sun::star::xml::xpath;
      68                 :            : using namespace com::sun::star::xml::dom::events;
      69                 :            : 
      70                 :            : using rtl::OUString;
      71                 :            : using rtl::OUStringBuffer;
      72                 :            : using std::vector;
      73                 :            : using xforms::Binding;
      74                 :            : using xforms::MIP;
      75                 :            : using xforms::Model;
      76                 :            : using xforms::getResource;
      77                 :            : using xforms::EvaluationContext;
      78                 :            : using com::sun::star::beans::PropertyVetoException;
      79                 :            : using com::sun::star::beans::UnknownPropertyException;
      80                 :            : using com::sun::star::beans::XPropertySet;
      81                 :            : using com::sun::star::container::XSet;
      82                 :            : using com::sun::star::container::XNameAccess;
      83                 :            : using com::sun::star::form::binding::IncompatibleTypesException;
      84                 :            : using com::sun::star::form::binding::InvalidBindingStateException;
      85                 :            : using com::sun::star::form::binding::XValueBinding;
      86                 :            : using com::sun::star::lang::EventObject;
      87                 :            : using com::sun::star::lang::IllegalArgumentException;
      88                 :            : using com::sun::star::lang::IndexOutOfBoundsException;
      89                 :            : using com::sun::star::lang::NoSupportException;
      90                 :            : using com::sun::star::lang::NullPointerException;
      91                 :            : using com::sun::star::lang::WrappedTargetException;
      92                 :            : using com::sun::star::lang::XUnoTunnel;
      93                 :            : using com::sun::star::uno::Any;
      94                 :            : using com::sun::star::uno::Reference;
      95                 :            : using com::sun::star::uno::RuntimeException;
      96                 :            : using com::sun::star::uno::Sequence;
      97                 :            : using com::sun::star::uno::UNO_QUERY;
      98                 :            : using com::sun::star::uno::UNO_QUERY_THROW;
      99                 :            : using com::sun::star::uno::XInterface;
     100                 :            : using com::sun::star::uno::Exception;
     101                 :            : using com::sun::star::uno::makeAny;
     102                 :            : using com::sun::star::util::XModifyListener;
     103                 :            : using com::sun::star::xforms::XDataTypeRepository;
     104                 :            : using com::sun::star::xml::dom::NodeType_ATTRIBUTE_NODE;
     105                 :            : using com::sun::star::xml::dom::NodeType_TEXT_NODE;
     106                 :            : using com::sun::star::xml::dom::XNode;
     107                 :            : using com::sun::star::xml::dom::XNodeList;
     108                 :            : using com::sun::star::xml::dom::events::XEventListener;
     109                 :            : using com::sun::star::xml::dom::events::XEventTarget;
     110                 :            : using com::sun::star::xsd::XDataType;
     111                 :            : 
     112                 :            : 
     113                 :            : 
     114                 :            : 
     115                 :            : #define EXCEPT(msg) OUSTRING(msg),static_cast<XValueBinding*>(this)
     116                 :            : 
     117                 :            : #define HANDLE_BindingID 0
     118                 :            : #define HANDLE_BindingExpression 1
     119                 :            : #define HANDLE_Model 2
     120                 :            : #define HANDLE_ModelID 3
     121                 :            : #define HANDLE_BindingNamespaces 4
     122                 :            : #define HANDLE_ReadonlyExpression 5
     123                 :            : #define HANDLE_RelevantExpression 6
     124                 :            : #define HANDLE_RequiredExpression 7
     125                 :            : #define HANDLE_ConstraintExpression 8
     126                 :            : #define HANDLE_CalculateExpression 9
     127                 :            : #define HANDLE_Type 10
     128                 :            : #define HANDLE_ReadOnly 11  // from com.sun.star.form.binding.ValueBinding, for interaction with a bound form control
     129                 :            : #define HANDLE_Relevant 12  // from com.sun.star.form.binding.ValueBinding, for interaction with a bound form control
     130                 :            : #define HANDLE_ModelNamespaces 13
     131                 :            : #define HANDLE_ExternalData 14
     132                 :            : 
     133                 :            : 
     134                 :          0 : Binding::Binding() :
     135                 :            :     mxModel(),
     136                 :            :     msBindingID(),
     137                 :            :     maBindingExpression(),
     138                 :            :     maReadonly(),
     139                 :          0 :     mxNamespaces( new NameContainer<OUString>() ),
     140                 :            :     mbInCalculate( false ),
     141                 :            :     mnDeferModifyNotifications( 0 ),
     142                 :            :     mbValueModified( false ),
     143 [ #  # ][ #  # ]:          0 :     mbBindingModified( false )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     144                 :            : 
     145                 :            : {
     146         [ #  # ]:          0 :     initializePropertySet();
     147                 :          0 : }
     148                 :            : 
     149 [ #  # ][ #  # ]:          0 : Binding::~Binding() throw()
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     150                 :            : {
     151 [ #  # ][ #  # ]:          0 :     _setModel(NULL);
     152         [ #  # ]:          0 : }
     153                 :            : 
     154                 :            : 
     155                 :          0 : Binding::Model_t Binding::getModel() const
     156                 :            : {
     157                 :          0 :     return mxModel;
     158                 :            : }
     159                 :            : 
     160                 :          0 : void Binding::_setModel( const Model_t& xModel )
     161                 :            : {
     162         [ #  # ]:          0 :     PropertyChangeNotifier aNotifyModelChange( *this, HANDLE_Model );
     163         [ #  # ]:          0 :     PropertyChangeNotifier aNotifyModelIDChange( *this, HANDLE_ModelID );
     164                 :            : 
     165                 :            :     // prepare binding for removal of old model
     166         [ #  # ]:          0 :     clear(); // remove all cached data (e.g. XPath evaluation results)
     167         [ #  # ]:          0 :     XNameContainer_t xNamespaces = getModelNamespaces(); // save namespaces
     168                 :            : 
     169         [ #  # ]:          0 :     mxModel = xModel;
     170                 :            : 
     171                 :            :     // set namespaces (and move to model, if appropriate)
     172         [ #  # ]:          0 :     setBindingNamespaces( xNamespaces );
     173         [ #  # ]:          0 :     _checkBindingID();
     174                 :            : 
     175 [ #  # ][ #  # ]:          0 :     notifyAndCachePropertyValue( HANDLE_ExternalData );
                 [ #  # ]
     176                 :          0 : }
     177                 :            : 
     178                 :            : 
     179                 :          0 : OUString Binding::getModelID() const
     180                 :            : {
     181                 :          0 :     Model* pModel = getModelImpl();
     182         [ #  # ]:          0 :     return ( pModel == NULL ) ? OUString() : pModel->getID();
     183                 :            : }
     184                 :            : 
     185                 :            : 
     186                 :          0 : Binding::XNodeList_t Binding::getXNodeList()
     187                 :            : {
     188                 :            :     // first make sure we are bound
     189         [ #  # ]:          0 :     if( ! maBindingExpression.hasValue() )
     190                 :          0 :         bind( sal_False );
     191                 :            : 
     192                 :          0 :     return maBindingExpression.getXNodeList();
     193                 :            : }
     194                 :            : 
     195                 :          0 : bool Binding::isSimpleBinding() const
     196                 :            : {
     197                 :          0 :     return maBindingExpression.isSimpleExpression()
     198                 :          0 :         && maReadonly.isSimpleExpression()
     199                 :          0 :         && maRelevant.isSimpleExpression()
     200                 :          0 :         && maRequired.isSimpleExpression()
     201                 :          0 :         && maConstraint.isSimpleExpression()
     202 [ #  # ][ #  #  :          0 :         && maCalculate.isSimpleExpression();
          #  #  #  #  #  
                #  #  # ]
     203                 :            : }
     204                 :            : 
     205                 :          0 : bool Binding::isSimpleBindingExpression() const
     206                 :            : {
     207                 :          0 :     return maBindingExpression.isSimpleExpression();
     208                 :            : }
     209                 :            : 
     210                 :          0 : void Binding::update()
     211                 :            : {
     212                 :            :     // clear all expressions (to remove cached node references)
     213                 :          0 :     maBindingExpression.clear();
     214                 :          0 :     maReadonly.clear();
     215                 :          0 :     maRelevant.clear();
     216                 :          0 :     maRequired.clear();
     217                 :          0 :     maConstraint.clear();
     218                 :          0 :     maCalculate.clear();
     219                 :            : 
     220                 :            :     // let's just pretend the binding has been modified -> full rebind()
     221                 :          0 :     bindingModified();
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : void Binding::deferNotifications( bool bDefer )
     225                 :            : {
     226         [ #  # ]:          0 :     mnDeferModifyNotifications += ( bDefer ? 1 : -1 );
     227                 :            :     OSL_ENSURE( mnDeferModifyNotifications >= 0, "you're deferring too much" );
     228                 :            : 
     229         [ #  # ]:          0 :     if( mnDeferModifyNotifications == 0 )
     230                 :            :     {
     231         [ #  # ]:          0 :         if( mbBindingModified )
     232                 :          0 :             bindingModified();
     233         [ #  # ]:          0 :         if( mbValueModified )
     234                 :          0 :             valueModified();
     235                 :            :     }
     236                 :            : 
     237                 :            :     OSL_ENSURE( ( mnDeferModifyNotifications > 0 )
     238                 :            :                 || ( ! mbBindingModified  &&  ! mbValueModified ),
     239                 :            :                 "deferred modifications not delivered?" );
     240                 :          0 : }
     241                 :            : 
     242                 :          0 : bool Binding::isValid()
     243                 :            : {
     244                 :            :     // TODO: determine whether node is suitable, not just whether it exists
     245 [ #  # ][ #  # ]:          0 :     return maBindingExpression.getNode().is() &&
                 [ #  # ]
     246         [ #  # ]:          0 :         isValid_DataType() &&
     247         [ #  # ]:          0 :         maMIP.isConstraint() &&
     248         [ #  # ]:          0 :         ( ! maMIP.isRequired() ||
     249         [ #  # ]:          0 :              ( maBindingExpression.hasValue() &&
     250 [ #  # ][ #  # ]:          0 :                !maBindingExpression.getString().isEmpty() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     251                 :            : }
     252                 :            : 
     253                 :          0 : bool Binding::isUseful()
     254                 :            : {
     255                 :            :     // we are useful, if
     256                 :            :     // 0) we don't have a model
     257                 :            :     //    (at least, in this case we shouldn't be removed from the model)
     258                 :            :     // 1) we have a proper name
     259                 :            :     // 2) we have some MIPs,
     260                 :            :     // 3) we are bound to some control
     261                 :            :     //    (this can be assumed if some listeners are set)
     262                 :            :     bool bUseful =
     263                 :          0 :         getModelImpl() == NULL
     264                 :            : //        || msBindingID.getLength() > 0
     265                 :          0 :         || ! msTypeName.isEmpty()
     266                 :          0 :         || ! maReadonly.isEmptyExpression()
     267                 :          0 :         || ! maRelevant.isEmptyExpression()
     268                 :          0 :         || ! maRequired.isEmptyExpression()
     269                 :          0 :         || ! maConstraint.isEmptyExpression()
     270                 :          0 :         || ! maCalculate.isEmptyExpression()
     271                 :          0 :         || ! maModifyListeners.empty()
     272                 :          0 :         || ! maListEntryListeners.empty()
     273 [ #  # ][ #  #  :          0 :         || ! maValidityListeners.empty();
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     274                 :            : 
     275                 :          0 :     return bUseful;
     276                 :            : }
     277                 :            : 
     278                 :          0 : OUString Binding::explainInvalid()
     279                 :            : {
     280                 :          0 :     OUString sReason;
     281 [ #  # ][ #  # ]:          0 :     if( ! maBindingExpression.getNode().is() )
     282                 :            :     {
     283         [ #  # ]:          0 :         sReason = ( maBindingExpression.getExpression().isEmpty() )
     284                 :            :             ? getResource( RID_STR_XFORMS_NO_BINDING_EXPRESSION )
     285 [ #  # ][ #  # ]:          0 :             : getResource( RID_STR_XFORMS_INVALID_BINDING_EXPRESSION );
                 [ #  # ]
     286                 :            :     }
     287 [ #  # ][ #  # ]:          0 :     else if( ! isValid_DataType() )
     288                 :            :     {
     289         [ #  # ]:          0 :         sReason = explainInvalid_DataType();
     290         [ #  # ]:          0 :         if( sReason.isEmpty() )
     291                 :            :         {
     292                 :            :             // no explanation given by data type? Then give generic message
     293                 :            :             sReason = getResource( RID_STR_XFORMS_INVALID_VALUE,
     294 [ #  # ][ #  # ]:          0 :                                    maMIP.getTypeName() );
     295                 :            :         }
     296                 :            :     }
     297 [ #  # ][ #  # ]:          0 :     else if( ! maMIP.isConstraint() )
     298                 :            :     {
     299         [ #  # ]:          0 :         sReason = maMIP.getConstraintExplanation();
     300                 :            :     }
     301 [ #  # ][ #  # ]:          0 :     else if( maMIP.isRequired() && maBindingExpression.hasValue() &&
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     302 [ #  # ][ #  # ]:          0 :         maBindingExpression.getString().isEmpty() )
                 [ #  # ]
           [ #  #  #  # ]
     303                 :            :     {
     304         [ #  # ]:          0 :         sReason = getResource( RID_STR_XFORMS_REQUIRED );
     305                 :            :     }
     306                 :            :     // else: no explanation given; should only happen if data is valid
     307                 :            : 
     308                 :            :     OSL_ENSURE( sReason.isEmpty() == isValid(),
     309                 :            :                 "invalid data should have an explanation!" );
     310                 :            : 
     311                 :          0 :     return sReason;
     312                 :            : }
     313                 :            : 
     314                 :            : 
     315                 :            : 
     316                 :          0 : EvaluationContext Binding::getEvaluationContext() const
     317                 :            : {
     318                 :            :     OSL_ENSURE( getModelImpl() != NULL, "need model impl" );
     319                 :          0 :     EvaluationContext aContext = getModelImpl()->getEvaluationContext();
     320 [ #  # ][ #  # ]:          0 :     aContext.mxNamespaces = getBindingNamespaces();
     321                 :          0 :     return aContext;
     322                 :            : }
     323                 :            : 
     324                 :          0 : ::std::vector<EvaluationContext> Binding::getMIPEvaluationContexts()
     325                 :            : {
     326                 :            :     OSL_ENSURE( getModelImpl() != NULL, "need model impl" );
     327                 :            : 
     328                 :            :     // bind (in case we were not bound before)
     329                 :          0 :     bind( sal_False );
     330                 :          0 :     return _getMIPEvaluationContexts();
     331                 :            : }
     332                 :            : 
     333                 :            : 
     334                 :          0 : Binding::IntSequence_t Binding::getUnoTunnelID()
     335                 :            : {
     336 [ #  # ][ #  # ]:          0 :     static cppu::OImplementationId aImplementationId;
     337                 :          0 :     return aImplementationId.getImplementationId();
     338                 :            : }
     339                 :            : 
     340                 :          0 : Binding* SAL_CALL Binding::getBinding( const Reference<XPropertySet>& xPropertySet )
     341                 :            : {
     342         [ #  # ]:          0 :     Reference<XUnoTunnel> xTunnel( xPropertySet, UNO_QUERY );
     343                 :          0 :     return xTunnel.is()
     344 [ #  # ][ #  # ]:          0 :         ? reinterpret_cast<Binding*>( xTunnel->getSomething(getUnoTunnelID()))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     345         [ #  # ]:          0 :         : NULL;
     346                 :            : }
     347                 :            : 
     348                 :            : 
     349                 :            : 
     350                 :            : 
     351                 :          0 : OUString Binding::getBindingID() const
     352                 :            : {
     353                 :          0 :     return msBindingID;
     354                 :            : }
     355                 :            : 
     356                 :          0 : void Binding::setBindingID( const OUString& sBindingID )
     357                 :            : {
     358                 :          0 :     msBindingID = sBindingID;
     359                 :          0 : }
     360                 :            : 
     361                 :          0 : OUString Binding::getBindingExpression() const
     362                 :            : {
     363                 :          0 :     return maBindingExpression.getExpression();
     364                 :            : }
     365                 :            : 
     366                 :          0 : void Binding::setBindingExpression( const OUString& sBindingExpression)
     367                 :            : {
     368                 :          0 :     maBindingExpression.setExpression( sBindingExpression );
     369                 :          0 :     bindingModified();
     370                 :          0 : }
     371                 :            : 
     372                 :          0 : OUString Binding::getReadonlyExpression() const
     373                 :            : {
     374                 :          0 :     return maReadonly.getExpression();
     375                 :            : }
     376                 :            : 
     377                 :          0 : void Binding::setReadonlyExpression( const OUString& sReadonly)
     378                 :            : {
     379                 :          0 :     maReadonly.setExpression( sReadonly );
     380                 :          0 :     bindingModified();
     381                 :          0 : }
     382                 :            : 
     383                 :          0 : OUString Binding::getRelevantExpression() const
     384                 :            : {
     385                 :          0 :     return maRelevant.getExpression();
     386                 :            : }
     387                 :            : 
     388                 :          0 : void Binding::setRelevantExpression( const OUString& sRelevant )
     389                 :            : {
     390                 :          0 :     maRelevant.setExpression( sRelevant );
     391                 :          0 :     bindingModified();
     392                 :          0 : }
     393                 :            : 
     394                 :          0 : OUString Binding::getRequiredExpression() const
     395                 :            : {
     396                 :          0 :     return maRequired.getExpression();
     397                 :            : }
     398                 :            : 
     399                 :          0 : void Binding::setRequiredExpression( const OUString& sRequired )
     400                 :            : {
     401                 :          0 :     maRequired.setExpression( sRequired );
     402                 :          0 :     bindingModified();
     403                 :          0 : }
     404                 :            : 
     405                 :          0 : OUString Binding::getConstraintExpression() const
     406                 :            : {
     407                 :          0 :     return maConstraint.getExpression();
     408                 :            : }
     409                 :            : 
     410                 :          0 : void Binding::setConstraintExpression( const OUString& sConstraint )
     411                 :            : {
     412                 :          0 :     maConstraint.setExpression( sConstraint );
     413                 :            :     msExplainConstraint = getResource( RID_STR_XFORMS_INVALID_CONSTRAINT,
     414                 :          0 :                                        sConstraint );
     415                 :            : 
     416                 :            :     // TODO: This should only re-evaluate the constraint, and notify
     417                 :            :     // the validity constraint listeners; instead we currently pretend
     418                 :            :     // the entire binding was notified, which does a little too much.
     419                 :          0 :     bindingModified();
     420                 :          0 : }
     421                 :            : 
     422                 :          0 : OUString Binding::getCalculateExpression() const
     423                 :            : {
     424                 :          0 :     return maCalculate.getExpression();
     425                 :            : }
     426                 :            : 
     427                 :          0 : void Binding::setCalculateExpression( const OUString& sCalculate )
     428                 :            : {
     429                 :          0 :     maCalculate.setExpression( sCalculate );
     430                 :          0 :     bindingModified();
     431                 :          0 : }
     432                 :            : 
     433                 :          0 : OUString Binding::getType() const
     434                 :            : {
     435                 :          0 :     return msTypeName;
     436                 :            : }
     437                 :            : 
     438                 :          0 : void Binding::setType( const OUString& sTypeName )
     439                 :            : {
     440                 :          0 :     msTypeName = sTypeName;
     441                 :          0 :     bindingModified();
     442                 :          0 : }
     443                 :            : 
     444                 :          0 : Binding::XNameContainer_t Binding::getBindingNamespaces() const
     445                 :            : {
     446                 :            :     //    return _getNamespaces();
     447                 :          0 :     return mxNamespaces;
     448                 :            : }
     449                 :            : 
     450                 :          0 : void Binding::setBindingNamespaces( const XNameContainer_t& rNamespaces )
     451                 :            : {
     452                 :          0 :     _setNamespaces( rNamespaces, true );
     453                 :          0 : }
     454                 :            : 
     455                 :          0 : Binding::XNameContainer_t Binding::getModelNamespaces() const
     456                 :            : {
     457                 :          0 :     return _getNamespaces();
     458                 :            : }
     459                 :            : 
     460                 :          0 : void Binding::setModelNamespaces( const XNameContainer_t& rNamespaces )
     461                 :            : {
     462                 :          0 :     _setNamespaces( rNamespaces, false );
     463                 :          0 : }
     464                 :            : 
     465                 :          0 : bool Binding::getReadOnly() const
     466                 :            : {
     467                 :          0 :     return maMIP.isReadonly();
     468                 :            : }
     469                 :            : 
     470                 :          0 : bool Binding::getRelevant() const
     471                 :            : {
     472                 :          0 :     return maMIP.isRelevant();
     473                 :            : }
     474                 :            : 
     475                 :          0 : bool Binding::getExternalData() const
     476                 :            : {
     477                 :          0 :     bool bExternalData = true;
     478         [ #  # ]:          0 :     if ( !mxModel.is() )
     479                 :          0 :         return bExternalData;
     480                 :            : 
     481                 :            :     try
     482                 :            :     {
     483         [ #  # ]:          0 :         Reference< XPropertySet > xModelProps( mxModel, UNO_QUERY_THROW );
     484 [ #  # ][ #  # ]:          0 :         OSL_VERIFY(
                 [ #  # ]
     485         [ #  # ]:          0 :             xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExternalData" ) ) ) >>= bExternalData );
     486                 :            :     }
     487         [ #  # ]:          0 :     catch( const Exception& )
     488                 :            :     {
     489                 :            :         DBG_UNHANDLED_EXCEPTION();
     490                 :            :     }
     491                 :          0 :     return bExternalData;
     492                 :            : }
     493                 :            : 
     494                 :            : 
     495                 :          0 : void Binding::checkLive()
     496                 :            :     throw( RuntimeException )
     497                 :            : {
     498         [ #  # ]:          0 :     if( ! isLive() )
     499 [ #  # ][ #  # ]:          0 :         throw RuntimeException( EXCEPT("Binding not initialized") );
                 [ #  # ]
     500                 :          0 : }
     501                 :            : 
     502                 :          0 : void Binding::checkModel()
     503                 :            :     throw( RuntimeException )
     504                 :            : {
     505         [ #  # ]:          0 :     if( ! mxModel.is() )
     506 [ #  # ][ #  # ]:          0 :         throw RuntimeException( EXCEPT("Binding has no Model") );
                 [ #  # ]
     507                 :          0 : }
     508                 :            : 
     509                 :          0 : bool Binding::isLive() const
     510                 :            : {
     511                 :          0 :     const Model* pModel = getModelImpl();
     512         [ #  # ]:          0 :     return ( pModel != NULL ) ? pModel->isInitialized() : false;
     513                 :            : }
     514                 :            : 
     515                 :          0 : Model* Binding::getModelImpl() const
     516                 :            : {
     517                 :          0 :     return getModelImpl( mxModel );
     518                 :            : }
     519                 :            : 
     520                 :          0 : Model* Binding::getModelImpl( const Model_t& xModel ) const
     521                 :            : {
     522         [ #  # ]:          0 :     Reference<XUnoTunnel> xTunnel( xModel, UNO_QUERY );
     523                 :          0 :     Model* pModel = xTunnel.is()
     524                 :            :         ? reinterpret_cast<Model*>(
     525 [ #  # ][ #  # ]:          0 :             xTunnel->getSomething( Model::getUnoTunnelID() ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     526         [ #  # ]:          0 :         : NULL;
     527                 :          0 :     return pModel;
     528                 :            : }
     529                 :            : 
     530                 :          0 : void lcl_addListenerToNode( Reference<XNode> xNode,
     531                 :            :                             Reference<XEventListener> xListener )
     532                 :            : {
     533         [ #  # ]:          0 :     Reference<XEventTarget> xTarget( xNode, UNO_QUERY );
     534         [ #  # ]:          0 :     if( xTarget.is() )
     535                 :            :     {
     536         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("DOMCharacterDataModified"),
     537 [ #  # ][ #  # ]:          0 :                                    xListener, false );
     538         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("DOMCharacterDataModified"),
     539 [ #  # ][ #  # ]:          0 :                                    xListener, true );
     540         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("DOMAttrModified"),
     541 [ #  # ][ #  # ]:          0 :                                    xListener, false );
     542         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("DOMAttrModified"),
     543 [ #  # ][ #  # ]:          0 :                                    xListener, true );
     544         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("DOMAttrModified"),
     545 [ #  # ][ #  # ]:          0 :                                    xListener, true );
     546         [ #  # ]:          0 :         xTarget->addEventListener( OUSTRING("xforms-generic"),
     547 [ #  # ][ #  # ]:          0 :                                    xListener, true );
     548                 :          0 :     }
     549                 :          0 : }
     550                 :            : 
     551                 :          0 : void lcl_removeListenerFromNode( Reference<XNode> xNode,
     552                 :            :                                  Reference<XEventListener> xListener )
     553                 :            : {
     554         [ #  # ]:          0 :     Reference<XEventTarget> xTarget( xNode, UNO_QUERY );
     555         [ #  # ]:          0 :     if( xTarget.is() )
     556                 :            :     {
     557         [ #  # ]:          0 :         xTarget->removeEventListener( OUSTRING("DOMCharacterDataModified"),
     558 [ #  # ][ #  # ]:          0 :                                       xListener, false );
     559         [ #  # ]:          0 :         xTarget->removeEventListener( OUSTRING("DOMCharacterDataModified"),
     560 [ #  # ][ #  # ]:          0 :                                       xListener, true );
     561         [ #  # ]:          0 :         xTarget->removeEventListener( OUSTRING("DOMAttrModified"),
     562 [ #  # ][ #  # ]:          0 :                                       xListener, false );
     563         [ #  # ]:          0 :         xTarget->removeEventListener( OUSTRING("DOMAttrModified"),
     564 [ #  # ][ #  # ]:          0 :                                       xListener, true );
     565         [ #  # ]:          0 :         xTarget->removeEventListener( OUSTRING("xforms-generic"),
     566 [ #  # ][ #  # ]:          0 :                                       xListener, true );
     567                 :          0 :     }
     568                 :          0 : }
     569                 :            : 
     570                 :          0 : ::std::vector<EvaluationContext> Binding::_getMIPEvaluationContexts() const
     571                 :            : {
     572                 :            :     OSL_ENSURE( getModelImpl() != NULL, "need model impl" );
     573                 :            : 
     574                 :            :     // iterate over nodes of bind expression and create
     575                 :            :     // EvaluationContext for each
     576         [ #  # ]:          0 :     PathExpression::NodeVector_t aNodes = maBindingExpression.getNodeList();
     577         [ #  # ]:          0 :     ::std::vector<EvaluationContext> aVector;
     578                 :          0 :     sal_Int32 nCount = 0; // count nodes for context position
     579 [ #  # ][ #  # ]:          0 :     for( PathExpression::NodeVector_t::iterator aIter = aNodes.begin();
     580                 :          0 :          aIter != aNodes.end();
     581                 :            :          ++aIter, ++nCount )
     582                 :            :     {
     583                 :            :         OSL_ENSURE( aIter->is(), "no node?" );
     584                 :            : 
     585                 :            :         // create proper evaluation context for this MIP
     586                 :          0 :         aVector.push_back( EvaluationContext( *aIter, getModel(),
     587                 :            :                                               getBindingNamespaces(),
     588         [ #  # ]:          0 :                                               nCount, aNodes.size() ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
     589                 :            :     }
     590                 :          0 :     return aVector;
     591                 :            : }
     592                 :            : 
     593                 :          0 : void Binding::bind( bool bForceRebind )
     594                 :            : {
     595         [ #  # ]:          0 :     checkModel();
     596                 :            : 
     597                 :            :     // bind() will evaluate this binding as follows:
     598                 :            :     // 1) evaluate the binding expression
     599                 :            :     // 1b) if necessary, create node according to 'lazy author' rules
     600                 :            :     // 2) register suitable listeners on the instance (and remove old ones)
     601                 :            :     // 3) remove old MIPs defined by this binding
     602                 :            :     // 4) for every node in the binding nodeset do:
     603                 :            :     //    1) create proper evaluation context for this MIP
     604                 :            :     //    2) evaluate calculate expression (and push value into instance)
     605                 :            :     //    3) evaluate remaining MIPs
     606                 :            :     //    4) evaluate the locally defined MIPs, and push them to the model
     607                 :            : 
     608                 :            : 
     609                 :            :     // 1) evaluate the binding expression
     610         [ #  # ]:          0 :     EvaluationContext aContext = getEvaluationContext();
     611         [ #  # ]:          0 :     maBindingExpression.evaluate( aContext );
     612 [ #  # ][ #  # ]:          0 :     if( ! maBindingExpression.getNode().is() )
     613                 :            :     {
     614                 :            :         // 1b) create node (if valid element name)
     615   [ #  #  #  # ]:          0 :         if( isValidQName( maBindingExpression.getExpression(),
     616         [ #  # ]:          0 :                           aContext.mxNamespaces ) )
     617                 :            :         {
     618         [ #  # ]:          0 :             aContext.mxContextNode->appendChild(
     619                 :            :                 Reference<XNode>(
     620 [ #  # ][ #  # ]:          0 :                     aContext.mxContextNode->getOwnerDocument()->createElement(
                 [ #  # ]
     621                 :          0 :                         maBindingExpression.getExpression() ),
     622 [ #  # ][ #  # ]:          0 :                     UNO_QUERY ) );
         [ #  # ][ #  # ]
     623         [ #  # ]:          0 :             maBindingExpression.evaluate( aContext );
     624                 :            :             OSL_ENSURE( maBindingExpression.getNode().is(),
     625                 :            :                         "we should bind to the newly inserted node!" );
     626                 :            :         }
     627                 :            :     }
     628         [ #  # ]:          0 :     PathExpression::NodeVector_t aNodes = maBindingExpression.getNodeList();
     629                 :            : 
     630                 :            :     // 2) register suitable listeners on the instance (and remove old ones)
     631 [ #  # ][ #  # ]:          0 :     if( maEventNodes.empty() || bForceRebind )
                 [ #  # ]
     632                 :            :     {
     633 [ #  # ][ #  # ]:          0 :         for( XNodes_t::iterator aIter = maEventNodes.begin();
     634                 :          0 :              aIter != maEventNodes.end();
     635                 :            :              ++aIter )
     636 [ #  # ][ #  # ]:          0 :             lcl_removeListenerFromNode( *aIter, this );
     637                 :          0 :         maEventNodes.clear();
     638 [ #  # ][ #  # ]:          0 :         if( isSimpleBinding() )
     639 [ #  # ][ #  # ]:          0 :             for( PathExpression::NodeVector_t::iterator aIter = aNodes.begin();
     640                 :          0 :                  aIter != aNodes.end();
     641                 :            :                  ++aIter )
     642         [ #  # ]:          0 :                 maEventNodes.push_back( *aIter );
     643                 :            :         else
     644                 :            :             maEventNodes.push_back(
     645         [ #  # ]:          0 :                 Reference<XNode>( aContext.mxContextNode->getOwnerDocument(),
     646 [ #  # ][ #  # ]:          0 :                                   UNO_QUERY_THROW ) );
                 [ #  # ]
     647 [ #  # ][ #  # ]:          0 :         for( PathExpression::NodeVector_t::iterator aIter2 = maEventNodes.begin();
     648                 :          0 :              aIter2 != maEventNodes.end();
     649                 :            :              ++aIter2 )
     650 [ #  # ][ #  # ]:          0 :             lcl_addListenerToNode( *aIter2, this );
     651                 :            :     }
     652                 :            : 
     653                 :            :     // 3) remove old MIPs defined by this binding
     654         [ #  # ]:          0 :     Model* pModel = getModelImpl();
     655                 :            :     OSL_ENSURE( pModel != NULL, "need model" );
     656         [ #  # ]:          0 :     pModel->removeMIPs( this );
     657                 :            : 
     658                 :            :     // 4) calculate all MIPs
     659         [ #  # ]:          0 :     ::std::vector<EvaluationContext> aMIPContexts = _getMIPEvaluationContexts();
     660 [ #  # ][ #  # ]:          0 :     for( ::std::vector<EvaluationContext>::iterator aIter = aMIPContexts.begin();
     661                 :          0 :          aIter != aMIPContexts.end();
     662                 :            :          ++aIter )
     663                 :            :     {
     664                 :          0 :         EvaluationContext& rContext = *aIter;
     665                 :            : 
     666                 :            :         // evaluate calculate expression (and push value into instance)
     667                 :            :         // (prevent recursion using mbInCalculate
     668 [ #  # ][ #  # ]:          0 :         if( ! maCalculate.isEmptyExpression() )
     669                 :            :         {
     670         [ #  # ]:          0 :             if( ! mbInCalculate )
     671                 :            :             {
     672                 :          0 :                 mbInCalculate = true;
     673         [ #  # ]:          0 :                 maCalculate.evaluate( rContext );
     674                 :            :                 pModel->setSimpleContent( rContext.mxContextNode,
     675 [ #  # ][ #  # ]:          0 :                                           maCalculate.getString() );
     676                 :          0 :                 mbInCalculate = false;
     677                 :            :             }
     678                 :            :         }
     679                 :            : 
     680                 :            :         // now evaluate remaining MIPs in the apropriate context
     681         [ #  # ]:          0 :         maReadonly.evaluate( rContext );
     682         [ #  # ]:          0 :         maRelevant.evaluate( rContext );
     683         [ #  # ]:          0 :         maRequired.evaluate( rContext );
     684         [ #  # ]:          0 :         maConstraint.evaluate( rContext );
     685                 :            :         // type is static; does not need updating
     686                 :            : 
     687                 :            :         // evaluate the locally defined MIPs, and push them to the model
     688 [ #  # ][ #  # ]:          0 :         pModel->addMIP( this, rContext.mxContextNode, getLocalMIP() );
                 [ #  # ]
     689         [ #  # ]:          0 :     }
     690                 :          0 : }
     691                 :            : 
     692                 :            : 
     693                 :            : // helper for Binding::valueModified
     694                 :          0 : void lcl_modified( const Binding::XModifyListener_t xListener,
     695                 :            :                    const Reference<XInterface> xSource )
     696                 :            : {
     697                 :            :     OSL_ENSURE( xListener.is(), "no listener?" );
     698         [ #  # ]:          0 :     xListener->modified( EventObject( xSource ) );
     699                 :          0 : }
     700                 :            : 
     701                 :            : // helper for Binding::valueModified
     702                 :          0 : void lcl_listentry( const Binding::XListEntryListener_t xListener,
     703                 :            :                     const Reference<XInterface> xSource )
     704                 :            : {
     705                 :            :     OSL_ENSURE( xListener.is(), "no listener?" );
     706                 :            :     // TODO: send fine granular events
     707         [ #  # ]:          0 :     xListener->allEntriesChanged( EventObject( xSource ) );
     708                 :          0 : }
     709                 :            : 
     710                 :            : // helper for Binding::valueModified
     711                 :          0 : void lcl_validate( const Binding::XValidityConstraintListener_t xListener,
     712                 :            :                    const Reference<XInterface> xSource )
     713                 :            : {
     714                 :            :     OSL_ENSURE( xListener.is(), "no listener?" );
     715         [ #  # ]:          0 :     xListener->validityConstraintChanged( EventObject( xSource ) );
     716                 :          0 : }
     717                 :            : 
     718                 :            : 
     719                 :          0 : void Binding::valueModified()
     720                 :            : {
     721                 :            :     // defer notifications, if so desired
     722         [ #  # ]:          0 :     if( mnDeferModifyNotifications > 0 )
     723                 :            :     {
     724                 :          0 :         mbValueModified = true;
     725                 :          0 :         return;
     726                 :            :     }
     727                 :          0 :     mbValueModified = false;
     728                 :            : 
     729                 :            :     // query MIP used by our first node (also note validity)
     730         [ #  # ]:          0 :     Reference<XNode> xNode = maBindingExpression.getNode();
     731 [ #  # ][ #  # ]:          0 :     maMIP = getModelImpl()->queryMIP( xNode );
                 [ #  # ]
     732                 :            : 
     733                 :            :     // distribute MIPs _used_ by this binding
     734         [ #  # ]:          0 :     if( xNode.is() )
     735                 :            :     {
     736         [ #  # ]:          0 :         notifyAndCachePropertyValue( HANDLE_ReadOnly );
     737         [ #  # ]:          0 :         notifyAndCachePropertyValue( HANDLE_Relevant );
     738                 :            :     }
     739                 :            : 
     740                 :            :     // iterate over _value_ listeners and send each a modified signal,
     741                 :            :     // using this object as source (will also update validity, because
     742                 :            :     // control will query once the value has changed)
     743         [ #  # ]:          0 :     Reference<XInterface> xSource = static_cast<XPropertySet*>( this );
     744                 :            :     ::std::for_each( maModifyListeners.begin(),
     745                 :            :               maModifyListeners.end(),
     746 [ #  # ][ #  # ]:          0 :               ::std::bind2nd( ::std::ptr_fun( lcl_modified ), xSource ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     747                 :            :     ::std::for_each( maListEntryListeners.begin(),
     748                 :            :               maListEntryListeners.end(),
     749 [ #  # ][ #  # ]:          0 :               ::std::bind2nd( ::std::ptr_fun( lcl_listentry ), xSource ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     750                 :            :     ::std::for_each( maValidityListeners.begin(),
     751                 :            :               maValidityListeners.end(),
     752 [ #  # ][ #  # ]:          0 :               ::std::bind2nd( ::std::ptr_fun( lcl_validate ), xSource ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     753                 :            : 
     754                 :            :     // now distribute MIPs to children
     755         [ #  # ]:          0 :     if( xNode.is() )
     756 [ #  # ][ #  # ]:          0 :         distributeMIP( xNode->getFirstChild() );
                 [ #  # ]
     757                 :            : }
     758                 :            : 
     759                 :          0 : void Binding::distributeMIP( const XNode_t & rxNode ) {
     760                 :            : 
     761                 :            :     typedef com::sun::star::xforms::XFormsEventConcrete XFormsEvent_t;
     762         [ #  # ]:          0 :     OUString sEventName( RTL_CONSTASCII_USTRINGPARAM("xforms-generic") );
     763         [ #  # ]:          0 :     XFormsEvent_t *pEvent = new XFormsEvent_t;
     764         [ #  # ]:          0 :     pEvent->initXFormsEvent(sEventName, sal_True, sal_False);
     765 [ #  # ][ #  # ]:          0 :     Reference<XEvent> xEvent(pEvent);
     766                 :            : 
     767                 :            :     // naive depth-first traversal
     768                 :          0 :     XNode_t xNode( rxNode );
     769         [ #  # ]:          0 :     while(xNode.is()) {
     770                 :            : 
     771                 :            :         // notifications should be triggered at the
     772                 :            :         // leaf nodes first, bubbling upwards the hierarchy.
     773 [ #  # ][ #  # ]:          0 :         XNode_t child(xNode->getFirstChild());
     774         [ #  # ]:          0 :         if(child.is())
     775         [ #  # ]:          0 :             distributeMIP(child);
     776                 :            : 
     777                 :            :         // we're standing at a particular node somewhere
     778                 :            :         // below the one which changed a property (MIP).
     779                 :            :         // bindings which are listening at this node will receive
     780                 :            :         // a notification message about what exactly happened.
     781         [ #  # ]:          0 :         Reference< XEventTarget > target(xNode,UNO_QUERY);
     782 [ #  # ][ #  # ]:          0 :         target->dispatchEvent(xEvent);
     783                 :            : 
     784 [ #  # ][ #  # ]:          0 :         xNode = xNode->getNextSibling();
                 [ #  # ]
     785                 :          0 :     };
     786                 :          0 : }
     787                 :            : 
     788                 :          0 : void Binding::bindingModified()
     789                 :            : {
     790                 :            :     // defer notifications, if so desired
     791         [ #  # ]:          0 :     if( mnDeferModifyNotifications > 0 )
     792                 :            :     {
     793                 :          0 :         mbBindingModified = true;
     794                 :          0 :         return;
     795                 :            :     }
     796                 :          0 :     mbBindingModified = false;
     797                 :            : 
     798                 :            :     // rebind (if live); then call valueModified
     799                 :            :     // A binding should be inert until its model is fully constructed.
     800         [ #  # ]:          0 :     if( isLive() )
     801                 :            :     {
     802                 :          0 :         bind( true );
     803                 :          0 :         valueModified();
     804                 :            :     }
     805                 :            : }
     806                 :            : 
     807                 :            : 
     808                 :          0 : MIP Binding::getLocalMIP() const
     809                 :            : {
     810                 :          0 :     MIP aMIP;
     811                 :            : 
     812 [ #  # ][ #  # ]:          0 :     if( maReadonly.hasValue() )
     813 [ #  # ][ #  # ]:          0 :         aMIP.setReadonly( maReadonly.getBool( false ) );
     814 [ #  # ][ #  # ]:          0 :     if( maRelevant.hasValue() )
     815 [ #  # ][ #  # ]:          0 :         aMIP.setRelevant( maRelevant.getBool( true ) );
     816 [ #  # ][ #  # ]:          0 :     if( maRequired.hasValue() )
     817 [ #  # ][ #  # ]:          0 :         aMIP.setRequired( maRequired.getBool( false ) );
     818 [ #  # ][ #  # ]:          0 :     if( maConstraint.hasValue() )
     819                 :            :     {
     820 [ #  # ][ #  # ]:          0 :         aMIP.setConstraint( maConstraint.getBool( true ) );
     821 [ #  # ][ #  # ]:          0 :         if( ! aMIP.isConstraint() )
     822         [ #  # ]:          0 :             aMIP.setConstraintExplanation( msExplainConstraint );
     823                 :            :     }
     824         [ #  # ]:          0 :     if( !msTypeName.isEmpty() )
     825         [ #  # ]:          0 :         aMIP.setTypeName( msTypeName );
     826                 :            : 
     827                 :            :     // calculate: only handle presence of calculate; value set elsewhere
     828 [ #  # ][ #  # ]:          0 :     aMIP.setHasCalculate( !maCalculate.isEmptyExpression() );
     829                 :            : 
     830                 :          0 :     return aMIP;
     831                 :            : }
     832                 :            : 
     833                 :          0 : Binding::XDataType_t Binding::getDataType()
     834                 :            : {
     835                 :            :     OSL_ENSURE( getModel().is(), "need model" );
     836                 :            :     OSL_ENSURE( getModel()->getDataTypeRepository().is(), "need types" );
     837                 :            : 
     838                 :            :     Reference<XDataTypeRepository> xRepository(
     839 [ #  # ][ #  # ]:          0 :         getModel()->getDataTypeRepository(), UNO_QUERY );
         [ #  # ][ #  # ]
     840         [ #  # ]:          0 :     OUString sTypeName = maMIP.getTypeName();
     841                 :            : 
     842 [ #  # ][ #  # ]:          0 :     return ( xRepository.is() && xRepository->hasByName( sTypeName ) )
     843         [ #  # ]:          0 :         ? Reference<XDataType>( xRepository->getByName( sTypeName ), UNO_QUERY)
     844 [ #  # ][ #  # ]:          0 :         : Reference<XDataType>( NULL );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     845                 :            : }
     846                 :            : 
     847                 :          0 : bool Binding::isValid_DataType()
     848                 :            : {
     849         [ #  # ]:          0 :     Reference<XDataType> xDataType = getDataType();
     850                 :          0 :     return xDataType.is()
     851 [ #  # ][ #  # ]:          0 :         ? xDataType->validate( maBindingExpression.getString() )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     852 [ #  # ][ #  # ]:          0 :         : true;
     853                 :            : }
     854                 :            : 
     855                 :          0 : rtl::OUString Binding::explainInvalid_DataType()
     856                 :            : {
     857         [ #  # ]:          0 :     Reference<XDataType> xDataType = getDataType();
     858                 :          0 :     return xDataType.is()
     859         [ #  # ]:          0 :         ? xDataType->explainInvalid( maBindingExpression.getString() )
     860 [ #  # ][ #  # ]:          0 :         : OUString();
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     861                 :            : }
     862                 :            : 
     863                 :          0 : void Binding::clear()
     864                 :            : {
     865                 :            :     // remove MIPs contributed by this binding
     866                 :          0 :     Model* pModel = getModelImpl();
     867         [ #  # ]:          0 :     if( pModel != NULL )
     868                 :          0 :         pModel->removeMIPs( this );
     869                 :            : 
     870                 :            :     // remove all references
     871 [ #  # ][ #  # ]:          0 :     for( XNodes_t::iterator aIter = maEventNodes.begin();
     872                 :          0 :          aIter != maEventNodes.end();
     873                 :            :          ++aIter )
     874 [ #  # ][ #  # ]:          0 :         lcl_removeListenerFromNode( *aIter, this );
     875                 :          0 :     maEventNodes.clear();
     876                 :            : 
     877                 :            :     // clear expressions
     878                 :          0 :     maBindingExpression.clear();
     879                 :          0 :     maReadonly.clear();
     880                 :          0 :     maRelevant.clear();
     881                 :          0 :     maRequired.clear();
     882                 :          0 :     maConstraint.clear();
     883                 :          0 :     maCalculate.clear();
     884                 :            : 
     885                 :            :     // TODO: what about our listeners?
     886                 :          0 : }
     887                 :            : 
     888                 :            : 
     889                 :          0 : void lcl_removeOtherNamespaces( const Binding::XNameContainer_t& xFrom,
     890                 :            :                                 Binding::XNameContainer_t& xTo )
     891                 :            : {
     892                 :            :     OSL_ENSURE( xFrom.is(), "no source" );
     893                 :            :     OSL_ENSURE( xTo.is(), "no target" );
     894                 :            : 
     895                 :            :     // iterate over name in source
     896 [ #  # ][ #  # ]:          0 :     Sequence<OUString> aNames = xTo->getElementNames();
     897                 :          0 :     sal_Int32 nNames = aNames.getLength();
     898                 :          0 :     const OUString* pNames = aNames.getConstArray();
     899         [ #  # ]:          0 :     for( sal_Int32 i = 0; i < nNames; i++ )
     900                 :            :     {
     901                 :          0 :         const OUString& rName = pNames[i];
     902                 :            : 
     903 [ #  # ][ #  # ]:          0 :         if( ! xFrom->hasByName( rName ) )
                 [ #  # ]
     904 [ #  # ][ #  # ]:          0 :             xTo->removeByName( rName );
     905         [ #  # ]:          0 :     }
     906                 :          0 : }
     907                 :            : 
     908                 :            : /** copy namespaces from one namespace container into another
     909                 :            :  * @param bOverwrite true: overwrite namespaces in target
     910                 :            :  *                   false: do not overwrite namespaces in target
     911                 :            :  * @param bMove true: move namespaces (i.e., delete in source)
     912                 :            :  *              false: copy namespaces (do not modify source)
     913                 :            :  * @param bFromSource true: use elements from source
     914                 :            :  *                    false: use only elements from target
     915                 :            :  */
     916                 :          0 : void lcl_copyNamespaces( const Binding::XNameContainer_t& xFrom,
     917                 :            :                          Binding::XNameContainer_t& xTo,
     918                 :            :                          bool bOverwrite )
     919                 :            : {
     920                 :            :     OSL_ENSURE( xFrom.is(), "no source" );
     921                 :            :     OSL_ENSURE( xTo.is(), "no target" );
     922                 :            : 
     923                 :            :     // iterate over name in source
     924 [ #  # ][ #  # ]:          0 :     Sequence<OUString> aNames = xFrom->getElementNames();
     925                 :          0 :     sal_Int32 nNames = aNames.getLength();
     926                 :          0 :     const OUString* pNames = aNames.getConstArray();
     927         [ #  # ]:          0 :     for( sal_Int32 i = 0; i < nNames; i++ )
     928                 :            :     {
     929                 :          0 :         const OUString& rName = pNames[i];
     930                 :            : 
     931                 :            :         // determine whether to copy the value, and whether to delete
     932                 :            :         // it in the source:
     933                 :            : 
     934 [ #  # ][ #  # ]:          0 :         bool bInTarget = xTo->hasByName( rName );
     935                 :            : 
     936                 :            :         // we copy: if property is in target, and
     937                 :            :         //          if bOverwrite is set, or when the namespace prefix is free
     938 [ #  # ][ #  # ]:          0 :         bool bCopy = bOverwrite || ! bInTarget;
     939                 :            : 
     940                 :            :         // and now... ACTION!
     941         [ #  # ]:          0 :         if( bCopy )
     942                 :            :         {
     943         [ #  # ]:          0 :             if( bInTarget )
     944 [ #  # ][ #  # ]:          0 :                 xTo->replaceByName( rName, xFrom->getByName( rName ) );
         [ #  # ][ #  # ]
     945                 :            :             else
     946 [ #  # ][ #  # ]:          0 :                 xTo->insertByName( rName, xFrom->getByName( rName ) );
         [ #  # ][ #  # ]
     947                 :            :         }
     948         [ #  # ]:          0 :     }
     949                 :          0 : }
     950                 :            : 
     951                 :            : // implement get*Namespaces()
     952                 :            : // (identical for both variants)
     953                 :          0 : Binding::XNameContainer_t Binding::_getNamespaces() const
     954                 :            : {
     955 [ #  # ][ #  # ]:          0 :     XNameContainer_t xNamespaces = new NameContainer<OUString>();
                 [ #  # ]
     956         [ #  # ]:          0 :     lcl_copyNamespaces( mxNamespaces, xNamespaces, true );
     957                 :            : 
     958                 :            :     // merge model's with binding's own namespaces
     959         [ #  # ]:          0 :     Model* pModel = getModelImpl();
     960         [ #  # ]:          0 :     if( pModel != NULL )
     961 [ #  # ][ #  # ]:          0 :         lcl_copyNamespaces( pModel->getNamespaces(), xNamespaces, false );
     962                 :            : 
     963                 :          0 :     return xNamespaces;
     964                 :            : }
     965                 :            : 
     966                 :            : // implement set*Namespaces()
     967                 :            : // bBinding = true: setBindingNamespaces, otherwise: setModelNamespaces
     968                 :          0 : void Binding::_setNamespaces( const XNameContainer_t& rNamespaces,
     969                 :            :                               bool bBinding )
     970                 :            : {
     971         [ #  # ]:          0 :     Model* pModel = getModelImpl();
     972                 :            :     XNameContainer_t xModelNamespaces = ( pModel != NULL )
     973                 :            :                                             ? pModel->getNamespaces()
     974 [ #  # ][ #  # ]:          0 :                                             : NULL;
                 [ #  # ]
     975                 :            :     OSL_ENSURE( ( pModel != NULL ) == xModelNamespaces.is(), "no model nmsp?");
     976                 :            : 
     977                 :            :     // remove deleted namespaces
     978         [ #  # ]:          0 :     lcl_removeOtherNamespaces( rNamespaces, mxNamespaces );
     979 [ #  # ][ #  # ]:          0 :     if( !bBinding && xModelNamespaces.is() )
                 [ #  # ]
     980         [ #  # ]:          0 :         lcl_removeOtherNamespaces( rNamespaces, xModelNamespaces );
     981                 :            : 
     982                 :            :     // copy namespaces as appropriate
     983 [ #  # ][ #  # ]:          0 :     Sequence<OUString> aNames = rNamespaces->getElementNames();
     984                 :          0 :     sal_Int32 nNames = aNames.getLength();
     985                 :          0 :     const OUString* pNames = aNames.getConstArray();
     986         [ #  # ]:          0 :     for( sal_Int32 i = 0; i < nNames; i++ )
     987                 :            :     {
     988                 :          0 :         const OUString& rName = pNames[i];
     989 [ #  # ][ #  # ]:          0 :         Any aValue = rNamespaces->getByName( rName );
     990                 :            : 
     991                 :            :         // determine whether the namespace should go into model's or
     992                 :            :         // into binding's namespaces
     993                 :            :         bool bLocal =
     994                 :          0 :             ! xModelNamespaces.is()
     995 [ #  # ][ #  # ]:          0 :             || mxNamespaces->hasByName( rName )
     996                 :            :             || ( bBinding
     997                 :          0 :                  && xModelNamespaces.is()
     998         [ #  # ]:          0 :                  && xModelNamespaces->hasByName( rName ) );
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     999                 :            : 
    1000                 :            :         // write namespace into the appropriate namespace container
    1001         [ #  # ]:          0 :         XNameContainer_t& rWhich = bLocal ? mxNamespaces : xModelNamespaces;
    1002                 :            :         OSL_ENSURE( rWhich.is(), "whoops" );
    1003 [ #  # ][ #  # ]:          0 :         if( rWhich->hasByName( rName ) )
                 [ #  # ]
    1004 [ #  # ][ #  # ]:          0 :             rWhich->replaceByName( rName, aValue );
    1005                 :            :         else
    1006 [ #  # ][ #  # ]:          0 :             rWhich->insertByName( rName, aValue );
    1007                 :            : 
    1008                 :            :         // always 'promote' namespaces from binding to model, if equal
    1009 [ #  # ][ #  # ]:          0 :         if( xModelNamespaces.is()
           [ #  #  #  # ]
                 [ #  # ]
    1010 [ #  # ][ #  # ]:          0 :             && xModelNamespaces->hasByName( rName )
    1011 [ #  # ][ #  # ]:          0 :             && mxNamespaces->hasByName( rName )
    1012 [ #  # ][ #  # ]:          0 :             && xModelNamespaces->getByName( rName ) == mxNamespaces->getByName( rName ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
    1013                 :            :         {
    1014 [ #  # ][ #  # ]:          0 :             mxNamespaces->removeByName( rName );
    1015                 :            :         }
    1016                 :          0 :     }
    1017                 :            : 
    1018                 :            :     // ... done. But we modified the binding!
    1019 [ #  # ][ #  # ]:          0 :     bindingModified();
    1020                 :          0 : }
    1021                 :            : 
    1022                 :          0 : void Binding::_checkBindingID()
    1023                 :            : {
    1024         [ #  # ]:          0 :     if( getModel().is() )
    1025                 :            :     {
    1026 [ #  # ][ #  # ]:          0 :         Reference<XNameAccess> xBindings( getModel()->getBindings(), UNO_QUERY_THROW );
         [ #  # ][ #  # ]
    1027         [ #  # ]:          0 :         if( msBindingID.isEmpty() )
    1028                 :            :         {
    1029                 :            :             // no binding ID? then make one up!
    1030         [ #  # ]:          0 :             OUString sIDPrefix = getResource( RID_STR_XFORMS_BINDING_UI_NAME );
    1031                 :          0 :             sIDPrefix += rtl::OUString(" ");
    1032                 :          0 :             sal_Int32 nNumber = 0;
    1033                 :          0 :             OUString sName;
    1034         [ #  # ]:          0 :             do
    1035                 :            :             {
    1036                 :          0 :                 nNumber++;
    1037                 :          0 :                 sName = sIDPrefix + OUString::valueOf( nNumber );
    1038                 :            :             }
    1039 [ #  # ][ #  # ]:          0 :             while( xBindings->hasByName( sName ) );
    1040                 :          0 :             setBindingID( sName );
    1041                 :          0 :         }
    1042                 :            :     }
    1043                 :          0 : }
    1044                 :            : 
    1045                 :            : 
    1046                 :            : 
    1047                 :            : 
    1048                 :            : //
    1049                 :            : // XValueBinding
    1050                 :            : //
    1051                 :            : 
    1052                 :          0 : Binding::Sequence_Type_t Binding::getSupportedValueTypes()
    1053                 :            :     throw( RuntimeException )
    1054                 :            : {
    1055                 :          0 :     return Convert::get().getTypes();
    1056                 :            : }
    1057                 :            : 
    1058                 :          0 : sal_Bool Binding::supportsType( const Type_t& rType )
    1059                 :            :     throw( RuntimeException )
    1060                 :            : {
    1061                 :          0 :     return Convert::get().hasType( rType );
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : Binding::Any_t Binding::getValue( const Type_t& rType )
    1065                 :            :     throw( IncompatibleTypesException,
    1066                 :            :            RuntimeException )
    1067                 :            : {
    1068                 :            :     // first, check for model
    1069                 :          0 :     checkLive();
    1070                 :            : 
    1071                 :            :     // second, check for type
    1072         [ #  # ]:          0 :     if( ! supportsType( rType ) )
    1073 [ #  # ][ #  # ]:          0 :         throw IncompatibleTypesException( EXCEPT( "type unsupported" ) );
                 [ #  # ]
    1074                 :            : 
    1075                 :            :     // return string value (if present; else return empty Any)
    1076                 :          0 :         Binding::Any_t result = Any();
    1077 [ #  # ][ #  # ]:          0 :         if(maBindingExpression.hasValue()) {
    1078         [ #  # ]:          0 :             rtl::OUString pathExpr(maBindingExpression.getString());
    1079         [ #  # ]:          0 :             Convert &rConvert = Convert::get();
    1080         [ #  # ]:          0 :             result = rConvert.toAny(pathExpr,rType);
    1081                 :            :         }
    1082                 :            : 
    1083                 :            : //      return maBindingExpression.hasValue()
    1084                 :            :   //      ? Convert::get().toAny( maBindingExpression.getString(), rType )
    1085                 :            :     //    : Any();
    1086                 :            : 
    1087                 :          0 :         return result;
    1088                 :            : }
    1089                 :            : 
    1090                 :          0 : void Binding::setValue( const Any_t& aValue )
    1091                 :            :     throw( IncompatibleTypesException,
    1092                 :            :            InvalidBindingStateException,
    1093                 :            :            NoSupportException,
    1094                 :            :            RuntimeException )
    1095                 :            : {
    1096                 :            :     // first, check for model
    1097                 :          0 :     checkLive();
    1098                 :            : 
    1099                 :            :     // check for supported type
    1100         [ #  # ]:          0 :     if( ! supportsType( aValue.getValueType() ) )
    1101 [ #  # ][ #  # ]:          0 :         throw IncompatibleTypesException( EXCEPT( "type unsupported" ) );
                 [ #  # ]
    1102                 :            : 
    1103         [ #  # ]:          0 :     if( maBindingExpression.hasValue() )
    1104                 :            :     {
    1105         [ #  # ]:          0 :         Binding::XNode_t xNode = maBindingExpression.getNode();
    1106         [ #  # ]:          0 :         if( xNode.is() )
    1107                 :            :         {
    1108 [ #  # ][ #  # ]:          0 :             OUString sValue = Convert::get().toXSD( aValue );
    1109 [ #  # ][ #  # ]:          0 :             bool bSuccess = getModelImpl()->setSimpleContent( xNode, sValue );
    1110         [ #  # ]:          0 :             if( ! bSuccess )
    1111 [ #  # ][ #  # ]:          0 :                 throw InvalidBindingStateException( EXCEPT( "can't set value" ) );
                 [ #  # ]
    1112                 :            :         }
    1113                 :            :         else
    1114 [ #  # ][ #  # ]:          0 :             throw InvalidBindingStateException( EXCEPT( "no suitable node found" ) );
                 [ #  # ]
    1115                 :            :     }
    1116                 :            :     else
    1117 [ #  # ][ #  # ]:          0 :         throw InvalidBindingStateException( EXCEPT( "no suitable node found" ) );
                 [ #  # ]
    1118                 :          0 : }
    1119                 :            : 
    1120                 :            : 
    1121                 :            : //
    1122                 :            : // XListEntry Source
    1123                 :            : //
    1124                 :            : 
    1125                 :          0 : sal_Int32 Binding::getListEntryCount()
    1126                 :            :     throw( RuntimeException )
    1127                 :            : {
    1128                 :            :     // first, check for model
    1129                 :          0 :     checkLive();
    1130                 :            : 
    1131                 :            :     // return size of node list
    1132                 :          0 :     return maBindingExpression.getNodeList().size();
    1133                 :            : }
    1134                 :            : 
    1135                 :          0 : void lcl_getString( const Reference<XNode>& xNode, OUStringBuffer& rBuffer )
    1136                 :            : {
    1137   [ #  #  #  # ]:          0 :     if( xNode->getNodeType() == NodeType_TEXT_NODE
                 [ #  # ]
    1138                 :          0 :         || xNode->getNodeType() == NodeType_ATTRIBUTE_NODE )
    1139                 :            :     {
    1140         [ #  # ]:          0 :         rBuffer.append( xNode->getNodeValue() );
    1141                 :            :     }
    1142                 :            :     else
    1143                 :            :     {
    1144 [ #  # ][ #  # ]:          0 :         for( Reference<XNode> xChild = xNode->getFirstChild();
           [ #  #  #  # ]
    1145                 :          0 :              xChild.is();
    1146 [ #  # ][ #  # ]:          0 :              xChild = xChild->getNextSibling() )
    1147                 :            :         {
    1148         [ #  # ]:          0 :             lcl_getString( xChild, rBuffer );
    1149                 :          0 :         }
    1150                 :            :     }
    1151                 :          0 : }
    1152                 :            : 
    1153                 :          0 : OUString lcl_getString( const Reference<XNode>& xNode )
    1154                 :            : {
    1155                 :          0 :     OUStringBuffer aBuffer;
    1156         [ #  # ]:          0 :     lcl_getString( xNode, aBuffer );
    1157         [ #  # ]:          0 :     return aBuffer.makeStringAndClear();
    1158                 :            : }
    1159                 :            : 
    1160                 :          0 : OUString Binding::getListEntry( sal_Int32 nPosition )
    1161                 :            :     throw( IndexOutOfBoundsException,
    1162                 :            :            RuntimeException )
    1163                 :            : {
    1164                 :            :     // first, check for model
    1165         [ #  # ]:          0 :     checkLive();
    1166                 :            : 
    1167                 :            :     // check bounds and return proper item
    1168         [ #  # ]:          0 :     PathExpression::NodeVector_t aNodes = maBindingExpression.getNodeList();
    1169 [ #  # ][ #  # ]:          0 :     if( nPosition < 0 || nPosition >= static_cast<sal_Int32>( aNodes.size() ) )
                 [ #  # ]
    1170 [ #  # ][ #  # ]:          0 :         throw IndexOutOfBoundsException( EXCEPT("") );
                 [ #  # ]
    1171         [ #  # ]:          0 :     return lcl_getString( aNodes[ nPosition ] );
    1172                 :            : }
    1173                 :            : 
    1174                 :          0 : Sequence<OUString> Binding::getAllListEntries()
    1175                 :            :     throw( RuntimeException )
    1176                 :            : {
    1177                 :            :     // first, check for model
    1178         [ #  # ]:          0 :     checkLive();
    1179                 :            : 
    1180                 :            :     // create sequence of string values
    1181         [ #  # ]:          0 :     PathExpression::NodeVector_t aNodes = maBindingExpression.getNodeList();
    1182         [ #  # ]:          0 :     Sequence<OUString> aSequence( aNodes.size() );
    1183         [ #  # ]:          0 :     OUString* pSequence = aSequence.getArray();
    1184         [ #  # ]:          0 :     for( sal_Int32 n = 0; n < aSequence.getLength(); n++ )
    1185                 :            :     {
    1186         [ #  # ]:          0 :         pSequence[n] = lcl_getString( aNodes[n] );
    1187                 :            :     }
    1188                 :            : 
    1189                 :          0 :     return aSequence;
    1190                 :            : }
    1191                 :            : 
    1192                 :          0 : void Binding::addListEntryListener( const XListEntryListener_t& xListener )
    1193                 :            :     throw( NullPointerException,
    1194                 :            :            RuntimeException )
    1195                 :            : {
    1196                 :            :     OSL_ENSURE( xListener.is(), "need listener!" );
    1197 [ #  # ][ #  # ]:          0 :     if( ::std::find( maListEntryListeners.begin(),
    1198                 :            :               maListEntryListeners.end(),
    1199                 :          0 :               xListener)
    1200         [ #  # ]:          0 :         == maListEntryListeners.end() )
    1201                 :          0 :         maListEntryListeners.push_back( xListener );
    1202                 :          0 : }
    1203                 :            : 
    1204                 :          0 : void Binding::removeListEntryListener( const XListEntryListener_t& xListener )
    1205                 :            :     throw( NullPointerException,
    1206                 :            :            RuntimeException )
    1207                 :            : {
    1208                 :            :     XListEntryListeners_t::iterator aIter =
    1209                 :            :         ::std::find( maListEntryListeners.begin(), maListEntryListeners.end(),
    1210         [ #  # ]:          0 :               xListener );
    1211 [ #  # ][ #  # ]:          0 :     if( aIter != maListEntryListeners.end() )
    1212         [ #  # ]:          0 :         maListEntryListeners.erase( aIter );
    1213                 :          0 : }
    1214                 :            : 
    1215                 :            : 
    1216                 :            : //
    1217                 :            : // XValidator
    1218                 :            : //
    1219                 :            : 
    1220                 :          0 : sal_Bool Binding::isValid( const Any_t& )
    1221                 :            :     throw( RuntimeException )
    1222                 :            : {
    1223                 :            :     // first, check for model
    1224                 :          0 :     checkLive();
    1225                 :            : 
    1226                 :            :     // ignore value; determine validate only on current data
    1227                 :          0 :     return isValid();
    1228                 :            : }
    1229                 :            : 
    1230                 :          0 : rtl::OUString Binding::explainInvalid(
    1231                 :            :     const Any_t& /*Value*/ )
    1232                 :            :     throw( RuntimeException )
    1233                 :            : {
    1234                 :            :     // first, check for model
    1235                 :          0 :     checkLive();
    1236                 :            : 
    1237                 :            :     // ignore value; determine explanation  only on current data
    1238                 :          0 :     return explainInvalid();
    1239                 :            : }
    1240                 :            : 
    1241                 :          0 : void Binding::addValidityConstraintListener(
    1242                 :            :     const XValidityConstraintListener_t& xListener )
    1243                 :            :     throw( NullPointerException,
    1244                 :            :            RuntimeException )
    1245                 :            : {
    1246                 :            :     OSL_ENSURE( xListener.is(), "need listener!" );
    1247 [ #  # ][ #  # ]:          0 :     if( ::std::find(maValidityListeners.begin(), maValidityListeners.end(), xListener)
    1248         [ #  # ]:          0 :         == maValidityListeners.end() )
    1249                 :          0 :         maValidityListeners.push_back( xListener );
    1250                 :          0 : }
    1251                 :            : 
    1252                 :          0 : void Binding::removeValidityConstraintListener(
    1253                 :            :     const XValidityConstraintListener_t& xListener )
    1254                 :            :     throw( NullPointerException,
    1255                 :            :            RuntimeException )
    1256                 :            : {
    1257                 :            :     XValidityConstraintListeners_t::iterator aIter =
    1258                 :            :         ::std::find( maValidityListeners.begin(), maValidityListeners.end(),
    1259         [ #  # ]:          0 :               xListener );
    1260 [ #  # ][ #  # ]:          0 :     if( aIter != maValidityListeners.end() )
    1261         [ #  # ]:          0 :         maValidityListeners.erase( aIter );
    1262                 :          0 : }
    1263                 :            : 
    1264                 :            : 
    1265                 :            : 
    1266                 :            : //
    1267                 :            : // xml::dom::event::XEventListener
    1268                 :            : //
    1269                 :            : 
    1270                 :          0 : void Binding::handleEvent( const XEvent_t& xEvent )
    1271                 :            :     throw( RuntimeException )
    1272                 :            : {
    1273 [ #  # ][ #  # ]:          0 :     OUString sType(xEvent->getType());
    1274                 :            :     //OUString sEventMIPChanged(RTL_CONSTASCII_USTRINGPARAM("xforms-generic"));
    1275                 :            :     //if(sType.equals(sEventMIPChanged)) {
    1276         [ #  # ]:          0 :     if(!sType.compareToAscii("xforms-generic")) {
    1277                 :            : 
    1278                 :            :         // the modification of the 'mnDeferModifyNotifications'-member
    1279                 :            :         // is necessary to prevent infinite notication looping.
    1280                 :            :         // This can happend in case the binding which caused
    1281                 :            :         // the notification chain is listening to those events
    1282                 :            :         // as well...
    1283                 :          0 :         bool bPreserveValueModified = mbValueModified;
    1284                 :          0 :         mnDeferModifyNotifications++;
    1285         [ #  # ]:          0 :         valueModified();
    1286                 :          0 :         --mnDeferModifyNotifications;
    1287                 :          0 :         mbValueModified = bPreserveValueModified;
    1288                 :          0 :         return;
    1289                 :            :     }
    1290                 :            : 
    1291                 :            :     // if we're a dynamic binding, we better re-bind, too!
    1292         [ #  # ]:          0 :     bind( false );
    1293                 :            : 
    1294                 :            :     // our value was maybe modified
    1295 [ #  # ][ #  # ]:          0 :     valueModified();
    1296                 :            : }
    1297                 :            : 
    1298                 :            : 
    1299                 :            : //
    1300                 :            : // lang::XUnoTunnel
    1301                 :            : //
    1302                 :            : 
    1303                 :          0 : sal_Int64 Binding::getSomething( const IntSequence_t& xId )
    1304                 :            :     throw( RuntimeException )
    1305                 :            : {
    1306 [ #  # ][ #  # ]:          0 :     return reinterpret_cast<sal_Int64>( ( xId == getUnoTunnelID() ) ? this : NULL );
    1307                 :            : }
    1308                 :            : 
    1309                 :            : //
    1310                 :            : // XCloneable
    1311                 :            : //
    1312                 :            : 
    1313                 :          0 : Binding::XCloneable_t SAL_CALL Binding::createClone()
    1314                 :            :     throw( RuntimeException )
    1315                 :            : {
    1316                 :          0 :     Reference< XPropertySet > xClone;
    1317                 :            : 
    1318         [ #  # ]:          0 :     Model* pModel = getModelImpl();
    1319         [ #  # ]:          0 :     if ( pModel )
    1320 [ #  # ][ #  # ]:          0 :         xClone = pModel->cloneBinding( this );
                 [ #  # ]
    1321                 :            :     else
    1322                 :            :     {
    1323 [ #  # ][ #  # ]:          0 :         xClone = new Binding;
                 [ #  # ]
    1324 [ #  # ][ #  # ]:          0 :         copy( this, xClone );
    1325                 :            :     }
    1326         [ #  # ]:          0 :     return XCloneable_t( xClone, UNO_QUERY );
    1327                 :            : }
    1328                 :            : 
    1329                 :            : //
    1330                 :            : // property set implementations
    1331                 :            : //
    1332                 :            : 
    1333                 :            : #define REGISTER_PROPERTY( property, type )   \
    1334                 :            :     registerProperty( PROPERTY( property, type ), \
    1335                 :            :     new DirectPropertyAccessor< Binding, type >( this, &Binding::set##property, &Binding::get##property ) );
    1336                 :            : 
    1337                 :            : #define REGISTER_PROPERTY_RO( property, type )   \
    1338                 :            :     registerProperty( PROPERTY_RO( property, type ), \
    1339                 :            :     new DirectPropertyAccessor< Binding, type >( this, NULL, &Binding::get##property ) );
    1340                 :            : 
    1341                 :            : #define REGISTER_BOOL_PROPERTY_RO( property )   \
    1342                 :            :     registerProperty( PROPERTY_RO( property, sal_Bool ), \
    1343                 :            :     new BooleanPropertyAccessor< Binding, bool >( this, NULL, &Binding::get##property ) );
    1344                 :            : 
    1345                 :          0 : void Binding::initializePropertySet()
    1346                 :            : {
    1347 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( BindingID,            OUString );
         [ #  # ][ #  # ]
    1348 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( BindingExpression,    OUString );
         [ #  # ][ #  # ]
    1349 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY_RO     ( Model,                Model_t );
         [ #  # ][ #  # ]
    1350 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( BindingNamespaces,    XNameContainer_t );
         [ #  # ][ #  # ]
    1351 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( ModelNamespaces,      XNameContainer_t );
         [ #  # ][ #  # ]
    1352 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY_RO     ( ModelID,              OUString );
         [ #  # ][ #  # ]
    1353 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( ReadonlyExpression,   OUString );
         [ #  # ][ #  # ]
    1354 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( RelevantExpression,   OUString );
         [ #  # ][ #  # ]
    1355 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( RequiredExpression,   OUString );
         [ #  # ][ #  # ]
    1356 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( ConstraintExpression, OUString );
         [ #  # ][ #  # ]
    1357 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( CalculateExpression,  OUString );
         [ #  # ][ #  # ]
    1358 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY        ( Type,                 OUString );
         [ #  # ][ #  # ]
    1359 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY_RO     ( ReadOnly,             bool );
         [ #  # ][ #  # ]
    1360 [ #  # ][ #  # ]:          0 :     REGISTER_PROPERTY_RO     ( Relevant,             bool );
         [ #  # ][ #  # ]
    1361 [ #  # ][ #  # ]:          0 :     REGISTER_BOOL_PROPERTY_RO( ExternalData               );
         [ #  # ][ #  # ]
    1362                 :            : 
    1363                 :          0 :     initializePropertyValueCache( HANDLE_ReadOnly );
    1364                 :          0 :     initializePropertyValueCache( HANDLE_Relevant );
    1365                 :          0 :     initializePropertyValueCache( HANDLE_ExternalData );
    1366                 :          0 : }
    1367                 :            : 
    1368                 :          0 : void Binding::addModifyListener(
    1369                 :            :     const XModifyListener_t& xListener )
    1370                 :            :     throw( RuntimeException )
    1371                 :            : {
    1372                 :            :     OSL_ENSURE( xListener.is(), "need listener!" );
    1373 [ #  # ][ #  # ]:          0 :     if( ::std::find( maModifyListeners.begin(), maModifyListeners.end(), xListener )
    1374         [ #  # ]:          0 :           == maModifyListeners.end() )
    1375                 :          0 :         maModifyListeners.push_back( xListener );
    1376                 :            : 
    1377                 :            :     // HACK: currently, we have to 'push' some MIPs to the control
    1378                 :            :     // (read-only, relevant, etc.) To enable this, we need to update
    1379                 :            :     // the control at least once when it registers here.
    1380                 :          0 :     valueModified();
    1381                 :          0 : }
    1382                 :            : 
    1383                 :          0 : void Binding::removeModifyListener(
    1384                 :            :     const XModifyListener_t& xListener )
    1385                 :            :     throw( RuntimeException )
    1386                 :            : {
    1387                 :            :     ModifyListeners_t::iterator aIter =
    1388         [ #  # ]:          0 :         ::std::find( maModifyListeners.begin(), maModifyListeners.end(), xListener );
    1389 [ #  # ][ #  # ]:          0 :     if( aIter != maModifyListeners.end() )
    1390         [ #  # ]:          0 :         maModifyListeners.erase( aIter );
    1391                 :          0 : }
    1392                 :            : 
    1393                 :            : 
    1394                 :            : 
    1395                 :            : 
    1396                 :          0 : rtl::OUString Binding::getName()
    1397                 :            :     throw( RuntimeException )
    1398                 :            : {
    1399                 :          0 :     return getBindingID();
    1400                 :            : }
    1401                 :            : 
    1402                 :          0 : void SAL_CALL Binding::setName( const rtl::OUString& rName )
    1403                 :            :     throw( RuntimeException )
    1404                 :            : {
    1405                 :            :     // use the XPropertySet methods, so the change in the name is notified to the
    1406                 :            :     // property listeners
    1407         [ #  # ]:          0 :     setFastPropertyValue( HANDLE_BindingID, makeAny( rName ) );
    1408                 :          0 : }
    1409                 :            : 
    1410                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10